blob: f55cb1f6e0abbf7adbc3e827a3d5b4cceaba618e [file] [log] [blame]
/*
*
* Copyright 2018-2020 NXP
* SPDX-License-Identifier: Apache-2.0
*/
/* ************************************************************************** */
/* Includes */
/* ************************************************************************** */
#include <a71ch_api.h>
#include <ex_sss.h>
#include <ex_sss_boot.h>
#include <fsl_sss_se05x_apis.h>
#include <nxEnsure.h>
#include <nxLog_App.h>
/* ************************************************************************** */
/* Local Defines */
/* ************************************************************************** */
#define EC_KEY_BIT_LEN 256
/* ************************************************************************** */
/* Structures and Typedefs */
/* ************************************************************************** */
/* ************************************************************************** */
/* Global Variables */
/* ************************************************************************** */
/* clang-format off */
const uint8_t aesKey[32] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
};
const uint8_t aesKey1[32] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
};
/* wrapped first 16 bytes of aesKey1 key with first 16 bytes of aesKey*/
const uint8_t wapped_AesKey1_0[24] = { 0xb2, 0x68, 0x75, 0x57, 0xa1, 0x4e, 0xc8, 0xa8,
0x2f, 0xe0, 0x7b, 0x8d, 0xc1, 0xe6, 0xf9, 0xf9,
0x8c, 0xe7, 0x4a, 0x4b, 0xf5, 0x7, 0xf3, 0xa9
};
/* wrapped last 16 bytes of aesKey1 key with last 16 bytes of aesKey*/
const uint8_t wapped_AesKey1_1[24] = { 0x6b, 0x53, 0x16, 0xe4, 0x72, 0x64, 0x02, 0x18,
0x7f, 0x7c, 0x1e, 0x5b, 0x70, 0x16, 0xab, 0xab,
0xa2, 0x35, 0xc8, 0xd2, 0x06, 0xaa, 0xb3, 0x82
};
/* clang-format on */
static ex_sss_boot_ctx_t gex_sss_aes_wrap_key_boot_ctx;
/* ************************************************************************** */
/* Static function declarations */
/* ************************************************************************** */
/* ************************************************************************** */
/* Private Functions */
/* ************************************************************************** */
/* ************************************************************************** */
/* Public Functions */
/* ************************************************************************** */
#define EX_SSS_BOOT_PCONTEXT (&gex_sss_aes_wrap_key_boot_ctx)
#define EX_SSS_BOOT_DO_ERASE 1
#define EX_SSS_BOOT_EXPOSE_ARGC_ARGV 0
#include <ex_sss_main_inc.h>
#include "a71ch_util.h"
#include "sm_types.h"
#include "tst_sm_util.h"
sss_status_t calculate_hkdf_key(
ex_sss_boot_ctx_t *pCtx, sss_object_t aeskeyObject, uint32_t hkdfKeyId, uint8_t *outHkdfKey, size_t *outHkdfKeyLen);
sss_status_t ex_sss_entry(ex_sss_boot_ctx_t *pCtx)
{
sss_status_t status = kStatus_SSS_Success;
sss_object_t aesObj1;
sss_object_t aesObj2;
uint8_t HkdfKey1[128] = {
0,
};
size_t HkdfKey1Len = sizeof(HkdfKey1);
uint8_t HkdfKey2[128] = {
0,
};
size_t HkdfKey2Len = sizeof(HkdfKey2);
// Variables used by calls to legacy API
U16 sw = 0;
SST_Index_t keyIdx = 0;
LOG_I(
"Running Set AES Wrapped Key Example "
"ex_a71ch_sss_aes_wrap_key.c");
/* doc:start ex_sss-set-aes-key */
status = sss_key_object_init(&aesObj1, &pCtx->ks);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
status = sss_key_object_allocate_handle(&aesObj1,
MAKE_TEST_ID(__LINE__),
kSSS_KeyPart_Default,
kSSS_CipherType_AES,
sizeof(aesKey),
kKeyObject_Mode_Persistent);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
status = sss_key_store_set_key(&pCtx->ks, &aesObj1, aesKey, sizeof(aesKey), sizeof(aesKey) * 8, NULL, 0);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
/* doc:end ex_sss-set-aes-key */
/* doc:start ex_hostlib-set-wrapped-aes-key */
keyIdx = (((sss_sscp_object_t *)&aesObj1)->slotId) & 0x0F;
/* Set wrapped aes key - aesKey1 */
sw = A71_SetRfc3394WrappedAesKey(keyIdx, wapped_AesKey1_0, sizeof(wapped_AesKey1_0));
status = ((sw == SW_OK) ? kStatus_SSS_Success : kStatus_SSS_Fail);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
sw = A71_SetRfc3394WrappedAesKey(keyIdx + 1, wapped_AesKey1_1, sizeof(wapped_AesKey1_1));
status = ((sw == SW_OK) ? kStatus_SSS_Success : kStatus_SSS_Fail);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
/* doc:end ex_hostlib-set-wrapped-aes-key */
/* Verify if the wrapped key is injected properly */
/* doc:start ex_verify-wrapped-key */
/* 1 - Calculate HKDF key with wrapped AES key injected - aesKey1 */
status = calculate_hkdf_key(pCtx, aesObj1, MAKE_TEST_ID(__LINE__), HkdfKey1, &HkdfKey1Len);
/* 2 - Inject aesKey1 AES key and calculate HKDF key */
status = sss_key_object_init(&aesObj2, &pCtx->ks);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
status = sss_key_object_allocate_handle(&aesObj2,
MAKE_TEST_ID(__LINE__),
kSSS_KeyPart_Default,
kSSS_CipherType_AES,
sizeof(aesKey1),
kKeyObject_Mode_Persistent);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
status = sss_key_store_set_key(&pCtx->ks, &aesObj2, aesKey1, sizeof(aesKey1), sizeof(aesKey1) * 8, NULL, 0);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
status = calculate_hkdf_key(pCtx, aesObj2, MAKE_TEST_ID(__LINE__), HkdfKey2, &HkdfKey2Len);
/* 3 - compare both hkdf keys generated */
if (0 != memcmp(HkdfKey1, HkdfKey2, HkdfKey1Len)) {
status = kStatus_SSS_Fail;
}
/* doc:end ex_verify-wrapped-key */
cleanup:
if (kStatus_SSS_Success == status) {
LOG_I("ex_a71ch_sss_aes_wrap_key Example Success !!!...");
}
else {
LOG_E("ex_a71ch_sss_aes_wrap_key Example Failed !!!...");
}
return status;
}
sss_status_t calculate_hkdf_key(
ex_sss_boot_ctx_t *pCtx, sss_object_t aeskeyObject, uint32_t hkdfKeyId, uint8_t *outHkdfKey, size_t *outHkdfKeyLen)
{
sss_status_t status;
/* HKDF Extract and Expand*/
sss_algorithm_t algorithm = kAlgorithm_SSS_HMAC_SHA256;
uint8_t info[DERIVE_KEYDATA_FROM_SHARED_SECRET_MAX_INFO] = {
0,
};
uint8_t infoLen = sizeof(info);
sss_object_t derived_key;
sss_derive_key_t ctx_derv = {0};
uint16_t deriveDataLen = 128;
/* clang-format off */
static uint8_t salt[32] = { 0xAA, 0x1A, 0x2A, 0xE3, 0xB2, 0x76, 0x15, 0x4D,
0x67, 0xF9, 0xD8, 0x4C, 0xB9, 0x35, 0x54, 0x56,
0xBB, 0x1B, 0x2B, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
/* clang-format on */
/* Store derived key in host */
status = sss_key_object_init(&derived_key, &pCtx->host_ks);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
status = sss_key_object_allocate_handle(
&derived_key, hkdfKeyId, kSSS_KeyPart_Default, kSSS_CipherType_AES, *outHkdfKeyLen, kKeyObject_Mode_Transient);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
status =
sss_derive_key_context_init(&ctx_derv, &pCtx->session, &aeskeyObject, algorithm, kMode_SSS_ComputeSharedSecret);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
status = sss_derive_key_go(
&ctx_derv, salt, sizeof(salt), info, infoLen, &derived_key, deriveDataLen, outHkdfKey, outHkdfKeyLen);
#if SSS_HAVE_FIPS
ENSURE_OR_GO_CLEANUP(status != kStatus_SSS_Success);
status = kStatus_SSS_Success;
goto cleanup;
#else
size_t hkdfKeyLenBits = *outHkdfKeyLen * 8;
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
status = sss_key_store_get_key(&pCtx->host_ks, &derived_key, outHkdfKey, outHkdfKeyLen, &hkdfKeyLenBits);
ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
LOG_I(" Key Derivation successful !!!");
LOG_MAU8_I("hkdfOutput", outHkdfKey, *outHkdfKeyLen);
#endif
cleanup:
if (ctx_derv.session != NULL)
sss_derive_key_context_free(&ctx_derv);
return status;
}