Merge remote-tracking branch 'origin/bugfix-speedup-integrity' into integration_2024_w17
This commit is contained in:
@@ -2124,9 +2124,12 @@ pdcp_config_set_security(
|
||||
pdcp_pP->cipheringAlgorithm,
|
||||
pdcp_pP->integrityProtAlgorithm);
|
||||
|
||||
kRRCenc != NULL ? memcpy(pdcp_pP->kRRCenc, kRRCenc, 32) : memset(pdcp_pP->kRRCenc, 0, 32);
|
||||
kRRCint != NULL ? memcpy(pdcp_pP->kRRCint, kRRCint, 32) : memset(pdcp_pP->kRRCint, 0, 32);
|
||||
kUPenc != NULL ? memcpy(pdcp_pP->kUPenc, kUPenc, 32) : memset(pdcp_pP->kUPenc, 0, 32);
|
||||
kRRCenc != NULL ? memcpy(pdcp_pP->kRRCenc, kRRCenc+16, 16) : memset(pdcp_pP->kRRCenc, 0, 16);
|
||||
kRRCint != NULL ? memcpy(pdcp_pP->kRRCint, kRRCint+16, 16) : memset(pdcp_pP->kRRCint, 0, 16);
|
||||
kUPenc != NULL ? memcpy(pdcp_pP->kUPenc, kUPenc+16, 16) : memset(pdcp_pP->kUPenc, 0, 16);
|
||||
|
||||
pdcp_pP->security_container_rrc = stream_security_container_init(pdcp_pP->cipheringAlgorithm, pdcp_pP->integrityProtAlgorithm, pdcp_pP->kRRCenc, pdcp_pP->kRRCint);
|
||||
pdcp_pP->security_container_up = stream_security_container_init(pdcp_pP->cipheringAlgorithm, 0, pdcp_pP->kUPenc, NULL);
|
||||
|
||||
/* Activate security */
|
||||
pdcp_pP->security_activated = 1;
|
||||
@@ -2196,6 +2199,8 @@ void rrc_pdcp_config_req (
|
||||
pdcp_p->last_submitted_pdcp_rx_sn = 4095;
|
||||
pdcp_p->seq_num_size = 0;
|
||||
pdcp_p->first_missing_pdu = -1;
|
||||
stream_security_container_delete(pdcp_p->security_container_rrc);
|
||||
stream_security_container_delete(pdcp_p->security_container_up);
|
||||
pdcp_p->security_activated = 0;
|
||||
h_rc = hashtable_remove(pdcp_coll_p, key);
|
||||
break;
|
||||
|
||||
@@ -181,9 +181,12 @@ typedef struct pdcp_s {
|
||||
* Control-Plane RRC integrity key
|
||||
* These keys are configured by RRC layer
|
||||
*/
|
||||
uint8_t kUPenc[32];
|
||||
uint8_t kRRCint[32];
|
||||
uint8_t kRRCenc[32];
|
||||
uint8_t kUPenc[16];
|
||||
uint8_t kRRCint[16];
|
||||
uint8_t kRRCenc[16];
|
||||
|
||||
stream_security_container_t *security_container_rrc;
|
||||
stream_security_container_t *security_container_up;
|
||||
|
||||
uint8_t security_activated;
|
||||
|
||||
|
||||
@@ -112,6 +112,7 @@ pdcp_apply_security(
|
||||
{
|
||||
uint8_t *buffer_encrypted = NULL;
|
||||
nas_stream_cipher_t encrypt_params = {0};
|
||||
stream_security_container_t *container;
|
||||
|
||||
DevAssert(pdcp_pP != NULL);
|
||||
DevAssert(pdcp_pdu_buffer != NULL);
|
||||
@@ -122,7 +123,11 @@ pdcp_apply_security(
|
||||
encrypt_params.direction = (pdcp_pP->is_ue == 1) ? SECU_DIRECTION_UPLINK : SECU_DIRECTION_DOWNLINK;
|
||||
encrypt_params.bearer = rb_id - 1;
|
||||
encrypt_params.count = pdcp_get_next_count_tx(pdcp_pP, srb_flagP, current_sn);
|
||||
encrypt_params.key_length = 16;
|
||||
|
||||
if (srb_flagP)
|
||||
container = pdcp_pP->security_container_rrc;
|
||||
else
|
||||
container = pdcp_pP->security_container_up;
|
||||
|
||||
if (srb_flagP) {
|
||||
/* SRBs */
|
||||
@@ -133,7 +138,7 @@ pdcp_apply_security(
|
||||
|
||||
encrypt_params.message = pdcp_pdu_buffer;
|
||||
encrypt_params.blength = (pdcp_header_len + sdu_buffer_size) << 3;
|
||||
encrypt_params.key = pdcp_pP->kRRCint + 16; // + 128;
|
||||
encrypt_params.context = container->integrity_context;
|
||||
|
||||
mac_i = &pdcp_pdu_buffer[pdcp_header_len + sdu_buffer_size];
|
||||
|
||||
@@ -142,15 +147,13 @@ pdcp_apply_security(
|
||||
stream_compute_integrity(pdcp_pP->integrityProtAlgorithm,
|
||||
&encrypt_params,
|
||||
mac_i);
|
||||
|
||||
encrypt_params.key = pdcp_pP->kRRCenc; // + 128 // bit key
|
||||
} else {
|
||||
LOG_D(PDCP, "[OSA][RB %ld] %s Applying user-plane security\n",
|
||||
rb_id, (pdcp_pP->is_ue != 0) ? "UE -> eNB" : "eNB -> UE");
|
||||
|
||||
encrypt_params.key = pdcp_pP->kUPenc;// + 128;
|
||||
}
|
||||
|
||||
encrypt_params.context = container->ciphering_context;
|
||||
|
||||
encrypt_params.message = &pdcp_pdu_buffer[pdcp_header_len];
|
||||
encrypt_params.blength = sdu_buffer_size << 3;
|
||||
|
||||
@@ -180,6 +183,7 @@ pdcp_validate_security(
|
||||
{
|
||||
uint8_t *buffer_decrypted = NULL;
|
||||
nas_stream_cipher_t decrypt_params = {0};
|
||||
stream_security_container_t *container;
|
||||
|
||||
DevAssert(pdcp_pP != NULL);
|
||||
|
||||
@@ -195,17 +199,17 @@ pdcp_validate_security(
|
||||
decrypt_params.count = pdcp_get_next_count_rx(pdcp_pP, srb_flagP, hfn, sn);
|
||||
decrypt_params.message = &pdcp_pdu_buffer[pdcp_header_len];
|
||||
decrypt_params.blength = (sdu_buffer_size - pdcp_header_len) << 3;
|
||||
decrypt_params.key_length = 16;
|
||||
|
||||
if (srb_flagP) {
|
||||
LOG_D(PDCP, "[OSA][RB %ld] %s Validating control-plane security\n", rb_id, (pdcp_pP->is_ue != 0) ? "eNB -> UE" : "UE -> eNB");
|
||||
decrypt_params.key = pdcp_pP->kRRCenc;// + 128;
|
||||
container = pdcp_pP->security_container_rrc;
|
||||
} else {
|
||||
LOG_D(PDCP, "[OSA][RB %ld] %s Validating user-plane security\n", rb_id, (pdcp_pP->is_ue != 0) ? "eNB -> UE" : "UE -> eNB");
|
||||
decrypt_params.key = pdcp_pP->kUPenc;// + 128;
|
||||
container = pdcp_pP->security_container_up;
|
||||
}
|
||||
|
||||
/* Uncipher the block */
|
||||
decrypt_params.context = container->ciphering_context;
|
||||
stream_compute_encrypt(pdcp_pP->cipheringAlgorithm, &decrypt_params, buffer_decrypted);
|
||||
|
||||
if (!IS_SOFTMODEM_IQPLAYER) {
|
||||
@@ -213,7 +217,7 @@ pdcp_validate_security(
|
||||
/* Now check the integrity of the complete PDU */
|
||||
decrypt_params.message = pdcp_pdu_buffer;
|
||||
decrypt_params.blength = sdu_buffer_size << 3;
|
||||
decrypt_params.key = pdcp_pP->kRRCint + 16;// 128;
|
||||
decrypt_params.context = container->integrity_context;
|
||||
|
||||
if (pdcp_pP->integrityProtAlgorithm != EIA0_ALG_ID) {
|
||||
uint8_t result[4] = {0};
|
||||
@@ -221,10 +225,9 @@ pdcp_validate_security(
|
||||
|
||||
if (memcmp(result, &pdcp_pdu_buffer[sdu_buffer_size], 4) != 0) {
|
||||
LOG_E(PDCP,
|
||||
"[OSA][RB %ld] %s failed to validate MAC-I (key %llx) of incoming PDU\n",
|
||||
"[OSA][RB %ld] %s failed to validate MAC-I of incoming PDU\n",
|
||||
rb_id,
|
||||
(pdcp_pP->is_ue != 0) ? "UE" : "eNB",
|
||||
((long long unsigned int *)decrypt_params.key)[0]);
|
||||
(pdcp_pP->is_ue != 0) ? "UE" : "eNB");
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "nr_pdcp_sdu.h"
|
||||
#include "openair2/RRC/NR/rrc_gNB_radio_bearers.h"
|
||||
#include "openair3/SECU/secu_defs.h"
|
||||
|
||||
/* PDCP Formats according to clause 6.2 of 3GPP TS 38.323 */
|
||||
/* SN Size applicable to SRBs, UM DRBs and AM DRBs */
|
||||
@@ -151,16 +152,17 @@ typedef struct nr_pdcp_entity_t {
|
||||
int integrity_algorithm;
|
||||
unsigned char ciphering_key[16];
|
||||
unsigned char integrity_key[16];
|
||||
void *security_context;
|
||||
void (*cipher)(void *security_context,
|
||||
stream_security_context_t *security_context;
|
||||
void (*cipher)(stream_security_context_t *security_context,
|
||||
unsigned char *buffer, int length,
|
||||
int bearer, int count, int direction);
|
||||
void (*free_security)(void *security_context);
|
||||
void *integrity_context;
|
||||
void (*integrity)(void *integrity_context, unsigned char *out,
|
||||
void (*free_security)(stream_security_context_t *security_context);
|
||||
stream_security_context_t *integrity_context;
|
||||
void (*integrity)(stream_security_context_t *integrity_context,
|
||||
unsigned char *out,
|
||||
unsigned char *buffer, int length,
|
||||
int bearer, int count, int direction);
|
||||
void (*free_integrity)(void *integrity_context);
|
||||
void (*free_integrity)(stream_security_context_t *integrity_context);
|
||||
/* security/integrity algorithms need to know uplink/downlink information
|
||||
* which is reverse for gnb and ue, so we need to know if this
|
||||
* pdcp entity is for a gnb or an ue
|
||||
|
||||
@@ -28,24 +28,23 @@
|
||||
#include "openair3/SECU/secu_defs.h"
|
||||
#include "openair3/SECU/key_nas_deriver.h"
|
||||
|
||||
void *nr_pdcp_integrity_nia1_init(unsigned char *integrity_key)
|
||||
stream_security_context_t *nr_pdcp_integrity_nia1_init(unsigned char *integrity_key)
|
||||
{
|
||||
nas_stream_cipher_t *ret;
|
||||
|
||||
ret = calloc(1, sizeof(*ret)); if (ret == NULL) abort();
|
||||
ret->key = malloc(16); if (ret->key == NULL) abort();
|
||||
memcpy(ret->key, integrity_key, 16);
|
||||
ret->key_length = 16; /* unused */
|
||||
ret->context = malloc(16); if (ret->context == NULL) abort();
|
||||
memcpy(ret->context, integrity_key, 16);
|
||||
|
||||
return ret;
|
||||
return (stream_security_context_t *)ret;
|
||||
}
|
||||
|
||||
void nr_pdcp_integrity_nia1_integrity(void *integrity_context,
|
||||
void nr_pdcp_integrity_nia1_integrity(stream_security_context_t *integrity_context,
|
||||
unsigned char *out,
|
||||
unsigned char *buffer, int length,
|
||||
int bearer, int count, int direction)
|
||||
{
|
||||
nas_stream_cipher_t *ctx = integrity_context;
|
||||
nas_stream_cipher_t *ctx = (nas_stream_cipher_t *)integrity_context;
|
||||
|
||||
ctx->message = buffer;
|
||||
ctx->count = count;
|
||||
@@ -56,9 +55,9 @@ void nr_pdcp_integrity_nia1_integrity(void *integrity_context,
|
||||
stream_compute_integrity(EIA1_128_ALG_ID, ctx, out);
|
||||
}
|
||||
|
||||
void nr_pdcp_integrity_nia1_free_integrity(void *integrity_context)
|
||||
void nr_pdcp_integrity_nia1_free_integrity(stream_security_context_t *integrity_context)
|
||||
{
|
||||
nas_stream_cipher_t *ctx = integrity_context;
|
||||
free(ctx->key);
|
||||
nas_stream_cipher_t *ctx = (nas_stream_cipher_t *)integrity_context;
|
||||
free(ctx->context);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
@@ -22,13 +22,15 @@
|
||||
#ifndef _NR_PDCP_INTEGRITY_NIA1_H_
|
||||
#define _NR_PDCP_INTEGRITY_NIA1_H_
|
||||
|
||||
void *nr_pdcp_integrity_nia1_init(unsigned char *integrity_key);
|
||||
#include "openair3/SECU/secu_defs.h"
|
||||
|
||||
void nr_pdcp_integrity_nia1_integrity(void *integrity_context,
|
||||
stream_security_context_t *nr_pdcp_integrity_nia1_init(unsigned char *integrity_key);
|
||||
|
||||
void nr_pdcp_integrity_nia1_integrity(stream_security_context_t *integrity_context,
|
||||
unsigned char *out,
|
||||
unsigned char *buffer, int length,
|
||||
int bearer, int count, int direction);
|
||||
|
||||
void nr_pdcp_integrity_nia1_free_integrity(void *integrity_context);
|
||||
void nr_pdcp_integrity_nia1_free_integrity(stream_security_context_t *integrity_context);
|
||||
|
||||
#endif /* _NR_PDCP_INTEGRITY_NIA1_H_ */
|
||||
|
||||
@@ -30,29 +30,25 @@
|
||||
#include "openair3/SECU/aes_128.h"
|
||||
#include "openair3/SECU/aes_128_cbc_cmac.h"
|
||||
|
||||
void *nr_pdcp_integrity_nia2_init(uint8_t integrity_key[16])
|
||||
stream_security_context_t *nr_pdcp_integrity_nia2_init(uint8_t integrity_key[16])
|
||||
{
|
||||
// This is a hack. Reduce the 3 functions to just cipher?
|
||||
// No. The overhead is x8 times more. Don't change before measuring
|
||||
// return integrity_key;
|
||||
cbc_cmac_ctx_t* ctx = calloc(1, sizeof(cbc_cmac_ctx_t));
|
||||
AssertFatal(ctx, "Memory exhausted");
|
||||
|
||||
*ctx = init_aes_128_cbc_cmac(integrity_key);
|
||||
return ctx;
|
||||
return (stream_security_context_t *)ctx;
|
||||
}
|
||||
|
||||
void nr_pdcp_integrity_nia2_integrity(void *integrity_context, unsigned char *out, unsigned char *buffer, int length, int bearer, int count, int direction)
|
||||
void nr_pdcp_integrity_nia2_integrity(stream_security_context_t *integrity_context, unsigned char *out, unsigned char *buffer, int length, int bearer, int count, int direction)
|
||||
{
|
||||
DevAssert(integrity_context != NULL);
|
||||
DevAssert(out != NULL);
|
||||
DevAssert(buffer != NULL);
|
||||
DevAssert(length > -1);
|
||||
// Strange range: [1-32] instead of [0-31]
|
||||
DevAssert(bearer > 0 && bearer < 33);
|
||||
DevAssert(count > -1);
|
||||
|
||||
cbc_cmac_ctx_t* ctx = (cbc_cmac_ctx_t*)integrity_context;
|
||||
cbc_cmac_ctx_t *ctx = (cbc_cmac_ctx_t *)integrity_context;
|
||||
|
||||
aes_128_t k_iv = {0};
|
||||
memcpy(&k_iv.key, ctx->key, sizeof(k_iv.key));
|
||||
@@ -64,18 +60,13 @@ void nr_pdcp_integrity_nia2_integrity(void *integrity_context, unsigned char *ou
|
||||
uint8_t result[16] = {0};
|
||||
byte_array_t msg = {.buf = buffer, .len = length};
|
||||
|
||||
cipher_aes_128_cbc_cmac((cbc_cmac_ctx_t*)integrity_context, &k_iv, msg, sizeof(result), result);
|
||||
//aes_128_cbc_cmac(&k_iv, msg, sizeof(result), result);
|
||||
cipher_aes_128_cbc_cmac(ctx, &k_iv, msg, sizeof(result), result);
|
||||
|
||||
// AES CMAC (RFC 4493) outputs 128 bits but NR PDCP PDUs have a MAC-I of
|
||||
// 32 bits (see 38.323 6.2). RFC 4493 2.1 says to truncate most significant
|
||||
// bit first (so seems to say 33.401 B.2.3)
|
||||
// Precondition: out should have enough space...
|
||||
memcpy(out, result, 4);
|
||||
}
|
||||
|
||||
void nr_pdcp_integrity_nia2_free_integrity(void *integrity_context)
|
||||
void nr_pdcp_integrity_nia2_free_integrity(stream_security_context_t *integrity_context)
|
||||
{
|
||||
free( ( cbc_cmac_ctx_t*) integrity_context);
|
||||
free_aes_128_cbc_cmac((cbc_cmac_ctx_t *)integrity_context);
|
||||
free(integrity_context);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,13 +24,15 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void *nr_pdcp_integrity_nia2_init(uint8_t integrity_key[16]);
|
||||
#include "openair3/SECU/secu_defs.h"
|
||||
|
||||
void nr_pdcp_integrity_nia2_integrity(void *integrity_context,
|
||||
stream_security_context_t *nr_pdcp_integrity_nia2_init(uint8_t integrity_key[16]);
|
||||
|
||||
void nr_pdcp_integrity_nia2_integrity(stream_security_context_t *integrity_context,
|
||||
unsigned char *out,
|
||||
unsigned char *buffer, int length,
|
||||
int bearer, int count, int direction);
|
||||
|
||||
void nr_pdcp_integrity_nia2_free_integrity(void *integrity_context);
|
||||
void nr_pdcp_integrity_nia2_free_integrity(stream_security_context_t *integrity_context);
|
||||
|
||||
#endif /* _NR_PDCP_INTEGRITY_NIA2_H_ */
|
||||
|
||||
@@ -29,14 +29,14 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void *nr_pdcp_security_nea2_init(unsigned char *ciphering_key)
|
||||
stream_security_context_t *nr_pdcp_security_nea2_init(unsigned char *ciphering_key)
|
||||
{
|
||||
// This is a hack, IMO init, cipher and free functions should be reduced to cipher.
|
||||
// Test show a ~10% more processing time
|
||||
return ciphering_key;
|
||||
return (stream_security_context_t *)ciphering_key;
|
||||
}
|
||||
|
||||
void nr_pdcp_security_nea2_cipher(void *security_context, unsigned char *buffer, int length, int bearer, int count, int direction)
|
||||
void nr_pdcp_security_nea2_cipher(stream_security_context_t *security_context, unsigned char *buffer, int length, int bearer, int count, int direction)
|
||||
{
|
||||
DevAssert(security_context != NULL);
|
||||
DevAssert(buffer != NULL);
|
||||
@@ -62,7 +62,7 @@ void nr_pdcp_security_nea2_cipher(void *security_context, unsigned char *buffer,
|
||||
memcpy(buffer, out, length);
|
||||
}
|
||||
|
||||
void nr_pdcp_security_nea2_free_security(void *security_context)
|
||||
void nr_pdcp_security_nea2_free_security(stream_security_context_t *security_context)
|
||||
{
|
||||
(void)security_context;
|
||||
}
|
||||
|
||||
@@ -22,12 +22,14 @@
|
||||
#ifndef _NR_PDCP_SECURITY_NEA2_H_
|
||||
#define _NR_PDCP_SECURITY_NEA2_H_
|
||||
|
||||
void *nr_pdcp_security_nea2_init(unsigned char *ciphering_key);
|
||||
#include "openair3/SECU/secu_defs.h"
|
||||
|
||||
void nr_pdcp_security_nea2_cipher(void *security_context,
|
||||
stream_security_context_t *nr_pdcp_security_nea2_init(unsigned char *ciphering_key);
|
||||
|
||||
void nr_pdcp_security_nea2_cipher(stream_security_context_t *security_context,
|
||||
unsigned char *buffer, int length,
|
||||
int bearer, int count, int direction);
|
||||
|
||||
void nr_pdcp_security_nea2_free_security(void *security_context);
|
||||
void nr_pdcp_security_nea2_free_security(stream_security_context_t *security_context);
|
||||
|
||||
#endif /* _NR_PDCP_SECURITY_NEA2_H_ */
|
||||
|
||||
Reference in New Issue
Block a user