|
|
@ -289,90 +289,8 @@ hss::gen_auth_info_answer(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
|
|
|
hss::resync_sqn(uint64_t imsi, uint8_t *auts)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
switch (m_auth_algo)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
case HSS_ALGO_XOR:
|
|
|
|
|
|
|
|
ret = resync_sqn_xor(imsi, auts);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case HSS_ALGO_MILENAGE:
|
|
|
|
|
|
|
|
ret = resync_sqn_milenage(imsi, auts);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
increment_ue_sqn(imsi);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
|
|
|
hss::resync_sqn_xor(uint64_t imsi, uint8_t *auts)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
m_hss_log->error("XOR SQN synchronization not supported yet\n");
|
|
|
|
|
|
|
|
m_hss_log->console("XOR SQNs synchronization not supported yet\n");
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
|
|
|
hss::resync_sqn_milenage(uint64_t imsi, uint8_t *auts)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
uint8_t last_rand[16];
|
|
|
|
|
|
|
|
uint8_t ak[6];
|
|
|
|
|
|
|
|
uint8_t mac_s[8];
|
|
|
|
|
|
|
|
uint8_t sqn_ms_xor_ak[6];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t k[16];
|
|
|
|
|
|
|
|
uint8_t amf[2];
|
|
|
|
|
|
|
|
uint8_t opc[16];
|
|
|
|
|
|
|
|
uint8_t sqn[6];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!get_k_amf_opc_sqn(imsi, k, amf, opc, sqn))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get_last_rand(imsi, last_rand);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(int i=0; i<6; i++){
|
|
|
|
|
|
|
|
sqn_ms_xor_ak[i] = auts[i];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(int i=0; i<8; i++){
|
|
|
|
|
|
|
|
mac_s[i] = auts[i+6];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(k, 16, "User Key : ");
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(opc, 16, "User OPc : ");
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(last_rand, 16, "User Last Rand : ");
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(auts, 16, "AUTS : ");
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(sqn_ms_xor_ak, 6, "SQN xor AK : ");
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(mac_s, 8, "MAC : ");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
security_milenage_f5_star(k, opc, last_rand, ak);
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(ak, 6, "Resynch AK : ");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t sqn_ms[6];
|
|
|
|
|
|
|
|
for(int i=0; i<6; i++){
|
|
|
|
|
|
|
|
sqn_ms[i] = sqn_ms_xor_ak[i] ^ ak[i];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(sqn_ms, 6, "SQN MS : ");
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(sqn , 6, "SQN HE : ");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(amf, 2, "AMF : ");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t mac_s_tmp[8];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
security_milenage_f1_star(k, opc, last_rand, sqn_ms, amf, mac_s_tmp);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(mac_s_tmp, 8, "MAC calc : ");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
set_sqn(imsi, sqn_ms);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
bool
|
|
|
|
hss::gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres)
|
|
|
|
hss::gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -536,7 +454,7 @@ hss::gen_auth_info_answer_xor(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uin
|
|
|
|
mcc,
|
|
|
|
mcc,
|
|
|
|
mnc,
|
|
|
|
mnc,
|
|
|
|
k_asme);
|
|
|
|
k_asme);
|
|
|
|
|
|
|
|
|
|
|
|
m_hss_log->debug("User MCC : %x MNC : %x \n", mcc, mnc);
|
|
|
|
m_hss_log->debug("User MCC : %x MNC : %x \n", mcc, mnc);
|
|
|
|
m_hss_log->debug_hex(k_asme, 32, "User k_asme : ");
|
|
|
|
m_hss_log->debug_hex(k_asme, 32, "User k_asme : ");
|
|
|
|
|
|
|
|
|
|
|
@ -561,6 +479,23 @@ hss::gen_auth_info_answer_xor(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uin
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
|
|
|
hss::gen_update_loc_answer(uint64_t imsi, uint8_t* qci)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
std::map<uint64_t,hss_ue_ctx_t*>::iterator ue_ctx_it = m_imsi_to_ue_ctx.find(imsi);
|
|
|
|
|
|
|
|
if(ue_ctx_it == m_imsi_to_ue_ctx.end())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
m_hss_log->info("User not found. IMSI: %015lu\n",imsi);
|
|
|
|
|
|
|
|
m_hss_log->console("User not found. IMSI: %015lu\n",imsi);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
hss_ue_ctx_t *ue_ctx = ue_ctx_it->second;
|
|
|
|
|
|
|
|
m_hss_log->info("Found User %015lu\n",imsi);
|
|
|
|
|
|
|
|
*qci = ue_ctx->qci;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
bool
|
|
|
|
hss::get_k_amf_opc_sqn(uint64_t imsi, uint8_t *k, uint8_t *amf, uint8_t *opc, uint8_t *sqn)
|
|
|
|
hss::get_k_amf_opc_sqn(uint64_t imsi, uint8_t *k, uint8_t *amf, uint8_t *opc, uint8_t *sqn)
|
|
|
@ -583,6 +518,90 @@ hss::get_k_amf_opc_sqn(uint64_t imsi, uint8_t *k, uint8_t *amf, uint8_t *opc, ui
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
|
|
|
hss::resync_sqn(uint64_t imsi, uint8_t *auts)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
switch (m_auth_algo)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
case HSS_ALGO_XOR:
|
|
|
|
|
|
|
|
ret = resync_sqn_xor(imsi, auts);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case HSS_ALGO_MILENAGE:
|
|
|
|
|
|
|
|
ret = resync_sqn_milenage(imsi, auts);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
increment_ue_sqn(imsi);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
|
|
|
hss::resync_sqn_xor(uint64_t imsi, uint8_t *auts)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
m_hss_log->error("XOR SQN synchronization not supported yet\n");
|
|
|
|
|
|
|
|
m_hss_log->console("XOR SQNs synchronization not supported yet\n");
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
|
|
|
hss::resync_sqn_milenage(uint64_t imsi, uint8_t *auts)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
uint8_t last_rand[16];
|
|
|
|
|
|
|
|
uint8_t ak[6];
|
|
|
|
|
|
|
|
uint8_t mac_s[8];
|
|
|
|
|
|
|
|
uint8_t sqn_ms_xor_ak[6];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t k[16];
|
|
|
|
|
|
|
|
uint8_t amf[2];
|
|
|
|
|
|
|
|
uint8_t opc[16];
|
|
|
|
|
|
|
|
uint8_t sqn[6];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!get_k_amf_opc_sqn(imsi, k, amf, opc, sqn))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get_last_rand(imsi, last_rand);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(int i=0; i<6; i++){
|
|
|
|
|
|
|
|
sqn_ms_xor_ak[i] = auts[i];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(int i=0; i<8; i++){
|
|
|
|
|
|
|
|
mac_s[i] = auts[i+6];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(k, 16, "User Key : ");
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(opc, 16, "User OPc : ");
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(last_rand, 16, "User Last Rand : ");
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(auts, 16, "AUTS : ");
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(sqn_ms_xor_ak, 6, "SQN xor AK : ");
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(mac_s, 8, "MAC : ");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
security_milenage_f5_star(k, opc, last_rand, ak);
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(ak, 6, "Resynch AK : ");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t sqn_ms[6];
|
|
|
|
|
|
|
|
for(int i=0; i<6; i++){
|
|
|
|
|
|
|
|
sqn_ms[i] = sqn_ms_xor_ak[i] ^ ak[i];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(sqn_ms, 6, "SQN MS : ");
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(sqn , 6, "SQN HE : ");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(amf, 2, "AMF : ");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t mac_s_tmp[8];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
security_milenage_f1_star(k, opc, last_rand, sqn_ms, amf, mac_s_tmp);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m_hss_log->debug_hex(mac_s_tmp, 8, "MAC calc : ");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
set_sqn(imsi, sqn_ms);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
hss::increment_ue_sqn(uint64_t imsi)
|
|
|
|
hss::increment_ue_sqn(uint64_t imsi)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -615,6 +634,7 @@ hss::increment_sqn(uint8_t *sqn, uint8_t *next_sqn)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
hss::set_sqn(uint64_t imsi, uint8_t *sqn)
|
|
|
|
hss::set_sqn(uint64_t imsi, uint8_t *sqn)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -670,7 +690,7 @@ bool hss::get_ue_ctx(uint64_t imsi, hss_ue_ctx_t **ue_ctx)
|
|
|
|
m_hss_log->info("User not found. IMSI: %015lu\n",imsi);
|
|
|
|
m_hss_log->info("User not found. IMSI: %015lu\n",imsi);
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
*ue_ctx = ue_ctx_it->second;
|
|
|
|
*ue_ctx = ue_ctx_it->second;
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -715,15 +735,4 @@ hss::hex_string(uint8_t *hex, int size)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ss.str();
|
|
|
|
return ss.str();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
|
|
|
|
string_to_imsi()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
uint64_t imsi = 0;
|
|
|
|
|
|
|
|
for(int i=0;i<=14;i++){
|
|
|
|
|
|
|
|
imsi += attach_req.eps_mobile_id.imsi[i]*std::pow(10,14-i);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return imsi;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
} //namespace srsepc
|
|
|
|
} //namespace srsepc
|
|
|
|