Skip to content

Commit fc3185b

Browse files
committed
support rsa-pss in ARMORED mode
1 parent e306cc0 commit fc3185b

File tree

2 files changed

+79
-18
lines changed

2 files changed

+79
-18
lines changed

include/image.h

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,67 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok(
478478
asm volatile("nop"); \
479479
}
480480

481+
/**
482+
* Second part of RSA-PSS verification.
483+
*
484+
* Call wc_RsaPSS_CheckPadding twice, then confirm via
485+
* wolfBoot_image_confirm_signature_ok();
486+
*/
487+
#define RSA_PSS_VERIFY_HASH(img, pss_data, pss_data_sz, hash_type) \
488+
{ \
489+
volatile int pss_res; \
490+
if (!img || !pss_data) \
491+
asm volatile("b pnope"); \
492+
/* Redundant set of r0=50*/ \
493+
asm volatile("mov r0, #50":::"r0"); \
494+
asm volatile("mov r0, #50":::"r0"); \
495+
asm volatile("mov r0, #50":::"r0"); \
496+
pss_res = wc_RsaPSS_CheckPadding(img->sha_hash, WOLFBOOT_SHA_DIGEST_SIZE, \
497+
pss_data, pss_data_sz, hash_type); \
498+
/* Redundant checks that ensure the function actually returned 0 */ \
499+
asm volatile("cmp r0, #0":::"cc"); \
500+
asm volatile("cmp r0, #0":::"cc"); \
501+
asm volatile("cmp r0, #0":::"cc"); \
502+
asm volatile("bne pnope":::"cc"); \
503+
asm volatile("cmp r0, #0"); \
504+
asm volatile("cmp r0, #0"); \
505+
asm volatile("cmp r0, #0"); \
506+
asm volatile("bne pnope":::"cc"); \
507+
asm volatile("cmp r0, #0":::"cc"); \
508+
asm volatile("cmp r0, #0":::"cc"); \
509+
asm volatile("cmp r0, #0":::"cc"); \
510+
asm volatile("bne pnope"); \
511+
asm volatile("cmp r0, #0":::"cc"); \
512+
asm volatile("cmp r0, #0":::"cc"); \
513+
asm volatile("cmp r0, #0":::"cc"); \
514+
asm volatile("bne pnope"); \
515+
/* Repeat wc_RsaPSS_CheckPadding call */ \
516+
pss_res = wc_RsaPSS_CheckPadding(img->sha_hash, WOLFBOOT_SHA_DIGEST_SIZE, \
517+
pss_data, pss_data_sz, hash_type); \
518+
pss_res; \
519+
/* Redundant checks that ensure the function actually returned 0 */ \
520+
asm volatile("cmp r0, #0":::"cc"); \
521+
asm volatile("cmp r0, #0":::"cc"); \
522+
asm volatile("cmp r0, #0":::"cc"); \
523+
asm volatile("bne pnope"); \
524+
asm volatile("cmp r0, #0":::"cc"); \
525+
asm volatile("cmp r0, #0":::"cc"); \
526+
asm volatile("cmp r0, #0":::"cc"); \
527+
asm volatile("bne pnope"); \
528+
asm volatile("cmp r0, #0":::"cc"); \
529+
asm volatile("cmp r0, #0":::"cc"); \
530+
asm volatile("cmp r0, #0":::"cc"); \
531+
asm volatile("bne pnope"); \
532+
asm volatile("cmp r0, #0":::"cc"); \
533+
asm volatile("cmp r0, #0":::"cc"); \
534+
asm volatile("cmp r0, #0":::"cc"); \
535+
asm volatile("bne pnope"); \
536+
/* Confirm that the signature is OK */ \
537+
wolfBoot_image_confirm_signature_ok(img); \
538+
asm volatile("pnope:"); \
539+
asm volatile("nop"); \
540+
}
541+
481542
/**
482543
* ECC / Ed / PQ signature verification.
483544
* Those verify functions set an additional value 'p_res'
@@ -1247,6 +1308,11 @@ static void UNUSEDFUNCTION wolfBoot_image_clear_signature_ok(
12471308
if (XMEMCMP(img->sha_hash, digest, WOLFBOOT_SHA_DIGEST_SIZE) == 0) \
12481309
wolfBoot_image_confirm_signature_ok(img);
12491310

1311+
#define RSA_PSS_VERIFY_HASH(img, pss_data, pss_data_sz, hash_type) \
1312+
if (wc_RsaPSS_CheckPadding(img->sha_hash, WOLFBOOT_SHA_DIGEST_SIZE, \
1313+
pss_data, pss_data_sz, hash_type) == 0) \
1314+
wolfBoot_image_confirm_signature_ok(img);
1315+
12501316
#define PART_SANITY_CHECK(p) \
12511317
if (((p)->hdr_ok != 1) || ((p)->sha_ok != 1) || ((p)->signature_ok != 1)) \
12521318
wolfBoot_panic()

src/image.c

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -601,34 +601,29 @@ static void wolfBoot_verify_signature_rsa_pss(uint8_t key_slot,
601601
return;
602602
}
603603

604-
/* wolfCrypt software RSA-PSS verify */
604+
/* wolfCrypt software RSA-PSS verify (two-step)
605+
*
606+
* Step 1 (RSA_VERIFY_FN): wc_RsaPSS_VerifyInline performs the RSA
607+
* operation and PSS unmasking, returning a pointer to the PSS data and
608+
* its length.
609+
*
610+
* Step 2 (RSA_PSS_VERIFY_HASH): wc_RsaPSS_CheckPadding verifies the PSS
611+
* padding against img->sha_hash. Returns 0 on success. Both steps are
612+
* armored when WOLFBOOT_ARMORED is enabled. */
605613
ret = wc_InitRsaKey(&rsa, NULL);
606614
if (ret == 0) {
607615
/* Import public key */
608616
ret = wc_RsaPublicKeyDecode((byte*)pubkey, &inOutIdx, &rsa, pubkey_sz);
609617
if (ret >= 0) {
610618
XMEMCPY(output, sig, RSA_IMAGE_SIGNATURE_SIZE);
611619
RSA_VERIFY_FN(ret,
612-
wc_RsaPSS_VerifyCheckInline, output, RSA_IMAGE_SIGNATURE_SIZE,
613-
&digest_out, img->sha_hash, WOLFBOOT_SHA_DIGEST_SIZE,
614-
hash_type, mgf, &rsa);
620+
wc_RsaPSS_VerifyInline, output, RSA_IMAGE_SIGNATURE_SIZE,
621+
&digest_out, hash_type, mgf, &rsa);
615622
}
616623
}
617624
wc_FreeRsaKey(&rsa);
618-
/* wc_RsaPSS_VerifyCheckInline returns the PSS-verified data length on
619-
* success (>= digest size), or a negative error code on failure.
620-
* The hash comparison is performed internally by the function.
621-
*
622-
* Note: uses '>=' rather than '==' because PSS verify returns the digest
623-
* size on success, unlike PKCS#1 v1.5 which returns exact decoded length.
624-
*
625-
* ARMORED limitation: the PKCS#1 v1.5 path uses both RSA_VERIFY_FN and
626-
* RSA_VERIFY_HASH armored macros (two hardened gates), but PSS only uses
627-
* RSA_VERIFY_FN because wc_RsaPSS_VerifyCheckInline performs the hash
628-
* comparison internally. The branch below is not armored. Full armored
629-
* hardening for PSS would require a new macro or restructuring. */
630-
if (ret >= WOLFBOOT_SHA_DIGEST_SIZE && img) {
631-
wolfBoot_image_confirm_signature_ok(img);
625+
if (ret >= WOLFBOOT_SHA_DIGEST_SIZE && img && digest_out) {
626+
RSA_PSS_VERIFY_HASH(img, digest_out, ret, hash_type);
632627
}
633628
}
634629

0 commit comments

Comments
 (0)