From e91038088950021734b2950275f9f75c9073e1cc Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 23 Jun 2020 11:39:30 -0700 Subject: [PATCH 1/3] Add support for using an RSA signature that includes ASN.1 encoded header. On by default, can be disabled using `NO_RSA_SIG_ENCODING`. Added support for signing with encoding using `--rsa2048enc` or `--rsa4096enc`. --- src/image.c | 67 +++++++++++++++++++++++++++++++++++++++---- tools/keytools/sign.c | 31 ++++++++++++++++++-- 2 files changed, 89 insertions(+), 9 deletions(-) diff --git a/src/image.c b/src/image.c index 54e779b3..88d2cf56 100644 --- a/src/image.c +++ b/src/image.c @@ -115,8 +115,54 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig) #endif /* WOLFBOOT_SIGN_ECC256 */ #if defined(WOLFBOOT_SIGN_RSA2048) || defined (WOLFBOOT_SIGN_RSA4096) -#include +#include #include + +#ifndef NO_RSA_SIG_ENCODING /* option to reduce code size */ +static inline int DecodeAsn1Tag(const uint8_t* input, int inputSz, int* inOutIdx, + int* tag_len, uint8_t tag) +{ + if (input[*inOutIdx] != tag) { + return -1; + } + (*inOutIdx)++; + *tag_len = input[*inOutIdx]; + (*inOutIdx)++; + if (*tag_len + *inOutIdx > inputSz) { + return -1; + } + return 0; +} +static int RsaDecodeSignature(uint8_t** pInput, int inputSz) +{ + uint8_t* input = *pInput; + int idx = 0; + int digest_len = 0, algo_len, tot_len; + + /* sequence - total size */ + if (DecodeAsn1Tag(input, inputSz, &idx, &tot_len, + ASN_SEQUENCE | ASN_CONSTRUCTED) != 0) { + return -1; + } + + /* sequence - algoid */ + if (DecodeAsn1Tag(input, inputSz, &idx, &algo_len, + ASN_SEQUENCE | ASN_CONSTRUCTED) != 0) { + return -1; + } + idx += algo_len; /* skip algoid */ + + /* digest */ + if (DecodeAsn1Tag(input, inputSz, &idx, &digest_len, + ASN_OCTET_STRING) != 0) { + return -1; + } + /* return digest buffer pointer */ + *pInput = &input[idx]; + return digest_len; +} +#endif /* !NO_RSA_SIG_ENCODING */ + static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig) { #ifdef WOLFBOOT_TPM @@ -142,7 +188,8 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig) #else int ret; struct RsaKey rsa; - uint8_t digest_out[IMAGE_SIGNATURE_SIZE]; + uint8_t* digest_out = NULL; + uint8_t output[IMAGE_SIGNATURE_SIZE]; word32 in_out = 0; ret = wc_InitRsaKey(&rsa, NULL); @@ -156,10 +203,18 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig) /* Failed to import rsa key */ return -1; } - ret = wc_RsaSSL_Verify(sig, IMAGE_SIGNATURE_SIZE, digest_out, IMAGE_SIGNATURE_SIZE, &rsa); - if (ret == WOLFBOOT_SHA_DIGEST_SIZE) { - if (memcmp(digest_out, hash, ret) == 0) - return 0; + ret = wc_RsaSSL_Verify(sig, IMAGE_SIGNATURE_SIZE, output, + IMAGE_SIGNATURE_SIZE, &rsa); + digest_out = output; +#ifndef NO_RSA_SIG_ENCODING + if (ret > WOLFBOOT_SHA_DIGEST_SIZE) { + /* larger result indicates it might have an ASN.1 encoded header */ + ret = RsaDecodeSignature(&digest_out, ret); + } +#endif + if (ret == WOLFBOOT_SHA_DIGEST_SIZE && digest_out && + memcmp(digest_out, hash, ret) == 0) { + return 0; } return -1; #endif /* WOLFBOOT_TPM */ diff --git a/tools/keytools/sign.c b/tools/keytools/sign.c index 32e6c9d8..9ec029af 100755 --- a/tools/keytools/sign.c +++ b/tools/keytools/sign.c @@ -37,6 +37,7 @@ #include #include +#include #ifdef HAVE_CHACHA #include @@ -158,6 +159,7 @@ int main(int argc, char** argv) uint32_t idx, read_sz, pos; uint16_t image_type; uint32_t fw_version32; + uint32_t sign_wenc = 0; struct stat attrib; union { #ifdef HAVE_ED25519 @@ -178,7 +180,7 @@ int main(int argc, char** argv) /* Check arguments and print usage */ if (argc < 4 || argc > 10) { - printf("Usage: %s [--ed25519 | --ecc256 | --rsa2048 | --rsa4096 ] [--sha256 | --sha3] [--wolfboot-update] [--encrypt enc_key.bin] image key.der fw_version\n", argv[0]); + printf("Usage: %s [--ed25519 | --ecc256 | --rsa2048 | --rsa2048enc | --rsa4096 | --rsa4096enc ] [--sha256 | --sha3] [--wolfboot-update] [--encrypt enc_key.bin] image key.der fw_version\n", argv[0]); printf(" - or - "); printf(" %s [--sha256 | --sha3] [--sha-only] [--wolfboot-update] image pub_key.der fw_version\n", argv[0]); printf(" - or - "); @@ -196,10 +198,20 @@ int main(int argc, char** argv) sign = SIGN_ECC256; sign_str = "ECC256"; } + else if (strcmp(argv[i], "--rsa2048enc") == 0) { + sign = SIGN_RSA2048; + sign_str = "RSA2048ENC"; + sign_wenc = 1; + } else if (strcmp(argv[i], "--rsa2048") == 0) { sign = SIGN_RSA2048; sign_str = "RSA2048"; } + else if (strcmp(argv[i], "--rsa4096enc") == 0) { + sign = SIGN_RSA4096; + sign_str = "RSA4096ENC"; + sign_wenc = 1; + } else if (strcmp(argv[i], "--rsa4096") == 0) { sign = SIGN_RSA4096; sign_str = "RSA4096"; @@ -585,7 +597,7 @@ int main(int argc, char** argv) } /* Sign the digest */ - ret = NOT_COMPILED_IN; /* default erorr */ + ret = NOT_COMPILED_IN; /* default error */ signature = malloc(signature_sz); if (signature == NULL) { printf("Signature malloc error!\n"); @@ -614,7 +626,20 @@ int main(int argc, char** argv) } else if (sign == SIGN_RSA2048 || sign == SIGN_RSA4096) { #ifndef NO_RSA - ret = wc_RsaSSL_Sign(digest, digest_sz, signature, signature_sz, &key.rsa, &rng); + uint32_t enchash_sz = digest_sz; + uint8_t* enchash = digest; + if (sign_wenc) { + /* add ASN.1 signature encoding */ + int hashOID = 0; + if (hash_algo == HASH_SHA256) + hashOID = SHA256h; + else if (hash_algo == HASH_SHA3) + hashOID = SHA3_384h; + enchash_sz = wc_EncodeSignature(buf, digest, digest_sz, hashOID); + enchash = buf; + } + ret = wc_RsaSSL_Sign(enchash, enchash_sz, signature, signature_sz, + &key.rsa, &rng); wc_FreeRsaKey(&key.rsa); if (ret > 0) { signature_sz = ret; From 0c5b66c39e4e584a979377e6d6f456943eb78188 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 22 Jun 2020 12:10:40 -0700 Subject: [PATCH 2/3] Fixes for TPM with RSA. * Requires PR https://github.com/wolfSSL/wolfTPM/pull/101 * Cleanup of software vs. TPM code `wolfBoot_verify_signature` functions (ECC and RSA) * Adjusted the stack size checks with TPM. * Added STM32F4 programming/debugging instructions. * In V=1 mode show the keygen command. --- .gitignore | 2 +- Makefile | 92 ++++++++++++---------- config/examples/stm32f4.config | 1 + docs/Targets.md | 23 ++++++ lib/wolfTPM | 2 +- src/image.c | 135 ++++++++++++++++++++++++--------- tools/keytools/sign.c | 2 +- 7 files changed, 180 insertions(+), 77 deletions(-) diff --git a/.gitignore b/.gitignore index 7044c209..8f1b8068 100644 --- a/.gitignore +++ b/.gitignore @@ -78,6 +78,7 @@ include/target.h # Test tools tools/test-expect-version/test-expect-version tools/test-update-server/server +tools/uart-flash-server/ufserver config/*.ld # Generated confiuguration file @@ -89,4 +90,3 @@ config/*.ld # IAR files not under version control IDE/IAR/settings IDE/IAR/*.ewt - diff --git a/Makefile b/Makefile index 220f7ce0..2aa1fc3c 100644 --- a/Makefile +++ b/Makefile @@ -38,13 +38,17 @@ ifeq ($(SIGN),ECC256) PRIVATE_KEY=ecc256.der WOLFCRYPT_OBJS+= \ $(MATH_OBJS) \ - ./lib/wolfssl/wolfcrypt/src/ecc.o \ - ./lib/wolfssl/wolfcrypt/src/memory.o \ - ./lib/wolfssl/wolfcrypt/src/wc_port.o \ + ./lib/wolfssl/wolfcrypt/src/ecc.o \ + ./lib/wolfssl/wolfcrypt/src/memory.o \ + ./lib/wolfssl/wolfcrypt/src/wc_port.o \ ./lib/wolfssl/wolfcrypt/src/hash.o \ ./src/xmalloc_ecc.o - CFLAGS+=-DWOLFBOOT_SIGN_ECC256 -DXMALLOC_USER \ - -Wstack-usage=1024 + CFLAGS+=-DWOLFBOOT_SIGN_ECC256 -DXMALLOC_USER + ifeq ($(WOLFTPM),0) + CFLAGS+=-Wstack-usage=1024 + else + CFLAGS+=-Wstack-usage=6680 + endif PUBLIC_KEY_OBJS=./src/ecc256_pub_key.o endif @@ -53,15 +57,14 @@ ifeq ($(SIGN),ED25519) SIGN_OPTIONS+=--ed25519 PRIVATE_KEY=ed25519.der WOLFCRYPT_OBJS+= ./lib/wolfssl/wolfcrypt/src/sha512.o \ - ./lib/wolfssl/wolfcrypt/src/ed25519.o \ - ./lib/wolfssl/wolfcrypt/src/ge_low_mem.o \ + ./lib/wolfssl/wolfcrypt/src/ed25519.o \ + ./lib/wolfssl/wolfcrypt/src/ge_low_mem.o \ ./lib/wolfssl/wolfcrypt/src/hash.o \ - ./lib/wolfssl/wolfcrypt/src/wolfmath.o \ - ./lib/wolfssl/wolfcrypt/src/wc_port.o \ + ./lib/wolfssl/wolfcrypt/src/wolfmath.o \ + ./lib/wolfssl/wolfcrypt/src/wc_port.o \ ./lib/wolfssl/wolfcrypt/src/fe_low_mem.o PUBLIC_KEY_OBJS=./src/ed25519_pub_key.o - CFLAGS+=-DWOLFBOOT_SIGN_ED25519 \ - -Wstack-usage=1024 + CFLAGS+=-DWOLFBOOT_SIGN_ED25519 -Wstack-usage=1024 endif ifeq ($(SIGN),RSA2048) @@ -72,14 +75,19 @@ ifeq ($(SIGN),RSA2048) WOLFCRYPT_OBJS+= \ $(RSA_EXTRA_OBJS) \ $(MATH_OBJS) \ - ./lib/wolfssl/wolfcrypt/src/rsa.o \ - ./lib/wolfssl/wolfcrypt/src/asn.o \ - ./lib/wolfssl/wolfcrypt/src/hash.o \ - ./lib/wolfssl/wolfcrypt/src/wc_port.o \ - ./src/xmalloc_rsa.o + ./lib/wolfssl/wolfcrypt/src/rsa.o \ + ./lib/wolfssl/wolfcrypt/src/asn.o \ + ./lib/wolfssl/wolfcrypt/src/hash.o \ + ./lib/wolfssl/wolfcrypt/src/wc_port.o \ + ./src/xmalloc_rsa.o PUBLIC_KEY_OBJS=./src/rsa2048_pub_key.o CFLAGS+=-DWOLFBOOT_SIGN_RSA2048 -DXMALLOC_USER $(RSA_EXTRA_CFLAGS) \ - -Wstack-usage=12288 -DIMAGE_HEADER_SIZE=512 + -DIMAGE_HEADER_SIZE=512 + ifeq ($(WOLFTPM),0) + CFLAGS+=-Wstack-usage=12288 + else + CFLAGS+=-Wstack-usage=8320 + endif endif ifeq ($(SIGN),RSA4096) @@ -90,35 +98,41 @@ ifeq ($(SIGN),RSA4096) WOLFCRYPT_OBJS+= \ $(RSA_EXTRA_OBJS) \ $(MATH_OBJS) \ - ./lib/wolfssl/wolfcrypt/src/rsa.o \ - ./lib/wolfssl/wolfcrypt/src/asn.o \ - ./lib/wolfssl/wolfcrypt/src/hash.o \ - ./lib/wolfssl/wolfcrypt/src/wolfmath.o \ - ./src/xmalloc_rsa.o + ./lib/wolfssl/wolfcrypt/src/rsa.o \ + ./lib/wolfssl/wolfcrypt/src/asn.o \ + ./lib/wolfssl/wolfcrypt/src/hash.o \ + ./lib/wolfssl/wolfcrypt/src/wolfmath.o \ + ./lib/wolfssl/wolfcrypt/src/wc_port.o \ + ./src/xmalloc_rsa.o PUBLIC_KEY_OBJS=./src/rsa4096_pub_key.o CFLAGS+=-DWOLFBOOT_SIGN_RSA4096 -DXMALLOC_USER $(RSA_EXTRA_CFLAGS) \ - -Wstack-usage=12288 -DIMAGE_HEADER_SIZE=1024 + -DIMAGE_HEADER_SIZE=1024 + ifeq ($(WOLFTPM),0) + CFLAGS+=-Wstack-usage=12288 + else + CFLAGS+=-Wstack-usage=10680 + endif endif CFLAGS+=-Wall -Wextra -Wno-main -ffreestanding -Wno-unused \ - -I. -Iinclude/ -Ilib/wolfssl -nostartfiles \ - -DWOLFSSL_USER_SETTINGS \ - -DPLATFORM_$(TARGET) + -I. -Iinclude/ -Ilib/wolfssl -nostartfiles \ + -DWOLFSSL_USER_SETTINGS \ + -DPLATFORM_$(TARGET) ifeq ($(RAM_CODE),1) - CFLAGS+= -DRAM_CODE + CFLAGS+= -DRAM_CODE endif ifeq ($(DUALBANK_SWAP),1) - CFLAGS+= -DDUALBANK_SWAP + CFLAGS+= -DDUALBANK_SWAP endif ifeq ($(SPI_FLASH),1) - EXT_FLASH=1 - CFLAGS+= -DSPI_FLASH=1 - OBJS+= src/spi_flash.o - WOLFCRYPT_OBJS+=hal/spi/spi_drv_$(SPI_TARGET).o + EXT_FLASH=1 + CFLAGS+= -DSPI_FLASH=1 + OBJS+= src/spi_flash.o + WOLFCRYPT_OBJS+=hal/spi/spi_drv_$(SPI_TARGET).o endif ifeq ($(UART_FLASH),1) @@ -126,8 +140,8 @@ ifeq ($(UART_FLASH),1) endif ifeq ($(ENCRYPT),1) - CFLAGS+=-DEXT_ENCRYPTED=1 - WOLFCRYPT_OBJS+=./lib/wolfssl/wolfcrypt/src/chacha.o + CFLAGS+=-DEXT_ENCRYPTED=1 + WOLFCRYPT_OBJS+=./lib/wolfssl/wolfcrypt/src/chacha.o endif ifeq ($(EXT_FLASH),1) @@ -242,15 +256,13 @@ include tools/test.mk include tools/test-enc.mk ed25519.der: - @$(KEYGEN_TOOL) $(KEYGEN_OPTIONS) src/ed25519_pub_key.c + $(Q)$(KEYGEN_TOOL) $(KEYGEN_OPTIONS) src/ed25519_pub_key.c ecc256.der: - @$(KEYGEN_TOOL) $(KEYGEN_OPTIONS) src/ecc256_pub_key.c - + $(Q)$(KEYGEN_TOOL) $(KEYGEN_OPTIONS) src/ecc256_pub_key.c rsa2048.der: - @$(KEYGEN_TOOL) $(KEYGEN_OPTIONS) src/rsa2048_pub_key.c - + $(Q)$(KEYGEN_TOOL) $(KEYGEN_OPTIONS) src/rsa2048_pub_key.c rsa4096.der: - @$(KEYGEN_TOOL) $(KEYGEN_OPTIONS) src/rsa4096_pub_key.c + $(Q)$(KEYGEN_TOOL) $(KEYGEN_OPTIONS) src/rsa4096_pub_key.c keytools: @make -C tools/keytools diff --git a/config/examples/stm32f4.config b/config/examples/stm32f4.config index 20bfe5a7..108d633a 100644 --- a/config/examples/stm32f4.config +++ b/config/examples/stm32f4.config @@ -21,3 +21,4 @@ WOLFBOOT_SECTOR_SIZE?=0x20000 WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x20000 WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x40000 WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x60000 +WOLFTPM?=0 diff --git a/docs/Targets.md b/docs/Targets.md index 21cd750d..156a43cb 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -37,6 +37,29 @@ On other systems, the SWAP space can be as small as 512B, if multiple smaller fl More information about the geometry of the flash and in-application programming (IAP) can be found in the manufacturer manual of each target device. +### STM32F4 Programming + +``` +st-flash write factory.bin 0x08000000 +``` + +### STM32F4 Debugging + +1. Start GDB server + +OpenOCD: `openocd --file ./config/openocd/openocd_stm32f4.cfg` +OR +ST-Link: `st-util -p 3333` + +2. Start GDB Client + +```sh +arm-none-eabi-gdb +add-symbol-file test-app/image.elf 0x20100 +mon reset init +b main +c +``` ## STM32L0x3 diff --git a/lib/wolfTPM b/lib/wolfTPM index 156fd122..ad255402 160000 --- a/lib/wolfTPM +++ b/lib/wolfTPM @@ -1 +1 @@ -Subproject commit 156fd1225e5ba04a4510ff4733a96d7875aa634c +Subproject commit ad2554020820a4348003167a59de4afba525d897 diff --git a/src/image.c b/src/image.c index 88d2cf56..bcba6aeb 100644 --- a/src/image.c +++ b/src/image.c @@ -65,27 +65,39 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig) #define ECC_KEY_SIZE 32 static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig) { + int ret, verify_res = 0; #ifdef WOLFBOOT_TPM - int rc; WOLFTPM2_KEY tpmKey; + #ifdef DEBUG + const char* errStr; + #endif /* Load public key into TPM */ - XMEMSET(&tpmKey, 0, sizeof(tpmKey)); - rc = wolfTPM2_LoadEccPublicKey(&wolftpm_dev, &tpmKey, TPM_ECC_NIST_P256, + memset(&tpmKey, 0, sizeof(tpmKey)); + ret = wolfTPM2_LoadEccPublicKey(&wolftpm_dev, &tpmKey, TPM_ECC_NIST_P256, KEY_BUFFER, ECC_KEY_SIZE, KEY_BUFFER + ECC_KEY_SIZE, ECC_KEY_SIZE); - if (rc < 0) + if (ret < 0) return -1; - rc = wolfTPM2_VerifyHash(&wolftpm_dev, &tpmKey, sig, IMAGE_SIGNATURE_SIZE, - hash, WOLFBOOT_SHA_DIGEST_SIZE); + ret = wolfTPM2_VerifyHashScheme(&wolftpm_dev, &tpmKey, sig, IMAGE_SIGNATURE_SIZE, + hash, WOLFBOOT_SHA_DIGEST_SIZE, TPM_ALG_ECDSA, TPM_ALG_SHA256); wolfTPM2_UnloadHandle(&wolftpm_dev, &tpmKey.handle); - if (rc < 0) - return -1; - return 0; + if (ret == 0) { + verify_res = 1; /* TPM does hash verify compare */ + } + else { + #ifdef DEBUG + /* retrieve error string (for debugging) */ + errStr = wolfTPM2_GetRCString(ret); + (void)errStr; + #endif + ret = -1; + } #else - int ret, res; + /* wolfCrypt software ECC verify */ mp_int r, s; ecc_key ecc; + ret = wc_ecc_init(&ecc); if (ret < 0) { /* Failed to initialize key */ @@ -105,12 +117,13 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig) mp_init(&s); mp_read_unsigned_bin(&r, sig, ECC_KEY_SIZE); mp_read_unsigned_bin(&s, sig + ECC_KEY_SIZE, ECC_KEY_SIZE); - ret = wc_ecc_verify_hash_ex(&r, &s, hash, WOLFBOOT_SHA_DIGEST_SIZE, &res, &ecc); - if ((ret < 0) || (res == 0)) { - return -1; - } - return 0; + ret = wc_ecc_verify_hash_ex(&r, &s, hash, WOLFBOOT_SHA_DIGEST_SIZE, &verify_res, &ecc); #endif /* WOLFBOOT_TPM */ + if (ret < 0 || verify_res == 0) + ret = -1; + else + ret = 0; + return ret; } #endif /* WOLFBOOT_SIGN_ECC256 */ @@ -163,33 +176,85 @@ static int RsaDecodeSignature(uint8_t** pInput, int inputSz) } #endif /* !NO_RSA_SIG_ENCODING */ +#ifdef WOLFBOOT_TPM +/* RSA PKCSV15 un-padding with RSA_BLOCK_TYPE_1 (public) */ +/* UnPad plaintext, set start to *output, return length of plaintext or error */ +static int RsaUnPad(const byte *pkcsBlock, int pkcsBlockLen, byte **output) +{ + int ret = BAD_FUNC_ARG, i; + if (output == NULL || pkcsBlockLen < 2 || pkcsBlockLen > 0xFFFF) { + return BAD_FUNC_ARG; + } + /* First byte must be 0x00 and Second byte, block type, 0x01 */ + if (pkcsBlock[0] != 0 || pkcsBlock[1] != RSA_BLOCK_TYPE_1) { + return RSA_PAD_E; + } + /* check the padding until we find the separator */ + for (i = 2; i < pkcsBlockLen && pkcsBlock[i++] == 0xFF; ) { } + /* Minimum of 11 bytes of pre-message data and must have separator. */ + if (i < RSA_MIN_PAD_SZ || pkcsBlock[i-1] != 0) { + return RSA_PAD_E; + } + *output = (byte *)(pkcsBlock + i); + ret = pkcsBlockLen - i; + return ret; +} +#endif /* WOLFBOOT_TPM */ + static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig) { + int ret; + uint8_t output[IMAGE_SIGNATURE_SIZE]; + int output_sz = sizeof(output); + uint8_t* digest_out = NULL; #ifdef WOLFBOOT_TPM - int rc; WOLFTPM2_KEY tpmKey; const byte *n = NULL, *e = NULL; word32 nSz = 0, eSz = 0, inOutIdx = 0; + #ifdef DEBUG + const char* errStr; + #endif /* Extract DER RSA key struct */ - rc = wc_RsaPublicKeyDecode_ex(KEY_BUFFER, &inOutIdx, KEY_LEN, &n, &nSz, &e, &eSz); - if (rc < 0) + ret = wc_RsaPublicKeyDecode_ex(KEY_BUFFER, &inOutIdx, KEY_LEN, &n, &nSz, &e, &eSz); + if (ret < 0) return -1; /* Load public key into TPM */ - XMEMSET(&tpmKey, 0, sizeof(tpmKey)); - rc = wolfTPM2_LoadRsaPublicKey(&wolftpm_dev, &tpmKey, n, nSz, *((word32*)e)); - if (rc < 0) + memset(&tpmKey, 0, sizeof(tpmKey)); + ret = wolfTPM2_LoadRsaPublicKey_ex(&wolftpm_dev, &tpmKey, n, nSz, + *((word32*)e), TPM_ALG_NULL, TPM_ALG_SHA256); + if (ret != 0) { + #ifdef DEBUG + /* retrieve error string (for debugging) */ + errStr = wolfTPM2_GetRCString(ret); + (void)errStr; + #endif return -1; - rc = wolfTPM2_VerifyHash(&wolftpm_dev, &tpmKey, sig, IMAGE_SIGNATURE_SIZE, - hash, WOLFBOOT_SHA_DIGEST_SIZE); + } + + /* Perform public decrypt and manually un-pad */ + ret = wolfTPM2_RsaEncrypt(&wolftpm_dev, &tpmKey, + TPM_ALG_NULL, /* no padding */ + sig, IMAGE_SIGNATURE_SIZE, + output, &output_sz); + if (ret != 0) { + #ifdef DEBUG + /* retrieve error string (for debugging) */ + errStr = wolfTPM2_GetRCString(ret); + (void)errStr; + #endif + ret = -1; + } + else { + /* Perform PKCSv1.5 UnPadding */ + ret = RsaUnPad(output, output_sz, &digest_out); + } wolfTPM2_UnloadHandle(&wolftpm_dev, &tpmKey.handle); - return rc; + #else - int ret; + /* wolfCrypt software RSA verify */ struct RsaKey rsa; - uint8_t* digest_out = NULL; - uint8_t output[IMAGE_SIGNATURE_SIZE]; word32 in_out = 0; ret = wc_InitRsaKey(&rsa, NULL); @@ -201,11 +266,13 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig) ret = wc_RsaPublicKeyDecode((byte*)KEY_BUFFER, &in_out, &rsa, KEY_LEN); if (ret < 0) { /* Failed to import rsa key */ + wc_FreeRsaKey(&rsa); return -1; } - ret = wc_RsaSSL_Verify(sig, IMAGE_SIGNATURE_SIZE, output, - IMAGE_SIGNATURE_SIZE, &rsa); + ret = wc_RsaSSL_Verify(sig, IMAGE_SIGNATURE_SIZE, output, output_sz, &rsa); digest_out = output; +#endif /* WOLFBOOT_TPM */ + #ifndef NO_RSA_SIG_ENCODING if (ret > WOLFBOOT_SHA_DIGEST_SIZE) { /* larger result indicates it might have an ASN.1 encoded header */ @@ -216,10 +283,10 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig) memcmp(digest_out, hash, ret) == 0) { return 0; } - return -1; -#endif /* WOLFBOOT_TPM */ + + return ret; } -#endif /* WOLFBOOT_SIGN_RSA2048 */ +#endif /* WOLFBOOT_SIGN_RSA2048 || WOLFBOOT_SIGN_RSA4096 */ static uint16_t get_header_ext(struct wolfBoot_image *img, uint16_t type, uint8_t **ptr); @@ -298,7 +365,7 @@ static int image_sha256(struct wolfBoot_image *img, uint8_t *hash) stored_sha_len = get_header(img, HDR_SHA256, &stored_sha); if (stored_sha_len != WOLFBOOT_SHA_DIGEST_SIZE) return -1; - XMEMSET(&tpmHash, 0, sizeof(tpmHash)); + memset(&tpmHash, 0, sizeof(tpmHash)); rc = wolfTPM2_HashStart(&wolftpm_dev, &tpmHash, TPM_ALG_SHA256, (const byte*)usageAuth, sizeof(usageAuth)-1); if (rc != 0) @@ -368,7 +435,7 @@ static void key_sha256(uint8_t *hash) const char usageAuth[] = "wolfBoot TPM Usage Auth"; uint32_t hashSz = WOLFBOOT_SHA_DIGEST_SIZE; WOLFTPM2_HASH tpmHash; - XMEMSET(&tpmHash, 0, sizeof(tpmHash)); + memset(&tpmHash, 0, sizeof(tpmHash)); rc = wolfTPM2_HashStart(&wolftpm_dev, &tpmHash, TPM_ALG_SHA256, (const byte*)usageAuth, sizeof(usageAuth)-1); if (rc != 0) diff --git a/tools/keytools/sign.c b/tools/keytools/sign.c index 9ec029af..f0acf511 100755 --- a/tools/keytools/sign.c +++ b/tools/keytools/sign.c @@ -392,7 +392,7 @@ int main(int argc, char** argv) ret = wc_ecc_import_unsigned(&key.ecc, &key_buffer[0], &key_buffer[32], &key_buffer[64], ECC_SECP256R1); if (ret == 0) { - pubkey = key_buffer; /* first 64 bytes is public porition */ + pubkey = key_buffer; /* first 64 bytes is public portion */ pubkey_sz = 64; } } From e303c282c7bbb6e1edb7f6143a061fc893e8912c Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Wed, 24 Jun 2020 16:56:32 +0200 Subject: [PATCH 3/3] Added TPM+RSA automated tests for jenkins --- tools/test.mk | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/tools/test.mk b/tools/test.mk index 6afc9ce4..7399cb05 100644 --- a/tools/test.mk +++ b/tools/test.mk @@ -308,7 +308,7 @@ test-53-rollback-RSA: $(EXPVER) FORCE test-61-forward-update-no-downgrade-TPM: $(EXPVER) FORCE @make test-tpm-on - @make test-01-forward-update-no-downgrade SIGN=ECC256 WOLFTPM=1 + @make test-01-forward-update-no-downgrade SIGN=ECC256 WOLFTPM=1 TPM2=1 @make test-tpm-off test-63-rollback-TPM: $(EXPVER) FORCE @@ -334,6 +334,16 @@ test-101-forward-update-no-downgrade-RSA2048-SHA3: $(EXPVER) FORCE test-111-forward-update-no-downgrade-RSA4096-SHA3: $(EXPVER) FORCE @make test-01-forward-update-no-downgrade SIGN=RSA4096 HASH=SHA3 +test-161-forward-update-no-downgrade-TPM-RSA: $(EXPVER) FORCE + @make test-tpm-on + @make test-01-forward-update-no-downgrade SIGN=RSA2048 WOLFTPM=1 + @make test-tpm-off + +test-163-rollback-TPM-RSA: $(EXPVER) FORCE + @make test-tpm-on + @make test-03-rollback SIGN=RSA2048 WOLFTPM=1 + @make test-tpm-off + test-all: clean test-01-forward-update-no-downgrade test-02-forward-update-allow-downgrade test-03-rollback \ test-11-forward-update-no-downgrade-ECC test-13-rollback-ECC test-21-forward-update-no-downgrade-SPI test-23-rollback-SPI \ test-34-forward-self-update \ @@ -347,4 +357,6 @@ test-all: clean test-01-forward-update-no-downgrade test-02-forward-update-allow test-81-forward-update-no-downgrade-ED25519-SHA3 \ test-91-forward-update-no-downgrade-ECC256-SHA3 \ test-101-forward-update-no-downgrade-RSA2048-SHA3 \ - test-111-forward-update-no-downgrade-RSA4096-SHA3 + test-111-forward-update-no-downgrade-RSA4096-SHA3 \ + test-161-forward-update-no-downgrade-TPM-RSA \ + test-163-rollback-TPM-RSA