30#include <openssl/err.h>
31#include <openssl/rand.h>
47 EVP_PKEY_free(key->
pkey);
54#define M_OPL_BSLB_CryptoKey_t() M_OPEXTEND(M_POD_OPLIST, CLEAR(API_2(BSLB_CryptoKey_Deinit)))
56DICT_DEF2(BSLB_CryptoKeyDict, uint64_t, M_BASIC_OPLIST,
BSLB_CryptoKey_t, M_OPL_BSLB_CryptoKey_t())
61static pthread_mutex_t StaticCryptoMutex = PTHREAD_MUTEX_INITIALIZER;
77 const EVP_CIPHER *cipher = (aes_variant == BSL_CRYPTO_AES_128) ? EVP_aes_128_wrap() : EVP_aes_256_wrap();
78 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
83 uint8_t *key = &keybuf[16];
84 memset(keybuf, 0,
sizeof(keybuf));
90 int dec_result = EVP_DecryptInit_ex(ctx, cipher, NULL, key, NULL);
91 assert(dec_result == 1);
92 EVP_CIPHER_CTX_set_padding(ctx, 0);
94 int unwrapped_key_len = 16;
95 int decrypt_res = EVP_DecryptUpdate(ctx, unwrapped_key_output->
ptr, &unwrapped_key_len, wrapped_key_plaintext.
ptr,
96 (
int)wrapped_key_plaintext.
len);
99 BSL_LOG_ERR(
"EVP_DecryptUpdate: %s", ERR_error_string(ERR_get_error(), NULL));
100 EVP_CIPHER_CTX_free(ctx);
104 unwrapped_key_output->
len = (size_t)unwrapped_key_len;
107 int res = EVP_DecryptFinal_ex(ctx, &unwrapped_key_output->
ptr[unwrapped_key_output->
len], &final_len);
110 BSL_LOG_ERR(
"Failed DecryptFinal: %s", ERR_error_string(ERR_get_error(), NULL));
111 EVP_CIPHER_CTX_free(ctx);
114 unwrapped_key_output->
len += (size_t)final_len;
116 EVP_CIPHER_CTX_free(ctx);
122 const EVP_CIPHER *cipher = (aes_variant == BSL_CRYPTO_AES_128) ? EVP_aes_128_wrap() : EVP_aes_256_wrap();
123 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
131 uint8_t *key = &keybuf[16];
132 memset(keybuf, 0,
sizeof(keybuf));
138 assert(got_crypto_key == 0);
141 int enc_result = EVP_EncryptInit_ex(ctx, cipher, NULL, cek.
ptr, NULL);
144 EVP_CIPHER_CTX_free(ctx);
148 int len = (int)wrapped_key->
len;
149 if (!EVP_EncryptUpdate(ctx, wrapped_key->
ptr, &len,
153 EVP_CIPHER_CTX_free(ctx);
157 wrapped_key->
len = (size_t)len;
159 if (!EVP_EncryptFinal_ex(ctx, &wrapped_key->
ptr[wrapped_key->
len], &final_len))
161 EVP_CIPHER_CTX_free(ctx);
164 wrapped_key->
len += (size_t)final_len;
165 EVP_CIPHER_CTX_free(ctx);
171 CHK_ARG_NONNULL(hmac_ctx);
174 CHK_PRECONDITION(hmac_ctx->
libhandle != NULL);
178 const EVP_MD *sha = NULL;
181 case BSL_CRYPTO_SHA_256:
184 case BSL_CRYPTO_SHA_384:
187 case BSL_CRYPTO_SHA_512:
195 pthread_mutex_lock(&StaticCryptoMutex);
197 if (key_info == NULL)
200 BSL_LOG_ERR(
"Failed to lookup Key ID %" PRId64, keyid);
201 pthread_mutex_unlock(&StaticCryptoMutex);
205 int res = EVP_DigestSignInit(hmac_ctx->
libhandle, NULL, sha, NULL, key_info->
pkey);
206 pthread_mutex_unlock(&StaticCryptoMutex);
207 CHK_PROPERTY(res == 1);
216 assert(data != NULL);
217 int res = EVP_DigestSignUpdate(hmac_ctx->
libhandle, data, data_len);
218 CHK_PROPERTY(res == 1);
231 EVP_DigestSignUpdate(hmac_ctx->
libhandle, buf, block_size);
240 int res = EVP_DigestSignFinal(hmac_ctx->
libhandle, NULL, &req);
241 CHK_PROPERTY(res == 1);
244 res = EVP_DigestSignFinal(hmac_ctx->
libhandle, *hmac, hmac_len);
245 CHK_PROPERTY(res == 1);
257 const void *init_vec,
int iv_len,
BSL_Data_t content_enc_key)
259 assert(cipher_ctx != NULL);
260 assert(init_vec != NULL);
261 assert(content_enc_key.
ptr != NULL);
262 assert(content_enc_key.
len > 0);
264 cipher_ctx->
libhandle = EVP_CIPHER_CTX_new();
265 cipher_ctx->
enc = enc;
268 const EVP_CIPHER *cipher = NULL;
271 case BSL_CRYPTO_AES_128:
272 cipher = EVP_aes_128_gcm();
274 case BSL_CRYPTO_AES_256:
275 cipher = EVP_aes_256_gcm();
283 CHK_PROPERTY(res == 1);
287 res = EVP_CIPHER_CTX_ctrl(cipher_ctx->
libhandle, EVP_CTRL_GCM_SET_IVLEN, iv_len, NULL);
288 CHK_PROPERTY(res == 1);
290 res = EVP_CipherInit_ex(cipher_ctx->
libhandle, NULL, NULL, content_enc_key.
ptr, init_vec, -1);
291 CHK_PROPERTY(res == 1);
300 int res = EVP_CipherUpdate(cipher_ctx->
libhandle, NULL, &len, aad, aad_len);
301 CHK_PROPERTY(res == 1);
307 assert(cipher_ctx != NULL);
308 int cipherlen = (int)ciphertext.
len;
309 if (EVP_CipherUpdate(cipher_ctx->
libhandle, ciphertext.
ptr, &cipherlen, plaintext.
ptr, (
int)plaintext.
len) != 1)
322 while (block_size == (cipher_ctx->
block_size))
325 int block_size_int = (int)block_size;
326 int res = EVP_CipherUpdate(cipher_ctx->
libhandle, write_buf, &block_size_int, read_buf, block_size_int);
327 CHK_PROPERTY(res == 1);
328 block_size = (size_t)block_size_int;
337 int res = EVP_CIPHER_CTX_ctrl(cipher_ctx->
libhandle, EVP_CTRL_GCM_GET_TAG, BSL_CRYPTO_AESGCM_AUTH_TAG_LEN, *tag);
338 CHK_PROPERTY(res == 1);
345 EVP_CIPHER_CTX_ctrl(cipher_ctx->
libhandle, EVP_CTRL_GCM_SET_TAG, BSL_CRYPTO_AESGCM_AUTH_TAG_LEN, (
void *)tag);
346 BSL_LOG_INFO(
"Completed EVP_CIPHER_CTX_ctrl *tag=%p", (uint8_t *)tag);
347 CHK_PROPERTY(res == 1);
354 CHK_ARG_NONNULL(cipher_ctx);
355 CHK_ARG_EXPR(extra->
ptr != NULL);
356 uint8_t buf[EVP_CIPHER_CTX_block_size(cipher_ctx->
libhandle)];
357 CHK_PRECONDITION(extra->
len >=
sizeof(buf));
362 int res = EVP_CipherFinal_ex(cipher_ctx->
libhandle, buf, &len);
365 BSL_LOG_ERR(
"%s", ERR_error_string(ERR_get_error(), NULL));
367 CHK_PROPERTY(res == 1);
369 memset(extra->
ptr, 0, extra->
len);
373 memcpy(extra->
ptr, buf,
sizeof(buf));
382 uint8_t buf[EVP_CIPHER_CTX_block_size(cipher_ctx->
libhandle)];
385 int res = EVP_CipherFinal_ex(cipher_ctx->
libhandle, buf, &len);
386 CHK_PROPERTY(res == 1);
398 CHK_ARG_NONNULL(cipher_ctx);
399 EVP_CIPHER_CTX_free(cipher_ctx->
libhandle);
400 memset(cipher_ctx, 0,
sizeof(*cipher_ctx));
404int BSL_Crypto_GenKey(uint8_t *key_buffer,
size_t key_length)
406 CHK_ARG_NONNULL(key_buffer);
407 CHK_ARG_EXPR(key_length == 16 || key_length == 32);
409 int key_length_int = (int)key_length;
410 if (RAND_bytes(key_buffer, key_length_int) != 1)
412 OPENSSL_cleanse(key_buffer, key_length_int);
421 CHK_ARG_NONNULL(buf);
422 if (!(size >= 8 && size <= 16))
427 memset(buf, 0, size);
428 CHK_PROPERTY(RAND_bytes((
unsigned char *)buf, size) == 1);
434 CHK_ARG_NONNULL(secret);
435 CHK_ARG_EXPR(secret_len > 0);
438 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HMAC, NULL);
439 int res = EVP_PKEY_keygen_init(ctx);
440 CHK_PROPERTY(res == 1);
442 key.
pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, secret, (
int)secret_len);
443 EVP_PKEY_CTX_free(ctx);
454 pthread_mutex_lock(&StaticCryptoMutex);
456 pthread_mutex_unlock(&StaticCryptoMutex);
463 CHK_ARG_NONNULL(secret);
466 pthread_mutex_lock(&StaticCryptoMutex);
478 *secret_len = found->
raw.
len;
481 pthread_mutex_unlock(&StaticCryptoMutex);
Single entry-point include file for all of the BPSec Lib (BSL) frontend API.
#define BSL_LOG_DEBUG(...)
This is an overloaded member function, provided for convenience. It differs from the above function o...
#define BSL_LOG_INFO(...)
This is an overloaded member function, provided for convenience. It differs from the above function o...
#define BSL_LOG_ERR(...)
This is an overloaded member function, provided for convenience. It differs from the above function o...
@ BSL_ERR_NOT_FOUND
Requested value not found for key.
@ BSL_SUCCESS
Placeholder for non-error code.
@ BSL_ERR_FAILURE
Uncategorized failed (prefer to avoid)
int BSL_AuthCtx_Finalize(BSL_AuthCtx_t *hmac_ctx, void **hmac, size_t *hmac_len)
Finalize HMAC tag.
int BSL_AuthCtx_Init(BSL_AuthCtx_t *hmac_ctx, uint64_t keyid, BSL_CryptoCipherSHAVariant_e sha_var)
Initialize HMAC context resources and set private key and SHA variant.
int BSL_AuthCtx_DigestBuffer(BSL_AuthCtx_t *hmac_ctx, const void *data, size_t data_len)
Input data to HMAC sign to context.
int BSL_Crypto_GenIV(void *buf, int size)
Generate initialization vector (IV) for AES-GCM for BCBs.
int BSL_AuthCtx_DigestSeq(BSL_AuthCtx_t *hmac_ctx, BSL_SeqReader_t *reader)
Input data to HMAC sign to context.
int BSL_Crypto_AddRegistryKey(uint64_t keyid, const uint8_t *secret, size_t secret_len)
Add a new key to the crypto key registry.
int BSL_Cipher_AddData(BSL_Cipher_t *cipher_ctx, BSL_Data_t plaintext, BSL_Data_t ciphertext)
int BSL_AuthCtx_Deinit(BSL_AuthCtx_t *hmac_ctx)
Deinitialize HMAC context resources.
int BSLB_Crypto_GetRegistryKey(uint64_t keyid, const uint8_t **secret, size_t *secret_len)
Get pointers to an existing key, if present.
int BSL_Cipher_Init(BSL_Cipher_t *cipher_ctx, BSL_CipherMode_e enc, BSL_CryptoCipherAESVariant_e aes_var, const void *init_vec, int iv_len, BSL_Data_t content_enc_key)
Initialize crypto context resources and set as encoding or decoding.
struct BSLB_CryptoKey_s BSLB_CryptoKey_t
Struct to hold private key information.
static BSLB_CryptoKeyDict_t StaticKeyRegistry
Crypto key registry.
int BSL_Crypto_WrapKey(BSL_Data_t *wrapped_key, BSL_Data_t cek, size_t content_key_id, size_t aes_variant)
void BSL_CryptoInit(void)
Initialize the crypto subsystem.
int BSL_Cipher_Deinit(BSL_Cipher_t *cipher_ctx)
De-initialize crypto context resources.
int BSL_Cipher_FinalizeSeq(BSL_Cipher_t *cipher_ctx, BSL_SeqWriter_t *writer)
Finalize crypto operation.
int BSL_Cipher_AddAAD(BSL_Cipher_t *cipher_ctx, const void *aad, int aad_len)
Add additional authenticated data (AAD) to cipher context.
int BSL_Crypto_UnwrapKey(BSL_Data_t *unwrapped_key_output, BSL_Data_t wrapped_key_plaintext, size_t key_id, size_t aes_variant)
void BSL_CryptoDeinit(void)
Deinitialize the crypto subsystem.
int BSL_Cipher_SetTag(BSL_Cipher_t *cipher_ctx, const void *tag)
Set the tag of the crypto operation.
int BSL_Cipher_GetTag(BSL_Cipher_t *cipher_ctx, void **tag)
Get the tag of the crypto operation.
int BSL_Cipher_AddSeq(BSL_Cipher_t *cipher_ctx, BSL_SeqReader_t *reader, BSL_SeqWriter_t *writer)
Add data to encrypt or decrypt to the context sequentially.
Abstract interface for crypto processing.
BSL_CipherMode_e
Enum def to define cipher contexts as encryption or decryption operations.
@ BSL_CRYPTO_ENCRYPT
We use undefined for zero, in case this value is never explicitly set and is just zero by default.
int BSL_Data_Deinit(BSL_Data_t *data)
De-initialize a data struct, freeing if necessary.
int BSL_Data_CopyFrom(BSL_Data_t *data, size_t len, BSL_DataConstPtr_t src)
Set an initialized data struct to a given size.
int BSL_Data_Init(BSL_Data_t *data)
Initialize an empty data struct.
int BSL_SeqWriter_Put(BSL_SeqWriter_t *obj, const uint8_t *buf, size_t *bufsize)
Iterate a sequential writer.
int BSL_SeqReader_Get(BSL_SeqReader_t *obj, uint8_t *buf, size_t *bufsize)
Iterate a sequential reader.
Struct to hold private key information.
EVP_PKEY * pkey
Pointer to OpenSSL PKEY struct (used in hmac ctx)
BSL_Data_t raw
Pointer to raw key information (used in cipher ctx)
Struct def for HMAC operation context.
size_t block_size
Block size used by backend.
void * libhandle
pointer to library specific data
BSL_CryptoCipherSHAVariant_e SHA_variant
SHA variant of context.
Struct def for cipher operation context.
BSL_CipherMode_e enc
indicates if operation is encryption or decryption
BSL_CryptoCipherAESVariant_e AES_variant
AES variant of context.
size_t block_size
block size of cipher context
void * libhandle
pointer to library specific data
Heap data storage and views.
size_t len
Size of the data buffer.
BSL_DataPtr_t ptr
Pointer to the front of the buffer.
Definition of a simple flat buffer iterator.
Definition of a simple flat buffer iterator.