mirror of https://github.com/PentHertz/srsLTE.git
Add EIA3 and test case
This commit is contained in:
parent
7e13860dd5
commit
d580a94dab
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*****************************************************************************/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
*****************************************************************************/
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
Loading…
Reference in New Issue