bugfix: speedup integrity computation
The main work of this commit is to rewrite cipher_aes_128_cbc_cmac() which was too slow and created issues when running the 4G eNB on some machines (LLL when using a b210). Instead of creating the security context, use it, and delete it, all in cipher_aes_128_cbc_cmac(), we introduce the function init_aes_128_cbc_cmac() to create it, and we change cipher_aes_128_cbc_cmac() to just use it, and we also adapt free_aes_128_cbc_cmac(). The function aes_128_cbc_cmac() is removed, it does not follow the new init/use/free API. Doing so, on the primary test machine used to do this work (a powerful and fast machine where it is possible to set the CPUs' frequencies) it was possible to limit the CPUs' frequencies to 500 MHz (it was not possible to go lower) without any LLL (using a b210, quectel UE in idle, no data traffic, only periodic measurement reports). Before this commit, it was necessary to set a frequency of at least 1.8 GHz otherwise some LLL would appear. Then we need to adapt the rest of the code to take into account those changes. A notion of security container (stream_security_container_t) containing ciphering and integrity contexts is introduced. And the code is harmonized for, hopefully, better readability. The (opaque) type stream_security_context_t is introduced, used by both integrity and ciphering contexts. The idea is to use a init()/use()/free() API for all the security procedures, identical for all the ciphering and integrity procedures.
This commit is contained in:
@@ -1009,8 +1009,7 @@ static int _nas_message_decrypt(
|
||||
(direction == SECU_DIRECTION_UPLINK) ? "UPLINK":"DOWNLINK",
|
||||
(direction == SECU_DIRECTION_UPLINK) ? emm_security_context->ul_count.seq_num:emm_security_context->dl_count.seq_num,
|
||||
count);
|
||||
stream_cipher.key = emm_security_context->knas_enc.value;
|
||||
stream_cipher.key_length = AUTH_KNAS_ENC_SIZE;
|
||||
stream_cipher.context = emm_security_context->security_container->ciphering_context;
|
||||
stream_cipher.count = count;
|
||||
stream_cipher.bearer = 0x00; //33.401 section 8.1.1
|
||||
stream_cipher.direction = direction;
|
||||
@@ -1045,8 +1044,7 @@ static int _nas_message_decrypt(
|
||||
(direction == SECU_DIRECTION_UPLINK) ? "UPLINK":"DOWNLINK",
|
||||
(direction == SECU_DIRECTION_UPLINK) ? emm_security_context->ul_count.seq_num:emm_security_context->dl_count.seq_num,
|
||||
count);
|
||||
stream_cipher.key = emm_security_context->knas_enc.value;
|
||||
stream_cipher.key_length = AUTH_KNAS_ENC_SIZE;
|
||||
stream_cipher.context = emm_security_context->security_container->ciphering_context;
|
||||
stream_cipher.count = count;
|
||||
stream_cipher.bearer = 0x00; //33.401 section 8.1.1
|
||||
stream_cipher.direction = direction;
|
||||
@@ -1178,8 +1176,7 @@ static int _nas_message_encrypt(
|
||||
(direction == SECU_DIRECTION_UPLINK) ? "UPLINK":"DOWNLINK",
|
||||
(direction == SECU_DIRECTION_UPLINK) ? emm_security_context->ul_count.seq_num:emm_security_context->dl_count.seq_num,
|
||||
count);
|
||||
stream_cipher.key = emm_security_context->knas_enc.value;
|
||||
stream_cipher.key_length = AUTH_KNAS_ENC_SIZE;
|
||||
stream_cipher.context = emm_security_context->security_container->ciphering_context;
|
||||
stream_cipher.count = count;
|
||||
stream_cipher.bearer = 0x00; //33.401 section 8.1.1
|
||||
stream_cipher.direction = direction;
|
||||
@@ -1208,8 +1205,7 @@ static int _nas_message_encrypt(
|
||||
(direction == SECU_DIRECTION_UPLINK) ? "UPLINK":"DOWNLINK",
|
||||
(direction == SECU_DIRECTION_UPLINK) ? emm_security_context->ul_count.seq_num:emm_security_context->dl_count.seq_num,
|
||||
count);
|
||||
stream_cipher.key = emm_security_context->knas_enc.value;
|
||||
stream_cipher.key_length = AUTH_KNAS_ENC_SIZE;
|
||||
stream_cipher.context = emm_security_context->security_container->ciphering_context;
|
||||
stream_cipher.count = count;
|
||||
stream_cipher.bearer = 0x00; //33.401 section 8.1.1
|
||||
stream_cipher.direction = direction;
|
||||
@@ -1347,8 +1343,7 @@ static uint32_t _nas_message_get_mac(
|
||||
fflush(stderr);
|
||||
#endif
|
||||
|
||||
stream_cipher.key = emm_security_context->knas_int.value;
|
||||
stream_cipher.key_length = AUTH_KNAS_INT_SIZE;
|
||||
stream_cipher.context = emm_security_context->security_container->integrity_context;
|
||||
stream_cipher.count = count;
|
||||
stream_cipher.bearer = 0x00; //33.401 section 8.1.1
|
||||
stream_cipher.direction = direction;
|
||||
@@ -1391,8 +1386,7 @@ static uint32_t _nas_message_get_mac(
|
||||
(direction == SECU_DIRECTION_UPLINK) ? emm_security_context->ul_count.seq_num:emm_security_context->dl_count.seq_num,
|
||||
count);
|
||||
|
||||
stream_cipher.key = emm_security_context->knas_int.value;
|
||||
stream_cipher.key_length = AUTH_KNAS_INT_SIZE;
|
||||
stream_cipher.context = emm_security_context->security_container->integrity_context;
|
||||
stream_cipher.count = count;
|
||||
stream_cipher.bearer = 0x00; //33.401 section 8.1.1
|
||||
stream_cipher.direction = direction;
|
||||
|
||||
@@ -515,6 +515,10 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype
|
||||
static void generateAuthenticationResp(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, uint8_t *buf)
|
||||
{
|
||||
derive_ue_keys(buf, nas);
|
||||
/* todo: as of now, nia2 is hardcoded in derive_ue_keys(), remove this hardcoding, use NAS signalling for getting proper algorithm */
|
||||
/* todo: deal with ciphering for this stream_security_container_create() (handle ciphering in general) */
|
||||
/* todo: stream_security_container_delete() is not called anywhere, deal with that */
|
||||
nas->security_container = stream_security_container_create(0, 2 /* hardcoded: nia2 */, NULL, nas->security.knas_int);
|
||||
OctetString res;
|
||||
res.length = 16;
|
||||
res.value = calloc(1,16);
|
||||
@@ -598,8 +602,7 @@ static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
|
||||
|
||||
initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len);
|
||||
|
||||
stream_cipher.key = nas->security.knas_int;
|
||||
stream_cipher.key_length = 16;
|
||||
stream_cipher.context = nas->security_container->integrity_context;
|
||||
stream_cipher.count = nas->security.mm_counter++;
|
||||
stream_cipher.bearer = 1;
|
||||
stream_cipher.direction = 0;
|
||||
@@ -701,8 +704,7 @@ static void generateRegistrationComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
|
||||
}
|
||||
|
||||
initialNasMsg->length = length;
|
||||
stream_cipher.key = nas->security.knas_int;
|
||||
stream_cipher.key_length = 16;
|
||||
stream_cipher.context = nas->security_container->integrity_context;
|
||||
stream_cipher.count = nas->security.mm_counter++;
|
||||
stream_cipher.bearer = 1;
|
||||
stream_cipher.direction = 0;
|
||||
@@ -764,8 +766,7 @@ static void generateDeregistrationRequest(nr_ue_nas_t *nas, as_nas_info_t *initi
|
||||
initialNasMsg->length = security_header_len + mm_msg_encode(&sp_msg->plain.mm_msg, (uint8_t *)(initialNasMsg->data + security_header_len), size - security_header_len);
|
||||
|
||||
nas_stream_cipher_t stream_cipher = {
|
||||
.key = nas->security.knas_int,
|
||||
.key_length = 16,
|
||||
.context = nas->security_container->integrity_context,
|
||||
.count = nas->security.mm_counter++,
|
||||
.bearer = 1,
|
||||
.direction = 0,
|
||||
@@ -857,8 +858,7 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *
|
||||
|
||||
initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len);
|
||||
|
||||
stream_cipher.key = nas->security.knas_int;
|
||||
stream_cipher.key_length = 16;
|
||||
stream_cipher.context = nas->security_container->integrity_context;
|
||||
stream_cipher.count = nas->security.mm_counter++;
|
||||
stream_cipher.bearer = 1;
|
||||
stream_cipher.direction = 0;
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "as_message.h"
|
||||
#include "FGSUplinkNasTransport.h"
|
||||
#include <openair3/UICC/usim_interface.h>
|
||||
#include "secu_defs.h"
|
||||
|
||||
#define PLAIN_5GS_MSG 0b0000
|
||||
#define INTEGRITY_PROTECTED 0b0001
|
||||
@@ -98,6 +99,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
uicc_t *uicc;
|
||||
ue_sa_security_key_t security;
|
||||
stream_security_container_t *security_container;
|
||||
Guti5GSMobileIdentity_t *guti;
|
||||
bool termination_procedure;
|
||||
} nr_ue_nas_t;
|
||||
|
||||
@@ -258,6 +258,7 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi,
|
||||
LOG_TRACE(INFO,
|
||||
"EMM-PROC - Update Current security context");
|
||||
/* Release non-current security context */
|
||||
stream_security_container_delete(user->emm_data->security->security_container);
|
||||
_security_release(user->emm_data->security);
|
||||
user->emm_data->security = user->emm_data->non_current;
|
||||
/* Reset the uplink NAS COUNT counter */
|
||||
@@ -265,6 +266,12 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi,
|
||||
user->emm_data->security->ul_count.seq_num = 0;
|
||||
/* Set new security context indicator */
|
||||
security_context_is_new = true;
|
||||
/* create contexts */
|
||||
user->emm_data->security->security_container = stream_security_container_create(
|
||||
seea,
|
||||
seia,
|
||||
user->emm_data->non_current->knas_enc.value,
|
||||
user->emm_data->non_current->knas_int.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ Description Defines internal private data handled by EPS Mobility
|
||||
#include "commonDef.h"
|
||||
#include "networkDef.h"
|
||||
#include "securityDef.h"
|
||||
#include "openair3/SECU/secu_defs.h"
|
||||
|
||||
#include "OctetString.h"
|
||||
#include "nas_timer.h"
|
||||
@@ -138,6 +139,7 @@ typedef struct emm_security_context_s {
|
||||
//OctetString ksgsn; /* SGSN security key (mapped context) */
|
||||
OctetString knas_enc; /* NAS cyphering key */
|
||||
OctetString knas_int; /* NAS integrity key */
|
||||
stream_security_container_t *security_container; /* container for NAS security */
|
||||
struct count_s{
|
||||
uint32_t spare:8;
|
||||
uint32_t overflow:16;
|
||||
|
||||
Reference in New Issue
Block a user