diff --git a/lib/include/srslte/common/liblte_security.h b/lib/include/srslte/common/liblte_security.h index 9a5f1feea..f7d2ad8c5 100644 --- a/lib/include/srslte/common/liblte_security.h +++ b/lib/include/srslte/common/liblte_security.h @@ -38,7 +38,6 @@ #include "srslte/asn1/liblte_common.h" - /******************************************************************************* DEFINES *******************************************************************************/ diff --git a/lib/include/srslte/common/security.h b/lib/include/srslte/common/security.h index 67500f59b..37c7ac24c 100644 --- a/lib/include/srslte/common/security.h +++ b/lib/include/srslte/common/security.h @@ -103,90 +103,40 @@ uint8_t security_generate_k_up( uint8_t *k_enb, /****************************************************************************** * Integrity Protection *****************************************************************************/ -uint8_t security_128_eia1( uint8_t *key, - uint32_t count, - uint32_t bearer, - uint8_t direction, - uint8_t *msg, - uint32_t msg_len, - uint8_t *mac); - -uint8_t security_128_eia2( uint8_t *key, - uint32_t count, - uint32_t bearer, - uint8_t direction, - uint8_t *msg, - uint32_t msg_len, - uint8_t *mac); - -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); - -uint8_t security_md5(const uint8_t *input, - size_t len, - uint8_t *output); +uint8_t security_128_eia1( + uint8_t* key, uint32_t count, uint32_t bearer, uint8_t direction, uint8_t* msg, uint32_t msg_len, uint8_t* mac); +uint8_t security_128_eia2( + uint8_t* key, uint32_t count, uint32_t bearer, uint8_t direction, uint8_t* msg, uint32_t msg_len, uint8_t* mac); + +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); + +uint8_t security_md5(const uint8_t* input, size_t len, uint8_t* output); /****************************************************************************** * Encryption / Decryption *****************************************************************************/ -uint8_t security_128_eea1( uint8_t *key, - uint32_t count, - uint8_t bearer, - uint8_t direction, - uint8_t *msg, - uint32_t msg_len, - uint8_t *msg_out); - -uint8_t security_128_eea2(uint8_t *key, - uint32_t count, - uint8_t bearer, - uint8_t direction, - uint8_t *msg, - uint32_t msg_len, - uint8_t *msg_out); - -uint8_t security_128_eea3(uint8_t *key, - uint32_t count, - uint8_t bearer, - uint8_t direction, - uint8_t *msg, - uint32_t msg_len, - uint8_t *msg_out); +uint8_t security_128_eea1( + uint8_t* key, uint32_t count, uint8_t bearer, uint8_t direction, uint8_t* msg, uint32_t msg_len, uint8_t* msg_out); + +uint8_t security_128_eea2( + uint8_t* key, uint32_t count, uint8_t bearer, uint8_t direction, uint8_t* msg, uint32_t msg_len, uint8_t* msg_out); + +uint8_t security_128_eea3( + uint8_t* key, uint32_t count, uint8_t bearer, uint8_t direction, uint8_t* msg, uint32_t msg_len, uint8_t* msg_out); /****************************************************************************** * Authentication *****************************************************************************/ -uint8_t compute_opc( uint8_t *k, - uint8_t *op, - uint8_t *opc); - -uint8_t security_milenage_f1( uint8_t *k, - uint8_t *op, - uint8_t *rand, - uint8_t *sqn, - uint8_t *amf, - uint8_t *mac_a); - -uint8_t security_milenage_f1_star( uint8_t *k, - uint8_t *op, - uint8_t *rand, - uint8_t *sqn, - uint8_t *amf, - uint8_t *mac_s); - -uint8_t security_milenage_f2345( uint8_t *k, - uint8_t *op, - uint8_t *rand, - uint8_t *res, - uint8_t *ck, - uint8_t *ik, - uint8_t *ak); +uint8_t compute_opc(uint8_t* k, uint8_t* op, uint8_t* opc); + +uint8_t security_milenage_f1(uint8_t* k, uint8_t* op, uint8_t* rand, uint8_t* sqn, uint8_t* amf, uint8_t* mac_a); + +uint8_t security_milenage_f1_star(uint8_t* k, uint8_t* op, uint8_t* rand, uint8_t* sqn, uint8_t* amf, uint8_t* mac_s); + +uint8_t +security_milenage_f2345(uint8_t* k, uint8_t* op, uint8_t* rand, uint8_t* res, uint8_t* ck, uint8_t* ik, uint8_t* ak); uint8_t security_milenage_f5_star( uint8_t *k, uint8_t *op, diff --git a/lib/include/srslte/common/zuc.h b/lib/include/srslte/common/zuc.h index 950143611..8c8f81fad 100644 --- a/lib/include/srslte/common/zuc.h +++ b/lib/include/srslte/common/zuc.h @@ -32,7 +32,7 @@ typedef struct { u32 BRC_X3; } zuc_state_t; -void zuc_initialize(zuc_state_t *state, u8* k, u8* iv); -void zuc_generate_keystream(zuc_state_t *state, int key_stream_len, u32* p_keystream); +void zuc_initialize(zuc_state_t* state, u8* k, u8* iv); +void zuc_generate_keystream(zuc_state_t* state, int key_stream_len, u32* p_keystream); #endif // SRSLTE_ZUC_H \ No newline at end of file diff --git a/lib/src/common/liblte_security.cc b/lib/src/common/liblte_security.cc index 90e868f00..3bc4ebe49 100644 --- a/lib/src/common/liblte_security.cc +++ b/lib/src/common/liblte_security.cc @@ -35,9 +35,9 @@ *******************************************************************************/ #include "srslte/common/liblte_security.h" -#include "srslte/common/zuc.h" #include "math.h" #include "srslte/common/liblte_ssl.h" +#include "srslte/common/zuc.h" /******************************************************************************* DEFINES @@ -808,89 +808,86 @@ LIBLTE_ERROR_ENUM liblte_security_128_eia2( return (err); } -u32 GET_WORD(u32 * DATA, u32 i) +u32 GET_WORD(u32* DATA, u32 i) { - u32 WORD, ti; - ti = i % 32; - if (ti == 0) - WORD = DATA[i/32]; - else - WORD = (DATA[i/32]<>(32-ti)); - return WORD; + u32 WORD, ti; + ti = i % 32; + if (ti == 0) + WORD = DATA[i / 32]; + else + WORD = (DATA[i / 32] << ti) | (DATA[i / 32 + 1] >> (32 - ti)); + return WORD; } -u8 GET_BIT(uint8_t * DATA, u32 i) +u8 GET_BIT(uint8_t* DATA, u32 i) { - return (DATA[i/8] & (1<<(7-(i%8)))) ? 1 : 0; + return (DATA[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0; } -LIBLTE_ERROR_ENUM liblte_security_128_eia3(uint8* key, uint32 count, uint8 bearer, uint8 direction, uint8* msg, - uint32 msg_len, uint8* mac) - -{ - LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8_t iv[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - - uint32 *ks; - uint32 msg_len_block_8, msg_len_block_32, m; - - if(key != NULL && - msg != NULL && - mac != NULL) - { - msg_len_block_8 = (msg_len + 7) / 8; - msg_len_block_32 = (msg_len + 31) / 32; - - // Construct iv - iv[0] = (count >> 24) & 0xFF; - iv[1] = (count >> 16) & 0xFF; - iv[2] = (count >> 8) & 0xFF; - iv[3] = count & 0xFF; - - iv[4] = (bearer << 3) & 0xF8; - iv[5] = iv[6] = iv[7] = 0; - - iv[8] = ((count >> 24) & 0xFF) ^ ((direction & 1) << 7); - iv[9] = (count >> 16) & 0xFF; - iv[10] = (count >> 8) & 0xFF; - iv[11] = count & 0xFF; - - iv[12] = iv[4]; - iv[13] = iv[5]; - iv[14] = iv[6] ^ ((direction & 1) << 7); - iv[15] = iv[7]; - - zuc_state_t zuc_state; - // Initialize keystream - zuc_initialize(&zuc_state, key, iv); - - // Generate keystream - int N = msg_len + 64; - int L = (N + 31) / 32; - - ks = (uint32*)calloc(L, sizeof(uint32)); - - zuc_generate_keystream(&zuc_state, L, ks); - - uint32_t T = 0; - for (uint32_t i = 0; i < msg_len; i++) { - if (GET_BIT(msg, i)) { - T ^= GET_WORD(ks, i); - } - } - - T ^= GET_WORD(ks, msg_len); - - uint32_t mac_tmp = T ^ ks[L - 1]; - mac[0] = (mac_tmp >> 24) & 0xFF; - mac[1] = (mac_tmp >> 16) & 0xFF; - mac[2] = (mac_tmp >> 8) & 0xFF; - mac[3] = mac_tmp & 0xFF; - - free(ks); - } - - return (err); +LIBLTE_ERROR_ENUM liblte_security_128_eia3( + uint8* key, uint32 count, uint8 bearer, uint8 direction, uint8* msg, uint32 msg_len, uint8* mac) + +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + uint8_t iv[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + uint32* ks; + uint32 msg_len_block_8, msg_len_block_32, m; + + if (key != NULL && msg != NULL && mac != NULL) { + msg_len_block_8 = (msg_len + 7) / 8; + msg_len_block_32 = (msg_len + 31) / 32; + + // Construct iv + iv[0] = (count >> 24) & 0xFF; + iv[1] = (count >> 16) & 0xFF; + iv[2] = (count >> 8) & 0xFF; + iv[3] = count & 0xFF; + + iv[4] = (bearer << 3) & 0xF8; + iv[5] = iv[6] = iv[7] = 0; + + iv[8] = ((count >> 24) & 0xFF) ^ ((direction & 1) << 7); + iv[9] = (count >> 16) & 0xFF; + iv[10] = (count >> 8) & 0xFF; + iv[11] = count & 0xFF; + + iv[12] = iv[4]; + iv[13] = iv[5]; + iv[14] = iv[6] ^ ((direction & 1) << 7); + iv[15] = iv[7]; + + zuc_state_t zuc_state; + // Initialize keystream + zuc_initialize(&zuc_state, key, iv); + + // Generate keystream + int N = msg_len + 64; + int L = (N + 31) / 32; + + ks = (uint32*)calloc(L, sizeof(uint32)); + + zuc_generate_keystream(&zuc_state, L, ks); + + uint32_t T = 0; + for (uint32_t i = 0; i < msg_len; i++) { + if (GET_BIT(msg, i)) { + T ^= GET_WORD(ks, i); + } + } + + T ^= GET_WORD(ks, msg_len); + + uint32_t mac_tmp = T ^ ks[L - 1]; + mac[0] = (mac_tmp >> 24) & 0xFF; + mac[1] = (mac_tmp >> 16) & 0xFF; + mac[2] = (mac_tmp >> 8) & 0xFF; + mac[3] = mac_tmp & 0xFF; + + free(ks); + } + + return (err); } /********************************************************************* @@ -1047,83 +1044,75 @@ LIBLTE_ERROR_ENUM liblte_security_decryption_eea2( Specification of the 3GPP Confidentiality and Integrity Algorithms UEA2 & UIA2 D1 v2.1 *********************************************************************/ -LIBLTE_ERROR_ENUM liblte_security_encryption_eea3(uint8 *key, - uint32 count, - uint8 bearer, - uint8 direction, - uint8 *msg, - uint32 msg_len, - uint8 *out) +LIBLTE_ERROR_ENUM liblte_security_encryption_eea3( + uint8* key, uint32 count, uint8 bearer, uint8 direction, uint8* msg, uint32 msg_len, uint8* out) { - LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8_t iv[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - - uint32 *ks; - int32 i; - uint32 msg_len_block_8, msg_len_block_32, m; - - if (key != NULL && - msg != NULL && - out != NULL) - { - msg_len_block_8 = (msg_len + 7) / 8; - msg_len_block_32 = (msg_len + 31) / 32; - - // Construct iv - iv[0] = (count >> 24) & 0xFF; - iv[1] = (count >> 16) & 0xFF; - iv[2] = (count >> 8) & 0xFF; - iv[3] = (count)&0xFF; - iv[4] = ((bearer & 0x1F) << 3) | ((direction & 0x01) << 2); - iv[5] = 0; - iv[6] = 0; - iv[7] = 0; - iv[8] = iv[0]; - iv[9] = iv[1]; - iv[10] = iv[2]; - iv[11] = iv[3]; - iv[12] = iv[4]; - iv[13] = iv[5]; - iv[14] = iv[6]; - iv[15] = iv[7]; - - zuc_state_t zuc_state; - // Initialize keystream - zuc_initialize(&zuc_state, key, iv); - - // Generate keystream - - ks = (uint32 *) calloc(msg_len_block_32, sizeof(uint32)); - zuc_generate_keystream(&zuc_state, msg_len_block_32, ks); - - // Generate output except last block - for (i = 0; i < (int32_t)msg_len_block_32 - 1; i++) { - out[4 * i + 0] = msg[4 * i + 0] ^ ((ks[i] >> 24) & 0xFF); - out[4 * i + 1] = msg[4 * i + 1] ^ ((ks[i] >> 16) & 0xFF); - out[4 * i + 2] = msg[4 * i + 2] ^ ((ks[i] >> 8) & 0xFF); - out[4 * i + 3] = msg[4 * i + 3] ^ ((ks[i] & 0xFF)); - } - - // Process last bytes - for (i = (msg_len_block_32 - 1) * 4; i < (int32_t)msg_len_block_8; i++) { - out[i] = msg[i] ^ ((ks[i / 4] >> ((3 - (i % 4)) * 8)) & 0xFF); - } - - // Zero tailing bits - zero_tailing_bits(out, msg_len); - - // Clean up - free(ks); - // zuc_deinitialize(state_ptr); - - err = LIBLTE_SUCCESS; - } - - return(err); + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + uint8_t iv[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + uint32* ks; + int32 i; + uint32 msg_len_block_8, msg_len_block_32, m; + + if (key != NULL && msg != NULL && out != NULL) { + msg_len_block_8 = (msg_len + 7) / 8; + msg_len_block_32 = (msg_len + 31) / 32; + + // Construct iv + iv[0] = (count >> 24) & 0xFF; + iv[1] = (count >> 16) & 0xFF; + iv[2] = (count >> 8) & 0xFF; + iv[3] = (count)&0xFF; + iv[4] = ((bearer & 0x1F) << 3) | ((direction & 0x01) << 2); + iv[5] = 0; + iv[6] = 0; + iv[7] = 0; + iv[8] = iv[0]; + iv[9] = iv[1]; + iv[10] = iv[2]; + iv[11] = iv[3]; + iv[12] = iv[4]; + iv[13] = iv[5]; + iv[14] = iv[6]; + iv[15] = iv[7]; + + zuc_state_t zuc_state; + // Initialize keystream + zuc_initialize(&zuc_state, key, iv); + + // Generate keystream + + ks = (uint32*)calloc(msg_len_block_32, sizeof(uint32)); + zuc_generate_keystream(&zuc_state, msg_len_block_32, ks); + + // Generate output except last block + for (i = 0; i < (int32_t)msg_len_block_32 - 1; i++) { + out[4 * i + 0] = msg[4 * i + 0] ^ ((ks[i] >> 24) & 0xFF); + out[4 * i + 1] = msg[4 * i + 1] ^ ((ks[i] >> 16) & 0xFF); + out[4 * i + 2] = msg[4 * i + 2] ^ ((ks[i] >> 8) & 0xFF); + out[4 * i + 3] = msg[4 * i + 3] ^ ((ks[i] & 0xFF)); + } + + // Process last bytes + for (i = (msg_len_block_32 - 1) * 4; i < (int32_t)msg_len_block_8; i++) { + out[i] = msg[i] ^ ((ks[i / 4] >> ((3 - (i % 4)) * 8)) & 0xFF); + } + + // Zero tailing bits + zero_tailing_bits(out, msg_len); + + // Clean up + free(ks); + // zuc_deinitialize(state_ptr); + + err = LIBLTE_SUCCESS; + } + + return (err); } -LIBLTE_ERROR_ENUM liblte_security_decryption_eea3(uint8* key, uint32 count, uint8 bearer, uint8 direction, uint8* msg, - uint32 msg_len, uint8* out) +LIBLTE_ERROR_ENUM liblte_security_decryption_eea3( + uint8* key, uint32 count, uint8 bearer, uint8 direction, uint8* msg, uint32 msg_len, uint8* out) { return liblte_security_encryption_eea3(key, count, bearer, direction, msg, msg_len, out); } @@ -1857,6 +1846,3 @@ void s3g_generate_keystream(S3G_STATE* state, uint32 n, uint32* ks) s3g_clock_lfsr(state, 0x0); } } - - - diff --git a/lib/src/common/security.cc b/lib/src/common/security.cc index 8f5559aff..56de0697f 100644 --- a/lib/src/common/security.cc +++ b/lib/src/common/security.cc @@ -150,19 +150,19 @@ uint8_t security_128_eia1( uint8_t *key, return SRSLTE_SUCCESS; } -uint8_t security_128_eia2(uint8_t* key, uint32_t count, uint32_t bearer, uint8_t direction, uint8_t* msg, - uint32_t msg_len, uint8_t* mac) +uint8_t security_128_eia2( + uint8_t* key, uint32_t count, uint32_t bearer, uint8_t direction, uint8_t* msg, uint32_t msg_len, uint8_t* mac) { return liblte_security_128_eia2(key, count, bearer, direction, msg, msg_len, mac); } -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) +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) { 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) { memset(output, 0x00, 16); #ifdef HAVE_MBEDTLS @@ -174,7 +174,6 @@ uint8_t security_md5(const uint8_t *input, size_t len, uint8_t *output) return SRSLTE_SUCCESS; } - /****************************************************************************** * Encryption / Decryption *****************************************************************************/ @@ -197,54 +196,26 @@ uint8_t security_128_eea1(uint8_t *key, } +uint8_t security_128_eea2( + uint8_t* key, uint32_t count, uint8_t bearer, uint8_t direction, uint8_t* msg, uint32_t msg_len, uint8_t* msg_out) +{ -uint8_t security_128_eea2(uint8_t *key, - uint32_t count, - uint8_t bearer, - uint8_t direction, - uint8_t *msg, - uint32_t msg_len, - uint8_t *msg_out){ - - return liblte_security_encryption_eea2(key, - count, - bearer, - direction, - msg, - msg_len * 8, - msg_out); + return liblte_security_encryption_eea2(key, count, bearer, direction, msg, msg_len * 8, msg_out); } +uint8_t security_128_eea3( + uint8_t* key, uint32_t count, uint8_t bearer, uint8_t direction, uint8_t* msg, uint32_t msg_len, uint8_t* msg_out) +{ -uint8_t security_128_eea3(uint8_t *key, - uint32_t count, - uint8_t bearer, - uint8_t direction, - uint8_t *msg, - uint32_t msg_len, - uint8_t *msg_out){ - - return liblte_security_encryption_eea3(key, - count, - bearer, - direction, - msg, - msg_len * 8, - msg_out); + return liblte_security_encryption_eea3(key, count, bearer, direction, msg, msg_len * 8, msg_out); } - - /****************************************************************************** * Authentication *****************************************************************************/ -uint8_t compute_opc( uint8_t *k, - uint8_t *op, - uint8_t *opc) +uint8_t compute_opc(uint8_t* k, uint8_t* op, uint8_t* opc) { - return liblte_compute_opc(k, - op, - opc); + return liblte_compute_opc(k, op, opc); } uint8_t security_milenage_f1( uint8_t *k, diff --git a/lib/src/common/zuc.cc b/lib/src/common/zuc.cc index 383099e47..9b3e335c5 100644 --- a/lib/src/common/zuc.cc +++ b/lib/src/common/zuc.cc @@ -2,17 +2,13 @@ #include "srslte/common/zuc.h" -/* ——————————————————————- */ -/* the state registers of LFSR */ - - -#define MAKEU32(a, b, c, d) (((u32)(a) << 24) | ((u32)(b) << 16) | ((u32)(c) << 8) | ((u32)(d))) +#define MAKEU32(a, b, c, d) (((u32)(a) << 24) | ((u32)(b) << 16) | ((u32)(c) << 8) | ((u32)(d))) #define MulByPow2(x, k) ((((x) << k) | ((x) >> (31 - k))) & 0x7FFFFFFF) -#define MAKEU31(a, b, c) (((u32)(a) << 23) | ((u32)(b) << 8) | (u32)(c)) +#define MAKEU31(a, b, c) (((u32)(a) << 23) | ((u32)(b) << 8) | (u32)(c)) #define ROT(a, k) (((a) << k) | ((a) >> (32 - k))) /* the s-boxes */ -u8 S0[256] = { +u8 S0[256] = { 0x3e, 0x72, 0x5b, 0x47, 0xca, 0xe0, 0x00, 0x33, 0x04, 0xd1, 0x54, 0x98, 0x09, 0xb9, 0x6d, 0xcb, 0x7b, 0x1b, 0xf9, 0x32, 0xaf, 0x9d, 0x6a, 0xa5, 0xb8, 0x2d, 0xfc, 0x1d, 0x08, 0x53, 0x03, 0x90, 0x4d, 0x4e, 0x84, 0x99, 0xe4, 0xce, 0xd9, 0x91, 0xdd, 0xb6, 0x85, 0x48, 0x8b, 0x29, 0x6e, 0xac, 0xcd, 0xc1, 0xf8, 0x1e, 0x73, 0x43, 0x69, 0xc6, 0xb5, @@ -27,6 +23,7 @@ u8 S0[256] = { 0xfa, 0x36, 0xd2, 0x50, 0x68, 0x9e, 0x62, 0x71, 0x15, 0x3d, 0xd6, 0x40, 0xc4, 0xe2, 0x0f, 0x8e, 0x83, 0x77, 0x6b, 0x25, 0x05, 0x3f, 0x0c, 0x30, 0xea, 0x70, 0xb7, 0xa1, 0xe8, 0xa9, 0x65, 0x8d, 0x27, 0x1a, 0xdb, 0x81, 0xb3, 0xa0, 0xf4, 0x45, 0x7a, 0x19, 0xdf, 0xee, 0x78, 0x34, 0x60}; + u8 S1[256] = { 0x55, 0xc2, 0x63, 0x71, 0x3b, 0xc8, 0x47, 0x86, 0x9f, 0x3c, 0xda, 0x5b, 0x29, 0xaa, 0xfd, 0x77, 0x8c, 0xc5, 0x94, 0x0c, 0xa6, 0x1a, 0x13, 0x00, 0xe3, 0xa8, 0x16, 0x72, 0x40, 0xf9, 0xf8, 0x42, 0x44, 0x26, 0x68, 0x96, 0x81, 0xd9, @@ -41,14 +38,28 @@ u8 S1[256] = { 0xc3, 0xde, 0xa3, 0xef, 0xea, 0x51, 0xe6, 0x6b, 0x18, 0xec, 0x1b, 0x2c, 0x80, 0xf7, 0x74, 0xe7, 0xff, 0x21, 0x5a, 0x6a, 0x54, 0x1e, 0x41, 0x31, 0x92, 0x35, 0xc4, 0x33, 0x07, 0x0a, 0xba, 0x7e, 0x0e, 0x34, 0x88, 0xb1, 0x98, 0x7c, 0xf3, 0x3d, 0x60, 0x6c, 0x7b, 0xca, 0xd3, 0x1f, 0x32, 0x65, 0x04, 0x28, 0x64, 0xbe, 0x85, 0x9b, 0x2f, 0x59, 0x8a, - 0xd7, 0xb0, 0x25, 0xac, 0xaf, 0x12, 0x03, 0xe2, 0xf2}; /* the constants D */ - -u32 EK_d[16] = {0x44D7, 0x26BC, 0x626B, 0x135E, 0x5789, 0x35E2, 0x7135, 0x09AF, - 0x4D78, 0x2F13, 0x6BC4, 0x1AF1, 0x5E26, 0x3C4D, 0x789A, 0x47AC}; + 0xd7, 0xb0, 0x25, 0xac, 0xaf, 0x12, 0x03, 0xe2, 0xf2}; + +/* the constants D */ +u32 EK_d[16] = {0x44D7, + 0x26BC, + 0x626B, + 0x135E, + 0x5789, + 0x35E2, + 0x7135, + 0x09AF, + 0x4D78, + 0x2F13, + 0x6BC4, + 0x1AF1, + 0x5E26, + 0x3C4D, + 0x789A, + 0x47AC}; /* ——————————————————————- */ /* c = a + b mod (2^31 – 1) */ - u32 AddM(u32 a, u32 b) { u32 c = a + b; @@ -56,21 +67,23 @@ u32 AddM(u32 a, u32 b) } /* LFSR with initialization mode */ -void LFSRWithInitialisationMode(zuc_state_t * state, u32 u) +void LFSRWithInitialisationMode(zuc_state_t* state, u32 u) { u32 f, v; - f = state->LFSR_S0; - v = MulByPow2(state->LFSR_S0, 8); - f = AddM(f, v); - v = MulByPow2(state->LFSR_S4, 20); - f = AddM(f, v); - v = MulByPow2(state->LFSR_S10, 21); - f = AddM(f, v); - v = MulByPow2(state->LFSR_S13, 17); - f = AddM(f, v); - v = MulByPow2(state->LFSR_S15, 15); - f = AddM(f, v); - f = AddM(f, u); /* update the state */ + f = state->LFSR_S0; + v = MulByPow2(state->LFSR_S0, 8); + f = AddM(f, v); + v = MulByPow2(state->LFSR_S4, 20); + f = AddM(f, v); + v = MulByPow2(state->LFSR_S10, 21); + f = AddM(f, v); + v = MulByPow2(state->LFSR_S13, 17); + f = AddM(f, v); + v = MulByPow2(state->LFSR_S15, 15); + f = AddM(f, v); + f = AddM(f, u); + + /* update the state */ state->LFSR_S0 = state->LFSR_S1; state->LFSR_S1 = state->LFSR_S2; state->LFSR_S2 = state->LFSR_S3; @@ -87,22 +100,25 @@ void LFSRWithInitialisationMode(zuc_state_t * state, u32 u) state->LFSR_S13 = state->LFSR_S14; state->LFSR_S14 = state->LFSR_S15; state->LFSR_S15 = f; -} /* LFSR with work mode */ +} -void LFSRWithWorkMode(zuc_state_t *state) +/* LFSR with work mode */ +void LFSRWithWorkMode(zuc_state_t* state) { u32 f, v; - f = state->LFSR_S0; - v = MulByPow2(state->LFSR_S0, 8); - f = AddM(f, v); - v = MulByPow2(state->LFSR_S4, 20); - f = AddM(f, v); - v = MulByPow2(state->LFSR_S10, 21); - f = AddM(f, v); - v = MulByPow2(state->LFSR_S13, 17); - f = AddM(f, v); - v = MulByPow2(state->LFSR_S15, 15); - f = AddM(f, v); /* update the state */ + f = state->LFSR_S0; + v = MulByPow2(state->LFSR_S0, 8); + f = AddM(f, v); + v = MulByPow2(state->LFSR_S4, 20); + f = AddM(f, v); + v = MulByPow2(state->LFSR_S10, 21); + f = AddM(f, v); + v = MulByPow2(state->LFSR_S13, 17); + f = AddM(f, v); + v = MulByPow2(state->LFSR_S15, 15); + f = AddM(f, v); + + /* update the state */ state->LFSR_S0 = state->LFSR_S1; state->LFSR_S1 = state->LFSR_S2; state->LFSR_S2 = state->LFSR_S3; @@ -122,7 +138,7 @@ void LFSRWithWorkMode(zuc_state_t *state) } /* BitReorganization */ -void BitReorganization(zuc_state_t *state) +void BitReorganization(zuc_state_t* state) { state->BRC_X0 = ((state->LFSR_S15 & 0x7FFF8000) << 1) | (state->LFSR_S14 & 0xFFFF); state->BRC_X1 = ((state->LFSR_S11 & 0xFFFF) << 16) | (state->LFSR_S9 >> 15); @@ -134,22 +150,24 @@ void BitReorganization(zuc_state_t *state) u32 L1(u32 X) { return (X ^ ROT(X, 2) ^ ROT(X, 10) ^ ROT(X, 18) ^ ROT(X, 24)); -} /* L2 */ +} +/* L2 */ u32 L2(u32 X) { return (X ^ ROT(X, 8) ^ ROT(X, 14) ^ ROT(X, 22) ^ ROT(X, 30)); } /* F */ -u32 F(zuc_state_t *state) +u32 F(zuc_state_t* state) { u32 W, W1, W2, u, v; - W = (state->BRC_X0 ^ state->F_R1) + state->F_R2; - W1 = state->F_R1 + state->BRC_X1; - W2 = state->F_R2 ^ state->BRC_X2; - u = L1((W1 << 16) | (W2 >> 16)); - v = L2((W2 << 16) | (W1 >> 16)); + W = (state->BRC_X0 ^ state->F_R1) + state->F_R2; + W1 = state->F_R1 + state->BRC_X1; + W2 = state->F_R2 ^ state->BRC_X2; + u = L1((W1 << 16) | (W2 >> 16)); + v = L2((W2 << 16) | (W1 >> 16)); + state->F_R1 = MAKEU32(S0[u >> 24], S1[(u >> 16) & 0xFF], S0[(u >> 8) & 0xFF], S1[u & 0xFF]); state->F_R2 = MAKEU32(S0[v >> 24], S1[(v >> 16) & 0xFF], S0[(v >> 8) & 0xFF], S1[v & 0xFF]); return W; @@ -157,10 +175,11 @@ u32 F(zuc_state_t *state) /* initialize */ -void zuc_initialize(zuc_state_t *state, u8* k, u8* iv) +void zuc_initialize(zuc_state_t* state, u8* k, u8* iv) { u32 w, nCount; - /* expand key */ + + /* expand key */ state->LFSR_S0 = MAKEU31(k[0], EK_d[0], iv[0]); state->LFSR_S1 = MAKEU31(k[1], EK_d[1], iv[1]); state->LFSR_S2 = MAKEU31(k[2], EK_d[2], iv[2]); @@ -176,11 +195,12 @@ void zuc_initialize(zuc_state_t *state, u8* k, u8* iv) state->LFSR_S12 = MAKEU31(k[12], EK_d[12], iv[12]); state->LFSR_S13 = MAKEU31(k[13], EK_d[13], iv[13]); state->LFSR_S14 = MAKEU31(k[14], EK_d[14], iv[14]); - state->LFSR_S15 = MAKEU31(k[15], EK_d[15], iv[15]); + state->LFSR_S15 = MAKEU31(k[15], EK_d[15], iv[15]); + /* set F_R1 and F_R2 to zero */ - state->F_R1 = 0; - state->F_R2 = 0; - nCount = 32; + state->F_R1 = 0; + state->F_R2 = 0; + nCount = 32; while (nCount > 0) { BitReorganization(state); w = F(state); @@ -189,7 +209,7 @@ void zuc_initialize(zuc_state_t *state, u8* k, u8* iv) } } -void zuc_generate_keystream(zuc_state_t *state, int key_stream_len, u32* p_keystream) +void zuc_generate_keystream(zuc_state_t* state, int key_stream_len, u32* p_keystream) { int i; { @@ -202,4 +222,4 @@ void zuc_generate_keystream(zuc_state_t *state, int key_stream_len, u32* p_keyst p_keystream[i] = F(state) ^ state->BRC_X3; LFSRWithWorkMode(state); } -} \ No newline at end of file +} diff --git a/lib/test/common/test_eea2.cc b/lib/test/common/test_eea2.cc index 5fd7c1868..c3969c080 100644 --- a/lib/test/common/test_eea2.cc +++ b/lib/test/common/test_eea2.cc @@ -19,12 +19,12 @@ * */ -#include -#include #include +#include +#include -#include "srslte/srslte.h" #include "srslte/common/liblte_security.h" +#include "srslte/srslte.h" /* * Prototypes diff --git a/lib/test/common/test_eia3.cc b/lib/test/common/test_eia3.cc index dd3629f52..6fbdb9b30 100644 --- a/lib/test/common/test_eia3.cc +++ b/lib/test/common/test_eia3.cc @@ -99,7 +99,6 @@ void test_set_3() liblte_security_128_eia3(key, count, bearer, direction, msg, len_bits, mac); int i; - bool failed = false; for (i = 0; i < 4; i++) { if (mac[i] != expected_mac[i]) { diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index cc6915d01..483ab7ec5 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -2015,9 +2015,8 @@ bool rrc::ue::select_security_algorithms() break; case srslte::CIPHERING_ALGORITHM_ID_128_EEA3: // “third bit” – 128-EEA3, - if (security_capabilities.encryptionAlgorithms - .buffer[srslte::CIPHERING_ALGORITHM_ID_128_EEA3 - 1]) { - cipher_algo = srslte::CIPHERING_ALGORITHM_ID_128_EEA3; + if (security_capabilities.encryptionAlgorithms.buffer[srslte::CIPHERING_ALGORITHM_ID_128_EEA3 - 1]) { + cipher_algo = srslte::CIPHERING_ALGORITHM_ID_128_EEA3; enc_algo_found = true; parent->rrc_log->info("Selected EEA3 as RRC encryption algorithm\n"); break; @@ -2063,7 +2062,7 @@ bool rrc::ue::select_security_algorithms() case srslte::INTEGRITY_ALGORITHM_ID_128_EIA3: // “third bit” – 128-EIA3, if (security_capabilities.integrityProtectionAlgorithms.buffer[srslte::INTEGRITY_ALGORITHM_ID_128_EIA3 - 1]) { - integ_algo = srslte::INTEGRITY_ALGORITHM_ID_128_EIA3; + integ_algo = srslte::INTEGRITY_ALGORITHM_ID_128_EIA3; integ_algo_found = true; parent->rrc_log->info("Selected EIA3 as RRC integrity algorithm.\n"); } else { diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index 03220958d..18de1c7cb 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -949,18 +949,18 @@ void rrc::send_con_restablish_request() break; case INTEGRITY_ALGORITHM_ID_128_EIA2: security_128_eia2(&k_rrc_int[16], - 0xffffffff, // 32-bit all to ones - 0x1f, // 5-bit all to ones - 1, // 1-bit to one + 0xffffffff, // 32-bit all to ones + 0x1f, // 5-bit all to ones + 1, // 1-bit to one varShortMAC_packed, N_bytes, mac_key); 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 + 0xffffffff, // 32-bit all to ones + 0x1f, // 5-bit all to ones + 1, // 1-bit to one varShortMAC_packed, N_bytes, mac_key); diff --git a/srsue/src/stack/upper/nas.cc b/srsue/src/stack/upper/nas.cc index 91a4e16d0..d2e31f670 100644 --- a/srsue/src/stack/upper/nas.cc +++ b/srsue/src/stack/upper/nas.cc @@ -639,7 +639,7 @@ void nas::integrity_generate(uint8_t *key_128, case INTEGRITY_ALGORITHM_ID_128_EIA2: security_128_eia2(key_128, count, - 0, // Bearer always 0 for NAS + 0, // Bearer always 0 for NAS direction, msg, msg_len, @@ -648,7 +648,7 @@ void nas::integrity_generate(uint8_t *key_128, case INTEGRITY_ALGORITHM_ID_128_EIA3: security_128_eia3(key_128, count, - 0, // Bearer always 0 for NAS + 0, // Bearer always 0 for NAS direction, msg, msg_len, @@ -713,31 +713,31 @@ void nas::cipher_encrypt(byte_buffer_t* pdu) &pdu->msg[6], pdu->N_bytes-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; case CIPHERING_ALGORITHM_ID_128_EEA2: - security_128_eea2(&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; + security_128_eea2(&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; 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; + 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: - nas_log->error("Ciphering algorithm not known\n"); - break; + nas_log->error("Ciphering algorithm not known\n"); + break; } } @@ -759,30 +759,30 @@ void nas::cipher_decrypt(byte_buffer_t* pdu) memcpy(&pdu->msg[6], &tmp_pdu.msg[6], pdu->N_bytes-6); break; case CIPHERING_ALGORITHM_ID_128_EEA2: - security_128_eea2(&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; + security_128_eea2(&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; 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: - nas_log->error("Ciphering algorithms not known\n"); - break; + 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: + nas_log->error("Ciphering algorithms not known\n"); + break; } } diff --git a/srsue/test/upper/nas_test.cc b/srsue/test/upper/nas_test.cc index 046e7314f..f36cd7eb9 100644 --- a/srsue/test/upper/nas_test.cc +++ b/srsue/test/upper/nas_test.cc @@ -47,24 +47,20 @@ using namespace asn1::rrc; } \ } -uint8_t auth_request_pdu[] = { 0x07, 0x52, 0x01, 0x0c, 0x63, 0xa8, 0x54, 0x13, 0xe6, 0xa4, - 0xce, 0xd9, 0x86, 0xfb, 0xe5, 0xce, 0x9b, 0x62, 0x5e, 0x10, - 0x67, 0x57, 0xb3, 0xc2, 0xb9, 0x70, 0x90, 0x01, 0x0c, 0x72, - 0x8a, 0x67, 0x57, 0x92, 0x52, 0xb8 }; - -uint8_t sec_mode_command_pdu[] = { 0x37, 0x4e, 0xfd, 0x57, 0x11, 0x00, 0x07, 0x5d, 0x02, 0x01, - 0x02, 0xf0, 0x70, 0xc1 }; - -uint8_t attach_accept_pdu[] = { 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x42, 0x01, 0x3e, - 0x06, 0x00, 0x00, 0xf1, 0x10, 0x00, 0x01, 0x00, 0x2a, 0x52, - 0x01, 0xc1, 0x01, 0x04, 0x1b, 0x07, 0x74, 0x65, 0x73, 0x74, - 0x31, 0x32, 0x33, 0x06, 0x6d, 0x6e, 0x63, 0x30, 0x30, 0x31, - 0x06, 0x6d, 0x63, 0x63, 0x30, 0x30, 0x31, 0x04, 0x67, 0x70, - 0x72, 0x73, 0x05, 0x01, 0xc0, 0xa8, 0x05, 0x02, 0x27, 0x01, - 0x80, 0x50, 0x0b, 0xf6, 0x00, 0xf1, 0x10, 0x80, 0x01, 0x01, - 0x35, 0x16, 0x6d, 0xbc, 0x64, 0x01, 0x00 }; - -uint8_t esm_info_req_pdu[] = { 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x5a, 0xd9 }; +uint8_t auth_request_pdu[] = {0x07, 0x52, 0x01, 0x0c, 0x63, 0xa8, 0x54, 0x13, 0xe6, 0xa4, 0xce, 0xd9, + 0x86, 0xfb, 0xe5, 0xce, 0x9b, 0x62, 0x5e, 0x10, 0x67, 0x57, 0xb3, 0xc2, + 0xb9, 0x70, 0x90, 0x01, 0x0c, 0x72, 0x8a, 0x67, 0x57, 0x92, 0x52, 0xb8}; + +uint8_t sec_mode_command_pdu[] = {0x37, 0x4e, 0xfd, 0x57, 0x11, 0x00, 0x07, 0x5d, 0x02, 0x01, 0x02, 0xf0, 0x70, 0xc1}; + +uint8_t attach_accept_pdu[] = {0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x42, 0x01, 0x3e, 0x06, 0x00, 0x00, + 0xf1, 0x10, 0x00, 0x01, 0x00, 0x2a, 0x52, 0x01, 0xc1, 0x01, 0x04, 0x1b, 0x07, + 0x74, 0x65, 0x73, 0x74, 0x31, 0x32, 0x33, 0x06, 0x6d, 0x6e, 0x63, 0x30, 0x30, + 0x31, 0x06, 0x6d, 0x63, 0x63, 0x30, 0x30, 0x31, 0x04, 0x67, 0x70, 0x72, 0x73, + 0x05, 0x01, 0xc0, 0xa8, 0x05, 0x02, 0x27, 0x01, 0x80, 0x50, 0x0b, 0xf6, 0x00, + 0xf1, 0x10, 0x80, 0x01, 0x01, 0x35, 0x16, 0x6d, 0xbc, 0x64, 0x01, 0x00}; + +uint8_t esm_info_req_pdu[] = {0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x5a, 0xd9}; uint8_t activate_dedicated_eps_bearer_pdu[] = {0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0xc5, 0x05, 0x01, 0x01, 0x07, 0x21, 0x31, 0x00, 0x03, 0x40, 0x08, 0xae,