Commit 598eeb79 authored by Xue Song's avatar Xue Song

Derive keys from kgnb

parent ac902811
......@@ -182,13 +182,6 @@ typedef enum nr_e_rab_satus_e {
NR_E_RAB_STATUS_FAILED,
} nr_e_rab_status_t;
typedef enum nr_pdu_session_status_e {
NR_PDU_SESSION_STATUS_NEW,
NR_PDU_SESSION_STATUS_DONE, // from the gNB perspective
NR_PDU_SESSION_STATUS_ESTABLISHED, // get the reconfigurationcomplete form UE
NR_PDU_SESSION_STATUS_FAILED,
} nr_pdu_session_status_t;
typedef struct nr_e_rab_param_s {
e_rab_t param;
uint8_t status;
......@@ -265,8 +258,10 @@ typedef struct nr_rrc_guami_s {
} nr_rrc_guami_t;
typedef enum pdu_session_satus_e {
PDU_SESSION_STATUS_NEW
//TODO
PDU_SESSION_STATUS_NEW,
PDU_SESSION_STATUS_DONE,
PDU_SESSION_STATUS_ESTABLISHED,
PDU_SESSION_STATUS_FAILED,
} pdu_session_status_t;
typedef struct pdu_session_param_s {
......
......@@ -63,6 +63,18 @@ extern RAN_CONTEXT_t RC;
/* Value to indicate an invalid UE initial id */
static const uint16_t UE_INITIAL_ID_INVALID = 0;
/* Masks for NGAP Encryption algorithms, NEA0 is always supported (not coded) */
static const uint16_t NGAP_ENCRYPTION_NEA1_MASK = 0x8000;
static const uint16_t NGAP_ENCRYPTION_NEA2_MASK = 0x4000;
static const uint16_t NGAP_ENCRYPTION_NEA3_MASK = 0x2000;
/* Masks for NGAP Integrity algorithms, NIA0 is always supported (not coded) */
static const uint16_t NGAP_INTEGRITY_NIA1_MASK = 0x8000;
static const uint16_t NGAP_INTEGRITY_NIA2_MASK = 0x4000;
static const uint16_t NGAP_INTEGRITY_NIA3_MASK = 0x2000;
#define INTEGRITY_ALGORITHM_NONE NR_IntegrityProtAlgorithm_nia0
/*! \fn uint16_t get_next_ue_initial_id(uint8_t mod_id)
*\brief provide an UE initial ID for NGAP initial communication.
*\param mod_id Instance ID of gNB.
......@@ -248,6 +260,35 @@ rrc_gNB_get_ue_context_from_ngap_ids(
return NULL;
}
/*! \fn void process_gNB_security_key (const protocol_ctxt_t* const ctxt_pP, eNB_RRC_UE_t * const ue_context_pP, uint8_t *security_key)
*\brief save security key.
*\param ctxt_pP Running context.
*\param ue_context_pP UE context.
*\param security_key_pP The security key received from NGAP.
*/
//------------------------------------------------------------------------------
void process_gNB_security_key (
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
uint8_t *security_key_pP
)
//------------------------------------------------------------------------------
{
char ascii_buffer[65];
uint8_t i;
/* Saves the security key */
memcpy (ue_context_pP->ue_context.kgnb, security_key_pP, SECURITY_KEY_LENGTH);
memset (ue_context_pP->ue_context.nh, 0, SECURITY_KEY_LENGTH);
ue_context_pP->ue_context.nh_ncc = -1;
for (i = 0; i < 32; i++) {
sprintf(&ascii_buffer[2 * i], "%02X", ue_context_pP->ue_context.kgnb[i]);
}
ascii_buffer[2 * i] = '\0';
LOG_I(NR_RRC, "[gNB %d][UE %x] Saved security key %s\n", ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ascii_buffer);
}
//------------------------------------------------------------------------------
void
nr_rrc_pdcp_config_security(
......@@ -269,17 +310,17 @@ nr_rrc_pdcp_config_security(
#ifndef PHYSIM
/* Derive the keys from kgnb */
if (SRB_configList != NULL) {
derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
ue_context_pP->ue_context.kgnb,
&kUPenc);
nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
ue_context_pP->ue_context.kgnb,
&kUPenc);
}
derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm,
ue_context_pP->ue_context.kgnb,
&kRRCenc);
derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm,
ue_context_pP->ue_context.kgnb,
&kRRCint);
nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm,
ue_context_pP->ue_context.kgnb,
&kRRCenc);
nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm,
ue_context_pP->ue_context.kgnb,
&kRRCint);
#endif
if (!IS_SOFTMODEM_IQPLAYER) {
SET_LOG_DUMP(DEBUG_SECURITY) ;
......@@ -451,6 +492,7 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
uint32_t gNB_ue_ngap_id;
rrc_gNB_ue_context_t *ue_context_p = NULL;
protocol_ctxt_t ctxt;
uint8_t pdu_sessions_done = 0;
ue_initial_id = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).ue_initial_id;
gNB_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).gNB_ue_ngap_id;
......@@ -473,19 +515,23 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
ue_context_p->ue_context.gNB_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).gNB_ue_ngap_id;
ue_context_p->ue_context.amf_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).amf_ue_ngap_id;
ue_context_p->ue_context.nas_pdu_flag = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nas_pdu_flag;
ue_context_p->ue_context.nb_of_pdusessions = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nb_of_pdusessions;
for (int i = 0; i < ue_context_p->ue_context.nb_of_pdusessions; i++) {
ue_context_p->ue_context.pdusession[i].status = PDU_SESSION_STATUS_NEW;
ue_context_p->ue_context.pdusession[i].param = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[i];
//create_tunnel_req.eps_bearer_id[i] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).e_rab_param[i].e_rab_id;
//create_tunnel_req.sgw_S1u_teid[i] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).e_rab_param[i].gtp_teid;
//memcpy(&create_tunnel_req.sgw_addr[i],
// &S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).e_rab_param[i].sgw_addr,
// sizeof(transport_layer_addr_t));
//inde_list[create_tunnel_req.num_tunnels]= i;
//create_tunnel_req.num_tunnels++;
}
if (NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nb_of_pdusessions != 0) {
ue_context_p->ue_context.nb_of_pdusessions = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nb_of_pdusessions;
for (int i = 0; i < NR_NB_RB_MAX - 3; i++) {
if(ue_context_p->ue_context.pdusession[i].status >= PDU_SESSION_STATUS_DONE)
continue;
ue_context_p->ue_context.pdusession[i].status = PDU_SESSION_STATUS_NEW;
ue_context_p->ue_context.pdusession[i].param = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done];
pdu_sessions_done++;
// TODO establish PDU SESSION
if(pdu_sessions_done >= NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nb_of_pdusessions) {
break;
}
}
}
/* NAS PDU */
ue_context_p->ue_context.nas_pdu_flag = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu_flag;
......@@ -494,8 +540,12 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
ue_context_p->ue_context.nas_pdu.buffer = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.buffer;
}
/* TODO security */
/* security */
rrc_gNB_process_security(&ctxt, ue_context_p, &(NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).security_capabilities));
process_gNB_security_key (
&ctxt,
ue_context_p,
NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).security_key);
uint8_t send_security_mode_command = TRUE;
......@@ -575,13 +625,34 @@ rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(
}
static NR_CipheringAlgorithm_t rrc_gNB_select_ciphering(uint16_t algorithms) {
//#warning "Forced return NR_CipheringAlgorithm_nea0, to be deleted in future"
if (algorithms & NGAP_ENCRYPTION_NEA3_MASK) {
return NR_CipheringAlgorithm_nea3;
}
if (algorithms & NGAP_ENCRYPTION_NEA2_MASK) {
return NR_CipheringAlgorithm_nea2;
}
if (algorithms & NGAP_ENCRYPTION_NEA1_MASK) {
return NR_CipheringAlgorithm_nea1;
}
return NR_CipheringAlgorithm_nea0;
}
static e_NR_IntegrityProtAlgorithm rrc_gNB_select_integrity(uint16_t algorithms) {
if (algorithms & NGAP_INTEGRITY_NIA3_MASK) {
return NR_IntegrityProtAlgorithm_nia3;
}
if (algorithms & NGAP_INTEGRITY_NIA2_MASK) {
return NR_IntegrityProtAlgorithm_nia2;
}
if (algorithms & NGAP_INTEGRITY_NIA1_MASK) {
return NR_IntegrityProtAlgorithm_nia1;
}
// to be continue
return NR_IntegrityProtAlgorithm_nia0;
}
......@@ -598,7 +669,7 @@ rrc_gNB_process_security(
ue_context_pP->ue_context.security_capabilities = *security_capabilities_pP;
// translation
LOG_D(NR_RRC,
"[eNB %d] NAS security_capabilities.encryption_algorithms %u AS ciphering_algorithm %lu NAS security_capabilities.integrity_algorithms %u AS integrity_algorithm %u\n",
"[gNB %d] NAS security_capabilities.encryption_algorithms %u AS ciphering_algorithm %lu NAS security_capabilities.integrity_algorithms %u AS integrity_algorithm %u\n",
ctxt_pP->module_id,
ue_context_pP->ue_context.security_capabilities.nRencryption_algorithms,
(unsigned long)ue_context_pP->ue_context.ciphering_algorithm,
......@@ -619,7 +690,7 @@ rrc_gNB_process_security(
changed = TRUE;
}
LOG_I (NR_RRC, "[eNB %d][UE %x] Selected security algorithms (%p): %lx, %x, %s\n",
LOG_I (NR_RRC, "[gNB %d][UE %x] Selected security algorithms (%p): %lx, %x, %s\n",
ctxt_pP->module_id,
ue_context_pP->ue_context.rnti,
security_capabilities_pP,
......@@ -787,7 +858,7 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
for (pdusession = 0; pdusession < ue_context_pP->ue_context.setup_pdu_sessions; pdusession++) {
// if (xid == ue_context_pP->ue_context.pdusession[pdusession].xid) {
if (ue_context_pP->ue_context.pdusession[pdusession].status == NR_PDU_SESSION_STATUS_DONE) {
if (ue_context_pP->ue_context.pdusession[pdusession].status == PDU_SESSION_STATUS_DONE) {
NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id;
// NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].pdusession_id = 1;
NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].nb_of_qos_flow = ue_context_pP->ue_context.pdusession[pdusession].param.nb_qos;
......@@ -802,7 +873,7 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qos_flow_mapping_ind = QOSFLOW_MAPPING_INDICATION_DL;
}
ue_context_pP->ue_context.pdusession[pdusession].status = NR_PDU_SESSION_STATUS_ESTABLISHED;
ue_context_pP->ue_context.pdusession[pdusession].status = PDU_SESSION_STATUS_ESTABLISHED;
LOG_I (NR_RRC,"gnb_gtp_addr (msg index %d, pdu_sessions index %d, status %d, xid %d): nb_of_pdusessions %d, pdusession_id %d, teid: %u, addr: %d.%d.%d.%d \n ",
pdu_sessions_done, pdusession, ue_context_pP->ue_context.pdusession[pdusession].status, xid,
ue_context_pP->ue_context.nb_of_pdusessions,
......@@ -813,11 +884,11 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].gNB_addr.buffer[2],
NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].gNB_addr.buffer[3]);
pdu_sessions_done++;
} else if ((ue_context_pP->ue_context.pdusession[pdusession].status == NR_PDU_SESSION_STATUS_NEW) ||
(ue_context_pP->ue_context.pdusession[pdusession].status == NR_PDU_SESSION_STATUS_ESTABLISHED)) {
} else if ((ue_context_pP->ue_context.pdusession[pdusession].status == PDU_SESSION_STATUS_NEW) ||
(ue_context_pP->ue_context.pdusession[pdusession].status == PDU_SESSION_STATUS_ESTABLISHED)) {
LOG_D (NR_RRC,"PDU-SESSION is NEW or already ESTABLISHED\n");
} else { /* to be improved */
ue_context_pP->ue_context.pdusession[pdusession].status = NR_PDU_SESSION_STATUS_FAILED;
ue_context_pP->ue_context.pdusession[pdusession].status = PDU_SESSION_STATUS_FAILED;
NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions_failed[pdu_sessions_failed].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id;
pdu_sessions_failed++;
// TODO add cause when it will be integrated
......@@ -893,9 +964,9 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
for (int i = 0; i < NR_NB_RB_MAX - 3; i++) {
if(ue_context_p->ue_context.pdusession[i].status >= NR_PDU_SESSION_STATUS_DONE)
if(ue_context_p->ue_context.pdusession[i].status >= PDU_SESSION_STATUS_DONE)
continue;
ue_context_p->ue_context.pdusession[i].status = NR_PDU_SESSION_STATUS_NEW;
ue_context_p->ue_context.pdusession[i].status = PDU_SESSION_STATUS_NEW;
ue_context_p->ue_context.pdusession[i].param = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done];
create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].pdusession_id;
create_tunnel_req.upf_NGu_teid[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].gtp_teid;
......@@ -943,7 +1014,7 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(
ue_context_p->ue_context.setup_pdu_sessions += nb_pdusessions_tosetup;
// TEST
ue_context_p->ue_context.pdusession[0].status = NR_PDU_SESSION_STATUS_DONE;
ue_context_p->ue_context.pdusession[0].status = PDU_SESSION_STATUS_DONE;
rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(&ctxt, ue_context_p, 0);
return(0);
}
......
......@@ -55,6 +55,8 @@ typedef enum {
int derive_key(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
const uint8_t key[32], uint8_t **out);
int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id,
const uint8_t key[32], uint8_t **out);
//#define derive_key_nas_enc(aLGiD, kEY, kNAS) derive_key(NAS_ENC_ALG, aLGiD, kEY, kNAS)
......@@ -72,6 +74,19 @@ int derive_key(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
#define derive_key_up_int(aLGiD, kEY, kNAS) \
derive_key(UP_INT_ALG, aLGiD, kEY, kNAS)
// 5G SA
#define nr_derive_key_rrc_enc(aLGiD, kEY, kRRC) \
nr_derive_key(RRC_ENC_ALG, aLGiD, kEY, kRRC)
#define nr_derive_key_rrc_int(aLGiD, kEY, kRRC) \
nr_derive_key(RRC_INT_ALG, aLGiD, kEY, kRRC)
#define nr_derive_key_up_enc(aLGiD, kEY, kUP) \
nr_derive_key(UP_ENC_ALG, aLGiD, kEY, kUP)
#define nr_derive_key_up_int(aLGiD, kEY, kUP) \
nr_derive_key(UP_INT_ALG, aLGiD, kEY, kUP)
typedef struct {
uint8_t *key;
uint32_t key_length;
......
......@@ -36,6 +36,8 @@
#define FC_ALG_KEY_DER (0x15)
#define FC_KASME_TO_CK (0x16)
#define NR_FC_ALG_KEY_DER (0x69)
#ifndef hton_int32
# define hton_int32(x) \
(((x & 0x000000FF) << 24) | ((x & 0x0000FF00) << 8) | \
......
......@@ -97,6 +97,34 @@ int derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id,
return 0;
}
int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id,
const uint8_t key[32], uint8_t **out)
{
uint8_t string[7];
/* FC */
string[0] = NR_FC_ALG_KEY_DER;
/* P0 = algorithm type distinguisher */
string[1] = (uint8_t)(alg_type & 0xFF);
/* L0 = length(P0) = 1 */
string[2] = 0x00;
string[3] = 0x01;
/* P1 */
string[4] = alg_id;
/* L1 = length(P1) = 1 */
string[5] = 0x00;
string[6] = 0x01;
kdf(string, 7, key, 32, out, 32);
return 0;
}
/*
int derive_keNB(const uint8_t key[32], const uint32_t nas_count, uint8_t **keNB)
{
......
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