Skip to content

Commit ca08164

Browse files
Update hal_dice_update_cdi
1 parent 33aa1e0 commit ca08164

2 files changed

Lines changed: 103 additions & 51 deletions

File tree

arch.mk

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -875,7 +875,8 @@ ifeq ($(TARGET),mcxn)
875875
-I$(ELS_PKC)/src/platforms/mcxn/inc
876876
OBJS+=\
877877
$(ELS_PKC)/src/comps/mcuxClEls/src/mcuxClEls_Common.o \
878-
$(ELS_PKC)/src/comps/mcuxClEls/src/mcuxClEls_Kdf.o
878+
$(ELS_PKC)/src/comps/mcuxClEls/src/mcuxClEls_Kdf.o \
879+
$(ELS_PKC)/src/comps/mcuxClEls/src/mcuxClEls_KeyManagement.o
879880
endif
880881
endif
881882

hal/mcxn.c

Lines changed: 101 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "mcuxClEls_Ecc.h"
4747
#include "mcuxClEls_KeyManagement.h"
4848
#include "mcuxCsslFlowProtection.h"
49+
#include <wolfssl/wolfcrypt/sha256.h>
4950

5051
/* Key slot holding the UDS (pre-loaded by ROM before DICE).
5152
* TODO: Replace with NXP_DIE_DICE_UDS_MK_SK */
@@ -420,13 +421,13 @@ int hal_attestation_get_ueid(uint8_t *buf, size_t *len)
420421
}
421422

422423
/* 32 bytes CUSTOM PAD */
423-
memset(deriv, 0, sizeof(deriv));
424-
memcpy(deriv, "WOLFBOOT-UEID", 13);
424+
XMEMSET(deriv, 0, sizeof(deriv));
425+
XMEMCPY(deriv, "WOLFBOOT-UEID", 13);
425426

426427
/* UEID Type RANDOM */
427428
buf[0] = 0x01;
428429

429-
/* Trigger the HKDF operation.
430+
/* Trigger the HKDF command.
430431
* We just give the names of token and return value
431432
* since it's declared within the macro */
432433
MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(res_hkdf, tok_hkdf,
@@ -439,11 +440,11 @@ int hal_attestation_get_ueid(uint8_t *buf, size_t *len)
439440
MCUX_CSSL_FP_FUNCTION_CALL_END();
440441

441442
/* Wait for hardware to finish */
442-
MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(res_w2, tok_w2,
443+
MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(res_w, tok_w,
443444
mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR));
444445

445-
if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != tok_w2) ||
446-
(MCUXCLELS_STATUS_OK != res_w2))
446+
if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != tok_w) ||
447+
(MCUXCLELS_STATUS_OK != res_w))
447448
return -1;
448449

449450
MCUX_CSSL_FP_FUNCTION_CALL_END();
@@ -459,62 +460,112 @@ int hal_attestation_get_lifecycle(uint32_t *lifecycle)
459460
return 0;
460461
}
461462

