diff --git a/lib/include/srslte/common/liblte_security.h b/lib/include/srslte/common/liblte_security.h index e7138fb0b..9a5f1feea 100644 --- a/lib/include/srslte/common/liblte_security.h +++ b/lib/include/srslte/common/liblte_security.h @@ -180,6 +180,8 @@ LIBLTE_ERROR_ENUM liblte_security_128_eia2( uint8* key, uint32 count, uint8 bearer, uint8 direction, uint8* msg, uint32 msg_len, uint8* mac); LIBLTE_ERROR_ENUM liblte_security_128_eia2( uint8* key, uint32 count, uint8 bearer, uint8 direction, LIBLTE_BIT_MSG_STRUCT* msg, uint8* mac); +LIBLTE_ERROR_ENUM liblte_security_128_eia3( + uint8* key, uint32 count, uint8 bearer, uint8 direction, uint8* msg, uint32 msg_len, uint8* mac); /********************************************************************* Name: liblte_security_encryption_eea1 @@ -227,22 +229,11 @@ LIBLTE_ERROR_ENUM liblte_security_encryption_eea2( LIBLTE_ERROR_ENUM liblte_security_decryption_eea2( uint8* key, uint32 count, uint8 bearer, uint8 direction, uint8* ct, uint32 ct_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 liblte_security_decryption_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 liblte_security_decryption_eea3( + uint8* key, uint32 count, uint8 bearer, uint8 direction, uint8* msg, uint32 msg_len, uint8* out); /********************************************************************* Name: liblte_security_milenage_f1 diff --git a/lib/include/srslte/common/security.h b/lib/include/srslte/common/security.h index 2345079bd..ee897ba50 100644 --- a/lib/include/srslte/common/security.h +++ b/lib/include/srslte/common/security.h @@ -115,6 +115,14 @@ uint8_t security_128_eia2( uint8_t *key, 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); @@ -139,6 +147,14 @@ uint8_t security_128_eea2(uint8_t *key, 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 *****************************************************************************/ diff --git a/lib/src/common/liblte_security.cc b/lib/src/common/liblte_security.cc index 5a1b528d3..c34d7a978 100644 --- a/lib/src/common/liblte_security.cc +++ b/lib/src/common/liblte_security.cc @@ -808,6 +808,91 @@ LIBLTE_ERROR_ENUM liblte_security_128_eia2( return (err); } +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; +} + +u8 GET_BIT(uint8_t * DATA, u32 i) +{ + 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; + int32 i; + 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 & 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 + 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 (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); +} + /********************************************************************* Name: liblte_security_encryption_eea1 @@ -971,9 +1056,7 @@ LIBLTE_ERROR_ENUM liblte_security_encryption_eea3(uint8 *key, uint8 *out) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - S3G_STATE state, *state_ptr; - uint32 k[] = {0,0,0,0}; - uint32 iv[] = {0,0,0,0}; + uint8_t iv[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; uint32 *ks; int32 i; @@ -983,21 +1066,10 @@ LIBLTE_ERROR_ENUM liblte_security_encryption_eea3(uint8 *key, msg != NULL && out != NULL) { - state_ptr = &state; msg_len_block_8 = (msg_len + 7) / 8; msg_len_block_32 = (msg_len + 31) / 32; - // Transform key - for (i = 3; i >= 0; i--) { - k[i] = (key[4 * (3 - i) + 0] << 24) | - (key[4 * (3 - i) + 1] << 16) | - (key[4 * (3 - i) + 2] << 8) | - (key[4 * (3 - i) + 3]); - } - - // Construct iv - uint8_t iv[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - + // Construct IV iv[0] = (count >> 24) & 0xFF; iv[1] = (count >> 16) & 0xFF; iv[2] = (count >> 8) & 0xFF; diff --git a/lib/src/common/security.cc b/lib/src/common/security.cc index 9bf21766e..50eb0281c 100644 --- a/lib/src/common/security.cc +++ b/lib/src/common/security.cc @@ -150,21 +150,16 @@ 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) { - return liblte_security_128_eia2(key, - count, - bearer, - direction, - msg, - msg_len, - mac); + return liblte_security_128_eia3(key, count, bearer, direction, msg, msg_len, mac); } uint8_t security_md5(const uint8_t *input, size_t len, uint8_t *output) @@ -220,6 +215,26 @@ uint8_t security_128_eea2(uint8_t *key, 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); +} + + + /****************************************************************************** * Authentication *****************************************************************************/ diff --git a/lib/test/common/CMakeLists.txt b/lib/test/common/CMakeLists.txt index f4969e54d..ca9edf4c3 100644 --- a/lib/test/common/CMakeLists.txt +++ b/lib/test/common/CMakeLists.txt @@ -33,6 +33,10 @@ add_executable(test_eia1 test_eia1.cc) target_link_libraries(test_eia1 srslte_common srslte_phy ${CMAKE_THREAD_LIBS_INIT}) add_test(test_eia1 test_eia1) +add_executable(test_eia3 test_eia3.cc) +target_link_libraries(test_eia3 srslte_common) +add_test(test_eia3 test_eia3) + add_executable(test_eea1 test_eea1.cc) target_link_libraries(test_eea1 srslte_common srslte_phy ${CMAKE_THREAD_LIBS_INIT}) add_test(test_eea1 test_eea1) diff --git a/lib/test/common/test_eia3.cc b/lib/test/common/test_eia3.cc new file mode 100644 index 000000000..03345f3f6 --- /dev/null +++ b/lib/test/common/test_eia3.cc @@ -0,0 +1,58 @@ +/* + * Includes + */ + +#include +#include +#include +#include + +#include "srslte/srslte.h" +#include "srslte/common/security.h" +#include "srslte/common/liblte_security.h" + +/* + * Tests + * + * Document Reference: 33.401 V14.6.0 Annex C.4 + * + */ + +void test_set_1() +{ + uint8_t key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + uint32_t count = 0x0; + uint8_t bearer = 0x0; + uint8_t direction = 0; + uint32_t len_bits = 1; + uint32_t len_bytes = (len_bits + 7) / 8; + uint8_t msg[] = {0x00, 0x00, 0x00, 0x00}; + uint8_t mt[] = {0xc8, 0xa9, 0x59, 0x5e}; + + uint8_t mac[4]; + + // gen mac +// srslte::security_128_eia3(key, count, bearer, direction, msg, len_bytes, mac); + liblte_security_128_eia3(key, count, bearer, direction, msg, len_bits, mac); + int i; + + for(i=0; i<4; i++) { + printf("%x ", mac[i]); + } + + printf("\n"); + + for(i=0; i<4; i++) { + if(mac[i] != mt[i]){ + printf("Test Set 1: Failed\n"); + } + assert(mac[i] == mt[i]); + } + +} + + + +int main(int argc, char * argv[]) { + test_set_1(); +} \ No newline at end of file