Merge remote-tracking branch 'origin/merge_secu_osa' into integration_2023_w21
This commit is contained in:
@@ -23,8 +23,6 @@
|
||||
|
||||
#include "commonDef.h"
|
||||
|
||||
#include "security_types.h"
|
||||
|
||||
#include "queue.h"
|
||||
|
||||
#ifndef COMMON_TYPES_H_
|
||||
|
||||
@@ -42,14 +42,6 @@
|
||||
#define AUTN_LENGTH_BITS (128)
|
||||
#define AUTN_LENGTH_OCTETS (AUTN_LENGTH_BITS/8)
|
||||
|
||||
/* Some methods to convert a string to an int64_t */
|
||||
/*
|
||||
#define STRING_TO_64BITS(sTRING, cONTAINER) \
|
||||
sscanf(sTRING, "%" SCN64, cONTAINER)
|
||||
#define STRING_TO_U64BITS(sTRING, cONTAINER) \
|
||||
sscanf(sTRING, "%" SCNu64, cONTAINER)
|
||||
*/
|
||||
|
||||
/* Converts a string to 128 bits gmplib integer holder */
|
||||
# define STRING_TO_XBITS(sTRING, lENGTH, cONTAINER, rET) \
|
||||
do { \
|
||||
@@ -63,18 +55,6 @@ STRING_TO_XBITS(sTRING, 16, cONTAINER, rET)
|
||||
# define STRING_TO_256BITS(sTRING, cONTAINER, rET) \
|
||||
STRING_TO_XBITS(sTRING, 32, cONTAINER, rET)
|
||||
|
||||
# define STRING_TO_RAND STRING_TO_128BITS
|
||||
# define STRING_TO_AUTH_KEY STRING_TO_128BITS
|
||||
# define STRING_TO_AUTH_RES STRING_TO_128BITS
|
||||
# define STRING_TO_AUTN STRING_TO_128BITS
|
||||
# define STRING_TO_KASME STRING_TO_256BITS
|
||||
# define STRING_TO_XRES(sTRING, lENGTH, cONTAINER, rET) \
|
||||
do { \
|
||||
STRING_TO_XBITS(sTRING, lENGTH, (cONTAINER)->data, rET); \
|
||||
if (rET != -1) \
|
||||
(cONTAINER)->size = lENGTH; \
|
||||
} while(0)
|
||||
|
||||
/* RES amd XRES can have a variable length of 4-16 octets */
|
||||
typedef struct {
|
||||
uint8_t size;
|
||||
@@ -107,28 +87,4 @@ typedef struct eutran_vector_s {
|
||||
uint8_t kasme[KASME_LENGTH_OCTETS];
|
||||
} eutran_vector_t;
|
||||
|
||||
#define FC_KASME (0x10)
|
||||
#define FC_KENB (0x11)
|
||||
#define FC_NH (0x12)
|
||||
#define FC_KENB_STAR (0x13)
|
||||
/* 33401 #A.7 Algorithm for key derivation function.
|
||||
* This FC should be used for:
|
||||
* - NAS Encryption algorithm
|
||||
* - NAS Integrity algorithm
|
||||
* - RRC Encryption algorithm
|
||||
* - RRC Integrity algorithm
|
||||
* - User Plane Encryption algorithm
|
||||
*/
|
||||
#define FC_ALG_KEY_DER (0x15)
|
||||
#define FC_KASME_TO_CK (0x16)
|
||||
|
||||
typedef enum {
|
||||
NAS_ENC_ALG = 0x01,
|
||||
NAS_INT_ALG = 0x02,
|
||||
RRC_ENC_ALG = 0x03,
|
||||
RRC_INT_ALG = 0x04,
|
||||
UP_ENC_ALG = 0x05,
|
||||
UP_INT_ALG = 0x06
|
||||
} algorithm_type_dist_t;
|
||||
|
||||
#endif /* SECURITY_TYPES_H_ */
|
||||
|
||||
@@ -53,8 +53,6 @@ Description Defines the layer 3 messages supported by the NAS sublayer
|
||||
#include "secu_defs.h"
|
||||
#include "emmData.h"
|
||||
|
||||
//#define DEBUG_NAS_MESSAGE
|
||||
|
||||
/****************************************************************************/
|
||||
/**************** E X T E R N A L D E F I N I T I O N S ****************/
|
||||
/****************************************************************************/
|
||||
@@ -1019,7 +1017,8 @@ static int _nas_message_decrypt(
|
||||
stream_cipher.message = (unsigned char *)src;
|
||||
/* length in bits */
|
||||
stream_cipher.blength = length << 3;
|
||||
nas_stream_encrypt_eea1(&stream_cipher, (unsigned char *)dest);
|
||||
stream_compute_encrypt(EEA1_128_ALG_ID, &stream_cipher, (unsigned char *)dest);
|
||||
|
||||
/* Decode the first octet (security header type or EPS bearer identity,
|
||||
* and protocol discriminator) */
|
||||
DECODE_U8(dest, *(uint8_t*)(&header), size);
|
||||
@@ -1054,7 +1053,8 @@ static int _nas_message_decrypt(
|
||||
stream_cipher.message = (unsigned char *)src;
|
||||
/* length in bits */
|
||||
stream_cipher.blength = length << 3;
|
||||
nas_stream_encrypt_eea1(&stream_cipher, (unsigned char *)dest);
|
||||
stream_compute_encrypt(EEA1_128_ALG_ID, &stream_cipher, (unsigned char *)dest);
|
||||
|
||||
/* Decode the first octet (security header type or EPS bearer identity,
|
||||
* and protocol discriminator) */
|
||||
DECODE_U8(dest, *(uint8_t*)(&header), size);
|
||||
@@ -1186,8 +1186,7 @@ static int _nas_message_encrypt(
|
||||
stream_cipher.message = (unsigned char *)src;
|
||||
/* length in bits */
|
||||
stream_cipher.blength = length << 3;
|
||||
nas_stream_encrypt_eea1(&stream_cipher, (unsigned char *)dest);
|
||||
|
||||
stream_compute_encrypt(EEA1_128_ALG_ID, &stream_cipher, (unsigned char *)dest);
|
||||
LOG_FUNC_RETURN (length);
|
||||
|
||||
}
|
||||
@@ -1217,7 +1216,7 @@ static int _nas_message_encrypt(
|
||||
stream_cipher.message = (unsigned char *)src;
|
||||
/* length in bits */
|
||||
stream_cipher.blength = length << 3;
|
||||
nas_stream_encrypt_eea2(&stream_cipher, (unsigned char *)dest);
|
||||
stream_compute_encrypt(EEA2_128_ALG_ID, &stream_cipher, (unsigned char *)dest);
|
||||
|
||||
LOG_FUNC_RETURN (length);
|
||||
|
||||
@@ -1356,10 +1355,8 @@ static uint32_t _nas_message_get_mac(
|
||||
stream_cipher.message = (unsigned char *)buffer;
|
||||
/* length in bits */
|
||||
stream_cipher.blength = length << 3;
|
||||
stream_compute_integrity(EIA1_128_ALG_ID, &stream_cipher, mac);
|
||||
|
||||
nas_stream_encrypt_eia1(
|
||||
&stream_cipher,
|
||||
mac);
|
||||
LOG_TRACE(DEBUG,
|
||||
"NAS_SECURITY_ALGORITHMS_EIA1 returned MAC %x.%x.%x.%x(%u) for length %d direction %d, count %d",
|
||||
mac[0], mac[1], mac[2],mac[3],
|
||||
@@ -1402,10 +1399,8 @@ static uint32_t _nas_message_get_mac(
|
||||
stream_cipher.message = (unsigned char *)buffer;
|
||||
/* length in bits */
|
||||
stream_cipher.blength = length << 3;
|
||||
stream_compute_integrity(EIA2_128_ALG_ID, &stream_cipher, mac);
|
||||
|
||||
nas_stream_encrypt_eia2(
|
||||
&stream_cipher,
|
||||
mac);
|
||||
LOG_TRACE(DEBUG,
|
||||
"NAS_SECURITY_ALGORITHMS_EIA2 returned MAC %x.%x.%x.%x(%u) for length %d direction %d, count %d",
|
||||
mac[0], mac[1], mac[2],mac[3],
|
||||
|
||||
@@ -29,10 +29,11 @@
|
||||
|
||||
#ifndef MILENAGE_H
|
||||
#define MILENAGE_H
|
||||
|
||||
#include <openssl/aes.h>
|
||||
|
||||
#include "openair3/SECU/aes_128_ecb.h"
|
||||
|
||||
#define u8 uint8_t
|
||||
/**
|
||||
milenage_f1 - Milenage f1 and f1* algorithms
|
||||
@opc: OPc = 128-bit value derived from OP and K
|
||||
@@ -45,16 +46,29 @@
|
||||
Returns: true on success, false on failure
|
||||
*/
|
||||
|
||||
void aes_128_encrypt_block(const u8* key, const u8* in, u8* out) {
|
||||
AES_KEY k;
|
||||
u8 tmp[16];
|
||||
AES_set_encrypt_key(key, 128, &k);
|
||||
AES_encrypt(in, tmp, &k);
|
||||
void aes_128_encrypt_block(const uint8_t *key, const uint8_t *in, uint8_t *out)
|
||||
{
|
||||
abort();
|
||||
assert(0 != 0 && "Here we are!");
|
||||
// Precondition: key, in and out occupy 16 bytes
|
||||
aes_128_t k_iv = {.type = NONE_INITIALIZATION_VECTOR};
|
||||
memcpy(k_iv.key, key, sizeof(k_iv.key));
|
||||
|
||||
byte_array_t msg = {.buf = (uint8_t *)in, .len = 16};
|
||||
uint8_t tmp[16] = {0};
|
||||
aes_128_ecb(&k_iv, msg, sizeof(tmp), tmp);
|
||||
memcpy(out, tmp, sizeof(tmp));
|
||||
}
|
||||
static bool milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand,
|
||||
const u8 *sqn, const u8 *amf, u8 *mac_a, u8 *mac_s) {
|
||||
u8 tmp1[16], tmp2[16], tmp3[16];
|
||||
|
||||
static bool milenage_f1(const uint8_t *opc,
|
||||
const uint8_t *k,
|
||||
const uint8_t *_rand,
|
||||
const uint8_t *sqn,
|
||||
const uint8_t *amf,
|
||||
uint8_t *mac_a,
|
||||
uint8_t *mac_s)
|
||||
{
|
||||
uint8_t tmp1[16], tmp2[16], tmp3[16];
|
||||
int i;
|
||||
|
||||
/* tmp1 = TEMP = E_K(RAND XOR OP_C) */
|
||||
@@ -62,10 +76,10 @@ static bool milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand,
|
||||
tmp1[i] = _rand[i] ^ opc[i];
|
||||
|
||||
aes_128_encrypt_block(k, tmp1, tmp1);
|
||||
AES_KEY kTab;
|
||||
uint8_t cyphered[16];
|
||||
AES_set_encrypt_key(k, 128, &kTab);
|
||||
AES_encrypt(tmp1, cyphered, &kTab);
|
||||
|
||||
uint8_t cyphered[16] = {0};
|
||||
aes_128_encrypt_block(k, tmp1, cyphered);
|
||||
|
||||
/* tmp2 = IN1 = SQN || AMF || SQN || AMF */
|
||||
memcpy(tmp2, sqn, 6);
|
||||
memcpy(tmp2 + 6, amf, 2);
|
||||
@@ -97,7 +111,6 @@ static bool milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
milenage_f2345 - Milenage f2, f3, f4, f5, f5* algorithms
|
||||
@opc: OPc = 128-bit value derived from OP and K
|
||||
@@ -110,9 +123,16 @@ static bool milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand,
|
||||
@akstar: Buffer for AK = 48-bit anonymity key (f5*), or %NULL
|
||||
Returns: true on success, false on failure
|
||||
*/
|
||||
static bool milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand,
|
||||
u8 *res, u8 *ck, u8 *ik, u8 *ak, u8 *akstar) {
|
||||
u8 tmp1[16], tmp2[16], tmp3[16];
|
||||
static bool milenage_f2345(const uint8_t *opc,
|
||||
const uint8_t *k,
|
||||
const uint8_t *_rand,
|
||||
uint8_t *res,
|
||||
uint8_t *ck,
|
||||
uint8_t *ik,
|
||||
uint8_t *ak,
|
||||
uint8_t *akstar)
|
||||
{
|
||||
uint8_t tmp1[16], tmp2[16], tmp3[16];
|
||||
int i;
|
||||
|
||||
/* tmp2 = TEMP = E_K(RAND XOR OP_C) */
|
||||
@@ -186,7 +206,6 @@ static bool milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
milenage_generate - Generate AKA AUTN,IK,CK,RES
|
||||
@opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
|
||||
@@ -200,11 +219,18 @@ static bool milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand,
|
||||
@res: Buffer for RES = 64-bit signed response (f2), or %NULL
|
||||
@res_len: Max length for res; set to used length or 0 on failure
|
||||
*/
|
||||
static bool milenage_generate(const u8 *opc, const u8 *amf, const u8 *k,
|
||||
const u8 *sqn, const u8 *_rand, u8 *autn, u8 *ik,
|
||||
u8 *ck, u8 *res) {
|
||||
static bool milenage_generate(const uint8_t *opc,
|
||||
const uint8_t *amf,
|
||||
const uint8_t *k,
|
||||
const uint8_t *sqn,
|
||||
const uint8_t *_rand,
|
||||
uint8_t *autn,
|
||||
uint8_t *ik,
|
||||
uint8_t *ck,
|
||||
uint8_t *res)
|
||||
{
|
||||
int i;
|
||||
u8 mac_a[8], ak[6];
|
||||
uint8_t mac_a[8], ak[6];
|
||||
|
||||
if (!milenage_f1(opc, k, _rand, sqn, amf, mac_a, NULL) ||
|
||||
!milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL))
|
||||
@@ -219,7 +245,6 @@ static bool milenage_generate(const u8 *opc, const u8 *amf, const u8 *k,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
milenage_auts - Milenage AUTS validation
|
||||
@opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
|
||||
@@ -232,10 +257,10 @@ static bool milenage_generate(const u8 *opc, const u8 *amf, const u8 *k,
|
||||
#define p(a) printf("%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n", (int)((a)[0]), (int)((a)[1]), (int)((a)[2]), (int)((a)[3]),(int)((a)[4]), (int)((a)[5]));
|
||||
// valid code but put in comment as it is not used right now
|
||||
#if 0
|
||||
static bool milenage_auts(const u8 *opc, const u8 *k, const u8 *_rand, const u8 *auts,
|
||||
u8 *sqn) {
|
||||
u8 amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */
|
||||
u8 ak[6], mac_s[8];
|
||||
static bool milenage_auts(const uint8_t *opc, const uint8_t *k, const uint8_t *_rand, const uint8_t *auts,
|
||||
uint8_t *sqn) {
|
||||
uint8_t amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */
|
||||
uint8_t ak[6], mac_s[8];
|
||||
int i;
|
||||
|
||||
if (!milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak))
|
||||
@@ -262,8 +287,8 @@ static bool milenage_auts(const u8 *opc, const u8 *k, const u8 *_rand, const u8
|
||||
@kc: Buffer for Kc = 64-bit Kc
|
||||
Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
static bool gsm_milenage(const u8 *opc, const u8 *k, const u8 *_rand, u8 *sres, u8 *kc) {
|
||||
u8 res[8], ck[16], ik[16];
|
||||
static bool gsm_milenage(const uint8_t *opc, const uint8_t *k, const uint8_t *_rand, uint8_t *sres, uint8_t *kc) {
|
||||
uint8_t res[8], ck[16], ik[16];
|
||||
int i;
|
||||
|
||||
if (milenage_f2345(opc, k, _rand, res, ck, ik, NULL, NULL))
|
||||
@@ -298,12 +323,12 @@ static bool gsm_milenage(const u8 *opc, const u8 *k, const u8 *_rand, u8 *sres,
|
||||
@auts: 112-bit buffer for AUTS
|
||||
Returns: 0 on success, -1 on failure, or -2 on synchronization failure
|
||||
*/
|
||||
static int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_rand,
|
||||
const u8 *autn, u8 *ik, u8 *ck, u8 *res, size_t *res_len,
|
||||
u8 *auts) {
|
||||
static int milenage_check(const uint8_t *opc, const uint8_t *k, const uint8_t *sqn, const uint8_t *_rand,
|
||||
const uint8_t *autn, uint8_t *ik, uint8_t *ck, uint8_t *res, size_t *res_len,
|
||||
uint8_t *auts) {
|
||||
int i;
|
||||
u8 mac_a[8], ak[6], rx_sqn[6];
|
||||
const u8 *amf;
|
||||
uint8_t mac_a[8], ak[6], rx_sqn[6];
|
||||
const uint8_t *amf;
|
||||
|
||||
if (milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL))
|
||||
return -1;
|
||||
@@ -315,7 +340,7 @@ static int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_
|
||||
rx_sqn[i] = autn[i] ^ ak[i];
|
||||
|
||||
if (memcmp(rx_sqn, sqn, 6) <= 0) {
|
||||
u8 auts_amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */
|
||||
uint8_t auts_amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */
|
||||
|
||||
if (milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak))
|
||||
return -1;
|
||||
@@ -342,7 +367,7 @@ static int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void milenage_opc_gen(const u8 *k, const u8 *op, u8 *opc) {
|
||||
static void milenage_opc_gen(const uint8_t *k, const uint8_t *op, uint8_t *opc) {
|
||||
int i;
|
||||
/* Encrypt OP using K */
|
||||
aes_128_encrypt_block(k, op, opc);
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "aka_functions.h"
|
||||
#include "secu_defs.h"
|
||||
#include "kdf.h"
|
||||
#include "key_nas_deriver.h"
|
||||
#include "PduSessionEstablishRequest.h"
|
||||
#include "PduSessionEstablishmentAccept.h"
|
||||
#include "RegistrationAccept.h"
|
||||
@@ -50,6 +51,7 @@
|
||||
#include <openair1/PHY/phy_extern_nr_ue.h>
|
||||
#include <openair1/SIMULATION/ETH_TRANSPORT/proto.h>
|
||||
#include "openair2/SDAP/nr_sdap/nr_sdap.h"
|
||||
#include "openair3/SECU/nas_stream_eia2.h"
|
||||
|
||||
uint8_t *registration_request_buf;
|
||||
uint32_t registration_request_len;
|
||||
@@ -597,9 +599,7 @@ static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
|
||||
stream_cipher.blength = (initialNasMsg->length - 6) << 3;
|
||||
|
||||
// only for Type of integrity protection algorithm: 128-5G-IA2 (2)
|
||||
nas_stream_encrypt_eia2(
|
||||
&stream_cipher,
|
||||
mac);
|
||||
stream_compute_integrity(EIA2_128_ALG_ID, &stream_cipher, mac);
|
||||
|
||||
printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]);
|
||||
for(int i = 0; i < 4; i++){
|
||||
@@ -702,9 +702,7 @@ static void generateRegistrationComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
|
||||
stream_cipher.blength = (initialNasMsg->length - 6) << 3;
|
||||
|
||||
// only for Type of integrity protection algorithm: 128-5G-IA2 (2)
|
||||
nas_stream_encrypt_eia2(
|
||||
&stream_cipher,
|
||||
mac);
|
||||
stream_compute_integrity(EIA2_128_ALG_ID, &stream_cipher, mac);
|
||||
|
||||
printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]);
|
||||
for(int i = 0; i < 4; i++){
|
||||
@@ -861,9 +859,7 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *
|
||||
stream_cipher.blength = (initialNasMsg->length - 6) << 3;
|
||||
|
||||
// only for Type of integrity protection algorithm: 128-5G-IA2 (2)
|
||||
nas_stream_encrypt_eia2(
|
||||
&stream_cipher,
|
||||
mac);
|
||||
stream_compute_integrity(EIA2_128_ALG_ID, &stream_cipher, mac);
|
||||
|
||||
printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]);
|
||||
for(int i = 0; i < 4; i++){
|
||||
|
||||
@@ -62,9 +62,10 @@ typedef struct{
|
||||
};
|
||||
} iv8_t;
|
||||
|
||||
typedef enum{
|
||||
typedef enum {
|
||||
AES_INITIALIZATION_VECTOR_8,
|
||||
AES_INITIALIZATION_VECTOR_16,
|
||||
NONE_INITIALIZATION_VECTOR,
|
||||
|
||||
AES_INITIALIZATION_VECTOR_END,
|
||||
} iv_e;
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "aes_128_ecb.h"
|
||||
#include "common/utils/assertions.h"
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
void aes_128_ecb(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out])
|
||||
{
|
||||
DevAssert(k_iv != NULL);
|
||||
DevAssert(k_iv->type == NONE_INITIALIZATION_VECTOR);
|
||||
|
||||
// Create and initialise the context
|
||||
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
|
||||
DevAssert(ctx != NULL);
|
||||
|
||||
// Initialise the encryption operation.
|
||||
int rc = EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, k_iv->key, NULL);
|
||||
DevAssert(rc == 1);
|
||||
|
||||
int len_ev = 0;
|
||||
rc = EVP_EncryptUpdate(ctx, out, &len_ev, msg.buf, msg.len);
|
||||
DevAssert(!(len_ev > len_out) && "Buffer overflow");
|
||||
|
||||
// Finalise the encryption. Normally ciphertext bytes may be written at
|
||||
// this stage, but this does not occur in GCM mode
|
||||
rc = EVP_EncryptFinal_ex(ctx, out + len_ev, &len_ev);
|
||||
DevAssert(rc == 1);
|
||||
|
||||
// Get the tag
|
||||
// rc == EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag))
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef AES_128_ECB_OAI_H
|
||||
#define AES_128_ECB_OAI_H
|
||||
|
||||
#include "aes_128.h"
|
||||
#include "common/utils/ds/byte_array.h"
|
||||
|
||||
void aes_128_ecb(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]);
|
||||
|
||||
#endif
|
||||
+202
-40
@@ -19,16 +19,84 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "aes_128.h"
|
||||
#include "aes_128_cbc_cmac.h"
|
||||
|
||||
#include "common/utils/assertions.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "kdf.h"
|
||||
#include "key_nas_deriver.h"
|
||||
#include "nas_stream_eea1.h"
|
||||
#include "nas_stream_eea2.h"
|
||||
#include "nas_stream_eia1.h"
|
||||
#include "nas_stream_eia2.h"
|
||||
#include "secu_defs.h"
|
||||
#include "snow3g.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "security_types.h"
|
||||
#include "secu_defs.h"
|
||||
#include "kdf.h"
|
||||
#define FC_KENB (0x11)
|
||||
#define FC_NH (0x12)
|
||||
#define FC_KENB_STAR (0x13)
|
||||
/* 33401 #A.7 Algorithm for key derivation function.
|
||||
* This FC should be used for:
|
||||
* - NAS Encryption algorithm
|
||||
* - NAS Integrity algorithm
|
||||
* - RRC Encryption algorithm
|
||||
* - RRC Integrity algorithm
|
||||
* - User Plane Encryption algorithm
|
||||
*/
|
||||
#define FC_ALG_KEY_DER (0x15)
|
||||
#define FC_KASME_TO_CK (0x16)
|
||||
|
||||
#define NR_FC_ALG_KEY_DER (0x69)
|
||||
#define NR_FC_ALG_KEY_NG_RAN_STAR_DER (0x70)
|
||||
|
||||
// #define SECU_DEBUG 1
|
||||
|
||||
static void derive_key_common(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t kasme[32], uint8_t FC, uint8_t out[32])
|
||||
{
|
||||
uint8_t s[7];
|
||||
#if defined(SECU_DEBUG)
|
||||
int i;
|
||||
#endif
|
||||
|
||||
/* FC */
|
||||
s[0] = FC;
|
||||
|
||||
/* P0 = algorithm type distinguisher */
|
||||
s[1] = (uint8_t)(alg_type & 0xFF);
|
||||
|
||||
/* L0 = length(P0) = 1 */
|
||||
s[2] = 0x00;
|
||||
s[3] = 0x01;
|
||||
|
||||
/* P1 */
|
||||
s[4] = alg_id;
|
||||
|
||||
/* L1 = length(P1) = 1 */
|
||||
s[5] = 0x00;
|
||||
s[6] = 0x01;
|
||||
|
||||
#if defined(SECU_DEBUG)
|
||||
printf("%s FC %d nas_alg_type distinguisher %d nas_enc_alg_identity %d\n", __FUNCTION__, FC_ALG_KEY_DER, alg_type, alg_id);
|
||||
|
||||
for (i = 0; i < 7; i ++) {
|
||||
printf("0x%02x ", s[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
byte_array_t data = {.len = 7, .buf = s};
|
||||
kdf(kasme, data, 32, out);
|
||||
}
|
||||
|
||||
#define SECU_DEBUG 1
|
||||
/*!
|
||||
* @brief Derive the kNASenc from kasme and perform truncate on the generated key to
|
||||
* reduce his size to 128 bits. Definition of the derivation function can
|
||||
@@ -41,50 +109,144 @@
|
||||
* - 2 for 128-EIA2 AES
|
||||
* @param[in] kasme Key for MME as provided by AUC
|
||||
* @param[out] knas Pointer to reference where output of KDF will be stored.
|
||||
*/
|
||||
void derive_key_nas(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t kasme[32], uint8_t knas[32])
|
||||
{
|
||||
derive_key_common(alg_type, alg_id, kasme, FC_ALG_KEY_DER, knas);
|
||||
}
|
||||
|
||||
void nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t out[16])
|
||||
{
|
||||
uint8_t tmp[32] = {0};
|
||||
derive_key_common(alg_type, alg_id, key, NR_FC_ALG_KEY_DER, tmp);
|
||||
|
||||
// Only the last 16 bytes are needed in 5G
|
||||
memcpy(out, &tmp[16], 16);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Derive the keys from key and perform truncate on the generated key to
|
||||
* reduce his size to 128 bits. Definition of the derivation function can
|
||||
* be found in 3GPP TS.33401 #A.7
|
||||
* @param[in] alg_type Algorithm distinguisher
|
||||
* @param[in] alg_id Algorithm identifier.
|
||||
* Possible values are:
|
||||
* - 0 for EIA0 algorithm (Null Integrity Protection algorithm)
|
||||
* - 1 for 128-EIA1 SNOW 3G
|
||||
* - 2 for 128-EIA2 AES
|
||||
* @param[in] key The top key used to derive other subkeys
|
||||
* @param[out] out Pointer to reference where output of KDF will be stored.
|
||||
* NOTE: knas is dynamically allocated by the KDF function
|
||||
*/
|
||||
int derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
|
||||
const uint8_t kasme[32], uint8_t *knas)
|
||||
|
||||
#ifndef NAS_UE
|
||||
void derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB)
|
||||
{
|
||||
uint8_t s[7];
|
||||
uint8_t out[32];
|
||||
#if defined(SECU_DEBUG)
|
||||
int i;
|
||||
uint8_t s[7] = {0};
|
||||
|
||||
// FC
|
||||
s[0] = FC_KENB;
|
||||
// P0 = Uplink NAS count
|
||||
s[1] = (nas_count & 0xff000000) >> 24;
|
||||
s[2] = (nas_count & 0x00ff0000) >> 16;
|
||||
s[3] = (nas_count & 0x0000ff00) >> 8;
|
||||
s[4] = (nas_count & 0x000000ff);
|
||||
|
||||
// Length of NAS count
|
||||
s[5] = 0x00;
|
||||
s[6] = 0x04;
|
||||
|
||||
byte_array_t data = {.buf = s, .len = 7};
|
||||
kdf(kasme, data, 32, keNB);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* FC */
|
||||
s[0] = FC_ALG_KEY_DER;
|
||||
|
||||
/* P0 = algorithm type distinguisher */
|
||||
s[1] = (uint8_t)(nas_alg_type & 0xFF);
|
||||
|
||||
/* L0 = length(P0) = 1 */
|
||||
s[2] = 0x00;
|
||||
s[3] = 0x01;
|
||||
|
||||
/* P1 */
|
||||
s[4] = nas_enc_alg_id;
|
||||
|
||||
/* L1 = length(P1) = 1 */
|
||||
s[5] = 0x00;
|
||||
s[6] = 0x01;
|
||||
|
||||
#if defined(SECU_DEBUG)
|
||||
printf("%s FC %d nas_alg_type distinguisher %d nas_enc_alg_identity %d\n",
|
||||
__FUNCTION__, FC_ALG_KEY_DER, nas_alg_type, nas_enc_alg_id);
|
||||
|
||||
for (i = 0; i < 7; i ++) {
|
||||
printf("0x%02x ", s[i]);
|
||||
void derive_keNB_star(const uint8_t *kenb_32,
|
||||
const uint16_t pci,
|
||||
const uint32_t earfcn_dl,
|
||||
const bool is_rel8_only,
|
||||
uint8_t *kenb_star)
|
||||
{
|
||||
// see 33.401 section A.5 KeNB* derivation function
|
||||
uint8_t s[10] = {0};
|
||||
byte_array_t data = {.buf = s};
|
||||
// FC = 0x13
|
||||
s[0] = FC_KENB_STAR;
|
||||
// P0 = PCI (target physical cell id)
|
||||
s[1] = (pci & 0x0000ff00) >> 8;
|
||||
s[2] = (pci & 0x000000ff);
|
||||
// L0 = length of PCI (i.e. 0x00 0x02)
|
||||
s[3] = 0x00;
|
||||
s[4] = 0x02;
|
||||
// P1 = EARFCN-DL (target physical cell downlink frequency)
|
||||
if (is_rel8_only) {
|
||||
s[5] = (earfcn_dl & 0x0000ff00) >> 8;
|
||||
s[6] = (earfcn_dl & 0x000000ff);
|
||||
s[7] = 0x00;
|
||||
s[8] = 0x02;
|
||||
data.len = 9;
|
||||
} else {
|
||||
s[5] = (earfcn_dl & 0x00ff0000) >> 16;
|
||||
s[6] = (earfcn_dl & 0x0000ff00) >> 8;
|
||||
s[7] = (earfcn_dl & 0x000000ff);
|
||||
s[8] = 0x00;
|
||||
s[9] = 0x03;
|
||||
data.len = 10;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
#endif
|
||||
kdf(kenb_32, data, 32, kenb_star);
|
||||
|
||||
//kdf(kasme, 32, s, 7, out, 32);
|
||||
byte_array_t data = {.len = 7, .buf = s};
|
||||
kdf(kasme, data, 32, out);
|
||||
// L1 length of EARFCN-DL (i.e. L1 = 0x00 0x02 if EARFCN-DL is between 0 and 65535, and L1 = 0x00 0x03 if EARFCN-DL is between
|
||||
// 65536 and 262143) NOTE: The length of EARFCN-DL cannot be generally set to 3 bytes for backward compatibility reasons: A Rel-8
|
||||
// entity (UE or eNB) would always assume an input parameter length of 2 bytes for the EARFCN-DL. This
|
||||
// would lead to different derived keys if another entity assumed an input parameter length of 3 bytes for the
|
||||
// EARFCN-DL.
|
||||
}
|
||||
|
||||
memcpy(knas, &out[31-16+1], 16);
|
||||
void nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star)
|
||||
{
|
||||
uint8_t s[10] = {0};
|
||||
|
||||
return 0;
|
||||
/* FC */
|
||||
s[0] = NR_FC_ALG_KEY_NG_RAN_STAR_DER;
|
||||
|
||||
/* P0 = PCI */
|
||||
s[1] = (pci & 0x0000ff00) >> 8;
|
||||
s[2] = (pci & 0x000000ff);
|
||||
|
||||
/* L0 = length(P0) = 2 */
|
||||
s[3] = 0x00;
|
||||
s[4] = 0x02;
|
||||
|
||||
/* P1 = NR ARFCN */
|
||||
s[5] = (nr_arfcn_dl & 0x00ff0000) >> 16;
|
||||
s[6] = (nr_arfcn_dl & 0x0000ff00) >> 8;
|
||||
s[7] = (nr_arfcn_dl & 0x000000ff);
|
||||
|
||||
/* L1 = length(P1) = 3 */
|
||||
s[8] = 0x00;
|
||||
s[9] = 0x03;
|
||||
|
||||
byte_array_t data = {.buf = s, .len = 10};
|
||||
const uint32_t len_key = 32;
|
||||
kdf(key, data, len_key, key_ng_ran_star);
|
||||
}
|
||||
|
||||
void derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB)
|
||||
{
|
||||
uint8_t s[5] = {0};
|
||||
|
||||
/* FC is 0x1c (see 3gpp 33.401 annex A.15) */
|
||||
s[0] = 0x1c;
|
||||
|
||||
/* put sk_counter */
|
||||
s[1] = (sk_counter >> 8) & 0xff;
|
||||
s[2] = sk_counter & 0xff;
|
||||
|
||||
/* put length of sk_counter (2) */
|
||||
s[3] = 0x00;
|
||||
s[4] = 0x02;
|
||||
|
||||
byte_array_t data = {.buf = s, .len = 5};
|
||||
kdf(keNB, data, 32, skgNB);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#ifndef KEY_NAS_DERIVER_H
|
||||
#define KEY_NAS_DERIVER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
NAS_ENC_ALG = 0x01,
|
||||
NAS_INT_ALG = 0x02,
|
||||
RRC_ENC_ALG = 0x03,
|
||||
RRC_INT_ALG = 0x04,
|
||||
UP_ENC_ALG = 0x05,
|
||||
UP_INT_ALG = 0x06
|
||||
} algorithm_type_dist_t;
|
||||
|
||||
void derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB);
|
||||
|
||||
void derive_keNB_star(const uint8_t *kenb_32,
|
||||
const uint16_t pci,
|
||||
const uint32_t earfcn_dl,
|
||||
const bool is_rel8_only,
|
||||
uint8_t *kenb_star);
|
||||
|
||||
void derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id, const uint8_t kasme[32], uint8_t knas[32]);
|
||||
|
||||
void derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB);
|
||||
|
||||
void nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t out[16]);
|
||||
|
||||
void nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "nas_stream_eea0.h"
|
||||
|
||||
#include "common/utils/assertions.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void nas_stream_encrypt_eea0(nas_stream_cipher_t const *stream_cipher, uint8_t *out)
|
||||
{
|
||||
DevAssert(stream_cipher != NULL);
|
||||
DevAssert(out != NULL);
|
||||
|
||||
LOG_D(OSA,
|
||||
"Entering stream_encrypt_eea0, bits length %u, bearer %u, "
|
||||
"count %u, direction %s\n",
|
||||
stream_cipher->blength,
|
||||
stream_cipher->bearer,
|
||||
stream_cipher->count,
|
||||
stream_cipher->direction == SECU_DIRECTION_DOWNLINK ? "Downlink" : "Uplink");
|
||||
|
||||
uint32_t byte_length = (stream_cipher->blength + 7) >> 3;
|
||||
memcpy(out, stream_cipher->message, byte_length);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef OAI_NAS_STREAM_EEA0_H
|
||||
#define OAI_NAS_STREAM_EEA0_H
|
||||
|
||||
#include "secu_defs.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void nas_stream_encrypt_eea0(nas_stream_cipher_t const *stream_cipher, uint8_t *out);
|
||||
|
||||
#endif
|
||||
@@ -26,13 +26,10 @@
|
||||
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
#include "secu_defs.h"
|
||||
#include "nas_stream_eea1.h"
|
||||
#include "snow3g.h"
|
||||
|
||||
// #define SECU_DEBUG
|
||||
|
||||
|
||||
int nas_stream_encrypt_eea1(nas_stream_cipher_t *stream_cipher, uint8_t *out)
|
||||
void nas_stream_encrypt_eea1(nas_stream_cipher_t const *stream_cipher, uint8_t *out)
|
||||
{
|
||||
snow_3g_context_t snow_3g_context;
|
||||
int n ;
|
||||
@@ -106,6 +103,4 @@ int nas_stream_encrypt_eea1(nas_stream_cipher_t *stream_cipher, uint8_t *out)
|
||||
if (zero_bit > 0) {
|
||||
out[ceil_index - 1] = stream_cipher->message[ceil_index - 1];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef OAI_NAS_STREAM_EEA1_H
|
||||
#define OAI_NAS_STREAM_EEA1_H
|
||||
|
||||
#include "secu_defs.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void nas_stream_encrypt_eea1(nas_stream_cipher_t const *stream_cipher, uint8_t *out);
|
||||
|
||||
#endif
|
||||
@@ -28,9 +28,9 @@
|
||||
#include "aes_128_ctr.h"
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
#include "secu_defs.h"
|
||||
#include "nas_stream_eea2.h"
|
||||
|
||||
int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t *out)
|
||||
void nas_stream_encrypt_eea2(nas_stream_cipher_t const *stream_cipher, uint8_t *out)
|
||||
{
|
||||
DevAssert(stream_cipher != NULL);
|
||||
DevAssert(stream_cipher->key != NULL);
|
||||
@@ -53,6 +53,4 @@ int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t *out)
|
||||
const size_t len_out = byte_lenght;
|
||||
byte_array_t msg = {.buf = stream_cipher->message, .len = byte_lenght};
|
||||
aes_128_ctr(&p, msg, len_out, out);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef OAI_NAS_STREAM_EEA2_H
|
||||
#define OAI_NAS_STREAM_EEA2_H
|
||||
|
||||
#include "secu_defs.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/* Rijndael S-box OSA_SR */
|
||||
|
||||
static const uint8_t OSA_SR[256] = {
|
||||
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D,
|
||||
0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
|
||||
0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
|
||||
0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
|
||||
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB,
|
||||
0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
|
||||
0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D,
|
||||
0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
|
||||
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,
|
||||
0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
|
||||
0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9,
|
||||
0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
|
||||
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16};
|
||||
|
||||
/* S-box OSA_SQ */
|
||||
|
||||
static const uint8_t OSA_SQ[256] = {
|
||||
0x25, 0x24, 0x73, 0x67, 0xD7, 0xAE, 0x5C, 0x30, 0xA4, 0xEE, 0x6E, 0xCB, 0x7D, 0xB5, 0x82, 0xDB, 0xE4, 0x8E, 0x48, 0x49,
|
||||
0x4F, 0x5D, 0x6A, 0x78, 0x70, 0x88, 0xE8, 0x5F, 0x5E, 0x84, 0x65, 0xE2, 0xD8, 0xE9, 0xCC, 0xED, 0x40, 0x2F, 0x11, 0x28,
|
||||
0x57, 0xD2, 0xAC, 0xE3, 0x4A, 0x15, 0x1B, 0xB9, 0xB2, 0x80, 0x85, 0xA6, 0x2E, 0x02, 0x47, 0x29, 0x07, 0x4B, 0x0E, 0xC1,
|
||||
0x51, 0xAA, 0x89, 0xD4, 0xCA, 0x01, 0x46, 0xB3, 0xEF, 0xDD, 0x44, 0x7B, 0xC2, 0x7F, 0xBE, 0xC3, 0x9F, 0x20, 0x4C, 0x64,
|
||||
0x83, 0xA2, 0x68, 0x42, 0x13, 0xB4, 0x41, 0xCD, 0xBA, 0xC6, 0xBB, 0x6D, 0x4D, 0x71, 0x21, 0xF4, 0x8D, 0xB0, 0xE5, 0x93,
|
||||
0xFE, 0x8F, 0xE6, 0xCF, 0x43, 0x45, 0x31, 0x22, 0x37, 0x36, 0x96, 0xFA, 0xBC, 0x0F, 0x08, 0x52, 0x1D, 0x55, 0x1A, 0xC5,
|
||||
0x4E, 0x23, 0x69, 0x7A, 0x92, 0xFF, 0x5B, 0x5A, 0xEB, 0x9A, 0x1C, 0xA9, 0xD1, 0x7E, 0x0D, 0xFC, 0x50, 0x8A, 0xB6, 0x62,
|
||||
0xF5, 0x0A, 0xF8, 0xDC, 0x03, 0x3C, 0x0C, 0x39, 0xF1, 0xB8, 0xF3, 0x3D, 0xF2, 0xD5, 0x97, 0x66, 0x81, 0x32, 0xA0, 0x00,
|
||||
0x06, 0xCE, 0xF6, 0xEA, 0xB7, 0x17, 0xF7, 0x8C, 0x79, 0xD6, 0xA7, 0xBF, 0x8B, 0x3F, 0x1F, 0x53, 0x63, 0x75, 0x35, 0x2C,
|
||||
0x60, 0xFD, 0x27, 0xD3, 0x94, 0xA5, 0x7C, 0xA1, 0x05, 0x58, 0x2D, 0xBD, 0xD9, 0xC7, 0xAF, 0x6B, 0x54, 0x0B, 0xE0, 0x38,
|
||||
0x04, 0xC8, 0x9D, 0xE7, 0x14, 0xB1, 0x87, 0x9C, 0xDF, 0x6F, 0xF9, 0xDA, 0x2A, 0xC4, 0x59, 0x16, 0x74, 0x91, 0xAB, 0x26,
|
||||
0x61, 0x76, 0x34, 0x2B, 0xAD, 0x99, 0xFB, 0x72, 0xEC, 0x33, 0x12, 0xDE, 0x98, 0x3B, 0xC0, 0x9B, 0x3E, 0x18, 0x10, 0x3A,
|
||||
0x56, 0xE1, 0x77, 0xC9, 0x1E, 0x9E, 0x95, 0xA3, 0x90, 0x19, 0xA8, 0x6C, 0x09, 0xD0, 0xF0, 0x86};
|
||||
|
||||
void nas_stream_encrypt_eea2(nas_stream_cipher_t const *stream_cipher, uint8_t *out);
|
||||
|
||||
#endif
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <string.h>
|
||||
#include <math.h> // double ceil(double x);
|
||||
|
||||
#include "secu_defs.h"
|
||||
#include "nas_stream_eia1.h"
|
||||
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
@@ -33,12 +33,6 @@
|
||||
|
||||
#define SECU_DEBUG
|
||||
|
||||
uint64_t MUL64x(uint64_t V, uint64_t c);
|
||||
uint64_t MUL64xPOW(uint64_t V, uint32_t i, uint64_t c);
|
||||
uint64_t MUL64(uint64_t V, uint64_t P, uint64_t c);
|
||||
int nas_stream_encrypt_eia1(nas_stream_cipher_t *stream_cipher, uint8_t out[4]);
|
||||
|
||||
|
||||
// see spec 3GPP Confidentiality and Integrity Algorithms UEA2&UIA2. Document 1: UEA2 and UIA2 Specification. Version 1.1
|
||||
|
||||
/* MUL64x.
|
||||
@@ -49,7 +43,7 @@ int nas_stream_encrypt_eia1(nas_stream_cipher_t *stream_cipher, uint8_t out
|
||||
* function.
|
||||
* See section 4.3.2 for details.
|
||||
*/
|
||||
uint64_t MUL64x(uint64_t V, uint64_t c)
|
||||
static uint64_t MUL64x(uint64_t V, uint64_t c)
|
||||
{
|
||||
if ( V & 0x8000000000000000 )
|
||||
return (V << 1) ^ c;
|
||||
@@ -65,7 +59,7 @@ uint64_t MUL64x(uint64_t V, uint64_t c)
|
||||
function.
|
||||
* See section 4.3.3 for details.
|
||||
*/
|
||||
uint64_t MUL64xPOW(uint64_t V, uint32_t i, uint64_t c)
|
||||
static uint64_t MUL64xPOW(uint64_t V, uint32_t i, uint64_t c)
|
||||
{
|
||||
if ( i == 0)
|
||||
return V;
|
||||
@@ -81,7 +75,7 @@ uint64_t MUL64xPOW(uint64_t V, uint32_t i, uint64_t c)
|
||||
* function.
|
||||
* See section 4.3.4 for details.
|
||||
*/
|
||||
uint64_t MUL64(uint64_t V, uint64_t P, uint64_t c)
|
||||
static uint64_t MUL64(uint64_t V, uint64_t P, uint64_t c)
|
||||
{
|
||||
uint64_t result = 0;
|
||||
int i = 0;
|
||||
@@ -99,7 +93,7 @@ uint64_t MUL64(uint64_t V, uint64_t P, uint64_t c)
|
||||
* Output : a 32 bit mask.
|
||||
* Prepares a 32 bit mask with required number of 1 bits on the MSB side.
|
||||
*/
|
||||
uint32_t mask32bit(int n)
|
||||
static uint32_t mask32bit(int n)
|
||||
{
|
||||
uint32_t mask=0x0;
|
||||
|
||||
@@ -118,7 +112,7 @@ uint32_t mask32bit(int n)
|
||||
* @param[in] stream_cipher Structure containing various variables to setup encoding
|
||||
* @param[out] out For EIA1 the output string is 32 bits long
|
||||
*/
|
||||
int nas_stream_encrypt_eia1(nas_stream_cipher_t *stream_cipher, uint8_t out[4])
|
||||
void nas_stream_encrypt_eia1(nas_stream_cipher_t const *stream_cipher, uint8_t out[4])
|
||||
{
|
||||
snow_3g_context_t snow_3g_context;
|
||||
uint32_t K[4],IV[4], z[5];
|
||||
@@ -218,5 +212,4 @@ int nas_stream_encrypt_eia1(nas_stream_cipher_t *stream_cipher, uint8_t out[4])
|
||||
//printf ("MAC_I:%16X\n",MAC_I);
|
||||
MAC_I = hton_int32(MAC_I);
|
||||
memcpy(out, &MAC_I, 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef OAI_NAS_STREAM_EIA1_H
|
||||
#define OAI_NAS_STREAM_EIA1_H
|
||||
|
||||
#include "secu_defs.h"
|
||||
|
||||
void nas_stream_encrypt_eia1(nas_stream_cipher_t const* stream_cipher, uint8_t out[4]);
|
||||
|
||||
#endif
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "secu_defs.h"
|
||||
#include "nas_stream_eia2.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include "aes_128_cbc_cmac.h"
|
||||
@@ -40,7 +40,7 @@
|
||||
* @param[out] out For EIA2 the output string is 32 bits long
|
||||
*/
|
||||
|
||||
int nas_stream_encrypt_eia2(nas_stream_cipher_t *stream_cipher, uint8_t out[4])
|
||||
void nas_stream_encrypt_eia2(nas_stream_cipher_t const *stream_cipher, uint8_t out[4])
|
||||
{
|
||||
DevAssert(stream_cipher != NULL);
|
||||
DevAssert(stream_cipher->message != NULL);
|
||||
@@ -49,7 +49,7 @@ int nas_stream_encrypt_eia2(nas_stream_cipher_t *stream_cipher, uint8_t out[4])
|
||||
DevAssert((stream_cipher->blength & 0x7) == 0);
|
||||
|
||||
aes_128_t k_iv = {0};
|
||||
memcpy(&k_iv.key, stream_cipher->key, sizeof(k_iv.key));
|
||||
memcpy(k_iv.key, stream_cipher->key, sizeof(k_iv.key));
|
||||
k_iv.type = AES_INITIALIZATION_VECTOR_8;
|
||||
k_iv.iv8.d.bearer = stream_cipher->bearer;
|
||||
k_iv.iv8.d.direction = stream_cipher->direction;
|
||||
@@ -59,8 +59,7 @@ int nas_stream_encrypt_eia2(nas_stream_cipher_t *stream_cipher, uint8_t out[4])
|
||||
uint8_t result[16] = {0};
|
||||
byte_array_t msg = {.buf = stream_cipher->message, .len = m_length };
|
||||
aes_128_cbc_cmac(&k_iv, msg, sizeof(result), result);
|
||||
|
||||
|
||||
memcpy(out, result, 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef OAI_NAS_STREAM_EIA2_H
|
||||
#define OAI_NAS_STREAM_EIA2_H
|
||||
|
||||
#include "secu_defs.h"
|
||||
|
||||
void nas_stream_encrypt_eia2(nas_stream_cipher_t const* stream_cipher, uint8_t out[4]);
|
||||
|
||||
#endif
|
||||
+38
-68
@@ -19,78 +19,48 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
|
||||
#include "secu_defs.h"
|
||||
#include "kdf.h"
|
||||
|
||||
#ifndef NAS_UE
|
||||
int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB)
|
||||
#include "common/utils/assertions.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
|
||||
#include "nas_stream_eea0.h"
|
||||
#include "nas_stream_eea1.h"
|
||||
#include "nas_stream_eea2.h"
|
||||
|
||||
#include "nas_stream_eia1.h"
|
||||
#include "nas_stream_eia2.h"
|
||||
|
||||
void stream_compute_integrity(eia_alg_id_e alg, nas_stream_cipher_t const* stream_cipher, uint8_t out[4])
|
||||
{
|
||||
uint8_t s[7] = {0};
|
||||
|
||||
// FC
|
||||
s[0] = FC_KENB;
|
||||
// P0 = Uplink NAS count
|
||||
s[1] = (nas_count & 0xff000000) >> 24;
|
||||
s[2] = (nas_count & 0x00ff0000) >> 16;
|
||||
s[3] = (nas_count & 0x0000ff00) >> 8;
|
||||
s[4] = (nas_count & 0x000000ff);
|
||||
|
||||
// Length of NAS count
|
||||
s[5] = 0x00;
|
||||
s[6] = 0x04;
|
||||
|
||||
// kdf(kasme, 32, s, 7, keNB, 32);
|
||||
byte_array_t data = {.buf = s, .len = 7};
|
||||
kdf(kasme, data, 32, keNB);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int derive_keNB_star(
|
||||
const uint8_t *kenb_32,
|
||||
const uint16_t pci,
|
||||
const uint32_t earfcn_dl,
|
||||
const bool is_rel8_only,
|
||||
uint8_t *kenb_star)
|
||||
{
|
||||
// see 33.401 section A.5 KeNB* derivation function
|
||||
uint8_t s[10] = {0};
|
||||
byte_array_t data = {.buf = s};
|
||||
// FC = 0x13
|
||||
s[0] = FC_KENB_STAR;
|
||||
// P0 = PCI (target physical cell id)
|
||||
s[1] = (pci & 0x0000ff00) >> 8;
|
||||
s[2] = (pci & 0x000000ff);
|
||||
// L0 = length of PCI (i.e. 0x00 0x02)
|
||||
s[3] = 0x00;
|
||||
s[4] = 0x02;
|
||||
// P1 = EARFCN-DL (target physical cell downlink frequency)
|
||||
if (is_rel8_only) {
|
||||
s[5] = (earfcn_dl & 0x0000ff00) >> 8;
|
||||
s[6] = (earfcn_dl & 0x000000ff);
|
||||
s[7] = 0x00;
|
||||
s[8] = 0x02;
|
||||
// kdf (kenb_32, 32, s, 9, kenb_star, 32);
|
||||
data.len = 9;
|
||||
if (alg == EIA0_ALG_ID) {
|
||||
LOG_E(OSA, "Provided integrity algorithm is currently not supported = %u\n", alg);
|
||||
} else if (alg == EIA1_128_ALG_ID) {
|
||||
LOG_D(OSA, "EIA1 algorithm applied for integrity\n");
|
||||
nas_stream_encrypt_eia1(stream_cipher, out);
|
||||
} else if (alg == EIA2_128_ALG_ID) {
|
||||
LOG_D(OSA, "EIA2 algorithm applied for integrity\n");
|
||||
nas_stream_encrypt_eia2(stream_cipher, out);
|
||||
} else {
|
||||
s[5] = (earfcn_dl & 0x00ff0000) >> 16;
|
||||
s[6] = (earfcn_dl & 0x0000ff00) >> 8;
|
||||
s[7] = (earfcn_dl & 0x000000ff);
|
||||
s[8] = 0x00;
|
||||
s[9] = 0x03;
|
||||
//kdf (kenb_32, 32, s, 10, kenb_star, 32);
|
||||
data.len = 10;
|
||||
LOG_E(OSA, "Provided integrity algorithm is currently not supported = %u\n", alg);
|
||||
DevAssert(0 != 0 && "Unknown Algorithm type");
|
||||
}
|
||||
}
|
||||
|
||||
void stream_compute_encrypt(eea_alg_id_e alg, nas_stream_cipher_t const* stream_cipher, uint8_t* out)
|
||||
{
|
||||
if (alg == EEA0_ALG_ID) {
|
||||
LOG_D(OSA, "EEA0 algorithm applied for encryption\n");
|
||||
nas_stream_encrypt_eea0(stream_cipher, out);
|
||||
} else if (alg == EEA1_128_ALG_ID) {
|
||||
LOG_D(OSA, "EEA1 algorithm applied for encryption\n");
|
||||
nas_stream_encrypt_eea1(stream_cipher, out);
|
||||
} else if (alg == EEA2_128_ALG_ID) {
|
||||
LOG_D(OSA, "EEA2 algorithm applied for encryption\n");
|
||||
nas_stream_encrypt_eea2(stream_cipher, out);
|
||||
} else {
|
||||
LOG_E(OSA, "Provided encrypt algorithm is currently not supported = %u\n", alg);
|
||||
DevAssert(0 != 0 && "Unknown Algorithm type");
|
||||
}
|
||||
|
||||
kdf (kenb_32, data, 32, kenb_star);
|
||||
|
||||
// L1 length of EARFCN-DL (i.e. L1 = 0x00 0x02 if EARFCN-DL is between 0 and 65535, and L1 = 0x00 0x03 if EARFCN-DL is between 65536 and 262143)
|
||||
// NOTE: The length of EARFCN-DL cannot be generally set to 3 bytes for backward compatibility reasons: A Rel-8
|
||||
// entity (UE or eNB) would always assume an input parameter length of 2 bytes for the EARFCN-DL. This
|
||||
// would lead to different derived keys if another entity assumed an input parameter length of 3 bytes for the
|
||||
// EARFCN-DL.
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+25
-43
@@ -22,47 +22,9 @@
|
||||
#ifndef SECU_DEFS_H_
|
||||
#define SECU_DEFS_H_
|
||||
|
||||
#include "security_types.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define EIA0_ALG_ID 0x00
|
||||
#define EIA1_128_ALG_ID 0x01
|
||||
#define EIA2_128_ALG_ID 0x02
|
||||
|
||||
#define EEA0_ALG_ID 0x00
|
||||
#define EEA1_128_ALG_ID 0x01
|
||||
#define EEA2_128_ALG_ID 0x02
|
||||
|
||||
#define SECU_DIRECTION_UPLINK 0
|
||||
#define SECU_DIRECTION_DOWNLINK 1
|
||||
|
||||
int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB);
|
||||
|
||||
int derive_keNB_star(const uint8_t *kenb_32, const uint16_t pci, const uint32_t earfcn_dl,
|
||||
const bool is_rel8_only, uint8_t * kenb_star);
|
||||
|
||||
int derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
|
||||
const uint8_t kasme[32], uint8_t *knas);
|
||||
|
||||
#define derive_key_nas_enc(aLGiD, kASME, kNAS) \
|
||||
derive_key_nas(NAS_ENC_ALG, aLGiD, kASME, kNAS)
|
||||
|
||||
#define derive_key_nas_int(aLGiD, kASME, kNAS) \
|
||||
derive_key_nas(NAS_INT_ALG, aLGiD, kASME, kNAS)
|
||||
|
||||
#define derive_key_rrc_enc(aLGiD, kASME, kNAS) \
|
||||
derive_key_nas(RRC_ENC_ALG, aLGiD, kASME, kNAS)
|
||||
|
||||
#define derive_key_rrc_int(aLGiD, kASME, kNAS) \
|
||||
derive_key_nas(RRC_INT_ALG, aLGiD, kASME, kNAS)
|
||||
|
||||
#define derive_key_up_enc(aLGiD, kASME, kNAS) \
|
||||
derive_key_nas(UP_ENC_ALG, aLGiD, kASME, kNAS)
|
||||
|
||||
#define derive_key_up_int(aLGiD, kASME, kNAS) \
|
||||
derive_key_nas(UP_INT_ALG, aLGiD, kASME, kNAS)
|
||||
|
||||
#define SECU_DIRECTION_UPLINK 0
|
||||
#define SECU_DIRECTION_DOWNLINK 1
|
||||
|
||||
@@ -77,14 +39,34 @@ typedef struct {
|
||||
uint32_t blength;
|
||||
} nas_stream_cipher_t;
|
||||
|
||||
int nas_stream_encrypt_eea1(nas_stream_cipher_t *stream_cipher, uint8_t *out);
|
||||
/*!
|
||||
* @brief Encrypt/Decrypt a block of data based on the provided algorithm
|
||||
* @param[in] algorithm Algorithm used to encrypt the data
|
||||
* Possible values are:
|
||||
* - EIA0_ALG_ID for NULL encryption
|
||||
* - EIA1_128_ALG_ID for SNOW-3G encryption (not avalaible right now)
|
||||
* - EIA2_128_ALG_ID for 128 bits AES LTE encryption
|
||||
* @param[in] stream_cipher All parameters used to compute the encrypted block of data
|
||||
* @param[out] out The encrypted block of data
|
||||
*/
|
||||
|
||||
int nas_stream_encrypt_eia1(nas_stream_cipher_t *stream_cipher, uint8_t out[4]);
|
||||
typedef enum {
|
||||
EIA0_ALG_ID = 0x00,
|
||||
EIA1_128_ALG_ID = 0x01,
|
||||
EIA2_128_ALG_ID = 0x02,
|
||||
END_EIA0_ALG_ID,
|
||||
} eia_alg_id_e;
|
||||
|
||||
int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t *out);
|
||||
void stream_compute_integrity(eia_alg_id_e alg, nas_stream_cipher_t const *stream_cipher, uint8_t out[4]);
|
||||
|
||||
int nas_stream_encrypt_eia2(nas_stream_cipher_t *stream_cipher, uint8_t out[4]);
|
||||
typedef enum {
|
||||
EEA0_ALG_ID = 0x00,
|
||||
EEA1_128_ALG_ID = 0x01,
|
||||
EEA2_128_ALG_ID = 0x02,
|
||||
|
||||
#undef SECU_DEBUG
|
||||
END_EEA_ALG_ID
|
||||
} eea_alg_id_e;
|
||||
|
||||
void stream_compute_encrypt(eea_alg_id_e alg, nas_stream_cipher_t const *stream_cipher, uint8_t *out);
|
||||
|
||||
#endif /* SECU_DEFS_H_ */
|
||||
|
||||
@@ -52,8 +52,7 @@ void eea1_encrypt(uint8_t direction, uint32_t count,
|
||||
nas_cipher->blength = length;
|
||||
nas_cipher->message = message;
|
||||
|
||||
if (nas_stream_encrypt_eea1(nas_cipher, result) != 0)
|
||||
fail("Fail: nas_stream_encrypt_eea1\n");
|
||||
stream_compute_encrypt(EEA1_128_ALG_ID, nas_cipher, result);
|
||||
|
||||
if (compare_buffer(result, byte_length, expected, byte_length) != 0) {
|
||||
fail("Fail: eea1_encrypt\n");
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "test_util.h"
|
||||
|
||||
#include "secu_defs.h"
|
||||
|
||||
static
|
||||
@@ -52,8 +51,7 @@ void eea2_encrypt(uint8_t direction, uint32_t count,
|
||||
nas_cipher->blength = length;
|
||||
nas_cipher->message = message;
|
||||
|
||||
if (nas_stream_encrypt_eea2(nas_cipher, result) != 0)
|
||||
fail("Fail: nas_stream_encrypt_eea2\n");
|
||||
nas_stream_encrypt_eea2(nas_cipher, result);
|
||||
|
||||
if (compare_buffer(result, byte_length, expected, byte_length) != 0) {
|
||||
fail("Fail: eea2_encrypt\n");
|
||||
|
||||
Reference in New Issue
Block a user