|
59 | 59 | #define MCXN_ELS_DICE_CDI_DERIVED_KEYSLOT 11U |
60 | 60 |
|
61 | 61 | /* wolfBoot stores the per-boot IAK (P-256) here. */ |
62 | | -#define MCXN_ELS_DICE_IAK_KEYSLOT 13U |
| 62 | +#define MCXN_ELS_DICE_IAK_KEYSLOT 9U |
63 | 63 |
|
64 | 64 | #endif |
65 | 65 |
|
@@ -466,8 +466,8 @@ int hal_dice_update_cdi(const uint8_t *measurement, size_t meas_len) |
466 | 466 | static int cdi_step = 0; |
467 | 467 | uint8_t deriv[MCUXCLELS_HKDF_RFC5869_DERIVATIONDATA_SIZE]; |
468 | 468 | wc_Sha256 sha; |
469 | | - mcuxClEls_HkdfOption_t opts; |
470 | | - mcuxClEls_KeyProp_t props; |
| 469 | + mcuxClEls_HkdfOption_t opts = {0}; |
| 470 | + mcuxClEls_KeyProp_t props = {0}; |
471 | 471 | int ret = 0; |
472 | 472 |
|
473 | 473 | if (cdi_step == 0) { |
@@ -532,9 +532,18 @@ int hal_dice_update_cdi(const uint8_t *measurement, size_t meas_len) |
532 | 532 | } |
533 | 533 |
|
534 | 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; |
| 535 | + /* Set HKDF options */ |
| 536 | + opts.bits.hkdf_algo = MCUXCLELS_HKDF_ALGO_RFC5869; |
| 537 | + |
| 538 | + /* Set key properties */ |
| 539 | + props.bits.upprot_priv = MCUXCLELS_KEYPROPERTY_PRIVILEGED_TRUE; |
| 540 | + props.bits.upprot_sec = MCUXCLELS_KEYPROPERTY_SECURE_TRUE; |
| 541 | + props.bits.ukgsrc = MCUXCLELS_KEYPROPERTY_INPUT_FOR_ECC_TRUE; |
| 542 | + props.bits.uhkdf = MCUXCLELS_KEYPROPERTY_HKDF_TRUE; |
| 543 | + props.bits.fgp = MCUXCLELS_KEYPROPERTY_GENERAL_PURPOSE_SLOT_TRUE; |
| 544 | + props.bits.kbase = MCUXCLELS_KEYPROPERTY_BASE_SLOT; |
| 545 | + props.bits.kactv = MCUXCLELS_KEYPROPERTY_ACTIVE_TRUE; |
| 546 | + props.bits.ksize = MCUXCLELS_KEYPROPERTY_KEY_SIZE_256; |
538 | 547 |
|
539 | 548 | /* Trigger the HKDF command. |
540 | 549 | * We just give the names of token and return value |
@@ -568,34 +577,79 @@ int hal_dice_update_cdi(const uint8_t *measurement, size_t meas_len) |
568 | 577 | return ret; |
569 | 578 | } |
570 | 579 |
|
| 580 | +/* Generate P-256 IAK from derived CDI using ELS KEYGEN. |
| 581 | + * Private key stays in ELS keystore. Public key written to system memory. */ |
571 | 582 | int hal_dice_create_attest_key(void) |
572 | 583 | { |
573 | | - /* |
574 | | - * Generate P-256 IAK from derived CDI using ELS KEYGEN. |
575 | | - * Private key stays in ELS keystore. Public key written to system memory. |
576 | | - * |
577 | | - * TODO: Implement using mcuxClEls_KeyDelete_Async + mcuxClEls_EccKeyGen_Async: |
578 | | - * |
579 | | - * // Step 1: Free target slot (KDELETE, cmd 0xB) |
580 | | - * MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(..., |
581 | | - * mcuxClEls_KeyDelete_Async(MCXN_ELS_DICE_IAK_KEYSLOT)); |
582 | | - * mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR); |
583 | | - * |
584 | | - * // Step 2: Generate IAK into freed slot from derived CDI |
585 | | - * static uint8_t pub_key[64] __attribute__((aligned(4))); |
586 | | - * mcuxClEls_EccKeyGenOption_t opts = {0}; |
587 | | - * opts.bits.kgsrc = 0; // deterministic from CDI key material |
588 | | - * opts.bits.kgtypedh = 0; // signing key (not DH) |
589 | | - * mcuxClEls_KeyProp_t props = {.word.value = |
590 | | - * MCUXCLELS_KEYPROPERTY_VALUE_ECSGN | MCUXCLELS_KEYPROPERTY_VALUE_ACTIVE}; |
591 | | - * MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(..., |
592 | | - * mcuxClEls_EccKeyGen_Async(opts, |
593 | | - * MCXN_ELS_DICE_CDI_DERIVED_KEYSLOT, |
594 | | - * MCXN_ELS_DICE_IAK_KEYSLOT, |
595 | | - * props, NULL, pub_key)); |
596 | | - * mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR); |
597 | | - */ |
598 | | - return -1; /* placeholder */ |
| 584 | + static uint8_t pub_key[64] __attribute__((aligned(4))); |
| 585 | + mcuxClEls_EccKeyGenOption_t opts = {0}; |
| 586 | + mcuxClEls_KeyProp_t props = {0}; |
| 587 | + int ret = 0; |
| 588 | + |
| 589 | + /* Trigger the KDELETE command to free the key slot. |
| 590 | + * We just give the names of token and return value |
| 591 | + * since it's declared within the macro */ |
| 592 | + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(res_kdel, tok_kdel, |
| 593 | + mcuxClEls_KeyDelete_Async(MCXN_ELS_DICE_IAK_KEYSLOT)); |
| 594 | + |
| 595 | + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_KeyDelete_Async) != tok_kdel) || |
| 596 | + (MCUXCLELS_STATUS_OK_WAIT != res_kdel)) |
| 597 | + ret = -1; |
| 598 | + |
| 599 | + MCUX_CSSL_FP_FUNCTION_CALL_END(); |
| 600 | + |
| 601 | + /* Wait for hardware to finish */ |
| 602 | + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(res_w, tok_w, |
| 603 | + mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); |
| 604 | + |
| 605 | + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != tok_w) || |
| 606 | + (MCUXCLELS_STATUS_OK != res_w)) |
| 607 | + ret = -1; |
| 608 | + |
| 609 | + MCUX_CSSL_FP_FUNCTION_CALL_END(); |
| 610 | + |
| 611 | + if (ret == 0) { |
| 612 | + /* Set KeyGen options */ |
| 613 | + opts.bits.kgsrc = MCUXCLELS_ECC_OUTPUTKEY_DETERMINISTIC; |
| 614 | + opts.bits.kgtypedh = MCUXCLELS_ECC_OUTPUTKEY_SIGN; |
| 615 | + |
| 616 | + /* Set key properties */ |
| 617 | + props.bits.upprot_priv = MCUXCLELS_KEYPROPERTY_PRIVILEGED_TRUE; |
| 618 | + props.bits.upprot_sec = MCUXCLELS_KEYPROPERTY_SECURE_TRUE; |
| 619 | + props.bits.uecsg = MCUXCLELS_KEYPROPERTY_ECC_TRUE; |
| 620 | + props.bits.uksk = MCUXCLELS_KEYPROPERTY_KSK_TRUE; |
| 621 | + props.bits.fgp = MCUXCLELS_KEYPROPERTY_GENERAL_PURPOSE_SLOT_TRUE; |
| 622 | + props.bits.kbase = MCUXCLELS_KEYPROPERTY_BASE_SLOT; |
| 623 | + props.bits.kactv = MCUXCLELS_KEYPROPERTY_ACTIVE_TRUE; |
| 624 | + props.bits.ksize = MCUXCLELS_KEYPROPERTY_KEY_SIZE_256; |
| 625 | + |
| 626 | + /* Trigger the ECC KeyGen command. |
| 627 | + * We just give the names of token and return value |
| 628 | + * since it's declared within the macro */ |
| 629 | + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(res_kg, tok_kg, |
| 630 | + mcuxClEls_EccKeyGen_Async(opts, |
| 631 | + MCXN_ELS_DICE_CDI_DERIVED_KEYSLOT, |
| 632 | + MCXN_ELS_DICE_IAK_KEYSLOT, |
| 633 | + props, NULL, pub_key)); |
| 634 | + |
| 635 | + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_EccKeyGen_Async) != tok_kg) || |
| 636 | + (MCUXCLELS_STATUS_OK_WAIT != res_kg)) |
| 637 | + ret = -1; |
| 638 | + |
| 639 | + MCUX_CSSL_FP_FUNCTION_CALL_END(); |
| 640 | + |
| 641 | + /* Wait for hardware to finish */ |
| 642 | + MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(res_w, tok_w, |
| 643 | + mcuxClEls_WaitForOperation(MCUXCLELS_ERROR_FLAGS_CLEAR)); |
| 644 | + |
| 645 | + if ((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClEls_WaitForOperation) != tok_w) || |
| 646 | + (MCUXCLELS_STATUS_OK != res_w)) |
| 647 | + ret = -1; |
| 648 | + |
| 649 | + MCUX_CSSL_FP_FUNCTION_CALL_END(); |
| 650 | + } |
| 651 | + |
| 652 | + return ret; |
599 | 653 | } |
600 | 654 |
|
601 | 655 | int hal_dice_sign_hash(const uint8_t *hash, size_t hash_len, |
|
0 commit comments