Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/BSLConfig.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ const char * bsl_version(void);
*/
#cmakedefine HAVE_CLOCK_GETTIME


#ifdef __cplusplus
} // extern C
#endif
Expand Down
15 changes: 15 additions & 0 deletions src/CryptoInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,14 @@ typedef struct BSL_Cipher_s
size_t block_size;
} BSL_Cipher_t;

/**
* Function pointer def for random bytestring generator
* @param buf buffer to fill with random bytes
* @param len size of random buffer
* @return 1 if success, 0 if failure
*/
typedef int (*BSL_Crypto_RandBytesFn)(unsigned char *buf, int len);

/** Initialize the crypto subsystem.
* This must be called once per process.
*/
Expand All @@ -133,6 +141,13 @@ void BSL_CryptoInit(void);
*/
void BSL_CryptoDeinit(void);

/**
* Set RNG generator to be used by crypto library
* @param[in] rand_gen_fn random bytes generation function.
* @warning Intended to be used only for testing. Providing an alternative RNG may break FIPS-140 compatibility
*/
void BSL_Crypto_SetRngGenerator(BSL_Crypto_RandBytesFn rand_gen_fn);

/**
* Initialize HMAC context resources and set private key and SHA variant
* @param[in,out] hmac_ctx pointer to hmac context struct to init and set
Expand Down
27 changes: 17 additions & 10 deletions src/crypto/CryptoInterface.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ static int BSLB_CryptoKey_Deinit(BSLB_CryptoKey_t *key)
DICT_DEF2(BSLB_CryptoKeyDict, string_t, STRING_OPLIST, BSLB_CryptoKey_t, M_OPL_BSLB_CryptoKey_t())
/// @endcond

/// Random bytes generator
static BSL_Crypto_RandBytesFn rand_bytes_generator;

/// Crypto key registry
static BSLB_CryptoKeyDict_t StaticKeyRegistry;
static pthread_mutex_t StaticCryptoMutex = PTHREAD_MUTEX_INITIALIZER;
Expand All @@ -65,13 +68,19 @@ static pthread_mutex_t StaticCryptoMutex = PTHREAD_MUTEX_INITIALIZER;
void BSL_CryptoInit(void)
{
BSLB_CryptoKeyDict_init(StaticKeyRegistry);
rand_bytes_generator = RAND_bytes;
}

void BSL_CryptoDeinit(void)
{
BSLB_CryptoKeyDict_clear(StaticKeyRegistry);
}

void BSL_Crypto_SetRngGenerator(BSL_Crypto_RandBytesFn rand_gen_fn)
{
rand_bytes_generator = rand_gen_fn;
}

int BSL_Crypto_UnwrapKey(BSL_Data_t *unwrapped_key_output, BSL_Data_t wrapped_key_plaintext, const char *key_id,
size_t aes_variant)
{
Expand Down Expand Up @@ -118,7 +127,7 @@ int BSL_Crypto_UnwrapKey(BSL_Data_t *unwrapped_key_output, BSL_Data_t wrapped_ke
return 0;
}

int BSL_Crypto_WrapKey(BSL_Data_t *wrapped_key, BSL_Data_t cek, const char *content_key_id, size_t aes_variant)
int BSL_Crypto_WrapKey(BSL_Data_t *wrapped_key, BSL_Data_t cek, const char *kek_id, size_t aes_variant)
{
const EVP_CIPHER *cipher = (aes_variant == BSL_CRYPTO_AES_128) ? EVP_aes_128_wrap() : EVP_aes_256_wrap();
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
Expand All @@ -134,22 +143,20 @@ int BSL_Crypto_WrapKey(BSL_Data_t *wrapped_key, BSL_Data_t cek, const char *cont
size_t keylen = 64;

// TODO(bvb) replace w error checking
BSL_LOG_INFO("Content key ID = %lu", cek);
int got_crypto_key = BSLB_Crypto_GetRegistryKey(content_key_id, (const uint8_t **)&key, &keylen);
int got_crypto_key = BSLB_Crypto_GetRegistryKey(kek_id, (const uint8_t **)&key, &keylen);

assert(got_crypto_key == 0);
assert(keylen > 0);

int enc_result = EVP_EncryptInit_ex(ctx, cipher, NULL, cek.ptr, NULL);
int enc_result = EVP_EncryptInit_ex(ctx, cipher, NULL, key, NULL);
if (!enc_result)
{
EVP_CIPHER_CTX_free(ctx);
return -1;
}

int len = (int)wrapped_key->len;
if (!EVP_EncryptUpdate(ctx, wrapped_key->ptr, &len,
// (int*)&wrapped_key->len,
key, (int)keylen))
if (!EVP_EncryptUpdate(ctx, (unsigned char *)wrapped_key->ptr, &len, cek.ptr, cek.len))
{
EVP_CIPHER_CTX_free(ctx);
return -2;
Expand Down Expand Up @@ -413,9 +420,9 @@ int BSL_Crypto_GenKey(uint8_t *key_buffer, size_t key_length)
CHK_ARG_EXPR(key_length == 16 || key_length == 32);

int key_length_int = (int)key_length;
if (RAND_bytes(key_buffer, key_length_int) != 1)
if (rand_bytes_generator(key_buffer, key_length_int) != 1)
{
OPENSSL_cleanse(key_buffer, key_length_int);
memset(key_buffer, 0, key_length_int);
return -2;
}

Expand All @@ -431,7 +438,7 @@ int BSL_Crypto_GenIV(void *buf, int size)
}

memset(buf, 0, size);
CHK_PROPERTY(RAND_bytes((unsigned char *)buf, size) == 1);
CHK_PROPERTY(rand_bytes_generator((unsigned char *)buf, size) == 1);
return 0;
}

Expand Down
66 changes: 17 additions & 49 deletions src/security_context/BCB_AES_GCM.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,25 +236,15 @@ int BSLX_BCB_Encrypt(BSLX_BCB_t *bcb_context)
bool is_aes128 = bcb_context->aes_variant == RFC9173_BCB_AES_VARIANT_A128GCM;
BSL_CryptoCipherAESVariant_e aes_mode = is_aes128 ? BSL_CRYPTO_AES_128 : BSL_CRYPTO_AES_256;

// The IV is already defined if being populated from a test
// Normally, this won't be the case, so we check here.
// If it is empty, then generate a random IV.
if (bcb_context->iv.len == 0)
{
// https://www.rfc-editor.org/rfc/rfc9173.html#name-initialization-vector-iv
// "A value of 12 bytes SHOULD be used unless local security policy requires a different length"
BSL_Data_InitBuffer(&bcb_context->iv, RFC9173_BCB_DEFAULT_IV_LEN);
void *iv_ptr = bcb_context->iv.ptr;
const size_t iv_len = bcb_context->iv.len;
if (BSL_SUCCESS != BSL_Crypto_GenIV(iv_ptr, iv_len))
{
BSL_LOG_ERR("Failed to generate IV");
return BSL_ERR_SECURITY_CONTEXT_FAILED;
}
}
else
// https://www.rfc-editor.org/rfc/rfc9173.html#name-initialization-vector-iv
// "A value of 12 bytes SHOULD be used unless local security policy requires a different length"
BSL_Data_InitBuffer(&bcb_context->iv, RFC9173_BCB_DEFAULT_IV_LEN);
void *iv_ptr = bcb_context->iv.ptr;
const size_t iv_len = bcb_context->iv.len;
if (BSL_SUCCESS != BSL_Crypto_GenIV(iv_ptr, iv_len))
{
BSL_LOG_WARNING("Using test-harness IV");
BSL_LOG_ERR("Failed to generate IV");
return BSL_ERR_SECURITY_CONTEXT_FAILED;
}

BSL_Data_t content_enc_key = { 0 };
Expand Down Expand Up @@ -283,23 +273,17 @@ int BSLX_BCB_Encrypt(BSLX_BCB_t *bcb_context)
}
else
{
if (bcb_context->test_content_enc_key.len > 0)
// FIXME the key bytes shouldn't be copied outside of crypto library.
// possible alternative:
// GenKey should instead return a keyid and add generated key to registry
const size_t keysize = is_aes128 ? 16 : 32;
BSL_LOG_DEBUG("Generating %lu bit AES key", keysize * 8);
if (BSL_SUCCESS != BSL_Crypto_GenKey(content_enc_key.ptr, keysize))
{
ASSERT_PROPERTY(content_enc_key.len >= bcb_context->test_content_enc_key.len);
BSL_LOG_WARNING("Using CEK from test parameter");
memcpy(content_enc_key.ptr, bcb_context->test_content_enc_key.ptr, bcb_context->test_content_enc_key.len);
content_enc_key.len = bcb_context->test_content_enc_key.len;
}
else
{
const size_t keysize = is_aes128 ? 16 : 32;
BSL_LOG_DEBUG("Generating %lu bit AES key", keysize * 8);
if (BSL_SUCCESS != BSL_Crypto_GenKey(content_enc_key.ptr, keysize))
{
BSL_LOG_ERR("Failed to generate AES key");
goto error;
}
BSL_LOG_ERR("Failed to generate AES key");
goto error;
}
content_enc_key.len = keysize;

if (BSL_SUCCESS != BSL_Data_InitBuffer(&bcb_context->wrapped_key, BSLX_MAX_KEYLEN))
{
Expand Down Expand Up @@ -478,25 +462,12 @@ int BSLX_BCB_GetParams(const BSL_BundleRef_t *bundle, BSLX_BCB_t *bcb_context, c
BSL_LOG_DEBUG("Param[%lu]: KEY_ID value = %s", param_id, bcb_context->key_id);
break;
}
case BSL_SECPARAM_TYPE_INT_FIXED_KEY:
{
BSL_LOG_DEBUG("BCB using fixed key from test harness");
BSL_SecParam_GetAsBytestr(param, &bcb_context->test_content_enc_key);
break;
}
case BSL_SECPARAM_TYPE_AUTH_TAG:
{
BSL_LOG_DEBUG("Parsing auth tag");
BSL_SecParam_GetAsBytestr(param, &bcb_context->authtag);
break;
}
case BSL_SECPARAM_TYPE_IV:
{
// If we need to pass in an IV for testing purposes.
BSL_LOG_DEBUG("Param[%lu]: USE TEST INITIALIZATION VECTOR", param_id);
BSL_SecParam_GetAsBytestr(param, &bcb_context->iv);
break;
}
case BSL_SECPARAM_TYPE_INT_USE_WRAPPED_KEY:
{
const uint64_t arg_val = BSL_SecParam_GetAsUInt64(param);
Expand Down Expand Up @@ -584,9 +555,6 @@ static void BSLX_BCB_Deinit(BSLX_BCB_t *bcb_context)
BSL_Data_Deinit(&bcb_context->debugstr);
BSL_Data_Deinit(&bcb_context->authtag);
BSL_Data_Deinit(&bcb_context->iv);
BSL_Data_Deinit(&bcb_context->test_content_enc_key);
BSL_Data_Deinit(&bcb_context->test_init_vector);
BSL_Data_Deinit(&bcb_context->test_key_enc_key);
BSL_Data_Deinit(&bcb_context->wrapped_key);
memset(bcb_context, 0, sizeof(*bcb_context));
}
Expand Down
3 changes: 0 additions & 3 deletions src/security_context/DefaultSecContext_Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,6 @@ typedef struct BSLX_BCB_s
BSL_Data_t authtag;
BSL_Data_t iv;
BSL_Data_t wrapped_key;
BSL_Data_t test_content_enc_key;
BSL_Data_t test_init_vector;
BSL_Data_t test_key_enc_key;
BSL_Data_t btsd_replacement;
BSL_Data_t debugstr;
BSL_Data_t aad;
Expand Down
70 changes: 65 additions & 5 deletions test/bsl_test_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ void BSL_TestUtils_InitBCB_Appendix2(BCBTestContext *context, BSL_SecRole_e role
quick_data(context->auth_tag, ApxA2_AuthTag);
quick_data(context->wrapped_key, ApxA2_WrappedKey);
quick_data(context->key_enc_key, ApxA2_KeyEncKey);
quick_data(context->content_enc_key, ApxA2_ContentEncKey);

BSL_SecParam_InitInt64(&context->param_scope_flags, RFC9173_BCB_SECPARAM_AADSCOPE, 0);
BSL_SecParam_InitStr(&context->param_test_key_id, BSL_SECPARAM_TYPE_KEY_ID, RFC9173_EXAMPLE_A2_KEY);
Expand All @@ -70,8 +69,6 @@ void BSL_TestUtils_InitBCB_Appendix2(BCBTestContext *context, BSL_SecRole_e role
BSL_SecParam_InitBytestr(&context->param_init_vec, RFC9173_BCB_SECPARAM_IV, context->init_vector);
BSL_SecParam_InitBytestr(&context->param_auth_tag, BSL_SECPARAM_TYPE_AUTH_TAG, context->auth_tag);
BSL_SecParam_InitBytestr(&context->param_wrapped_key, RFC9173_BCB_SECPARAM_WRAPPEDKEY, context->wrapped_key);
BSL_SecParam_InitBytestr(&context->param_content_enc_key, BSL_SECPARAM_TYPE_INT_FIXED_KEY,
context->content_enc_key);

BSL_SecOper_Init(&context->sec_oper, 2, 1, 2, BSL_SECBLOCKTYPE_BCB, role, BSL_POLICYACTION_NOTHING);

Expand All @@ -81,8 +78,6 @@ void BSL_TestUtils_InitBCB_Appendix2(BCBTestContext *context, BSL_SecRole_e role
BSL_SecOper_AppendParam(&context->sec_oper, &context->param_scope_flags);
if (role != BSL_SECROLE_SOURCE)
BSL_SecOper_AppendParam(&context->sec_oper, &context->param_auth_tag);
if (role == BSL_SECROLE_SOURCE)
BSL_SecOper_AppendParam(&context->sec_oper, &context->param_content_enc_key);
BSL_SecOper_AppendParam(&context->sec_oper, &context->param_test_key_id);
}

Expand All @@ -102,6 +97,71 @@ BSL_SecurityResponseSet_t *BSL_TestUtils_MallocEmptyPolicyResponse(void)
return calloc(BSL_SecurityResponseSet_Sizeof(), 1);
}

int rfc9173_byte_gen_fn_a1(unsigned char *buf, int len)
{
if (len == 12) // IV
{
uint8_t iv[] = { 0x54, 0x77, 0x65, 0x6c, 0x76, 0x65, 0x31, 0x32, 0x31, 0x32, 0x31, 0x32 };
memcpy(buf, iv, 12);
}
else // A1 KEY
{
uint8_t rfc9173A1_key[] = { 0x1a, 0x2b, 0x1a, 0x2b, 0x1a, 0x2b, 0x1a, 0x2b,
0x1a, 0x2b, 0x1a, 0x2b, 0x1a, 0x2b, 0x1a, 0x2b };
memcpy(buf, rfc9173A1_key, len);
}
return 1;
}

int rfc9173_byte_gen_fn_a2_kek(unsigned char *buf, int len)
{
if (len == 12) // IV
{
uint8_t iv[] = { 0x54, 0x77, 0x65, 0x6c, 0x76, 0x65, 0x31, 0x32, 0x31, 0x32, 0x31, 0x32 };
memcpy(buf, iv, 12);
}
else // A2 KEY
{
uint8_t rfc9173A2_key[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70 };
memcpy(buf, rfc9173A2_key, len);
}
return 1;
}

int rfc9173_byte_gen_fn_a2_cek(unsigned char *buf, int len)
{
if (len == 12) // IV
{
uint8_t iv[] = { 0x54, 0x77, 0x65, 0x6c, 0x76, 0x65, 0x31, 0x32, 0x31, 0x32, 0x31, 0x32 };
memcpy(buf, iv, 12);
}
else // A3 KEY
{
uint8_t rfc9173A3_key[] = { 0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69,
0x6f, 0x70, 0x61, 0x73, 0x64, 0x66, 0x67, 0x68 };
memcpy(buf, rfc9173A3_key, len);
}
return 1;
}

int rfc9173_byte_gen_fn_a4(unsigned char *buf, int len)
{
if (len == 12) // IV
{
uint8_t iv[] = { 0x54, 0x77, 0x65, 0x6c, 0x76, 0x65, 0x31, 0x32, 0x31, 0x32, 0x31, 0x32 };
memcpy(buf, iv, 12);
}
else // A4 KEY
{
uint8_t rfc9173A4_key[] = { 0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69, 0x6f, 0x70, 0x61,
0x73, 0x64, 0x66, 0x67, 0x68, 0x71, 0x77, 0x65, 0x72, 0x74, 0x79,
0x75, 0x69, 0x6f, 0x70, 0x61, 0x73, 0x64, 0x66, 0x67, 0x68 };
memcpy(buf, rfc9173A4_key, len);
}
return 1;
}

void BSL_TestUtils_SetupDefaultSecurityContext(BSL_LibCtx_t *bsl_lib)
{
assert(bsl_lib != NULL);
Expand Down
5 changes: 5 additions & 0 deletions test/bsl_test_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,4 +333,9 @@ int BSL_TestUtils_EncodeBase16(string_t output, const BSL_Data_t *input, bool up
*/
int BSL_TestUtils_DecodeBase16(BSL_Data_t *output, const string_t input);

