Commit 8b332240 authored by mir's avatar mir

OAI UE Mode complete ciphering bug

parent a1de5e3d
...@@ -111,13 +111,12 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, ...@@ -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); entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1);
if (entity->has_integrity) { if (entity->has_integrity) {
unsigned char integrity[4]; unsigned char integrity[4] = {0};
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 + size - integrity_size, 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;
entity->stats.rxpdu_dd_pkts++; entity->stats.rxpdu_dd_pkts++;
entity->stats.rxpdu_dd_bytes += size; entity->stats.rxpdu_dd_bytes += size;
...@@ -220,20 +219,27 @@ static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity, ...@@ -220,20 +219,27 @@ static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity,
memcpy(buf + header_size, buffer, size); memcpy(buf + header_size, buffer, size);
if (entity->has_integrity) if (entity->has_integrity){
uint8_t integrity[4] = {0};
entity->integrity(entity->integrity_context, entity->integrity(entity->integrity_context,
(unsigned char *)buf + header_size + size, integrity,
(unsigned char *)buf, header_size + size, (unsigned char *)buf, header_size + size,
entity->rb_id, count, entity->is_gnb ? 1 : 0); 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 // set MAC-I to 0 for SRBs with integrity not active
else if (integrity_size == 4) else if (integrity_size == 4)
memset(buf + header_size + size, 0, 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, entity->cipher(entity->security_context,
(unsigned char *)buf + header_size, size + integrity_size, (unsigned char *)buf + header_size, size + integrity_size,
entity->rb_id, count, entity->is_gnb ? 1 : 0); entity->rb_id, count, entity->is_gnb ? 1 : 0);
} else {
entity->security_mode_completed = true;
}
entity->tx_next++; entity->tx_next++;
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#ifndef _NR_PDCP_ENTITY_H_ #ifndef _NR_PDCP_ENTITY_H_
#define _NR_PDCP_ENTITY_H_ #define _NR_PDCP_ENTITY_H_
#include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "nr_pdcp_sdu.h" #include "nr_pdcp_sdu.h"
...@@ -149,6 +150,19 @@ typedef struct nr_pdcp_entity_t { ...@@ -149,6 +150,19 @@ typedef struct nr_pdcp_entity_t {
int rx_size; int rx_size;
int rx_maxsize; int rx_maxsize;
nr_pdcp_statistics_t stats; 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;
nr_pdcp_entity_t *new_nr_pdcp_entity( nr_pdcp_entity_t *new_nr_pdcp_entity(
......
...@@ -1267,6 +1267,7 @@ void pdcp_config_set_security( ...@@ -1267,6 +1267,7 @@ void pdcp_config_set_security(
ciphering_algorithm = security_modeP & 0x0f; ciphering_algorithm = security_modeP & 0x0f;
rb->set_security(rb, integrity_algorithm, (char *)kRRCint_pP, rb->set_security(rb, integrity_algorithm, (char *)kRRCint_pP,
ciphering_algorithm, (char *)kRRCenc_pP); ciphering_algorithm, (char *)kRRCenc_pP);
rb->security_mode_completed = false;
} else { } else {
LOG_E(PDCP, "%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__); LOG_E(PDCP, "%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__);
exit(1); exit(1);
......
...@@ -54,14 +54,13 @@ void nr_pdcp_security_nea2_cipher(void *security_context, ...@@ -54,14 +54,13 @@ void nr_pdcp_security_nea2_cipher(void *security_context,
unsigned char *buffer, int length, unsigned char *buffer, int length,
int bearer, int count, int direction) int bearer, int count, int direction)
{ {
unsigned char t[16]; unsigned char t[16] = {0};
t[0] = (count >> 24) & 255; t[0] = (count >> 24) & 255;
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-1) << 3) | (direction << 2); t[4] = ((bearer-1) << 3) | (direction << 2);
memset(&t[5], 0, 16-5);
nettle_ctr_crypt(security_context, nettle_aes128.encrypt, nettle_ctr_crypt(security_context, nettle_aes128.encrypt,
nettle_aes128.block_size, t, nettle_aes128.block_size, t,
......
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