From 2560bdc6d7290c5a073c864bee3f2a4a5bba5fd5 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 25 May 2020 08:28:02 -0700 Subject: [PATCH] Added TPM RSA verify support. Added support for using software SHA-256 hasing with TPM because its much faster. (Note: to use TPM for hashing define `WOLFBOOT_HASH_TPM`). --- Makefile | 31 +++--- hal/spi/spi_drv_stm32.c | 2 +- include/loader.h | 2 +- src/image.c | 238 +++++++++++++++++++++------------------- src/loader.c | 2 +- 5 files changed, 145 insertions(+), 130 deletions(-) diff --git a/Makefile b/Makefile index 1a5b013d..7c0abf7a 100644 --- a/Makefile +++ b/Makefile @@ -57,6 +57,7 @@ ifeq ($(SIGN),ED25519) ./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/fe_low_mem.o PUBLIC_KEY_OBJS=./src/ed25519_pub_key.o CFLAGS+=-DWOLFBOOT_SIGN_ED25519 \ @@ -74,6 +75,7 @@ ifeq ($(SIGN),RSA2048) ./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) \ @@ -148,9 +150,9 @@ endif ifeq ($(DEBUG),1) - CFLAGS+=-O0 -g -ggdb3 -DDEBUG=1 + CFLAGS+=-O0 -g -ggdb3 -DDEBUG=1 else - CFLAGS+=-Os + CFLAGS+=-Os endif ifeq ($(V),0) @@ -158,7 +160,7 @@ ifeq ($(V),0) endif ifeq ($(VTOR),0) - CFLAGS+=-DNO_VTOR + CFLAGS+=-DNO_VTOR endif ifeq ($(PKA),1) @@ -170,18 +172,21 @@ OBJS+=$(PUBLIC_KEY_OBJS) OBJS+=$(UPDATE_OBJS) ifeq ($(WOLFTPM),1) -OBJS += lib/wolfTPM/src/tpm2.o \ - lib/wolfTPM/src/tpm2_packet.o \ - lib/wolfTPM/src/tpm2_tis.o \ - lib/wolfTPM/src/tpm2_wrap.o \ + OBJS += lib/wolfTPM/src/tpm2.o \ + lib/wolfTPM/src/tpm2_packet.o \ + lib/wolfTPM/src/tpm2_tis.o \ + lib/wolfTPM/src/tpm2_wrap.o \ hal/spi/spi_drv_$(SPI_TARGET).o - CFLAGS+=-DWOLFTPM_SLB9670 -DWOLFTPM2_NO_WOLFCRYPT -DSIZEOF_LONG=4 -Ilib/wolfTPM \ - -DMAX_COMMAND_SIZE=1024 -DMAX_RESPONSE_SIZE=1024 -DWOLFTPM2_MAX_BUFFER=1500 -DMAX_SESSION_NUM=1 -DMAX_DIGEST_BUFFER=973 \ - -DWOLFTPM_SMALL_STACK - -else - OBJS+=$(WOLFCRYPT_OBJS) + CFLAGS+=-DWOLFBOOT_TPM -DSIZEOF_LONG=4 -Ilib/wolfTPM \ + -DMAX_COMMAND_SIZE=1024 -DMAX_RESPONSE_SIZE=1024 -DWOLFTPM2_MAX_BUFFER=1500 \ + -DMAX_SESSION_NUM=1 -DMAX_DIGEST_BUFFER=973 \ + -DWOLFTPM_SMALL_STACK + # Chip Type: WOLFTPM_SLB9670, WOLFTPM_ST33, WOLFTPM_MCHP + CFLAGS+=-DWOLFTPM_SLB9670 + # Use TPM for hashing (slow) + #CFLAGS+=-DWOLFBOOT_HASH_TPM endif +OBJS+=$(WOLFCRYPT_OBJS) ASFLAGS:=$(CFLAGS) diff --git a/hal/spi/spi_drv_stm32.c b/hal/spi/spi_drv_stm32.c index 0922c840..6074968e 100644 --- a/hal/spi/spi_drv_stm32.c +++ b/hal/spi/spi_drv_stm32.c @@ -58,7 +58,7 @@ static void spi_flash_pin_setup(void) static void spi_tpm2_pin_setup(void) { -#ifdef WOLFTPM2_NO_WOLFCRYPT +#ifdef WOLFBOOT_TPM uint32_t reg; RCC_GPIO_CLOCK_ER |= SPI_PIO_CS_CEN; reg = SPI_PIO_CS_MODE & ~ (0x03 << (SPI_CS_TPM * 2)); diff --git a/include/loader.h b/include/loader.h index 7e5fdb46..52ce53b1 100644 --- a/include/loader.h +++ b/include/loader.h @@ -53,7 +53,7 @@ # error "No public key available for given signing algorithm." #endif /* Algorithm selection */ -#ifdef WOLFTPM2_NO_WOLFCRYPT +#ifdef WOLFBOOT_TPM int wolfBoot_tpm2_init(void); #endif diff --git a/src/image.c b/src/image.c index aa16d087..89785f28 100644 --- a/src/image.c +++ b/src/image.c @@ -24,16 +24,15 @@ #include "hal.h" #include "spi_drv.h" -#ifndef WOLFTPM2_NO_WOLFCRYPT #include -#ifdef WOLFBOOT_HASH_SHA256 -#include -#endif - -#ifdef WOLFBOOT_HASH_SHA3_384 -#include -#endif +#ifdef WOLFBOOT_TPM +#include +#include +#include "wolftpm/tpm2.h" +#include "wolftpm/tpm2_wrap.h" +static WOLFTPM2_DEV wolftpm_dev; +#endif /* WOLFBOOT_TPM */ #ifdef WOLFBOOT_SIGN_ED25519 #include @@ -64,10 +63,26 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig) #ifdef WOLFBOOT_SIGN_ECC256 #include #define ECC_KEY_SIZE 32 -#define ECC_SIG_SIZE 64 - static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig) { +#ifdef WOLFBOOT_TPM + int rc; + WOLFTPM2_KEY tpmKey; + + /* Load public key into TPM */ + XMEMSET(&tpmKey, 0, sizeof(tpmKey)); + rc = 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) + return -1; + rc = wolfTPM2_VerifyHash(&wolftpm_dev, &tpmKey, sig, IMAGE_SIGNATURE_SIZE, + hash, WOLFBOOT_SHA_DIGEST_SIZE); + wolfTPM2_UnloadHandle(&wolftpm_dev, &tpmKey.handle); + if (rc < 0) + return -1; + return 0; +#else int ret, res; mp_int r, s; ecc_key ecc; @@ -78,7 +93,8 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig) } /* Import public key */ - ret = wc_ecc_import_unsigned(&ecc, (byte*)KEY_BUFFER, (byte*)(KEY_BUFFER + 32), NULL, ECC_SECP256R1); + ret = wc_ecc_import_unsigned(&ecc, (byte*)KEY_BUFFER, + (byte*)(KEY_BUFFER + ECC_KEY_SIZE), NULL, ECC_SECP256R1); if ((ret < 0) || ecc.type != ECC_PUBLICKEY) { /* Failed to import ecc key */ return -1; @@ -94,15 +110,36 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig) return -1; } return 0; +#endif /* WOLFBOOT_TPM */ } #endif /* WOLFBOOT_SIGN_ECC256 */ #if defined(WOLFBOOT_SIGN_RSA2048) || defined (WOLFBOOT_SIGN_RSA4096) -#include #include - +#include static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig) { +#ifdef WOLFBOOT_TPM + int rc; + WOLFTPM2_KEY tpmKey; + const byte *n = NULL, *e = NULL; + word32 nSz = 0, eSz = 0, inOutIdx = 0; + + /* Extract DER RSA key struct */ + rc = wc_RsaPublicKeyDecode_ex(KEY_BUFFER, &inOutIdx, KEY_LEN, &n, &nSz, &e, &eSz); + if (rc < 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) + return -1; + rc = wolfTPM2_VerifyHash(&wolftpm_dev, &tpmKey, sig, IMAGE_SIGNATURE_SIZE, + hash, WOLFBOOT_SHA_DIGEST_SIZE); + wolfTPM2_UnloadHandle(&wolftpm_dev, &tpmKey.handle); + return rc; +#else int ret; struct RsaKey rsa; uint8_t digest_out[IMAGE_SIGNATURE_SIZE]; @@ -125,17 +162,10 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig) return 0; } return -1; +#endif /* WOLFBOOT_TPM */ } #endif /* WOLFBOOT_SIGN_RSA2048 */ -#else -#include -#include -#include "wolftpm/tpm2.h" -#include "wolftpm/tpm2_wrap.h" -static WOLFTPM2_DEV wolftpm_dev; - -#endif /* WOLFTPM2_NO_WOLFCRYPT */ static uint16_t get_header_ext(struct wolfBoot_image *img, uint16_t type, uint8_t **ptr); @@ -194,11 +224,51 @@ static uint8_t *get_img_hdr(struct wolfBoot_image *img) return (uint8_t *)(img->hdr); } -#ifndef WOLFTPM2_NO_WOLFCRYPT - #if defined(WOLFBOOT_HASH_SHA256) +#include static int image_sha256(struct wolfBoot_image *img, uint8_t *hash) { +#if defined(WOLFBOOT_TPM) && defined(WOLFBOOT_HASH_TPM) + const char usageAuth[] = "wolfBoot TPM Usage Auth"; + uint8_t *stored_sha, *end_sha; + uint16_t stored_sha_len; + uint8_t *p; + int blksz; + uint32_t position = 0; + WOLFTPM2_HASH tpmHash; + uint32_t hashSz = WOLFBOOT_SHA_DIGEST_SIZE; + int rc; + if (!img) + return -1; + p = get_img_hdr(img); + 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)); + rc = wolfTPM2_HashStart(&wolftpm_dev, &tpmHash, TPM_ALG_SHA256, + (const byte*)usageAuth, sizeof(usageAuth)-1); + if (rc != 0) + return -1; + end_sha = stored_sha - (2 * sizeof(uint16_t)); /* Subtract 2 Type + 2 Len */ + while (p < end_sha) { + blksz = WOLFBOOT_SHA_BLOCK_SIZE; + if (end_sha - p < blksz) + blksz = end_sha - p; + wolfTPM2_HashUpdate(&wolftpm_dev, &tpmHash, p, blksz); + p += blksz; + } + do { + p = get_sha_block(img, position); + if (p == NULL) + break; + blksz = WOLFBOOT_SHA_BLOCK_SIZE; + if (position + blksz > img->fw_size) + blksz = img->fw_size - position; + wolfTPM2_HashUpdate(&wolftpm_dev, &tpmHash, p, blksz); + position += blksz; + } while(position < img->fw_size); + return wolfTPM2_HashFinish(&wolftpm_dev, &tpmHash, hash, (word32*)&hashSz); +#else uint8_t *stored_sha, *end_sha; uint16_t stored_sha_len; uint8_t *p; @@ -233,10 +303,32 @@ static int image_sha256(struct wolfBoot_image *img, uint8_t *hash) wc_Sha256Final(&sha256_ctx, hash); return 0; +#endif /* WOLFBOOT_TPM && WOLFBOOT_HASH_TPM */ } static void key_sha256(uint8_t *hash) { +#if defined(WOLFBOOT_TPM) && defined(WOLFBOOT_HASH_TPM) + int blksz, rc; + unsigned int i = 0; + const char usageAuth[] = "wolfBoot TPM Usage Auth"; + uint32_t hashSz = WOLFBOOT_SHA_DIGEST_SIZE; + WOLFTPM2_HASH tpmHash; + XMEMSET(&tpmHash, 0, sizeof(tpmHash)); + rc = wolfTPM2_HashStart(&wolftpm_dev, &tpmHash, TPM_ALG_SHA256, + (const byte*)usageAuth, sizeof(usageAuth)-1); + if (rc != 0) + return; + while(i < KEY_LEN) + { + blksz = WOLFBOOT_SHA_BLOCK_SIZE; + if ((i + blksz) > KEY_LEN) + blksz = KEY_LEN - i; + wolfTPM2_HashUpdate(&wolftpm_dev, &tpmHash, KEY_BUFFER + i, blksz); + i += blksz; + } + wolfTPM2_HashFinish(&wolftpm_dev, &tpmHash, hash, (word32*)&hashSz); +#else int blksz; unsigned int i = 0; wc_Sha256 sha256_ctx; @@ -250,9 +342,14 @@ static void key_sha256(uint8_t *hash) i += blksz; } wc_Sha256Final(&sha256_ctx, hash); +#endif /* WOLFBOOT_TPM && WOLFBOOT_HASH_TPM */ } -#endif /* SHA2 256 */ +#endif /* SHA2-256 */ + #if defined(WOLFBOOT_HASH_SHA3_384) + +#include + static int image_sha3_384(struct wolfBoot_image *img, uint8_t *hash) { uint8_t *stored_sha, *end_sha; @@ -307,9 +404,9 @@ static void key_sha3_384(uint8_t *hash) } wc_Sha3_384_Final(&sha3_ctx, hash); } -#endif +#endif /* SHA3-384 */ -#else /* WOLFTPM2_NO_WOLFCRYPT */ +#ifdef WOLFBOOT_TPM static int TPM2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf, word16 xferSz, void* userCtx) @@ -335,26 +432,6 @@ static int TPM2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf, return 0; } -#define ECC_INT_SIZE 32 -static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig) -{ - int rc; - int curve_id = TPM_ECC_NIST_P256; - WOLFTPM2_KEY tpmKey; - - /* Load public key into TPM */ - rc = wolfTPM2_LoadEccPublicKey(&wolftpm_dev, &tpmKey, TPM_ECC_NIST_P256, - KEY_BUFFER, ECC_INT_SIZE, - KEY_BUFFER + ECC_INT_SIZE, ECC_INT_SIZE); - if (rc < 0) - return -1; - rc = wolfTPM2_VerifyHash(&wolftpm_dev, &tpmKey, sig, 2 * ECC_INT_SIZE, hash, WOLFBOOT_SHA_DIGEST_SIZE); - wolfTPM2_UnloadHandle(&wolftpm_dev, &tpmKey.handle); - if (rc < 0) - return -1; - return 0; -} - int wolfBoot_tpm2_init(void) { int rc; @@ -376,74 +453,7 @@ int wolfBoot_tpm2_init(void) return 0; } -static void key_sha256(uint8_t *hashBuf) -{ - int blksz, rc; - unsigned int i = 0; - const char gUsageAuth[]="wolfBoot TPM Usage Auth"; - uint32_t hashSz = WOLFBOOT_SHA_DIGEST_SIZE; - WOLFTPM2_HASH hash; - XMEMSET(&hash, 0, sizeof(hash)); - rc = wolfTPM2_HashStart(&wolftpm_dev, &hash, TPM_ALG_SHA256, - (const byte*)gUsageAuth, sizeof(gUsageAuth)-1); - if (rc != 0) - return; - while(i < KEY_LEN) - { - blksz = WOLFBOOT_SHA_BLOCK_SIZE; - if ((i + blksz) > KEY_LEN) - blksz = KEY_LEN - i; - wolfTPM2_HashUpdate(&wolftpm_dev, &hash, KEY_BUFFER + i, blksz); - i += blksz; - } - wolfTPM2_HashFinish(&wolftpm_dev, &hash, hashBuf, &hashSz); -} - -static int image_sha256(struct wolfBoot_image *img, uint8_t *hashBuf) -{ - const char gUsageAuth[]="wolfBoot TPM Usage Auth"; - uint8_t *stored_sha, *end_sha; - uint16_t stored_sha_len; - uint8_t *p; - int blksz; - uint32_t position = 0; - WOLFTPM2_HASH hash; - uint32_t hashSz = WOLFBOOT_SHA_DIGEST_SIZE; - int rc; - if (!img) - return -1; - p = get_img_hdr(img); - stored_sha_len = get_header(img, HDR_SHA256, &stored_sha); - if (stored_sha_len != WOLFBOOT_SHA_DIGEST_SIZE) - return -1; - XMEMSET(&hash, 0, sizeof(hash)); - rc = wolfTPM2_HashStart(&wolftpm_dev, &hash, TPM_ALG_SHA256, - (const byte*)gUsageAuth, sizeof(gUsageAuth)-1); - if (rc != 0) - return -1; - end_sha = stored_sha - (2 * sizeof(uint16_t)); /* Subtract 2 Type + 2 Len */ - while (p < end_sha) { - blksz = WOLFBOOT_SHA_BLOCK_SIZE; - if (end_sha - p < blksz) - blksz = end_sha - p; - wolfTPM2_HashUpdate(&wolftpm_dev, &hash, p, blksz); - p += blksz; - } - do { - p = get_sha_block(img, position); - if (p == NULL) - break; - blksz = WOLFBOOT_SHA_BLOCK_SIZE; - if (position + blksz > img->fw_size) - blksz = img->fw_size - position; - wolfTPM2_HashUpdate(&wolftpm_dev, &hash, p, blksz); - position += blksz; - } while(position < img->fw_size); - return wolfTPM2_HashFinish(&wolftpm_dev, &hash, hashBuf, &hashSz); -} - -#endif - +#endif /* WOLFBOOT_TPM */ int wolfBoot_open_image(struct wolfBoot_image *img, uint8_t part) diff --git a/src/loader.c b/src/loader.c index 66a728fc..14d4a876 100644 --- a/src/loader.c +++ b/src/loader.c @@ -175,7 +175,7 @@ int main(void) uart_init(UART_FLASH_BITRATE, 8, 'N', 1); uart_send_current_version(); #endif -#ifdef WOLFTPM2_NO_WOLFCRYPT +#ifdef WOLFBOOT_TPM wolfBoot_tpm2_init(); #endif wolfBoot_start();