int rfc9173_byte_gen_fn_a1(unsigned char *buf, int len);
int rfc9173_byte_gen_fn_a2_kek(unsigned char *buf, int len);
int rfc9173_byte_gen_fn_a2_cek(unsigned char *buf, int len);
int rfc9173_byte_gen_fn_a4(unsigned char *buf, int len);

#endif
9 changes: 3 additions & 6 deletions test/test_BackendSecurityContext.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ void test_SecurityContext_BIB_Acceptor(void)
// See RFC: https://www.rfc-editor.org/rfc/rfc9173.html#name-example-3-security-blocks-f
void test_RFC9173_AppendixA_Example3_Acceptor(void)
{
BSL_Crypto_SetRngGenerator(rfc9173_byte_gen_fn_a4);
const char *final_bundle = ("9f88070000820282010282028202018202820201820018281a000f4240850b0300"
"00585c8200020101820282030082820105820300828182015820cac6ce8e4c5dae57"
"988b757e49a6dd1431dc04763541b2845098265bc817241b81820158203ed614c0d9"
Expand Down Expand Up @@ -383,6 +384,7 @@ void test_RFC9173_AppendixA_Example3_Source(void)

void test_RFC9173_AppendixA_Example4_Acceptor(void)
{
BSL_Crypto_SetRngGenerator(rfc9173_byte_gen_fn_a4);
// See: https://www.rfc-editor.org/rfc/rfc9173.html#appendix-A.4.5
const char *final_bundle = ("9f88070000820282010282028202018202820201820018281a000f4240850b0300"
"005846438ed6208eb1c1ffb94d952175167df0902902064a2983910c4fb2340790bf"
Expand Down Expand Up @@ -469,6 +471,7 @@ void test_RFC9173_AppendixA_Example4_Acceptor(void)

void test_RFC9173_AppendixA_Example4_Source(void)
{
BSL_Crypto_SetRngGenerator(rfc9173_byte_gen_fn_a4);
const char *original_bundle = ("9f88070000820282010282028202018202820201820018281a000f424085010100"
"005823526561647920746f2067656e657261746520612033322d6279746520706179"
"6c6f6164ff");
Expand Down Expand Up @@ -498,25 +501,19 @@ void test_RFC9173_AppendixA_Example4_Source(void)
BSL_SecParam_InitInt64(&bcb_scope, RFC9173_BCB_SECPARAM_AADSCOPE, 0x07);
BSL_SecParam_t aes_variant = { 0 };
BSL_SecParam_InitInt64(&aes_variant, RFC9173_BCB_SECPARAM_AESVARIANT, RFC9173_BCB_AES_VARIANT_A256GCM);
uint8_t iv[] = { 0x54, 0x77, 0x65, 0x6c, 0x76, 0x65, 0x31, 0x32, 0x31, 0x32, 0x31, 0x32 };
BSL_Data_t iv_data = { .len = sizeof(iv), .ptr = iv };
BSL_SecParam_t init_vec = { 0 };
BSL_SecParam_InitBytestr(&init_vec, BSL_SECPARAM_TYPE_IV, iv_data);

BSL_SecOper_t bcb_op_tgt_payload = { 0 };
BSL_SecOper_Init(&bcb_op_tgt_payload, 2, 1, 3, BSL_SECBLOCKTYPE_BCB, BSL_SECROLE_SOURCE,
BSL_POLICYACTION_DROP_BLOCK);
BSL_SecOper_AppendParam(&bcb_op_tgt_payload, &bcb_param_key);
BSL_SecOper_AppendParam(&bcb_op_tgt_payload, &aes_variant);
BSL_SecOper_AppendParam(&bcb_op_tgt_payload, &bcb_scope);
BSL_SecOper_AppendParam(&bcb_op_tgt_payload, &init_vec);

BSL_SecOper_t bcb_op_tgt_bib = { 0 };
BSL_SecOper_Init(&bcb_op_tgt_bib, 2, 2, 3, BSL_SECBLOCKTYPE_BCB, BSL_SECROLE_SOURCE, BSL_POLICYACTION_DROP_BLOCK);
BSL_SecOper_AppendParam(&bcb_op_tgt_bib, &bcb_param_key);
BSL_SecOper_AppendParam(&bcb_op_tgt_bib, &aes_variant);
BSL_SecOper_AppendParam(&bcb_op_tgt_bib, &bcb_scope);
BSL_SecOper_AppendParam(&bcb_op_tgt_bib, &init_vec);

BSL_SecurityActionSet_t *malloced_actionset = calloc(1, BSL_SecurityActionSet_Sizeof());
BSL_SecurityActionSet_Init(malloced_actionset);
Expand Down
Loading