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`).

pull/51/head
David Garske 2020-05-25 08:28:02 -07:00
parent 782d4b685c
commit 2560bdc6d7
5 changed files with 145 additions and 130 deletions

View File

@ -57,6 +57,7 @@ ifeq ($(SIGN),ED25519)
./lib/wolfssl/wolfcrypt/src/ge_low_mem.o \ ./lib/wolfssl/wolfcrypt/src/ge_low_mem.o \
./lib/wolfssl/wolfcrypt/src/hash.o \ ./lib/wolfssl/wolfcrypt/src/hash.o \
./lib/wolfssl/wolfcrypt/src/wolfmath.o \ ./lib/wolfssl/wolfcrypt/src/wolfmath.o \
./lib/wolfssl/wolfcrypt/src/wc_port.o \
./lib/wolfssl/wolfcrypt/src/fe_low_mem.o ./lib/wolfssl/wolfcrypt/src/fe_low_mem.o
PUBLIC_KEY_OBJS=./src/ed25519_pub_key.o PUBLIC_KEY_OBJS=./src/ed25519_pub_key.o
CFLAGS+=-DWOLFBOOT_SIGN_ED25519 \ CFLAGS+=-DWOLFBOOT_SIGN_ED25519 \
@ -74,6 +75,7 @@ ifeq ($(SIGN),RSA2048)
./lib/wolfssl/wolfcrypt/src/rsa.o \ ./lib/wolfssl/wolfcrypt/src/rsa.o \
./lib/wolfssl/wolfcrypt/src/asn.o \ ./lib/wolfssl/wolfcrypt/src/asn.o \
./lib/wolfssl/wolfcrypt/src/hash.o \ ./lib/wolfssl/wolfcrypt/src/hash.o \
./lib/wolfssl/wolfcrypt/src/wc_port.o \
./src/xmalloc_rsa.o ./src/xmalloc_rsa.o
PUBLIC_KEY_OBJS=./src/rsa2048_pub_key.o PUBLIC_KEY_OBJS=./src/rsa2048_pub_key.o
CFLAGS+=-DWOLFBOOT_SIGN_RSA2048 -DXMALLOC_USER $(RSA_EXTRA_CFLAGS) \ CFLAGS+=-DWOLFBOOT_SIGN_RSA2048 -DXMALLOC_USER $(RSA_EXTRA_CFLAGS) \
@ -148,9 +150,9 @@ endif
ifeq ($(DEBUG),1) ifeq ($(DEBUG),1)
CFLAGS+=-O0 -g -ggdb3 -DDEBUG=1 CFLAGS+=-O0 -g -ggdb3 -DDEBUG=1
else else
CFLAGS+=-Os CFLAGS+=-Os
endif endif
ifeq ($(V),0) ifeq ($(V),0)
@ -158,7 +160,7 @@ ifeq ($(V),0)
endif endif
ifeq ($(VTOR),0) ifeq ($(VTOR),0)
CFLAGS+=-DNO_VTOR CFLAGS+=-DNO_VTOR
endif endif
ifeq ($(PKA),1) ifeq ($(PKA),1)
@ -170,18 +172,21 @@ OBJS+=$(PUBLIC_KEY_OBJS)
OBJS+=$(UPDATE_OBJS) OBJS+=$(UPDATE_OBJS)
ifeq ($(WOLFTPM),1) ifeq ($(WOLFTPM),1)
OBJS += lib/wolfTPM/src/tpm2.o \ OBJS += lib/wolfTPM/src/tpm2.o \
lib/wolfTPM/src/tpm2_packet.o \ lib/wolfTPM/src/tpm2_packet.o \
lib/wolfTPM/src/tpm2_tis.o \ lib/wolfTPM/src/tpm2_tis.o \
lib/wolfTPM/src/tpm2_wrap.o \ lib/wolfTPM/src/tpm2_wrap.o \
hal/spi/spi_drv_$(SPI_TARGET).o hal/spi/spi_drv_$(SPI_TARGET).o
CFLAGS+=-DWOLFTPM_SLB9670 -DWOLFTPM2_NO_WOLFCRYPT -DSIZEOF_LONG=4 -Ilib/wolfTPM \ 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 \ -DMAX_COMMAND_SIZE=1024 -DMAX_RESPONSE_SIZE=1024 -DWOLFTPM2_MAX_BUFFER=1500 \
-DWOLFTPM_SMALL_STACK -DMAX_SESSION_NUM=1 -DMAX_DIGEST_BUFFER=973 \
-DWOLFTPM_SMALL_STACK
else # Chip Type: WOLFTPM_SLB9670, WOLFTPM_ST33, WOLFTPM_MCHP
OBJS+=$(WOLFCRYPT_OBJS) CFLAGS+=-DWOLFTPM_SLB9670
# Use TPM for hashing (slow)
#CFLAGS+=-DWOLFBOOT_HASH_TPM
endif endif
OBJS+=$(WOLFCRYPT_OBJS)
ASFLAGS:=$(CFLAGS) ASFLAGS:=$(CFLAGS)

View File

@ -58,7 +58,7 @@ static void spi_flash_pin_setup(void)
static void spi_tpm2_pin_setup(void) static void spi_tpm2_pin_setup(void)
{ {
#ifdef WOLFTPM2_NO_WOLFCRYPT #ifdef WOLFBOOT_TPM
uint32_t reg; uint32_t reg;
RCC_GPIO_CLOCK_ER |= SPI_PIO_CS_CEN; RCC_GPIO_CLOCK_ER |= SPI_PIO_CS_CEN;
reg = SPI_PIO_CS_MODE & ~ (0x03 << (SPI_CS_TPM * 2)); reg = SPI_PIO_CS_MODE & ~ (0x03 << (SPI_CS_TPM * 2));

View File

@ -53,7 +53,7 @@
# error "No public key available for given signing algorithm." # error "No public key available for given signing algorithm."
#endif /* Algorithm selection */ #endif /* Algorithm selection */
#ifdef WOLFTPM2_NO_WOLFCRYPT #ifdef WOLFBOOT_TPM
int wolfBoot_tpm2_init(void); int wolfBoot_tpm2_init(void);
#endif #endif

View File

@ -24,16 +24,15 @@
#include "hal.h" #include "hal.h"
#include "spi_drv.h" #include "spi_drv.h"
#ifndef WOLFTPM2_NO_WOLFCRYPT
#include <wolfssl/wolfcrypt/settings.h> #include <wolfssl/wolfcrypt/settings.h>
#ifdef WOLFBOOT_HASH_SHA256 #ifdef WOLFBOOT_TPM
#include <wolfssl/wolfcrypt/sha256.h> #include <stdlib.h>
#endif #include <string.h>
#include "wolftpm/tpm2.h"
#ifdef WOLFBOOT_HASH_SHA3_384 #include "wolftpm/tpm2_wrap.h"
#include <wolfssl/wolfcrypt/sha3.h> static WOLFTPM2_DEV wolftpm_dev;
#endif #endif /* WOLFBOOT_TPM */
#ifdef WOLFBOOT_SIGN_ED25519 #ifdef WOLFBOOT_SIGN_ED25519
#include <wolfssl/wolfcrypt/ed25519.h> #include <wolfssl/wolfcrypt/ed25519.h>
@ -64,10 +63,26 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
#ifdef WOLFBOOT_SIGN_ECC256 #ifdef WOLFBOOT_SIGN_ECC256
#include <wolfssl/wolfcrypt/ecc.h> #include <wolfssl/wolfcrypt/ecc.h>
#define ECC_KEY_SIZE 32 #define ECC_KEY_SIZE 32
#define ECC_SIG_SIZE 64
static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig) 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; int ret, res;
mp_int r, s; mp_int r, s;
ecc_key ecc; ecc_key ecc;
@ -78,7 +93,8 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
} }
/* Import public key */ /* 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) { if ((ret < 0) || ecc.type != ECC_PUBLICKEY) {
/* Failed to import ecc key */ /* Failed to import ecc key */
return -1; return -1;
@ -94,15 +110,36 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
return -1; return -1;
} }
return 0; return 0;
#endif /* WOLFBOOT_TPM */
} }
#endif /* WOLFBOOT_SIGN_ECC256 */ #endif /* WOLFBOOT_SIGN_ECC256 */
#if defined(WOLFBOOT_SIGN_RSA2048) || defined (WOLFBOOT_SIGN_RSA4096) #if defined(WOLFBOOT_SIGN_RSA2048) || defined (WOLFBOOT_SIGN_RSA4096)
#include <wolfssl/wolfcrypt/rsa.h>
#include <wolfssl/wolfcrypt/asn_public.h> #include <wolfssl/wolfcrypt/asn_public.h>
#include <wolfssl/wolfcrypt/rsa.h>
static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig) 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; int ret;
struct RsaKey rsa; struct RsaKey rsa;
uint8_t digest_out[IMAGE_SIGNATURE_SIZE]; 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 0;
} }
return -1; return -1;
#endif /* WOLFBOOT_TPM */
} }
#endif /* WOLFBOOT_SIGN_RSA2048 */ #endif /* WOLFBOOT_SIGN_RSA2048 */
#else
#include <stdlib.h>
#include <string.h>
#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); 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); return (uint8_t *)(img->hdr);
} }
#ifndef WOLFTPM2_NO_WOLFCRYPT
#if defined(WOLFBOOT_HASH_SHA256) #if defined(WOLFBOOT_HASH_SHA256)
#include <wolfssl/wolfcrypt/sha256.h>
static int image_sha256(struct wolfBoot_image *img, uint8_t *hash) 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; uint8_t *stored_sha, *end_sha;
uint16_t stored_sha_len; uint16_t stored_sha_len;
uint8_t *p; uint8_t *p;
@ -233,10 +303,32 @@ static int image_sha256(struct wolfBoot_image *img, uint8_t *hash)
wc_Sha256Final(&sha256_ctx, hash); wc_Sha256Final(&sha256_ctx, hash);
return 0; return 0;
#endif /* WOLFBOOT_TPM && WOLFBOOT_HASH_TPM */
} }
static void key_sha256(uint8_t *hash) 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; int blksz;
unsigned int i = 0; unsigned int i = 0;
wc_Sha256 sha256_ctx; wc_Sha256 sha256_ctx;
@ -250,9 +342,14 @@ static void key_sha256(uint8_t *hash)
i += blksz; i += blksz;
} }
wc_Sha256Final(&sha256_ctx, hash); wc_Sha256Final(&sha256_ctx, hash);
#endif /* WOLFBOOT_TPM && WOLFBOOT_HASH_TPM */
} }
#endif /* SHA2 256 */ #endif /* SHA2-256 */
#if defined(WOLFBOOT_HASH_SHA3_384) #if defined(WOLFBOOT_HASH_SHA3_384)
#include <wolfssl/wolfcrypt/sha3.h>
static int image_sha3_384(struct wolfBoot_image *img, uint8_t *hash) static int image_sha3_384(struct wolfBoot_image *img, uint8_t *hash)
{ {
uint8_t *stored_sha, *end_sha; 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); 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, static int TPM2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
word16 xferSz, void* userCtx) word16 xferSz, void* userCtx)
@ -335,26 +432,6 @@ static int TPM2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
return 0; 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 wolfBoot_tpm2_init(void)
{ {
int rc; int rc;
@ -376,74 +453,7 @@ int wolfBoot_tpm2_init(void)
return 0; return 0;
} }
static void key_sha256(uint8_t *hashBuf) #endif /* WOLFBOOT_TPM */
{
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
int wolfBoot_open_image(struct wolfBoot_image *img, uint8_t part) int wolfBoot_open_image(struct wolfBoot_image *img, uint8_t part)

View File

@ -175,7 +175,7 @@ int main(void)
uart_init(UART_FLASH_BITRATE, 8, 'N', 1); uart_init(UART_FLASH_BITRATE, 8, 'N', 1);
uart_send_current_version(); uart_send_current_version();
#endif #endif
#ifdef WOLFTPM2_NO_WOLFCRYPT #ifdef WOLFBOOT_TPM
wolfBoot_tpm2_init(); wolfBoot_tpm2_init();
#endif #endif
wolfBoot_start(); wolfBoot_start();