From a645d74eaf4e621a59fcd9e90914030b771f1c0f Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Mon, 26 Jul 2021 18:03:02 +0200 Subject: [PATCH] USIM functions for res star Added gen_res_star in security.h Added USIM interfaces for res star Added RES star test case --- lib/include/srsran/common/liblte_security.h | 7 ++ lib/include/srsran/common/security.h | 8 ++- .../srsran/interfaces/ue_usim_interfaces.h | 7 ++ lib/src/common/liblte_security.cc | 66 +++++++++++++++++++ lib/test/common/test_security_kdf.cc | 23 +++++++ srsue/hdr/stack/upper/usim_base.h | 7 ++ srsue/src/stack/upper/usim_base.cc | 26 ++++++++ 7 files changed, 143 insertions(+), 1 deletion(-) diff --git a/lib/include/srsran/common/liblte_security.h b/lib/include/srsran/common/liblte_security.h index 95c6a691e..165d74fb2 100644 --- a/lib/include/srsran/common/liblte_security.h +++ b/lib/include/srsran/common/liblte_security.h @@ -147,6 +147,13 @@ LIBLTE_ERROR_ENUM liblte_security_generate_k_up(uint8* uint8* k_up_int); LIBLTE_ERROR_ENUM liblte_security_generate_sk_gnb(uint8_t* k_enb, uint8_t* sk_gnb, uint16_t scg_counter); +LIBLTE_ERROR_ENUM liblte_security_generate_res_star(uint8_t* ck, + uint8_t* ik, + const char* serving_network_name, + uint8_t* rand, + uint8_t* res, + size_t res_len, + uint8_t* res_star); /********************************************************************* Name: liblte_security_128_eia2 diff --git a/lib/include/srsran/common/security.h b/lib/include/srsran/common/security.h index ce1c59ed6..b72117d81 100644 --- a/lib/include/srsran/common/security.h +++ b/lib/include/srsran/common/security.h @@ -174,7 +174,13 @@ uint8_t security_generate_k_nr_up(uint8_t* k_gnb, uint8_t* k_up_int); uint8_t security_generate_sk_gnb(uint8_t* k_enb, uint8_t* sk_gnb, uint16_t scg_count); - +uint8_t security_generate_res_star(uint8_t* ck, + uint8_t* ik, + const char* serving_network_name, + uint8_t* rand, + uint8_t* res, + size_t res_len, + uint8_t* res_star); /****************************************************************************** * Integrity Protection *****************************************************************************/ diff --git a/lib/include/srsran/interfaces/ue_usim_interfaces.h b/lib/include/srsran/interfaces/ue_usim_interfaces.h index 34d15a5f3..b2d53b2c0 100644 --- a/lib/include/srsran/interfaces/ue_usim_interfaces.h +++ b/lib/include/srsran/interfaces/ue_usim_interfaces.h @@ -47,6 +47,13 @@ public: uint8_t* k_nas_int, srsran::CIPHERING_ALGORITHM_ID_ENUM cipher_algo, srsran::INTEGRITY_ALGORITHM_ID_ENUM integ_algo) = 0; + + virtual bool generate_res_star(uint8_t* rand, + uint8_t* res, + int res_len, + const char* serving_network_name, + uint8_t* res_start, + uint32_t* res_star_len) = 0; }; // USIM interface for RRC diff --git a/lib/src/common/liblte_security.cc b/lib/src/common/liblte_security.cc index 4eb9fa733..509355d11 100644 --- a/lib/src/common/liblte_security.cc +++ b/lib/src/common/liblte_security.cc @@ -21,6 +21,8 @@ #include "srsran/common/ssl.h" #include "srsran/common/zuc.h" +#include + /******************************************************************************* LOCAL FUNCTION PROTOTYPES *******************************************************************************/ @@ -120,6 +122,70 @@ LIBLTE_ERROR_ENUM liblte_security_generate_k_enb(uint8* k_asme, uint32 nas_count return (err); } +LIBLTE_ERROR_ENUM liblte_security_generate_res_star(uint8_t* ck, + uint8_t* ik, + const char* serving_network_name, + uint8_t* rand, + uint8_t* res, + size_t res_len, + uint8_t* res_star) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + uint8_t key[32]; + uint8_t* s; + + if (ck != NULL && ik != NULL && serving_network_name != NULL && rand != NULL && res != NULL && res_star != NULL) { + // Construct S + uint16_t ssn_length = strlen(serving_network_name); + uint16_t rand_length = 16; + uint32_t s_len = 1 + ssn_length + 2 + rand_length + 2 + res_len + 2; + + uint8_t output[32] = {}; + + s = (uint8_t*)calloc(s_len, sizeof(uint8_t)); + if (s == nullptr) { + return err; + } + + uint32_t i = 0; + s[i] = 0x6B; // FC + i++; + + // SSN + memcpy(&s[i], serving_network_name, strlen(serving_network_name)); + i += ssn_length; + uint16_t ssn_length_value = htons(ssn_length); + memcpy(&s[i], &ssn_length_value, sizeof(ssn_length)); + i += sizeof(ssn_length_value); + + // RAND + memcpy(&s[i], rand, rand_length); + i += rand_length; + uint16_t rand_length_value = htons(rand_length); + memcpy(&s[i], &rand_length_value, sizeof(rand_length)); + i += sizeof(rand_length_value); + + // RES + memcpy(&s[i], res, res_len); + i += res_len; + uint16_t res_length_value = htons(res_len); + memcpy(&s[i], &res_length_value, sizeof(res_length_value)); + i += sizeof(res_length_value); + + // The input key Key shall be equal to the concatenation CK || IK of CK and IK. + memcpy(key, ck, 16); + memcpy(key + 16, ik, 16); + + // Derive output + sha256(key, 32, s, s_len, output, 0); + memcpy(res_star, output + 16, 16); + + free(s); + err = LIBLTE_SUCCESS; + } + return (err); +} + /********************************************************************* Name: liblte_security_generate_k_enb_star diff --git a/lib/test/common/test_security_kdf.cc b/lib/test/common/test_security_kdf.cc index 84c5a7048..ca1676acd 100644 --- a/lib/test/common/test_security_kdf.cc +++ b/lib/test/common/test_security_kdf.cc @@ -282,6 +282,28 @@ int test_generate_k_nh() return SRSRAN_SUCCESS; } +int test_generate_res_star() +{ + auto& logger = srslog::fetch_basic_logger("LOG", false); + uint8_t res_star_o[16]; + + uint8_t ck[] = {0x3c, 0xba, 0x90, 0x25, 0x75, 0xed, 0x80, 0xcb, 0xfa, 0x36, 0x25, 0xaf, 0xf0, 0x9d, 0xaf, 0xfc}; + uint8_t ik[] = {0xba, 0x90, 0x25, 0x75, 0xed, 0x80, 0xcb, 0xfa, 0x36, 0x25, 0xaf, 0xf0, 0x9d, 0xaf, 0xfc, 0x3c}; + uint8_t rand[] = {0xfc, 0x2d, 0x98, 0xa3, 0x61, 0x20, 0x8b, 0xf7, 0x43, 0x63, 0x9c, 0x9e, 0x63, 0x2d, 0x73, 0x50}; + uint8_t res[] = {0xfc, 0x3c, 0xba, 0x90, 0x25, 0x75, 0xed, 0x80}; + std::string ssn = "5G:mnc001.mcc001.3gppnetwork.org"; + + TESTASSERT(srsran::security_generate_res_star(ck, ik, ssn.c_str(), rand, res, sizeof(res), res_star_o) == + SRSRAN_SUCCESS); + + uint8_t res_star[] = {0xb0, 0xe3, 0x5b, 0x23, 0xdb, 0xd7, 0xa1, 0x8c, 0x84, 0x8b, 0xfa, 0xd9, 0x11, 0x35, 0xe3, 0xfd}; + + logger.info(res_star, 16, "RES STAR:"); + TESTASSERT(arrcmp(res_star_o, res_star, sizeof(res_star)) == 0); + + return SRSRAN_SUCCESS; +} + int main(int argc, char** argv) { auto& logger = srslog::fetch_basic_logger("LOG", false); @@ -298,6 +320,7 @@ int main(int argc, char** argv) TESTASSERT(test_generate_k_enb_star() == SRSRAN_SUCCESS); TESTASSERT(test_generate_k_nh() == SRSRAN_SUCCESS); + TESTASSERT(test_generate_res_star() == SRSRAN_SUCCESS); TESTASSERT(test_set_ksg() == SRSRAN_SUCCESS); TESTASSERT(test_set_nr_rrc_up() == SRSRAN_SUCCESS); diff --git a/srsue/hdr/stack/upper/usim_base.h b/srsue/hdr/stack/upper/usim_base.h index fcda0c6aa..cb2927172 100644 --- a/srsue/hdr/stack/upper/usim_base.h +++ b/srsue/hdr/stack/upper/usim_base.h @@ -100,6 +100,13 @@ public: bool generate_nr_context(uint16_t sk_counter, srsran::as_security_config_t* sec_cfg) final; bool update_nr_context(srsran::as_security_config_t* sec_cfg) final; + // 5G NAS interface + bool generate_res_star(uint8_t* rand, + uint8_t* res, + int res_len, + const char* serving_network_name, + uint8_t* res_start, + uint32_t* res_star_len) final; // Helpers std::string get_mcc_str(const uint8_t* imsi_vec); virtual std::string get_mnc_str(const uint8_t* imsi_vec, std::string mcc_str) = 0; diff --git a/srsue/src/stack/upper/usim_base.cc b/srsue/src/stack/upper/usim_base.cc index 0c4b23674..2cb80423a 100644 --- a/srsue/src/stack/upper/usim_base.cc +++ b/srsue/src/stack/upper/usim_base.cc @@ -396,4 +396,30 @@ bool usim_base::update_nr_context(srsran::as_security_config_t* sec_cfg) return true; } +bool usim_base::generate_res_star(uint8_t* rand, + uint8_t* res, + int res_len, + const char* serving_network_name, + uint8_t* res_star, + uint32_t* res_star_len) +{ + if (!initiated) { + logger.error("USIM not initiated!"); + return false; + } + + logger.info("Generate res_star"); + + logger.info(rand, 16, "RAND"); + logger.info(res, res_len, "RES"); + logger.info( + (uint8_t*)serving_network_name, strlen(serving_network_name), "Serving Network Name %s", serving_network_name); + + srsran::security_generate_res_star(ck, ik, serving_network_name, rand, res, res_len, res_star); + *res_star_len = 16; + logger.info(res_star, *res_star_len, "res_star"); + + return true; +} + } // namespace srsue