Remove nettle library from OAI, support OpenSSL 3.0 and 1.1
Add byte_array_t structure under common/
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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_OAI_H
|
||||
#define AES_128_OAI_H
|
||||
|
||||
#include <endian.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// see 33.401 B.2.3 for the input to 128-EIA2
|
||||
// (which is identical to 128-NIA2, see 33.501 D.3.1.3)
|
||||
|
||||
typedef struct {
|
||||
uint32_t count;
|
||||
uint8_t padding: 2;
|
||||
uint8_t direction: 1;
|
||||
uint8_t bearer: 5;
|
||||
uint8_t pad_8;
|
||||
uint16_t pad_16;
|
||||
uint64_t pad_64;
|
||||
} data_iv16_t;
|
||||
|
||||
typedef struct{
|
||||
union{
|
||||
data_iv16_t d;
|
||||
uint8_t iv[16];
|
||||
};
|
||||
} iv16_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t count;
|
||||
uint8_t padding: 2;
|
||||
uint8_t direction: 1;
|
||||
uint8_t bearer: 5;
|
||||
uint8_t pad_8;
|
||||
uint16_t pad_16;
|
||||
} data_iv8_t;
|
||||
|
||||
typedef struct{
|
||||
union{
|
||||
data_iv8_t d;
|
||||
uint8_t iv[8];
|
||||
};
|
||||
} iv8_t;
|
||||
|
||||
typedef enum{
|
||||
AES_INITIALIZATION_VECTOR_8,
|
||||
AES_INITIALIZATION_VECTOR_16,
|
||||
|
||||
AES_INITIALIZATION_VECTOR_END,
|
||||
} iv_e;
|
||||
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
static_assert(0 != 0, "The struct iv_t needs little endianness");
|
||||
#endif
|
||||
|
||||
// static_assert((16 == sizeof(iv_t)) , "Initialization Vector needs to have an AES_BLOCK_SIZE" );
|
||||
|
||||
typedef struct {
|
||||
uint8_t key[16];
|
||||
iv_e type;
|
||||
union{
|
||||
iv8_t iv8;
|
||||
iv16_t iv16;
|
||||
};
|
||||
} aes_128_t;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
* 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 <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "aes_128_cbc_cmac.h"
|
||||
|
||||
#include "common/utils/assertions.h"
|
||||
#include <openssl/cmac.h>
|
||||
|
||||
#if OPENSSL_VERSION_MAJOR >= 3
|
||||
// code for version 3.0 or greater
|
||||
#include <openssl/core_names.h>
|
||||
|
||||
static
|
||||
const char *propq = NULL;
|
||||
|
||||
void aes_128_cbc_cmac(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out])
|
||||
{
|
||||
OSSL_LIB_CTX* library_context = OSSL_LIB_CTX_new();
|
||||
DevAssert(library_context != NULL);
|
||||
|
||||
/* Fetch the CMAC implementation */
|
||||
EVP_MAC* mac = EVP_MAC_fetch(library_context, "CMAC", propq);
|
||||
DevAssert(mac != NULL);
|
||||
|
||||
/* Create a context for the CMAC operation */
|
||||
EVP_MAC_CTX* mctx = EVP_MAC_CTX_new(mac);
|
||||
DevAssert(mctx != NULL);
|
||||
|
||||
// The underlying cipher to be used
|
||||
char cipher_name[] = "aes128";
|
||||
|
||||
OSSL_PARAM params[2] = {0};
|
||||
params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, cipher_name,
|
||||
sizeof(cipher_name));
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
|
||||
/* Initialise the CMAC operation */
|
||||
int rc = EVP_MAC_init(mctx, k_iv->key, sizeof(k_iv->key), params);
|
||||
DevAssert(rc != 0);
|
||||
|
||||
size_t sz_iv = 0;
|
||||
uint8_t* iv = NULL;
|
||||
if(k_iv->type == AES_INITIALIZATION_VECTOR_8){
|
||||
sz_iv = 8;
|
||||
iv = (uint8_t*)k_iv->iv8.iv;
|
||||
} else if(k_iv->type == AES_INITIALIZATION_VECTOR_16) {
|
||||
sz_iv = 16;
|
||||
iv = (uint8_t*)k_iv->iv16.iv;
|
||||
} else {
|
||||
DevAssert(0!=0 && "Unknwon Initialization vector");
|
||||
}
|
||||
|
||||
/* Make one or more calls to process the data to be authenticated */
|
||||
rc = EVP_MAC_update(mctx, iv, sz_iv);
|
||||
DevAssert(rc != 0);
|
||||
|
||||
/* Make one or more calls to process the data to be authenticated */
|
||||
rc = EVP_MAC_update(mctx, msg.buf, msg.len);
|
||||
DevAssert(rc != 0);
|
||||
|
||||
/* Make a call to the final with a NULL buffer to get the length of the MAC */
|
||||
size_t out_len = 0;
|
||||
rc = EVP_MAC_final(mctx, out, &out_len, len_out);
|
||||
DevAssert(rc != 0);
|
||||
|
||||
EVP_MAC_CTX_free(mctx);
|
||||
EVP_MAC_free(mac);
|
||||
OSSL_LIB_CTX_free(library_context);
|
||||
}
|
||||
|
||||
cbc_cmac_ctx_t init_aes_128_cbc_cmac(uint8_t key[16])
|
||||
{
|
||||
DevAssert(key != NULL);
|
||||
|
||||
OSSL_LIB_CTX* library_context = OSSL_LIB_CTX_new();
|
||||
DevAssert(library_context != NULL);
|
||||
|
||||
/* Fetch the CMAC implementation */
|
||||
EVP_MAC* mac = EVP_MAC_fetch(library_context, "CMAC", propq);
|
||||
DevAssert(mac != NULL);
|
||||
|
||||
cbc_cmac_ctx_t ctx = {.lib_ctx = library_context, .mac = mac };
|
||||
|
||||
assert(16 == sizeof(ctx.key));
|
||||
memcpy(ctx.key, key, 16);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void cipher_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx, const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out])
|
||||
{
|
||||
DevAssert(ctx != NULL);
|
||||
DevAssert(k_iv != NULL);
|
||||
/* Create a context for the CMAC operation */
|
||||
EVP_MAC_CTX* mctx = EVP_MAC_CTX_new(ctx->mac);
|
||||
DevAssert(mctx != NULL);
|
||||
|
||||
// The underlying cipher to be used
|
||||
char cipher_name[] = "aes128";
|
||||
|
||||
OSSL_PARAM params[2] = {0};
|
||||
params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, cipher_name,
|
||||
sizeof(cipher_name));
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
|
||||
/* Initialise the CMAC operation */
|
||||
int rc = EVP_MAC_init(mctx, k_iv->key, sizeof(k_iv->key), params);
|
||||
DevAssert(rc != 0);
|
||||
|
||||
size_t sz_iv = 0;
|
||||
uint8_t* iv = NULL;
|
||||
if(k_iv->type == AES_INITIALIZATION_VECTOR_8){
|
||||
sz_iv = 8;
|
||||
iv = (uint8_t*)k_iv->iv8.iv;
|
||||
} else if(k_iv->type == AES_INITIALIZATION_VECTOR_16) {
|
||||
sz_iv = 16;
|
||||
iv = (uint8_t*)k_iv->iv16.iv;
|
||||
} else {
|
||||
DevAssert(0!=0 && "Unknwon Initialization vector");
|
||||
}
|
||||
|
||||
/* Make one or more calls to process the data to be authenticated */
|
||||
rc = EVP_MAC_update(mctx, iv, sz_iv);
|
||||
DevAssert(rc != 0);
|
||||
|
||||
/* Make one or more calls to process the data to be authenticated */
|
||||
rc = EVP_MAC_update(mctx, msg.buf, msg.len);
|
||||
DevAssert(rc != 0);
|
||||
|
||||
/* Make a call to the final with a NULL buffer to get the length of the MAC */
|
||||
size_t out_len = 0;
|
||||
rc = EVP_MAC_final(mctx, out, &out_len, len_out);
|
||||
DevAssert(rc != 0);
|
||||
|
||||
EVP_MAC_CTX_free(mctx);
|
||||
}
|
||||
|
||||
void free_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx)
|
||||
{
|
||||
DevAssert(ctx != NULL);
|
||||
EVP_MAC_free(ctx->mac);
|
||||
OSSL_LIB_CTX_free(ctx->lib_ctx);
|
||||
}
|
||||
|
||||
#else
|
||||
// code for 1.1.x or lower
|
||||
|
||||
void aes_128_cbc_cmac(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out])
|
||||
{
|
||||
DevAssert(k_iv != NULL);
|
||||
|
||||
CMAC_CTX *ctx = CMAC_CTX_new();
|
||||
DevAssert(ctx != NULL);
|
||||
|
||||
CMAC_Init(ctx, k_iv->key, sizeof(k_iv->key), EVP_aes_128_cbc(), NULL);
|
||||
|
||||
size_t sz_iv = 0;
|
||||
uint8_t* iv = NULL;
|
||||
if(k_iv->type == AES_INITIALIZATION_VECTOR_8){
|
||||
sz_iv = 8;
|
||||
iv = (uint8_t*)k_iv->iv8.iv;
|
||||
} else if(k_iv->type == AES_INITIALIZATION_VECTOR_16) {
|
||||
sz_iv = 16;
|
||||
iv = (uint8_t*)k_iv->iv16.iv;
|
||||
} else {
|
||||
DevAssert(0!=0 && "Unknwon Initialization vector");
|
||||
}
|
||||
|
||||
CMAC_Update(ctx, iv, sz_iv);
|
||||
|
||||
CMAC_Update(ctx, msg.buf, msg.len);
|
||||
size_t len_res = 0;
|
||||
CMAC_Final(ctx, out, &len_res);
|
||||
DevAssert(len_res <= len_out);
|
||||
|
||||
CMAC_CTX_free(ctx);
|
||||
}
|
||||
|
||||
cbc_cmac_ctx_t init_aes_128_cbc_cmac(uint8_t key[16])
|
||||
{
|
||||
DevAssert(key != NULL);
|
||||
cbc_cmac_ctx_t ctx = {.lib_ctx = NULL, .mac = NULL };
|
||||
|
||||
ctx.mac = CMAC_CTX_new();
|
||||
DevAssert(ctx.mac != NULL);
|
||||
|
||||
//assert(16 == sizeof(ctx.key));
|
||||
memcpy(ctx.key, key, 16); //sizeof(ctx.key));
|
||||
|
||||
CMAC_Init(ctx.mac, ctx.key, 16, EVP_aes_128_cbc(), NULL);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void cipher_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx, const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out])
|
||||
{
|
||||
DevAssert(ctx != NULL);
|
||||
DevAssert(k_iv != NULL);
|
||||
|
||||
//From https://man.openbsd.org/CMAC_Init.3
|
||||
//If ctx is already initialized, CMAC_Init() can be called again with key,
|
||||
//cipher, and impl all set to NULL and key_len set to 0. In that case, any
|
||||
//data already processed is discarded and ctx is re-initialized to start
|
||||
//reading data anew.
|
||||
CMAC_Init(ctx->mac, NULL, 0, NULL, NULL);
|
||||
|
||||
size_t sz_iv = 0;
|
||||
uint8_t* iv = NULL;
|
||||
if(k_iv->type == AES_INITIALIZATION_VECTOR_8){
|
||||
sz_iv = 8;
|
||||
iv = (uint8_t*)k_iv->iv8.iv;
|
||||
} else if(k_iv->type == AES_INITIALIZATION_VECTOR_16) {
|
||||
sz_iv = 16;
|
||||
iv = (uint8_t*)k_iv->iv16.iv;
|
||||
} else {
|
||||
DevAssert(0!=0 && "Unknwon Initialization vector");
|
||||
}
|
||||
|
||||
CMAC_Update(ctx->mac, iv, sz_iv);
|
||||
|
||||
CMAC_Update(ctx->mac, msg.buf, msg.len);
|
||||
size_t len_res = 0;
|
||||
CMAC_Final(ctx->mac, out, &len_res);
|
||||
DevAssert(len_res <= len_out);
|
||||
}
|
||||
|
||||
void free_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx)
|
||||
{
|
||||
DevAssert(ctx != NULL);
|
||||
CMAC_CTX_free(ctx->mac);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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_CBC_CMAC_H
|
||||
#define AES_128_CBC_CMAC_H
|
||||
|
||||
#include "aes_128.h"
|
||||
#include "common/utils/ds/byte_array.h"
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct {
|
||||
void* lib_ctx;
|
||||
void* mac;
|
||||
uint8_t key[16];
|
||||
} cbc_cmac_ctx_t ;
|
||||
|
||||
void aes_128_cbc_cmac(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]);
|
||||
|
||||
cbc_cmac_ctx_t init_aes_128_cbc_cmac(uint8_t key[16]);
|
||||
|
||||
void cipher_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx, const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]);
|
||||
|
||||
void free_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
// TS 133 401 pag. 88
|
||||
|
||||
#include "aes_128_ctr.h"
|
||||
#include "common/utils/assertions.h"
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
void aes_128_ctr(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out])
|
||||
{
|
||||
DevAssert(k_iv != NULL);
|
||||
|
||||
DevAssert(sizeof(iv16_t) == AES_BLOCK_SIZE);
|
||||
DevAssert(k_iv->type == AES_INITIALIZATION_VECTOR_16);
|
||||
|
||||
// Create and initialise the context
|
||||
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
|
||||
DevAssert(ctx != NULL);
|
||||
|
||||
// Set IV length if default 12 bytes (96 bits) is not appropriate
|
||||
// int rc = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CTR_SET_IVLEN, 16, NULL))
|
||||
|
||||
// Initialise the encryption operation.
|
||||
int rc = EVP_EncryptInit_ex(ctx, EVP_aes_128_ctr(), NULL, k_iv->key, k_iv->iv16.iv);
|
||||
DevAssert(rc == 1);
|
||||
|
||||
OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) == AES_BLOCK_SIZE);
|
||||
|
||||
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,33 @@
|
||||
/*
|
||||
* 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_CTR_OAI_H
|
||||
#define AES_128_CTR_OAI_H
|
||||
|
||||
#include "aes_128.h"
|
||||
#include "common/utils/ds/byte_array.h"
|
||||
#include <endian.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void aes_128_ctr(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]);
|
||||
|
||||
#endif
|
||||
+6
-75
@@ -19,87 +19,18 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "common/utils/assertions.h"
|
||||
#include "openair3/SECU/sha_256_hmac.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nettle/hmac.h>
|
||||
|
||||
#include "security_types.h"
|
||||
#include "secu_defs.h"
|
||||
#include "kdf.h"
|
||||
|
||||
void kdf(const uint8_t *key, uint16_t key_len, uint8_t *s, uint16_t s_len, uint8_t *out,
|
||||
uint16_t out_len)
|
||||
void kdf(const uint8_t key[32], byte_array_t data, size_t len, uint8_t out[len])
|
||||
{
|
||||
struct hmac_sha256_ctx ctx;
|
||||
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
|
||||
hmac_sha256_set_key(&ctx, key_len, key);
|
||||
hmac_sha256_update(&ctx, s_len, s);
|
||||
hmac_sha256_digest(&ctx, out_len, out);
|
||||
// Do we still need kdf function?
|
||||
sha_256_hmac(key, data, len, out);
|
||||
}
|
||||
|
||||
#ifndef NAS_UE
|
||||
int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB)
|
||||
{
|
||||
uint8_t s[7];
|
||||
|
||||
// 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);
|
||||
|
||||
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};
|
||||
|
||||
// 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);
|
||||
} 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);
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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 KEY_DERIVATION_FUNCTION_OSA_H
|
||||
#define KEY_DERIVATION_FUNCTION_OSA_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "byte_array.h"
|
||||
|
||||
void kdf(const uint8_t key[32], byte_array_t data, size_t len, uint8_t out[len]);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "security_types.h"
|
||||
#include "secu_defs.h"
|
||||
#include "kdf.h"
|
||||
|
||||
#define SECU_DEBUG 1
|
||||
/*!
|
||||
@@ -79,7 +80,9 @@ int derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
kdf(kasme, 32, s, 7, out, 32);
|
||||
//kdf(kasme, 32, s, 7, out, 32);
|
||||
byte_array_t data = {.len = 7, .buf = s};
|
||||
kdf(kasme, data, 32, out);
|
||||
|
||||
memcpy(knas, &out[31-16+1], 16);
|
||||
|
||||
|
||||
@@ -24,10 +24,6 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nettle/nettle-meta.h>
|
||||
#include <nettle/aes.h>
|
||||
#include <nettle/ctr.h>
|
||||
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
#include "secu_defs.h"
|
||||
|
||||
@@ -19,84 +19,40 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nettle/nettle-meta.h>
|
||||
#include <nettle/aes.h>
|
||||
#include <nettle/ctr.h>
|
||||
|
||||
#include "aes_128_ctr.h"
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
#include "secu_defs.h"
|
||||
|
||||
// #define SECU_DEBUG
|
||||
|
||||
int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t *out)
|
||||
{
|
||||
uint8_t m[16];
|
||||
uint32_t local_count;
|
||||
|
||||
void *ctx;
|
||||
uint8_t *data;
|
||||
|
||||
uint32_t zero_bit = 0;
|
||||
uint32_t byte_length;
|
||||
|
||||
DevAssert(stream_cipher != NULL);
|
||||
DevAssert(out != NULL);
|
||||
DevAssert(stream_cipher->key != NULL);
|
||||
DevAssert(stream_cipher->key_length == 32);
|
||||
DevAssert(stream_cipher->bearer < 32);
|
||||
DevAssert(stream_cipher->direction < 2);
|
||||
DevAssert(stream_cipher->message != NULL);
|
||||
DevAssert(stream_cipher->blength > 7);
|
||||
|
||||
zero_bit = stream_cipher->blength & 0x7;
|
||||
aes_128_t p = {0};
|
||||
memcpy(p.key, stream_cipher->key, stream_cipher->key_length);
|
||||
p.type = AES_INITIALIZATION_VECTOR_16;
|
||||
p.iv16.d.count = htonl(stream_cipher->count);
|
||||
p.iv16.d.bearer = stream_cipher->bearer;
|
||||
p.iv16.d.direction = stream_cipher->direction;
|
||||
|
||||
byte_length = stream_cipher->blength >> 3;
|
||||
|
||||
if (zero_bit > 0)
|
||||
byte_length += 1;
|
||||
|
||||
ctx = malloc(nettle_aes128.context_size);
|
||||
data = malloc(byte_length);
|
||||
|
||||
local_count = hton_int32(stream_cipher->count);
|
||||
|
||||
memset(m, 0, sizeof(m));
|
||||
memcpy(&m[0], &local_count, 4);
|
||||
m[4] = ((stream_cipher->bearer & 0x1F) << 3) |
|
||||
((stream_cipher->direction & 0x01) << 2);
|
||||
/* Other bits are 0 */
|
||||
|
||||
#if defined(SECU_DEBUG)
|
||||
{
|
||||
int i;
|
||||
printf("Blength: %u, Zero bits: %u\n", stream_cipher->blength, zero_bit);
|
||||
|
||||
for (i = 0; i < sizeof(m); i++)
|
||||
printf("0x%02x ", m[i]);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NETTLE_VERSION_MAJOR < 3
|
||||
nettle_aes128.set_encrypt_key(ctx, stream_cipher->key_length,
|
||||
stream_cipher->key);
|
||||
#else
|
||||
nettle_aes128.set_encrypt_key(ctx,
|
||||
stream_cipher->key);
|
||||
#endif
|
||||
|
||||
nettle_ctr_crypt(ctx, nettle_aes128.encrypt,
|
||||
nettle_aes128.block_size, m,
|
||||
byte_length, data, stream_cipher->message);
|
||||
|
||||
if (zero_bit > 0)
|
||||
data[byte_length - 1] = data[byte_length - 1] & (uint8_t)(0xFF << (8 - zero_bit));
|
||||
|
||||
|
||||
memcpy(out, data, byte_length);
|
||||
free(data);
|
||||
free(ctx);
|
||||
DevAssert((stream_cipher->blength & 0x07) == 0);
|
||||
const uint32_t byte_lenght = stream_cipher->blength >> 3;
|
||||
// Precondition: out must have enough space, at least as much as the input
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
@@ -26,15 +27,8 @@
|
||||
|
||||
#include "secu_defs.h"
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/cmac.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
// test
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bio.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include "aes_128_cbc_cmac.h"
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
|
||||
@@ -45,84 +39,28 @@
|
||||
* @param[in] stream_cipher Structure containing various variables to setup encoding
|
||||
* @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])
|
||||
{
|
||||
uint8_t *m = NULL;
|
||||
uint32_t local_count;
|
||||
size_t size = 4;
|
||||
uint8_t data[16];
|
||||
CMAC_CTX *cmac_ctx = NULL;
|
||||
const EVP_CIPHER *cipher = EVP_aes_128_cbc();
|
||||
uint32_t zero_bit = 0;
|
||||
uint32_t m_length;
|
||||
int ret;
|
||||
|
||||
DevAssert(stream_cipher != NULL);
|
||||
DevAssert(stream_cipher->key != NULL);
|
||||
DevAssert(stream_cipher->key_length > 0);
|
||||
DevAssert(out != NULL);
|
||||
DevAssert(stream_cipher->message != NULL);
|
||||
DevAssert(stream_cipher->bearer < 32);
|
||||
DevAssert(stream_cipher->key_length == 16);
|
||||
DevAssert((stream_cipher->blength & 0x7) == 0);
|
||||
|
||||
memset(data, 0, 16);
|
||||
|
||||
zero_bit = stream_cipher->blength & 0x7;
|
||||
|
||||
m_length = stream_cipher->blength >> 3;
|
||||
|
||||
if (zero_bit > 0)
|
||||
m_length += 1;
|
||||
|
||||
local_count = hton_int32(stream_cipher->count);
|
||||
|
||||
m = calloc(m_length + 8, sizeof(uint8_t));
|
||||
|
||||
memcpy(&m[0], &local_count, 4);
|
||||
m[4] = ((stream_cipher->bearer & 0x1F) << 3) | ((stream_cipher->direction & 0x01) << 2);
|
||||
|
||||
memcpy(&m[8], stream_cipher->message, m_length);
|
||||
|
||||
#if defined(SECU_DEBUG)
|
||||
{
|
||||
int i;
|
||||
printf("Byte length: %u, Zero bits: %u\nm: ", m_length + 8, zero_bit);
|
||||
|
||||
for (i = 0; i < m_length + 8; i++)
|
||||
printf("%02x", m[i]);
|
||||
|
||||
printf("\nKey:");
|
||||
|
||||
for (i = 0; i < stream_cipher->key_length; i++)
|
||||
printf("%02x", stream_cipher->key[i]);
|
||||
|
||||
printf("\nMessage:");
|
||||
|
||||
for (i = 0; i < m_length; i++)
|
||||
printf("%02x", stream_cipher->message[i]);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
cmac_ctx = CMAC_CTX_new();
|
||||
ret = CMAC_Init(cmac_ctx, stream_cipher->key, stream_cipher->key_length, cipher, NULL);
|
||||
ret = CMAC_Update(cmac_ctx, m, m_length + 8);
|
||||
(void)ret; /* avoid gcc warning "set but not used" */
|
||||
CMAC_Final(cmac_ctx, data, &size);
|
||||
CMAC_CTX_free(cmac_ctx);
|
||||
|
||||
#if defined(SECU_DEBUG)
|
||||
{
|
||||
int i;
|
||||
printf("out: ");
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%02x", data[i]);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
memcpy(out, data, 4);
|
||||
free(m);
|
||||
aes_128_t k_iv = {0};
|
||||
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;
|
||||
k_iv.iv8.d.count = htonl(stream_cipher->count);
|
||||
|
||||
size_t const m_length = stream_cipher->blength >> 3;
|
||||
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,96 @@
|
||||
/*
|
||||
* 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 "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)
|
||||
{
|
||||
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;
|
||||
} 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "security_types.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define EIA0_ALG_ID 0x00
|
||||
#define EIA1_128_ALG_ID 0x01
|
||||
@@ -36,13 +37,6 @@
|
||||
#define SECU_DIRECTION_UPLINK 0
|
||||
#define SECU_DIRECTION_DOWNLINK 1
|
||||
|
||||
void kdf(const uint8_t *key,
|
||||
uint16_t key_len,
|
||||
uint8_t *s,
|
||||
uint16_t s_len,
|
||||
uint8_t *out,
|
||||
uint16_t out_len);
|
||||
|
||||
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,
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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 "common/utils/assertions.h"
|
||||
#include "sha_256_hmac.h"
|
||||
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
#if OPENSSL_VERSION_MAJOR >= 3
|
||||
// code for version 3.0 or greater
|
||||
|
||||
#include <openssl/core_names.h>
|
||||
|
||||
void sha_256_hmac(const uint8_t key[32], byte_array_t data, size_t len, uint8_t out[len])
|
||||
{
|
||||
DevAssert(key != NULL);
|
||||
DevAssert(data.buf != NULL);
|
||||
DevAssert(data.len != 0);
|
||||
DevAssert(len != 0);
|
||||
|
||||
OSSL_LIB_CTX* library_context = OSSL_LIB_CTX_new();
|
||||
DevAssert(library_context != NULL);
|
||||
|
||||
// A property query used for selecting the MAC implementation.
|
||||
const char* propq = NULL;
|
||||
// Fetch the HMAC implementation
|
||||
EVP_MAC* mac = EVP_MAC_fetch(library_context, "HMAC", propq);
|
||||
DevAssert(mac != NULL);
|
||||
|
||||
// Create a context for the HMAC operation
|
||||
EVP_MAC_CTX* mctx = EVP_MAC_CTX_new(mac);
|
||||
DevAssert(mctx != NULL);
|
||||
|
||||
// The underlying digest to be used
|
||||
OSSL_PARAM params[2] = {0};
|
||||
char digest_name[] = "SHA2-256";
|
||||
params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, digest_name, sizeof(digest_name));
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
|
||||
// Initialise the HMAC operation
|
||||
int rc = EVP_MAC_init(mctx, key, 32, params);
|
||||
DevAssert(rc == 1);
|
||||
|
||||
// Make one or more calls to process the data to be authenticated
|
||||
rc = EVP_MAC_update(mctx, data.buf, data.len);
|
||||
DevAssert(rc == 1);
|
||||
|
||||
// Make one call to the final to get the MAC
|
||||
rc = EVP_MAC_final(mctx, out, &len, len);
|
||||
DevAssert(rc == 1);
|
||||
|
||||
// OpenSSL free functions will ignore NULL arguments
|
||||
EVP_MAC_CTX_free(mctx);
|
||||
EVP_MAC_free(mac);
|
||||
OSSL_LIB_CTX_free(library_context);
|
||||
}
|
||||
#else
|
||||
// code for 1.1.x or lower
|
||||
void sha_256_hmac(const uint8_t key[32], byte_array_t data, size_t len, uint8_t out[len])
|
||||
{
|
||||
DevAssert(key != NULL);
|
||||
DevAssert(data.buf != NULL);
|
||||
DevAssert(data.len != 0);
|
||||
DevAssert(len != 0);
|
||||
|
||||
HMAC_CTX* ctx = HMAC_CTX_new();
|
||||
|
||||
HMAC_Init_ex(ctx, key, 32, EVP_sha256(), NULL);
|
||||
|
||||
HMAC_Update(ctx, data.buf, data.len);
|
||||
|
||||
HMAC_Final(ctx, out, (uint32_t*)&len);
|
||||
|
||||
HMAC_CTX_free(ctx);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 SHA_256_HMAC_OAI_H
|
||||
#define SHA_256_HMAC_OAI_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "byte_array.h"
|
||||
|
||||
void sha_256_hmac(const uint8_t key[32], byte_array_t data, size_t len, uint8_t out[len]);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user