Added support for PK callbacks with RSA Sign using PKCSv1.5 and PSS.

Fixes for building wolfTPM without crypto callbacks.
Fixes for building/running with FIPS.
pull/312/head
David Garske 2023-11-30 11:00:20 -08:00
parent 18e6177634
commit e601803f1b
12 changed files with 610 additions and 34 deletions

View File

@ -46,6 +46,8 @@ make
./examples
```
Note: To install the development base tools on MSYS2 use: `pacman -s base-devel` and `pacman -S mingw-w64-x86_64-toolchain`.
## Building on linux
Tested using mingw-w32-bin_x86_64-linux_20131221.tar.bz2

View File

@ -25,7 +25,8 @@
#include <stdio.h>
#if !defined(WOLFTPM2_NO_WRAPPER) && defined(WOLFTPM2_CERT_GEN)
#if !defined(WOLFTPM2_NO_WRAPPER) && defined(WOLFTPM2_CERT_GEN) && \
defined(WOLFTPM_CRYPTOCB)
#include <hal/tpm_io.h>
#include <examples/tpm_test.h>
@ -252,14 +253,15 @@ int TPM2_CSR_ExampleArgs(void* userCtx, int argc, char *argv[])
/* --- END TPM2 CSR Example -- */
/******************************************************************************/
#endif /* !WOLFTPM2_NO_WRAPPER && WOLFTPM2_CERT_GEN */
#endif /* !WOLFTPM2_NO_WRAPPER && WOLFTPM2_CERT_GEN && WOLFTPM_CRYPTOCB */
#ifndef NO_MAIN_DRIVER
int main(int argc, char *argv[])
{
int rc = -1;
#if !defined(WOLFTPM2_NO_WRAPPER) && defined(WOLFTPM2_CERT_GEN)
#if !defined(WOLFTPM2_NO_WRAPPER) && defined(WOLFTPM2_CERT_GEN) && \
defined(WOLFTPM_CRYPTOCB)
rc = TPM2_CSR_ExampleArgs(NULL, argc, argv);
#else
(void)argc;

View File

@ -176,9 +176,11 @@ if [ $WOLFCRYPT_ENABLE -eq 1 ]; then
[ $RESULT -ne 0 ] && echo -e "pkcs7 failed! $RESULT" && exit 1
fi
# TLS Tests RSA
# TLS Tests
echo -e "TLS tests"
generate_port() { # function to produce a random port number
generate_port() {
# for now it is okay to use the same port
# Note: The SW TPM uses many local ports, which can cause bind() issue
port=11111
echo -e "Using port $port"
echo -e "Using port $port" >> run.out
@ -193,6 +195,7 @@ run_tpm_tls_client() { # Usage: run_tpm_tls_client [ecc/rsa] [tpmargs]]
[ $RESULT -ne 0 ] && echo -e "tls server $1 $2 failed! $RESULT" && exit 1
popd >> run.out
sleep 0.1
./examples/tls/tls_client -p=$port -$1 $2 2>&1 >> run.out
RESULT=$?
[ $RESULT -ne 0 ] && echo -e "tpm tls client $1 $2 failed! $RESULT" && exit 1

View File

@ -25,7 +25,7 @@
#include <stdio.h>
#if !defined(WOLFTPM2_NO_WRAPPER) && defined(WOLFTPM_CRYPTOCB) && \
#if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_WOLFCRYPT) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(WOLFCRYPT_ONLY)
#include <hal/tpm_io.h>
@ -83,6 +83,9 @@ static void usage(void)
printf("* -ecc: Use RSA or ECC key\n");
printf("* -aes/xor: Use Parameter Encryption\n");
printf("* -p=port: Supply a custom port number (default %d)\n", TLS_PORT);
#if defined(WOLFTPM_CRYPTOCB) && defined(HAVE_PK_CALLBACKS)
printf("* -pk: Use PK callbacks, not crypto callbacks\n");
#endif
}
int TPM2_TLS_Client(void* userCtx)
@ -108,7 +111,7 @@ int TPM2_TLS_ClientArgs(void* userCtx, int argc, char *argv[])
#endif
TpmCryptoDevCtx tpmCtx;
SockIoCbCtx sockIoCtx;
int tpmDevId;
int tpmDevId = INVALID_DEVID;
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
#ifndef TLS_BENCH_MODE
@ -121,6 +124,7 @@ int TPM2_TLS_ClientArgs(void* userCtx, int argc, char *argv[])
int i;
#endif
int useECC = 0;
int usePK = 0;
TPM_ALG_ID paramEncAlg = TPM_ALG_NULL;
WOLFTPM2_SESSION tpmSession;
TPMT_PUBLIC publicTemplate;
@ -139,6 +143,10 @@ int TPM2_TLS_ClientArgs(void* userCtx, int argc, char *argv[])
#ifdef HAVE_ECC
XMEMSET(&eccKey, 0, sizeof(eccKey));
XMEMSET(&wolfEccKey, 0, sizeof(wolfEccKey));
#ifndef WOLFTPM2_USE_SW_ECDHE
/* Ephemeral Key */
XMEMSET(&ecdhKey, 0, sizeof(ecdhKey));
#endif
#endif
XMEMSET(&tpmSession, 0, sizeof(tpmSession));
@ -163,6 +171,11 @@ int TPM2_TLS_ClientArgs(void* userCtx, int argc, char *argv[])
else if (XSTRCMP(argv[argc-1], "-xor") == 0) {
paramEncAlg = TPM_ALG_XOR;
}
#if defined(WOLFTPM_CRYPTOCB) && defined(HAVE_PK_CALLBACKS)
else if (XSTRCMP(argv[argc-1], "-pk") == 0) {
usePK = 1;
}
#endif
else if (XSTRNCMP(argv[argc-1], "-p=", XSTRLEN("-p=")) == 0) {
const char* portStr = argv[argc-1] + XSTRLEN("-p=");
port = (word32)XATOI(portStr);
@ -183,6 +196,7 @@ int TPM2_TLS_ClientArgs(void* userCtx, int argc, char *argv[])
}
/* Setup the wolf crypto device callback */
tpmCtx.dev = &dev;
#ifndef NO_RSA
tpmCtx.rsaKey = &rsaKey;
#endif
@ -193,9 +207,14 @@ int TPM2_TLS_ClientArgs(void* userCtx, int argc, char *argv[])
#ifdef WOLFTPM_USE_SYMMETRIC
tpmCtx.useSymmetricOnTPM = 1;
#endif
rc = wolfTPM2_SetCryptoDevCb(&dev, wolfTPM2_CryptoDevCb, &tpmCtx, &tpmDevId);
if (rc != 0) goto exit;
#ifdef WOLFTPM_CRYPTOCB
if (!usePK) {
rc = wolfTPM2_SetCryptoDevCb(&dev, wolfTPM2_CryptoDevCb, &tpmCtx, &tpmDevId);
if (rc != 0) goto exit;
}
#endif
/* See if primary storage key already exists */
rc = getPrimaryStoragekey(&dev, &storageKey, TPM_ALG_RSA);
if (rc != 0) goto exit;
@ -209,7 +228,8 @@ int TPM2_TLS_ClientArgs(void* userCtx, int argc, char *argv[])
/* set session for authorization of the storage key */
rc = wolfTPM2_SetAuthSession(&dev, 0, &tpmSession,
(TPMA_SESSION_decrypt | TPMA_SESSION_encrypt | TPMA_SESSION_continueSession));
(TPMA_SESSION_decrypt | TPMA_SESSION_encrypt |
TPMA_SESSION_continueSession));
if (rc != 0) goto exit;
}
@ -251,7 +271,6 @@ int TPM2_TLS_ClientArgs(void* userCtx, int argc, char *argv[])
#ifndef WOLFTPM2_USE_SW_ECDHE
/* Ephemeral Key */
XMEMSET(&ecdhKey, 0, sizeof(ecdhKey));
tpmCtx.ecdhKey = &ecdhKey;
#endif
#endif /* HAVE_ECC */
@ -269,6 +288,13 @@ int TPM2_TLS_ClientArgs(void* userCtx, int argc, char *argv[])
wolfSSL_CTX_SetIORecv(ctx, SockIORecv);
wolfSSL_CTX_SetIOSend(ctx, SockIOSend);
/* Setup PK callbacks */
#ifdef HAVE_PK_CALLBACKS
if (usePK) {
wolfTPM_PK_SetCb(ctx);
}
#endif
/* Server certificate validation */
/* Note: Can use "WOLFSSL_VERIFY_NONE" to skip server cert validation */
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, myVerify);
@ -456,6 +482,13 @@ int TPM2_TLS_ClientArgs(void* userCtx, int argc, char *argv[])
goto exit;
}
/* Setup PK Callback context */
#ifdef HAVE_PK_CALLBACKS
if (usePK) {
wolfTPM_PK_SetCbCtx(ssl, &tpmCtx);
}
#endif
/* Setup socket and connection */
rc = SetupSocketAndConnect(&sockIoCtx, TLS_HOST, port);
if (rc != 0) goto exit;
@ -564,10 +597,11 @@ exit:
printf("Shutdown not complete\n");
}
CloseAndCleanupSocket(&sockIoCtx);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
CloseAndCleanupSocket(&sockIoCtx);
wolfTPM2_UnloadHandle(&dev, &storageKey.handle);
#ifndef NO_RSA
wc_FreeRsaKey(&wolfRsaKey);
@ -591,23 +625,23 @@ exit:
/* --- END TPM TLS Client Example -- */
/******************************************************************************/
#endif /* !WOLFTPM2_NO_WRAPPER && WOLFTPM_CRYPTOCB && !NO_WOLFSSL_CLIENT && \
* !WOLFCRYPT_ONLY */
#endif /* !WOLFTPM2_NO_WRAPPER && !WOLFTPM2_NO_WOLFCRYPT && !NO_WOLFSSL_CLIENT \
* && !WOLFCRYPT_ONLY */
#ifndef NO_MAIN_DRIVER
int main(int argc, char* argv[])
{
int rc = -1;
#if !defined(WOLFTPM2_NO_WRAPPER) && defined(WOLFTPM_CRYPTOCB) && \
#if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_WOLFCRYPT) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(WOLFCRYPT_ONLY)
rc = TPM2_TLS_ClientArgs(NULL, argc, argv);
#else
(void)argc;
(void)argv;
printf("Wrapper/Crypto callback code or TLS support not compiled in\n");
printf("Build wolfssl with ./configure --enable-cryptocb\n");
printf("TPM Wrapper or PK//Crypto callback or TLS support not compiled in\n");
printf("Build wolfssl with ./configure --enable-wolftpm\n");
#endif
return rc;

View File

@ -25,7 +25,7 @@
#include <stdio.h>
#if !defined(WOLFTPM2_NO_WRAPPER) && defined(WOLFTPM_CRYPTOCB) && \
#if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_WOLFCRYPT) && \
!defined(NO_WOLFSSL_SERVER) && !defined(WOLFCRYPT_ONLY)
#include <hal/tpm_io.h>
@ -80,6 +80,9 @@ static void usage(void)
printf("* -ecc: Use RSA or ECC key\n");
printf("* -aes/xor: Use Parameter Encryption\n");
printf("* -p=port: Supply a custom port number (default %d)\n", TLS_PORT);
#if defined(WOLFTPM_CRYPTOCB) && defined(HAVE_PK_CALLBACKS)
printf("* -pk: Use PK callbacks, not crypto callbacks\n");
#endif
}
int TPM2_TLS_Server(void* userCtx)
@ -104,7 +107,7 @@ int TPM2_TLS_ServerArgs(void* userCtx, int argc, char *argv[])
#endif
TpmCryptoDevCtx tpmCtx;
SockIoCbCtx sockIoCtx;
int tpmDevId;
int tpmDevId = INVALID_DEVID;
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
#ifndef TLS_BENCH_MODE
@ -128,6 +131,7 @@ int TPM2_TLS_ServerArgs(void* userCtx, int argc, char *argv[])
int total_size;
#endif
int useECC = 0;
int usePK = 0;
TPM_ALG_ID paramEncAlg = TPM_ALG_NULL;
WOLFTPM2_SESSION tpmSession;
TPMT_PUBLIC publicTemplate;
@ -174,6 +178,11 @@ int TPM2_TLS_ServerArgs(void* userCtx, int argc, char *argv[])
else if (XSTRCMP(argv[argc-1], "-xor") == 0) {
paramEncAlg = TPM_ALG_XOR;
}
#if defined(WOLFTPM_CRYPTOCB) && defined(HAVE_PK_CALLBACKS)
else if (XSTRCMP(argv[argc-1], "-pk") == 0) {
usePK = 1;
}
#endif
else if (XSTRNCMP(argv[argc-1], "-p=", XSTRLEN("-p=")) == 0) {
const char* portStr = argv[argc-1] + XSTRLEN("-p=");
port = (word32)XATOI(portStr);
@ -197,6 +206,7 @@ int TPM2_TLS_ServerArgs(void* userCtx, int argc, char *argv[])
}
/* Setup the wolf crypto device callback */
tpmCtx.dev = &dev;
#ifndef NO_RSA
tpmCtx.rsaKey = &rsaKey;
#endif
@ -207,9 +217,13 @@ int TPM2_TLS_ServerArgs(void* userCtx, int argc, char *argv[])
#ifdef WOLFTPM_USE_SYMMETRIC
tpmCtx.useSymmetricOnTPM = 1;
#endif
rc = wolfTPM2_SetCryptoDevCb(&dev, wolfTPM2_CryptoDevCb, &tpmCtx, &tpmDevId);
if (rc != 0) goto exit;
#ifdef WOLFTPM_CRYPTOCB
if (!usePK) {
rc = wolfTPM2_SetCryptoDevCb(&dev, wolfTPM2_CryptoDevCb, &tpmCtx, &tpmDevId);
if (rc != 0) goto exit;
}
#endif
/* See if primary storage key already exists */
rc = getPrimaryStoragekey(&dev, &storageKey, TPM_ALG_RSA);
if (rc != 0) goto exit;
@ -285,6 +299,13 @@ int TPM2_TLS_ServerArgs(void* userCtx, int argc, char *argv[])
wolfSSL_CTX_SetIORecv(ctx, SockIORecv);
wolfSSL_CTX_SetIOSend(ctx, SockIOSend);
/* Setup PK callbacks */
#ifdef HAVE_PK_CALLBACKS
if (usePK) {
wolfTPM_PK_SetCb(ctx);
}
#endif
/* Server certificate validation */
#if 0
/* skip server cert validation for this test */
@ -439,6 +460,13 @@ int TPM2_TLS_ServerArgs(void* userCtx, int argc, char *argv[])
goto exit;
}
/* Setup PK Callback context */
#ifdef HAVE_PK_CALLBACKS
if (usePK) {
wolfTPM_PK_SetCbCtx(ssl, &tpmCtx);
}
#endif
/* Setup socket and connection */
rc = SetupSocketAndListen(&sockIoCtx, port);
if (rc != 0) goto exit;
@ -568,23 +596,23 @@ exit:
/* --- END TLS Server Example -- */
/******************************************************************************/
#endif /* !WOLFTPM2_NO_WRAPPER && WOLFTPM_CRYPTOCB && !NO_WOLFSSL_SERVER && \
* !WOLFCRYPT_ONLY */
#endif /* !WOLFTPM2_NO_WRAPPER && !WOLFTPM2_NO_WOLFCRYPT && !NO_WOLFSSL_SERVER \
* && !WOLFCRYPT_ONLY */
#ifndef NO_MAIN_DRIVER
int main(int argc, char* argv[])
{
int rc = -1;
#if !defined(WOLFTPM2_NO_WRAPPER) && defined(WOLFTPM_CRYPTOCB) && \
#if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_WOLFCRYPT) && \
!defined(NO_WOLFSSL_SERVER) && !defined(WOLFCRYPT_ONLY)
rc = TPM2_TLS_ServerArgs(NULL, argc, argv);
#else
(void)argc;
(void)argv;
printf("Wrapper/Crypto callback code or TLS support not compiled in\n");
printf("Build wolfssl with ./configure --enable-cryptocb\n");
printf("TPM Wrapper or PK//Crypto callback or TLS support not compiled in\n");
printf("Build wolfssl with ./configure --enable-wolftpm\n");
#endif
return rc;

View File

@ -437,8 +437,10 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[])
rc = wc_InitRsaKey(&wolfRsaPrivKey, NULL);
if (rc != 0) goto exit;
idx = 0;
PRIVATE_KEY_UNLOCK();
rc = wc_RsaPrivateKeyDecode(kRsaKeyPrivDer, &idx, &wolfRsaPrivKey,
(word32)sizeof(kRsaKeyPrivDer));
PRIVATE_KEY_LOCK();
if (rc != 0) goto exit;
rc = wolfTPM2_RsaKey_WolfToTpm_ex(&dev, &storageKey, &wolfRsaPrivKey,
&rsaKey);

View File

@ -442,6 +442,19 @@ static TPM_RC TPM2_SendCommand(TPM2_CTX* ctx, TPM2_Packet* packet)
}
#ifndef WOLFTPM2_NO_WOLFCRYPT
#ifdef HAVE_FIPS
static void WolfFipsCb(int ok, int err, const char* hash)
{
printf("in my Fips callback, ok = %d, err = %d\n", ok, err);
printf("message = %s\n", wc_GetErrorString(err));
printf("hash = %s\n", hash);
if (err == IN_CORE_FIPS_E) {
printf("In core integrity hash check failure, copy above hash\n");
printf("into verifyCore[] in fips_test.c and rebuild\n");
}
}
#endif
static inline int TPM2_WolfCrypt_Init(void)
{
int rc = 0;
@ -451,7 +464,9 @@ static inline int TPM2_WolfCrypt_Init(void)
#ifdef DEBUG_WOLFSSL
wolfSSL_Debugging_ON();
#endif
#ifdef HAVE_FIPS
wolfCrypt_SetCb_fips(WolfFipsCb);
#endif
rc = wolfCrypt_Init();
#ifdef WC_RNG_SEED_CB
if (rc == 0)

View File

@ -21,7 +21,9 @@
#include <wolftpm/tpm2_wrap.h>
#if defined(WOLFTPM_CRYPTOCB) && !defined(WOLFTPM2_NO_WRAPPER)
#if !defined(WOLFTPM2_NO_WRAPPER)
#ifdef WOLFTPM_CRYPTOCB
/* Internal structure for tracking hash state */
typedef struct WOLFTPM2_HASHCTX {
@ -687,5 +689,440 @@ static int wolfTPM2_HashUpdateCache(WOLFTPM2_HASHCTX* hashCtx,
return ret;
}
#endif /* WOLFTPM_USE_SYMMETRIC */
#endif /* WOLFTPM_CRYPTOCB */
#endif /* WOLFTPM_CRYPTOCB && !WOLFTPM2_NO_WRAPPER */
#if defined(HAVE_PK_CALLBACKS) && !defined(WOLFCRYPT_ONLY)
#ifndef NO_RSA
#ifndef RSA_MAX_SIZE
#define RSA_MAX_SIZE 4096
#endif
/* Padding Function, PKCSv15 (not exposed in wolfCrypt FIPS 3389) */
static int RsaPadPkcsv15Type1(const byte* input, word32 inputLen,
byte* pkcsBlock, word32 pkcsBlockLen)
{
if (input == NULL || inputLen == 0 || pkcsBlock == NULL ||
pkcsBlockLen == 0) {
return BAD_FUNC_ARG;
}
if (pkcsBlockLen > RSA_MAX_SIZE/8) {
return RSA_BUFFER_E;
}
if (pkcsBlockLen - RSA_MIN_PAD_SZ < inputLen) {
#ifdef DEBUG_WOLFTPM
printf("RsaPad error, invalid length\n");
#endif
return RSA_PAD_E;
}
pkcsBlock[0] = 0x0; /* set first byte to zero and advance */
pkcsBlock++; pkcsBlockLen--;
pkcsBlock[0] = RSA_BLOCK_TYPE_1; /* insert padValue */
/* pad with 0xff bytes */
XMEMSET(&pkcsBlock[1], 0xFF, pkcsBlockLen - inputLen - 2);
pkcsBlock[pkcsBlockLen-inputLen-1] = 0; /* separator */
XMEMCPY(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);
return 0;
}
int wolfTPM2_PK_RsaSign(WOLFSSL* ssl,
const unsigned char* in, unsigned int inSz,
unsigned char* out, word32* outSz,
const unsigned char* keyDer, unsigned int keySz,
void* ctx)
{
int ret;
RsaKey rsapub;
TpmCryptoDevCtx* tlsCtx = (TpmCryptoDevCtx*)ctx;
(void)ssl;
#ifdef DEBUG_WOLFTPM
printf("PK RSA Sign: inSz %u, keySz %u\n", inSz, keySz);
#endif
/* load RSA public key */
ret = wc_InitRsaKey(&rsapub, NULL);
if (ret == 0) {
word32 keyIdx = 0;
ret = wc_RsaPublicKeyDecode(keyDer, &keyIdx, &rsapub, (word32)keySz);
if (ret == 0) {
byte inPad[RSA_MAX_SIZE/8];
word32 inPadSz = wc_RsaEncryptSize(&rsapub);
/* Pad with PKCSv1.5 type 1 */
ret = RsaPadPkcsv15Type1(in, inSz, inPad, inPadSz);
if (ret == 0) {
/* private operations */
ret = wolfTPM2_RsaDecrypt(tlsCtx->dev, tlsCtx->rsaKey,
TPM_ALG_NULL, /* no padding */
inPad, inPadSz,
out, (int*)outSz);
}
}
wc_FreeRsaKey(&rsapub);
}
if (ret > 0) {
ret = WC_HW_E;
}
#ifdef DEBUG_WOLFTPM
printf("PK RSA Sign: ret %d, outSz %u\n", ret, *outSz);
#endif
return ret;
}
int wolfTPM2_PK_RsaSignCheck(WOLFSSL* ssl,
unsigned char* sig, unsigned int sigSz,
unsigned char** out,
const unsigned char* keyDer, unsigned int keySz,
void* ctx)
{
TpmCryptoDevCtx* tlsCtx = (TpmCryptoDevCtx*)ctx;
(void)ssl;
(void)sig;
(void)sigSz;
(void)out;
(void)keyDer;
(void)keySz;
(void)tlsCtx;
/* We used sign hardware, so assume sign is good */
return 0;
}
#ifdef WC_RSA_PSS
/* Uses MGF1 standard as a mask generation function
hType: hash type used
seed: seed to use for generating mask
seedSz: size of seed buffer
out: mask output after generation
outSz: size of output buffer
*/
static int RsaMGF1(wc_HashAlg* hash, enum wc_HashType hType,
byte* seed, word32 seedSz, byte* out, word32 outSz)
{
int ret;
byte tmp[RSA_MAX_SIZE/8];
word32 tmpSz = 0, counter = 0, idx = 0;
int hLen, i = 0;
hLen = wc_HashGetDigestSize(hType);
if (hLen < 0) {
return hLen;
}
/* find largest amount of memory needed, which will be the max of
* hLen and (seedSz + 4) since tmp is used to store the hash digest */
tmpSz = ((seedSz + 4) > (word32)hLen) ? seedSz + 4: (word32)hLen;
if (tmpSz > sizeof(tmp)) {
return BAD_FUNC_ARG;
}
do {
XMEMCPY(tmp, seed, seedSz);
/* counter to byte array appended to tmp */
tmp[seedSz] = (byte)((counter >> 24) & 0xFF);
tmp[seedSz + 1] = (byte)((counter >> 16) & 0xFF);
tmp[seedSz + 2] = (byte)((counter >> 8) & 0xFF);
tmp[seedSz + 3] = (byte)((counter) & 0xFF);
/* hash and append to existing output */
ret = wc_HashUpdate(hash, hType, tmp, (seedSz + 4));
if (ret == 0) {
ret = wc_HashFinal(hash, hType, tmp);
}
if (ret == 0) {
for (i = 0; i < hLen && idx < outSz; i++) {
out[idx++] = tmp[i];
}
}
counter++;
} while (ret == 0 && idx < outSz);
return ret;
}
/* This routine performs a bitwise XOR operation of <*buf> and <*mask> of n
* counts, placing the result in <*buf>. */
static void xorbuf(void* buf, const void* mask, word32 count)
{
word32 i;
byte* b = (byte*)buf;
const byte* m = (const byte*)mask;
for (i = 0; i < count; i++) {
b[i] ^= m[i];
}
}
/* 0x00 .. 0x00 0x01 | Salt | Gen Hash | 0xbc
* XOR MGF over all bytes down to end of Salt
* Gen Hash = HASH(8 * 0x00 | Message Hash | Salt)
*
* input Digest of the message.
* inputLen Length of digest.
* pkcsBlock Buffer to write to.
* pkcsBlockLen Length of buffer to write to.
* rng Random number generator (for salt).
* htype Hash function to use.
* mgf Mask generation function.
* saltLen Length of salt to put in padding.
* bits Length of key in bits.
* returns 0 on success, PSS_SALTLEN_E when the salt length is invalid
* and other negative values on error.
*/
static int RsaPadPss(const byte* input, word32 inputLen, byte* pkcsBlock,
word32 pkcsBlockLen, WC_RNG* rng, int hash, int mgf,
int saltLen, int bits)
{
int ret = 0, hLen, o, maskLen, hiBits;
byte *m, *s, *salt;
byte msg[RSA_MAX_SIZE/8 + RSA_PSS_PAD_SZ];
enum wc_HashType hType;
wc_HashAlg hashCtx; /* big stack consumer */
switch (hash) {
#ifndef NO_SHA256
case SHA256h:
hType = WC_HASH_TYPE_SHA256;
break;
#endif
#ifdef WOLFSSL_SHA384
case SHA384h:
hType = WC_HASH_TYPE_SHA384;
break;
#endif
#ifdef WOLFSSL_SHA512
case SHA512h:
hType = WC_HASH_TYPE_SHA512;
break;
#endif
default:
return NOT_COMPILED_IN;
}
ret = wc_HashGetDigestSize(hType);
if (ret < 0) {
return ret;
}
hLen = ret;
if ((int)inputLen != hLen) {
return BAD_FUNC_ARG;
}
hiBits = (bits - 1) & 0x7;
if (hiBits == 0) {
/* Per RFC8017, set the leftmost 8emLen - emBits bits of the
* leftmost octet in DB to zero. */
*(pkcsBlock++) = 0;
pkcsBlockLen--;
}
if (saltLen == RSA_PSS_SALT_LEN_DEFAULT) {
saltLen = hLen;
#ifdef WOLFSSL_SHA512
/* See FIPS 186-4 section 5.5 item (e). */
if (bits == 1024 && hLen == WC_SHA512_DIGEST_SIZE) {
saltLen = RSA_PSS_SALT_MAX_SZ;
}
#endif
}
if ((int)pkcsBlockLen - hLen < saltLen + 2) {
return PSS_SALTLEN_E;
}
ret = wc_HashInit_ex(&hashCtx, hType, NULL, INVALID_DEVID);
if (ret != 0) {
return ret;
}
maskLen = (int)pkcsBlockLen - 1 - hLen;
salt = s = m = msg;
XMEMSET(m, 0, RSA_PSS_PAD_SZ);
m += RSA_PSS_PAD_SZ;
XMEMCPY(m, input, inputLen);
m += inputLen;
o = (int)(m - s);
if (saltLen > 0) {
ret = wc_RNG_GenerateBlock(rng, m, (word32)saltLen);
if (ret == 0) {
m += saltLen;
}
}
if (ret == 0) {
/* Put Hash at end of pkcsBlock - 1 */
ret = wc_HashUpdate(&hashCtx, hType, s, (word32)(m - s));
if (ret == 0) {
ret = wc_HashFinal(&hashCtx, hType, pkcsBlock + maskLen);
}
}
if (ret == 0) {
/* Set the last eight bits or trailer field to the octet 0xbc */
pkcsBlock[pkcsBlockLen - 1] = RSA_PSS_PAD_TERM;
ret = RsaMGF1(&hashCtx, hType, pkcsBlock + maskLen, (word32)hLen,
pkcsBlock, (word32)maskLen);
(void)mgf; /* not needed, using hType */
}
if (ret == 0) {
/* Clear the first high bit when "8emLen - emBits" is non-zero,
* where emBits = n modBits - 1 */
if (hiBits) {
pkcsBlock[0] &= (byte)((1 << hiBits) - 1);
}
m = pkcsBlock + maskLen - saltLen - 1;
*(m++) ^= 0x01;
xorbuf(m, salt + o, (word32)saltLen);
}
wc_HashFree(&hashCtx, hType);
return ret;
}
int wolfTPM2_PK_RsaPssSign(WOLFSSL* ssl,
const unsigned char* in, unsigned int inSz,
unsigned char* out, unsigned int* outSz,
int hash, int mgf,
const unsigned char* keyDer, unsigned int keySz,
void* ctx)
{
int ret;
TpmCryptoDevCtx* tlsCtx = (TpmCryptoDevCtx*)ctx;
RsaKey rsapub;
(void)ssl;
#ifdef DEBUG_WOLFTPM
printf("PK RSA PSS Sign: inSz %u, keySz %u, hash %d\n", inSz, keySz, hash);
#endif
/* load RSA public key */
ret = wc_InitRsaKey(&rsapub, NULL);
if (ret == 0) {
word32 keyIdx = 0;
ret = wc_RsaPublicKeyDecode(keyDer, &keyIdx, &rsapub, (word32)keySz);
if (ret == 0) {
byte inPad[RSA_MAX_SIZE/8];
word32 inPadSz = (word32)wc_RsaEncryptSize(&rsapub);
#if 1
/* Use local PSS padding function */
ret = RsaPadPss(
in, inSz,
inPad, inPadSz,
wolfTPM2_GetRng(tlsCtx->dev), hash, mgf,
RSA_PSS_SALT_LEN_DEFAULT, inPadSz*8);
#else
/* Pad with PSS using internal wolfSSL API, if available */
ret = wc_RsaPad_ex(in, inSz, inPad, inPadSz, RSA_BLOCK_TYPE_1,
wolfTPM2_GetRng(tlsCtx->dev), WC_RSA_PSS_PAD, hash, mgf,
NULL, 0, RSA_PSS_SALT_LEN_DEFAULT, inPadSz*8, NULL);
#endif
if (ret == 0) {
/* private operations */
ret = wolfTPM2_RsaDecrypt(tlsCtx->dev, tlsCtx->rsaKey,
TPM_ALG_NULL, /* no padding */
inPad, inPadSz,
out, (int*)outSz);
}
}
wc_FreeRsaKey(&rsapub);
}
if (ret > 0) {
#ifdef DEBUG_WOLFTPM
printf("PK RSA PSS Sign Hash Failure 0x%x: %s\n",
ret, wolfTPM2_GetRCString(ret));
#endif
ret = WC_HW_E;
}
#ifdef DEBUG_WOLFTPM
printf("PK RSA PSS Sign: ret %d, outSz %u\n", ret, *outSz);
#endif
return ret;
}
int wolfTPM2_PK_RsaPssSignCheck(WOLFSSL* ssl,
unsigned char* sig, unsigned int sigSz, unsigned char** out,
int hash, int mgf,
const unsigned char* keyDer, unsigned int keySz,
void* ctx)
{
TpmCryptoDevCtx* tlsCtx = (TpmCryptoDevCtx*)ctx;
(void)ssl;
(void)sig;
(void)sigSz;
(void)out;
(void)hash;
(void)mgf;
(void)keyDer;
(void)keySz;
(void)tlsCtx;
/* We used sign hardware, so assume sign is good */
return 0;
}
#endif /* WC_RSA_PSS */
#endif /* !NO_RSA */
#if 0 /* TODO: def HAVE_ECC */
int wolfTPM2_PK_EccSign(WOLFSSL* ssl,
const unsigned char* in, unsigned int inSz,
unsigned char* out, word32* outSz,
const unsigned char* keyDer, unsigned int keySz,
void* ctx)
{
}
#endif
/* Setup PK callbacks */
int wolfTPM_PK_SetCb(WOLFSSL_CTX* ctx)
{
if (ctx == NULL)
return BAD_FUNC_ARG;
#ifndef NO_RSA
wolfSSL_CTX_SetRsaSignCb(ctx, wolfTPM2_PK_RsaSign);
wolfSSL_CTX_SetRsaSignCheckCb(ctx, wolfTPM2_PK_RsaSignCheck);
#ifdef WC_RSA_PSS
wolfSSL_CTX_SetRsaPssSignCb(ctx, wolfTPM2_PK_RsaPssSign);
wolfSSL_CTX_SetRsaPssSignCheckCb(ctx, wolfTPM2_PK_RsaPssSignCheck);
#endif
#endif
#if 0 /* TODO: def HAVE_ECC */
wolfSSL_CTX_SetEccSignCb(ctx, wolfTPM2_PK_EccSign);
#endif
return 0;
}
/* Setup PK Callback context */
int wolfTPM_PK_SetCbCtx(WOLFSSL* ssl, void* userCtx)
{
if (ssl == NULL)
return BAD_FUNC_ARG;
#ifndef NO_RSA
wolfSSL_SetRsaSignCtx(ssl, userCtx);
#ifdef WC_RSA_PSS
wolfSSL_SetRsaPssSignCtx(ssl, userCtx);
#endif
#endif
#if 0 /* TODO: def HAVE_ECC */
wolfSSL_SetEccSignCtx(ssl, userCtx);
#endif
return 0;
}
#endif /* HAVE_PK_CALLBACKS && !WOLFCRYPT_ONLY */
#endif /* !WOLFTPM2_NO_WRAPPER */

View File

@ -3066,8 +3066,10 @@ int wolfTPM2_RsaKey_WolfToTpm_ex(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* parentKe
XMEMSET(q, 0, sizeof(q));
/* export the raw private and public RSA as unsigned binary */
PRIVATE_KEY_UNLOCK();
rc = wc_RsaExportKey(wolfKey, e, &eSz, n, &nSz,
d, &dSz, p, &pSz, q, &qSz);
PRIVATE_KEY_LOCK();
if (rc == 0) {
exponent = wolfTPM2_RsaKey_Exponent(e, eSz);
rc = wolfTPM2_LoadRsaPrivateKey(dev, parentKey, tpmKey, n, nSz,
@ -6099,7 +6101,7 @@ static void wolfTPM2_CopyNvPublic(TPMS_NV_PUBLIC* out, const TPMS_NV_PUBLIC* in)
/* --- BEGIN Certificate Signing Request (CSR) Functions -- */
/******************************************************************************/
#ifdef WOLFTPM2_CERT_GEN
#if defined(WOLFTPM2_CERT_GEN) && defined(WOLFTPM_CRYPTOCB)
/* Distinguished Name Strings */
typedef struct DNTags {
@ -6476,7 +6478,7 @@ int wolfTPM2_CSR_Generate(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
out, outSz, 0, 0, INVALID_DEVID);
}
#endif /* WOLFTPM2_CERT_GEN */
#endif /* WOLFTPM2_CERT_GEN && WOLFTPM_CRYPTOCB */
/******************************************************************************/
/* --- END Certificate Signing Request (CSR) Functions -- */

View File

@ -298,7 +298,8 @@ static void test_TPM2_KDFa(void)
static void test_wolfTPM2_CSR(void)
{
#if defined(WOLFTPM2_CERT_GEN) && !defined(WOLFTPM2_NO_HEAP)
#if defined(WOLFTPM2_CERT_GEN) && !defined(WOLFTPM2_NO_HEAP) && \
defined(WOLFTPM_CRYPTOCB)
int rc;
WOLFTPM2_CSR* csr = wolfTPM2_NewCSR();
AssertNotNull(csr);

View File

@ -99,6 +99,9 @@ typedef int64_t INT64;
#include <wolfssl/wolfcrypt/hash.h>
#include <wolfssl/wolfcrypt/rsa.h>
#include <wolfssl/wolfcrypt/ecc.h>
#if defined(HAVE_PK_CALLBACKS) && !defined(NO_RSA) && defined(WC_RSA_PSS)
#include <wolfssl/wolfcrypt/asn.h> /* for enum Hash_Sum */
#endif
#include <wolfssl/wolfcrypt/asn_public.h>
#include <wolfssl/wolfcrypt/hmac.h>
#include <wolfssl/wolfcrypt/aes.h>

View File

@ -2862,9 +2862,8 @@ WOLFTPM_LOCAL int wolfTPM2_EncryptSecret(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY*
TPM2B_DATA *secret, TPM2B_ENCRYPTED_SECRET *encSecret, const char* label);
#ifdef WOLFTPM_CRYPTOCB
#if defined(WOLFTPM_CRYPTOCB) || defined(HAVE_PK_CALLBACKS)
struct TpmCryptoDevCtx;
typedef int (*CheckWolfKeyCallbackFunc)(wc_CryptoInfo* info, struct TpmCryptoDevCtx* ctx);
typedef struct TpmCryptoDevCtx {
WOLFTPM2_DEV* dev;
@ -2887,6 +2886,10 @@ typedef struct TpmCryptoDevCtx {
unsigned short useFIPSMode:1; /* if set requires FIPS mode on TPM and no fallback to software algos */
} TpmCryptoDevCtx;
#endif /* WOLFTPM_CRYPTOCB || HAVE_PK_CALLBACKS */
#ifdef WOLFTPM_CRYPTOCB
/*!
\ingroup wolfTPM2_Wrappers
\brief A reference crypto callback API for using the TPM for crypto offload.
@ -2942,6 +2945,50 @@ WOLFTPM_API int wolfTPM2_ClearCryptoDevCb(WOLFTPM2_DEV* dev, int devId);
#endif /* WOLFTPM_CRYPTOCB */
#if defined(HAVE_PK_CALLBACKS) && !defined(WOLFTPM2_NO_WRAPPER) && \
!defined(WOLFCRYPT_ONLY)
#ifndef NO_RSA
WOLFTPM_API int wolfTPM2_PK_RsaSign(WOLFSSL* ssl,
const unsigned char* in, unsigned int inSz,
unsigned char* out, word32* outSz,
const unsigned char* keyDer, unsigned int keySz,
void* ctx);
WOLFTPM_API int wolfTPM2_PK_RsaSignCheck(WOLFSSL* ssl,
unsigned char* sig, unsigned int sigSz,
unsigned char** out,
const unsigned char* keyDer, unsigned int keySz,
void* ctx);
#ifdef WC_RSA_PSS
WOLFTPM_API int wolfTPM2_PK_RsaPssSign(WOLFSSL* ssl,
const unsigned char* in, unsigned int inSz,
unsigned char* out, unsigned int* outSz,
int hash, int mgf,
const unsigned char* keyDer, unsigned int keySz,
void* ctx);
WOLFTPM_API int wolfTPM2_PK_RsaPssSignCheck(WOLFSSL* ssl,
unsigned char* sig, unsigned int sigSz, unsigned char** out,
int hash, int mgf,
const unsigned char* keyDer, unsigned int keySz,
void* ctx);
#endif /* WC_RSA_PSS */
#endif /* !NO_RSA */
#ifdef HAVE_ECC
WOLFTPM_API int wolfTPM2_PK_EccSign(WOLFSSL* ssl,
const unsigned char* in, unsigned int inSz,
unsigned char* out, word32* outSz,
const unsigned char* keyDer, unsigned int keySz,
void* ctx);
#endif
/* Helpers for setting generic PK callbacks */
WOLFTPM_API int wolfTPM_PK_SetCb(WOLFSSL_CTX* ctx);
WOLFTPM_API int wolfTPM_PK_SetCbCtx(WOLFSSL* ssl, void* userCtx);
#endif /* HAVE_PK_CALLBACKS */
#ifndef WOLFTPM2_NO_HEAP
/*!