2020-11-26 01:25:22 -08:00
|
|
|
/**
|
2022-04-29 00:28:44 -07:00
|
|
|
* Copyright 2013-2022 Software Radio Systems Limited
|
2017-05-18 03:11:31 -07:00
|
|
|
*
|
2021-04-22 01:59:40 -07:00
|
|
|
* This file is part of srsRAN.
|
2017-05-18 03:11:31 -07:00
|
|
|
*
|
2021-04-22 01:59:40 -07:00
|
|
|
* srsRAN is free software: you can redistribute it and/or modify
|
2021-03-28 14:12:42 -07:00
|
|
|
* it under the terms of the GNU Affero General Public License as
|
|
|
|
* published by the Free Software Foundation, either version 3 of
|
|
|
|
* the License, or (at your option) any later version.
|
|
|
|
*
|
2021-04-22 01:59:40 -07:00
|
|
|
* srsRAN is distributed in the hope that it will be useful,
|
2021-03-28 14:12:42 -07:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Affero General Public License for more details.
|
2017-05-18 03:11:31 -07:00
|
|
|
*
|
2021-03-28 14:12:42 -07:00
|
|
|
* A copy of the GNU Affero General Public License can be found in
|
|
|
|
* the LICENSE file in the top-level directory of this distribution
|
|
|
|
* and at http://www.gnu.org/licenses/.
|
2017-05-18 03:11:31 -07:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2021-03-19 03:45:56 -07:00
|
|
|
#include "srsran/common/security.h"
|
2022-10-25 07:03:54 -07:00
|
|
|
#include "mbedtls/md5.h"
|
2021-03-19 03:45:56 -07:00
|
|
|
#include "srsran/common/liblte_security.h"
|
|
|
|
#include "srsran/common/s3g.h"
|
2021-07-27 08:52:02 -07:00
|
|
|
#include "srsran/common/ssl.h"
|
2021-03-19 03:45:56 -07:00
|
|
|
#include "srsran/config.h"
|
2021-07-27 08:52:02 -07:00
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
|
|
|
#define FC_EPS_K_ASME_DERIVATION 0x10
|
|
|
|
#define FC_EPS_K_ENB_DERIVATION 0x11
|
|
|
|
#define FC_EPS_NH_DERIVATION 0x12
|
|
|
|
#define FC_EPS_K_ENB_STAR_DERIVATION 0x13
|
|
|
|
#define FC_EPS_ALGORITHM_KEY_DERIVATION 0x15
|
|
|
|
|
|
|
|
#define ALGO_EPS_DISTINGUISHER_NAS_ENC_ALG 0x01
|
|
|
|
#define ALGO_EPS_DISTINGUISHER_NAS_INT_ALG 0x02
|
|
|
|
#define ALGO_EPS_DISTINGUISHER_RRC_ENC_ALG 0x03
|
|
|
|
#define ALGO_EPS_DISTINGUISHER_RRC_INT_ALG 0x04
|
|
|
|
#define ALGO_EPS_DISTINGUISHER_UP_ENC_ALG 0x05
|
|
|
|
#define ALGO_EPS_DISTINGUISHER_UP_INT_ALG 0x06
|
|
|
|
|
2022-01-12 06:27:12 -08:00
|
|
|
#define FC_5G_K_GNB_STAR_DERIVATION 0x70
|
2021-07-27 08:52:02 -07:00
|
|
|
#define FC_5G_ALGORITHM_KEY_DERIVATION 0x69
|
|
|
|
#define FC_5G_KAUSF_DERIVATION 0x6A
|
|
|
|
#define FC_5G_RES_STAR_DERIVATION 0x6B
|
|
|
|
#define FC_5G_KSEAF_DERIVATION 0x6C
|
|
|
|
#define FC_5G_KAMF_DERIVATION 0x6D
|
|
|
|
#define FC_5G_KGNB_KN3IWF_DERIVATION 0x6E
|
|
|
|
#define FC_5G_NH_GNB_DERIVATION 0x6F
|
|
|
|
|
|
|
|
#define ALGO_5G_DISTINGUISHER_NAS_ENC_ALG 0x01
|
|
|
|
#define ALGO_5G_DISTINGUISHER_NAS_INT_ALG 0x02
|
|
|
|
#define ALGO_5G_DISTINGUISHER_RRC_ENC_ALG 0x03
|
|
|
|
#define ALGO_5G_DISTINGUISHER_RRC_INT_ALG 0x04
|
|
|
|
#define ALGO_5G_DISTINGUISHER_UP_ENC_ALG 0x05
|
|
|
|
#define ALGO_5G_DISTINGUISHER_UP_INT_ALG 0x06
|
2021-03-19 03:45:56 -07:00
|
|
|
namespace srsran {
|
2017-05-18 03:11:31 -07:00
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* Key Generation
|
|
|
|
*****************************************************************************/
|
|
|
|
|
2021-07-29 05:24:58 -07:00
|
|
|
uint8_t security_generate_k_asme(const uint8_t* ck,
|
|
|
|
const uint8_t* ik,
|
|
|
|
const uint8_t* ak_xor_sqn_,
|
|
|
|
const uint16_t mcc,
|
|
|
|
const uint16_t mnc,
|
|
|
|
uint8_t* k_asme)
|
2017-05-18 03:11:31 -07:00
|
|
|
{
|
2021-07-27 08:52:02 -07:00
|
|
|
if (ck == NULL || ik == NULL || ak_xor_sqn_ == NULL || k_asme == NULL) {
|
|
|
|
log_error("Invalid inputs");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
std::array<uint8_t, 32> key;
|
|
|
|
|
|
|
|
// The input key Key shall be equal to the concatenation CK || IK of CK and IK.
|
|
|
|
memcpy(key.data(), ck, 16);
|
|
|
|
memcpy(key.data() + 16, ik, 16);
|
|
|
|
|
|
|
|
// Serving Network id
|
|
|
|
std::vector<uint8_t> sn_id;
|
|
|
|
sn_id.resize(3);
|
|
|
|
sn_id[0] = (mcc & 0x00F0) | ((mcc & 0x0F00) >> 8); // First byte of P0
|
|
|
|
if ((mnc & 0xFF00) == 0xFF00) {
|
|
|
|
// 2-digit MNC
|
|
|
|
sn_id[1] = 0xF0 | (mcc & 0x000F); // Second byte of P0
|
|
|
|
sn_id[2] = ((mnc & 0x000F) << 4) | ((mnc & 0x00F0) >> 4); // Third byte of P0
|
|
|
|
} else {
|
|
|
|
// 3-digit MNC
|
|
|
|
sn_id[1] = ((mnc & 0x000F) << 4) | (mcc & 0x000F); // Second byte of P0
|
|
|
|
sn_id[2] = ((mnc & 0x00F0)) | ((mnc & 0x0F00) >> 8); // Third byte of P0
|
|
|
|
}
|
|
|
|
|
|
|
|
// AK XOR SQN
|
|
|
|
std::vector<uint8_t> ak_xor_sqn;
|
|
|
|
ak_xor_sqn.resize(AK_LEN);
|
|
|
|
memcpy(ak_xor_sqn.data(), ak_xor_sqn_, ak_xor_sqn.size());
|
|
|
|
|
|
|
|
uint8_t output[32];
|
|
|
|
if (kdf_common(FC_EPS_K_ASME_DERIVATION, key, sn_id, ak_xor_sqn, output) != SRSRAN_SUCCESS) {
|
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(k_asme, output, 32);
|
|
|
|
return SRSRAN_SUCCESS;
|
2017-05-18 03:11:31 -07:00
|
|
|
}
|
|
|
|
|
2021-07-29 05:24:58 -07:00
|
|
|
uint8_t security_generate_k_ausf(const uint8_t* ck,
|
|
|
|
const uint8_t* ik,
|
|
|
|
const uint8_t* ak_xor_sqn_,
|
|
|
|
const char* serving_network_name,
|
|
|
|
uint8_t* k_ausf)
|
2017-05-18 03:11:31 -07:00
|
|
|
{
|
2021-07-27 08:52:02 -07:00
|
|
|
if (ck == NULL || ik == NULL || ak_xor_sqn_ == NULL || serving_network_name == NULL || k_ausf == NULL) {
|
|
|
|
log_error("Invalid inputs");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::array<uint8_t, 32> key;
|
|
|
|
|
|
|
|
// The input key Key shall be equal to the concatenation CK || IK of CK and IK.
|
|
|
|
memcpy(key.data(), ck, 16);
|
|
|
|
memcpy(key.data() + 16, ik, 16);
|
|
|
|
|
|
|
|
// Serving Network Name
|
|
|
|
std::vector<uint8_t> ssn;
|
|
|
|
ssn.resize(strlen(serving_network_name));
|
|
|
|
memcpy(ssn.data(), serving_network_name, ssn.size());
|
|
|
|
|
|
|
|
// AK XOR SQN
|
|
|
|
std::vector<uint8_t> ak_xor_sqn;
|
|
|
|
ak_xor_sqn.resize(AK_LEN);
|
|
|
|
memcpy(ak_xor_sqn.data(), ak_xor_sqn_, ak_xor_sqn.size());
|
|
|
|
|
|
|
|
uint8_t output[32];
|
2021-07-29 05:24:58 -07:00
|
|
|
if (kdf_common(FC_5G_KAUSF_DERIVATION, key, ssn, ak_xor_sqn, output) != SRSRAN_SUCCESS) {
|
2021-07-27 08:52:02 -07:00
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
memcpy(k_ausf, output, 32);
|
|
|
|
|
|
|
|
return SRSRAN_SUCCESS;
|
2017-05-18 03:11:31 -07:00
|
|
|
}
|
|
|
|
|
2021-07-29 05:24:58 -07:00
|
|
|
uint8_t security_generate_k_seaf(const uint8_t* k_ausf, const char* serving_network_name, uint8_t* k_seaf)
|
|
|
|
{
|
|
|
|
if (k_ausf == NULL || serving_network_name == NULL || k_seaf == NULL) {
|
|
|
|
log_error("Invalid inputs");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::array<uint8_t, 32> key;
|
|
|
|
memcpy(key.data(), k_ausf, 32);
|
|
|
|
|
|
|
|
// Serving Network Name
|
|
|
|
std::vector<uint8_t> ssn;
|
|
|
|
ssn.resize(strlen(serving_network_name));
|
|
|
|
memcpy(ssn.data(), serving_network_name, ssn.size());
|
|
|
|
|
|
|
|
if (kdf_common(FC_5G_KSEAF_DERIVATION, key, ssn, k_seaf) != SRSRAN_SUCCESS) {
|
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
return SRSRAN_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t security_generate_k_amf(const uint8_t* k_seaf,
|
|
|
|
const char* supi_,
|
|
|
|
const uint8_t* abba_,
|
|
|
|
const uint32_t abba_len,
|
|
|
|
uint8_t* k_amf)
|
|
|
|
{
|
|
|
|
if (k_seaf == NULL || supi_ == NULL || abba_ == NULL || k_amf == NULL) {
|
|
|
|
log_error("Invalid inputs");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::array<uint8_t, 32> key;
|
|
|
|
memcpy(key.data(), k_seaf, 32);
|
|
|
|
|
|
|
|
// SUPI
|
|
|
|
std::vector<uint8_t> supi;
|
|
|
|
supi.resize(strlen(supi_));
|
|
|
|
memcpy(supi.data(), supi_, supi.size());
|
|
|
|
|
|
|
|
// ABBA
|
|
|
|
std::vector<uint8_t> abba;
|
|
|
|
abba.resize(abba_len);
|
|
|
|
memcpy(abba.data(), abba_, abba.size());
|
|
|
|
|
|
|
|
if (kdf_common(FC_5G_KAMF_DERIVATION, key, supi, abba, k_amf) != SRSRAN_SUCCESS) {
|
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
return SRSRAN_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2022-01-24 08:27:37 -08:00
|
|
|
uint8_t security_generate_k_gnb(const as_key_t& k_amf, const uint32_t nas_count_, as_key_t& k_gnb)
|
|
|
|
{
|
|
|
|
if (k_amf.empty()) {
|
|
|
|
log_error("Invalid inputs");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
// NAS Count
|
|
|
|
std::vector<uint8_t> nas_count;
|
|
|
|
nas_count.resize(4);
|
|
|
|
nas_count[0] = (nas_count_ >> 24) & 0xFF;
|
|
|
|
nas_count[1] = (nas_count_ >> 16) & 0xFF;
|
|
|
|
nas_count[2] = (nas_count_ >> 8) & 0xFF;
|
|
|
|
nas_count[3] = nas_count_ & 0xFF;
|
|
|
|
|
|
|
|
// Access Type Distinguisher 3GPP access = 0x01 (TS 33501 Annex A.9)
|
|
|
|
std::vector<uint8_t> access_type_distinguisher = {1};
|
|
|
|
|
|
|
|
if (kdf_common(FC_5G_KGNB_KN3IWF_DERIVATION, k_amf, nas_count, access_type_distinguisher, k_gnb.data()) !=
|
|
|
|
SRSRAN_SUCCESS) {
|
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
return SRSRAN_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2021-07-29 05:24:58 -07:00
|
|
|
uint8_t security_generate_k_enb(const uint8_t* k_asme, const uint32_t nas_count_, uint8_t* k_enb)
|
2017-05-18 03:11:31 -07:00
|
|
|
{
|
2021-07-27 08:52:02 -07:00
|
|
|
if (k_asme == NULL || k_enb == NULL) {
|
|
|
|
log_error("Invalid inputs");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
std::array<uint8_t, 32> key;
|
|
|
|
|
|
|
|
memcpy(key.data(), k_asme, 32);
|
|
|
|
|
|
|
|
// NAS Count
|
|
|
|
std::vector<uint8_t> nas_count;
|
|
|
|
nas_count.resize(4);
|
|
|
|
nas_count[0] = (nas_count_ >> 24) & 0xFF;
|
|
|
|
nas_count[1] = (nas_count_ >> 16) & 0xFF;
|
|
|
|
nas_count[2] = (nas_count_ >> 8) & 0xFF;
|
|
|
|
nas_count[3] = nas_count_ & 0xFF;
|
|
|
|
|
|
|
|
if (kdf_common(FC_EPS_K_ENB_DERIVATION, key, nas_count, k_enb) != SRSRAN_SUCCESS) {
|
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
return SRSRAN_SUCCESS;
|
2017-05-18 03:11:31 -07:00
|
|
|
}
|
|
|
|
|
2022-01-12 06:27:12 -08:00
|
|
|
// Generate k_enb* according to TS 33.401 Appendix A.5
|
2021-07-29 05:24:58 -07:00
|
|
|
uint8_t
|
|
|
|
security_generate_k_enb_star(const uint8_t* k_enb, const uint32_t pci_, const uint32_t earfcn_, uint8_t* k_enb_star)
|
2022-01-12 06:27:12 -08:00
|
|
|
|
|
|
|
{
|
|
|
|
return security_generate_k_nb_star_common(FC_EPS_K_ENB_STAR_DERIVATION, k_enb, pci_, earfcn_, k_enb_star);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generate k_gnb* according to TS 33.501 Appendix A.11
|
|
|
|
uint8_t
|
|
|
|
security_generate_k_gnb_star(const uint8_t* k_gnb, const uint32_t pci_, const uint32_t dl_arfcn_, uint8_t* k_gnb_star)
|
|
|
|
|
|
|
|
{
|
|
|
|
return security_generate_k_nb_star_common(FC_5G_K_GNB_STAR_DERIVATION, k_gnb, pci_, dl_arfcn_, k_gnb_star);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t security_generate_k_nb_star_common(uint8_t fc,
|
|
|
|
const uint8_t* k_enb,
|
|
|
|
const uint32_t pci_,
|
|
|
|
const uint32_t earfcn_,
|
|
|
|
uint8_t* k_enb_star)
|
2017-05-18 03:11:31 -07:00
|
|
|
{
|
2021-07-27 08:52:02 -07:00
|
|
|
if (k_enb == NULL || k_enb_star == NULL) {
|
|
|
|
log_error("Invalid inputs");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
std::array<uint8_t, 32> key;
|
|
|
|
memcpy(key.data(), k_enb, 32);
|
|
|
|
|
|
|
|
// PCI
|
|
|
|
std::vector<uint8_t> pci;
|
|
|
|
pci.resize(2);
|
|
|
|
pci[0] = (pci_ >> 8) & 0xFF;
|
|
|
|
pci[1] = pci_ & 0xFF;
|
|
|
|
|
2022-01-12 06:27:12 -08:00
|
|
|
// ARFCN, can be two or three bytes
|
2021-07-27 08:52:02 -07:00
|
|
|
std::vector<uint8_t> earfcn;
|
2022-01-12 06:27:12 -08:00
|
|
|
if (earfcn_ < pow(2, 16)) {
|
|
|
|
earfcn.resize(2);
|
|
|
|
earfcn[0] = (earfcn_ >> 8) & 0xFF;
|
|
|
|
earfcn[1] = earfcn_ & 0xFF;
|
|
|
|
} else if (earfcn_ < pow(2, 24)) {
|
|
|
|
earfcn.resize(3);
|
|
|
|
earfcn[0] = (earfcn_ >> 16) & 0xFF;
|
|
|
|
earfcn[1] = (earfcn_ >> 8) & 0xFF;
|
|
|
|
earfcn[2] = earfcn_ & 0xFF;
|
|
|
|
}
|
2021-07-27 08:52:02 -07:00
|
|
|
|
2022-01-12 06:27:12 -08:00
|
|
|
if (kdf_common(fc, key, pci, earfcn, k_enb_star) != SRSRAN_SUCCESS) {
|
2021-07-27 08:52:02 -07:00
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
return SRSRAN_SUCCESS;
|
2017-05-18 03:11:31 -07:00
|
|
|
}
|
|
|
|
|
2021-07-29 05:24:58 -07:00
|
|
|
uint8_t security_generate_nh(const uint8_t* k_asme, const uint8_t* sync_, uint8_t* nh)
|
2017-11-23 10:46:34 -08:00
|
|
|
{
|
2021-07-27 08:52:02 -07:00
|
|
|
if (k_asme == NULL || sync_ == NULL || nh == NULL) {
|
|
|
|
log_error("Invalid inputs");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
std::array<uint8_t, 32> key;
|
|
|
|
memcpy(key.data(), k_asme, 32);
|
|
|
|
|
|
|
|
// PCI
|
|
|
|
std::vector<uint8_t> sync;
|
|
|
|
sync.resize(32);
|
|
|
|
memcpy(sync.data(), sync_, 32);
|
|
|
|
|
|
|
|
if (kdf_common(FC_EPS_NH_DERIVATION, key, sync, nh) != SRSRAN_SUCCESS) {
|
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
return SRSRAN_SUCCESS;
|
2017-11-23 10:46:34 -08:00
|
|
|
}
|
|
|
|
|
2021-07-29 05:24:58 -07:00
|
|
|
uint8_t security_generate_k_nas(const uint8_t* k_asme,
|
|
|
|
const CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
|
|
|
|
const INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
|
|
|
|
uint8_t* k_nas_enc,
|
|
|
|
uint8_t* k_nas_int)
|
2017-11-27 04:57:05 -08:00
|
|
|
{
|
2021-07-27 08:52:02 -07:00
|
|
|
if (k_asme == NULL || k_nas_enc == NULL || k_nas_int == NULL) {
|
|
|
|
log_error("Invalid inputs");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
std::array<uint8_t, 32> key;
|
|
|
|
|
|
|
|
memcpy(key.data(), k_asme, 32);
|
|
|
|
|
|
|
|
// Derive NAS ENC
|
|
|
|
// algorithm type distinguisher
|
|
|
|
std::vector<uint8_t> algo_distinguisher;
|
|
|
|
algo_distinguisher.resize(1);
|
|
|
|
algo_distinguisher[0] = ALGO_EPS_DISTINGUISHER_NAS_ENC_ALG;
|
|
|
|
|
|
|
|
// algorithm type distinguisher
|
|
|
|
std::vector<uint8_t> algorithm_identity;
|
|
|
|
algorithm_identity.resize(1);
|
|
|
|
algorithm_identity[0] = enc_alg_id;
|
|
|
|
|
|
|
|
if (kdf_common(FC_EPS_ALGORITHM_KEY_DERIVATION, key, algo_distinguisher, algorithm_identity, k_nas_enc) !=
|
|
|
|
SRSRAN_SUCCESS) {
|
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Derive NAS INT
|
|
|
|
// algorithm type distinguisher
|
|
|
|
algo_distinguisher.resize(1);
|
|
|
|
algo_distinguisher[0] = ALGO_EPS_DISTINGUISHER_NAS_INT_ALG;
|
|
|
|
|
|
|
|
// algorithm type distinguisher
|
|
|
|
algorithm_identity.resize(1);
|
|
|
|
algorithm_identity[0] = int_alg_id;
|
|
|
|
|
|
|
|
// Derive NAS int
|
|
|
|
if (kdf_common(FC_EPS_ALGORITHM_KEY_DERIVATION, key, algo_distinguisher, algorithm_identity, k_nas_int) !=
|
|
|
|
SRSRAN_SUCCESS) {
|
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
return SRSRAN_SUCCESS;
|
2017-05-18 03:11:31 -07:00
|
|
|
}
|
|
|
|
|
2021-07-29 05:24:58 -07:00
|
|
|
uint8_t security_generate_k_nas_5g(const uint8_t* k_amf,
|
|
|
|
const CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
|
|
|
|
const INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
|
|
|
|
uint8_t* k_nas_enc,
|
|
|
|
uint8_t* k_nas_int)
|
|
|
|
{
|
|
|
|
if (k_amf == NULL || k_nas_enc == NULL || k_nas_int == NULL) {
|
|
|
|
log_error("Invalid inputs");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
std::array<uint8_t, 32> key;
|
|
|
|
|
|
|
|
memcpy(key.data(), k_amf, 32);
|
|
|
|
|
|
|
|
// Derive NAS ENC
|
|
|
|
// algorithm type distinguisher
|
|
|
|
std::vector<uint8_t> algo_distinguisher;
|
|
|
|
algo_distinguisher.resize(1);
|
|
|
|
algo_distinguisher[0] = ALGO_5G_DISTINGUISHER_NAS_ENC_ALG;
|
|
|
|
|
|
|
|
// algorithm type distinguisher
|
|
|
|
std::vector<uint8_t> algorithm_identity;
|
|
|
|
algorithm_identity.resize(1);
|
|
|
|
algorithm_identity[0] = enc_alg_id;
|
|
|
|
|
|
|
|
if (kdf_common(FC_5G_ALGORITHM_KEY_DERIVATION, key, algo_distinguisher, algorithm_identity, k_nas_enc) !=
|
|
|
|
SRSRAN_SUCCESS) {
|
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Derive NAS INT
|
|
|
|
// algorithm type distinguisher
|
|
|
|
algo_distinguisher.resize(1);
|
|
|
|
algo_distinguisher[0] = ALGO_5G_DISTINGUISHER_NAS_INT_ALG;
|
|
|
|
|
|
|
|
// algorithm type distinguisher
|
|
|
|
algorithm_identity.resize(1);
|
|
|
|
algorithm_identity[0] = int_alg_id;
|
|
|
|
|
|
|
|
// Derive NAS int
|
|
|
|
if (kdf_common(FC_5G_ALGORITHM_KEY_DERIVATION, key, algo_distinguisher, algorithm_identity, k_nas_int) !=
|
|
|
|
SRSRAN_SUCCESS) {
|
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
return SRSRAN_SUCCESS;
|
2017-11-27 04:57:05 -08:00
|
|
|
}
|
|
|
|
|
2021-07-29 05:24:58 -07:00
|
|
|
uint8_t security_generate_k_rrc(const uint8_t* k_enb,
|
|
|
|
const CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
|
|
|
|
const INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
|
|
|
|
uint8_t* k_rrc_enc,
|
|
|
|
uint8_t* k_rrc_int)
|
2017-05-18 03:11:31 -07:00
|
|
|
{
|
2021-07-27 08:52:02 -07:00
|
|
|
if (k_enb == NULL || k_rrc_enc == NULL || k_rrc_int == NULL) {
|
|
|
|
log_error("Invalid inputs");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
std::array<uint8_t, 32> key;
|
|
|
|
|
|
|
|
memcpy(key.data(), k_enb, 32);
|
|
|
|
|
|
|
|
// Derive RRC ENC
|
|
|
|
// algorithm type distinguisher
|
|
|
|
std::vector<uint8_t> algo_distinguisher;
|
|
|
|
algo_distinguisher.resize(1);
|
|
|
|
algo_distinguisher[0] = ALGO_EPS_DISTINGUISHER_RRC_ENC_ALG;
|
|
|
|
|
|
|
|
// algorithm type distinguisher
|
|
|
|
std::vector<uint8_t> algorithm_identity;
|
|
|
|
algorithm_identity.resize(1);
|
|
|
|
algorithm_identity[0] = enc_alg_id;
|
|
|
|
|
|
|
|
if (kdf_common(FC_EPS_ALGORITHM_KEY_DERIVATION, key, algo_distinguisher, algorithm_identity, k_rrc_enc) !=
|
|
|
|
SRSRAN_SUCCESS) {
|
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Derive RRC INT
|
|
|
|
// algorithm type distinguisher
|
|
|
|
algo_distinguisher.resize(1);
|
|
|
|
algo_distinguisher[0] = ALGO_EPS_DISTINGUISHER_RRC_INT_ALG;
|
|
|
|
|
|
|
|
// algorithm type distinguisher
|
|
|
|
algorithm_identity.resize(1);
|
|
|
|
algorithm_identity[0] = int_alg_id;
|
|
|
|
|
|
|
|
// Derive RRC int
|
|
|
|
if (kdf_common(FC_EPS_ALGORITHM_KEY_DERIVATION, key, algo_distinguisher, algorithm_identity, k_rrc_int) !=
|
|
|
|
SRSRAN_SUCCESS) {
|
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
return SRSRAN_SUCCESS;
|
2017-05-18 03:11:31 -07:00
|
|
|
}
|
|
|
|
|
2021-07-29 05:24:58 -07:00
|
|
|
uint8_t security_generate_k_up(const uint8_t* k_enb,
|
|
|
|
const CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
|
|
|
|
const INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
|
|
|
|
uint8_t* k_up_enc,
|
|
|
|
uint8_t* k_up_int)
|
2017-05-18 03:11:31 -07:00
|
|
|
{
|
2021-07-27 08:52:02 -07:00
|
|
|
if (k_enb == NULL || k_up_enc == NULL || k_up_int == NULL) {
|
|
|
|
log_error("Invalid inputs");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
std::array<uint8_t, 32> key;
|
|
|
|
|
|
|
|
memcpy(key.data(), k_enb, 32);
|
|
|
|
|
|
|
|
// Derive UP ENC
|
|
|
|
// algorithm type distinguisher
|
|
|
|
std::vector<uint8_t> algo_distinguisher;
|
|
|
|
algo_distinguisher.resize(1);
|
|
|
|
algo_distinguisher[0] = ALGO_EPS_DISTINGUISHER_UP_ENC_ALG;
|
|
|
|
|
|
|
|
// algorithm type distinguisher
|
|
|
|
std::vector<uint8_t> algorithm_identity;
|
|
|
|
algorithm_identity.resize(1);
|
|
|
|
algorithm_identity[0] = enc_alg_id;
|
|
|
|
|
|
|
|
if (kdf_common(FC_EPS_ALGORITHM_KEY_DERIVATION, key, algo_distinguisher, algorithm_identity, k_up_enc) !=
|
|
|
|
SRSRAN_SUCCESS) {
|
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Derive UP INT
|
|
|
|
// algorithm type distinguisher
|
|
|
|
algo_distinguisher.resize(1);
|
|
|
|
algo_distinguisher[0] = ALGO_EPS_DISTINGUISHER_UP_INT_ALG;
|
|
|
|
|
|
|
|
// algorithm type distinguisher
|
|
|
|
algorithm_identity.resize(1);
|
|
|
|
algorithm_identity[0] = int_alg_id;
|
|
|
|
|
|
|
|
// Derive UP int
|
|
|
|
if (kdf_common(FC_EPS_ALGORITHM_KEY_DERIVATION, key, algo_distinguisher, algorithm_identity, k_up_int) !=
|
|
|
|
SRSRAN_SUCCESS) {
|
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
return SRSRAN_SUCCESS;
|
2017-05-18 03:11:31 -07:00
|
|
|
}
|
|
|
|
|
2021-07-29 05:24:58 -07:00
|
|
|
uint8_t security_generate_sk_gnb(const uint8_t* k_enb, const uint16_t scg_count_, uint8_t* sk_gnb)
|
2017-05-18 03:11:31 -07:00
|
|
|
{
|
2021-07-27 08:52:02 -07:00
|
|
|
if (k_enb == NULL || sk_gnb == NULL) {
|
|
|
|
log_error("Invalid inputs");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
std::array<uint8_t, 32> key;
|
|
|
|
|
|
|
|
memcpy(key.data(), k_enb, 32);
|
|
|
|
|
|
|
|
// SCG Count
|
|
|
|
std::vector<uint8_t> scg_count;
|
|
|
|
scg_count.resize(2);
|
|
|
|
scg_count[0] = (scg_count_ >> 8) & 0xFF; // first byte of P0
|
|
|
|
scg_count[1] = scg_count_ & 0xFF; // second byte of P0
|
|
|
|
|
|
|
|
// Derive sk_gnb
|
|
|
|
uint8_t output[32];
|
|
|
|
if (kdf_common(0x1C, key, scg_count, output) != SRSRAN_SUCCESS) {
|
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
memcpy(sk_gnb, output, 32);
|
|
|
|
|
|
|
|
return SRSRAN_SUCCESS;
|
2017-05-18 03:11:31 -07:00
|
|
|
}
|
|
|
|
|
2021-07-29 05:24:58 -07:00
|
|
|
uint8_t security_generate_k_nr_rrc(const uint8_t* k_gnb,
|
|
|
|
const CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
|
|
|
|
const INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
|
|
|
|
uint8_t* k_rrc_enc,
|
|
|
|
uint8_t* k_rrc_int)
|
2021-01-22 04:43:53 -08:00
|
|
|
{
|
2021-07-27 08:52:02 -07:00
|
|
|
if (k_gnb == NULL || k_rrc_enc == NULL || k_rrc_int == NULL) {
|
|
|
|
log_error("Invalid inputs");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
std::array<uint8_t, 32> key;
|
|
|
|
|
|
|
|
memcpy(key.data(), k_gnb, 32);
|
|
|
|
|
|
|
|
// Derive RRC ENC
|
|
|
|
// algorithm type distinguisher
|
|
|
|
std::vector<uint8_t> algo_distinguisher;
|
|
|
|
algo_distinguisher.resize(1);
|
|
|
|
algo_distinguisher[0] = ALGO_5G_DISTINGUISHER_RRC_ENC_ALG;
|
|
|
|
|
|
|
|
// algorithm type distinguisher
|
|
|
|
std::vector<uint8_t> algorithm_identity;
|
|
|
|
algorithm_identity.resize(1);
|
|
|
|
algorithm_identity[0] = enc_alg_id;
|
|
|
|
|
|
|
|
if (kdf_common(FC_5G_ALGORITHM_KEY_DERIVATION, key, algo_distinguisher, algorithm_identity, k_rrc_enc) !=
|
|
|
|
SRSRAN_SUCCESS) {
|
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Derive RRC INT
|
|
|
|
// algorithm type distinguisher
|
|
|
|
algo_distinguisher.resize(1);
|
|
|
|
algo_distinguisher[0] = ALGO_5G_DISTINGUISHER_RRC_INT_ALG;
|
|
|
|
|
|
|
|
// algorithm type distinguisher
|
|
|
|
algorithm_identity.resize(1);
|
|
|
|
algorithm_identity[0] = int_alg_id;
|
|
|
|
|
|
|
|
// Derive RRC int
|
|
|
|
if (kdf_common(FC_5G_ALGORITHM_KEY_DERIVATION, key, algo_distinguisher, algorithm_identity, k_rrc_int) !=
|
|
|
|
SRSRAN_SUCCESS) {
|
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
return SRSRAN_SUCCESS;
|
2021-01-22 04:43:53 -08:00
|
|
|
}
|
|
|
|
|
2021-07-29 05:24:58 -07:00
|
|
|
uint8_t security_generate_k_nr_up(const uint8_t* k_gnb,
|
|
|
|
const CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
|
|
|
|
const INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
|
|
|
|
uint8_t* k_up_enc,
|
|
|
|
uint8_t* k_up_int)
|
2021-01-22 04:43:53 -08:00
|
|
|
{
|
2021-07-27 08:52:02 -07:00
|
|
|
if (k_gnb == NULL || k_up_enc == NULL || k_up_int == NULL) {
|
|
|
|
log_error("Invalid inputs");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
std::array<uint8_t, 32> key;
|
|
|
|
|
|
|
|
memcpy(key.data(), k_gnb, 32);
|
|
|
|
|
|
|
|
// Derive UP ENC
|
|
|
|
// algorithm type distinguisher
|
|
|
|
std::vector<uint8_t> algo_distinguisher;
|
|
|
|
algo_distinguisher.resize(1);
|
|
|
|
algo_distinguisher[0] = ALGO_5G_DISTINGUISHER_UP_ENC_ALG;
|
|
|
|
|
|
|
|
// algorithm type distinguisher
|
|
|
|
std::vector<uint8_t> algorithm_identity;
|
|
|
|
algorithm_identity.resize(1);
|
|
|
|
algorithm_identity[0] = enc_alg_id;
|
|
|
|
|
|
|
|
if (kdf_common(FC_5G_ALGORITHM_KEY_DERIVATION, key, algo_distinguisher, algorithm_identity, k_up_enc) !=
|
|
|
|
SRSRAN_SUCCESS) {
|
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Derive UP INT
|
|
|
|
// algorithm type distinguisher
|
|
|
|
algo_distinguisher.resize(1);
|
|
|
|
algo_distinguisher[0] = ALGO_5G_DISTINGUISHER_UP_INT_ALG;
|
|
|
|
|
|
|
|
// algorithm type distinguisher
|
|
|
|
algorithm_identity.resize(1);
|
|
|
|
algorithm_identity[0] = int_alg_id;
|
|
|
|
|
|
|
|
// Derive UP int
|
|
|
|
if (kdf_common(FC_5G_ALGORITHM_KEY_DERIVATION, key, algo_distinguisher, algorithm_identity, k_up_int) !=
|
|
|
|
SRSRAN_SUCCESS) {
|
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
return SRSRAN_SUCCESS;
|
2021-01-22 04:43:53 -08:00
|
|
|
}
|
|
|
|
|
2021-07-29 05:24:58 -07:00
|
|
|
uint8_t security_generate_res_star(const uint8_t* ck,
|
|
|
|
const uint8_t* ik,
|
|
|
|
const char* serving_network_name,
|
|
|
|
const uint8_t* rand_,
|
|
|
|
const uint8_t* res_,
|
|
|
|
const size_t res_len_,
|
|
|
|
uint8_t* res_star)
|
2021-01-22 04:43:53 -08:00
|
|
|
{
|
2021-07-27 08:52:02 -07:00
|
|
|
if (ck == NULL || ik == NULL || serving_network_name == NULL || rand_ == NULL || res_ == NULL || res_star == NULL) {
|
|
|
|
log_error("Invalid inputs");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
std::array<uint8_t, 32> key;
|
|
|
|
|
|
|
|
// The input key Key shall be equal to the concatenation CK || IK of CK and IK.
|
|
|
|
memcpy(key.data(), ck, 16);
|
|
|
|
memcpy(key.data() + 16, ik, 16);
|
|
|
|
|
|
|
|
// Serving Network Name
|
|
|
|
std::vector<uint8_t> ssn;
|
|
|
|
ssn.resize(strlen(serving_network_name));
|
|
|
|
memcpy(ssn.data(), serving_network_name, strlen(serving_network_name));
|
|
|
|
|
|
|
|
// RAND
|
|
|
|
std::vector<uint8_t> rand;
|
|
|
|
rand.resize(AKA_RAND_LEN);
|
|
|
|
memcpy(rand.data(), rand_, rand.size());
|
|
|
|
|
|
|
|
// RES
|
|
|
|
std::vector<uint8_t> res;
|
|
|
|
res.resize(res_len_);
|
|
|
|
memcpy(res.data(), res_, res.size());
|
|
|
|
|
|
|
|
uint8_t output[32];
|
|
|
|
if (kdf_common(FC_5G_RES_STAR_DERIVATION, key, ssn, rand, res, output) != SRSRAN_SUCCESS) {
|
|
|
|
log_error("Failed to run kdf_common");
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
memcpy(res_star, output + 16, 16);
|
|
|
|
|
|
|
|
return SRSRAN_SUCCESS;
|
2021-01-22 04:43:53 -08:00
|
|
|
}
|
|
|
|
|
2021-07-27 08:52:02 -07:00
|
|
|
int kdf_common(const uint8_t fc, const std::array<uint8_t, 32>& key, const std::vector<uint8_t>& P0, uint8_t* output)
|
|
|
|
{
|
|
|
|
uint8_t* s;
|
|
|
|
uint32_t s_len = 1 + P0.size() + 2;
|
|
|
|
|
|
|
|
s = (uint8_t*)calloc(s_len, sizeof(uint8_t));
|
|
|
|
|
|
|
|
if (s == nullptr) {
|
|
|
|
log_error("Unable to allocate memory in %s()", __FUNCTION__);
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t i = 0;
|
|
|
|
s[i] = fc; // FC
|
|
|
|
i++;
|
|
|
|
|
|
|
|
// P0
|
|
|
|
memcpy(&s[i], P0.data(), P0.size());
|
|
|
|
i += P0.size();
|
|
|
|
uint16_t p0_length_value = htons(P0.size());
|
|
|
|
memcpy(&s[i], &p0_length_value, sizeof(p0_length_value));
|
|
|
|
i += sizeof(p0_length_value);
|
|
|
|
|
|
|
|
sha256(key.data(), key.size(), s, i, output, 0);
|
|
|
|
free(s);
|
|
|
|
|
|
|
|
return SRSRAN_SUCCESS;
|
2021-01-22 04:43:53 -08:00
|
|
|
}
|
|
|
|
|
2021-07-27 08:52:02 -07:00
|
|
|
int kdf_common(const uint8_t fc,
|
|
|
|
const std::array<uint8_t, 32>& key,
|
|
|
|
const std::vector<uint8_t>& P0,
|
|
|
|
const std::vector<uint8_t>& P1,
|
|
|
|
uint8_t* output)
|
2021-01-22 04:43:53 -08:00
|
|
|
{
|
2021-07-27 08:52:02 -07:00
|
|
|
uint8_t* s;
|
|
|
|
uint32_t s_len = 1 + P0.size() + 2 + P1.size() + 2;
|
|
|
|
|
|
|
|
s = (uint8_t*)calloc(s_len, sizeof(uint8_t));
|
|
|
|
|
|
|
|
if (s == nullptr) {
|
|
|
|
log_error("Unable to allocate memory in %s()", __FUNCTION__);
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t i = 0;
|
|
|
|
s[i] = fc; // FC
|
|
|
|
i++;
|
|
|
|
|
|
|
|
// P0
|
|
|
|
memcpy(&s[i], P0.data(), P0.size());
|
|
|
|
i += P0.size();
|
|
|
|
uint16_t p0_length_value = htons(P0.size());
|
|
|
|
memcpy(&s[i], &p0_length_value, sizeof(p0_length_value));
|
|
|
|
i += sizeof(p0_length_value);
|
|
|
|
|
|
|
|
// P1
|
|
|
|
memcpy(&s[i], P1.data(), P1.size());
|
|
|
|
i += P1.size();
|
|
|
|
uint16_t p1_length_value = htons(P1.size());
|
|
|
|
memcpy(&s[i], &p1_length_value, sizeof(p1_length_value));
|
|
|
|
i += sizeof(p1_length_value);
|
|
|
|
|
|
|
|
sha256(key.data(), key.size(), s, i, output, 0);
|
|
|
|
free(s);
|
|
|
|
|
|
|
|
return SRSRAN_SUCCESS;
|
2021-01-22 04:43:53 -08:00
|
|
|
}
|
|
|
|
|
2021-07-27 08:52:02 -07:00
|
|
|
int kdf_common(const uint8_t fc,
|
|
|
|
const std::array<uint8_t, 32>& key,
|
|
|
|
const std::vector<uint8_t>& P0,
|
|
|
|
const std::vector<uint8_t>& P1,
|
|
|
|
const std::vector<uint8_t>& P2,
|
|
|
|
uint8_t* output)
|
|
|
|
{
|
|
|
|
uint8_t* s;
|
|
|
|
uint32_t s_len = 1 + P0.size() + 2 + P1.size() + 2 + P2.size() + 2;
|
|
|
|
|
|
|
|
s = (uint8_t*)calloc(s_len, sizeof(uint8_t));
|
|
|
|
|
|
|
|
if (s == nullptr) {
|
|
|
|
log_error("Unable to allocate memory in %s()", __FUNCTION__);
|
|
|
|
return SRSRAN_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t i = 0;
|
|
|
|
s[i] = fc; // FC
|
|
|
|
i++;
|
|
|
|
|
|
|
|
// P0
|
|
|
|
memcpy(&s[i], P0.data(), P0.size());
|
|
|
|
i += P0.size();
|
|
|
|
uint16_t p0_length_value = htons(P0.size());
|
|
|
|
memcpy(&s[i], &p0_length_value, sizeof(p0_length_value));
|
|
|
|
i += sizeof(p0_length_value);
|
|
|
|
|
|
|
|
// P1
|
|
|
|
memcpy(&s[i], P1.data(), P1.size());
|
|
|
|
i += P1.size();
|
|
|
|
uint16_t p1_length_value = htons(P1.size());
|
|
|
|
memcpy(&s[i], &p1_length_value, sizeof(p1_length_value));
|
|
|
|
i += sizeof(p1_length_value);
|
|
|
|
|
|
|
|
// P2
|
|
|
|
memcpy(&s[i], P2.data(), P2.size());
|
|
|
|
i += P2.size();
|
|
|
|
uint16_t p2_length_value = htons(P2.size());
|
|
|
|
memcpy(&s[i], &p2_length_value, sizeof(p2_length_value));
|
|
|
|
i += sizeof(p2_length_value);
|
|
|
|
|
|
|
|
sha256(key.data(), key.size(), s, i, output, 0);
|
|
|
|
free(s);
|
|
|
|
|
|
|
|
return SRSRAN_SUCCESS;
|
|
|
|
}
|
2017-05-18 03:11:31 -07:00
|
|
|
/******************************************************************************
|
|
|
|
* Integrity Protection
|
|
|
|
*****************************************************************************/
|
|
|
|
|
2020-05-12 05:43:49 -07:00
|
|
|
uint8_t security_128_eia1(const uint8_t* key,
|
|
|
|
uint32_t count,
|
|
|
|
uint32_t bearer,
|
|
|
|
uint8_t direction,
|
|
|
|
uint8_t* msg,
|
|
|
|
uint32_t msg_len,
|
|
|
|
uint8_t* mac)
|
2017-05-18 03:11:31 -07:00
|
|
|
{
|
2020-05-18 01:38:59 -07:00
|
|
|
return liblte_security_128_eia1(key, count, bearer, direction, msg, msg_len, mac);
|
2017-05-18 03:11:31 -07:00
|
|
|
}
|
|
|
|
|
2020-05-12 05:43:49 -07:00
|
|
|
uint8_t security_128_eia2(const uint8_t* key,
|
|
|
|
uint32_t count,
|
|
|
|
uint32_t bearer,
|
|
|
|
uint8_t direction,
|
|
|
|
uint8_t* msg,
|
|
|
|
uint32_t msg_len,
|
|
|
|
uint8_t* mac)
|
2019-04-10 04:15:23 -07:00
|
|
|
{
|
|
|
|
return liblte_security_128_eia2(key, count, bearer, direction, msg, msg_len, mac);
|
|
|
|
}
|
|
|
|
|
2020-05-18 01:38:59 -07:00
|
|
|
uint8_t security_128_eia3(const uint8_t* key,
|
|
|
|
uint32_t count,
|
|
|
|
uint32_t bearer,
|
|
|
|
uint8_t direction,
|
|
|
|
uint8_t* msg,
|
|
|
|
uint32_t msg_len,
|
|
|
|
uint8_t* mac)
|
2017-05-18 03:11:31 -07:00
|
|
|
{
|
2019-04-10 11:29:34 -07:00
|
|
|
return liblte_security_128_eia3(key, count, bearer, direction, msg, msg_len * 8, mac);
|
2017-05-18 03:11:31 -07:00
|
|
|
}
|
|
|
|
|
2019-08-08 07:46:21 -07:00
|
|
|
uint8_t security_md5(const uint8_t* input, size_t len, uint8_t* output)
|
2018-05-02 07:49:16 -07:00
|
|
|
{
|
|
|
|
memset(output, 0x00, 16);
|
|
|
|
mbedtls_md5(input, len, output);
|
2021-03-19 03:45:56 -07:00
|
|
|
return SRSRAN_SUCCESS;
|
2018-05-02 07:49:16 -07:00
|
|
|
}
|
|
|
|
|
2017-11-30 09:09:12 -08:00
|
|
|
/******************************************************************************
|
|
|
|
* Encryption / Decryption
|
|
|
|
*****************************************************************************/
|
|
|
|
|
2019-12-16 07:04:22 -08:00
|
|
|
uint8_t security_128_eea1(uint8_t* key,
|
|
|
|
uint32_t count,
|
|
|
|
uint8_t bearer,
|
|
|
|
uint8_t direction,
|
|
|
|
uint8_t* msg,
|
|
|
|
uint32_t msg_len,
|
|
|
|
uint8_t* msg_out)
|
|
|
|
{
|
|
|
|
return liblte_security_encryption_eea1(key, count, bearer, direction, msg, msg_len * 8, msg_out);
|
2017-11-30 09:09:12 -08:00
|
|
|
}
|
|
|
|
|
2019-12-16 07:04:22 -08:00
|
|
|
uint8_t security_128_eea2(uint8_t* key,
|
|
|
|
uint32_t count,
|
|
|
|
uint8_t bearer,
|
|
|
|
uint8_t direction,
|
|
|
|
uint8_t* msg,
|
|
|
|
uint32_t msg_len,
|
|
|
|
uint8_t* msg_out)
|
2019-08-08 07:46:21 -07:00
|
|
|
{
|
|
|
|
return liblte_security_encryption_eea2(key, count, bearer, direction, msg, msg_len * 8, msg_out);
|
2017-11-30 09:09:12 -08:00
|
|
|
}
|
|
|
|
|
2019-12-16 07:04:22 -08:00
|
|
|
uint8_t security_128_eea3(uint8_t* key,
|
|
|
|
uint32_t count,
|
|
|
|
uint8_t bearer,
|
|
|
|
uint8_t direction,
|
|
|
|
uint8_t* msg,
|
|
|
|
uint32_t msg_len,
|
|
|
|
uint8_t* msg_out)
|
2019-08-08 07:46:21 -07:00
|
|
|
{
|
|
|
|
return liblte_security_encryption_eea3(key, count, bearer, direction, msg, msg_len * 8, msg_out);
|
2019-04-10 04:15:23 -07:00
|
|
|
}
|
|
|
|
|
2017-05-18 03:11:31 -07:00
|
|
|
/******************************************************************************
|
|
|
|
* Authentication
|
|
|
|
*****************************************************************************/
|
2019-08-08 07:46:21 -07:00
|
|
|
uint8_t compute_opc(uint8_t* k, uint8_t* op, uint8_t* opc)
|
2018-06-18 07:19:04 -07:00
|
|
|
{
|
2019-08-08 07:46:21 -07:00
|
|
|
return liblte_compute_opc(k, op, opc);
|
2018-06-18 07:19:04 -07:00
|
|
|
}
|
2017-05-18 03:11:31 -07:00
|
|
|
|
2019-12-16 07:04:22 -08:00
|
|
|
uint8_t security_milenage_f1(uint8_t* k, uint8_t* op, uint8_t* rand, uint8_t* sqn, uint8_t* amf, uint8_t* mac_a)
|
2017-05-18 03:11:31 -07:00
|
|
|
{
|
2019-12-16 07:04:22 -08:00
|
|
|
return liblte_security_milenage_f1(k, op, rand, sqn, amf, mac_a);
|
2017-05-18 03:11:31 -07:00
|
|
|
}
|
|
|
|
|
2019-12-16 07:04:22 -08:00
|
|
|
uint8_t security_milenage_f1_star(uint8_t* k, uint8_t* op, uint8_t* rand, uint8_t* sqn, uint8_t* amf, uint8_t* mac_s)
|
2017-05-18 03:11:31 -07:00
|
|
|
{
|
2019-12-16 07:04:22 -08:00
|
|
|
return liblte_security_milenage_f1_star(k, op, rand, sqn, amf, mac_s);
|
2017-05-18 03:11:31 -07:00
|
|
|
}
|
|
|
|
|
2019-12-16 07:04:22 -08:00
|
|
|
uint8_t
|
|
|
|
security_milenage_f2345(uint8_t* k, uint8_t* op, uint8_t* rand, uint8_t* res, uint8_t* ck, uint8_t* ik, uint8_t* ak)
|
2017-05-18 03:11:31 -07:00
|
|
|
{
|
2019-12-16 07:04:22 -08:00
|
|
|
return liblte_security_milenage_f2345(k, op, rand, res, ck, ik, ak);
|
2017-05-18 03:11:31 -07:00
|
|
|
}
|
|
|
|
|
2019-12-16 07:04:22 -08:00
|
|
|
uint8_t security_milenage_f5_star(uint8_t* k, uint8_t* op, uint8_t* rand, uint8_t* ak)
|
2017-05-18 03:11:31 -07:00
|
|
|
{
|
2019-12-16 07:04:22 -08:00
|
|
|
return liblte_security_milenage_f5_star(k, op, rand, ak);
|
2017-05-18 03:11:31 -07:00
|
|
|
}
|
|
|
|
|
2021-07-27 08:47:42 -07:00
|
|
|
int security_xor_f2345(uint8_t* k, uint8_t* rand, uint8_t* res, uint8_t* ck, uint8_t* ik, uint8_t* ak)
|
|
|
|
{
|
|
|
|
uint8_t xdout[16];
|
|
|
|
uint8_t cdout[8];
|
|
|
|
// Use RAND and K to compute RES, CK, IK and AK
|
|
|
|
for (uint32_t i = 0; i < 16; i++) {
|
|
|
|
xdout[i] = k[i] ^ rand[i];
|
|
|
|
}
|
|
|
|
for (uint32_t i = 0; i < 16; i++) {
|
|
|
|
res[i] = xdout[i];
|
|
|
|
ck[i] = xdout[(i + 1) % 16];
|
|
|
|
ik[i] = xdout[(i + 2) % 16];
|
|
|
|
}
|
|
|
|
for (uint32_t i = 0; i < 6; i++) {
|
|
|
|
ak[i] = xdout[i + 3];
|
|
|
|
}
|
|
|
|
return SRSRAN_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int security_xor_f1(uint8_t* k, uint8_t* rand, uint8_t* sqn, uint8_t* amf, uint8_t* mac_a)
|
|
|
|
{
|
|
|
|
uint8_t xdout[16];
|
|
|
|
uint8_t cdout[8];
|
|
|
|
// Use RAND and K to compute RES, CK, IK and AK
|
|
|
|
for (uint32_t i = 0; i < 16; i++) {
|
|
|
|
xdout[i] = k[i] ^ rand[i];
|
|
|
|
}
|
|
|
|
// Generate cdout
|
|
|
|
for (uint32_t i = 0; i < 6; i++) {
|
|
|
|
cdout[i] = sqn[i];
|
|
|
|
}
|
|
|
|
for (uint32_t i = 0; i < 2; i++) {
|
|
|
|
cdout[6 + i] = amf[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generate MAC
|
|
|
|
for (uint32_t i = 0; i < 8; i++) {
|
|
|
|
mac_a[i] = xdout[i] ^ cdout[i];
|
|
|
|
}
|
|
|
|
return SRSRAN_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2021-03-19 03:45:56 -07:00
|
|
|
} // namespace srsran
|