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

Merge branch 'fix_naked_ptr_security_ctx' into 'develop'

Fix naked ptr for NAS security context

See merge request oai/cn5g/oai-cn5g-amf!200
parents f659ec6b 2cb03dbe
This diff is collapsed.
......@@ -366,7 +366,7 @@ class amf_n1 {
/*
* Encode the NAS message with corresponding integrity and ciphered algorithms
* @param [nas_secu_ctx*] nsc: NAS Security context
* @param [nas_secu_ctx&] nsc: NAS Security context
* @param [bool] is_secu_ctx_new: indicate the status of the security context
* (new/old)
* @param [uint8_t] security_header_type: Security Header Type
......@@ -377,13 +377,13 @@ class amf_n1 {
* @return void
*/
void encode_nas_message_protected(
nas_secu_ctx* nsc, bool is_secu_ctx_new, uint8_t security_header_type,
nas_secu_ctx& nsc, bool is_secu_ctx_new, uint8_t security_header_type,
uint8_t direction, uint8_t* input_nas_buf, int input_nas_len,
bstring& encrypted_nas);
/*
* Encrypt with integrity algorithm
* @param [nas_secu_ctx*] nsc: NAS Security context
* @param [nas_secu_ctx&] nsc: NAS Security context
* @param [uint8_t] direction: Direction
* @param [uint8_t*] input_nas_buf: Buffer of the input NAS
* @param [int] input_nas_les: Length of the buffer
......@@ -391,19 +391,19 @@ class amf_n1 {
* @return true if MAC can be calculated successfully, otherwise return false
*/
bool nas_message_integrity_protected(
nas_secu_ctx* nsc, uint8_t direction, uint8_t* input_nas,
nas_secu_ctx& nsc, uint8_t direction, uint8_t* input_nas,
int input_nas_len, uint32_t& mac);
/*
* Cipher NAS message with the corresponding ciphered algorithm
* @param [nas_secu_ctx*] nsc: NAS Security context
* @param [nas_secu_ctx&] nsc: NAS Security context
* @param [uint8_t] direction: Direction
* @param [bstring] input_nas: Input NAS message
* @param [bstring&] output_nas: Output NAS message
* @return true if message is successfully ciphered, otherwise return false
*/
bool nas_message_cipher_protected(
nas_secu_ctx* nsc, uint8_t direction, bstring input_nas,
nas_secu_ctx& nsc, uint8_t direction, bstring input_nas,
bstring& output_nas);
// NOTE: All the MySQL-related functions are currently implemented in
......
......@@ -1581,20 +1581,27 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) {
return false;
}
nas_secu_ctx* secu = nc->security_ctx;
if (!secu) {
if (!nc->security_ctx.has_value()) {
Logger::amf_n2().error("No Security Context found");
return false;
}
uint8_t* kamf = nc->kamf[secu->vector_pointer];
uint8_t kgnb[32];
uint32_t ulcount = secu->ul_count.seq_num | (secu->ul_count.overflow << 8);
uint8_t kamf[AUTH_VECTOR_LENGTH_OCTETS];
uint8_t kgnb[AUTH_VECTOR_LENGTH_OCTETS];
if (!nc->get_kamf(nc->security_ctx.value().vector_pointer, kamf)) {
Logger::amf_n1().warn("No Kamf found");
return false;
}
uint32_t ulcount = nc->security_ctx.value().ul_count.seq_num |
(nc->security_ctx.value().ul_count.overflow << 8);
Logger::amf_n2().debug(
"Handover Required, Uplink count (%d)", secu->ul_count.seq_num);
uint8_t knh[32];
"Handover Required, Uplink count (%d)",
nc->security_ctx.value().ul_count.seq_num);
uint8_t knh[AUTH_VECTOR_LENGTH_OCTETS];
Authentication_5gaka::handover_ncc_derive_knh(
ulcount, 0x01, kamf, kgnb, knh, unc->ncc);
bstring knh_bs = blk2bstr(knh, 32);
ulcount, 0x01, kamf, kgnb, knh,
unc->ncc); // TODO: remove hardcoded value
bstring knh_bs = blk2bstr(knh, AUTH_VECTOR_LENGTH_OCTETS);
handover_request->setSecurityContext(unc->ncc /*NCC count*/, knh_bs);
string supi = conv::imsi_to_supi(nc->imsi);
......
......@@ -203,7 +203,6 @@ void nf_profile::to_json(nlohmann::json& data) const {
nlohmann::json tmp = {};
tmp["sst"] = s.sST;
tmp["sd"] = s.sD;
;
data["sNssais"].push_back(tmp);
}
// ipv4_addresses
......
......@@ -22,9 +22,7 @@
#include "nas_context.hpp"
//------------------------------------------------------------------------------
nas_context::nas_context()
: _vector(), _5g_he_av(), _5g_av(), kamf(), _5gmm_capability() {
security_ctx = nullptr;
nas_context::nas_context() : _5g_he_av(), _5g_av(), kamf(), _5gmm_capability() {
is_imsi_present = false;
is_stacs_available = false;
is_auth_vectors_present = false;
......@@ -44,7 +42,7 @@ nas_context::nas_context()
is_common_procedure_for_identification_running = false;
is_common_procedure_for_security_mode_control_running = false;
is_common_procedure_for_nas_transport_running = false;
security_ctx = nullptr;
security_ctx = std::nullopt;
is_current_security_available = false;
registration_attempt_counter = 0;
is_imsi_present = false;
......@@ -62,3 +60,13 @@ nas_context::nas_context()
//------------------------------------------------------------------------------
nas_context::~nas_context() {}
//------------------------------------------------------------------------------
bool nas_context::get_kamf(
uint8_t index, uint8_t (&k)[AUTH_VECTOR_LENGTH_OCTETS]) const {
if (index >= MAX_5GS_AUTH_VECTORS) return false;
for (uint8_t i = 0; i < AUTH_VECTOR_LENGTH_OCTETS; i++) {
k[i] = kamf[index][i];
}
return true;
}
......@@ -22,10 +22,6 @@
#ifndef _AMF_NAS_CONTEXT_H_
#define _AMF_NAS_CONTEXT_H_
#include <stdint.h>
#include <string>
#include "UESecurityCapability.hpp"
#include "authentication_algorithms_with_5gaka.hpp"
#include "itti.hpp"
......@@ -110,14 +106,13 @@ class nas_context {
bool is_common_procedure_for_security_mode_control_running;
bool is_common_procedure_for_nas_transport_running;
// security related
// Security-related parameters
#define MAX_5GS_AUTH_VECTORS 1
auc_vector_t _vector[MAX_5GS_AUTH_VECTORS]; // 5GS Authentication vector
_5G_HE_AV_t _5g_he_av[MAX_5GS_AUTH_VECTORS]; // generated by UDM
_5G_AV_t _5g_av[MAX_5GS_AUTH_VECTORS]; // generated by AUSF
std::string href;
uint8_t kamf[MAX_5GS_AUTH_VECTORS][32];
nas_secu_ctx* security_ctx; // TODO: avoid using naked ptr
uint8_t kamf[MAX_5GS_AUTH_VECTORS][AUTH_VECTOR_LENGTH_OCTETS];
std::optional<nas_secu_ctx> security_ctx;
bool is_current_security_available;
int registration_attempt_counter; // used to limit the subsequently reject
// registration
......@@ -128,6 +123,8 @@ class nas_context {
bool is_5g_guti_present;
bool is_auth_vectors_present;
bool to_be_register_by_new_suci;
bool get_kamf(uint8_t index, uint8_t (&k)[AUTH_VECTOR_LENGTH_OCTETS]) const;
};
#endif
......@@ -405,8 +405,10 @@ void Authentication_5gaka::derive_knas(
}
void Authentication_5gaka::derive_kgnb(
uint32_t uplinkCount, uint8_t accessType, uint8_t kamf[32], uint8_t* kgnb) {
Logger::amf_n1().debug("derive_kgnb ...");
uint32_t uplinkCount, uint8_t accessType,
uint8_t kamf[AUTH_VECTOR_LENGTH_OCTETS],
uint8_t (&kgnb)[AUTH_VECTOR_LENGTH_OCTETS]) {
Logger::amf_n1().debug("Derive Kgnb ...");
uint8_t S[20];
S[0] = 0x6E;
*(uint32_t*) (S + 1) = htonl(uplinkCount);
......@@ -417,13 +419,15 @@ void Authentication_5gaka::derive_kgnb(
S[9] = 0x01;
// output_wrapper::print_buffer("amf_n1", "inputstring S", S, 10);
// output_wrapper::print_buffer("amf_n1", "key KEY", kamf, 32);
kdf(kamf, 32, S, 10, kgnb, 32);
kdf(kamf, 32, S, 10, kgnb, AUTH_VECTOR_LENGTH_OCTETS);
// output_wrapper::print_buffer("amf_n1", "kgnb", kgnb, 32);
// Logger::amf_n1().debug("derive kgnb finished!");
}
void Authentication_5gaka::handover_ncc_derive_knh(
uint32_t uplinkCount, uint8_t accessType, uint8_t kamf[32], uint8_t* kgnb,
uint8_t* knh, int ncc) {
uint32_t uplinkCount, uint8_t accessType,
uint8_t kamf[AUTH_VECTOR_LENGTH_OCTETS],
uint8_t (&kgnb)[AUTH_VECTOR_LENGTH_OCTETS],
uint8_t (&knh)[AUTH_VECTOR_LENGTH_OCTETS], int ncc) {
Logger::amf_n1().debug("derive_handover_ncc_knh ...");
uint8_t S[20], SS[ncc][35];
S[0] = 0x6E;
......
......@@ -41,6 +41,8 @@
#define KASME_LENGTH_OCTETS (32)
#define MAC_S_LENGTH (8)
#define AUTH_VECTOR_LENGTH_OCTETS 32
typedef mpz_t random_t;
typedef mpz_t sqn_t;
......@@ -140,11 +142,14 @@ class Authentication_5gaka {
algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t kamf[32],
uint8_t* knas);
static void derive_kgnb(
uint32_t uplinkCount, uint8_t accessType, uint8_t kamf[32],
uint8_t* kgnb);
uint32_t uplinkCount, uint8_t accessType,
uint8_t kamf[AUTH_VECTOR_LENGTH_OCTETS],
uint8_t (&kgnb)[AUTH_VECTOR_LENGTH_OCTETS]);
static void handover_ncc_derive_knh(
uint32_t uplinkCount, uint8_t accessType, uint8_t kamf[32], uint8_t* kgnb,
uint8_t* knh, int ncc);
uint32_t uplinkCount, uint8_t accessType,
uint8_t kamf[AUTH_VECTOR_LENGTH_OCTETS],
uint8_t (&kgnb)[AUTH_VECTOR_LENGTH_OCTETS],
uint8_t (&knh)[AUTH_VECTOR_LENGTH_OCTETS], int ncc);
static uint8_t* sqn_ms_derive(
const uint8_t opc[16], uint8_t* key, uint8_t* auts, uint8_t* rand);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment