From 85511067e454441fa8e74ab17abd8cd1bf0ac212 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 21 May 2018 13:03:49 -0700 Subject: [PATCH] Added crypto device framework to handle PK RSA/ECC operations using callbacks. Adds new build option `./configure --enable-cryptodev` or `#define WOLF_CRYPTO_DEV`. Added devId support to PKCS7. --- configure.ac | 14 +++ wolfcrypt/src/cryptodev.c | 207 ++++++++++++++++++++++++++++++++++ wolfcrypt/src/ecc.c | 37 +++++- wolfcrypt/src/include.am | 4 + wolfcrypt/src/pkcs7.c | 29 ++--- wolfcrypt/src/rsa.c | 22 +++- wolfcrypt/src/wc_port.c | 8 ++ wolfcrypt/test/test.c | 37 +++++- wolfssl/wolfcrypt/cryptodev.h | 114 +++++++++++++++++++ wolfssl/wolfcrypt/ecc.h | 2 +- wolfssl/wolfcrypt/include.am | 3 +- wolfssl/wolfcrypt/pkcs7.h | 1 + wolfssl/wolfcrypt/rsa.h | 3 + wolfssl/wolfcrypt/types.h | 32 +++++- 14 files changed, 486 insertions(+), 27 deletions(-) create mode 100644 wolfcrypt/src/cryptodev.c create mode 100644 wolfssl/wolfcrypt/cryptodev.h diff --git a/configure.ac b/configure.ac index 9c8dfd4d3..a240142ab 100644 --- a/configure.ac +++ b/configure.ac @@ -3868,6 +3868,20 @@ else fi +# Support for crypto device hardware +AC_ARG_ENABLE([cryptodev], + [AS_HELP_STRING([--enable-cryptodev],[Enable crypto hardware support (default: disabled)])], + [ ENABLED_CRYPTODEV=$enableval ], + [ ENABLED_CRYPTODEV=no ] + ) + +if test "$ENABLED_CRYPTODEV" = "yes" +then + AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_DEV" +fi +AM_CONDITIONAL([BUILD_CRYPTODEV], [test "x$ENABLED_CRYPTODEV" = "xyes"]) + + # Session Export AC_ARG_ENABLE([sessionexport], [AS_HELP_STRING([--enable-sessionexport],[Enable export and import of sessions (default: disabled)])], diff --git a/wolfcrypt/src/cryptodev.c b/wolfcrypt/src/cryptodev.c new file mode 100644 index 000000000..80179e0e1 --- /dev/null +++ b/wolfcrypt/src/cryptodev.c @@ -0,0 +1,207 @@ +/* cryptodev.c + * + * Copyright (C) 2006-2018 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* This framework provides a central place for crypto hardware integration + using the devId scheme. If not supported return `NOT_COMPILED_IN`. */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#ifdef WOLF_CRYPTO_DEV + +#include +#include +#include + + +/* TODO: Consider linked list with mutex */ +#ifndef MAX_CRYPTO_DEVICES +#define MAX_CRYPTO_DEVICES 8 +#endif + +typedef struct CryptoDev { + int devId; + CryptoDevCallbackFunc cb; + void* ctx; +} CryptoDev; +static CryptoDev gCryptoDev[MAX_CRYPTO_DEVICES]; + +static CryptoDev* wc_CryptoDev_FindDevice(int devId) +{ + int i; + for (i=0; idevId = devId; + dev->cb = cb; + dev->ctx = ctx; + + return 0; +} + +void wc_CryptoDev_UnRegisterDevice(int devId) +{ + CryptoDev* dev = wc_CryptoDev_FindDevice(devId); + if (dev) { + XMEMSET(dev, 0, sizeof(*dev)); + dev->devId = INVALID_DEVID; + } +} + +#ifndef NO_RSA +int wc_CryptoDev_Rsa(const byte* in, word32 inLen, byte* out, + word32* outLen, int type, RsaKey* key, WC_RNG* rng) +{ + int ret = NOT_COMPILED_IN; + CryptoDev* dev; + + /* locate registered callback */ + dev = wc_CryptoDev_FindDevice(key->devId); + if (dev) { + if (dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_PK; + cryptoInfo.pk.type = WC_PK_TYPE_RSA; + cryptoInfo.pk.rsa.in = in; + cryptoInfo.pk.rsa.inLen = inLen; + cryptoInfo.pk.rsa.out = out; + cryptoInfo.pk.rsa.outLen = outLen; + cryptoInfo.pk.rsa.type = type; + cryptoInfo.pk.rsa.key = key; + cryptoInfo.pk.rsa.rng = rng; + + ret = dev->cb(key->devId, &cryptoInfo, dev->ctx); + } + } + + return ret; +} +#endif /* !NO_RSA */ + +#ifdef HAVE_ECC +int wc_CryptoDev_Ecdh(ecc_key* private_key, ecc_key* public_key, + byte* out, word32* outlen) +{ + int ret = NOT_COMPILED_IN; + CryptoDev* dev; + + /* locate registered callback */ + dev = wc_CryptoDev_FindDevice(private_key->devId); + if (dev) { + if (dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_PK; + cryptoInfo.pk.type = WC_PK_TYPE_ECDH; + cryptoInfo.pk.ecdh.private_key = private_key; + cryptoInfo.pk.ecdh.public_key = public_key; + cryptoInfo.pk.ecdh.out = out; + cryptoInfo.pk.ecdh.outlen = outlen; + + ret = dev->cb(private_key->devId, &cryptoInfo, dev->ctx); + } + } + + return ret; +} + +int wc_CryptoDev_EccSign(const byte* in, word32 inlen, byte* out, + word32 *outlen, WC_RNG* rng, ecc_key* key) +{ + int ret = NOT_COMPILED_IN; + CryptoDev* dev; + + /* locate registered callback */ + dev = wc_CryptoDev_FindDevice(key->devId); + if (dev) { + if (dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_PK; + cryptoInfo.pk.type = WC_PK_TYPE_ECDSA_SIGN; + cryptoInfo.pk.eccsign.in = in; + cryptoInfo.pk.eccsign.inlen = inlen; + cryptoInfo.pk.eccsign.out = out; + cryptoInfo.pk.eccsign.outlen = outlen; + cryptoInfo.pk.eccsign.rng = rng; + cryptoInfo.pk.eccsign.key = key; + + ret = dev->cb(key->devId, &cryptoInfo, dev->ctx); + } + } + + return ret; +} + +int wc_CryptoDev_EccVerify(const byte* sig, word32 siglen, + const byte* hash, word32 hashlen, int* res, ecc_key* key) +{ + int ret = NOT_COMPILED_IN; + CryptoDev* dev; + + /* locate registered callback */ + dev = wc_CryptoDev_FindDevice(key->devId); + if (dev) { + if (dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_PK; + cryptoInfo.pk.type = WC_PK_TYPE_ECDSA_VERIFY; + cryptoInfo.pk.eccverify.sig = sig; + cryptoInfo.pk.eccverify.siglen = siglen; + cryptoInfo.pk.eccverify.hash = hash; + cryptoInfo.pk.eccverify.hashlen = hashlen; + cryptoInfo.pk.eccverify.res = res; + cryptoInfo.pk.eccverify.key = key; + + ret = dev->cb(key->devId, &cryptoInfo, dev->ctx); + } + } + + return ret; +} +#endif /* HAVE_ECC */ + +#endif /* WOLF_CRYPTO_DEV */ diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 9801a51c5..d53847ae7 100755 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -122,6 +122,10 @@ ECC Curve Sizes: #include #endif +#ifdef WOLF_CRYPTO_DEV + #include +#endif + #ifdef NO_INLINE #include #else @@ -2793,6 +2797,15 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, return BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_DEV + if (private_key->devId != INVALID_DEVID) { + err = wc_CryptoDev_Ecdh(private_key, public_key, out, outlen); + if (err != NOT_COMPILED_IN) + return err; + err = 0; /* reset error code and try using software */ + } +#endif + /* type valid? */ if (private_key->type != ECC_PRIVATEKEY && private_key->type != ECC_PRIVATEKEY_ONLY) { @@ -3495,8 +3508,10 @@ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId) XMEMSET(key, 0, sizeof(ecc_key)); key->state = ECC_STATE_NONE; -#ifdef PLUTON_CRYPTO_ECC +#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_DEV) key->devId = devId; +#else + (void)devId; #endif #ifdef WOLFSSL_ATECC508A @@ -3532,8 +3547,6 @@ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId) /* handle as async */ ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC, key->heap, devId); -#else - (void)devId; #endif return ret; @@ -3641,6 +3654,15 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, return ECC_BAD_ARG_E; } +#ifdef WOLF_CRYPTO_DEV + if (key->devId != INVALID_DEVID) { + err = wc_CryptoDev_EccSign(in, inlen, out, outlen, rng, key); + if (err != NOT_COMPILED_IN) + return err; + err = 0; /* reset error code and try using software */ + } +#endif + #ifdef WOLFSSL_ASYNC_CRYPT err = wc_ecc_alloc_async(key); if (err != 0) @@ -4291,6 +4313,15 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash, return ECC_BAD_ARG_E; } +#ifdef WOLF_CRYPTO_DEV + if (key->devId != INVALID_DEVID) { + err = wc_CryptoDev_EccVerify(sig, siglen, hash, hashlen, res, key); + if (err != NOT_COMPILED_IN) + return err; + err = 0; /* reset error code and try using software */ + } +#endif + #ifdef WOLFSSL_ASYNC_CRYPT err = wc_ecc_alloc_async(key); if (err != 0) diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index 315388e12..cf181f82f 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -63,6 +63,10 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \ wolfcrypt/src/port/caam/caam_doc.pdf \ wolfcrypt/src/port/st/stm32.c +if BUILD_CRYPTODEV +src_libwolfssl_la_SOURCES += wolfcrypt/src/cryptodev.c +endif + if BUILD_CAVIUM src_libwolfssl_la_SOURCES += wolfcrypt/src/port/cavium/cavium_nitrox.c diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 807d90e00..835f58209 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -247,8 +247,8 @@ int wc_PKCS7_Init(PKCS7* pkcs7, void* heap, int devId) XMEMSET(pkcs7, 0, sizeof(PKCS7)); pkcs7->heap = heap; + pkcs7->devId = devId; - (void)devId; /* silence unused warning */ return 0; } @@ -600,8 +600,7 @@ static int wc_PKCS7_RsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd) return MEMORY_E; #endif - ret = wc_InitRsaKey(privKey, pkcs7->heap); - + ret = wc_InitRsaKey_ex(privKey, pkcs7->heap, pkcs7->devId); if (ret == 0) { idx = 0; ret = wc_RsaPrivateKeyDecode(pkcs7->privateKey, &idx, privKey, @@ -649,7 +648,7 @@ static int wc_PKCS7_EcdsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd) return MEMORY_E; #endif - ret = wc_ecc_init_ex(privKey, pkcs7->heap, INVALID_DEVID); + ret = wc_ecc_init_ex(privKey, pkcs7->heap, pkcs7->devId); if (ret == 0) { idx = 0; @@ -1309,7 +1308,7 @@ static int wc_PKCS7_RsaVerify(PKCS7* pkcs7, byte* sig, int sigSz, XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ); - ret = wc_InitRsaKey(key, pkcs7->heap); + ret = wc_InitRsaKey_ex(key, pkcs7->heap, pkcs7->devId); if (ret != 0) { #ifdef WOLFSSL_SMALL_STACK XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -1384,7 +1383,7 @@ static int wc_PKCS7_EcdsaVerify(PKCS7* pkcs7, byte* sig, int sigSz, XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ); - ret = wc_ecc_init_ex(key, pkcs7->heap, INVALID_DEVID); + ret = wc_ecc_init_ex(key, pkcs7->heap, pkcs7->devId); if (ret != 0) { #ifdef WOLFSSL_SMALL_STACK XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -2124,6 +2123,7 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz) typedef struct WC_PKCS7_KARI { DecodedCert* decoded; /* decoded recip cert */ void* heap; /* user heap, points to PKCS7->heap */ + int devId; /* device ID for HW based private key */ ecc_key* recipKey; /* recip key (pub | priv) */ ecc_key* senderKey; /* sender key (pub | priv) */ byte* senderKeyExport; /* sender ephemeral key DER */ @@ -2249,6 +2249,7 @@ static WC_PKCS7_KARI* wc_PKCS7_KariNew(PKCS7* pkcs7, byte direction) kari->direction = direction; kari->heap = pkcs7->heap; + kari->devId = pkcs7->devId; return kari; } @@ -2333,7 +2334,7 @@ static int wc_PKCS7_KariParseRecipCert(WC_PKCS7_KARI* kari, const byte* cert, return BAD_FUNC_ARG; } - ret = wc_ecc_init_ex(kari->recipKey, kari->heap, INVALID_DEVID); + ret = wc_ecc_init_ex(kari->recipKey, kari->heap, kari->devId); if (ret != 0) return ret; @@ -2384,7 +2385,7 @@ static int wc_PKCS7_KariGenerateEphemeralKey(WC_PKCS7_KARI* kari, WC_RNG* rng) kari->senderKeyExportSz = kari->decoded->pubKeySize; - ret = wc_ecc_init_ex(kari->senderKey, kari->heap, INVALID_DEVID); + ret = wc_ecc_init_ex(kari->senderKey, kari->heap, kari->devId); if (ret != 0) return ret; @@ -2986,7 +2987,7 @@ static int wc_CreateRecipientInfo(const byte* cert, word32 certSz, #endif /* EncryptedKey */ - ret = wc_InitRsaKey(pubKey, 0); + ret = wc_InitRsaKey_ex(pubKey, heap, INVALID_DEVID); if (ret != 0) { FreeDecodedCert(decoded); #ifdef WOLFSSL_SMALL_STACK @@ -3250,7 +3251,7 @@ static int wc_PKCS7_GenerateIV(PKCS7* pkcs7, WC_RNG* rng, byte* iv, word32 ivSz) if (rnd == NULL) return MEMORY_E; - ret = wc_InitRng_ex(rnd, pkcs7->heap, INVALID_DEVID); + ret = wc_InitRng_ex(rnd, pkcs7->heap, pkcs7->devId); if (ret != 0) { XFREE(rnd, pkcs7->heap, DYNAMIC_TYPE_RNG); return ret; @@ -3384,7 +3385,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) } /* generate random content encryption key */ - ret = wc_InitRng_ex(&rng, pkcs7->heap, INVALID_DEVID); + ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId); if (ret != 0) return ret; @@ -3712,7 +3713,7 @@ static int wc_PKCS7_DecodeKtri(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz, } #endif - ret = wc_InitRsaKey(privKey, 0); + ret = wc_InitRsaKey_ex(privKey, NULL, INVALID_DEVID); if (ret != 0) { #ifdef WOLFSSL_SMALL_STACK XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -3735,7 +3736,7 @@ static int wc_PKCS7_DecodeKtri(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz, /* decrypt encryptedKey */ #ifdef WC_RSA_BLINDING - ret = wc_InitRng_ex(&rng, pkcs7->heap, INVALID_DEVID); + ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId); if (ret == 0) { ret = wc_RsaSetRNG(privKey, &rng); } @@ -3823,7 +3824,7 @@ static int wc_PKCS7_KariGetOriginatorIdentifierOrKey(WC_PKCS7_KARI* kari, return ASN_EXPECT_0_E; /* get sender ephemeral public ECDSA key */ - ret = wc_ecc_init_ex(kari->senderKey, kari->heap, INVALID_DEVID); + ret = wc_ecc_init_ex(kari->senderKey, kari->heap, kari->devId); if (ret != 0) return ret; diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 658b5a29c..6108aa583 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -190,6 +190,9 @@ int wc_RsaFlattenPublicKey(RsaKey* key, byte* a, word32* aSz, byte* b, #include #include +#ifdef WOLF_CRYPTO_DEV + #include +#endif #ifdef NO_INLINE #include #else @@ -237,8 +240,6 @@ int wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId) return BAD_FUNC_ARG; } - (void)devId; - XMEMSET(key, 0, sizeof(RsaKey)); key->type = RSA_TYPE_UNKNOWN; @@ -251,6 +252,12 @@ int wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId) key->rng = NULL; #endif +#ifdef WOLF_CRYPTO_DEV + key->devId = devId; +#else + (void)devId; +#endif + #ifdef WOLFSSL_ASYNC_CRYPT #ifdef WOLFSSL_CERT_GEN XMEMSET(&key->certSignCtx, 0, sizeof(CertSignCtx)); @@ -263,8 +270,6 @@ int wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId) if (ret != 0) return ret; #endif /* WC_ASYNC_ENABLE_RSA */ -#else - (void)devId; #endif /* WOLFSSL_ASYNC_CRYPT */ ret = mp_init_multi(&key->n, &key->e, NULL, NULL, NULL, NULL); @@ -1619,6 +1624,15 @@ int wc_RsaFunction(const byte* in, word32 inLen, byte* out, return BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_DEV + if (key->devId != INVALID_DEVID) { + ret = wc_CryptoDev_Rsa(in, inLen, out, outLen, type, key, rng); + if (ret != NOT_COMPILED_IN) + return ret; + ret = 0; /* reset error code and try using software */ + } +#endif + #ifndef NO_RSA_BOUNDS_CHECK if (type == RSA_PRIVATE_DECRYPT && key->state == RSA_STATE_DECRYPT_EXPTMOD) { diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index b0d2c1998..9b2868be0 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -64,6 +64,10 @@ #include #endif +#ifdef WOLF_CRYPTO_DEV + #include +#endif + #ifdef _MSC_VER /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */ #pragma warning(disable: 4996) @@ -82,6 +86,10 @@ int wolfCrypt_Init(void) if (initRefCount == 0) { WOLFSSL_ENTER("wolfCrypt_Init"); + #ifdef WOLF_CRYPTO_DEV + wc_CryptoDev_Init(); + #endif + #ifdef WOLFSSL_ASYNC_CRYPT ret = wolfAsync_HardwareStart(); if (ret != 0) { diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 314285f0c..3945d57ce 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -119,6 +119,9 @@ #ifdef WOLFSSL_IMX6_CAAM_BLOB #include #endif +#ifdef WOLF_CRYPTO_DEV + #include +#endif #define WOLFSSL_MISC_INCLUDED #include @@ -341,6 +344,9 @@ int blob_test(void); #endif int misc_test(void); +#ifdef WOLF_CRYPTO_DEV +int cryptodev_test(void); +#endif /* General big buffer size for many tests. */ #define FOURK_BUF 4096 @@ -960,6 +966,13 @@ initDefaultName(); else printf( "misc test passed!\n"); +#ifdef WOLF_CRYPTO_DEV + if ( (ret = cryptodev_test()) != 0) + return err_sys("crypto dev test failed!\n", ret); + else + printf( "crypto dev test passed!\n"); +#endif + #ifdef WOLFSSL_ASYNC_CRYPT wolfAsync_DevClose(&devId); #endif @@ -8297,7 +8310,7 @@ static int rsa_sig_test(RsaKey* key, word32 keyLen, int modLen, WC_RNG* rng) * -101 = USER_CRYPTO_ERROR */ if (ret == 0) -#elif defined(WOLFSSL_ASYNC_CRYPT) +#elif defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_DEV) /* async may not require RNG */ if (ret != 0 && ret != MISSING_RNG_E) #elif defined(HAVE_FIPS) || defined(WOLFSSL_ASYNC_CRYPT) || \ @@ -18561,6 +18574,28 @@ int misc_test(void) return 0; } +#ifdef WOLF_CRYPTO_DEV +int cryptodev_test(void) +{ + int ret = 0; + + /* set devId to something other than INVALID_DEVID */ + devId = 1; + +#ifndef NO_RSA + if (ret == 0) + ret = rsa_test(); +#endif +#ifdef HAVE_ECC + if (ret == 0) + ret = ecc_test(); +#endif + + return ret; +} +#endif /* WOLF_CRYPTO_DEV */ + + #undef ERROR_OUT #else diff --git a/wolfssl/wolfcrypt/cryptodev.h b/wolfssl/wolfcrypt/cryptodev.h new file mode 100644 index 000000000..98be93cb4 --- /dev/null +++ b/wolfssl/wolfcrypt/cryptodev.h @@ -0,0 +1,114 @@ +/* cryptodev.h + * + * Copyright (C) 2006-2018 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _WOLF_CRYPTO_DEV_H_ +#define _WOLF_CRYPTO_DEV_H_ + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef WOLF_CRYPTO_DEV + +#ifndef NO_RSA + #include +#endif +#ifdef HAVE_ECC + #include +#endif + +/* Crypto Information Structure for callbacks */ +typedef struct wc_CryptoInfo { + int algo_type; /* enum wc_AlgoType */ + struct { + int type; /* enum wc_PkType */ + union { + #ifndef NO_RSA + struct { + const byte* in; + word32 inLen; + byte* out; + word32* outLen; + int type; + RsaKey* key; + WC_RNG* rng; + } rsa; + #endif + #ifdef HAVE_ECC + struct { + ecc_key* private_key; + ecc_key* public_key; + byte* out; + word32* outlen; + } ecdh; + struct { + const byte* in; + word32 inlen; + byte* out; + word32 *outlen; + WC_RNG* rng; + ecc_key* key; + } eccsign; + struct { + const byte* sig; + word32 siglen; + const byte* hash; + word32 hashlen; + int* res; + ecc_key* key; + } eccverify; + #endif + }; + } pk; +} wc_CryptoInfo; + +typedef int (*CryptoDevCallbackFunc)(int devId, wc_CryptoInfo* info, void* ctx); + +WOLFSSL_LOCAL void wc_CryptoDev_Init(void); + +WOLFSSL_API int wc_CryptoDev_RegisterDevice(int devId, CryptoDevCallbackFunc cb, void* ctx); +WOLFSSL_API void wc_CryptoDev_UnRegisterDevice(int devId); + + +#ifndef NO_RSA +WOLFSSL_LOCAL int wc_CryptoDev_Rsa(const byte* in, word32 inLen, byte* out, + word32* outLen, int type, RsaKey* key, WC_RNG* rng); +#endif /* !NO_RSA */ + +#ifdef HAVE_ECC +WOLFSSL_LOCAL int wc_CryptoDev_Ecdh(ecc_key* private_key, ecc_key* public_key, + byte* out, word32* outlen); + +WOLFSSL_LOCAL int wc_CryptoDev_EccSign(const byte* in, word32 inlen, byte* out, + word32 *outlen, WC_RNG* rng, ecc_key* key); + +WOLFSSL_LOCAL int wc_CryptoDev_EccVerify(const byte* sig, word32 siglen, + const byte* hash, word32 hashlen, int* res, ecc_key* key); +#endif /* HAVE_ECC */ + +#endif /* WOLF_CRYPTO_DEV */ + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* _WOLF_CRYPTO_DEV_H_ */ diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index f6fdf219b..7554c2963 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -319,7 +319,7 @@ struct ecc_key { int slot; /* Key Slot Number (-1 unknown) */ byte pubkey_raw[ECC_MAX_CRYPTO_HW_PUBKEY_SIZE]; #endif -#ifdef PLUTON_CRYPTO_ECC +#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_DEV) int devId; #endif #ifdef WOLFSSL_ASYNC_CRYPT diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 6e84ed9d5..95221ef1d 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -61,7 +61,8 @@ nobase_include_HEADERS+= \ wolfssl/wolfcrypt/pkcs12.h \ wolfssl/wolfcrypt/wolfmath.h \ wolfssl/wolfcrypt/sha3.h \ - wolfssl/wolfcrypt/cpuid.h + wolfssl/wolfcrypt/cpuid.h \ + wolfssl/wolfcrypt/cryptodev.h noinst_HEADERS+= \ wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h \ diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index 764e2668e..f0b4deed1 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -133,6 +133,7 @@ typedef struct PKCS7 { int encryptOID; /* key encryption algorithm OID */ int keyWrapOID; /* key wrap algorithm OID */ int keyAgreeOID; /* key agreement algorithm OID */ + int devId; /* device ID for HW based private key */ byte issuerHash[KEYID_SIZE]; /* hash of all alt Names */ byte issuerSn[MAX_SN_SZ]; /* singleCert's serial number */ byte publicKey[MAX_RSA_INT_SZ + MAX_RSA_E_SZ ];/*MAX RSA key size (m + e)*/ diff --git a/wolfssl/wolfcrypt/rsa.h b/wolfssl/wolfcrypt/rsa.h index 5cbc76770..ecf41413d 100644 --- a/wolfssl/wolfcrypt/rsa.h +++ b/wolfssl/wolfcrypt/rsa.h @@ -121,6 +121,9 @@ struct RsaKey { #ifdef WC_RSA_BLINDING WC_RNG* rng; /* for PrivateDecrypt blinding */ #endif +#ifdef WOLF_CRYPTO_DEV + int devId; +#endif #ifdef WOLFSSL_ASYNC_CRYPT WC_ASYNC_DEV asyncDev; #ifdef WOLFSSL_CERT_GEN diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 3329b794f..37a982bf8 100755 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -102,7 +102,7 @@ (defined(LP64) || defined(_LP64)) /* LP64 with GNU GCC compiler is reserved for when long int is 64 bits * and int uses 32 bits. When using Solaris Studio sparc and __sparc are - * avialable for 32 bit detection but __sparc64__ could be missed. This + * available for 32 bit detection but __sparc64__ could be missed. This * uses LP64 for checking 64 bit CPU arch. */ typedef word64 wolfssl_word; #define WC_64BIT_CPU @@ -201,7 +201,7 @@ /* idea to add global alloc override by Moises Guimaraes */ /* default to libc stuff */ /* XREALLOC is used once in normal math lib, not in fast math lib */ - /* XFREE on some embeded systems doesn't like free(0) so test */ + /* XFREE on some embedded systems doesn't like free(0) so test */ #if defined(HAVE_IO_POOL) WOLFSSL_API void* XMALLOC(size_t n, void* heap, int type); WOLFSSL_API void* XREALLOC(void *p, size_t n, void* heap, int type); @@ -496,6 +496,17 @@ MIN_STACK_BUFFER = 8 }; + + /* Algorithm Types */ + enum wc_AlgoType { + WC_ALGO_TYPE_NONE = 0, + WC_ALGO_TYPE_HASH = 1, + WC_ALGO_TYPE_CIPHER = 2, + WC_ALGO_TYPE_PK = 3, + + WC_ALGO_TYPE_MAX = WC_ALGO_TYPE_PK + }; + /* hash types */ enum wc_HashType { WC_HASH_TYPE_NONE = 0, @@ -518,7 +529,7 @@ }; /* cipher types */ - enum CipherTypes { + enum wc_CipherType { WC_CIPHER_NONE = 0, WC_CIPHER_AES = 1, WC_CIPHER_AES_CBC = 2, @@ -530,10 +541,25 @@ WC_CIPHER_DES = 8, WC_CIPHER_CHACHA = 9, WC_CIPHER_HC128 = 10, + WC_CIPHER_IDEA = 11, WC_CIPHER_MAX = WC_CIPHER_HC128 }; + /* PK=public key (asymmetric) based algorithms */ + enum wc_PkType { + WC_PK_TYPE_NONE = 0, + WC_PK_TYPE_RSA = 1, + WC_PK_TYPE_DH = 2, + WC_PK_TYPE_ECDH = 3, + WC_PK_TYPE_ECDSA_SIGN = 4, + WC_PK_TYPE_ECDSA_VERIFY = 5, + WC_PK_TYPE_ED25519 = 6, + WC_PK_TYPE_CURVE25519 = 7, + + WC_PK_TYPE_MAX = WC_PK_TYPE_CURVE25519 + }; + /* settings detection for compile vs runtime math incompatibilities */ enum {