nr pdcp: bugfixes
- use bearer-1 in compute_t of integrity NIA2 - compare integrity at the right place in nr_pdcp_entity_recv_pdu - proper handling of security parameters settings (algos, keys)
This commit is contained in:
@@ -101,7 +101,7 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
|
|||||||
entity->integrity(entity->integrity_context, integrity,
|
entity->integrity(entity->integrity_context, integrity,
|
||||||
buffer, size - integrity_size,
|
buffer, size - integrity_size,
|
||||||
entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1);
|
entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1);
|
||||||
if (memcmp(integrity, buffer, 4) != 0) {
|
if (memcmp(integrity, buffer + size - integrity_size, 4) != 0) {
|
||||||
LOG_E(PDCP, "discard NR PDU, integrity failed\n");
|
LOG_E(PDCP, "discard NR PDU, integrity failed\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -212,6 +212,7 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* may be called several times, take care to clean previous settings */
|
||||||
static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity,
|
static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity,
|
||||||
int integrity_algorithm,
|
int integrity_algorithm,
|
||||||
char *integrity_key,
|
char *integrity_key,
|
||||||
@@ -226,6 +227,46 @@ static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity,
|
|||||||
memcpy(entity->integrity_key, integrity_key, 16);
|
memcpy(entity->integrity_key, integrity_key, 16);
|
||||||
if (ciphering_key != NULL)
|
if (ciphering_key != NULL)
|
||||||
memcpy(entity->ciphering_key, ciphering_key, 16);
|
memcpy(entity->ciphering_key, ciphering_key, 16);
|
||||||
|
|
||||||
|
if (integrity_algorithm == 0) {
|
||||||
|
entity->has_integrity = 0;
|
||||||
|
if (entity->free_integrity != NULL)
|
||||||
|
entity->free_integrity(entity->integrity_context);
|
||||||
|
entity->free_integrity = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (integrity_algorithm != 0 && integrity_algorithm != -1) {
|
||||||
|
if (integrity_algorithm != 2) {
|
||||||
|
LOG_E(PDCP, "FATAL: only nia2 supported for the moment\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
entity->has_integrity = 1;
|
||||||
|
if (entity->free_integrity != NULL)
|
||||||
|
entity->free_integrity(entity->integrity_context);
|
||||||
|
entity->integrity_context = nr_pdcp_integrity_nia2_init(entity->integrity_key);
|
||||||
|
entity->integrity = nr_pdcp_integrity_nia2_integrity;
|
||||||
|
entity->free_integrity = nr_pdcp_integrity_nia2_free_integrity;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ciphering_algorithm == 0) {
|
||||||
|
entity->has_ciphering = 0;
|
||||||
|
if (entity->free_security != NULL)
|
||||||
|
entity->free_security(entity->security_context);
|
||||||
|
entity->free_security = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ciphering_algorithm != 0 && ciphering_algorithm != -1) {
|
||||||
|
if (ciphering_algorithm != 2) {
|
||||||
|
LOG_E(PDCP, "FATAL: only nea2 supported for the moment\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
entity->has_ciphering = 1;
|
||||||
|
if (entity->free_security != NULL)
|
||||||
|
entity->free_security(entity->security_context);
|
||||||
|
entity->security_context = nr_pdcp_security_nea2_init(entity->ciphering_key);
|
||||||
|
entity->cipher = nr_pdcp_security_nea2_cipher;
|
||||||
|
entity->free_security = nr_pdcp_security_nea2_free_security;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_t_reordering(nr_pdcp_entity_t *entity)
|
static void check_t_reordering(nr_pdcp_entity_t *entity)
|
||||||
@@ -339,34 +380,11 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
|
|||||||
ret->sn_max = (1 << sn_size) - 1;
|
ret->sn_max = (1 << sn_size) - 1;
|
||||||
ret->window_size = 1 << (sn_size - 1);
|
ret->window_size = 1 << (sn_size - 1);
|
||||||
|
|
||||||
if (ciphering_key != NULL && ciphering_algorithm != 0) {
|
|
||||||
if (ciphering_algorithm != 2) {
|
|
||||||
LOG_E(PDCP, "FATAL: only nea2 supported for the moment\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
ret->has_ciphering = 1;
|
|
||||||
ret->ciphering_algorithm = ciphering_algorithm;
|
|
||||||
memcpy(ret->ciphering_key, ciphering_key, 16);
|
|
||||||
|
|
||||||
ret->security_context = nr_pdcp_security_nea2_init(ciphering_key);
|
|
||||||
ret->cipher = nr_pdcp_security_nea2_cipher;
|
|
||||||
ret->free_security = nr_pdcp_security_nea2_free_security;
|
|
||||||
}
|
|
||||||
ret->is_gnb = is_gnb;
|
ret->is_gnb = is_gnb;
|
||||||
|
|
||||||
if (integrity_key != NULL && integrity_algorithm != 0) {
|
nr_pdcp_entity_set_security(ret,
|
||||||
if (integrity_algorithm != 2) {
|
integrity_algorithm, (char *)integrity_key,
|
||||||
LOG_E(PDCP, "FATAL: only nia2 supported for the moment\n");
|
ciphering_algorithm, (char *)ciphering_key);
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
ret->has_integrity = 1;
|
|
||||||
ret->integrity_algorithm = integrity_algorithm;
|
|
||||||
memcpy(ret->integrity_key, integrity_key, 16);
|
|
||||||
|
|
||||||
ret->integrity_context = nr_pdcp_integrity_nia2_init(integrity_key);
|
|
||||||
ret->integrity = nr_pdcp_integrity_nia2_integrity;
|
|
||||||
ret->free_integrity = nr_pdcp_integrity_nia2_free_integrity;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ static void compute_t(unsigned char *t, uint32_t count, int bearer,
|
|||||||
t[1] = (count >> 16) & 255;
|
t[1] = (count >> 16) & 255;
|
||||||
t[2] = (count >> 8) & 255;
|
t[2] = (count >> 8) & 255;
|
||||||
t[3] = (count ) & 255;
|
t[3] = (count ) & 255;
|
||||||
t[4] = (bearer << 3) | (direction << 2);
|
t[4] = ((bearer-1) << 3) | (direction << 2);
|
||||||
memset(&t[5], 0, 8-5);
|
memset(&t[5], 0, 8-5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user