Add EEA3 and EIA3 support for UE/enodeb and MME

master
David Rupprecht 6 years ago committed by Andre Puschmann
parent f05bb12c78
commit 50332089ce

@ -35,17 +35,21 @@ typedef enum {
CIPHERING_ALGORITHM_ID_EEA0 = 0, CIPHERING_ALGORITHM_ID_EEA0 = 0,
CIPHERING_ALGORITHM_ID_128_EEA1, CIPHERING_ALGORITHM_ID_128_EEA1,
CIPHERING_ALGORITHM_ID_128_EEA2, CIPHERING_ALGORITHM_ID_128_EEA2,
CIPHERING_ALGORITHM_ID_128_EEA3,
CIPHERING_ALGORITHM_ID_N_ITEMS, CIPHERING_ALGORITHM_ID_N_ITEMS,
} CIPHERING_ALGORITHM_ID_ENUM; } CIPHERING_ALGORITHM_ID_ENUM;
static const char ciphering_algorithm_id_text[CIPHERING_ALGORITHM_ID_N_ITEMS][20] = {"EEA0", "128-EEA1", "128-EEA2"}; static const char ciphering_algorithm_id_text[CIPHERING_ALGORITHM_ID_N_ITEMS][20] = {
"EEA0", "128-EEA1", "128-EEA2", "128-EEA3"};
typedef enum { typedef enum {
INTEGRITY_ALGORITHM_ID_EIA0 = 0, INTEGRITY_ALGORITHM_ID_EIA0 = 0,
INTEGRITY_ALGORITHM_ID_128_EIA1, INTEGRITY_ALGORITHM_ID_128_EIA1,
INTEGRITY_ALGORITHM_ID_128_EIA2, INTEGRITY_ALGORITHM_ID_128_EIA2,
INTEGRITY_ALGORITHM_ID_128_EIA3,
INTEGRITY_ALGORITHM_ID_N_ITEMS, INTEGRITY_ALGORITHM_ID_N_ITEMS,
} INTEGRITY_ALGORITHM_ID_ENUM; } INTEGRITY_ALGORITHM_ID_ENUM;
static const char integrity_algorithm_id_text[INTEGRITY_ALGORITHM_ID_N_ITEMS][20] = {"EIA0", "128-EIA1", "128-EIA2"}; static const char integrity_algorithm_id_text[INTEGRITY_ALGORITHM_ID_N_ITEMS][20] = {
"EIA0", "128-EIA1", "128-EIA2", "128-EIA3"};
typedef enum { typedef enum {
SECURITY_DIRECTION_UPLINK = 0, SECURITY_DIRECTION_UPLINK = 0,

@ -159,7 +159,7 @@ uint8_t security_128_eia2(uint8_t* key, uint32_t count, uint32_t bearer, uint8_t
uint8_t security_128_eia3(uint8_t* key, uint32_t count, uint32_t bearer, uint8_t direction, uint8_t* msg, uint8_t security_128_eia3(uint8_t* key, uint32_t count, uint32_t bearer, uint8_t direction, uint8_t* msg,
uint32_t msg_len, uint8_t* mac) uint32_t msg_len, uint8_t* mac)
{ {
return liblte_security_128_eia3(key, count, bearer, direction, msg, msg_len, mac); return liblte_security_128_eia3(key, count, bearer, direction, msg, msg_len * 8, mac);
} }
uint8_t security_md5(const uint8_t *input, size_t len, uint8_t *output) uint8_t security_md5(const uint8_t *input, size_t len, uint8_t *output)

@ -79,6 +79,9 @@ void pdcp_entity_base::integrity_generate(uint8_t* msg, uint32_t msg_len, uint32
case INTEGRITY_ALGORITHM_ID_128_EIA2: case INTEGRITY_ALGORITHM_ID_128_EIA2:
security_128_eia2(&k_int[16], count, cfg.bearer_id - 1, cfg.tx_direction, msg, msg_len, mac); security_128_eia2(&k_int[16], count, cfg.bearer_id - 1, cfg.tx_direction, msg, msg_len, mac);
break; break;
case INTEGRITY_ALGORITHM_ID_128_EIA3:
security_128_eia3(&k_int[16], count, cfg.bearer_id - 1, cfg.tx_direction, msg, msg_len, mac);
break;
default: default:
break; break;
} }
@ -113,6 +116,9 @@ bool pdcp_entity_base::integrity_verify(uint8_t* msg, uint32_t msg_len, uint32_t
case INTEGRITY_ALGORITHM_ID_128_EIA2: case INTEGRITY_ALGORITHM_ID_128_EIA2:
security_128_eia2(&k_int[16], count, cfg.bearer_id - 1, cfg.rx_direction, msg, msg_len, mac_exp); security_128_eia2(&k_int[16], count, cfg.bearer_id - 1, cfg.rx_direction, msg, msg_len, mac_exp);
break; break;
case INTEGRITY_ALGORITHM_ID_128_EIA3:
security_128_eia3(&k_int[16], count, cfg.bearer_id - 1, cfg.rx_direction, msg, msg_len, mac_exp);
break;
default: default:
break; break;
} }
@ -169,6 +175,10 @@ void pdcp_entity_base::cipher_encrypt(uint8_t* msg, uint32_t msg_len, uint32_t c
security_128_eea2(&(k_enc[16]), count, cfg.bearer_id - 1, cfg.tx_direction, msg, msg_len, ct_tmp); security_128_eea2(&(k_enc[16]), count, cfg.bearer_id - 1, cfg.tx_direction, msg, msg_len, ct_tmp);
memcpy(ct, ct_tmp, msg_len); memcpy(ct, ct_tmp, msg_len);
break; break;
case CIPHERING_ALGORITHM_ID_128_EEA3:
security_128_eea3(&(k_enc[16]), count, cfg.bearer_id - 1, cfg.tx_direction, msg, msg_len, ct_tmp);
memcpy(ct, ct_tmp, msg_len);
break;
default: default:
break; break;
} }
@ -204,6 +214,10 @@ void pdcp_entity_base::cipher_decrypt(uint8_t* ct, uint32_t ct_len, uint32_t cou
security_128_eea2(&k_enc[16], count, cfg.bearer_id - 1, cfg.rx_direction, ct, ct_len, msg_tmp); security_128_eea2(&k_enc[16], count, cfg.bearer_id - 1, cfg.rx_direction, ct, ct_len, msg_tmp);
memcpy(msg, msg_tmp, ct_len); memcpy(msg, msg_tmp, ct_len);
break; break;
case CIPHERING_ALGORITHM_ID_128_EEA3:
security_128_eea3(&k_enc[16], count, cfg.bearer_id - 1, cfg.rx_direction, ct, ct_len, msg_tmp);
memcpy(msg, msg_tmp, ct_len);
break;
default: default:
break; break;
} }

