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