Commit 8baa1fe0 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Merge branch 'fix_naked_ptr_security_ctx' into 'develop'

Fix naked ptr for NAS security context

See merge request oai/cn5g/oai-cn5g-amf!200
parents f659ec6b 2cb03dbe
......@@ -218,17 +218,17 @@ void amf_n1::handle_itti_message(itti_downlink_nas_transfer& itti_msg) {
amf_ue_ngap_id);
return;
}
nas_secu_ctx* secu = nc->security_ctx;
if (!secu) {
if (!nc->security_ctx.has_value()) {
Logger::amf_n1().error("No Security Context found");
return;
}
bstring protected_nas = nullptr;
encode_nas_message_protected(
secu, false, INTEGRITY_PROTECTED_AND_CIPHERED, NAS_MESSAGE_DOWNLINK,
(uint8_t*) bdata(itti_msg.dl_nas), blength(itti_msg.dl_nas),
protected_nas);
nc->security_ctx.value(), false, INTEGRITY_PROTECTED_AND_CIPHERED,
NAS_MESSAGE_DOWNLINK, (uint8_t*) bdata(itti_msg.dl_nas),
blength(itti_msg.dl_nas), protected_nas);
if (itti_msg.is_n2sm_set) {
// PDU Session Resource Release Command
......@@ -316,19 +316,25 @@ void amf_n1::handle_itti_message(itti_downlink_nas_transfer& itti_msg) {
}
} else {
// send using InitialContextSetupRequest
uint8_t* kamf = nc->kamf[secu->vector_pointer];
uint8_t kgnb[32];
uint32_t ulcount =
secu->ul_count.seq_num | (secu->ul_count.overflow << 8);
Authentication_5gaka::derive_kgnb(0, 0x01, kamf, kgnb);
output_wrapper::print_buffer("amf_n1", "Kamf", kamf, 32);
uint8_t kamf[AUTH_VECTOR_LENGTH_OCTETS];
uint8_t kgnb[AUTH_VECTOR_LENGTH_OCTETS];
if (!nc->get_kamf(nc->security_ctx.value().vector_pointer, kamf)) {
Logger::amf_n1().warn("No Kamf found");
return;
}
uint32_t ulcount = nc->security_ctx.value().ul_count.seq_num |
(nc->security_ctx.value().ul_count.overflow << 8);
Authentication_5gaka::derive_kgnb(
0, 0x01, kamf, kgnb); // TODO: remove hardcoded value
output_wrapper::print_buffer(
"amf_n1", "Kamf", kamf, AUTH_VECTOR_LENGTH_OCTETS);
std::shared_ptr<itti_initial_context_setup_request> csr =
std::make_shared<itti_initial_context_setup_request>(
TASK_AMF_N1, TASK_AMF_N2);
csr->ran_ue_ngap_id = ran_ue_ngap_id;
csr->amf_ue_ngap_id = amf_ue_ngap_id;
csr->kgnb = blk2bstr(kgnb, 32);
csr->kgnb = blk2bstr(kgnb, AUTH_VECTOR_LENGTH_OCTETS);
csr->nas = protected_nas;
csr->pdu_session_id = itti_msg.pdu_session_id;
csr->is_pdu_exist = true;
......@@ -460,14 +466,14 @@ void amf_n1::handle_itti_message(itti_uplink_nas_data_ind& nas_data_ind) {
"Abnormal condition: NAS context does not exist ...");
return;
}
if (!nc->security_ctx) {
if (!nc->security_ctx.has_value()) {
Logger::amf_n1().error("No Security Context found");
return;
}
uint32_t mac32 = 0;
if (!nas_message_integrity_protected(
nc->security_ctx, NAS_MESSAGE_UPLINK,
nc->security_ctx.value(), NAS_MESSAGE_UPLINK,
(uint8_t*) bdata(received_nas_msg) + 6,
blength(received_nas_msg) - 6, mac32)) {
Logger::amf_n1().debug("IA0_5G");
......@@ -481,7 +487,7 @@ void amf_n1::handle_itti_message(itti_uplink_nas_data_ind& nas_data_ind) {
if (mac32 == mac32_recv) {
isMatched = true;
Logger::amf_n1().debug("Integrity matched");
// nc->security_ctx->ul_count.seq_num ++;
// nc->security_ctx.value().ul_count.seq_num ++;
}
if (!isMatched) {
Logger::amf_n1().error("Received message not integrity matched");
......@@ -493,7 +499,7 @@ void amf_n1::handle_itti_message(itti_uplink_nas_data_ind& nas_data_ind) {
(uint8_t*) bdata(received_nas_msg) + 7,
blength(received_nas_msg) - 7);
if (!nas_message_cipher_protected(
nc->security_ctx, NAS_MESSAGE_UPLINK, ciphered,
nc->security_ctx.value(), NAS_MESSAGE_UPLINK, ciphered,
decoded_plain_msg)) {
Logger::amf_n1().error("Decrypt NAS message failure");
bdestroy_wrapper(&ciphered);
......@@ -586,12 +592,13 @@ void amf_n1::nas_signalling_establishment_request_handle(
Logger::amf_n1().error("No NAS Context found");
return;
}
/* if (!nc->security_ctx) {
/* if (!nc->security_ctx.has_value()) {
Logger::amf_n1().error("No Security Context found");
return;
}
*/
if (nc && nc->security_ctx) nc->security_ctx->ul_count.seq_num = ulCount;
if (nc && nc->security_ctx.has_value())
nc->security_ctx.value().ul_count.seq_num = ulCount;
service_request_handle(nc, ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
} break;
......@@ -836,13 +843,15 @@ void amf_n1::service_request_handle(
"GUTI %s, 5G-TMSI %s", guti.c_str(), tmsi.c_str());
std::shared_ptr<nas_context> old_nc = {};
if (guti_2_nas_context(guti, old_nc)) {
// nc->security_ctx = old_nc->security_ctx;
// nc->security_ctx =
// std::make_optional<nas_secu_ctx>(old_nc->security_ctx.value);
}
}
}
// If there's no appropriate context, send Service Reject
if (!nc or !uc or !nc->security_ctx or (decoded_size == KEncodeDecodeError)) {
if (!nc or !uc or !nc->security_ctx.has_value() or
(decoded_size == KEncodeDecodeError)) {
// TODO: Try to get
Logger::amf_n1().debug(
"Cannot find NAS/UE context, send Service Reject to UE");
......@@ -878,8 +887,8 @@ void amf_n1::service_request_handle(
// Otherwise, continue to process Service Request message
set_amf_ue_ngap_id_2_nas_context(amf_ue_ngap_id, nc);
nas_secu_ctx* secu = nc->security_ctx; // TODO: remove naked ptr
if (!secu) {
if (!nc->security_ctx.has_value()) {
Logger::amf_n1().error("No Security Context found");
return;
}
......@@ -984,14 +993,23 @@ void amf_n1::service_request_handle(
int encoded_size = service_accept->Encode(buffer, BUFFER_SIZE_256);
bstring protected_nas = nullptr;
encode_nas_message_protected(
secu, false, INTEGRITY_PROTECTED_AND_CIPHERED, NAS_MESSAGE_DOWNLINK,
buffer, encoded_size, protected_nas);
uint8_t* kamf = nc->kamf[secu->vector_pointer];
uint8_t kgnb[32];
uint32_t ulcount = secu->ul_count.seq_num | (secu->ul_count.overflow << 8);
Logger::amf_n1().debug("uplink count(%d)", secu->ul_count.seq_num);
output_wrapper::print_buffer("amf_n1", "Kamf", kamf, 32);
Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
nc->security_ctx.value(), false, INTEGRITY_PROTECTED_AND_CIPHERED,
NAS_MESSAGE_DOWNLINK, buffer, encoded_size, protected_nas);
uint8_t kamf[AUTH_VECTOR_LENGTH_OCTETS];
uint8_t kgnb[AUTH_VECTOR_LENGTH_OCTETS];
if (!nc->get_kamf(nc->security_ctx.value().vector_pointer, kamf)) {
Logger::amf_n1().warn("No Kamf found");
return;
}
uint32_t ulcount = nc->security_ctx.value().ul_count.seq_num |
(nc->security_ctx.value().ul_count.overflow << 8);
Logger::amf_n1().debug(
"uplink count(%d)", nc->security_ctx.value().ul_count.seq_num);
output_wrapper::print_buffer(
"amf_n1", "Kamf", kamf, AUTH_VECTOR_LENGTH_OCTETS);
Authentication_5gaka::derive_kgnb(
ulcount, 0x01, kamf, kgnb); // TODO: remove hardcoded value
std::shared_ptr<itti_initial_context_setup_request> itti_msg =
std::make_shared<itti_initial_context_setup_request>(
......@@ -999,7 +1017,7 @@ void amf_n1::service_request_handle(
itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
itti_msg->amf_ue_ngap_id = amf_ue_ngap_id;
itti_msg->nas = bstrcpy(protected_nas);
itti_msg->kgnb = blk2bstr(kgnb, 32);
itti_msg->kgnb = blk2bstr(kgnb, AUTH_VECTOR_LENGTH_OCTETS);
itti_msg->is_sr = true; // Service Request indicator
itti_msg->is_pdu_exist = false;
......@@ -1033,14 +1051,23 @@ void amf_n1::service_request_handle(
int encoded_size = service_accept->Encode(buffer, BUFFER_SIZE_256);
bstring protected_nas = nullptr;
encode_nas_message_protected(
secu, false, INTEGRITY_PROTECTED_AND_CIPHERED, NAS_MESSAGE_DOWNLINK,
buffer, encoded_size, protected_nas);
uint8_t* kamf = nc->kamf[secu->vector_pointer];
uint8_t kgnb[32];
uint32_t ulcount = secu->ul_count.seq_num | (secu->ul_count.overflow << 8);
Logger::amf_n1().debug("uplink count(%d)", secu->ul_count.seq_num);
output_wrapper::print_buffer("amf_n1", "Kamf", kamf, 32);
Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
nc->security_ctx.value(), false, INTEGRITY_PROTECTED_AND_CIPHERED,
NAS_MESSAGE_DOWNLINK, buffer, encoded_size, protected_nas);
uint8_t kamf[AUTH_VECTOR_LENGTH_OCTETS];
uint8_t kgnb[AUTH_VECTOR_LENGTH_OCTETS];
if (!nc->get_kamf(nc->security_ctx.value().vector_pointer, kamf)) {
Logger::amf_n1().warn("No Kamf found");
return;
}
uint32_t ulcount = nc->security_ctx.value().ul_count.seq_num |
(nc->security_ctx.value().ul_count.overflow << 8);
Logger::amf_n1().debug(
"uplink count(%d)", nc->security_ctx.value().ul_count.seq_num);
output_wrapper::print_buffer(
"amf_n1", "Kamf", kamf, AUTH_VECTOR_LENGTH_OCTETS);
Authentication_5gaka::derive_kgnb(
ulcount, 0x01, kamf, kgnb); // TODO: remove hardcoded value
std::shared_ptr<itti_initial_context_setup_request> itti_msg =
std::make_shared<itti_initial_context_setup_request>(
......@@ -1048,7 +1075,7 @@ void amf_n1::service_request_handle(
itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
itti_msg->amf_ue_ngap_id = amf_ue_ngap_id;
itti_msg->nas = bstrcpy(protected_nas);
itti_msg->kgnb = blk2bstr(kgnb, 32);
itti_msg->kgnb = blk2bstr(kgnb, AUTH_VECTOR_LENGTH_OCTETS);
itti_msg->is_sr = true; // Service Request indicator
itti_msg->pdu_session_id = pdu_session_id;
itti_msg->is_pdu_exist = true;
......@@ -1193,8 +1220,8 @@ void amf_n1::registration_request_handle(
set_supi_2_ran_id(supi, ran_ue_ngap_id);
nc->is_auth_vectors_present = false;
nc->is_current_security_available = false;
if (nc->security_ctx)
nc->security_ctx->sc_type = SECURITY_CTX_TYPE_NOT_AVAILABLE;
if (nc->security_ctx.has_value())
nc->security_ctx.value().sc_type = SECURITY_CTX_TYPE_NOT_AVAILABLE;
} else {
Logger::amf_n1().debug(
"No existing nas_context with amf_ue_ngap_id (" AMF_UE_NGAP_ID_FMT
......@@ -1260,8 +1287,8 @@ void amf_n1::registration_request_handle(
nc->is_auth_vectors_present = false;
nc->is_current_security_available = false;
if (nc->security_ctx)
nc->security_ctx->sc_type = SECURITY_CTX_TYPE_NOT_AVAILABLE;
if (nc->security_ctx.has_value())
nc->security_ctx.value().sc_type = SECURITY_CTX_TYPE_NOT_AVAILABLE;
} else {
Logger::amf_n1().error("No nas_context with GUTI (%s)", guti.c_str());
send_registration_reject_msg(
......@@ -1292,8 +1319,8 @@ void amf_n1::registration_request_handle(
nc->amf_ue_ngap_id = amf_ue_ngap_id;
nc->serving_network = snn;
if (nc->security_ctx)
nc->security_ctx->sc_type = SECURITY_CTX_TYPE_NOT_AVAILABLE;
if (nc->security_ctx.has_value())
nc->security_ctx.value().sc_type = SECURITY_CTX_TYPE_NOT_AVAILABLE;
// Update UE context
if (uc != nullptr) {
......@@ -1671,7 +1698,7 @@ void amf_n1::run_registration_procedure(std::shared_ptr<nas_context>& nc) {
"Authentication vector in nas_context is not available");
if (auth_vectors_generator(nc)) { // all authentication in one (AMF)
ngksi_t ngksi = 0;
if (nc->security_ctx &&
if (nc->security_ctx.has_value() &&
nc->ngksi != NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE) {
// ngksi = (nc->ngksi + 1) % (NGKSI_MAX_VALUE + 1);
ngksi = (nc->amf_ue_ngap_id + 1); // % (NGKSI_MAX_VALUE + 1);
......@@ -1688,7 +1715,7 @@ void amf_n1::run_registration_procedure(std::shared_ptr<nas_context>& nc) {
Logger::amf_n1().debug(
"Authentication Vector in nas_context is available");
ngksi_t ngksi = 0;
if (nc->security_ctx &&
if (nc->security_ctx.has_value() &&
nc->ngksi != NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE) {
// ngksi = (nc->ngksi + 1) % (NGKSI_MAX_VALUE + 1);
ngksi = (nc->amf_ue_ngap_id + 1); // % (NGKSI_MAX_VALUE + 1);
......@@ -1739,6 +1766,7 @@ bool amf_n1::auth_vectors_generator(std::shared_ptr<nas_context>& nc) {
Authentication_5gaka::derive_kamf(
nc->imsi, nc->_5g_av[i].kseaf, nc->kamf[i],
0x0000); // second parameter: abba
// TODO: remove hardcoded value
}
}
return true;
......@@ -1882,9 +1910,10 @@ bool amf_n1::_5g_aka_confirmation_from_ausf(
if (!confirmationdataresponse.kseafIsSet()) return false;
unsigned char* kseaf_hex =
conv::format_string_as_hex(confirmationdataresponse.getKseaf());
memcpy(nc->_5g_av[0].kseaf, kseaf_hex, 32);
memcpy(nc->_5g_av[0].kseaf, kseaf_hex, AUTH_VECTOR_LENGTH_OCTETS);
output_wrapper::print_buffer(
"amf_n1", "5G AV: kseaf", nc->_5g_av[0].kseaf, 32);
"amf_n1", "5G AV: kseaf", nc->_5g_av[0].kseaf,
AUTH_VECTOR_LENGTH_OCTETS);
free_wrapper((void**) &kseaf_hex);
Logger::amf_n1().debug("Deriving Kamf");
......@@ -1892,7 +1921,8 @@ bool amf_n1::_5g_aka_confirmation_from_ausf(
Authentication_5gaka::derive_kamf(
nc->imsi, nc->_5g_av[i].kseaf, nc->kamf[i],
0x0000); // second parameter: abba
output_wrapper::print_buffer("amf_n1", "Kamf", nc->kamf[i], 32);
output_wrapper::print_buffer(
"amf_n1", "Kamf", nc->kamf[i], AUTH_VECTOR_LENGTH_OCTETS);
}
} catch (nlohmann::json::exception& e) {
Logger::amf_n1().info("Could not get JSON content from AUSF response");
......@@ -1917,15 +1947,16 @@ bool amf_n1::authentication_vectors_generator_in_ausf(
memcpy(&inputString[i][0], rand[i], 16);
memcpy(&inputString[i][16], xresStar[i], 16);
unsigned char sha256Out[Sha256::DIGEST_SIZE];
sha256((unsigned char*) inputString[i], 32, sha256Out);
sha256(
(unsigned char*) inputString[i], AUTH_VECTOR_LENGTH_OCTETS, sha256Out);
for (int j = 0; j < 16; j++)
nc->_5g_av[i].hxresStar[j] = (uint8_t) sha256Out[j];
memcpy(nc->_5g_av[i].rand, nc->_5g_he_av[i].rand, 16);
memcpy(nc->_5g_av[i].autn, nc->_5g_he_av[i].autn, 16);
uint8_t kseaf[32];
uint8_t kseaf[AUTH_VECTOR_LENGTH_OCTETS];
Authentication_5gaka::derive_kseaf(
nc->serving_network, nc->_5g_he_av[i].kausf, kseaf);
memcpy(nc->_5g_av[i].kseaf, kseaf, 32);
memcpy(nc->_5g_av[i].kseaf, kseaf, AUTH_VECTOR_LENGTH_OCTETS);
}
return true;
}
......@@ -2055,7 +2086,7 @@ void amf_n1::generate_5g_he_av_in_udm(
ck, ik, serving_network, sqn, ak,
vector.kausf); // derive Kausf
// output_wrapper::print_buffer("amf_n1", "Result For KDF: Kausf(5G HE AV)",
// vector.kausf, 32);
// vector.kausf, AUTH_VECTOR_LENGTH_OCTETS);
Logger::amf_n1().debug("Generate_5g_he_av_in_udm finished!");
return;
}
......@@ -2093,14 +2124,16 @@ void amf_n1::annex_a_4_33501(
oldS[33] = 0x08;
output_wrapper::print_buffer(
"amf_n1", "Input string: ", S, 31 + netName.size);
uint8_t key[32];
uint8_t key[AUTH_VECTOR_LENGTH_OCTETS];
memcpy(&key[0], ck, 16);
memcpy(&key[16], ik, 16); // KEY
// Authentication_5gaka::kdf(key, 32, oldS, 33, output, 16);
uint8_t out[32];
// Authentication_5gaka::kdf(key, AUTH_VECTOR_LENGTH_OCTETS, oldS, 33, output,
// 16);
uint8_t out[AUTH_VECTOR_LENGTH_OCTETS];
Authentication_5gaka::kdf(key, 32, S, 31 + netName.size, out, 32);
for (int i = 0; i < 16; i++) output[i] = out[16 + i];
output_wrapper::print_buffer("amf_n1", "XRES*(new)", out, 32);
output_wrapper::print_buffer(
"amf_n1", "XRES*(new)", out, AUTH_VECTOR_LENGTH_OCTETS);
}
//------------------------------------------------------------------------------
......@@ -2110,15 +2143,16 @@ void amf_n1::handle_auth_vector_successful_result(
"Received Security Vectors, try to setup security with the UE");
nc->is_auth_vectors_present = true;
ngksi_t ngksi = 0;
if (!nc->security_ctx) {
nc->security_ctx = new nas_secu_ctx();
nc->security_ctx->sc_type = SECURITY_CTX_TYPE_NOT_AVAILABLE;
if (nc->security_ctx && nc->ngksi != NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE)
if (!nc->security_ctx.has_value()) {
nc->security_ctx = std::make_optional<nas_secu_ctx>();
nc->security_ctx.value().sc_type = SECURITY_CTX_TYPE_NOT_AVAILABLE;
if (nc->security_ctx.has_value() &&
nc->ngksi != NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE)
ngksi = (nc->amf_ue_ngap_id + 1) % (NGKSI_MAX_VALUE + 1);
// ensure which vector is available?
nc->ngksi = ngksi;
}
int vindex = nc->security_ctx->vector_pointer;
int vindex = nc->security_ctx.value().vector_pointer;
if (!start_authentication_procedure(nc, vindex, nc->ngksi)) {
Logger::amf_n1().error("Start Authentication Procedure Failure, reject...");
Logger::amf_n1().error(
......@@ -2239,7 +2273,8 @@ void amf_n1::authentication_response_handle(
} else {
// Get stored XRES*
int secu_index = 0;
if (nc->security_ctx) secu_index = nc->security_ctx->vector_pointer;
if (nc->security_ctx.has_value())
secu_index = nc->security_ctx.value().vector_pointer;
uint8_t* hxresStar = nc->_5g_av[secu_index].hxresStar;
// Calculate HRES* from received RES*, then compare with XRES stored in
......@@ -2353,8 +2388,14 @@ void amf_n1::authentication_failure_handle(
// select new ngKSI and resend Authentication Request
ngksi_t ngksi =
(nc->ngksi + 1) % (NGKSI_MAX_VALUE + 1); // To be verified
nc->ngksi = ngksi;
int vindex = nc->security_ctx->vector_pointer;
nc->ngksi = ngksi;
if (!nc->security_ctx.has_value()) {
Logger::amf_n2().error("No Security Context found");
// TODO:
return;
}
int vindex = nc->security_ctx.value().vector_pointer;
if (!start_authentication_procedure(nc, vindex, nc->ngksi)) {
Logger::amf_n1().error(
"Start Authentication procedure failure, reject...");
......@@ -2380,34 +2421,36 @@ bool amf_n1::start_security_mode_control_procedure(
uint8_t amf_nea = EA0_5G;
uint8_t amf_nia = IA0_5G;
// Decide which ea/ia alg used by UE, which is supported by network
nas_secu_ctx* secu_ctx = nc->security_ctx;
if (!secu_ctx) {
if (!nc->security_ctx.has_value()) {
Logger::amf_n1().error("No Security Context found");
return false;
}
if (secu_ctx->sc_type == SECURITY_CTX_TYPE_NOT_AVAILABLE &&
if (nc->security_ctx.value().sc_type == SECURITY_CTX_TYPE_NOT_AVAILABLE &&
nc->is_common_procedure_for_security_mode_control_running) {
Logger::amf_n1().debug(
"Using INTEGRITY_PROTECTED_WITH_NEW_SECU_CTX for SecurityModeControl "
"message");
secu_ctx->ngksi = nc->ngksi;
secu_ctx->dl_count.overflow = 0;
secu_ctx->dl_count.seq_num = 0;
secu_ctx->ul_count.overflow = 0;
secu_ctx->ul_count.seq_num = 0;
nc->security_ctx.value().ngksi = nc->ngksi;
nc->security_ctx.value().dl_count.overflow = 0;
nc->security_ctx.value().dl_count.seq_num = 0;
nc->security_ctx.value().ul_count.overflow = 0;
nc->security_ctx.value().ul_count.seq_num = 0;
security_select_algorithms(
nc->ue_security_capability.GetEa(), nc->ue_security_capability.GetIa(),
amf_nea, amf_nia);
secu_ctx->nas_algs.integrity = amf_nia;
secu_ctx->nas_algs.encryption = amf_nea;
secu_ctx->sc_type = SECURITY_CTX_TYPE_FULL_NATIVE;
nc->security_ctx.value().nas_algs.integrity = amf_nia;
nc->security_ctx.value().nas_algs.encryption = amf_nea;
nc->security_ctx.value().sc_type = SECURITY_CTX_TYPE_FULL_NATIVE;
Authentication_5gaka::derive_knas(
NAS_INT_ALG, secu_ctx->nas_algs.integrity,
nc->kamf[secu_ctx->vector_pointer], secu_ctx->knas_int);
NAS_INT_ALG, nc->security_ctx.value().nas_algs.integrity,
nc->kamf[nc->security_ctx.value().vector_pointer],
nc->security_ctx.value().knas_int);
Authentication_5gaka::derive_knas(
NAS_ENC_ALG, secu_ctx->nas_algs.encryption,
nc->kamf[secu_ctx->vector_pointer], secu_ctx->knas_enc);
NAS_ENC_ALG, nc->security_ctx.value().nas_algs.encryption,
nc->kamf[nc->security_ctx.value().vector_pointer],
nc->security_ctx.value().knas_enc);
security_context_is_new = true;
nc->is_current_security_available = true;
}
......@@ -2431,8 +2474,9 @@ bool amf_n1::start_security_mode_control_procedure(
bstring protected_nas = nullptr;
encode_nas_message_protected(
secu_ctx, security_context_is_new, INTEGRITY_PROTECTED_WITH_NEW_SECU_CTX,
NAS_MESSAGE_DOWNLINK, buffer, encoded_size, protected_nas);
nc->security_ctx.value(), security_context_is_new,
INTEGRITY_PROTECTED_WITH_NEW_SECU_CTX, NAS_MESSAGE_DOWNLINK, buffer,
encoded_size, protected_nas);
output_wrapper::print_buffer(
"amf_n1", "Encrypted Security-Mode-Command message buffer",
(uint8_t*) bdata(protected_nas), blength(protected_nas));
......@@ -2652,16 +2696,16 @@ void amf_n1::security_mode_complete_handle(
set_guti_2_nas_context(guti, nc);
nc->is_common_procedure_for_security_mode_control_running = false;
nas_secu_ctx* secu = nc->security_ctx;
if (!secu) {
if (!nc->security_ctx.has_value()) {
Logger::amf_n1().error("No Security Context found");
return;
}
bstring protected_nas = nullptr;
encode_nas_message_protected(
secu, false, INTEGRITY_PROTECTED_AND_CIPHERED, NAS_MESSAGE_DOWNLINK,
buffer, encoded_size, protected_nas);
nc->security_ctx.value(), false, INTEGRITY_PROTECTED_AND_CIPHERED,
NAS_MESSAGE_DOWNLINK, buffer, encoded_size, protected_nas);
if (!uc->is_ue_context_request) {
Logger::amf_n1().debug(
......@@ -2691,20 +2735,25 @@ void amf_n1::security_mode_complete_handle(
} else {
// use InitialContextSetupRequest (NGAP message) to convey Registration
// Accept
uint8_t* kamf = nc->kamf[secu->vector_pointer];
uint8_t kgnb[32];
uint32_t ulcount = secu->ul_count.seq_num | (secu->ul_count.overflow << 8);
Authentication_5gaka::derive_kgnb(0, 0x01, kamf, kgnb);
output_wrapper::print_buffer("amf_n1", "Kamf", kamf, 32);
// Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
uint8_t kamf[AUTH_VECTOR_LENGTH_OCTETS];
uint8_t kgnb[AUTH_VECTOR_LENGTH_OCTETS];
if (!nc->get_kamf(nc->security_ctx.value().vector_pointer, kamf)) {
Logger::amf_n1().warn("No Kamf found");
return;
}
uint32_t ulcount = nc->security_ctx.value().ul_count.seq_num |
(nc->security_ctx.value().ul_count.overflow << 8);
Authentication_5gaka::derive_kgnb(
0, 0x01, kamf, kgnb); // TODO: remove harcoded value
output_wrapper::print_buffer(
"amf_n1", "Kamf", kamf, AUTH_VECTOR_LENGTH_OCTETS);
std::shared_ptr<itti_initial_context_setup_request> itti_msg =
std::make_shared<itti_initial_context_setup_request>(
TASK_AMF_N1, TASK_AMF_N2);
itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
itti_msg->amf_ue_ngap_id = amf_ue_ngap_id;
itti_msg->kgnb = blk2bstr(kgnb, 32);
itti_msg->kgnb = blk2bstr(kgnb, AUTH_VECTOR_LENGTH_OCTETS);
itti_msg->nas = protected_nas;
itti_msg->is_pdu_exist = false; // no pdu context
itti_msg->is_sr = false; // TODO: for Service Request procedure
......@@ -2746,8 +2795,7 @@ void amf_n1::registration_complete_handle(
return;
}
nas_secu_ctx* secu = nc->security_ctx;
if (!secu) {
if (!nc->security_ctx.has_value()) {
Logger::amf_n1().error("No Security Context found");
return;
}
......@@ -2792,8 +2840,8 @@ void amf_n1::registration_complete_handle(
// Protect NAS message
bstring protected_nas = nullptr;
encode_nas_message_protected(
secu, false, INTEGRITY_PROTECTED_AND_CIPHERED, NAS_MESSAGE_DOWNLINK,
buffer, encoded_size, protected_nas);
security_ctx.value(), false, INTEGRITY_PROTECTED_AND_CIPHERED,
NAS_MESSAGE_DOWNLINK, buffer, encoded_size, protected_nas);
std::shared_ptr<itti_dl_nas_transport> dnt =
std::make_shared<itti_dl_nas_transport>(TASK_AMF_N1, TASK_AMF_N2);
......@@ -2812,7 +2860,7 @@ void amf_n1::registration_complete_handle(
//------------------------------------------------------------------------------
void amf_n1::encode_nas_message_protected(
nas_secu_ctx* nsc, bool is_secu_ctx_new, uint8_t security_header_type,
nas_secu_ctx& nsc, bool is_secu_ctx_new, uint8_t security_header_type,
uint8_t direction, uint8_t* input_nas_buf, int input_nas_len,
bstring& protected_nas) {
Logger::amf_n1().debug("Encoding nas_message_protected...");
......@@ -2830,7 +2878,7 @@ void amf_n1::encode_nas_message_protected(
nas_message_cipher_protected(nsc, NAS_MESSAGE_DOWNLINK, input, ciphered);
protected_nas_buf[0] = EPD_5GS_MM_MSG;
protected_nas_buf[1] = INTEGRITY_PROTECTED_AND_CIPHERED;
protected_nas_buf[6] = (uint8_t) nsc->dl_count.seq_num;
protected_nas_buf[6] = (uint8_t) nsc.dl_count.seq_num;
uint8_t* buf_tmp = (uint8_t*) bdata(ciphered);
if (buf_tmp != nullptr)
......@@ -2852,13 +2900,13 @@ void amf_n1::encode_nas_message_protected(
} break;
case INTEGRITY_PROTECTED_WITH_NEW_SECU_CTX: {
if ((nsc == nullptr) || !is_secu_ctx_new) {
if (!is_secu_ctx_new) {
Logger::amf_n1().error("Security context is too old");
return;
}
protected_nas_buf[0] = EPD_5GS_MM_MSG;
protected_nas_buf[1] = INTEGRITY_PROTECTED_WITH_NEW_SECU_CTX;
protected_nas_buf[6] = (uint8_t) nsc->dl_count.seq_num;
protected_nas_buf[6] = (uint8_t) nsc.dl_count.seq_num;
memcpy(&protected_nas_buf[7], input_nas_buf, input_nas_len);
uint32_t mac32 = {};
if (!(nas_message_integrity_protected(
......@@ -2877,34 +2925,33 @@ void amf_n1::encode_nas_message_protected(
} break;
}
protected_nas = blk2bstr(protected_nas_buf, encoded_size);
nsc->dl_count.seq_num++;
nsc.dl_count.seq_num++;
}
//------------------------------------------------------------------------------
bool amf_n1::nas_message_integrity_protected(
nas_secu_ctx* nsc, uint8_t direction, uint8_t* input_nas, int input_nas_len,
nas_secu_ctx& nsc, uint8_t direction, uint8_t* input_nas, int input_nas_len,
uint32_t& mac32) {
if (nsc == nullptr) return false;
uint32_t count = 0x00000000;
if (direction) {
count = 0x00000000 | ((nsc->dl_count.overflow & 0x0000ffff) << 8) |
((nsc->dl_count.seq_num & 0x000000ff));
count = 0x00000000 | ((nsc.dl_count.overflow & 0x0000ffff) << 8) |
((nsc.dl_count.seq_num & 0x000000ff));
} else {
count = 0x00000000 | ((nsc->ul_count.overflow & 0x0000ffff) << 8) |
((nsc->ul_count.seq_num & 0x000000ff));
count = 0x00000000 | ((nsc.ul_count.overflow & 0x0000ffff) << 8) |
((nsc.ul_count.seq_num & 0x000000ff));
}
nas_stream_cipher_t stream_cipher = {0};
uint8_t mac[4];
stream_cipher.key = nsc->knas_int;
stream_cipher.key = nsc.knas_int;
output_wrapper::print_buffer(
"amf_n1", "Parameters for NIA: Knas_int", nsc->knas_int,
"amf_n1", "Parameters for NIA: Knas_int", nsc.knas_int,
AUTH_KNAS_INT_SIZE);
stream_cipher.key_length = AUTH_KNAS_INT_SIZE;
stream_cipher.count = *(input_nas);
// stream_cipher.count = count;
if (!direction) {
nsc->ul_count.seq_num = stream_cipher.count;
Logger::amf_n1().debug("Uplink count in uplink: %d", nsc->ul_count.seq_num);
nsc.ul_count.seq_num = stream_cipher.count;
Logger::amf_n1().debug("Uplink count in uplink: %d", nsc.ul_count.seq_num);
}
Logger::amf_n1().debug("Parameters for NIA, count: 0x%x", count);
stream_cipher.bearer = 0x01; // 33.501 section 8.1.1
......@@ -2917,7 +2964,7 @@ bool amf_n1::nas_message_integrity_protected(
"amf_n1", "Parameters for NIA, message: ", input_nas, input_nas_len);
stream_cipher.blength = input_nas_len * 8;
switch (nsc->nas_algs.integrity & 0x0f) {
switch (nsc.nas_algs.integrity & 0x0f) {
case IA0_5G: {
Logger::amf_n1().debug("Integrity with algorithms: 5G-IA0");
return false; // plain msg
......@@ -2946,22 +2993,22 @@ bool amf_n1::nas_message_integrity_protected(
//------------------------------------------------------------------------------
bool amf_n1::nas_message_cipher_protected(
nas_secu_ctx* nsc, uint8_t direction, bstring input_nas,
nas_secu_ctx& nsc, uint8_t direction, bstring input_nas,
bstring& output_nas) {
uint8_t* buf = (uint8_t*) bdata(input_nas);
int buf_len = blength(input_nas);
uint32_t count = 0x00000000;
if (direction) {
count = 0x00000000 | ((nsc->dl_count.overflow & 0x0000ffff) << 8) |
((nsc->dl_count.seq_num & 0x000000ff));
count = 0x00000000 | ((nsc.dl_count.overflow & 0x0000ffff) << 8) |
((nsc.dl_count.seq_num & 0x000000ff));
} else {
Logger::amf_n1().debug("nsc->ul_count.overflow %x", nsc->ul_count.overflow);
count = 0x00000000 | ((nsc->ul_count.overflow & 0x0000ffff) << 8) |
((nsc->ul_count.seq_num & 0x000000ff));
Logger::amf_n1().debug("nsc.ul_count.overflow %x", nsc.ul_count.overflow);
count = 0x00000000 | ((nsc.ul_count.overflow & 0x0000ffff) << 8) |
((nsc.ul_count.seq_num & 0x000000ff));
}
nas_stream_cipher_t stream_cipher = {0};
uint8_t mac[4];
stream_cipher.key = nsc->knas_enc;
stream_cipher.key = nsc.knas_enc;
stream_cipher.key_length = AUTH_KNAS_ENC_SIZE;
stream_cipher.count = count;
stream_cipher.bearer = 0x01; // 33.501 section 8.1.1
......@@ -2969,7 +3016,7 @@ bool amf_n1::nas_message_cipher_protected(
stream_cipher.message = (uint8_t*) bdata(input_nas);
stream_cipher.blength = blength(input_nas) << 3;
switch (nsc->nas_algs.encryption & 0x0f) {
switch (nsc.nas_algs.encryption & 0x0f) {
case EA0_5G: {
Logger::amf_n1().debug("Cipher protected with EA0_5G");
output_nas = blk2bstr(buf, buf_len);
......@@ -3384,8 +3431,7 @@ void amf_n1::run_mobility_registration_update_procedure(
return;
}
nas_secu_ctx* secu = nc->security_ctx;
if (!secu) {
if (!nc->security_ctx.has_value()) {
Logger::amf_n1().warn("No Security Context found");
// Run Registration procedure
// run_registration_procedure(nc);
......@@ -3414,8 +3460,8 @@ void amf_n1::run_mobility_registration_update_procedure(
// protect nas message
bstring protected_nas = nullptr;
encode_nas_message_protected(
secu, false, INTEGRITY_PROTECTED_AND_CIPHERED, NAS_MESSAGE_DOWNLINK,
buffer, encoded_size, protected_nas);
nc->security_ctx.value(), false, INTEGRITY_PROTECTED_AND_CIPHERED,
NAS_MESSAGE_DOWNLINK, buffer, encoded_size, protected_nas);
// get PDU session status
std::vector<uint8_t> pdu_session_to_be_activated = {};
......@@ -3428,23 +3474,25 @@ void amf_n1::run_mobility_registration_update_procedure(
uc->find_pdu_session_context(pdu_session_to_be_activated[0], psc);
}
uint8_t* kamf = nc->kamf[secu->vector_pointer];
if (!kamf) {
Logger::amf_n1().error("No Kamf found");
uint8_t kamf[AUTH_VECTOR_LENGTH_OCTETS];
uint8_t kgnb[AUTH_VECTOR_LENGTH_OCTETS];
if (!nc->get_kamf(nc->security_ctx.value().vector_pointer, kamf)) {
Logger::amf_n1().warn("No Kamf found");
return;
}
uint8_t kgnb[32];
uint32_t ulcount = secu->ul_count.seq_num | (secu->ul_count.overflow << 8);
Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
output_wrapper::print_buffer("amf_n1", "Kamf", kamf, 32);
uint32_t ulcount = nc->security_ctx.value().ul_count.seq_num |
(nc->security_ctx.value().ul_count.overflow << 8);
Authentication_5gaka::derive_kgnb(
ulcount, 0x01, kamf, kgnb); // TODO: remove hardcoded value
output_wrapper::print_buffer(
"amf_n1", "Kamf", kamf, AUTH_VECTOR_LENGTH_OCTETS);
std::shared_ptr<itti_initial_context_setup_request> itti_msg =
std::make_shared<itti_initial_context_setup_request>(
TASK_AMF_N1, TASK_AMF_N2);
itti_msg->ran_ue_ngap_id = nc->ran_ue_ngap_id;
itti_msg->amf_ue_ngap_id = nc->amf_ue_ngap_id;
itti_msg->kgnb = blk2bstr(kgnb, 32);
itti_msg->kgnb = blk2bstr(kgnb, AUTH_VECTOR_LENGTH_OCTETS);
itti_msg->nas = protected_nas;
itti_msg->is_sr = true; // service request indicator, to be verified
......@@ -3497,16 +3545,15 @@ void amf_n1::run_periodic_registration_update_procedure(
return;
}
nas_secu_ctx* secu = nc->security_ctx;
if (!secu) {
if (!nc->security_ctx.has_value()) {
Logger::amf_n1().error("No Security Context found");
return;
}
bstring protected_nas = nullptr;
encode_nas_message_protected(
secu, false, INTEGRITY_PROTECTED_AND_CIPHERED, NAS_MESSAGE_DOWNLINK,
buffer, encoded_size, protected_nas);
nc->security_ctx.value(), false, INTEGRITY_PROTECTED_AND_CIPHERED,
NAS_MESSAGE_DOWNLINK, buffer, encoded_size, protected_nas);
std::shared_ptr<itti_dl_nas_transport> itti_msg =
std::make_shared<itti_dl_nas_transport>(TASK_AMF_N1, TASK_AMF_N2);
......@@ -3566,16 +3613,15 @@ void amf_n1::run_periodic_registration_update_procedure(
return;
}
nas_secu_ctx* secu = nc->security_ctx;
if (!secu) {
if (!nc->security_ctx.has_value()) {
Logger::amf_n1().error("No Security Context found");
return;
}
bstring protected_nas = nullptr;
encode_nas_message_protected(
secu, false, INTEGRITY_PROTECTED_AND_CIPHERED, NAS_MESSAGE_DOWNLINK,
buffer, encoded_size, protected_nas);
nc->security_ctx.value(), false, INTEGRITY_PROTECTED_AND_CIPHERED,
NAS_MESSAGE_DOWNLINK, buffer, encoded_size, protected_nas);
std::shared_ptr<itti_dl_nas_transport> itti_msg =
std::make_shared<itti_dl_nas_transport>(TASK_AMF_N1, TASK_AMF_N2);
......
......@@ -366,7 +366,7 @@ class amf_n1 {
/*
* Encode the NAS message with corresponding integrity and ciphered algorithms
* @param [nas_secu_ctx*] nsc: NAS Security context
* @param [nas_secu_ctx&] nsc: NAS Security context
* @param [bool] is_secu_ctx_new: indicate the status of the security context
* (new/old)
* @param [uint8_t] security_header_type: Security Header Type
......@@ -377,13 +377,13 @@ class amf_n1 {
* @return void
*/
void encode_nas_message_protected(
nas_secu_ctx* nsc, bool is_secu_ctx_new, uint8_t security_header_type,
nas_secu_ctx& nsc, bool is_secu_ctx_new, uint8_t security_header_type,
uint8_t direction, uint8_t* input_nas_buf, int input_nas_len,
bstring& encrypted_nas);
/*
* Encrypt with integrity algorithm
* @param [nas_secu_ctx*] nsc: NAS Security context
* @param [nas_secu_ctx&] nsc: NAS Security context
* @param [uint8_t] direction: Direction
* @param [uint8_t*] input_nas_buf: Buffer of the input NAS
* @param [int] input_nas_les: Length of the buffer
......@@ -391,19 +391,19 @@ class amf_n1 {
* @return true if MAC can be calculated successfully, otherwise return false
*/
bool nas_message_integrity_protected(
nas_secu_ctx* nsc, uint8_t direction, uint8_t* input_nas,
nas_secu_ctx& nsc, uint8_t direction, uint8_t* input_nas,
int input_nas_len, uint32_t& mac);
/*
* Cipher NAS message with the corresponding ciphered algorithm
* @param [nas_secu_ctx*] nsc: NAS Security context
* @param [nas_secu_ctx&] nsc: NAS Security context
* @param [uint8_t] direction: Direction
* @param [bstring] input_nas: Input NAS message
* @param [bstring&] output_nas: Output NAS message
* @return true if message is successfully ciphered, otherwise return false
*/
bool nas_message_cipher_protected(
nas_secu_ctx* nsc, uint8_t direction, bstring input_nas,
nas_secu_ctx& nsc, uint8_t direction, bstring input_nas,
bstring& output_nas);
// NOTE: All the MySQL-related functions are currently implemented in
......
......@@ -1581,20 +1581,27 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) {
return false;
}
nas_secu_ctx* secu = nc->security_ctx;
if (!secu) {
if (!nc->security_ctx.has_value()) {
Logger::amf_n2().error("No Security Context found");
return false;
}
uint8_t* kamf = nc->kamf[secu->vector_pointer];
uint8_t kgnb[32];
uint32_t ulcount = secu->ul_count.seq_num | (secu->ul_count.overflow << 8);
uint8_t kamf[AUTH_VECTOR_LENGTH_OCTETS];
uint8_t kgnb[AUTH_VECTOR_LENGTH_OCTETS];
if (!nc->get_kamf(nc->security_ctx.value().vector_pointer, kamf)) {
Logger::amf_n1().warn("No Kamf found");
return false;
}
uint32_t ulcount = nc->security_ctx.value().ul_count.seq_num |
(nc->security_ctx.value().ul_count.overflow << 8);
Logger::amf_n2().debug(
"Handover Required, Uplink count (%d)", secu->ul_count.seq_num);
uint8_t knh[32];
"Handover Required, Uplink count (%d)",
nc->security_ctx.value().ul_count.seq_num);
uint8_t knh[AUTH_VECTOR_LENGTH_OCTETS];
Authentication_5gaka::handover_ncc_derive_knh(
ulcount, 0x01, kamf, kgnb, knh, unc->ncc);
bstring knh_bs = blk2bstr(knh, 32);
ulcount, 0x01, kamf, kgnb, knh,
unc->ncc); // TODO: remove hardcoded value
bstring knh_bs = blk2bstr(knh, AUTH_VECTOR_LENGTH_OCTETS);
handover_request->setSecurityContext(unc->ncc /*NCC count*/, knh_bs);
string supi = conv::imsi_to_supi(nc->imsi);
......
......@@ -203,7 +203,6 @@ void nf_profile::to_json(nlohmann::json& data) const {
nlohmann::json tmp = {};
tmp["sst"] = s.sST;
tmp["sd"] = s.sD;
;
data["sNssais"].push_back(tmp);
}
// ipv4_addresses
......
......@@ -22,9 +22,7 @@
#include "nas_context.hpp"
//------------------------------------------------------------------------------
nas_context::nas_context()
: _vector(), _5g_he_av(), _5g_av(), kamf(), _5gmm_capability() {
security_ctx = nullptr;
nas_context::nas_context() : _5g_he_av(), _5g_av(), kamf(), _5gmm_capability() {
is_imsi_present = false;
is_stacs_available = false;
is_auth_vectors_present = false;
......@@ -44,7 +42,7 @@ nas_context::nas_context()
is_common_procedure_for_identification_running = false;
is_common_procedure_for_security_mode_control_running = false;
is_common_procedure_for_nas_transport_running = false;
security_ctx = nullptr;
security_ctx = std::nullopt;
is_current_security_available = false;
registration_attempt_counter = 0;
is_imsi_present = false;
......@@ -62,3 +60,13 @@ nas_context::nas_context()
//------------------------------------------------------------------------------
nas_context::~nas_context() {}
//------------------------------------------------------------------------------
bool nas_context::get_kamf(
uint8_t index, uint8_t (&k)[AUTH_VECTOR_LENGTH_OCTETS]) const {
if (index >= MAX_5GS_AUTH_VECTORS) return false;
for (uint8_t i = 0; i < AUTH_VECTOR_LENGTH_OCTETS; i++) {
k[i] = kamf[index][i];
}
return true;
}
......@@ -22,10 +22,6 @@
#ifndef _AMF_NAS_CONTEXT_H_
#define _AMF_NAS_CONTEXT_H_
#include <stdint.h>
#include <string>
#include "UESecurityCapability.hpp"
#include "authentication_algorithms_with_5gaka.hpp"
#include "itti.hpp"
......@@ -110,14 +106,13 @@ class nas_context {
bool is_common_procedure_for_security_mode_control_running;
bool is_common_procedure_for_nas_transport_running;
// security related
// Security-related parameters
#define MAX_5GS_AUTH_VECTORS 1
auc_vector_t _vector[MAX_5GS_AUTH_VECTORS]; // 5GS Authentication vector
_5G_HE_AV_t _5g_he_av[MAX_5GS_AUTH_VECTORS]; // generated by UDM
_5G_AV_t _5g_av[MAX_5GS_AUTH_VECTORS]; // generated by AUSF
std::string href;
uint8_t kamf[MAX_5GS_AUTH_VECTORS][32];
nas_secu_ctx* security_ctx; // TODO: avoid using naked ptr
uint8_t kamf[MAX_5GS_AUTH_VECTORS][AUTH_VECTOR_LENGTH_OCTETS];
std::optional<nas_secu_ctx> security_ctx;
bool is_current_security_available;
int registration_attempt_counter; // used to limit the subsequently reject
// registration
......@@ -128,6 +123,8 @@ class nas_context {
bool is_5g_guti_present;
bool is_auth_vectors_present;
bool to_be_register_by_new_suci;
bool get_kamf(uint8_t index, uint8_t (&k)[AUTH_VECTOR_LENGTH_OCTETS]) const;
};
#endif
......@@ -405,8 +405,10 @@ void Authentication_5gaka::derive_knas(
}
void Authentication_5gaka::derive_kgnb(
uint32_t uplinkCount, uint8_t accessType, uint8_t kamf[32], uint8_t* kgnb) {
Logger::amf_n1().debug("derive_kgnb ...");
uint32_t uplinkCount, uint8_t accessType,
uint8_t kamf[AUTH_VECTOR_LENGTH_OCTETS],
uint8_t (&kgnb)[AUTH_VECTOR_LENGTH_OCTETS]) {
Logger::amf_n1().debug("Derive Kgnb ...");
uint8_t S[20];
S[0] = 0x6E;
*(uint32_t*) (S + 1) = htonl(uplinkCount);
......@@ -417,13 +419,15 @@ void Authentication_5gaka::derive_kgnb(
S[9] = 0x01;
// output_wrapper::print_buffer("amf_n1", "inputstring S", S, 10);
// output_wrapper::print_buffer("amf_n1", "key KEY", kamf, 32);
kdf(kamf, 32, S, 10, kgnb, 32);
kdf(kamf, 32, S, 10, kgnb, AUTH_VECTOR_LENGTH_OCTETS);
// output_wrapper::print_buffer("amf_n1", "kgnb", kgnb, 32);
// Logger::amf_n1().debug("derive kgnb finished!");
}
void Authentication_5gaka::handover_ncc_derive_knh(
uint32_t uplinkCount, uint8_t accessType, uint8_t kamf[32], uint8_t* kgnb,
uint8_t* knh, int ncc) {
uint32_t uplinkCount, uint8_t accessType,
uint8_t kamf[AUTH_VECTOR_LENGTH_OCTETS],
uint8_t (&kgnb)[AUTH_VECTOR_LENGTH_OCTETS],
uint8_t (&knh)[AUTH_VECTOR_LENGTH_OCTETS], int ncc) {
Logger::amf_n1().debug("derive_handover_ncc_knh ...");
uint8_t S[20], SS[ncc][35];
S[0] = 0x6E;
......
......@@ -41,6 +41,8 @@
#define KASME_LENGTH_OCTETS (32)
#define MAC_S_LENGTH (8)
#define AUTH_VECTOR_LENGTH_OCTETS 32
typedef mpz_t random_t;
typedef mpz_t sqn_t;
......@@ -140,11 +142,14 @@ class Authentication_5gaka {
algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t kamf[32],
uint8_t* knas);
static void derive_kgnb(
uint32_t uplinkCount, uint8_t accessType, uint8_t kamf[32],
uint8_t* kgnb);
uint32_t uplinkCount, uint8_t accessType,
uint8_t kamf[AUTH_VECTOR_LENGTH_OCTETS],
uint8_t (&kgnb)[AUTH_VECTOR_LENGTH_OCTETS]);
static void handover_ncc_derive_knh(
uint32_t uplinkCount, uint8_t accessType, uint8_t kamf[32], uint8_t* kgnb,
uint8_t* knh, int ncc);
uint32_t uplinkCount, uint8_t accessType,
uint8_t kamf[AUTH_VECTOR_LENGTH_OCTETS],
uint8_t (&kgnb)[AUTH_VECTOR_LENGTH_OCTETS],
uint8_t (&knh)[AUTH_VECTOR_LENGTH_OCTETS], int ncc);
static uint8_t* sqn_ms_derive(
const uint8_t opc[16], uint8_t* key, uint8_t* auts, uint8_t* rand);
......
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