@ -1571,6 +1571,15 @@ bool nas::short_integrity_check(srslte::byte_buffer_t* pdu)
2, 2,
&exp_mac[0]); &exp_mac[0]);
break; break;
case srslte::INTEGRITY_ALGORITHM_ID_128_EIA3:
srslte::security_128_eia3(&m_sec_ctx.k_nas_int[16],
m_sec_ctx.ul_nas_count,
0,
srslte::SECURITY_DIRECTION_UPLINK,
&pdu->msg[0],
2,
&exp_mac[0]);
break;
default: default:
break; break;
} }
@ -1616,6 +1625,15 @@ bool nas::integrity_check(srslte::byte_buffer_t* pdu)
pdu->N_bytes - 5, pdu->N_bytes - 5,
&exp_mac[0]); &exp_mac[0]);
break; break;
case srslte::INTEGRITY_ALGORITHM_ID_128_EIA3:
srslte::security_128_eia3(&m_sec_ctx.k_nas_int[16],
m_sec_ctx.ul_nas_count,
0,
srslte::SECURITY_DIRECTION_UPLINK,
&pdu->msg[5],
pdu->N_bytes - 5,
&exp_mac[0]);
break;
default: default:
break; break;
} }
@ -1657,6 +1675,15 @@ void nas::integrity_generate(srslte::byte_buffer_t* pdu, uint8_t* mac)
pdu->N_bytes - 5, pdu->N_bytes - 5,
mac); mac);
break; break;
case srslte::INTEGRITY_ALGORITHM_ID_128_EIA3:
srslte::security_128_eia3(&m_sec_ctx.k_nas_int[16],
m_sec_ctx.dl_nas_count,
0, // Bearer always 0 for NAS
SECURITY_DIRECTION_DOWNLINK,
&pdu->msg[5],
pdu->N_bytes - 5,
mac);
break;
default: default:
break; break;
} }
@ -1693,6 +1720,17 @@ void nas::cipher_decrypt(srslte::byte_buffer_t* pdu)
m_nas_log->debug_hex(tmp_pdu.msg, pdu->N_bytes, "Decrypted"); m_nas_log->debug_hex(tmp_pdu.msg, pdu->N_bytes, "Decrypted");
memcpy(&pdu->msg[6], &tmp_pdu.msg[6], pdu->N_bytes - 6); memcpy(&pdu->msg[6], &tmp_pdu.msg[6], pdu->N_bytes - 6);
break; break;
case srslte::CIPHERING_ALGORITHM_ID_128_EEA3:
srslte::security_128_eea3(&m_sec_ctx.k_nas_enc[16],
pdu->msg[5],
0, // Bearer always 0 for NAS
srslte::SECURITY_DIRECTION_UPLINK,
&pdu->msg[6],
pdu->N_bytes-6,
&tmp_pdu.msg[6]);
m_nas_log->debug_hex(tmp_pdu.msg, pdu->N_bytes, "Decrypted");
memcpy(&pdu->msg[6], &tmp_pdu.msg[6], pdu->N_bytes-6);
break;
default: default:
m_nas_log->error("Ciphering algorithms not known\n"); m_nas_log->error("Ciphering algorithms not known\n");
break; break;
@ -1727,6 +1765,17 @@ void nas::cipher_encrypt(srslte::byte_buffer_t* pdu)
memcpy(&pdu->msg[6], &pdu_tmp.msg[6], pdu->N_bytes - 6); memcpy(&pdu->msg[6], &pdu_tmp.msg[6], pdu->N_bytes - 6);
m_nas_log->debug_hex(pdu_tmp.msg, pdu->N_bytes, "Encrypted"); m_nas_log->debug_hex(pdu_tmp.msg, pdu->N_bytes, "Encrypted");
break; break;
case srslte::CIPHERING_ALGORITHM_ID_128_EEA3:
srslte::security_128_eea3(&m_sec_ctx.k_nas_enc[16],
pdu->msg[5],
0, // Bearer always 0 for NAS
srslte::SECURITY_DIRECTION_DOWNLINK,
&pdu->msg[6],
pdu->N_bytes - 6,
&pdu_tmp.msg[6]);
memcpy(&pdu->msg[6], &pdu_tmp.msg[6], pdu->N_bytes - 6);
m_nas_log->debug_hex(pdu_tmp.msg, pdu->N_bytes, "Encrypted");
break;
default: default:
m_nas_log->error("Ciphering algorithm not known\n"); m_nas_log->error("Ciphering algorithm not known\n");
break; break;

