Commit d0080142 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Add Supi to UE context/format N1

parent 9d4eb446
......@@ -64,38 +64,38 @@ using namespace nas;
using namespace amf_application;
using namespace config;
extern itti_mw *itti_inst;
extern amf_n1 *amf_n1_inst;
extern amf_n11 *amf_n11_inst;
extern itti_mw* itti_inst;
extern amf_n1* amf_n1_inst;
extern amf_n11* amf_n11_inst;
extern amf_config amf_cfg;
extern amf_app *amf_app_inst;
extern amf_n2 *amf_n2_inst;
extern amf_app* amf_app_inst;
extern amf_n2* amf_n2_inst;
extern statistics stacs;
Sha256 ctx;
random_state_t random_state;
static uint8_t no_random_delta = 0;
void amf_n1_task(void *);
void amf_n1_task(void*);
//------------------------------------------------------------------------------
void amf_n1_task(void *) {
void amf_n1_task(void*) {
const task_id_t task_id = TASK_AMF_N1;
itti_inst->notify_task_ready(task_id);
do {
std::shared_ptr<itti_msg> shared_msg = itti_inst->receive_msg(task_id);
auto *msg = shared_msg.get();
auto* msg = shared_msg.get();
switch (msg->msg_type) {
case UL_NAS_DATA_IND: { // receive nas message buffer from amf_n2
Logger::amf_n1().info("Received UL_NAS_DATA_IND");
itti_uplink_nas_data_ind *m =
dynamic_cast<itti_uplink_nas_data_ind *>(msg);
itti_uplink_nas_data_ind* m =
dynamic_cast<itti_uplink_nas_data_ind*>(msg);
amf_n1_inst->handle_itti_message(ref(*m));
} break;
case DOWNLINK_NAS_TRANSFER: {
Logger::amf_n1().info("Received DOWNLINK_NAS_TRANSFER");
itti_downlink_nas_transfer *m =
dynamic_cast<itti_downlink_nas_transfer *>(msg);
itti_downlink_nas_transfer* m =
dynamic_cast<itti_downlink_nas_transfer*>(msg);
amf_n1_inst->handle_itti_message(ref(*m));
} break;
default:
......@@ -118,29 +118,29 @@ amf_n1::amf_n1() {
amf_n1::~amf_n1() {}
//------------------------------------------------------------------------------
void amf_n1::handle_itti_message(itti_downlink_nas_transfer &itti_msg) {
void amf_n1::handle_itti_message(itti_downlink_nas_transfer& itti_msg) {
long amf_ue_ngap_id = itti_msg.amf_ue_ngap_id;
uint32_t ran_ue_ngap_id = itti_msg.ran_ue_ngap_id;
std::shared_ptr<nas_context> nc;
if (is_amf_ue_id_2_nas_context(amf_ue_ngap_id))
nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
else {
Logger::amf_n1().warn("No existed nas_context with amf_ue_ngap_id(0x%x)",
amf_ue_ngap_id);
Logger::amf_n1().warn(
"No existed nas_context with amf_ue_ngap_id(0x%x)", amf_ue_ngap_id);
return;
}
nas_secu_ctx *secu = nc.get()->security_ctx;
nas_secu_ctx* secu = nc.get()->security_ctx;
bstring protected_nas;
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);
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);
if (itti_msg.is_n2sm_set) {
if (itti_msg.n2sm_info_type.compare("PDU_RES_REL_CMD") ==
0) { // PDU SESSION RESOURCE RELEASE COMMAND
itti_pdu_session_resource_release_command *release_command =
new itti_pdu_session_resource_release_command(TASK_AMF_N1,
TASK_AMF_N2);
itti_pdu_session_resource_release_command* release_command =
new itti_pdu_session_resource_release_command(
TASK_AMF_N1, TASK_AMF_N2);
release_command->nas = protected_nas;
release_command->n2sm = itti_msg.n2sm;
release_command->amf_ue_ngap_id = amf_ue_ngap_id;
......@@ -156,7 +156,7 @@ void amf_n1::handle_itti_message(itti_downlink_nas_transfer &itti_msg) {
i->get_msg_name());
}
} else { // PDU SESSION RESOURCE SETUP_REQUEST
itti_pdu_session_resource_setup_request *psrsr =
itti_pdu_session_resource_setup_request* psrsr =
new itti_pdu_session_resource_setup_request(TASK_AMF_N1, TASK_AMF_N2);
psrsr->nas = protected_nas;
psrsr->n2sm = itti_msg.n2sm;
......@@ -174,7 +174,7 @@ void amf_n1::handle_itti_message(itti_downlink_nas_transfer &itti_msg) {
}
} else {
itti_dl_nas_transport *dnt =
itti_dl_nas_transport* dnt =
new itti_dl_nas_transport(TASK_AMF_N1, TASK_AMF_N2);
dnt->nas = protected_nas;
dnt->amf_ue_ngap_id = amf_ue_ngap_id;
......@@ -191,7 +191,7 @@ void amf_n1::handle_itti_message(itti_downlink_nas_transfer &itti_msg) {
}
//------------------------------------------------------------------------------
void amf_n1::handle_itti_message(itti_uplink_nas_data_ind &nas_data_ind) {
void amf_n1::handle_itti_message(itti_uplink_nas_data_ind& nas_data_ind) {
long amf_ue_ngap_id = nas_data_ind.amf_ue_ngap_id;
uint32_t ran_ue_ngap_id = nas_data_ind.ran_ue_ngap_id;
std::string nas_context_key =
......@@ -218,20 +218,20 @@ void amf_n1::handle_itti_message(itti_uplink_nas_data_ind &nas_data_ind) {
if (is_guti_2_nas_context(guti))
nc = guti_2_nas_context(guti);
else {
Logger::amf_n1().error("No existing nas_context with GUTI %s",
nas_data_ind.guti.c_str());
Logger::amf_n1().error(
"No existing nas_context with GUTI %s", nas_data_ind.guti.c_str());
return;
}
} else {
if (is_amf_ue_id_2_nas_context(amf_ue_ngap_id))
nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
else
Logger::amf_n1().warn("No existing nas_context with amf_ue_ngap_id 0x%x",
amf_ue_ngap_id);
Logger::amf_n1().warn(
"No existing nas_context with amf_ue_ngap_id 0x%x", amf_ue_ngap_id);
}
SecurityHeaderType type = {};
if (!check_security_header_type(type, (uint8_t *)bdata(recved_nas_msg))) {
if (!check_security_header_type(type, (uint8_t*) bdata(recved_nas_msg))) {
Logger::amf_n1().error("Not 5GS MOBILITY MANAGEMENT message");
return;
}
......@@ -243,11 +243,11 @@ void amf_n1::handle_itti_message(itti_uplink_nas_data_ind &nas_data_ind) {
} break;
case IntegrityProtected: {
Logger::amf_n1().debug("Received integrity protected NAS message");
ulCount = *((uint8_t *)bdata(recved_nas_msg) + 6);
Logger::amf_n1().info("Integrity protected message: ulCount(%d)",
ulCount);
decoded_plain_msg = blk2bstr((uint8_t *)bdata(recved_nas_msg) + 7,
blength(recved_nas_msg) - 7);
ulCount = *((uint8_t*) bdata(recved_nas_msg) + 6);
Logger::amf_n1().info(
"Integrity protected message: ulCount(%d)", ulCount);
decoded_plain_msg = blk2bstr(
(uint8_t*) bdata(recved_nas_msg) + 7, blength(recved_nas_msg) - 7);
} break;
case IntegrityProtectedAndCiphered: {
Logger::amf_n1().debug(
......@@ -269,17 +269,17 @@ void amf_n1::handle_itti_message(itti_uplink_nas_data_ind &nas_data_ind) {
uint32_t mac32 = 0;
if (!nas_message_integrity_protected(
nc.get()->security_ctx, NAS_MESSAGE_UPLINK,
(uint8_t *)bdata(recved_nas_msg) + 6, blength(recved_nas_msg) - 6,
(uint8_t*) bdata(recved_nas_msg) + 6, blength(recved_nas_msg) - 6,
mac32)) {
// IA0_5G
// TODO:
} else {
bool isMatched = false;
uint8_t *buf = (uint8_t *)bdata(recved_nas_msg);
uint8_t* buf = (uint8_t*) bdata(recved_nas_msg);
int buf_len = blength(recved_nas_msg);
uint32_t mac32_recv = ntohl((((uint32_t *)(buf + 2))[0]));
Logger::amf_n1().debug("Received mac32 (0x%x) from the message",
mac32_recv);
uint32_t mac32_recv = ntohl((((uint32_t*) (buf + 2))[0]));
Logger::amf_n1().debug(
"Received mac32 (0x%x) from the message", mac32_recv);
if (mac32 == mac32_recv) {
isMatched = true;
Logger::amf_n1().error("Integrity matched");
......@@ -290,8 +290,8 @@ void amf_n1::handle_itti_message(itti_uplink_nas_data_ind &nas_data_ind) {
return;
} else {
bstring ciphered = blk2bstr(buf + 7, buf_len - 7);
if (!nas_message_cipher_protected(nc.get()->security_ctx,
NAS_MESSAGE_UPLINK, ciphered,
if (!nas_message_cipher_protected(
nc.get()->security_ctx, NAS_MESSAGE_UPLINK, ciphered,
decoded_plain_msg)) {
Logger::amf_n1().error("Decrypt NAS message failure");
return;
......@@ -304,19 +304,20 @@ void amf_n1::handle_itti_message(itti_uplink_nas_data_ind &nas_data_ind) {
Logger::amf_n1().debug("Received NAS signalling establishment request...");
// dump_nas_message((uint8_t*)bdata(decoded_plain_msg),
// blength(decoded_plain_msg));
print_buffer("amf_n1", "Decoded plain NAS Message buffer",
(uint8_t *)bdata(decoded_plain_msg),
blength(decoded_plain_msg));
print_buffer(
"amf_n1", "Decoded plain NAS Message buffer",
(uint8_t*) bdata(decoded_plain_msg), blength(decoded_plain_msg));
nas_signalling_establishment_request_handle(
type, nc, nas_data_ind.ran_ue_ngap_id, nas_data_ind.amf_ue_ngap_id,
decoded_plain_msg, snn, ulCount);
} else {
Logger::amf_n1().debug("Received uplink NAS message...");
print_buffer("amf_n1", "Decoded NAS message buffer",
(uint8_t *)bdata(decoded_plain_msg),
blength(decoded_plain_msg));
uplink_nas_msg_handle(nas_data_ind.ran_ue_ngap_id,
nas_data_ind.amf_ue_ngap_id, decoded_plain_msg, plmn);
print_buffer(
"amf_n1", "Decoded NAS message buffer",
(uint8_t*) bdata(decoded_plain_msg), blength(decoded_plain_msg));
uplink_nas_msg_handle(
nas_data_ind.ran_ue_ngap_id, nas_data_ind.amf_ue_ngap_id,
decoded_plain_msg, plmn);
}
}
......@@ -347,24 +348,25 @@ void amf_n1::nas_signalling_establishment_request_handle(
// stacs.UE_connected += 1;
} else {
// Logger::amf_n1().debug("existing nas_context with amf_ue_ngap_id(0x%x)
// --> Update",amf_ue_ngap_id); nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
// --> Update",amf_ue_ngap_id); nc =
// amf_ue_id_2_nas_context(amf_ue_ngap_id);
}
uint8_t *buf = (uint8_t *)bdata(plain_msg);
uint8_t* buf = (uint8_t*) bdata(plain_msg);
uint8_t message_type = *(buf + 2);
Logger::amf_n1().debug("NAS message type 0x%x", message_type);
switch (message_type) {
case REGISTRATION_REQUEST: {
Logger::amf_n1().debug(
"Received registration request message, handling...");
registration_request_handle(true, nc, ran_ue_ngap_id, amf_ue_ngap_id, snn,
plain_msg);
registration_request_handle(
true, nc, ran_ue_ngap_id, amf_ue_ngap_id, snn, plain_msg);
} break;
case SERVICE_REQUEST: {
Logger::amf_n1().debug("Received service request message, handling...");
nc.get()->security_ctx->ul_count.seq_num = ulCount;
service_request_handle(true, nc, ran_ue_ngap_id, amf_ue_ngap_id,
plain_msg);
service_request_handle(
true, nc, ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
} break;
case UE_INIT_DEREGISTER: {
Logger::amf_n1().debug(
......@@ -432,9 +434,10 @@ void amf_n1::uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id,
*/
//------------------------------------------------------------------------------
void amf_n1::uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id,
bstring plain_msg, plmn_t plmn) {
uint8_t *buf = (uint8_t *)bdata(plain_msg);
void amf_n1::uplink_nas_msg_handle(
uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg,
plmn_t plmn) {
uint8_t* buf = (uint8_t*) bdata(plain_msg);
uint8_t message_type = *(buf + 2);
switch (message_type) {
case AUTHENTICATION_RESPONSE: {
......@@ -464,8 +467,8 @@ void amf_n1::uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id,
case UE_INIT_DEREGISTER: {
Logger::amf_n1().debug(
"Received de-registration request message, handling...");
ue_initiate_de_registration_handle(ran_ue_ngap_id, amf_ue_ngap_id,
plain_msg);
ue_initiate_de_registration_handle(
ran_ue_ngap_id, amf_ue_ngap_id, plain_msg);
} break;
case IDENTITY_RESPONSE: {
Logger::amf_n1().debug("received identity response messgae , handle ...");
......@@ -484,8 +487,8 @@ void amf_n1::uplink_nas_msg_handle(uint32_t ran_ue_ngap_id, long amf_ue_ngap_id,
// nas message decode
//------------------------------------------------------------------------------
bool amf_n1::check_security_header_type(SecurityHeaderType &type,
uint8_t *buffer) {
bool amf_n1::check_security_header_type(
SecurityHeaderType& type, uint8_t* buffer) {
uint8_t octet = 0, decoded_size = 0;
octet = *(buffer + decoded_size);
decoded_size++;
......@@ -516,11 +519,11 @@ bool amf_n1::check_security_header_type(SecurityHeaderType &type,
// nas message handlers
//------------------------------------------------------------------------------
void amf_n1::identity_response_handle(uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id, bstring plain_msg) {
IdentityResponse *ir = new IdentityResponse();
if (!ir->decodefrombuffer(NULL, (uint8_t *)bdata(plain_msg),
blength(plain_msg))) {
void amf_n1::identity_response_handle(
uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg) {
IdentityResponse* ir = new IdentityResponse();
if (!ir->decodefrombuffer(
NULL, (uint8_t*) bdata(plain_msg), blength(plain_msg))) {
Logger::amf_n1().error("decoding identity response error");
return;
}
......@@ -534,8 +537,8 @@ void amf_n1::identity_response_handle(uint32_t ran_ue_ngap_id,
std::shared_ptr<nas_context> nc;
if (is_amf_ue_id_2_nas_context(amf_ue_ngap_id)) {
nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
Logger::amf_n1().debug("find nas_context(%p) by amf_ue_ngap_id(%d)",
nc.get(), amf_ue_ngap_id);
Logger::amf_n1().debug(
"find nas_context(%p) by amf_ue_ngap_id(%d)", nc.get(), amf_ue_ngap_id);
} else {
nc = std::shared_ptr<nas_context>(new nas_context);
set_amf_ue_ngap_id_2_nas_context(amf_ue_ngap_id, nc);
......@@ -555,9 +558,8 @@ void amf_n1::identity_response_handle(uint32_t ran_ue_ngap_id,
}
//------------------------------------------------------------------------------
void amf_n1::service_request_handle(bool isNasSig,
std::shared_ptr<nas_context> nc,
uint32_t ran_ue_ngap_id,
void amf_n1::service_request_handle(
bool isNasSig, std::shared_ptr<nas_context> nc, uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id, bstring nas) {
if (!nc.get()) {
// service reject
......@@ -566,7 +568,7 @@ void amf_n1::service_request_handle(bool isNasSig,
nas[1] = PLAIN_5GS_MSG;
nas[2] = SERVICE_REJECT;
nas[3] = _5GMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED;
itti_dl_nas_transport *dnt =
itti_dl_nas_transport* dnt =
new itti_dl_nas_transport(TASK_AMF_N1, TASK_AMF_N2);
dnt->nas = blk2bstr(nas, 4);
dnt->amf_ue_ngap_id = amf_ue_ngap_id;
......@@ -583,17 +585,17 @@ void amf_n1::service_request_handle(bool isNasSig,
}
set_amf_ue_ngap_id_2_nas_context(amf_ue_ngap_id, nc);
nas_secu_ctx *secu = nc.get()->security_ctx;
ServiceRequest *serReq = new ServiceRequest();
serReq->decodefrombuffer(nullptr, (uint8_t *)bdata(nas), blength(nas));
nas_secu_ctx* secu = nc.get()->security_ctx;
ServiceRequest* serReq = new ServiceRequest();
serReq->decodefrombuffer(nullptr, (uint8_t*) bdata(nas), blength(nas));
bdestroy(nas);
ServiceAccept *serApt = new ServiceAccept();
ServiceAccept* serApt = new ServiceAccept();
serApt->setHeader(PLAIN_5GS_MSG);
string supi = "imsi-" + nc.get()->imsi;
supi2amfId[supi] = amf_ue_ngap_id;
supi2ranId[supi] = ran_ue_ngap_id;
Logger::amf_n1().debug("amf_ue_ngap_id %d, ran_ue_ngap_id %d", amf_ue_ngap_id,
ran_ue_ngap_id);
Logger::amf_n1().debug(
"amf_ue_ngap_id %d, ran_ue_ngap_id %d", amf_ue_ngap_id, ran_ue_ngap_id);
Logger::amf_n1().debug("Key for pdu session context: SUPI %s", supi.c_str());
std::shared_ptr<pdu_session_context> psc;
if (amf_n11_inst->is_supi_to_pdu_ctx(supi)) {
......@@ -605,13 +607,13 @@ void amf_n1::service_request_handle(bool isNasSig,
return;
}
} else {
Logger::amf_n1().error("Cannot get pdu_session_context with SUPI %s",
supi.c_str());
Logger::amf_n1().error(
"Cannot get pdu_session_context with SUPI %s", supi.c_str());
}
if (!amf_n11_inst->is_supi_to_pdu_ctx(supi) || !psc.get()->isn2sm_avaliable) {
Logger::amf_n1().error("Cannot get pdu session information with supi(%s)",
supi.c_str());
Logger::amf_n1().error(
"Cannot get pdu session information with supi(%s)", supi.c_str());
if (amf_n11_inst->is_supi_to_pdu_ctx(supi)) {
psc.get()->isn2sm_avaliable = true;
}
......@@ -619,10 +621,10 @@ void amf_n1::service_request_handle(bool isNasSig,
uint8_t buffer[BUFFER_SIZE_256];
int encoded_size = serApt->encode2buffer(buffer, BUFFER_SIZE_256);
bstring protectedNas;
encode_nas_message_protected(secu, false, INTEGRITY_PROTECTED_AND_CIPHERED,
NAS_MESSAGE_DOWNLINK, buffer, encoded_size,
protectedNas);
uint8_t *kamf = nc.get()->kamf[secu->vector_pointer];
encode_nas_message_protected(
secu, false, INTEGRITY_PROTECTED_AND_CIPHERED, NAS_MESSAGE_DOWNLINK,
buffer, encoded_size, protectedNas);
uint8_t* kamf = nc.get()->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);
......@@ -630,7 +632,7 @@ void amf_n1::service_request_handle(bool isNasSig,
Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
bstring kgnb_bs = blk2bstr(kgnb, 32);
itti_initial_context_setup_request *itti_msg =
itti_initial_context_setup_request* itti_msg =
new 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;
......@@ -655,17 +657,17 @@ void amf_n1::service_request_handle(bool isNasSig,
uint8_t buffer[BUFFER_SIZE_256];
int encoded_size = serApt->encode2buffer(buffer, BUFFER_SIZE_256);
bstring protectedNas;
encode_nas_message_protected(secu, false, INTEGRITY_PROTECTED_AND_CIPHERED,
NAS_MESSAGE_DOWNLINK, buffer, encoded_size,
protectedNas);
uint8_t *kamf = nc.get()->kamf[secu->vector_pointer];
encode_nas_message_protected(
secu, false, INTEGRITY_PROTECTED_AND_CIPHERED, NAS_MESSAGE_DOWNLINK,
buffer, encoded_size, protectedNas);
uint8_t* kamf = nc.get()->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);
print_buffer("amf_n1", "kamf", kamf, 32);
Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
bstring kgnb_bs = blk2bstr(kgnb, 32);
itti_initial_context_setup_request *itti_msg =
itti_initial_context_setup_request* itti_msg =
new 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;
......@@ -685,7 +687,8 @@ void amf_n1::service_request_handle(bool isNasSig,
std::shared_ptr<itti_initial_context_setup_request>(itti_msg);
int ret = itti_inst->send_msg(i);
if (0 != ret) {
Logger::amf_n1().error("Could not send ITTI message %s to task TASK_AMF_N2",
Logger::amf_n1().error(
"Could not send ITTI message %s to task TASK_AMF_N2",
i->get_msg_name());
}
delete serApt;
......@@ -693,17 +696,23 @@ void amf_n1::service_request_handle(bool isNasSig,
}
//------------------------------------------------------------------------------
void amf_n1::registration_request_handle(bool isNasSig,
std::shared_ptr<nas_context> nc,
uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id, std::string snn,
bstring reg) {
void amf_n1::registration_request_handle(
bool isNasSig, std::shared_ptr<nas_context> nc, uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id, std::string snn, bstring reg) {
// Decode registration request message
RegistrationRequest *regReq = new RegistrationRequest();
regReq->decodefrombuffer(nullptr, (uint8_t *)bdata(reg), blength(reg));
RegistrationRequest* regReq = new RegistrationRequest();
regReq->decodefrombuffer(nullptr, (uint8_t*) bdata(reg), blength(reg));
bdestroy(reg); // free buffer
// Check 5gs Mobility Identity (Mandatory IE)
std::string guti;
string ue_context_key = "app_ue_ranid_" + to_string(ran_ue_ngap_id) +
":amfid_" + to_string(amf_ue_ngap_id);
std::shared_ptr<ue_context> uc;
Logger::amf_n1().info(
"Try to find ue_context in amf_app using ran_amf_id (%s)",
ue_context_key.c_str());
uc = amf_app_inst->ran_amf_id_2_ue_context(ue_context_key);
uint8_t mobility_id_type = regReq->getMobilityIdentityType();
switch (mobility_id_type) {
case SUCI: {
......@@ -726,6 +735,7 @@ void amf_n1::registration_request_handle(bool isNasSig,
Logger::amf_n1().debug("Received IMSI %s", nc.get()->imsi.c_str());
supi2amfId[("imsi-" + nc.get()->imsi)] = amf_ue_ngap_id;
supi2ranId[("imsi-" + nc.get()->imsi)] = ran_ue_ngap_id;
// try to find old nas_context and release
std::shared_ptr<nas_context> old_nc =
imsi2nas_context[("imsi-" + nc.get()->imsi)];
......@@ -734,18 +744,10 @@ void amf_n1::registration_request_handle(bool isNasSig,
old_nc.reset();
}
imsi2nas_context[("imsi-" + nc.get()->imsi)] = nc;
Logger::amf_n1().info("Associating IMSI (%s) with nas_context (%p)",
Logger::amf_n1().info(
"Associating IMSI (%s) with nas_context (%p)",
("imsi-" + nc.get()->imsi).c_str(), nc.get());
if (!nc.get()->is_stacs_available) {
string ue_context_key = "app_ue_ranid_" + to_string(ran_ue_ngap_id) +
":amfid_" + to_string(amf_ue_ngap_id);
std::shared_ptr<ue_context> uc;
// uc = amf_app_inst->amf_ue_id_2_ue_context(amf_ue_ngap_id);
Logger::amf_n1().info(
"Try to find ue_context in amf_app using ran_amf_id (%s)",
ue_context_key.c_str());
uc = amf_app_inst->ran_amf_id_2_ue_context(ue_context_key);
ue_info_t ueItem;
ueItem.connStatus = "5GMM-CONNECTED"; //"CM-CONNECTED";
ueItem.registerStatus =
......@@ -753,9 +755,11 @@ void amf_n1::registration_request_handle(bool isNasSig,
ueItem.ranid = ran_ue_ngap_id;
ueItem.amfid = amf_ue_ngap_id;
ueItem.imsi = nc.get()->imsi;
if (uc.get() != nullptr) {
ueItem.mcc = uc.get()->cgi.mcc;
ueItem.mnc = uc.get()->cgi.mnc;
ueItem.cellId = uc.get()->cgi.nrCellID;
}
stacs.update_ue_info(ueItem);
set_5gmm_state(nc, _5GMM_COMMON_PROCEDURE_INITIATED);
......@@ -849,10 +853,6 @@ void amf_n1::registration_request_handle(bool isNasSig,
_5GMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED, ran_ue_ngap_id,
amf_ue_ngap_id);
// release ue_ngap_context and ue_context
string ue_context_key = "app_ue_ranid_" + to_string(ran_ue_ngap_id) +
":amfid_" + to_string(amf_ue_ngap_id);
std::shared_ptr<ue_context> uc =
amf_app_inst->ran_amf_id_2_ue_context(ue_context_key);
if (uc.get()) uc.reset();
std::shared_ptr<ue_ngap_context> unc =
amf_n2_inst->ran_ue_id_2_ue_ngap_context(ran_ue_ngap_id);
......@@ -868,13 +868,16 @@ void amf_n1::registration_request_handle(bool isNasSig,
nc.get()->amf_ue_ngap_id = amf_ue_ngap_id;
nc.get()->serving_network = snn;
// update UE conext
if (uc.get() != nullptr) uc.get()->supi = "imsi-" + nc.get()->imsi;
// Check 5GS_Registration_type IE (Mandatory IE)
uint8_t reg_type;
bool is_follow_on_req_pending;
if (!regReq->get5GSRegistrationType(is_follow_on_req_pending, reg_type)) {
Logger::amf_n1().error("Missing Mandatory IE 5GS Registration type...");
response_registration_reject_msg(_5GMM_CAUSE_INVALID_MANDATORY_INFO,
ran_ue_ngap_id, amf_ue_ngap_id);
response_registration_reject_msg(
_5GMM_CAUSE_INVALID_MANDATORY_INFO, ran_ue_ngap_id, amf_ue_ngap_id);
delete regReq;
return;
......@@ -886,8 +889,8 @@ void amf_n1::registration_request_handle(bool isNasSig,
uint8_t ngKSI = regReq->getngKSI();
if (ngKSI == -1) {
Logger::amf_n1().error("Missing Mandatory IE ngKSI...");
response_registration_reject_msg(_5GMM_CAUSE_INVALID_MANDATORY_INFO,
ran_ue_ngap_id, amf_ue_ngap_id);
response_registration_reject_msg(
_5GMM_CAUSE_INVALID_MANDATORY_INFO, ran_ue_ngap_id, amf_ue_ngap_id);
delete regReq;
return;
}
......@@ -946,7 +949,8 @@ void amf_n1::registration_request_handle(bool isNasSig,
if (!amf_cfg.is_emergency_support.compare("false")) {
Logger::amf_n1().error(
"Network doesn't support emergency registration, reject ...");
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id,
response_registration_reject_msg(
_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id,
amf_ue_ngap_id); // cause?
return;
}
......@@ -960,51 +964,50 @@ bool amf_n1::generate_authentication_vector() {}
// context management functions
//------------------------------------------------------------------------------
bool amf_n1::is_amf_ue_id_2_nas_context(const long &amf_ue_ngap_id) const {
bool amf_n1::is_amf_ue_id_2_nas_context(const long& amf_ue_ngap_id) const {
std::shared_lock lock(m_amfueid2nas_context);
return bool{amfueid2nas_context.count(amf_ue_ngap_id) > 0};
}
//------------------------------------------------------------------------------
std::shared_ptr<nas_context> amf_n1::amf_ue_id_2_nas_context(
const long &amf_ue_ngap_id) const {
const long& amf_ue_ngap_id) const {
std::shared_lock lock(m_amfueid2nas_context);
return amfueid2nas_context.at(amf_ue_ngap_id);
}
//------------------------------------------------------------------------------
void amf_n1::set_amf_ue_ngap_id_2_nas_context(const long &amf_ue_ngap_id,
std::shared_ptr<nas_context> nc) {
void amf_n1::set_amf_ue_ngap_id_2_nas_context(
const long& amf_ue_ngap_id, std::shared_ptr<nas_context> nc) {
std::shared_lock lock(m_amfueid2nas_context);
amfueid2nas_context[amf_ue_ngap_id] = nc;
}
//------------------------------------------------------------------------------
bool amf_n1::is_guti_2_nas_context(const std::string &guti) const {
bool amf_n1::is_guti_2_nas_context(const std::string& guti) const {
std::shared_lock lock(m_guti2nas_context);
return bool{guti2nas_context.count(guti) > 0};
}
//------------------------------------------------------------------------------
std::shared_ptr<nas_context> amf_n1::guti_2_nas_context(
const std::string &guti) const {
const std::string& guti) const {
std::shared_lock lock(m_guti2nas_context);
return guti2nas_context.at(guti);
}
//------------------------------------------------------------------------------
void amf_n1::set_guti_2_nas_context(const std::string &guti,
std::shared_ptr<nas_context> nc) {
void amf_n1::set_guti_2_nas_context(
const std::string& guti, std::shared_ptr<nas_context> nc) {
std::shared_lock lock(m_guti2nas_context);
guti2nas_context[guti] = nc;
}
// to lower layer TASK_N2
//------------------------------------------------------------------------------
void amf_n1::itti_send_dl_nas_buffer_to_task_n2(bstring &b,
uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id) {
itti_dl_nas_transport *msg =
void amf_n1::itti_send_dl_nas_buffer_to_task_n2(
bstring& b, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id) {
itti_dl_nas_transport* msg =
new itti_dl_nas_transport(TASK_AMF_N1, TASK_AMF_N2);
msg->ran_ue_ngap_id = ran_ue_ngap_id;
msg->amf_ue_ngap_id = amf_ue_ngap_id;
......@@ -1013,24 +1016,24 @@ void amf_n1::itti_send_dl_nas_buffer_to_task_n2(bstring &b,
std::shared_ptr<itti_dl_nas_transport>(msg);
int ret = itti_inst->send_msg(i);
if (0 != ret) {
Logger::amf_n1().error("Could not send ITTI message %s to task TASK_AMF_N2",
Logger::amf_n1().error(
"Could not send ITTI message %s to task TASK_AMF_N2",
i->get_msg_name());
}
}
//------------------------------------------------------------------------------
// response messages
void amf_n1::response_registration_reject_msg(uint8_t cause_value,
uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id) {
RegistrationReject *registrationRej = new RegistrationReject();
void amf_n1::response_registration_reject_msg(
uint8_t cause_value, uint32_t ran_ue_ngap_id, long amf_ue_ngap_id) {
RegistrationReject* registrationRej = new RegistrationReject();
registrationRej->setHeader(PLAIN_5GS_MSG);
registrationRej->set_5GMM_Cause(cause_value);
uint8_t buffer[BUFFER_SIZE_1024] = {0};
int encoded_size = registrationRej->encode2buffer(buffer, BUFFER_SIZE_1024);
// dump_nas_message(buffer, encoded_size);
print_buffer("amf_n1", "Registration-Reject message buffer", buffer,
encoded_size);
print_buffer(
"amf_n1", "Registration-Reject message buffer", buffer, encoded_size);
if (!encoded_size) {
Logger::nas_mm().error("Encode Registration-Reject message error");
return;
......@@ -1043,7 +1046,7 @@ void amf_n1::response_registration_reject_msg(uint8_t cause_value,
//------------------------------------------------------------------------------
// specific procedures running logic
void amf_n1::run_registration_procedure(std::shared_ptr<nas_context> &nc) {
void amf_n1::run_registration_procedure(std::shared_ptr<nas_context>& nc) {
Logger::amf_n1().debug("Start to run registration procedure");
if (!nc.get()->ctx_avaliability_ind) {
Logger::amf_n1().error("NAS context is not available");
......@@ -1066,8 +1069,8 @@ void amf_n1::run_registration_procedure(std::shared_ptr<nas_context> &nc) {
handle_auth_vector_successful_result(nc);
} else {
Logger::amf_n1().error("Request authentication vectors failure");
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE,
nc.get()->ran_ue_ngap_id,
response_registration_reject_msg(
_5GMM_CAUSE_ILLEGAL_UE, nc.get()->ran_ue_ngap_id,
nc.get()->amf_ue_ngap_id); // cause?
}
} else {
......@@ -1088,14 +1091,14 @@ void amf_n1::run_registration_procedure(std::shared_ptr<nas_context> &nc) {
Logger::amf_n1().debug("Start to run identification procedure");
nc.get()->is_auth_vectors_present = false;
// ... identification procedure
IdentityRequest *ir = new IdentityRequest();
IdentityRequest* ir = new IdentityRequest();
// itti_msg->cause = 28;//cause nas(2)--deregister
ir->setHeader(PLAIN_5GS_MSG);
ir->set_5GS_Identity_Type(SUCI);
uint8_t buffer[100];
int encoded_size = ir->encode2buffer(buffer, 100);
delete ir;
itti_dl_nas_transport *dnt =
itti_dl_nas_transport* dnt =
new itti_dl_nas_transport(TASK_AMF_N1, TASK_AMF_N2);
dnt->nas = blk2bstr(buffer, encoded_size);
dnt->amf_ue_ngap_id = nc.get()->amf_ue_ngap_id;
......@@ -1114,14 +1117,14 @@ void amf_n1::run_registration_procedure(std::shared_ptr<nas_context> &nc) {
//------------------------------------------------------------------------------
// authentication vectors
// TODO: should be done in UDM/AUSF
bool amf_n1::auth_vectors_generator(std::shared_ptr<nas_context> &nc) {
bool amf_n1::auth_vectors_generator(std::shared_ptr<nas_context>& nc) {
Logger::amf_n1().debug("Start to generate authentication vectors");
authentication_vectors_generator_in_udm(nc);
authentication_vectors_generator_in_ausf(nc);
Logger::amf_n1().debug("Deriving kamf");
for (int i = 0; i < MAX_5GS_AUTH_VECTORS; i++) {
Authentication_5gaka::derive_kamf(nc.get()->imsi, nc.get()->_5g_av[i].kseaf,
nc.get()->kamf[i],
Authentication_5gaka::derive_kamf(
nc.get()->imsi, nc.get()->_5g_av[i].kseaf, nc.get()->kamf[i],
0x0000); // second parameter: abba
}
return true;
......@@ -1129,25 +1132,25 @@ bool amf_n1::auth_vectors_generator(std::shared_ptr<nas_context> &nc) {
//------------------------------------------------------------------------------
bool amf_n1::authentication_vectors_generator_in_ausf(
std::shared_ptr<nas_context> &nc) { // A.5, 3gpp ts33.501
std::shared_ptr<nas_context>& nc) { // A.5, 3gpp ts33.501
Logger::amf_n1().debug("Authentication_vectors_generator_in_ausf");
uint8_t inputString[MAX_5GS_AUTH_VECTORS][40];
uint8_t *xresStar[MAX_5GS_AUTH_VECTORS];
uint8_t *rand[MAX_5GS_AUTH_VECTORS];
uint8_t* xresStar[MAX_5GS_AUTH_VECTORS];
uint8_t* rand[MAX_5GS_AUTH_VECTORS];
for (int i = 0; i < MAX_5GS_AUTH_VECTORS; i++) {
xresStar[i] = nc.get()->_5g_he_av[i].xresStar;
rand[i] = nc.get()->_5g_he_av[i].rand;
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], 32, sha256Out);
for (int j = 0; j < 16; j++)
nc.get()->_5g_av[i].hxresStar[j] = (uint8_t)sha256Out[j];
nc.get()->_5g_av[i].hxresStar[j] = (uint8_t) sha256Out[j];
memcpy(nc.get()->_5g_av[i].rand, nc.get()->_5g_he_av[i].rand, 16);
memcpy(nc.get()->_5g_av[i].autn, nc.get()->_5g_he_av[i].autn, 16);
uint8_t kseaf[32];
Authentication_5gaka::derive_kseaf(nc.get()->serving_network,
nc.get()->_5g_he_av[i].kausf, kseaf);
Authentication_5gaka::derive_kseaf(
nc.get()->serving_network, nc.get()->_5g_he_av[i].kausf, kseaf);
memcpy(nc.get()->_5g_av[i].kseaf, kseaf, 32);
// print_buffer("amf_n1", "5G AV: rand", nc.get()->_5g_av[i].rand, 16);
// print_buffer("amf_n1", "5G AV: autn", nc.get()->_5g_av[i].autn, 16);
......@@ -1161,11 +1164,11 @@ bool amf_n1::authentication_vectors_generator_in_ausf(
//------------------------------------------------------------------------------
// TODO: Get from UDM
bool amf_n1::authentication_vectors_generator_in_udm(
std::shared_ptr<nas_context> &nc) {
std::shared_ptr<nas_context>& nc) {
Logger::amf_n1().debug("Generate authentication vectors");
uint8_t *sqn = NULL;
uint8_t *auts = (uint8_t *)bdata(nc.get()->auts);
_5G_HE_AV_t *vector = nc.get()->_5g_he_av;
uint8_t* sqn = NULL;
uint8_t* auts = (uint8_t*) bdata(nc.get()->auts);
_5G_HE_AV_t* vector = nc.get()->_5g_he_av;
// Access to MySQL to fetch UE-related information
if (!connect_to_mysql()) {
Logger::amf_n1().error("Cannot connect to MySQL");
......@@ -1175,13 +1178,13 @@ bool amf_n1::authentication_vectors_generator_in_udm(
mysql_auth_info_t mysql_resp = {};
if (get_mysql_auth_info(nc.get()->imsi, mysql_resp)) {
if (auts) {
sqn = Authentication_5gaka::sqn_ms_derive(mysql_resp.opc, mysql_resp.key,
auts, mysql_resp.rand);
sqn = Authentication_5gaka::sqn_ms_derive(
mysql_resp.opc, mysql_resp.key, auts, mysql_resp.rand);
if (sqn) {
generate_random(vector[0].rand, RAND_LENGTH);
mysql_push_rand_sqn(nc.get()->imsi, vector[0].rand, sqn);
mysql_increment_sqn(nc.get()->imsi);
free_wrapper((void **)&sqn);
free_wrapper((void**) &sqn);
}
if (!get_mysql_auth_info(nc.get()->imsi, mysql_resp)) {
Logger::amf_n1().error("Cannot get data from MySQL");
......@@ -1190,17 +1193,19 @@ bool amf_n1::authentication_vectors_generator_in_udm(
sqn = mysql_resp.sqn;
for (int i = 0; i < MAX_5GS_AUTH_VECTORS; i++) {
generate_random(vector[i].rand, RAND_LENGTH);
print_buffer("amf_n1", "Generated random rand (5G HE AV)",
vector[i].rand, 16);
generate_5g_he_av_in_udm(mysql_resp.opc, nc.get()->imsi, mysql_resp.key,
sqn, nc.get()->serving_network,
print_buffer(
"amf_n1", "Generated random rand (5G HE AV)", vector[i].rand, 16);
generate_5g_he_av_in_udm(
mysql_resp.opc, nc.get()->imsi, mysql_resp.key, sqn,
nc.get()->serving_network,
vector[i]); // serving network name
}
mysql_push_rand_sqn(nc.get()->imsi, vector[MAX_5GS_AUTH_VECTORS - 1].rand,
sqn);
mysql_push_rand_sqn(
nc.get()->imsi, vector[MAX_5GS_AUTH_VECTORS - 1].rand, sqn);
} else {
Logger::amf_n1().debug("No auts ...");
Logger::amf_n1().debug("Receive information from MySQL with IMSI %s",
Logger::amf_n1().debug(
"Receive information from MySQL with IMSI %s",
nc.get()->imsi.c_str());
// print_buffer("amf_n1", "Received from MYSQL: rand", mysql_resp.rand,
// 16); print_buffer("amf_n1", "Received from MYSQL: opc", mysql_resp.opc,
......@@ -1212,12 +1217,13 @@ bool amf_n1::authentication_vectors_generator_in_udm(
// print_buffer("amf_n1", "generated random: rand(5G HE AV)",
// vector[i].rand, 16);
sqn = mysql_resp.sqn;
generate_5g_he_av_in_udm(mysql_resp.opc, nc.get()->imsi, mysql_resp.key,
sqn, nc.get()->serving_network,
generate_5g_he_av_in_udm(
mysql_resp.opc, nc.get()->imsi, mysql_resp.key, sqn,
nc.get()->serving_network,
vector[i]); // serving network name
}
mysql_push_rand_sqn(nc.get()->imsi, vector[MAX_5GS_AUTH_VECTORS - 1].rand,
sqn);
mysql_push_rand_sqn(
nc.get()->imsi, vector[MAX_5GS_AUTH_VECTORS - 1].rand, sqn);
}
mysql_increment_sqn(nc.get()->imsi);
} else {
......@@ -1227,34 +1233,37 @@ bool amf_n1::authentication_vectors_generator_in_udm(
}
//------------------------------------------------------------------------------
void amf_n1::test_generate_5g_he_av_in_udm(const uint8_t opc[16],
uint8_t key[16], uint8_t sqnak[6],
std::string serving_network,
_5G_HE_AV_t &vector) {
void amf_n1::test_generate_5g_he_av_in_udm(
const uint8_t opc[16], uint8_t key[16], uint8_t sqnak[6],
std::string serving_network, _5G_HE_AV_t& vector) {
uint8_t amf[] = {0x90, 0x01};
uint8_t mac_a[8];
uint8_t ck[16];
uint8_t ik[16];
uint8_t ak[6];
Authentication_5gaka::f2345(opc, key, vector.rand, vector.xres, ck, ik,
Authentication_5gaka::f2345(
opc, key, vector.rand, vector.xres, ck, ik,
ak); // to compute XRES, CK, IK, AK
uint8_t sqn[6];
for (int i = 0; i < 6; i++) sqn[i] = sqnak[i] ^ ak[i];
Authentication_5gaka::f1(opc, key, vector.rand, sqn, amf,
Authentication_5gaka::f1(
opc, key, vector.rand, sqn, amf,
mac_a); // to compute MAC, Figure 7, ts33.102
print_buffer("amf_n1", "sqn^ak", sqnak, 6);
print_buffer("amf_n1", "rand", vector.rand, 16);
print_buffer("amf_n1", "mac_a", mac_a, 8);
annex_a_4_33501(ck, ik, vector.xres, vector.rand, serving_network,
vector.xresStar);
Authentication_5gaka::generate_autn(sqn, ak, amf, mac_a,
annex_a_4_33501(
ck, ik, vector.xres, vector.rand, serving_network, vector.xresStar);
Authentication_5gaka::generate_autn(
sqn, ak, amf, mac_a,
vector.autn); // generate AUTN
Authentication_5gaka::derive_kausf(ck, ik, serving_network, sqn, ak,
Authentication_5gaka::derive_kausf(
ck, ik, serving_network, sqn, ak,
vector.kausf); // derive Kausf
}
//------------------------------------------------------------------------------
void amf_n1::generate_random(uint8_t *random_p, ssize_t length) {
void amf_n1::generate_random(uint8_t* random_p, ssize_t length) {
gmp_randinit_default(random_state.state);
gmp_randseed_ui(random_state.state, time(NULL));
if (!amf_cfg.auth_para.random.compare("true")) {
......@@ -1286,10 +1295,9 @@ void amf_n1::generate_random(uint8_t *random_p, ssize_t length) {
//------------------------------------------------------------------------------
// TODO: read from UDM
void amf_n1::generate_5g_he_av_in_udm(const uint8_t opc[16], string imsi,
uint8_t key[16], uint8_t sqn[6],
std::string serving_network,
_5G_HE_AV_t &vector) {
void amf_n1::generate_5g_he_av_in_udm(
const uint8_t opc[16], string imsi, uint8_t key[16], uint8_t sqn[6],
std::string serving_network, _5G_HE_AV_t& vector) {
Logger::amf_n1().debug("Generate 5g_he_av as in UDM");
uint8_t amf[] = {0x90, 0x01};
uint8_t mac_a[8];
......@@ -1298,19 +1306,23 @@ void amf_n1::generate_5g_he_av_in_udm(const uint8_t opc[16], string imsi,
uint8_t ak[6];
uint64_t _imsi = fromString<uint64_t>(imsi);
Authentication_5gaka::f1(opc, key, vector.rand, sqn, amf,
Authentication_5gaka::f1(
opc, key, vector.rand, sqn, amf,
mac_a); // to compute MAC, Figure 7, ts33.102
// print_buffer("amf_n1", "Result For F1-Alg: mac_a", mac_a, 8);
Authentication_5gaka::f2345(opc, key, vector.rand, vector.xres, ck, ik,
Authentication_5gaka::f2345(
opc, key, vector.rand, vector.xres, ck, ik,
ak); // to compute XRES, CK, IK, AK
annex_a_4_33501(ck, ik, vector.xres, vector.rand, serving_network,
vector.xresStar);
annex_a_4_33501(
ck, ik, vector.xres, vector.rand, serving_network, vector.xresStar);
// print_buffer("amf_n1", "Result For KDF: xres*(5G HE AV)", vector.xresStar,
// 16);
Authentication_5gaka::generate_autn(sqn, ak, amf, mac_a,
Authentication_5gaka::generate_autn(
sqn, ak, amf, mac_a,
vector.autn); // generate AUTN
// print_buffer("amf_n1", "Generated autn(5G HE AV)", vector.autn, 16);
Authentication_5gaka::derive_kausf(ck, ik, serving_network, sqn, ak,
Authentication_5gaka::derive_kausf(
ck, ik, serving_network, sqn, ak,
vector.kausf); // derive Kausf
// print_buffer("amf_n1", "Result For KDF: Kausf(5G HE AV)", vector.kausf,
// 32);
......@@ -1320,12 +1332,12 @@ void amf_n1::generate_5g_he_av_in_udm(const uint8_t opc[16], string imsi,
}
//------------------------------------------------------------------------------
void amf_n1::annex_a_4_33501(uint8_t ck[16], uint8_t ik[16], uint8_t *input,
uint8_t rand[16], std::string serving_network,
uint8_t *output) {
void amf_n1::annex_a_4_33501(
uint8_t ck[16], uint8_t ik[16], uint8_t* input, uint8_t rand[16],
std::string serving_network, uint8_t* output) {
OCTET_STRING_t netName;
OCTET_STRING_fromBuf(&netName, serving_network.c_str(),
serving_network.length());
OCTET_STRING_fromBuf(
&netName, serving_network.c_str(), serving_network.length());
uint8_t S[100];
S[0] = 0x6B;
memcpy(&S[1], netName.buf, netName.size);
......@@ -1380,8 +1392,8 @@ void amf_n1::handle_auth_vector_successful_result(
if (!start_authentication_procedure(nc, vindex, nc.get()->ngKsi)) {
Logger::amf_n1().error("Start authentication procedure failure, reject...");
Logger::amf_n1().error("Ran_ue_ngap_id 0x%x", nc.get()->ran_ue_ngap_id);
response_registration_reject_msg(_5GMM_CAUSE_INVALID_MANDATORY_INFO,
nc.get()->ran_ue_ngap_id,
response_registration_reject_msg(
_5GMM_CAUSE_INVALID_MANDATORY_INFO, nc.get()->ran_ue_ngap_id,
nc.get()->amf_ue_ngap_id); // cause?
} else {
// update mm state -> COMMON-PROCEDURE-INITIATED
......@@ -1389,33 +1401,33 @@ void amf_n1::handle_auth_vector_successful_result(
}
//------------------------------------------------------------------------------
bool amf_n1::start_authentication_procedure(std::shared_ptr<nas_context> nc,
int vindex, uint8_t ngksi) {
bool amf_n1::start_authentication_procedure(
std::shared_ptr<nas_context> nc, int vindex, uint8_t ngksi) {
Logger::amf_n1().debug("****Starting authentication procedure****");
if (check_nas_common_procedure_on_going(nc)) {
Logger::amf_n1().error("Existed NAS common procedure on going, reject...");
response_registration_reject_msg(_5GMM_CAUSE_INVALID_MANDATORY_INFO,
nc.get()->ran_ue_ngap_id,
response_registration_reject_msg(
_5GMM_CAUSE_INVALID_MANDATORY_INFO, nc.get()->ran_ue_ngap_id,
nc.get()->amf_ue_ngap_id); // cause?
return false;
}
nc.get()->is_common_procedure_for_authentication_running = true;
AuthenticationRequest *authReq = new AuthenticationRequest();
AuthenticationRequest* authReq = new AuthenticationRequest();
authReq->setHeader(PLAIN_5GS_MSG);
authReq->setngKSI(NAS_KEY_SET_IDENTIFIER_NATIVE, ngksi);
uint8_t abba[2];
abba[0] = 0x00;
abba[1] = 0x00;
authReq->setABBA(2, abba);
uint8_t *rand = nc.get()->_5g_av[vindex].rand;
uint8_t* rand = nc.get()->_5g_av[vindex].rand;
if (rand) authReq->setAuthentication_Parameter_RAND(rand);
Logger::amf_n1().debug("Sending Authentication request with rand");
printf("0x");
for (int i = 0; i < 16; i++) printf("%x", rand[i]);
printf("\n");
uint8_t *autn = nc.get()->_5g_av[vindex].autn;
uint8_t* autn = nc.get()->_5g_av[vindex].autn;
if (autn) authReq->setAuthentication_Parameter_AUTN(autn);
uint8_t buffer[1024] = {0};
int encoded_size = authReq->encode2buffer(buffer, 1024);
......@@ -1426,11 +1438,12 @@ bool amf_n1::start_authentication_procedure(std::shared_ptr<nas_context> nc,
delete authReq;
}
bstring b = blk2bstr(buffer, encoded_size);
print_buffer("amf_n1", "Authentication-Request message buffer",
(uint8_t *)bdata(b), blength(b));
print_buffer(
"amf_n1", "Authentication-Request message buffer", (uint8_t*) bdata(b),
blength(b));
Logger::amf_n1().debug("amf_ue_ngap_id 0x%x", nc.get()->amf_ue_ngap_id);
itti_send_dl_nas_buffer_to_task_n2(b, nc.get()->ran_ue_ngap_id,
nc.get()->amf_ue_ngap_id);
itti_send_dl_nas_buffer_to_task_n2(
b, nc.get()->ran_ue_ngap_id, nc.get()->amf_ue_ngap_id);
return true;
}
......@@ -1457,29 +1470,30 @@ bool amf_n1::check_nas_common_procedure_on_going(
}
//------------------------------------------------------------------------------
void amf_n1::authentication_response_handle(uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id,
bstring plain_msg) {
void amf_n1::authentication_response_handle(
uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg) {
std::shared_ptr<nas_context> nc;
if (!is_amf_ue_id_2_nas_context(amf_ue_ngap_id)) {
Logger::amf_n1().error(
"No existed NAS context for UE with amf_ue_ngap_id (0x%x)",
amf_ue_ngap_id);
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id,
response_registration_reject_msg(
_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id,
amf_ue_ngap_id); // cause?
return;
}
nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
Logger::amf_n1().info("Found nas_context(%p) with amf_ue_ngap_id (0x%x)",
nc.get(), amf_ue_ngap_id);
Logger::amf_n1().info(
"Found nas_context(%p) with amf_ue_ngap_id (0x%x)", nc.get(),
amf_ue_ngap_id);
// Stop timer? common procedure finished!
nc.get()->is_common_procedure_for_authentication_running = false;
// MM state: COMMON-PROCEDURE-INITIATED -> DEREGISTRED
// Decode AUTHENTICATION RESPONSE message
AuthenticationResponse *auth = new AuthenticationResponse();
auth->decodefrombuffer(nullptr, (uint8_t *)bdata(plain_msg),
blength(plain_msg));
AuthenticationResponse* auth = new AuthenticationResponse();
auth->decodefrombuffer(
nullptr, (uint8_t*) bdata(plain_msg), blength(plain_msg));
bstring resStar;
bool isAuthOk = true;
// Get response RES*
......@@ -1489,23 +1503,25 @@ void amf_n1::authentication_response_handle(uint32_t ran_ue_ngap_id,
} else {
// Get stored XRES*
int secu_index = nc.get()->security_ctx->vector_pointer;
uint8_t *hxresStar = nc.get()->_5g_av[secu_index].hxresStar;
uint8_t* hxresStar = nc.get()->_5g_av[secu_index].hxresStar;
// Calculate HRES* from received RES*, then compare with XRES stored in
// nas_context
uint8_t inputstring[32];
uint8_t *res = (uint8_t *)bdata(resStar);
uint8_t* res = (uint8_t*) bdata(resStar);
Logger::amf_n1().debug("Start to calculate HRES* from received RES*");
memcpy(&inputstring[0], nc.get()->_5g_av[secu_index].rand, 16);
memcpy(&inputstring[16], res, blength(resStar));
unsigned char sha256Out[Sha256::DIGEST_SIZE];
sha256((unsigned char *)inputstring, 16 + blength(resStar), sha256Out);
sha256((unsigned char*) inputstring, 16 + blength(resStar), sha256Out);
uint8_t hres[16];
for (int i = 0; i < 16; i++) hres[i] = (uint8_t)sha256Out[i];
print_buffer("amf_n1", "Received RES* From Authentication-Response", res,
16);
print_buffer("amf_n1", "Stored XRES* in 5G HE AV",
for (int i = 0; i < 16; i++) hres[i] = (uint8_t) sha256Out[i];
print_buffer(
"amf_n1", "Received RES* From Authentication-Response", res, 16);
print_buffer(
"amf_n1", "Stored XRES* in 5G HE AV",
nc.get()->_5g_he_av[secu_index].xresStar, 16);
print_buffer("amf_n1", "Stored XRES in 5G HE AV",
print_buffer(
"amf_n1", "Stored XRES in 5G HE AV",
nc.get()->_5g_he_av[secu_index].xres, 8);
print_buffer("amf_n1", "Computed HRES* from RES*", hres, 16);
print_buffer("amf_n1", "Computed HXRES* from XRES*", hxresStar, 16);
......@@ -1519,7 +1535,8 @@ void amf_n1::authentication_response_handle(uint32_t ran_ue_ngap_id,
Logger::amf_n1().error(
"Authentication failed for UE with amf_ue_ngap_id 0x%x",
amf_ue_ngap_id);
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id,
response_registration_reject_msg(
_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id,
amf_ue_ngap_id); // cause?
return;
} else {
......@@ -1535,29 +1552,30 @@ void amf_n1::authentication_response_handle(uint32_t ran_ue_ngap_id,
}
//------------------------------------------------------------------------------
void amf_n1::authentication_failure_handle(uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id,
bstring plain_msg) {
void amf_n1::authentication_failure_handle(
uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring plain_msg) {
std::shared_ptr<nas_context> nc;
if (!is_amf_ue_id_2_nas_context(amf_ue_ngap_id)) {
Logger::amf_n1().error(
"No existed NAS context for UE with amf_ue_ngap_id(0x%x)",
amf_ue_ngap_id);
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id,
response_registration_reject_msg(
_5GMM_CAUSE_ILLEGAL_UE, ran_ue_ngap_id,
amf_ue_ngap_id); // cause?
return;
}
nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
nc.get()->is_common_procedure_for_authentication_running = false;
// 1. decode AUTHENTICATION FAILURE message
AuthenticationFailure *authFail = new AuthenticationFailure();
authFail->decodefrombuffer(NULL, (uint8_t *)bdata(plain_msg),
blength(plain_msg));
AuthenticationFailure* authFail = new AuthenticationFailure();
authFail->decodefrombuffer(
NULL, (uint8_t*) bdata(plain_msg), blength(plain_msg));
uint8_t mm_cause = authFail->get5GMmCause();
if (mm_cause == -1) {
Logger::amf_n1().error("Missing mandatory IE 5G_MM_CAUSE");
response_registration_reject_msg(_5GMM_CAUSE_INVALID_MANDATORY_INFO,
ran_ue_ngap_id, amf_ue_ngap_id); // cause?
response_registration_reject_msg(
_5GMM_CAUSE_INVALID_MANDATORY_INFO, ran_ue_ngap_id,
amf_ue_ngap_id); // cause?
return;
}
switch (mm_cause) {
......@@ -1571,14 +1589,14 @@ void amf_n1::authentication_failure_handle(uint32_t ran_ue_ngap_id,
nc.get()->auts = auts;
printf("Received auts: 0x ");
for (int i = 0; i < blength(auts); i++)
printf("%x ", ((uint8_t *)bdata(auts))[i]);
printf("%x ", ((uint8_t*) bdata(auts))[i]);
printf("\n");
if (auth_vectors_generator(nc)) { // all authentication in one(AMF)
handle_auth_vector_successful_result(nc);
} else {
Logger::amf_n1().error("Request authentication vectors failure");
response_registration_reject_msg(_5GMM_CAUSE_ILLEGAL_UE,
nc.get()->ran_ue_ngap_id,
response_registration_reject_msg(
_5GMM_CAUSE_ILLEGAL_UE, nc.get()->ran_ue_ngap_id,
nc.get()->amf_ue_ngap_id); // cause?
}
// authentication_failure_synch_failure_handle(nc, auts);
......@@ -1595,8 +1613,8 @@ 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
security_data_t *data = (security_data_t *)calloc(1, sizeof(security_data_t));
nas_secu_ctx *secu_ctx = nc.get()->security_ctx;
security_data_t* data = (security_data_t*) calloc(1, sizeof(security_data_t));
nas_secu_ctx* secu_ctx = nc.get()->security_ctx;
if (!data)
Logger::amf_n1().error("Cannot allocate memory for security_data_t");
......@@ -1619,15 +1637,15 @@ bool amf_n1::start_security_mode_control_procedure(
secu_ctx->dl_count.seq_num = 0;
secu_ctx->ul_count.overflow = 0;
secu_ctx->ul_count.seq_num = 0;
int rc = security_select_algorithms(nc.get()->ueSecurityCapEnc,
nc.get()->ueSecurityCapInt, amf_nea,
int rc = security_select_algorithms(
nc.get()->ueSecurityCapEnc, nc.get()->ueSecurityCapInt, 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;
Authentication_5gaka::derive_knas(NAS_INT_ALG, secu_ctx->nas_algs.integrity,
nc.get()->kamf[secu_ctx->vector_pointer],
secu_ctx->knas_int);
Authentication_5gaka::derive_knas(
NAS_INT_ALG, secu_ctx->nas_algs.integrity,
nc.get()->kamf[secu_ctx->vector_pointer], secu_ctx->knas_int);
Authentication_5gaka::derive_knas(
NAS_ENC_ALG, secu_ctx->nas_algs.encryption,
nc.get()->kamf[secu_ctx->vector_pointer], secu_ctx->knas_enc);
......@@ -1635,34 +1653,35 @@ bool amf_n1::start_security_mode_control_procedure(
nc.get()->is_current_security_available = true;
}
SecurityModeCommand *smc = new SecurityModeCommand();
SecurityModeCommand* smc = new SecurityModeCommand();
smc->setHeader(PLAIN_5GS_MSG);
smc->setNAS_Security_Algorithms(amf_nea, amf_nia);
Logger::amf_n1().debug("Encoded ngKSI 0x%x", nc.get()->ngKsi);
smc->setngKSI(NAS_KEY_SET_IDENTIFIER_NATIVE, nc.get()->ngKsi & 0x07);
smc->setUE_Security_Capability(nc.get()->ueSecurityCapEnc,
nc.get()->ueSecurityCapInt);
smc->setUE_Security_Capability(
nc.get()->ueSecurityCapEnc, nc.get()->ueSecurityCapInt);
smc->setIMEISV_Request(0xe1);
smc->setAdditional_5G_Security_Information(true, false);
uint8_t buffer[1024];
int encoded_size = smc->encode2buffer(buffer, 1024);
print_buffer("amf_n1", "Security-Mode-Command message buffer", buffer,
encoded_size);
print_buffer(
"amf_n1", "Security-Mode-Command message buffer", buffer, encoded_size);
bstring intProtctedNas;
encode_nas_message_protected(
secu_ctx, security_context_is_new, INTEGRITY_PROTECTED_WITH_NEW_SECU_CTX,
NAS_MESSAGE_DOWNLINK, buffer, encoded_size, intProtctedNas);
print_buffer("amf_n1", "Encrypted Security-Mode-Command message buffer",
(uint8_t *)bdata(intProtctedNas), blength(intProtctedNas));
itti_send_dl_nas_buffer_to_task_n2(intProtctedNas, nc.get()->ran_ue_ngap_id,
nc.get()->amf_ue_ngap_id);
print_buffer(
"amf_n1", "Encrypted Security-Mode-Command message buffer",
(uint8_t*) bdata(intProtctedNas), blength(intProtctedNas));
itti_send_dl_nas_buffer_to_task_n2(
intProtctedNas, nc.get()->ran_ue_ngap_id, nc.get()->amf_ue_ngap_id);
// secu_ctx->dl_count.seq_num ++;
return true;
}
//------------------------------------------------------------------------------
int amf_n1::security_select_algorithms(uint8_t nea, uint8_t nia,
uint8_t &amf_nea, uint8_t &amf_nia) {
int amf_n1::security_select_algorithms(
uint8_t nea, uint8_t nia, uint8_t& amf_nea, uint8_t& amf_nia) {
for (int i = 0; i < 8; i++) {
if (nea & (0x80 >> amf_cfg.nas_cfg.prefered_ciphering_algorithm[i])) {
amf_nea = amf_cfg.nas_cfg.prefered_ciphering_algorithm[i];
......@@ -1681,9 +1700,8 @@ int amf_n1::security_select_algorithms(uint8_t nea, uint8_t nia,
}
//------------------------------------------------------------------------------
void amf_n1::security_mode_complete_handle(uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id,
bstring nas_msg) {
void amf_n1::security_mode_complete_handle(
uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas_msg) {
Logger::amf_n1().debug("Handling security mode complete ...");
string ue_context_key = "app_ue_ranid_" + to_string(ran_ue_ngap_id) +
":amfid_" + to_string(amf_ue_ngap_id);
......@@ -1700,20 +1718,21 @@ void amf_n1::security_mode_complete_handle(uint32_t ran_ue_ngap_id,
ue_context_key.c_str());
// encoding REGISTRATION ACCEPT
RegistrationAccept *regAccept = new RegistrationAccept();
RegistrationAccept* regAccept = new RegistrationAccept();
regAccept->setHeader(PLAIN_5GS_MSG);
regAccept->set_5GS_Registration_Result(false, false, false, 0x01);
std::string mcc;
std::string mnc;
uint32_t tmsi = 0;
if (!amf_app_inst->generate_5g_guti(ran_ue_ngap_id, amf_ue_ngap_id, mcc, mnc,
tmsi)) {
if (!amf_app_inst->generate_5g_guti(
ran_ue_ngap_id, amf_ue_ngap_id, mcc, mnc, tmsi)) {
Logger::amf_n1().error("Generate 5G GUTI error! exit");
// TODO:
return;
}
regAccept->set5G_GUTI(mcc, mnc, amf_cfg.guami.regionID,
amf_cfg.guami.AmfSetID, amf_cfg.guami.AmfPointer, tmsi);
regAccept->set5G_GUTI(
mcc, mnc, amf_cfg.guami.regionID, amf_cfg.guami.AmfSetID,
amf_cfg.guami.AmfPointer, tmsi);
std::vector<p_tai_t> tai_list = {};
p_tai_t item0 = {};
......@@ -1745,8 +1764,8 @@ void amf_n1::security_mode_complete_handle(uint32_t ran_ue_ngap_id,
regAccept->setT3512_Value(0x5, 0x1e);
uint8_t buffer[BUFFER_SIZE_1024] = {0};
int encoded_size = regAccept->encode2buffer(buffer, BUFFER_SIZE_1024);
print_buffer("amf_n1", "Registration-Accept message buffer", buffer,
encoded_size);
print_buffer(
"amf_n1", "Registration-Accept message buffer", buffer, encoded_size);
if (!encoded_size) {
Logger::nas_mm().error("Encode Registration-Accept message error");
return;
......@@ -1792,20 +1811,20 @@ void amf_n1::security_mode_complete_handle(uint32_t ran_ue_ngap_id,
set_guti_2_nas_context(guti, nc);
nc.get()->is_common_procedure_for_security_mode_control_running = false;
nas_secu_ctx *secu = nc.get()->security_ctx;
nas_secu_ctx* secu = nc.get()->security_ctx;
// protect nas message
bstring protectedNas;
encode_nas_message_protected(secu, false, INTEGRITY_PROTECTED_AND_CIPHERED,
NAS_MESSAGE_DOWNLINK, buffer, encoded_size,
protectedNas);
uint8_t *kamf = nc.get()->kamf[secu->vector_pointer];
encode_nas_message_protected(
secu, false, INTEGRITY_PROTECTED_AND_CIPHERED, NAS_MESSAGE_DOWNLINK,
buffer, encoded_size, protectedNas);
uint8_t* kamf = nc.get()->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);
print_buffer("amf_n1", "kamf", kamf, 32);
// Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
bstring kgnb_bs = blk2bstr(kgnb, 32);
itti_initial_context_setup_request *itti_msg =
itti_initial_context_setup_request* itti_msg =
new 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;
......@@ -1824,17 +1843,17 @@ void amf_n1::security_mode_complete_handle(uint32_t ran_ue_ngap_id,
}
//------------------------------------------------------------------------------
void amf_n1::security_mode_reject_handle(uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id, bstring nas_msg) {
void amf_n1::security_mode_reject_handle(
uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas_msg) {
Logger::amf_n1().debug(
"Receiving security mode reject message, handling ...");
}
//------------------------------------------------------------------------------
void amf_n1::encode_nas_message_protected(
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) {
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...");
uint8_t protected_nas_buf[1024];
int encoded_size = 0;
......@@ -1847,17 +1866,17 @@ 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;
memcpy(&protected_nas_buf[7], (uint8_t *)bdata(ciphered),
blength(ciphered));
protected_nas_buf[6] = (uint8_t) nsc->dl_count.seq_num;
memcpy(
&protected_nas_buf[7], (uint8_t*) bdata(ciphered), blength(ciphered));
uint32_t mac32;
if (!(nas_message_integrity_protected(nsc, NAS_MESSAGE_DOWNLINK,
protected_nas_buf + 6,
if (!(nas_message_integrity_protected(
nsc, NAS_MESSAGE_DOWNLINK, protected_nas_buf + 6,
input_nas_len + 1, mac32))) {
memcpy(protected_nas_buf, input_nas_buf, input_nas_len);
encoded_size = input_nas_len;
} else {
*(uint32_t *)(protected_nas_buf + 2) = htonl(mac32);
*(uint32_t*) (protected_nas_buf + 2) = htonl(mac32);
encoded_size = 7 + input_nas_len;
}
} break;
......@@ -1867,17 +1886,17 @@ void amf_n1::encode_nas_message_protected(
}
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(nsc, NAS_MESSAGE_DOWNLINK,
protected_nas_buf + 6,
if (!(nas_message_integrity_protected(
nsc, NAS_MESSAGE_DOWNLINK, protected_nas_buf + 6,
input_nas_len + 1, mac32))) {
memcpy(protected_nas_buf, input_nas_buf, input_nas_len);
encoded_size = input_nas_len;
} else {
Logger::amf_n1().debug("mac32: 0x%x", mac32);
*(uint32_t *)(protected_nas_buf + 2) = htonl(mac32);
*(uint32_t*) (protected_nas_buf + 2) = htonl(mac32);
encoded_size = 7 + input_nas_len;
}
} break;
......@@ -1889,11 +1908,9 @@ void amf_n1::encode_nas_message_protected(
}
//------------------------------------------------------------------------------
bool amf_n1::nas_message_integrity_protected(nas_secu_ctx *nsc,
uint8_t direction,
uint8_t *input_nas,
int input_nas_len,
uint32_t &mac32) {
bool amf_n1::nas_message_integrity_protected(
nas_secu_ctx* nsc, uint8_t direction, uint8_t* input_nas, int input_nas_len,
uint32_t& mac32) {
uint32_t count = 0x00000000;
if (direction)
count = 0x00000000 | ((nsc->dl_count.overflow & 0x0000ffff) << 8) |
......@@ -1904,7 +1921,8 @@ bool amf_n1::nas_message_integrity_protected(nas_secu_ctx *nsc,
nas_stream_cipher_t stream_cipher = {0};
uint8_t mac[4];
stream_cipher.key = nsc->knas_int;
print_buffer("amf_n1", "Parameters for NIA: knas_int", nsc->knas_int,
print_buffer(
"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);
......@@ -1915,13 +1933,13 @@ bool amf_n1::nas_message_integrity_protected(nas_secu_ctx *nsc,
}
Logger::amf_n1().debug("Parameters for NIA, count: 0x%x", count);
stream_cipher.bearer = 0x01; // 33.501 section 8.1.1
Logger::amf_n1().debug("Parameters for NIA, bearer: 0x%x",
stream_cipher.bearer);
Logger::amf_n1().debug(
"Parameters for NIA, bearer: 0x%x", stream_cipher.bearer);
stream_cipher.direction = direction; // "1" for downlink
Logger::amf_n1().debug("Parameters for NIA, direction: 0x%x", direction);
stream_cipher.message = (uint8_t *)input_nas;
print_buffer("amf_n1", "Parameters for NIA, message: ", input_nas,
input_nas_len);
stream_cipher.message = (uint8_t*) input_nas;
print_buffer(
"amf_n1", "Parameters for NIA, message: ", input_nas, input_nas_len);
stream_cipher.blength = input_nas_len * 8;
switch (nsc->nas_algs.integrity & 0x0f) {
case IA0_5G: {
......@@ -1932,7 +1950,7 @@ bool amf_n1::nas_message_integrity_protected(nas_secu_ctx *nsc,
Logger::amf_n1().debug("Integrity with algorithms: 128-5G-IA1");
nas_algorithms::nas_stream_encrypt_nia1(&stream_cipher, mac);
print_buffer("amf_n1", "Result for NIA1, mac: ", mac, 4);
mac32 = ntohl(*((uint32_t *)mac));
mac32 = ntohl(*((uint32_t*) mac));
Logger::amf_n1().debug("Result for NIA1, mac32: 0x%x", mac32);
return true;
} break;
......@@ -1940,7 +1958,7 @@ bool amf_n1::nas_message_integrity_protected(nas_secu_ctx *nsc,
Logger::amf_n1().debug("Integrity with algorithms: 128-5G-IA2");
nas_algorithms::nas_stream_encrypt_nia2(&stream_cipher, mac);
print_buffer("amf_n1", "Result for NIA2, mac: ", mac, 4);
mac32 = ntohl(*((uint32_t *)mac));
mac32 = ntohl(*((uint32_t*) mac));
Logger::amf_n1().debug("Result for NIA2, mac32: 0x%x", mac32);
return true;
} break;
......@@ -1948,10 +1966,10 @@ bool amf_n1::nas_message_integrity_protected(nas_secu_ctx *nsc,
}
//------------------------------------------------------------------------------
bool amf_n1::nas_message_cipher_protected(nas_secu_ctx *nsc, uint8_t direction,
bstring input_nas,
bstring &output_nas) {
uint8_t *buf = (uint8_t *)bdata(input_nas);
bool amf_n1::nas_message_cipher_protected(
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)
......@@ -1967,7 +1985,7 @@ bool amf_n1::nas_message_cipher_protected(nas_secu_ctx *nsc, uint8_t direction,
stream_cipher.count = count;
stream_cipher.bearer = 0x00; // 33.501 section 8.1.1
stream_cipher.direction = direction; // "1" for downlink
stream_cipher.message = (uint8_t *)bdata(input_nas);
stream_cipher.message = (uint8_t*) bdata(input_nas);
stream_cipher.blength = blength(input_nas) << 3;
switch (nsc->nas_algs.encryption & 0x0f) {
case EA0_5G: {
......@@ -1977,13 +1995,13 @@ bool amf_n1::nas_message_cipher_protected(nas_secu_ctx *nsc, uint8_t direction,
} break;
case EA1_128_5G: {
Logger::amf_n1().debug("Cipher protected with EA1_128_5G");
nas_algorithms::nas_stream_encrypt_nea1(&stream_cipher,
(uint8_t *)bdata(output_nas));
nas_algorithms::nas_stream_encrypt_nea1(
&stream_cipher, (uint8_t*) bdata(output_nas));
} break;
case EA2_128_5G: {
Logger::amf_n1().debug("Cipher protected with EA2_128_5G");
nas_algorithms::nas_stream_encrypt_nea2(&stream_cipher,
(uint8_t *)bdata(output_nas));
nas_algorithms::nas_stream_encrypt_nea2(
&stream_cipher, (uint8_t*) bdata(output_nas));
} break;
}
}
......@@ -1992,9 +2010,8 @@ bool amf_n1::nas_message_cipher_protected(nas_secu_ctx *nsc, uint8_t direction,
void amf_n1::run_initial_registration_procedure() {}
//------------------------------------------------------------------------------
void amf_n1::ue_initiate_de_registration_handle(uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id,
bstring nas) {
void amf_n1::ue_initiate_de_registration_handle(
uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas) {
Logger::amf_n1().debug("Handling UE-initiated De-registration Request");
/*
string guti = "1234567890";//need modify
......@@ -2032,14 +2049,14 @@ void amf_n1::ue_initiate_de_registration_handle(uint32_t ran_ue_ngap_id,
if (is_amf_ue_id_2_nas_context(amf_ue_ngap_id))
nc = amf_ue_id_2_nas_context(amf_ue_ngap_id);
else {
Logger::amf_n1().warn("No existed nas_context with amf_ue_ngap_id(0x%x)",
amf_ue_ngap_id);
Logger::amf_n1().warn(
"No existed nas_context with amf_ue_ngap_id(0x%x)", amf_ue_ngap_id);
return;
}
// decode NAS msg
DeregistrationRequest *deregReq = new DeregistrationRequest();
deregReq->decodefrombuffer(NULL, (uint8_t *)bdata(nas), blength(nas));
DeregistrationRequest* deregReq = new DeregistrationRequest();
deregReq->decodefrombuffer(NULL, (uint8_t*) bdata(nas), blength(nas));
/*
_5gs_deregistration_type_t type = {};
deregReq->getDeregistrationType(type);
......@@ -2054,22 +2071,22 @@ void amf_n1::ue_initiate_de_registration_handle(uint32_t ran_ue_ngap_id,
Logger::amf_n1().debug("5G Mobile Identity %X", mobile_id_type);
switch (mobile_id_type) {
case _5G_GUTI: {
Logger::amf_n1().debug("5G Mobile Identity, GUTI %s",
deregReq->get_5g_guti().c_str());
Logger::amf_n1().debug(
"5G Mobile Identity, GUTI %s", deregReq->get_5g_guti().c_str());
} break;
default: {
}
}
// Prepare DeregistrationAccept
DeregistrationAccept *deregAccept = new DeregistrationAccept();
DeregistrationAccept* deregAccept = new DeregistrationAccept();
deregAccept->setHeader(PLAIN_5GS_MSG);
uint8_t buffer[BUFFER_SIZE_512] = {0};
int encoded_size = deregAccept->encode2buffer(buffer, BUFFER_SIZE_512);
print_buffer("amf_n1", "De-registration Accept message buffer", buffer,
encoded_size);
print_buffer(
"amf_n1", "De-registration Accept message buffer", buffer, encoded_size);
if (encoded_size < 1) {
Logger::nas_mm().error("Encode De-registration Accept message error");
return;
......@@ -2085,12 +2102,12 @@ void amf_n1::ue_initiate_de_registration_handle(uint32_t ran_ue_ngap_id,
}
//------------------------------------------------------------------------------
void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id, bstring nas) {
void amf_n1::ul_nas_transport_handle(
uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas) {
// Decode UL_NAS_TRANSPORT message
Logger::amf_n1().debug("Handling UL NAS Transport");
ULNASTransport *ulNas = new ULNASTransport();
ulNas->decodefrombuffer(NULL, (uint8_t *)bdata(nas), blength(nas));
ULNASTransport* ulNas = new ULNASTransport();
ulNas->decodefrombuffer(NULL, (uint8_t*) bdata(nas), blength(nas));
uint8_t payload_type = ulNas->getPayloadContainerType();
uint8_t pdu_session_id = ulNas->getPduSessionId();
uint8_t request_type = ulNas->getRequestType();
......@@ -2102,8 +2119,8 @@ void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id,
} else {
dnn = bfromcstr("default");
}
print_buffer("amf_n1", "Decoded DNN bitstring", (uint8_t *)bdata(dnn),
blength(dnn));
print_buffer(
"amf_n1", "Decoded DNN bitstring", (uint8_t*) bdata(dnn), blength(dnn));
switch (payload_type) {
case N1_SM_INFORMATION: {
if (!ulNas->getPayloadContainer(sm_msg)) {
......@@ -2112,7 +2129,7 @@ void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id,
}
// send_itti_to_smf_services_consumer(ran_ue_ngap_id, amf_ue_ngap_id,
// request_type, pdu_session_id, dnn, sm_msg);
itti_smf_services_consumer *itti_msg =
itti_smf_services_consumer* itti_msg =
new itti_smf_services_consumer(TASK_AMF_N1, TASK_AMF_N11);
itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
itti_msg->amf_ue_ngap_id = amf_ue_ngap_id;
......@@ -2136,13 +2153,12 @@ void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id,
}
//------------------------------------------------------------------------------
void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id, bstring nas,
plmn_t plmn) {
void amf_n1::ul_nas_transport_handle(
uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, bstring nas, plmn_t plmn) {
// Decode UL_NAS_TRANSPORT message
Logger::amf_n1().debug("Handling UL NAS Transport");
ULNASTransport *ulNas = new ULNASTransport();
ulNas->decodefrombuffer(NULL, (uint8_t *)bdata(nas), blength(nas));
ULNASTransport* ulNas = new ULNASTransport();
ulNas->decodefrombuffer(NULL, (uint8_t*) bdata(nas), blength(nas));
uint8_t payload_type = ulNas->getPayloadContainerType();
uint8_t pdu_session_id = ulNas->getPduSessionId();
uint8_t request_type = ulNas->getRequestType();
......@@ -2154,8 +2170,8 @@ void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id,
} else {
dnn = bfromcstr("default");
}
print_buffer("amf_n1", "Decoded DNN bitstring", (uint8_t *)bdata(dnn),
blength(dnn));
print_buffer(
"amf_n1", "Decoded DNN bitstring", (uint8_t*) bdata(dnn), blength(dnn));
switch (payload_type) {
case N1_SM_INFORMATION: {
if (!ulNas->getPayloadContainer(sm_msg)) {
......@@ -2164,7 +2180,7 @@ void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id,
}
// send_itti_to_smf_services_consumer(ran_ue_ngap_id, amf_ue_ngap_id,
// request_type, pdu_session_id, dnn, sm_msg);
itti_smf_services_consumer *itti_msg =
itti_smf_services_consumer* itti_msg =
new itti_smf_services_consumer(TASK_AMF_N1, TASK_AMF_N11);
itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
itti_msg->amf_ue_ngap_id = amf_ue_ngap_id;
......@@ -2190,12 +2206,10 @@ void amf_n1::ul_nas_transport_handle(uint32_t ran_ue_ngap_id,
}
//------------------------------------------------------------------------------
void amf_n1::send_itti_to_smf_services_consumer(uint32_t ran_ue_ngap_id,
long amf_ue_ngap_id,
uint8_t request_type,
uint8_t pdu_session_id,
bstring dnn, bstring sm_msg) {
itti_smf_services_consumer *itti_msg =
void amf_n1::send_itti_to_smf_services_consumer(
uint32_t ran_ue_ngap_id, long amf_ue_ngap_id, uint8_t request_type,
uint8_t pdu_session_id, bstring dnn, bstring sm_msg) {
itti_smf_services_consumer* itti_msg =
new itti_smf_services_consumer(TASK_AMF_N1, TASK_AMF_N11);
itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
itti_msg->amf_ue_ngap_id = amf_ue_ngap_id;
......@@ -2214,13 +2228,13 @@ void amf_n1::send_itti_to_smf_services_consumer(uint32_t ran_ue_ngap_id,
}
//------------------------------------------------------------------------------
void amf_n1::dump_nas_message(uint8_t *buf, int len) {
void amf_n1::dump_nas_message(uint8_t* buf, int len) {
for (int i = 0; i < len; i++)
Logger::amf_n1().debug("[octet%d](0x%x)", i + 1, buf[i]);
}
//------------------------------------------------------------------------------
void amf_n1::ue_authentication_simulator(uint8_t *rand, uint8_t *autn) {
void amf_n1::ue_authentication_simulator(uint8_t* rand, uint8_t* autn) {
print_buffer("amf_n1", "[ue] received rand", rand, 16);
print_buffer("amf_n1", "[ue] received autn", autn, 16);
uint8_t opc[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
......@@ -2232,7 +2246,8 @@ void amf_n1::ue_authentication_simulator(uint8_t *rand, uint8_t *autn) {
print_buffer("amf_n1", "[ue] local key", key, 16);
uint8_t res[8], resStar[16];
uint8_t ck[16], ik[16], ak[6];
Authentication_5gaka::f2345(opc, key, rand, res, ck, ik,
Authentication_5gaka::f2345(
opc, key, rand, res, ck, ik,
ak); // to compute XRES, CK, IK, AK
print_buffer("amf_n1", "[ue] Result for f2345: res", res, 8);
print_buffer("amf_n1", "[ue] Result for f2345: ck", ck, 16);
......@@ -2254,8 +2269,8 @@ void amf_n1::ue_authentication_simulator(uint8_t *rand, uint8_t *autn) {
}
//------------------------------------------------------------------------------
void amf_n1::sha256(unsigned char *message, int msg_len,
unsigned char *output) {
void amf_n1::sha256(
unsigned char* message, int msg_len, unsigned char* output) {
memset(output, 0, Sha256::DIGEST_SIZE);
ctx.init();
ctx.update(message, msg_len);
......@@ -2266,12 +2281,12 @@ void amf_n1::sha256(unsigned char *message, int msg_len,
void amf_n1::run_mobility_registration_update_procedure(
std::shared_ptr<nas_context> nc) {
// encoding REGISTRATION ACCEPT
RegistrationAccept *regAccept = new RegistrationAccept();
RegistrationAccept* regAccept = new RegistrationAccept();
regAccept->setHeader(PLAIN_5GS_MSG);
regAccept->set_5GS_Registration_Result(false, false, false, 0x01);
regAccept->set5G_GUTI(amf_cfg.guami.mcc, amf_cfg.guami.mnc,
amf_cfg.guami.regionID, amf_cfg.guami.AmfSetID,
amf_cfg.guami.AmfPointer, 0x264a34c0);
regAccept->set5G_GUTI(
amf_cfg.guami.mcc, amf_cfg.guami.mnc, amf_cfg.guami.regionID,
amf_cfg.guami.AmfSetID, amf_cfg.guami.AmfPointer, 0x264a34c0);
regAccept->setT3512_Value(0x5, 0x1e);
std::vector<p_tai_t> tai_list;
......@@ -2295,28 +2310,28 @@ void amf_n1::run_mobility_registration_update_procedure(
regAccept->setALLOWED_NSSAI(nssai);
// std::string guti = amf_cfg.guami.mcc + amf_cfg.guami.mnc +
// amf_cfg.guami.regionID + amf_cfg.guami.AmfSetID + amf_cfg.guami.AmfPointer +
// "0001";
// amf_cfg.guami.regionID + amf_cfg.guami.AmfSetID + amf_cfg.guami.AmfPointer
// + "0001";
std::string guti = "1234567890"; // TODO: need modify
Logger::amf_n1().debug("Allocated GUTI %s", guti.c_str());
regAccept->set_5GS_Network_Feature_Support(0x00, 0x00);
uint8_t buffer[1024] = {0};
int encoded_size = regAccept->encode2buffer(buffer, 1024);
print_buffer("amf_n1", "Registration-Accept Message Buffer", buffer,
encoded_size);
print_buffer(
"amf_n1", "Registration-Accept Message Buffer", buffer, encoded_size);
if (!encoded_size) {
Logger::nas_mm().error("Encode Registration-Accept message error");
return;
} else {
delete regAccept;
}
nas_secu_ctx *secu = nc.get()->security_ctx;
nas_secu_ctx* secu = nc.get()->security_ctx;
// protect nas message
bstring protectedNas;
encode_nas_message_protected(secu, false, INTEGRITY_PROTECTED_AND_CIPHERED,
NAS_MESSAGE_DOWNLINK, buffer, encoded_size,
protectedNas);
encode_nas_message_protected(
secu, false, INTEGRITY_PROTECTED_AND_CIPHERED, NAS_MESSAGE_DOWNLINK,
buffer, encoded_size, protectedNas);
string supi = "imsi-" + nc.get()->imsi;
Logger::amf_n1().debug("Key for pdu session context SUPI (%s)", supi.c_str());
......@@ -2324,18 +2339,18 @@ void amf_n1::run_mobility_registration_update_procedure(
if (amf_n11_inst->is_supi_to_pdu_ctx(supi)) {
psc = amf_n11_inst->supi_to_pdu_ctx(supi);
} else {
Logger::amf_n1().error("Cannot get pdu_session_context with SUPI (%s)",
supi.c_str());
Logger::amf_n1().error(
"Cannot get pdu_session_context with SUPI (%s)", supi.c_str());
}
uint8_t *kamf = nc.get()->kamf[secu->vector_pointer];
uint8_t* kamf = nc.get()->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(ulcount, 0x01, kamf, kgnb);
print_buffer("amf_n1", "kamf", kamf, 32);
// Authentication_5gaka::derive_kgnb(ulcount, 0x01, kamf, kgnb);
bstring kgnb_bs = blk2bstr(kgnb, 32);
itti_initial_context_setup_request *itti_msg =
itti_initial_context_setup_request* itti_msg =
new itti_initial_context_setup_request(TASK_AMF_N1, TASK_AMF_N2);
itti_msg->ran_ue_ngap_id = nc.get()->ran_ue_ngap_id;
itti_msg->amf_ue_ngap_id = nc.get()->amf_ue_ngap_id;
......@@ -2348,24 +2363,25 @@ void amf_n1::run_mobility_registration_update_procedure(
std::shared_ptr<itti_initial_context_setup_request>(itti_msg);
int ret = itti_inst->send_msg(i);
if (0 != ret) {
Logger::amf_n1().error("Could not send ITTI message %s to task TASK_AMF_N2",
Logger::amf_n1().error(
"Could not send ITTI message %s to task TASK_AMF_N2",
i->get_msg_name());
}
}
//------------------------------------------------------------------------------
void amf_n1::set_5gmm_state(std::shared_ptr<nas_context> nc,
_5gmm_state_t state) {
Logger::amf_n1().debug("Set 5GMM state to %s",
_5gmm_state_e2str[state].c_str());
void amf_n1::set_5gmm_state(
std::shared_ptr<nas_context> nc, _5gmm_state_t state) {
Logger::amf_n1().debug(
"Set 5GMM state to %s", _5gmm_state_e2str[state].c_str());
std::unique_lock lock(m_nas_context);
nc.get()->_5gmm_state = state;
// TODO:
}
//------------------------------------------------------------------------------
void amf_n1::get_5gmm_state(std::shared_ptr<nas_context> nc,
_5gmm_state_t &state) {
void amf_n1::get_5gmm_state(
std::shared_ptr<nas_context> nc, _5gmm_state_t& state) {
// TODO:
state = nc.get()->_5gmm_state;
}
......@@ -48,6 +48,7 @@ class ue_context {
bool isUeContextRequest;
NrCgi_t cgi;
Tai_t tai;
std::string supi;
};
#endif
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