blob: 973aeec2cf5595ab65a5b20936ee9d8db6293d0f [file] [log] [blame]
/* Copyright 2019,2020 NXP
* SPDX-License-Identifier: Apache-2.0
*/
#include <ex_sss.h>
#include <ex_sss_boot.h>
#include <fsl_sss_se05x_apis.h>
#include <se05x_APDU.h>
#include <se05x_const.h>
#include <se05x_ecc_curves.h>
#include <se05x_ecc_curves_values.h>
#include <se05x_tlv.h>
#include <string.h>
#include <nxEnsure.h>
#include <nxLog_App.h>
#include "ex_sss_auth.h"
#if SSS_HAVE_APPLET_SE05X_IOT
static ex_sss_boot_ctx_t gex_sss_pcr_ctx;
#define EX_SSS_BOOT_PCONTEXT (&gex_sss_pcr_ctx)
#define EX_SSS_BOOT_DO_ERASE 0
#define EX_SSS_BOOT_EXPOSE_ARGC_ARGV 0
#include <ex_sss_main_inc.h>
#if (SSS_HAVE_SE05X_AUTH_USERID) || (SSS_HAVE_SE05X_AUTH_USERID_PLATFSCP03) //UserID Session
#define EX_LOCAL_OBJ_AUTH_ID EX_SSS_AUTH_SE05X_UserID_AUTH_ID
#elif (SSS_HAVE_SE05X_AUTH_NONE) || (SSS_HAVE_SE05X_AUTH_PLATFSCP03) //No auth
#define EX_LOCAL_OBJ_AUTH_ID EX_SSS_AUTH_SE05X_NONE_AUTH_ID
#elif (SSS_HAVE_SE05X_AUTH_AESKEY) || (SSS_HAVE_SE05X_AUTH_AESKEY_PLATFSCP03) //AESKey
#define EX_LOCAL_OBJ_AUTH_ID EX_SSS_AUTH_SE05X_APPLETSCP_AUTH_ID
#elif (SSS_HAVE_SE05X_AUTH_ECKEY) || (SSS_HAVE_SE05X_AUTH_ECKEY_PLATFSCP03) //ECKey session
#define EX_LOCAL_OBJ_AUTH_ID EX_SSS_AUTH_SE05X_ECKEY_ECDSA_AUTH_ID
#endif
#define ECC256R1_KEY_BIT_LENGTH 256
sss_status_t ex_sss_entry(ex_sss_boot_ctx_t *pCtx)
{
sss_status_t status = kStatus_SSS_Fail;
smStatus_t retval = SM_NOT_OK;
sss_se05x_session_t *pSession = (sss_se05x_session_t *)&pCtx->session;
sss_object_t ec_keyPair;
sss_asymmetric_t asymm = {0};
uint8_t digest[32] = "Hello World";
size_t digestLen = sizeof(digest);
uint8_t signature[ECC256R1_KEY_BIT_LENGTH] = {0};
size_t signatureLen = sizeof(signature);
sss_object_t pcr_object;
uint8_t pcr_init_value[32] = {0x12, 0xa1, 0x49, 0x82, 0x32};
uint8_t pcr_update_value[] = {0x12, 0xa1, 0x49, 0x82, 0x32};
size_t pcr_init_value_size = sizeof(pcr_init_value);
size_t pcr_update_value_size = sizeof(pcr_update_value);
uint32_t keyId = (0xEF000000u + __LINE__);
size_t keylen = ECC256R1_KEY_BIT_LENGTH / 8;
#if SSS_HAVE_SE05X_VER_GTE_06_00
/* clang-format off */
uint8_t pcr_expected_value[] = {
0x87, 0xD3, 0xE3, 0x93, 0x19, 0x8F, 0x5C, 0x80, 0xE0, 0xBC, 0x9B, 0xC9, 0x82, 0x00, 0x1F, 0xB0, 0xEE, 0x20, 0x1C, 0x27, 0x0B, 0x6D, 0xC8, 0x84, 0x52, 0xE4, 0x13, 0xA3, 0x25, 0x56, 0x81, 0x75};
#else
uint8_t pcr_expected_value[] = {
0x89, 0x51, 0x56, 0x9f, 0x41, 0x5f, 0xeb, 0x4f, 0xb6, 0x37, 0x02, 0x86, 0xe7, 0xdd, 0xa0, 0x99, 0x33, 0x6c, 0x46, 0x36, 0xbc, 0xbb, 0x4c, 0x11, 0x04, 0x10, 0x0a, 0x86, 0x0d, 0x0c, 0xa4, 0x14};
/* clang-format on */
#endif
size_t pcr_expected_value_size = sizeof(pcr_expected_value);
/* clang-format off */
/* Policies for ecc key */
const sss_policy_u key_withPol = {
.type = KPolicy_Asym_Key,
.auth_obj_id = EX_LOCAL_OBJ_AUTH_ID,
.policy = {
.asymmkey = {
.can_Sign = 1,
.can_Verify = 1,
.can_Encrypt = 1,
.can_Decrypt = 1,
.can_KD = 1,
.can_Wrap = 1,
.can_Write = 1,
.can_Gen = 1,
.can_Import_Export = 1,
.can_KA = 1,
.can_Read = 1,
.can_Attest = 1,
}
}
};
/* Common rules */
const sss_policy_u common = {
.type = KPolicy_Common,
.auth_obj_id = EX_LOCAL_OBJ_AUTH_ID,
.policy = {
.common = {
.req_Sm = 0,
.can_Delete = 1,
.forbid_All = 0,
}
}
};
sss_policy_u pcr = {
.type = KPolicy_Common_PCR_Value,
.auth_obj_id = EX_LOCAL_OBJ_AUTH_ID,
.policy = {
.common_pcr_value = {
.pcrObjId = 0x7fffffff,
}
}
};
memset(pcr.policy.common_pcr_value.pcrExpectedValue,
0x00,
sizeof(pcr.policy.common_pcr_value.pcrExpectedValue));
memcpy(pcr.policy.common_pcr_value.pcrExpectedValue,
pcr_expected_value, pcr_expected_value_size);
/* create policy set */
sss_policy_t policy_for_ec_key = {
.nPolicies = 3,
.policies = { &key_withPol, &common,&pcr}
};
/* clang-format on */
status = sss_key_object_init(&ec_keyPair, &pCtx->ks);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
status = sss_key_object_allocate_handle(
&ec_keyPair, keyId, kSSS_KeyPart_Pair, kSSS_CipherType_EC_NIST_P, keylen, kKeyObject_Mode_Persistent);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
status = sss_key_store_generate_key(&pCtx->ks, &ec_keyPair, ECC256R1_KEY_BIT_LENGTH, &policy_for_ec_key);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
status = sss_asymmetric_context_init(&asymm, &pCtx->session, &ec_keyPair, kAlgorithm_SSS_SHA256, kMode_SSS_Sign);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
status = sss_asymmetric_sign_digest(&asymm, digest, digestLen, signature, &signatureLen);
if (status == kStatus_SSS_Fail) {
LOG_I("Sign failed due to PCR expected value mismatch!!!");
}
sss_asymmetric_context_free(&asymm);
/* Create a PCR Object */
status = sss_key_object_init(&pcr_object, &pCtx->ks);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
status = sss_key_object_allocate_handle(
&pcr_object, 0x7fffffff, kSSS_KeyPart_Default, kSSS_CipherType_PCR, pcr_init_value_size, kKeyObject_Mode_None);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
/*
*Inject PCR object and update value
*/
retval = Se05x_API_WritePCR(&(pSession->s_ctx), NULL, 0x7fffffff, pcr_init_value, pcr_init_value_size, NULL, 0);
ENSURE_OR_GO_EXIT(retval == SM_OK);
retval = Se05x_API_WritePCR(&(pSession->s_ctx), NULL, 0x7fffffff, NULL, 0, pcr_update_value, pcr_update_value_size);
ENSURE_OR_GO_EXIT(retval == SM_OK);
status = sss_asymmetric_context_init(&asymm, &pCtx->session, &ec_keyPair, kAlgorithm_SSS_SHA256, kMode_SSS_Sign);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
status = sss_asymmetric_sign_digest(&asymm, digest, digestLen, signature, &signatureLen);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
sss_asymmetric_context_free(&asymm);
status = sss_asymmetric_context_init(&asymm, &pCtx->session, &ec_keyPair, kAlgorithm_SSS_SHA256, kMode_SSS_Verify);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
status = sss_asymmetric_verify_digest(&asymm, digest, digestLen, signature, signatureLen);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
LOG_I("Sign & Verify is Success with Expected PCR value!!!");
sss_asymmetric_context_free(&asymm);
status = sss_key_store_erase_key(&pCtx->ks, &ec_keyPair);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
status = sss_key_store_erase_key(&pCtx->ks, &pcr_object);
ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
status = kStatus_SSS_Success;
exit:
if (kStatus_SSS_Success == status) {
LOG_I("se05x_PCR Example Success !!!...");
}
else {
LOG_E("se05x_PCR Example Failed !!!...");
}
return status;
}
#endif //if SSS_HAVE_SE05X