Add EIA3 and test case

This commit is contained in:
David Rupprecht 2019-04-10 13:15:23 +02:00 committed by Andre Puschmann
parent 7e13860dd5
commit d580a94dab
6 changed files with 200 additions and 44 deletions

View File

@ -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_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_decryption_eea3(
uint8* key, uint32 count, uint8 bearer, uint8 direction, uint8* msg, uint32 msg_len, uint8* out);
/*********************************************************************
Name: liblte_security_milenage_f1

View File

@ -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
*****************************************************************************/

View File

@ -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]<<ti) | (DATA[i/32+1]>>(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;

View File

@ -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);
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_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
*****************************************************************************/

View File

@ -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)

View File

@ -0,0 +1,58 @@
/*
* Includes
*/
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <sys/time.h>
#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();
}