@ -956,6 +956,15 @@ void rrc::send_con_restablish_request()
N_bytes, N_bytes,
mac_key); mac_key);
break; break;
case INTEGRITY_ALGORITHM_ID_128_EIA3:
security_128_eia3(&k_rrc_int[16],
0xffffffff, // 32-bit all to ones
0x1f, // 5-bit all to ones
1, // 1-bit to one
varShortMAC_packed,
N_bytes,
mac_key);
break;
default: default:
rrc_log->info("Unsupported integrity algorithm during reestablishment\n"); rrc_log->info("Unsupported integrity algorithm during reestablishment\n");
} }

@ -645,6 +645,15 @@ void nas::integrity_generate(uint8_t *key_128,
msg_len, msg_len,
mac); mac);
break; break;
case INTEGRITY_ALGORITHM_ID_128_EIA3:
security_128_eia3(key_128,
count,
0, // Bearer always 0 for NAS
direction,
msg,
msg_len,
mac);
break;
default: default:
break; break;
} }
@ -716,6 +725,16 @@ void nas::cipher_encrypt(byte_buffer_t* pdu)
&pdu_tmp.msg[6]); &pdu_tmp.msg[6]);
memcpy(&pdu->msg[6], &pdu_tmp.msg[6], pdu->N_bytes-6); memcpy(&pdu->msg[6], &pdu_tmp.msg[6], pdu->N_bytes-6);
break; break;
case CIPHERING_ALGORITHM_ID_128_EEA3:
security_128_eea3(&k_nas_enc[16],
pdu->msg[5],
0, // Bearer always 0 for NAS
SECURITY_DIRECTION_UPLINK,
&pdu->msg[6],
pdu->N_bytes-6,
&pdu_tmp.msg[6]);
memcpy(&pdu->msg[6], &pdu_tmp.msg[6], pdu->N_bytes-6);
break;
default: default:
nas_log->error("Ciphering algorithm not known\n"); nas_log->error("Ciphering algorithm not known\n");
break; break;
@ -750,6 +769,17 @@ void nas::cipher_decrypt(byte_buffer_t* pdu)
nas_log->debug_hex(tmp_pdu.msg, pdu->N_bytes, "Decrypted"); nas_log->debug_hex(tmp_pdu.msg, pdu->N_bytes, "Decrypted");
memcpy(&pdu->msg[6], &tmp_pdu.msg[6], pdu->N_bytes-6); memcpy(&pdu->msg[6], &tmp_pdu.msg[6], pdu->N_bytes-6);
break; break;
case CIPHERING_ALGORITHM_ID_128_EEA3:
security_128_eea3(&k_nas_enc[16],
pdu->msg[5],
0, // Bearer always 0 for NAS
SECURITY_DIRECTION_DOWNLINK,
&pdu->msg[6],
pdu->N_bytes-6,
&tmp_pdu.msg[6]);
nas_log->debug_hex(tmp_pdu.msg, pdu->N_bytes, "Decrypted");
memcpy(&pdu->msg[6], &tmp_pdu.msg[6], pdu->N_bytes-6);
break;
default: default:
nas_log->error("Ciphering algorithms not known\n"); nas_log->error("Ciphering algorithms not known\n");
break; break;

Loading…
Cancel
Save