463+
/* Derive new CDI from measurement and previous CDI */
462464
int hal_dice_update_cdi(const uint8_t *measurement, size_t meas_len)
463465
{
464466
static int cdi_step = 0;
467+
uint8_t deriv[MCUXCLELS_HKDF_RFC5869_DERIVATIONDATA_SIZE];
468+
wc_Sha256 sha;
469+
mcuxClEls_HkdfOption_t opts;
470+
mcuxClEls_KeyProp_t props;
471+
int ret = 0;
465472

466473
if (cdi_step == 0) {
467474
/*
468-
* Component [0] is the wolfBoot hash. The ROM already incorporated
475+
* Component [0] is the wolfBoot hash. The boot ROM already incorporated
469476
* it as: HKDF(UDS, wolfBoot_hash) -> initial_CDI.
470477
* Skip re-applying it — doing so would produce the wrong CDI chain.
471478
*/
472479
cdi_step++;
473-
return 0;
480+
return ret;
481+
}
482+
else if (cdi_step > 1) {
483+
/* Limit to 2 components (including wolfBoot) due to key slot constraints */
484+
ret = -1;
474485
}
475486

476-
/*
477-
* Component [1+]: mix this measurement into the CDI chain via ELS HKDF RFC5869.
478-
*
479-
* The 32-byte derivation data buffer must be composed as:
480-
* deriv[0..30] = info/label (31 bytes, zero-padded)
481-
* deriv[31] = 0x01 (RFC5869 counter byte for single-block expansion)
482-
* The SDK does NOT add this formatting automatically.
483-
*
484-
* NOTE: The exact label policy (truncate SHA-384 to 31 bytes, or pre-hash
485-
* to SHA-256 then take first 31 bytes) and alignment with the ROM's approach
486-
* for component[0] must be confirmed before finalizing this implementation.
487-
* See also: whether a separate RFC5869 Extract step is needed before Expand.
488-
*
489-
* TODO: Implement using mcuxClEls_KeyDelete_Async + mcuxClEls_Hkdf_Rfc5869_Async:
490-
*
491-
* // Step 1: Free target slot (KDELETE, cmd 0xB)
492-
* MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(...,
493-
* mcuxClEls_KeyDelete_Async(MCXN_ELS_DICE_CDI_DERIVED_KEYSLOT));
494-
* mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR);
495-
*
496-
* // Step 2: Compose derivation data {label[31 bytes], counter[1 byte]}
497-
* uint8_t deriv[MCUXCLELS_HKDF_RFC5869_DERIVATIONDATA_SIZE] = {0};
498-
* size_t label_len = (meas_len < 31u) ? meas_len : 31u;
499-
* memcpy(deriv, measurement, label_len);
500-
* deriv[31] = 0x01u;
501-
*
502-
* // Step 3: Derive new CDI into freed slot
503-
* mcuxClEls_HkdfOption_t opts = {0};
504-
* opts.bits.rtfdrvdat = MCUXCLELS_HKDF_VALUE_RTF_DERIV_DISABLE;
505-
* mcuxClEls_KeyProp_t props = {.word.value =
506-
* MCUXCLELS_KEYPROPERTY_VALUE_HKDF | MCUXCLELS_KEYPROPERTY_VALUE_ACTIVE};
507-
* MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(...,
508-
* mcuxClEls_Hkdf_Rfc5869_Async(opts,
509-
* MCXN_ELS_DICE_CDI_INITIAL_KEYSLOT,
510-
* MCXN_ELS_DICE_CDI_DERIVED_KEYSLOT,
511-
* props, deriv));
512-
* mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR);
513-
*/
514-
cdi_step++;
515-
(void)measurement;
516-
(void)meas_len;
517-
return -1; /* placeholder */
487+
XMEMSET(deriv, 0, sizeof(deriv));
488+
489+
if (measurement == NULL || meas_len == 0) {
490+
ret = -1;
491+
}
492+
493+
if (ret == 0) {
494+
if (meas_len > SHA256_DIGEST_SIZE) {
495+
/* Pre-hash to SHA-256 digest */
496+
ret = wc_InitSha256(&sha);
497+
if (ret == 0) {
498+
ret = wc_Sha256Update(&sha, measurement, (word32)meas_len);
499+
if (ret == 0) {
500+
ret = wc_Sha256Final(&sha, deriv);
501+
}
502+
wc_Sha256Free(&sha);
503+
}
504+
}
505+
else {
506+
XMEMCPY(deriv, measurement, meas_len);
507+
}
508+
}
509+
510+
if (ret == 0) {
511+
/* Trigger the KDELETE command to free the key slot.
512+
* We just give the names of token and return value
513+
* since it's declared within the macro */
514+
MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(res_kdel, tok_kdel,
515+
mcuxClEls_KeyDelete_Async(MCXN_ELS_DICE_CDI_DERIVED_KEYSLOT));
516+
517+
if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_KeyDelete_Async) != tok_kdel) ||
518+
(MCUXCLELS_STATUS_OK_WAIT != res_kdel))
519+
ret = -1;
520+
521+
MCUX_CSSL_FP_FUNCTION_CALL_END();
522+
523+
/* Wait for hardware to finish */
524+
MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(res_w, tok_w,
525+
mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR));
526+
527+
if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != tok_w) ||
528+
(MCUXCLELS_STATUS_OK != res_w))
529+
ret = -1;
530+
531+
MCUX_CSSL_FP_FUNCTION_CALL_END();
532+
}
533+
534+
if (ret == 0) {
535+
opts.word.value = MCUXCLELS_HKDF_ALGO_RFC5869;
536+
/* UPPROT|UKGSRC|UHKDF|FGP|KBASE|KACTV|KSIZE */
537+
props.word.value = 0x440200E1U;
538+
539+
/* Trigger the HKDF command.
540+
* We just give the names of token and return value
541+
* since it's declared within the macro */
542+
MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(res_hkdf, tok_hkdf,
543+
mcuxClEls_Hkdf_Rfc5869_Async(opts,
544+
MCXN_ELS_DICE_CDI_INITIAL_KEYSLOT,
545+
MCXN_ELS_DICE_CDI_DERIVED_KEYSLOT,
546+
props, deriv));
547+
548+
if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_Hkdf_Rfc5869_Async) != tok_hkdf) ||
549+
(MCUXCLELS_STATUS_OK_WAIT != res_hkdf))
550+
ret = -1;
551+
552+
MCUX_CSSL_FP_FUNCTION_CALL_END();
553+
554+
/* Wait for hardware to finish */
555+
MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(res_w, tok_w,
556+
mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR));
557+
558+
if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != tok_w) ||
559+
(MCUXCLELS_STATUS_OK != res_w))
560+
ret = -1;
561+
562+
MCUX_CSSL_FP_FUNCTION_CALL_END();
563+
}
564+
565+
if (ret == 0)
566+
cdi_step++;
567+
568+
return ret;
518569
}
519570

520571
int hal_dice_create_attest_key(void)

0 commit comments

Comments
 (0)