mirror of https://github.com/PentHertz/srsLTE.git
Adding per UE authentication algorithm choice to the HSS and users_db.csv.
This commit is contained in:
parent
ca603810ce
commit
3ad19f21b6
|
@ -36,12 +36,10 @@ paging_timer = 2
|
|||
#####################################################################
|
||||
# HSS configuration
|
||||
#
|
||||
# algo: Authentication algorithm (xor/milenage)
|
||||
# db_file: Location of .csv file that stores UEs information.
|
||||
#
|
||||
#####################################################################
|
||||
[hss]
|
||||
auth_algo = xor
|
||||
db_file = user_db.csv
|
||||
|
||||
#####################################################################
|
||||
|
|
|
@ -50,27 +50,27 @@
|
|||
namespace srsepc {
|
||||
|
||||
typedef struct {
|
||||
std::string auth_algo;
|
||||
std::string db_file;
|
||||
uint16_t mcc;
|
||||
uint16_t mnc;
|
||||
} hss_args_t;
|
||||
|
||||
typedef struct {
|
||||
std::string name;
|
||||
uint64_t imsi;
|
||||
uint8_t key[16];
|
||||
bool op_configured;
|
||||
uint8_t op[16];
|
||||
uint8_t opc[16];
|
||||
uint8_t amf[2];
|
||||
uint8_t sqn[6];
|
||||
uint16_t qci;
|
||||
uint8_t last_rand[16];
|
||||
} hss_ue_ctx_t;
|
||||
|
||||
enum hss_auth_algo { HSS_ALGO_XOR, HSS_ALGO_MILENAGE };
|
||||
|
||||
typedef struct {
|
||||
std::string name;
|
||||
uint64_t imsi;
|
||||
enum hss_auth_algo algo;
|
||||
uint8_t key[16];
|
||||
bool op_configured;
|
||||
uint8_t op[16];
|
||||
uint8_t opc[16];
|
||||
uint8_t amf[2];
|
||||
uint8_t sqn[6];
|
||||
uint16_t qci;
|
||||
uint8_t last_rand[16];
|
||||
} hss_ue_ctx_t;
|
||||
|
||||
class hss : public hss_interface_nas
|
||||
{
|
||||
public:
|
||||
|
@ -118,7 +118,6 @@ private:
|
|||
|
||||
std::string hex_string(uint8_t* hex, int size);
|
||||
|
||||
enum hss_auth_algo m_auth_algo;
|
||||
std::string db_file;
|
||||
|
||||
/*Logs*/
|
||||
|
|
|
@ -73,10 +73,6 @@ int hss::init(hss_args_t* hss_args, srslte::log_filter* hss_log)
|
|||
/*Init loggers*/
|
||||
m_hss_log = hss_log;
|
||||
|
||||
/*Set authentication algorithm*/
|
||||
if (set_auth_algo(hss_args->auth_algo) == false) {
|
||||
return -1;
|
||||
}
|
||||
/*Read user information from DB*/
|
||||
if (read_db_file(hss_args->db_file) == false) {
|
||||
m_hss_log->console("Error reading user database file %s\n", hss_args->db_file.c_str());
|
||||
|
@ -88,8 +84,8 @@ int hss::init(hss_args_t* hss_args, srslte::log_filter* hss_log)
|
|||
|
||||
db_file = hss_args->db_file;
|
||||
|
||||
m_hss_log->info("HSS Initialized. DB file %s, authentication algorithm %s, MCC: %d, MNC: %d\n",
|
||||
hss_args->db_file.c_str(), hss_args->auth_algo.c_str(), mcc, mnc);
|
||||
m_hss_log->info("HSS Initialized. DB file %s, MCC: %d, MNC: %d\n",
|
||||
hss_args->db_file.c_str(), mcc, mnc);
|
||||
m_hss_log->console("HSS Initialized.\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -107,20 +103,6 @@ void hss::stop()
|
|||
return;
|
||||
}
|
||||
|
||||
bool hss::set_auth_algo(std::string auth_algo)
|
||||
{
|
||||
if (auth_algo != "xor" && auth_algo != "milenage") {
|
||||
m_hss_log->error("Unrecognized authentication algorithm. auth_algo = %s\n", auth_algo.c_str());
|
||||
return false;
|
||||
}
|
||||
if (auth_algo == "xor") {
|
||||
m_auth_algo = HSS_ALGO_XOR;
|
||||
} else {
|
||||
m_auth_algo = HSS_ALGO_MILENAGE;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hss::read_db_file(std::string db_filename)
|
||||
{
|
||||
std::ifstream m_db_file;
|
||||
|
@ -134,30 +116,45 @@ bool hss::read_db_file(std::string db_filename)
|
|||
std::string line;
|
||||
while (std::getline(m_db_file, line)) {
|
||||
if (line[0] != '#') {
|
||||
uint column_size = 8;
|
||||
uint column_size = 9;
|
||||
std::vector<std::string> split = split_string(line, ',');
|
||||
if (split.size() != column_size) {
|
||||
m_hss_log->error("Error parsing UE database. Wrong number of columns in .csv\n");
|
||||
m_hss_log->error("Columns: %zd, Expected %d.\n", split.size(), column_size);
|
||||
if (split.size() == 8) {
|
||||
m_hss_log->console("\nError parsing UE database. Wrong number of columns in user database CSV.\n");
|
||||
m_hss_log->console("Perhaps you are using an old user_db.csv?\n");
|
||||
m_hss_log->console("In the new 19.03 version of srsLTE you are required to specify the authentication "
|
||||
"algorithim in the CSV file.\n");
|
||||
m_hss_log->console("See 'srsepc/user_db.csv.example' for an example.\n\n");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
hss_ue_ctx_t* ue_ctx = new hss_ue_ctx_t;
|
||||
ue_ctx->name = split[0];
|
||||
ue_ctx->imsi = atoll(split[1].c_str());
|
||||
get_uint_vec_from_hex_str(split[2], ue_ctx->key, 16);
|
||||
if (split[3] == std::string("op")) {
|
||||
if (split[1] == std::string("xor")) {
|
||||
ue_ctx->algo = HSS_ALGO_XOR;
|
||||
} else if (split[1] == std::string("mil")) {
|
||||
ue_ctx->algo = HSS_ALGO_MILENAGE;
|
||||
} else {
|
||||
m_hss_log->error("Neither XOR nor MILENAGE configured.\n");
|
||||
return false;
|
||||
}
|
||||
ue_ctx->imsi = atoll(split[2].c_str());
|
||||
get_uint_vec_from_hex_str(split[3], ue_ctx->key, 16);
|
||||
if (split[4] == std::string("op")) {
|
||||
ue_ctx->op_configured = true;
|
||||
get_uint_vec_from_hex_str(split[4], ue_ctx->op, 16);
|
||||
get_uint_vec_from_hex_str(split[5], ue_ctx->op, 16);
|
||||
srslte::compute_opc(ue_ctx->key, ue_ctx->op, ue_ctx->opc);
|
||||
} else if (split[3] == std::string("opc")) {
|
||||
} else if (split[4] == std::string("opc")) {
|
||||
ue_ctx->op_configured = false;
|
||||
get_uint_vec_from_hex_str(split[4], ue_ctx->opc, 16);
|
||||
get_uint_vec_from_hex_str(split[5], ue_ctx->opc, 16);
|
||||
} else {
|
||||
m_hss_log->error("Neither OP nor OPc configured.\n");
|
||||
return false;
|
||||
}
|
||||
get_uint_vec_from_hex_str(split[5], ue_ctx->amf, 2);
|
||||
get_uint_vec_from_hex_str(split[6], ue_ctx->sqn, 6);
|
||||
get_uint_vec_from_hex_str(split[6], ue_ctx->amf, 2);
|
||||
get_uint_vec_from_hex_str(split[7], ue_ctx->sqn, 6);
|
||||
|
||||
m_hss_log->debug("Added user from DB, IMSI: %015" PRIu64 "\n", ue_ctx->imsi);
|
||||
m_hss_log->debug_hex(ue_ctx->key, 16, "User Key : ");
|
||||
|
@ -167,7 +164,7 @@ bool hss::read_db_file(std::string db_filename)
|
|||
m_hss_log->debug_hex(ue_ctx->opc, 16, "User OPc : ");
|
||||
m_hss_log->debug_hex(ue_ctx->amf, 2, "AMF : ");
|
||||
m_hss_log->debug_hex(ue_ctx->sqn, 6, "SQN : ");
|
||||
ue_ctx->qci = atoi(split[7].c_str());
|
||||
ue_ctx->qci = atoi(split[8].c_str());
|
||||
m_hss_log->debug("Default Bearer QCI: %d\n", ue_ctx->qci);
|
||||
m_imsi_to_ue_ctx.insert(std::pair<uint64_t, hss_ue_ctx_t*>(ue_ctx->imsi, ue_ctx));
|
||||
}
|
||||
|
@ -203,6 +200,8 @@ bool hss::write_db_file(std::string db_filename)
|
|||
<< "# " << std::endl
|
||||
<< "# Name: Human readable name to help distinguish UE's. Ignored by the HSS " << std::endl
|
||||
<< "# IMSI: UE's IMSI value " << std::endl
|
||||
<< "# Auth: Authentication algorithm used by the UE. Valid algorithms are XOR "
|
||||
"(xor) and MILENAGE (mil)" << std::endl
|
||||
<< "# Key: UE's key, where other keys are derived from. Stored in hexadecimal" << std::endl
|
||||
<< "# OP_Type: Operator's code type, either OP or OPc " << std::endl
|
||||
<< "# OP/OPc: Operator Code/Cyphered Operator Code, stored in hexadecimal " << std::endl
|
||||
|
@ -216,6 +215,8 @@ bool hss::write_db_file(std::string db_filename)
|
|||
while (it != m_imsi_to_ue_ctx.end()) {
|
||||
m_db_file << it->second->name;
|
||||
m_db_file << ",";
|
||||
m_db_file << (it->second->algo == HSS_ALGO_XOR ? "xor" : "mil");
|
||||
m_db_file << ",";
|
||||
m_db_file << std::setfill('0') << std::setw(15) << it->second->imsi;
|
||||
m_db_file << ",";
|
||||
m_db_file << hex_string(it->second->key, 16);
|
||||
|
@ -244,8 +245,16 @@ bool hss::write_db_file(std::string db_filename)
|
|||
|
||||
bool hss::gen_auth_info_answer(uint64_t imsi, uint8_t* k_asme, uint8_t* autn, uint8_t* rand, uint8_t* xres)
|
||||
{
|
||||
bool ret = false;
|
||||
switch (m_auth_algo) {
|
||||
hss_ue_ctx_t* ue_ctx = NULL;
|
||||
|
||||
bool ret = get_ue_ctx(imsi, &ue_ctx);
|
||||
if (ret == false) {
|
||||
m_hss_log->console("User not found at HSS. IMSI: %015" PRIu64 "\n", imsi);
|
||||
m_hss_log->error("User not found at HSS. IMSI: %015" PRIu64 "\n", imsi);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (ue_ctx->algo) {
|
||||
case HSS_ALGO_XOR:
|
||||
ret = gen_auth_info_answer_xor(imsi, k_asme, autn, rand, xres);
|
||||
break;
|
||||
|
@ -439,8 +448,16 @@ bool hss::get_k_amf_opc_sqn(uint64_t imsi, uint8_t* k, uint8_t* amf, uint8_t* op
|
|||
|
||||
bool hss::resync_sqn(uint64_t imsi, uint8_t* auts)
|
||||
{
|
||||
bool ret = false;
|
||||
switch (m_auth_algo) {
|
||||
hss_ue_ctx_t* ue_ctx = NULL;
|
||||
|
||||
bool ret = get_ue_ctx(imsi, &ue_ctx);
|
||||
if (ret == false) {
|
||||
m_hss_log->console("User not found at HSS. IMSI: %015" PRIu64 "\n", imsi);
|
||||
m_hss_log->error("User not found at HSS. IMSI: %015" PRIu64 "\n", imsi);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (ue_ctx->algo) {
|
||||
case HSS_ALGO_XOR:
|
||||
ret = resync_sqn_xor(imsi, auts);
|
||||
break;
|
||||
|
@ -448,6 +465,7 @@ bool hss::resync_sqn(uint64_t imsi, uint8_t* auts)
|
|||
ret = resync_sqn_milenage(imsi, auts);
|
||||
break;
|
||||
}
|
||||
|
||||
increment_seq_after_resync(imsi);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -124,7 +124,6 @@ void parse_args(all_args_t* args, int argc, char* argv[])
|
|||
("mme.integrity_algo", bpo::value<string>(&integrity_algo)->default_value("EIA1"), "Set preferred integrity protection algorithm for NAS")
|
||||
("mme.paging_timer", bpo::value<uint16_t>(&paging_timer)->default_value(2), "Set paging timer value in seconds (T3413)")
|
||||
("hss.db_file", bpo::value<string>(&hss_db_file)->default_value("ue_db.csv"), ".csv file that stores UE's keys")
|
||||
("hss.auth_algo", bpo::value<string>(&hss_auth_algo)->default_value("milenage"), "HSS uthentication algorithm.")
|
||||
("spgw.gtpu_bind_addr", bpo::value<string>(&spgw_bind_addr)->default_value("127.0.0.1"), "IP address of SP-GW for the S1-U connection")
|
||||
("spgw.sgi_if_addr", bpo::value<string>(&sgi_if_addr)->default_value("176.16.0.1"), "IP address of TUN interface for the SGi connection")
|
||||
("spgw.sgi_if_name", bpo::value<string>(&sgi_if_name)->default_value("srs_spgw_sgi"), "Name of TUN interface for the SGi connection")
|
||||
|
@ -272,7 +271,6 @@ void parse_args(all_args_t* args, int argc, char* argv[])
|
|||
args->spgw_args.sgi_if_name = sgi_if_name;
|
||||
args->spgw_args.max_paging_queue = max_paging_queue;
|
||||
args->hss_args.db_file = hss_db_file;
|
||||
args->hss_args.auth_algo = hss_auth_algo;
|
||||
|
||||
// Apply all_level to any unset layers
|
||||
if (vm.count("log.all_level")) {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
#
|
||||
# .csv to store UE's information in HSS
|
||||
# Kept in the following format: "Name,IMSI,Key,OP_Type,OP,AMF,SQN,QCI"
|
||||
# Kept in the following format: "Name,Auth,IMSI,Key,OP_Type,OP,AMF,SQN,QCI"
|
||||
#
|
||||
# Name: Human readable name to help distinguish UE's. Ignored by the HSS
|
||||
# Auth: Authentication algorithm used by the UE. Valid algorithms are XOR (xor) and MILENAGE (mil)
|
||||
# IMSI: UE's IMSI value
|
||||
# Key: UE's key, where other keys are derived from. Stored in hexadecimal
|
||||
# OP_Type: Operator's code type, either OP or OPc
|
||||
|
@ -12,5 +13,5 @@
|
|||
# QCI: QoS Class Identifier for the UE's default bearer.
|
||||
#
|
||||
# Note: Lines starting by '#' are ignored and will be overwritten
|
||||
ue1,001010123456789,00112233445566778899aabbccddeeff,opc,63bfa50ee6523365ff14c1f45f88737d,9001,000000001234,7
|
||||
ue2,001010123456780,00112233445566778899aabbccddeeff,opc,63bfa50ee6523365ff14c1f45f88737d,8000,000000001234,7
|
||||
ue1,xor,001010123456789,00112233445566778899aabbccddeeff,opc,63bfa50ee6523365ff14c1f45f88737d,9001,000000001234,7
|
||||
ue2,mil,001010123456780,00112233445566778899aabbccddeeff,opc,63bfa50ee6523365ff14c1f45f88737d,8000,000000001234,7
|
||||
|
|
Loading…
Reference in New Issue