mirror of https://github.com/wolfSSL/wolfBoot.git
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`).
parent
782d4b685c
commit
2560bdc6d7
17
Makefile
17
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) \
|
||||
|
@ -170,18 +172,21 @@ OBJS+=$(PUBLIC_KEY_OBJS)
|
|||
OBJS+=$(UPDATE_OBJS)
|
||||
|
||||
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_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 \
|
||||
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
|
||||
|
||||
else
|
||||
OBJS+=$(WOLFCRYPT_OBJS)
|
||||
# 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)
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
238
src/image.c
238
src/image.c
|
@ -24,16 +24,15 @@
|
|||
#include "hal.h"
|
||||
#include "spi_drv.h"
|
||||
|
||||
#ifndef WOLFTPM2_NO_WOLFCRYPT
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
|
||||
#ifdef WOLFBOOT_HASH_SHA256
|
||||
#include <wolfssl/wolfcrypt/sha256.h>
|
||||
#endif
|
||||
|
||||
#ifdef WOLFBOOT_HASH_SHA3_384
|
||||
#include <wolfssl/wolfcrypt/sha3.h>
|
||||
#endif
|
||||
#ifdef WOLFBOOT_TPM
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "wolftpm/tpm2.h"
|
||||
#include "wolftpm/tpm2_wrap.h"
|
||||
static WOLFTPM2_DEV wolftpm_dev;
|
||||
#endif /* WOLFBOOT_TPM */
|
||||
|
||||
#ifdef WOLFBOOT_SIGN_ED25519
|
||||
#include <wolfssl/wolfcrypt/ed25519.h>
|
||||
|
@ -64,10 +63,26 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
|
|||
#ifdef WOLFBOOT_SIGN_ECC256
|
||||
#include <wolfssl/wolfcrypt/ecc.h>
|
||||
#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 <wolfssl/wolfcrypt/rsa.h>
|
||||
#include <wolfssl/wolfcrypt/asn_public.h>
|
||||
|
||||
#include <wolfssl/wolfcrypt/rsa.h>
|
||||
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 <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);
|
||||
|
||||
|
@ -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 <wolfssl/wolfcrypt/sha256.h>
|
||||
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 <wolfssl/wolfcrypt/sha3.h>
|
||||
|
||||
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)
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue