OAI UE Mode complete ciphering bug
This commit is contained in:
@@ -111,13 +111,12 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
|
||||
entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1);
|
||||
|
||||
if (entity->has_integrity) {
|
||||
unsigned char integrity[4];
|
||||
unsigned char integrity[4] = {0};
|
||||
entity->integrity(entity->integrity_context, integrity,
|
||||
buffer, size - integrity_size,
|
||||
entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1);
|
||||
if (memcmp(integrity, buffer + size - integrity_size, 4) != 0) {
|
||||
LOG_E(PDCP, "discard NR PDU, integrity failed\n");
|
||||
// return;
|
||||
entity->stats.rxpdu_dd_pkts++;
|
||||
entity->stats.rxpdu_dd_bytes += size;
|
||||
|
||||
@@ -220,20 +219,27 @@ static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity,
|
||||
|
||||
memcpy(buf + header_size, buffer, size);
|
||||
|
||||
if (entity->has_integrity)
|
||||
if (entity->has_integrity){
|
||||
uint8_t integrity[4] = {0};
|
||||
entity->integrity(entity->integrity_context,
|
||||
(unsigned char *)buf + header_size + size,
|
||||
integrity,
|
||||
(unsigned char *)buf, header_size + size,
|
||||
entity->rb_id, count, entity->is_gnb ? 1 : 0);
|
||||
|
||||
memcpy((unsigned char *)buf + header_size + size, integrity, 4);
|
||||
}
|
||||
|
||||
// set MAC-I to 0 for SRBs with integrity not active
|
||||
else if (integrity_size == 4)
|
||||
memset(buf + header_size + size, 0, 4);
|
||||
|
||||
if (entity->has_ciphering)
|
||||
if (entity->has_ciphering && (entity->is_gnb || entity->security_mode_completed)){
|
||||
entity->cipher(entity->security_context,
|
||||
(unsigned char *)buf + header_size, size + integrity_size,
|
||||
entity->rb_id, count, entity->is_gnb ? 1 : 0);
|
||||
} else {
|
||||
entity->security_mode_completed = true;
|
||||
}
|
||||
|
||||
entity->tx_next++;
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#ifndef _NR_PDCP_ENTITY_H_
|
||||
#define _NR_PDCP_ENTITY_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "nr_pdcp_sdu.h"
|
||||
@@ -149,6 +150,19 @@ typedef struct nr_pdcp_entity_t {
|
||||
int rx_size;
|
||||
int rx_maxsize;
|
||||
nr_pdcp_statistics_t stats;
|
||||
|
||||
// WARNING: This is a hack!
|
||||
// 3GPP TS 38.331 (RRC) version 15.3
|
||||
// Section 5.3.4.3 Reception of the SecurityModeCommand by the UE
|
||||
// The UE needs to send the Security Mode Complete message. However, the message
|
||||
// needs to be sent without being ciphered.
|
||||
// However:
|
||||
// 1- The Security Mode Command arrives to the UE with the cipher algo (e.g., nea2).
|
||||
// 2- The UE is configured with the cipher algo.
|
||||
// 3- The Security Mode Complete message is sent to the itti task queue.
|
||||
// 4- The ITTI task, forwards the message ciphering (e.g., nea2) it.
|
||||
// 5- The gNB cannot understand the ciphered Security Mode Complete message.
|
||||
bool security_mode_completed;
|
||||
} nr_pdcp_entity_t;
|
||||
|
||||
nr_pdcp_entity_t *new_nr_pdcp_entity(
|
||||
|
||||
@@ -1267,6 +1267,7 @@ void pdcp_config_set_security(
|
||||
ciphering_algorithm = security_modeP & 0x0f;
|
||||
rb->set_security(rb, integrity_algorithm, (char *)kRRCint_pP,
|
||||
ciphering_algorithm, (char *)kRRCenc_pP);
|
||||
rb->security_mode_completed = false;
|
||||
} else {
|
||||
LOG_E(PDCP, "%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
|
||||
@@ -54,14 +54,13 @@ void nr_pdcp_security_nea2_cipher(void *security_context,
|
||||
unsigned char *buffer, int length,
|
||||
int bearer, int count, int direction)
|
||||
{
|
||||
unsigned char t[16];
|
||||
unsigned char t[16] = {0};
|
||||
|
||||
t[0] = (count >> 24) & 255;
|
||||
t[1] = (count >> 16) & 255;
|
||||
t[2] = (count >> 8) & 255;
|
||||
t[3] = (count ) & 255;
|
||||
t[4] = ((bearer-1) << 3) | (direction << 2);
|
||||
memset(&t[5], 0, 16-5);
|
||||
|
||||
nettle_ctr_crypt(security_context, nettle_aes128.encrypt,
|
||||
nettle_aes128.block_size, t,
|
||||
|
||||
Reference in New Issue
Block a user