Commit 9135d420 authored by Cedric Roux's avatar Cedric Roux

sa: nr pdcp: improve security

This commit implements integrity and security settings for nr pdcp. It will
only work for SRBs.

This commit has not been tested. It may fail to work completely. To be checked.
parent f916590e
...@@ -212,12 +212,20 @@ static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity, ...@@ -212,12 +212,20 @@ static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity,
header_size + size + integrity_size, sdu_id); header_size + size + integrity_size, sdu_id);
} }
static void nr_pdcp_entity_set_integrity_key(nr_pdcp_entity_t *entity, static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity,
char *key) int integrity_algorithm,
char *integrity_key,
int ciphering_algorithm,
char *ciphering_key)
{ {
LOG_E(PDCP, "%s: %d: %s: TODO? to remove?\n", __FILE__, __LINE__, __FUNCTION__); if (integrity_algorithm != -1)
exit(1); entity->integrity_algorithm = integrity_algorithm;
//memcpy(entity->integrity_key, key, 16); if (ciphering_algorithm != -1)
entity->ciphering_algorithm = ciphering_algorithm;
if (integrity_key != NULL)
memcpy(entity->integrity_key, integrity_key, 16);
if (ciphering_key != NULL)
memcpy(entity->ciphering_key, ciphering_key, 16);
} }
static void check_t_reordering(nr_pdcp_entity_t *entity) static void check_t_reordering(nr_pdcp_entity_t *entity)
...@@ -312,7 +320,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( ...@@ -312,7 +320,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
ret->recv_pdu = nr_pdcp_entity_recv_pdu; ret->recv_pdu = nr_pdcp_entity_recv_pdu;
ret->recv_sdu = nr_pdcp_entity_recv_sdu; ret->recv_sdu = nr_pdcp_entity_recv_sdu;
ret->set_integrity_key = nr_pdcp_entity_set_integrity_key; ret->set_security = nr_pdcp_entity_set_security;
ret->set_time = nr_pdcp_entity_set_time; ret->set_time = nr_pdcp_entity_set_time;
ret->delete = nr_pdcp_entity_delete; ret->delete = nr_pdcp_entity_delete;
......
...@@ -40,7 +40,16 @@ typedef struct nr_pdcp_entity_t { ...@@ -40,7 +40,16 @@ typedef struct nr_pdcp_entity_t {
void (*recv_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size, void (*recv_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size,
int sdu_id); int sdu_id);
void (*delete)(struct nr_pdcp_entity_t *entity); void (*delete)(struct nr_pdcp_entity_t *entity);
void (*set_integrity_key)(struct nr_pdcp_entity_t *entity, char *key); /* set_security: pass -1 to integrity_algorithm / ciphering_algorithm
* to keep the current algorithm
* pass NULL to integrity_key / ciphering_key
* to keep the current key
*/
void (*set_security)(struct nr_pdcp_entity_t *entity,
int integrity_algorithm,
char *integrity_key,
int ciphering_algorithm,
char *ciphering_key);
void (*set_time)(struct nr_pdcp_entity_t *entity, uint64_t now); void (*set_time)(struct nr_pdcp_entity_t *entity, uint64_t now);
/* callbacks provided to the PDCP module */ /* callbacks provided to the PDCP module */
......
...@@ -1043,6 +1043,12 @@ void pdcp_config_set_security( ...@@ -1043,6 +1043,12 @@ void pdcp_config_set_security(
uint8_t *const kRRCint_pP, uint8_t *const kRRCint_pP,
uint8_t *const kUPenc_pP) uint8_t *const kUPenc_pP)
{ {
nr_pdcp_ue_t *ue;
nr_pdcp_entity_t *rb;
int rnti = ctxt_pP->rnti;
int integrity_algorithm;
int ciphering_algorithm;
DevAssert(pdcp_pP != NULL); DevAssert(pdcp_pP != NULL);
if ((security_modeP >= 0) && (security_modeP <= 0x77)) { if ((security_modeP >= 0) && (security_modeP <= 0x77)) {
...@@ -1072,6 +1078,33 @@ void pdcp_config_set_security( ...@@ -1072,6 +1078,33 @@ void pdcp_config_set_security(
PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP),
security_modeP); security_modeP);
} }
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rnti);
/* TODO: proper handling of DRBs, for the moment only SRBs are handled */
if (rb_id >= 1 && rb_id <= 3) {
rb = ue->srb[rb_id - 1];
if (rb == NULL) {
LOG_E(PDCP, "%s:%d:%s: no SRB found (rnti %d, rb_id %ld)\n",
__FILE__, __LINE__, __FUNCTION__, rnti, rb_id);
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
return;
}
integrity_algorithm = (security_modeP>>4) & 0xf;
ciphering_algorithm = security_modeP & 0x0f;
rb->set_security(rb, integrity_algorithm, (char *)kRRCint_pP,
ciphering_algorithm, (char *)kRRCenc_pP);
} else {
LOG_E(PDCP, "%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
} }
......
...@@ -304,6 +304,7 @@ nr_rrc_pdcp_config_security( ...@@ -304,6 +304,7 @@ nr_rrc_pdcp_config_security(
uint8_t *kRRCenc = NULL; uint8_t *kRRCenc = NULL;
uint8_t *kRRCint = NULL; uint8_t *kRRCint = NULL;
uint8_t *kUPenc = NULL; uint8_t *kUPenc = NULL;
uint8_t *k_kdf = NULL;
pdcp_t *pdcp_p = NULL; pdcp_t *pdcp_p = NULL;
static int print_keys= 1; static int print_keys= 1;
hashtable_rc_t h_rc; hashtable_rc_t h_rc;
...@@ -312,17 +313,36 @@ nr_rrc_pdcp_config_security( ...@@ -312,17 +313,36 @@ nr_rrc_pdcp_config_security(
#ifndef PHYSIM #ifndef PHYSIM
/* Derive the keys from kgnb */ /* Derive the keys from kgnb */
if (SRB_configList != NULL) { if (SRB_configList != NULL) {
k_kdf = NULL;
nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
ue_context_pP->ue_context.kgnb, ue_context_pP->ue_context.kgnb,
&kUPenc); &k_kdf);
/* kUPenc: last 128 bits of key derivation function which returns 256 bits */
kUPenc = malloc(16);
if (kUPenc == NULL) exit(1);
memcpy(kUPenc, k_kdf+16, 16);
free(k_kdf);
} }
k_kdf = NULL;
nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm,
ue_context_pP->ue_context.kgnb, ue_context_pP->ue_context.kgnb,
&kRRCenc); &k_kdf);
/* kRRCenc: last 128 bits of key derivation function which returns 256 bits */
kRRCenc = malloc(16);
if (kRRCenc == NULL) exit(1);
memcpy(kRRCenc, k_kdf+16, 16);
free(k_kdf);
k_kdf = NULL;
nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm,
ue_context_pP->ue_context.kgnb, ue_context_pP->ue_context.kgnb,
&kRRCint); &k_kdf);
/* kRRCint: last 128 bits of key derivation function which returns 256 bits */
kRRCint = malloc(16);
if (kRRCint == NULL) exit(1);
memcpy(kRRCint, k_kdf+16, 16);
free(k_kdf);
#endif #endif
if (!IS_SOFTMODEM_IQPLAYER) { if (!IS_SOFTMODEM_IQPLAYER) {
SET_LOG_DUMP(DEBUG_SECURITY) ; SET_LOG_DUMP(DEBUG_SECURITY) ;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment