Commit 978cb1d7 authored by gauthier's avatar gauthier

X2HO keNB* derivation, compile, not tested

parent 6409658c
...@@ -387,6 +387,8 @@ typedef struct eNB_RRC_UE_s { ...@@ -387,6 +387,8 @@ typedef struct eNB_RRC_UE_s {
#if defined(ENABLE_SECURITY) #if defined(ENABLE_SECURITY)
/* KeNB as derived from KASME received from EPC */ /* KeNB as derived from KASME received from EPC */
uint8_t kenb[32]; uint8_t kenb[32];
uint8_t nh[32];
int8_t nh_ncc;
#endif #endif
/* Used integrity/ciphering algorithms */ /* Used integrity/ciphering algorithms */
CipheringAlgorithm_r12_t ciphering_algorithm; CipheringAlgorithm_r12_t ciphering_algorithm;
...@@ -600,6 +602,8 @@ typedef struct UE_RRC_INST_s { ...@@ -600,6 +602,8 @@ typedef struct UE_RRC_INST_s {
#if defined(ENABLE_SECURITY) #if defined(ENABLE_SECURITY)
/* KeNB as computed from parameters within USIM card */ /* KeNB as computed from parameters within USIM card */
uint8_t kenb[32]; uint8_t kenb[32];
uint8_t nh[32];
int8_t nh_ncc;
#endif #endif
/* Used integrity/ciphering algorithms */ /* Used integrity/ciphering algorithms */
......
...@@ -254,6 +254,8 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration( ...@@ -254,6 +254,8 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(
const uint8_t ho_state const uint8_t ho_state
); );
int freq_to_arfcn10(int band, unsigned long freq);
void void
rrc_eNB_generate_dedeicatedRRCConnectionReconfiguration( rrc_eNB_generate_dedeicatedRRCConnectionReconfiguration(
const protocol_ctxt_t* const ctxt_pP, const protocol_ctxt_t* const ctxt_pP,
......
...@@ -2160,7 +2160,113 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons ...@@ -2160,7 +2160,113 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons
PDCP_TRANSMISSION_MODE_CONTROL); PDCP_TRANSMISSION_MODE_CONTROL);
} }
typedef enum { BAND_TYPE_FDD, BAND_TYPE_TDD } band_type;
typedef struct {
band_type t;
int band;
unsigned long ul_minfreq, ul_maxfreq;
unsigned long dl_minfreq, dl_maxfreq;
} band_freq;
static band_freq bands[] = {
{ BAND_TYPE_FDD, 1, 1920000000UL, 1980000000UL, 2110000000UL, 2170000000UL },
{ BAND_TYPE_FDD, 2, 1850000000UL, 1910000000UL, 1930000000UL, 1990000000UL },
{ BAND_TYPE_FDD, 3, 1710000000UL, 1785000000UL, 1805000000UL, 1880000000UL },
{ BAND_TYPE_FDD, 4, 1710000000UL, 1755000000UL, 2110000000UL, 2155000000UL },
{ BAND_TYPE_FDD, 5, 824000000UL, 849000000UL, 869000000UL, 894000000UL },
/* to remove? */{ BAND_TYPE_FDD, 6, 830000000UL, 840000000UL, 875000000UL, 885000000UL },
{ BAND_TYPE_FDD, 7, 2500000000UL, 2570000000UL, 2620000000UL, 2690000000UL },
{ BAND_TYPE_FDD, 8, 880000000UL, 915000000UL, 925000000UL, 960000000UL },
{ BAND_TYPE_FDD, 9, 1749900000UL, 1784900000UL, 1844900000UL, 1879900000UL },
{ BAND_TYPE_FDD, 10, 1710000000UL, 1770000000UL, 2110000000UL, 2170000000UL },
{ BAND_TYPE_FDD, 11, 1427900000UL, 1447900000UL, 1475900000UL, 1495900000UL },
{ BAND_TYPE_FDD, 12, 699000000UL, 716000000UL, 729000000UL, 746000000UL },
{ BAND_TYPE_FDD, 13, 777000000UL, 787000000UL, 746000000UL, 756000000UL },
{ BAND_TYPE_FDD, 14, 788000000UL, 798000000UL, 758000000UL, 768000000UL },
{ BAND_TYPE_FDD, 17, 704000000UL, 716000000UL, 734000000UL, 746000000UL },
{ BAND_TYPE_FDD, 18, 815000000UL, 830000000UL, 860000000UL, 875000000UL },
{ BAND_TYPE_FDD, 19, 830000000UL, 845000000UL, 875000000UL, 890000000UL },
{ BAND_TYPE_FDD, 20, 832000000UL, 862000000UL, 791000000UL, 821000000UL },
{ BAND_TYPE_FDD, 21, 1447900000UL, 1462900000UL, 1495900000UL, 1510900000UL },
{ BAND_TYPE_FDD, 22, 3410000000UL, 3490000000UL, 3510000000UL, 3590000000UL },
{ BAND_TYPE_FDD, 23, 2000000000UL, 2020000000UL, 2180000000UL, 2200000000UL },
{ BAND_TYPE_FDD, 24, 1626500000UL, 1660500000UL, 1525000000UL, 1559000000UL },
{ BAND_TYPE_FDD, 25, 1850000000UL, 1915000000UL, 1930000000UL, 1995000000UL },
{ BAND_TYPE_TDD, 33, 1900000000UL, 1920000000UL, 1900000000UL, 1920000000UL },
{ BAND_TYPE_TDD, 34, 2010000000UL, 2025000000UL, 2010000000UL, 2025000000UL },
{ BAND_TYPE_TDD, 35, 1850000000UL, 1910000000UL, 1850000000UL, 1910000000UL },
{ BAND_TYPE_TDD, 36, 1930000000UL, 1990000000UL, 1930000000UL, 1990000000UL },
{ BAND_TYPE_TDD, 37, 1910000000UL, 1930000000UL, 1910000000UL, 1930000000UL },
{ BAND_TYPE_TDD, 38, 2570000000UL, 2620000000UL, 2570000000UL, 2620000000UL },
{ BAND_TYPE_TDD, 39, 1880000000UL, 1920000000UL, 1880000000UL, 1920000000UL },
{ BAND_TYPE_TDD, 40, 2300000000UL, 2400000000UL, 2300000000UL, 2400000000UL },
{ BAND_TYPE_TDD, 41, 2496000000UL, 2690000000UL, 2496000000UL, 2690000000UL },
{ BAND_TYPE_TDD, 42, 3400000000UL, 3600000000UL, 3400000000UL, 3600000000UL },
{ BAND_TYPE_TDD, 43, 3600000000UL, 3800000000UL, 3600000000UL, 3800000000UL },
};
typedef struct {
int band;
unsigned long dl_flow;
int dl_off;
int dl_offmin, dl_offmax;
unsigned long ul_flow;
int ul_off;
int ul_offmin, ul_offmax;
} earfcn;
static earfcn earfcn_table[] = {
{ 1, 2110000000UL, 0, 0, 599, 1920000000UL, 18000, 18000, 18599 },
{ 2, 1930000000UL, 600, 600, 1199, 1850000000UL, 18600, 18600, 19199 },
{ 3, 1805000000UL, 1200, 1200, 1949, 1710000000UL, 19200, 19200, 19949 },
{ 4, 2110000000UL, 1950, 1950, 2399, 1710000000UL, 19950, 19950, 20399 },
{ 5, 869000000UL, 2400, 2400, 2649, 824000000UL, 20400, 20400, 20649 },
{ 6, 875000000UL, 2650, 2650, 2749, 830000000UL, 20650, 20650, 20749 },
{ 7, 2620000000UL, 2750, 2750, 3449, 2500000000UL, 20750, 20750, 21449 },
{ 8, 925000000UL, 3450, 3450, 3799, 880000000UL, 21450, 21450, 21799 },
{ 9, 1844900000UL, 3800, 3800, 4149, 1749900000UL, 21800, 21800, 22149 },
{ 10, 2110000000UL, 4150, 4150, 4749, 1710000000UL, 22150, 22150, 22749 },
{ 11, 1475900000UL, 4750, 4750, 4949, 1427900000UL, 22750, 22750, 22949 },
{ 12, 729000000UL, 5010, 5010, 5179, 699000000UL, 23010, 23010, 23179 },
{ 13, 746000000UL, 5180, 5180, 5279, 777000000UL, 23180, 23180, 23279 },
{ 14, 758000000UL, 5280, 5280, 5379, 788000000UL, 23280, 23280, 23379 },
{ 17, 734000000UL, 5730, 5730, 5849, 704000000UL, 23730, 23730, 23849 },
{ 18, 860000000UL, 5850, 5850, 5999, 815000000UL, 23850, 23850, 23999 },
{ 19, 875000000UL, 6000, 6000, 6149, 830000000UL, 24000, 24000, 24149 },
{ 20, 791000000UL, 6150, 6150, 6449, 832000000UL, 24150, 24150, 24449 },
{ 21, 1495900000UL, 6450, 6450, 6599, 1447900000UL, 24450, 24450, 24599 },
{ 22, 3510000000UL, 6600, 6600, 7399, 3410000000UL, 24600, 24600, 25399 },
{ 23, 2180000000UL, 7500, 7500, 7699, 2000000000UL, 25500, 25500, 25699 },
{ 24, 1525000000UL, 7700, 7700, 8039, 1626500000UL, 25700, 25700, 26039 },
{ 25, 1930000000UL, 8040, 8040, 8689, 1850000000UL, 26040, 26040, 26689 },
{ 33, 1900000000UL, 36000, 36000, 36199, 1900000000UL, 36000, 36000, 36199 },
{ 34, 2010000000UL, 36200, 36200, 36349, 2010000000UL, 36200, 36200, 36349 },
{ 35, 1850000000UL, 36350, 36350, 36949, 1850000000UL, 36350, 36350, 36949 },
{ 36, 1930000000UL, 36950, 36950, 37549, 1930000000UL, 36950, 36950, 37549 },
{ 37, 1910000000UL, 37550, 37550, 37749, 1910000000UL, 37550, 37550, 37749 },
{ 38, 2570000000UL, 37750, 37750, 38249, 2570000000UL, 37750, 37750, 38249 },
{ 39, 1880000000UL, 38250, 38250, 38649, 1880000000UL, 38250, 38250, 38649 },
{ 40, 2300000000UL, 38650, 38650, 39649, 2300000000UL, 38650, 38650, 39649 },
{ 41, 2496000000UL, 39650, 39650, 41589, 2496000000UL, 39650, 39650, 41589 },
{ 42, 3400000000UL, 41590, 41590, 43589, 3400000000UL, 41590, 41590, 43589 },
{ 43, 3600000000UL, 43590, 43590, 45589, 3600000000UL, 43590, 43590, 45589 },
};
int freq_to_arfcn10(int band, unsigned long freq)
{
int N = sizeof(earfcn_table) / sizeof(earfcn_table[0]);
int i;
for (i = 0; i < N; i++) if (bands[i].band == band) break;
if (i == N) return -1;
if (!(bands[i].dl_minfreq < freq && freq < bands[i].dl_maxfreq))
return -1;
return (freq - earfcn_table[i].dl_flow) / 100000UL + earfcn_table[i].dl_off;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
int int
......
...@@ -339,6 +339,8 @@ static void process_eNB_security_key ( ...@@ -339,6 +339,8 @@ static void process_eNB_security_key (
/* Saves the security key */ /* Saves the security key */
memcpy (ue_context_pP->ue_context.kenb, security_key_pP, SECURITY_KEY_LENGTH); memcpy (ue_context_pP->ue_context.kenb, 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++) { for (i = 0; i < 32; i++) {
sprintf(&ascii_buffer[2 * i], "%02X", ue_context_pP->ue_context.kenb[i]); sprintf(&ascii_buffer[2 * i], "%02X", ue_context_pP->ue_context.kenb[i]);
......
...@@ -42,11 +42,19 @@ ...@@ -42,11 +42,19 @@
#include "x2ap_eNB_generate_messages.h" #include "x2ap_eNB_generate_messages.h"
#include "x2ap_eNB_encoder.h" #include "x2ap_eNB_encoder.h"
#include "x2ap_eNB_itti_messaging.h" #include "x2ap_eNB_itti_messaging.h"
#include "RRC/LITE/defs.h"
#include "RRC/LITE/extern.h"
#include "secu_defs.h"
#include "rrc_eNB_UE_context.h"
#include "enb_config.h"
#include "msc.h" #include "msc.h"
#include "assertions.h" #include "assertions.h"
#include "conversions.h" #include "conversions.h"
extern unsigned char NB_eNB_INST;
extern int x2id_to_source_rnti[1];
int x2ap_eNB_generate_x2_setup_request(x2ap_eNB_instance_t *instance_p, int x2ap_eNB_generate_x2_setup_request(x2ap_eNB_instance_t *instance_p,
x2ap_eNB_data_t *x2ap_enb_data_p) x2ap_eNB_data_t *x2ap_enb_data_p)
...@@ -334,10 +342,34 @@ int x2ap_eNB_generate_x2_handover_request(x2ap_eNB_instance_t *instance_p, ...@@ -334,10 +342,34 @@ int x2ap_eNB_generate_x2_handover_request(x2ap_eNB_instance_t *instance_p,
INTPROTALG_TO_BIT_STRING(0,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms); INTPROTALG_TO_BIT_STRING(0,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms);
char KeNB_star[32] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 }; uint8_t KeNB_star[32] = { 0 };
// find UE context
// use hack defined in x2ap_eNB.c in x2ap_eNB_handle_handover_req(...):
if ((instance_p->instance < 0) || (instance_p->instance >= NB_eNB_INST)) {
X2AP_ERROR("Failed to find RRC eNB instance %d\n", instance_p->instance);
return -1;
}
eNB_RRC_INST* rrc_instance = &eNB_rrc_inst[instance_p->instance];
struct rrc_eNB_ue_context_s* rrc_eNB_ue_context = rrc_eNB_get_ue_context(rrc_instance, x2id_to_source_rnti[0]);
if (!rrc_eNB_ue_context) {
X2AP_ERROR("Failed to find RRC UE context RNTI %X\n", x2id_to_source_rnti[0]);
return -1;
}
const Enb_properties_array_t *enb_properties = enb_config_get();
uint16_t pci = enb_properties->properties[instance_p->instance]->Nid_cell[0];
uint32_t earfcn_dl = (uint32_t)freq_to_arfcn10(enb_properties->properties[instance_p->instance]->eutra_band[0],
enb_properties->properties[instance_p->instance]->downlink_frequency[0]);
if (rrc_eNB_ue_context->ue_context.nh_ncc >= 0) {
derive_keNB_star (rrc_eNB_ue_context->ue_context.nh, pci, earfcn_dl, false, KeNB_star);
message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = rrc_eNB_ue_context->ue_context.nh_ncc;
} else {
derive_keNB_star (rrc_eNB_ue_context->ue_context.kenb, pci, earfcn_dl, false, KeNB_star);
// LG: really 1 ?
message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = 1;
}
KENB_STAR_TO_BIT_STRING(KeNB_star,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.aS_SecurityInformation.key_eNodeB_star); KENB_STAR_TO_BIT_STRING(KeNB_star,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.aS_SecurityInformation.key_eNodeB_star);
message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = 1;
UEAGMAXBITRTD_TO_ASN_PRIMITIVES(3L,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink); UEAGMAXBITRTD_TO_ASN_PRIMITIVES(3L,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink);
UEAGMAXBITRTU_TO_ASN_PRIMITIVES(6L,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateUplink); UEAGMAXBITRTU_TO_ASN_PRIMITIVES(6L,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateUplink);
......
...@@ -63,3 +63,45 @@ int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB ...@@ -63,3 +63,45 @@ int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB
} }
#endif #endif
int
derive_keNB_star (
const uint8_t *kenb_32,
const uint16_t pci,
const uint32_t earfcn_dl,
const bool is_rel8_only,
uint8_t *kenb_star)
{
// see 33.401 section A.5 KeNB* derivation function
uint8_t s[10] = {0};
// FC = 0x13
s[0] = FC_KENB_STAR;
// P0 = PCI (target physical cell id)
s[1] = (pci & 0x0000ff00) >> 8;
s[2] = (pci & 0x000000ff);
// L0 = length of PCI (i.e. 0x00 0x02)
s[3] = 0x00;
s[4] = 0x02;
// P1 = EARFCN-DL (target physical cell downlink frequency)
if (is_rel8_only) {
s[5] = (earfcn_dl & 0x0000ff00) >> 8;
s[6] = (earfcn_dl & 0x000000ff);
s[7] = 0x00;
s[8] = 0x02;
kdf (kenb_32, 32, s, 9, kenb_star, 32);
} else {
s[5] = (earfcn_dl & 0x00ff0000) >> 16;
s[6] = (earfcn_dl & 0x0000ff00) >> 8;
s[7] = (earfcn_dl & 0x000000ff);
s[8] = 0x00;
s[9] = 0x03;
kdf (kenb_32, 32, s, 10, kenb_star, 32);
}
// L1 length of EARFCN-DL (i.e. L1 = 0x00 0x02 if EARFCN-DL is between 0 and 65535, and L1 = 0x00 0x03 if EARFCN-DL is between 65536 and 262143)
// NOTE: The length of EARFCN-DL cannot be generally set to 3 bytes for backward compatibility reasons: A Rel-8
// entity (UE or eNB) would always assume an input parameter length of 2 bytes for the EARFCN-DL. This
// would lead to different derived keys if another entity assumed an input parameter length of 3 bytes for the
// EARFCN-DL.
return 0;
}
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#define SECU_DEFS_H_ #define SECU_DEFS_H_
#include "security_types.h" #include "security_types.h"
#include <stdbool.h>
#define EIA0_ALG_ID 0x00 #define EIA0_ALG_ID 0x00
#define EIA1_128_ALG_ID 0x01 #define EIA1_128_ALG_ID 0x01
...@@ -44,6 +45,9 @@ void kdf(const uint8_t *key, ...@@ -44,6 +45,9 @@ void kdf(const uint8_t *key,
int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB); int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB);
int derive_keNB_star (const uint8_t *kenb_32, const uint16_t pci, const uint32_t earfcn_dl,
const bool is_rel8_only, uint8_t * kenb_star);
int derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id, int derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
const uint8_t kasme[32], uint8_t *knas); const uint8_t kasme[32], uint8_t *knas);
......
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