| /* |
| * |
| * Copyright 2018-2020 NXP |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| /* ************************************************************************** */ |
| /* Includes */ |
| /* ************************************************************************** */ |
| |
| #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 HKDF_MAX_SALT 32 |
| #define SYM_KEY_MAX 16 |
| |
| #define EX_DERIVE_KEYDATA_FROM_SHARED_SECRET_MAX_INFO 80 |
| |
| /* ************************************************************************** */ |
| /* Structures and Typedefs */ |
| /* ************************************************************************** */ |
| |
| /* ************************************************************************** */ |
| /* Global Variables */ |
| /* ************************************************************************** */ |
| |
| /* clang-format on */ |
| |
| static ex_sss_boot_ctx_t gex_sss_hkdf_boot_ctx; |
| |
| /* ************************************************************************** */ |
| /* Static function declarations */ |
| /* ************************************************************************** */ |
| |
| /* ************************************************************************** */ |
| /* Private Functions */ |
| /* ************************************************************************** */ |
| |
| /* ************************************************************************** */ |
| /* Public Functions */ |
| /* ************************************************************************** */ |
| |
| #define EX_SSS_BOOT_PCONTEXT (&gex_sss_hkdf_boot_ctx) |
| #define EX_SSS_BOOT_DO_ERASE 1 |
| #define EX_SSS_BOOT_EXPOSE_ARGC_ARGV 0 |
| |
| #include <ex_sss_main_inc.h> |
| |
| sss_status_t ex_sss_entry(ex_sss_boot_ctx_t *pCtx) |
| { |
| sss_status_t status; |
| sss_derive_key_t ctx_derv = {0}; |
| sss_algorithm_t algorithm; |
| sss_mode_t mode; |
| /* HKDF Extract and Expand*/ |
| algorithm = kAlgorithm_SSS_HMAC_SHA256; |
| mode = kMode_SSS_ComputeSharedSecret; |
| uint32_t keyId = MAKE_TEST_ID(__LINE__); |
| int i; |
| uint32_t hmacKey_len = SYM_KEY_MAX; |
| uint16_t deriveDataLen = 128; |
| uint8_t hkdfKey[128] = {0}; |
| size_t hkdfKeyLen = sizeof(hkdfKey); |
| #if !SSS_HAVE_FIPS |
| size_t hkdfKeyLenBits = sizeof(hkdfKey) * 8; |
| #endif |
| /* clang-format off */ |
| const uint8_t hmacRef[SYM_KEY_MAX] = { 0xDB, 0xFE, 0xE9, 0xE3, 0xB2, 0x76, 0x15, 0x4D, |
| 0x67, 0xF9, 0xD8, 0x4C, 0xB9, 0x35, 0x54, 0x56 }; |
| static uint8_t salt[HKDF_MAX_SALT] = { 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 */ |
| |
| sss_object_t keyObject = {0}; |
| sss_object_t derived_key = {0}; |
| |
| LOG_I("Running HMAC Key Derivation Function Example ex_sss_hkdf.c"); |
| |
| uint8_t info[EX_DERIVE_KEYDATA_FROM_SHARED_SECRET_MAX_INFO]; |
| uint8_t infoLen = sizeof(info); |
| for (i = 0; i < EX_DERIVE_KEYDATA_FROM_SHARED_SECRET_MAX_INFO; i++) { |
| info[i] = (uint8_t)i; |
| } |
| |
| status = sss_key_object_init(&keyObject, &pCtx->ks); |
| ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success); |
| |
| status = sss_key_object_allocate_handle( |
| &keyObject, keyId, kSSS_KeyPart_Default, kSSS_CipherType_HMAC, SYM_KEY_MAX, kKeyObject_Mode_Persistent); |
| ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success); |
| |
| /* 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, keyId + 2, kSSS_KeyPart_Default, kSSS_CipherType_AES, hkdfKeyLen, kKeyObject_Mode_Transient); |
| ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success); |
| |
| status = sss_key_store_set_key(&pCtx->ks, &keyObject, hmacRef, hmacKey_len, hmacKey_len * 8, NULL, 0); |
| ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success); |
| |
| /* Note: |
| Set mode to kMode_SSS_HKDF_ExpandOnly to request only the Expand phase |
| of the HKDF to be calculated. |
| */ |
| status = sss_derive_key_context_init(&ctx_derv, &pCtx->session, &keyObject, algorithm, mode); |
| ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success); |
| |
| LOG_I("Do Key Derivation"); |
| LOG_MAU8_I("salt", salt, HKDF_MAX_SALT); |
| LOG_MAU8_I("info", info, infoLen); |
| |
| /* Note: |
| Use sss_derive_key_sobj_one_go in case the salt value is stored |
| as a key object in the same keystore as the hkdf context. |
| This allows the salt value to be secret. |
| */ |
| status = sss_derive_key_one_go(&ctx_derv, salt, HKDF_MAX_SALT, info, infoLen, &derived_key, deriveDataLen); |
| |
| #if SSS_HAVE_FIPS |
| ENSURE_OR_GO_CLEANUP(status != kStatus_SSS_Success); |
| status = kStatus_SSS_Success; |
| goto cleanup; |
| #else |
| |
| ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success); |
| |
| /* Note: |
| A key store associated with a secure element would not allow |
| to read back the value. |
| */ |
| status = sss_key_store_get_key(&pCtx->host_ks, &derived_key, hkdfKey, &hkdfKeyLen, &hkdfKeyLenBits); |
| ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success); |
| |
| LOG_I(" Key Derivation successful !!!"); |
| LOG_MAU8_I("hkdfOutput", hkdfKey, hkdfKeyLen); |
| #endif |
| cleanup: |
| if (kStatus_SSS_Success == status) { |
| LOG_I("ex_sss_hkdf Example Success !!!..."); |
| } |
| else { |
| LOG_E("ex_sss_hkdf Example Failed !!!..."); |
| } |
| |
| if (ctx_derv.session != NULL) |
| sss_derive_key_context_free(&ctx_derv); |
| |
| if (keyObject.keyStore != NULL) { |
| sss_key_object_free(&keyObject); |
| } |
| if (derived_key.keyStore != NULL) { |
| sss_key_object_free(&derived_key); |
| } |
| |
| return status; |
| } |