From 2e88151cfdb5f8a5435c529f06f3a00c280de3a9 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 17 Aug 2018 09:46:16 -0600 Subject: [PATCH 1/3] crypto only sha256 cryptodev formating and refactoring update configure for devcrypto add AES algorithms to cyrptodev port increase structure size for compatibility AES with cryptodev add wc_devcrypto.h to install path --- configure.ac | 56 ++- tests/api.c | 3 +- wolfcrypt/src/aes.c | 31 +- wolfcrypt/src/error.c | 3 + wolfcrypt/src/include.am | 10 +- wolfcrypt/src/port/devcrypto/devcrypto_aes.c | 383 ++++++++++++++++++ wolfcrypt/src/port/devcrypto/devcrypto_hash.c | 244 +++++++++++ wolfcrypt/src/port/devcrypto/wc_devcrypto.c | 167 ++++++++ wolfcrypt/src/sha256.c | 20 +- wolfcrypt/test/test.c | 2 +- wolfssl/openssl/aes.h | 4 + wolfssl/wolfcrypt/aes.h | 8 + wolfssl/wolfcrypt/error-crypt.h | 3 +- wolfssl/wolfcrypt/include.am | 4 + .../wolfcrypt/port/devcrypto/wc_devcrypto.h | 50 +++ wolfssl/wolfcrypt/sha256.h | 9 + 16 files changed, 990 insertions(+), 7 deletions(-) create mode 100644 wolfcrypt/src/port/devcrypto/devcrypto_aes.c create mode 100644 wolfcrypt/src/port/devcrypto/devcrypto_hash.c create mode 100644 wolfcrypt/src/port/devcrypto/wc_devcrypto.c create mode 100644 wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h diff --git a/configure.ac b/configure.ac index a78430fed..3ef593354 100644 --- a/configure.ac +++ b/configure.ac @@ -1023,6 +1023,49 @@ fi AM_CONDITIONAL([BUILD_AFALG], [test "x$ENABLED_AFALG" = "xyes"]) +# Support for Linux dev/crypto calls +AC_ARG_ENABLE([devcrypto], + [AS_HELP_STRING([--enable-devcrypto],[Enable Linux dev crypto calls: all | aes (all aes support) | hash (all hash algos) | cbc (aes-cbc only) (default: disabled)])], + [ ENABLED_DEVCRYPTO=$enableval ], + [ ENABLED_DEVCRYPTO=no ] + ) + +if test "$ENABLED_DEVCRYPTO" = "yes" || test "$ENABLED_DEVCRYPTO" = "all" +then + #enable all devcrypto supported algorithms + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO_CBC" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO_AES" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO_HASH" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_HASH_RAW" + ENABLED_DEVCRYPTO=yes +fi +if test "$ENABLED_DEVCRYPTO" = "aes" +then + #enable only AES-CBC algorithm support + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO_AES" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO_CBC" + ENABLED_DEVCRYPTO=yes +fi +if test "$ENABLED_DEVCRYPTO" = "cbc" +then + #enable only AES-CBC algorithm support + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO_CBC" + ENABLED_DEVCRYPTO=yes +fi +if test "$ENABLED_DEVCRYPTO" = "hash" +then + #enable only hash algorithm support + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO_HASH" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_HASH_RAW" + ENABLED_DEVCRYPTO=yes +fi +AM_CONDITIONAL([BUILD_DEVCRYPTO], [test "x$ENABLED_DEVCRYPTO" = "xyes"]) + + # Camellia AC_ARG_ENABLE([camellia], [AS_HELP_STRING([--enable-camellia],[Enable wolfSSL Camellia support (default: disabled)])], @@ -2182,7 +2225,7 @@ AM_CONDITIONAL([BUILD_SELFTEST], [test "x$ENABLED_SELFTEST" = "xyes"]) SHA224_DEFAULT=no if test "$host_cpu" = "x86_64" || test "$host_cpu" = "aarch64" then - if test "x$ENABLED_AFALG" = "xno" && ( test "x$ENABLED_FIPS" = "xno" || test "x$FIPS_VERSION" = "xv2" ) + if test "x$ENABLED_AFALG" = "xno" && test "x$ENABLED_DEVCRYPTO" = "xno" && ( test "x$ENABLED_FIPS" = "xno" || test "x$FIPS_VERSION" = "xv2" ) then SHA224_DEFAULT=yes fi @@ -3364,6 +3407,12 @@ then # for TLS connections the intermediate hash needs to store buffer AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AFALG_HASH_KEEP" fi + + if test "$ENABLED_DEVCRYPTO" = "yes" + then + # for TLS connections the intermediate hash needs to store buffer + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEVCRYPTO_HASH_KEEP" + fi fi @@ -4303,6 +4352,10 @@ AS_IF([test "x$ENABLED_MCAST" = "xyes"], AS_IF([(test "x$ENABLED_AFALG" = "xyes") && (test "x$ENABLED_SHA224" = "xyes")], [AC_MSG_ERROR([--enable-sha224 with --enable-afalg not yet supported])]) +# WOLFSSL_DEVCRYPTO does not support SHA224 yet +AS_IF([(test "x$ENABLED_DEVCRYPTO" = "xyes") && (test "x$ENABLED_SHA224" = "xyes")], + [AC_MSG_ERROR([--enable-sha224 with --enable-devcrypto not yet supported])]) + # SCTP and Multicast require DTLS AS_IF([(test "x$ENABLED_DTLS" = "xno") && \ (test "x$ENABLED_SCTP" = "xyes" || test "x$ENABLED_MCAST" = "xyes")], @@ -4659,6 +4712,7 @@ echo " * Intel Quick Assist: $ENABLED_INTEL_QA" echo " * Xilinx Hardware Acc.: $ENABLED_XILINX" echo " * Inline Code: $ENABLED_INLINE" echo " * Linux AF_ALG: $ENABLED_AFALG" +echo " * Linux cryptodev: $ENABLED_DEVCRYPTO" echo "" echo "---" diff --git a/tests/api.c b/tests/api.c index c29f97b83..c48a6dd23 100644 --- a/tests/api.c +++ b/tests/api.c @@ -8649,6 +8649,7 @@ static int test_wc_AesCbcEncryptDecrypt (void) if (ret == 0) { /* Re init for decrypt and set flag. */ cbcE = 0; + wc_AesFree(&aes); ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_DECRYPTION); } @@ -8939,7 +8940,7 @@ static int test_wc_AesGcmEncryptDecrypt (void) int ret = 0; /* WOLFSSL_AFALG requires 12 byte IV */ #if !defined(NO_AES) && defined(HAVE_AESGCM) && defined(WOLFSSL_AES_256) && \ - !defined(WOLFSSL_AFALG) + !defined(WOLFSSL_AFALG) && !defined(WOLFSSL_DEVCRYPTO_AES) Aes aes; byte key32[] = diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index d39b4323d..1638be621 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -728,6 +728,8 @@ } #elif defined(WOLFSSL_AFALG) +#elif defined(WOLFSSL_DEVCRYPTO_AES) + /* if all AES is enabled with devcrypto then tables are not needed */ #else @@ -1543,7 +1545,8 @@ static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) #endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT || HAVE_AESGCM */ #if defined(HAVE_AES_DECRYPT) -#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) +#if (defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)) && \ + !defined(WOLFSSL_DEVCRYPTO_CBC) /* load 4 Td Tables into cache by cache line stride */ static WC_INLINE word32 PreFetchTd(void) @@ -1944,6 +1947,9 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) #elif defined(WOLFSSL_AFALG) /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */ +#elif defined(WOLFSSL_DEVCRYPTO_AES) + /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */ + #else static int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir) @@ -2170,6 +2176,10 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) ret = wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir); + #if defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC) + aes->ctx.cfd = -1; + XMEMCPY(aes->devKey, userKey, keylen); + #endif #ifdef WOLFSSL_IMX6_CAAM_BLOB ForceZero(local, sizeof(local)); #endif @@ -2264,6 +2274,9 @@ int wc_AesSetIV(Aes* aes, const byte* iv) #elif defined(WOLFSSL_AFALG) /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */ + #elif defined(WOLFSSL_DEVCRYPTO_AES) + /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */ + #else /* Allow direct access to one block encrypt */ void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in) @@ -2805,6 +2818,9 @@ int wc_AesSetIV(Aes* aes, const byte* iv) #elif defined(WOLFSSL_AFALG) /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */ +#elif defined(WOLFSSL_DEVCRYPTO_CBC) + /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */ + #else int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) @@ -3129,6 +3145,9 @@ int wc_AesSetIV(Aes* aes, const byte* iv) #elif defined(WOLFSSL_AFALG) /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */ + #elif defined(WOLFSSL_DEVCRYPTO_AES) + /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */ + #else /* Use software based AES counter */ @@ -3242,6 +3261,9 @@ static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz) #elif defined(WOLFSSL_AFALG) /* implemented in wolfcrypt/src/port/afalg/afalg_aes.c */ +#elif defined(WOLFSSL_DEVCRYPTO_AES) + /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */ + #else /* software + AESNI implementation */ #if !defined(FREESCALE_LTC_AES_GCM) @@ -9456,6 +9478,10 @@ void wc_AesFree(Aes* aes) close(aes->alFd); } #endif /* WOLFSSL_AFALG */ +#if defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC) + wc_DevCryptoFree(&aes->ctx); + ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE); +#endif } @@ -9500,6 +9526,9 @@ int wc_AesGetKeySize(Aes* aes, word32* keySize) #elif defined(WOLFSSL_AFALG) /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */ +#elif defined(WOLFSSL_DEVCRYPTO_AES) + /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */ + #else /* software implementation */ diff --git a/wolfcrypt/src/error.c b/wolfcrypt/src/error.c index 04bb47287..87eb05d0c 100644 --- a/wolfcrypt/src/error.c +++ b/wolfcrypt/src/error.c @@ -485,6 +485,9 @@ const char* wc_GetErrorString(int error) case WC_AFALG_SOCK_E: return "AF_ALG socket error"; + case WC_DEVCRYPTO_E: + return "Error with /dev/crypto"; + default: return "unknown error number"; diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index 94eff74a5..9ff96930e 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -65,12 +65,20 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \ wolfcrypt/src/port/st/stsafe.c \ wolfcrypt/src/port/st/README.md \ wolfcrypt/src/port/af_alg/afalg_aes.c \ - wolfcrypt/src/port/af_alg/afalg_hash.c + wolfcrypt/src/port/af_alg/afalg_hash.c \ + wolfcrypt/src/port/devcrypto/devcrypto_hash.c \ + wolfcrypt/src/port/devcrypto/wc_devcrypto.c if BUILD_CRYPTODEV src_libwolfssl_la_SOURCES += wolfcrypt/src/cryptodev.c endif +if BUILD_DEVCRYPTO +src_libwolfssl_la_SOURCES += wolfcrypt/src/port/devcrypto/devcrypto_hash.c +src_libwolfssl_la_SOURCES += wolfcrypt/src/port/devcrypto/devcrypto_aes.c +src_libwolfssl_la_SOURCES += wolfcrypt/src/port/devcrypto/wc_devcrypto.c +endif + if BUILD_CAVIUM src_libwolfssl_la_SOURCES += wolfcrypt/src/port/cavium/cavium_nitrox.c diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_aes.c b/wolfcrypt/src/port/devcrypto/devcrypto_aes.c new file mode 100644 index 000000000..ea872f9db --- /dev/null +++ b/wolfcrypt/src/port/devcrypto/devcrypto_aes.c @@ -0,0 +1,383 @@ +/* devcrypto_aes.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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include + +#if !defined(NO_AES) && defined(WOLFSSL_DEVCRYPTO) + +#include +#include +#include + +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + + +#if defined(HAVE_AES_CBC) && defined(WOLFSSL_DEVCRYPTO_CBC) +int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + struct crypt_op crt; + int ret; + + if (aes == NULL || out == NULL || in == NULL) { + return BAD_FUNC_ARG; + } + + /* encrypt only up to AES block size of date */ + sz = sz - (sz % AES_BLOCK_SIZE); + if (aes->ctx.cfd == -1) { + ret = wc_DevCryptoCreate(&aes->ctx, CRYPTO_AES_CBC, + (byte*)aes->devKey, aes->keylen); + if (ret != 0) + return ret; + } + wc_SetupCryptSym(&crt, &aes->ctx, (byte*)in, sz, out, (byte*)aes->reg, + COP_ENCRYPT); + ret = ioctl(aes->ctx.cfd, CIOCCRYPT, &crt); + if (ret != 0) { + return WC_DEVCRYPTO_E; + } + + /* store iv for next call */ + XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + + return 0; +} + +#ifdef HAVE_AES_DECRYPT +int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + struct crypt_op crt; + int ret; + + if (aes == NULL || out == NULL || in == NULL || sz % AES_BLOCK_SIZE != 0) { + return BAD_FUNC_ARG; + } + + XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + if (aes->ctx.cfd == -1) { + ret = wc_DevCryptoCreate(&aes->ctx, CRYPTO_AES_CBC, + (byte*)aes->devKey, aes->keylen); + if (ret != 0) + return ret; + } + wc_SetupCryptSym(&crt, &aes->ctx, (byte*)in, sz, out, (byte*)aes->reg, + COP_DECRYPT); + ret = ioctl(aes->ctx.cfd, CIOCCRYPT, &crt); + if (ret != 0) { + return WC_DEVCRYPTO_E; + } + + XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); + return 0; +} +#endif /* HAVE_AES_DECRYPT */ +#endif /* HAVE_AES_CBC && WOLFSSL_DEVCRYPTO_CBC */ + + +#ifdef WOLFSSL_DEVCRYPTO_AES /* all AES algorithms supported */ +int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, + const byte* iv, int dir) +{ +#if defined(AES_MAX_KEY_SIZE) + const word32 max_key_len = (AES_MAX_KEY_SIZE / 8); +#endif + + if (aes == NULL || + !((keylen == 16) || (keylen == 24) || (keylen == 32))) { + return BAD_FUNC_ARG; + } + +#if defined(AES_MAX_KEY_SIZE) + /* Check key length */ + if (keylen > max_key_len) { + return BAD_FUNC_ARG; + } +#endif + aes->keylen = keylen; + aes->rounds = keylen/4 + 6; + +#ifdef WOLFSSL_AES_COUNTER + aes->left = 0; +#endif + aes->ctx.cfd = -1; + XMEMCPY(aes->devKey, userKey, keylen); + + (void)dir; + return wc_AesSetIV(aes, iv); +} + + +/* AES-DIRECT */ +#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AES_ECB) + +/* common code between ECB encrypt and decrypt + * returns 0 on success */ +static int wc_DevCrypto_AesDirect(Aes* aes, byte* out, const byte* in, + word32 sz, int dir) +{ + int ret; + struct crypt_op crt; + + if (aes == NULL || out == NULL || in == NULL) { + return BAD_FUNC_ARG; + } + + if (aes->ctx.cfd == -1) { + ret = wc_DevCryptoCreate(&aes->ctx, CRYPTO_AES_ECB, (byte*)aes->devKey, + aes->keylen); + if (ret != 0) + return ret; + } + + wc_SetupCryptSym(&crt, &aes->ctx, (byte*)in, sz, out, NULL, dir); + ret = ioctl(aes->ctx.cfd, CIOCCRYPT, &crt); + if (ret != 0) { + return WC_DEVCRYPTO_E; + } + return 0; +} +#endif + + +#if defined(WOLFSSL_AES_DIRECT) +void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in) +{ + wc_DevCrypto_AesDirect(aes, out, in, AES_BLOCK_SIZE, COP_ENCRYPT); +} + + +void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in) +{ + wc_DevCrypto_AesDirect(aes, out, in, AES_BLOCK_SIZE, COP_DECRYPT); +} + + +int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen, + const byte* iv, int dir) +{ + return wc_AesSetKey(aes, userKey, keylen, iv, dir); +} +#endif + + +/* AES-CTR */ +#if defined(WOLFSSL_AES_COUNTER) + +/* Increment AES counter */ +static WC_INLINE void IncrementAesCounter(byte* inOutCtr) +{ + /* in network byte order so start at end and work back */ + int i; + for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) { + if (++inOutCtr[i]) /* we're done unless we overflow */ + return; + } +} + +int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + int ret; + struct crypt_op crt; + byte* tmp; + + if (aes == NULL || out == NULL || in == NULL) { + return BAD_FUNC_ARG; + } + + /* consume any unused bytes left in aes->tmp */ + tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left; + while (aes->left && sz) { + *(out++) = *(in++) ^ *(tmp++); + aes->left--; + sz--; + } + + if (aes->ctx.cfd == -1) { + ret = wc_DevCryptoCreate(&aes->ctx, CRYPTO_AES_CTR, (byte*)aes->devKey, + aes->keylen); + if (ret != 0) + return ret; + } + + if (sz > 0) { + /* clear previously leftover data */ + tmp = (byte*)aes->tmp; + XMEMSET(tmp, 0, AES_BLOCK_SIZE); + + /* update IV */ + wc_SetupCryptSym(&crt, &aes->ctx, (byte*)in, sz, out, (byte*)aes->reg, + COP_ENCRYPT); + ret = ioctl(aes->ctx.cfd, CIOCCRYPT, &crt); + if (ret != 0) { + return WC_DEVCRYPTO_E; + } + + /* adjust counter after call to hardware */ + while (sz >= AES_BLOCK_SIZE) { + IncrementAesCounter((byte*)aes->reg); + sz -= AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + } + } + + /* create key stream for later if needed */ + if (sz > 0) { + Aes tmpAes; + wc_AesSetKey(&tmpAes, (byte*)aes->devKey, aes->keylen, (byte*)aes->reg, + AES_ENCRYPTION); + wc_AesEncryptDirect(&tmpAes, (byte*)aes->tmp, (const byte*)aes->reg); + wc_AesFree(&tmpAes); + IncrementAesCounter((byte*)aes->reg); + + aes->left = AES_BLOCK_SIZE - (sz % AES_BLOCK_SIZE); + } + + return 0; +} +#endif /* WOLFSSL_AES_COUNTER */ + + +#ifdef HAVE_AESGCM + +int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) +{ + return wc_AesSetKey(aes, key, len, NULL, AES_ENCRYPTION); +} + + + +/* common code for AES-GCM encrypt/decrypt */ +static int wc_DevCrypto_AesGcm(Aes* aes, byte* out, byte* in, word32 sz, + const byte* iv, word32 ivSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz, + int dir) +{ + struct crypt_auth_op crt; + int ret; + byte scratch[AES_BLOCK_SIZE]; + + /* argument checks */ + if (aes == NULL || authTagSz > AES_BLOCK_SIZE) { + return BAD_FUNC_ARG; + } + + /* Account for NULL in/out buffers. Up to tag size is still written into + * in/out buffers */ + if (out == NULL) + out = scratch; + if (in == NULL) + in = scratch; + + if (aes->ctx.cfd == -1) { + ret = wc_DevCryptoCreate(&aes->ctx, CRYPTO_AES_GCM, (byte*)aes->devKey, + aes->keylen); + if (ret != 0) + return ret; + } + + /* if decrypting then the tag is expected to be at the end of "in" buffer */ + if (dir == COP_DECRYPT) { + XMEMCPY(in + sz, authTag, authTagSz); + sz += authTagSz; + } + else{ + /* get full tag from hardware */ + authTagSz = AES_BLOCK_SIZE; + } + wc_SetupCryptAead(&crt, &aes->ctx, (byte*)in, sz, out, (byte*)iv, ivSz, + dir, (byte*)authIn, authInSz, authTag, authTagSz); + ret = ioctl(aes->ctx.cfd, CIOCAUTHCRYPT, &crt); + if (ret != 0) { + if (dir == COP_DECRYPT) { + return AES_GCM_AUTH_E; + } + else { + return WC_DEVCRYPTO_E; + } + } + + /* after encryption the tag has been placed at the end of "out" buffer */ + if (dir == COP_ENCRYPT) { + XMEMCPY(authTag, out + sz, authTagSz); + } + return 0; +} + + +/* it is assumed that "out" buffer has enough room for cipher text + tag */ +int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, + const byte* iv, word32 ivSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz) +{ + if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) { + WOLFSSL_MSG("GcmEncrypt authTagSz too small error"); + return BAD_FUNC_ARG; + } + + return wc_DevCrypto_AesGcm(aes, out, (byte*)in, sz, iv, ivSz, + authTag, authTagSz, authIn, authInSz, + COP_ENCRYPT); +} + +#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT) +/* it is assumed that "in" buffer has enough room for cipher text + tag */ +int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, + const byte* iv, word32 ivSz, + const byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz) +{ + return wc_DevCrypto_AesGcm(aes, out, (byte*)in, sz, iv, ivSz, + (byte*)authTag, authTagSz, authIn, authInSz, + COP_DECRYPT); +} +#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */ +#endif /* HAVE_AESGCM */ + + +#ifdef HAVE_AES_ECB +int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + return wc_DevCrypto_AesDirect(aes, out, in, sz, COP_ENCRYPT); +} + + +int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + return wc_DevCrypto_AesDirect(aes, out, in, sz, COP_DECRYPT); +} +#endif /* HAVE_AES_ECB */ +#endif /* WOLFSSL_DEVCRYPTO_AES */ +#endif /* !NO_AES && WOLFSSL_DEVCRYPTO */ + diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c new file mode 100644 index 000000000..96a9cec8d --- /dev/null +++ b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c @@ -0,0 +1,244 @@ +/* devcrypto_hash.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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#if defined(WOLFSSL_DEVCRYPTO_HASH) + +#include +#include +#include + +#if !defined(NO_SHA256) +#include +#endif + +/* dereference structure based on type to get cryptodev context pointer + * can return NULL on fail case */ +static WC_CRYPTODEV* GetHashContext(void* ctx, int type) +{ + switch (type) { + case CRYPTO_SHA2_256: + return &((wc_Sha256*)ctx)->ctx; + + default: + return NULL; + } + + return NULL; +} + + +/* generic hash initialization + * key is for hmac algorithms and keySz is for the size of key buffer + * key should be null in the case of non hmac algorithms + * return 0 on success */ +static int HashInit(void* ctx, int type, byte* key, word32 keySz) +{ + WC_CRYPTODEV* cdev; + + if ((cdev = GetHashContext(ctx, type)) == NULL) { + WOLFSSL_MSG("Unsuported hash type"); + return BAD_FUNC_ARG; + } + + return wc_DevCryptoCreate(cdev, type, key, keySz); +} + + +/* generic function for updated hash structure + * returns 0 on success */ +static int HashUpdate(void* ctx, int type, const byte* input, word32 inputSz) +{ + WC_CRYPTODEV* dev; + struct crypt_op crt; + byte digest[64]; + + if (inputSz == 0) { + return 0; + } + + if ((dev = GetHashContext(ctx, type)) == NULL) { + WOLFSSL_MSG("Unsuported hash type"); + return BAD_FUNC_ARG; + } + + wc_SetupCrypt(&crt, dev, (byte*)input, inputSz, NULL, digest, COP_FLAG_UPDATE); + if (ioctl(dev->cfd, CIOCCRYPT, &crt)) { + WOLFSSL_MSG("Error with call to ioctl"); + return WC_DEVCRYPTO_E; + } + + return 0; +} + + +/* generic function for getting final digest value */ +static int GetDigest(void* ctx, int type, byte* out) +{ + WC_CRYPTODEV* dev; + struct crypt_op crt; + + if ((dev = GetHashContext(ctx, type)) == NULL) { + WOLFSSL_MSG("Unsuported hash type"); + return BAD_FUNC_ARG; + } + + wc_SetupCrypt(&crt, dev, NULL, 0, NULL, out, COP_FLAG_FINAL); + if (ioctl(dev->cfd, CIOCCRYPT, &crt)) { + WOLFSSL_MSG("Error with call to ioctl"); + return WC_DEVCRYPTO_E; + } + + return 0; +} + +#if !defined(NO_SHA256) + +int wc_InitSha256_ex(wc_Sha256* sha, void* heap, int devId) +{ + if (sha == NULL) { + return BAD_FUNC_ARG; + } + + (void)devId; /* no async for now */ + XMEMSET(sha, 0, sizeof(wc_Sha256)); + sha->heap = heap; + + return HashInit((void*)sha, CRYPTO_SHA2_256, NULL, 0); +} + + +int wc_Sha256Update(wc_Sha256* sha, const byte* in, word32 sz) +{ + if (sha == NULL || (sz > 0 && in == NULL)) { + return BAD_FUNC_ARG; + } + +#ifdef WOLFSSL_DEVCRYPTO_HASH_KEEP + /* keep full message to hash at end instead of incremental updates */ + if (sha->len < sha->used + sz) { + if (sha->msg == NULL) { + sha->msg = (byte*)XMALLOC(sha->used + sz, sha->heap, + DYNAMIC_TYPE_TMP_BUFFER); + } else { + byte* pt = (byte*)XREALLOC(sha->msg, sha->used + sz, sha->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (pt == NULL) { + return MEMORY_E; + } + sha->msg = pt; + } + if (sha->msg == NULL) { + return MEMORY_E; + } + sha->len = sha->used + sz; + } + XMEMCPY(sha->msg + sha->used, in, sz); + sha->used += sz; + return 0; +#else + return HashUpdate(sha, CRYPTO_SHA2_256, in, sz); +#endif +} + + +int wc_Sha256Final(wc_Sha256* sha, byte* hash) +{ + int ret; + + if (sha == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + +#ifdef WOLFSSL_DEVCRYPTO_HASH_KEEP + /* keep full message to hash at end instead of incremental updates */ + if ((ret = HashUpdate(sha, CRYPTO_SHA2_256, sha->msg, sha->used)) < 0) { + return ret; + } + XFREE(sha->msg, sha->heap, DYNAMIC_TYPE_TMP_BUFFER); + sha->msg = NULL; +#endif + ret = GetDigest(sha, CRYPTO_SHA2_256, hash); + if (ret != 0) { + return ret; + } + + wc_Sha256Free(sha); + return wc_InitSha256_ex(sha, sha->heap, 0); +} + + +int wc_Sha256GetHash(wc_Sha256* sha, byte* hash) +{ + if (sha == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + +#ifdef WOLFSSL_DEVCRYPTO_HASH_KEEP + { + int ret; + wc_Sha256 cpy; + wc_Sha256Copy(sha, &cpy); + + if ((ret = HashUpdate(&cpy, CRYPTO_SHA2_256, cpy.msg, cpy.used)) == 0) { + ret = GetDigest(&cpy, CRYPTO_SHA2_256, hash); + } + wc_Sha256Free(&cpy); + return ret; + } +#else + (void)sha; + (void)hash; + + WOLFSSL_MSG("Compile with WOLFSSL_DEVCRYPTO_HASH_KEEP for this feature"); + return NOT_COMPILED_IN; +#endif +} + +int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) +{ + if (src == NULL || dst == NULL) { + return BAD_FUNC_ARG; + } + + wc_InitSha256_ex(dst, src->heap, 0); +#ifdef WOLFSSL_DEVCRYPTO_HASH_KEEP + dst->len = src->len; + dst->used = src->used; + dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (dst->msg == NULL) { + return MEMORY_E; + } + XMEMCPY(dst->msg, src->msg, src->len); +#endif + + return 0; +} + +#endif /* !NO_SHA256 */ + +#endif /* WOLFSSL_DEVCRYPTO */ diff --git a/wolfcrypt/src/port/devcrypto/wc_devcrypto.c b/wolfcrypt/src/port/devcrypto/wc_devcrypto.c new file mode 100644 index 000000000..f8372f948 --- /dev/null +++ b/wolfcrypt/src/port/devcrypto/wc_devcrypto.c @@ -0,0 +1,167 @@ +/* wc_devcrypto.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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#if defined(WOLFSSL_DEVCRYPTO) + +#include +#include +#include + +/* sets up a context for talking to /dev/crypto + * return 0 on success */ +int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz) +{ + int fd; + int isHash = 0; /* flag for if hashing algorithm */ + + if (ctx == NULL) { + return BAD_FUNC_ARG; + } + + /* sanity check on session type before creating descriptor */ + XMEMSET(ctx, 0, sizeof(WC_CRYPTODEV)); + switch (type) { + case CRYPTO_SHA1: + case CRYPTO_SHA2_256: + isHash = 1; + break; + + #ifndef NO_AES + case CRYPTO_AES_CTR: + case CRYPTO_AES_ECB: + case CRYPTO_AES_GCM: + case CRYPTO_AES_CBC: + isHash = 0; + break; + #endif + + default: + WOLFSSL_MSG("Unknown / Unimplemented algorithm type"); + return BAD_FUNC_ARG; + } + + /* create descriptor */ + if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) { + WOLFSSL_MSG("Error opening /dev/crypto is cryptodev module loaded?"); + return WC_DEVCRYPTO_E; + } + if (fcntl(fd, F_SETFD, 1) == -1) { + WOLFSSL_MSG("Error setting F_SETFD with fcntl"); + close(fd); + return WC_DEVCRYPTO_E; + } + + /* set up session */ + ctx->cfd = fd; + + if (isHash) { + ctx->sess.mac = type; + } + else { + ctx->sess.cipher = type; + ctx->sess.key = (void*)key; + ctx->sess.keylen = keySz; + } + + if (ioctl(ctx->cfd, CIOCGSESSION, &ctx->sess)) { + close(fd); + WOLFSSL_MSG("Error starting cryptodev session"); + return WC_DEVCRYPTO_E; + } + + (void)key; + (void)keySz; + + return 0; +} + + +/* free up descriptor and session used with ctx */ +void wc_DevCryptoFree(WC_CRYPTODEV* ctx) +{ + if (ctx != NULL && ctx->cfd >= 0) { + if (ioctl(ctx->cfd, CIOCFSESSION, &ctx->sess.ses)) { + WOLFSSL_MSG("Error stopping cryptodev session"); + } + close(ctx->cfd); + } +} + + +/* setup crypt_op structure */ +void wc_SetupCrypt(struct crypt_op* crt, WC_CRYPTODEV* dev, + byte* src, int srcSz, byte* dst, byte* dig, int flag) + +{ + XMEMSET(crt, 0, sizeof(struct crypt_op)); + crt->ses = dev->sess.ses; + crt->src = src; + crt->len = srcSz; + crt->dst = dst; + crt->mac = dig; + crt->flags = flag; +} + + +/* setup crypt_op structure for symetric key operations */ +void wc_SetupCryptSym(struct crypt_op* crt, WC_CRYPTODEV* dev, + byte* src, word32 srcSz, byte* dst, byte* iv, int flag) + +{ + XMEMSET(crt, 0, sizeof(struct crypt_op)); + crt->ses = dev->sess.ses; + crt->src = src; + crt->len = srcSz; + crt->dst = dst; + crt->iv = iv; + crt->op = flag; +} + + +/* setup crypt_auth_op structure for aead operations */ +void wc_SetupCryptAead(struct crypt_auth_op* crt, WC_CRYPTODEV* dev, + byte* src, word32 srcSz, byte* dst, byte* iv, word32 ivSz, int flag, + byte* authIn, word32 authInSz, byte* authTag, word32 authTagSz) +{ + XMEMSET(crt, 0, sizeof(struct crypt_op)); + crt->ses = dev->sess.ses; + crt->src = src; + crt->len = srcSz; + crt->dst = dst; + crt->iv = iv; + crt->iv_len = ivSz; + crt->op = flag; + + /* also set auth in and tag */ + crt->auth_src = authIn; + crt->auth_len = authInSz; + crt->tag = authTag; + crt->tag_len = authTagSz; +} +#endif /* WOLFSSL_DEVCRYPTO */ + diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 05bff8329..804b163d4 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -108,6 +108,11 @@ #include #endif +#ifdef WOLFSSL_DEVCRYPTO_HASH + #include +#endif + + #if defined(USE_INTEL_SPEEDUP) #define HAVE_INTEL_AVX1 @@ -136,7 +141,7 @@ #if !defined(WOLFSSL_PIC32MZ_HASH) && !defined(STM32_HASH_SHA2) && \ (!defined(WOLFSSL_IMX6_CAAM) || defined(NO_IMX6_CAAM_HASH)) && \ - !defined(WOLFSSL_AFALG_HASH) + !defined(WOLFSSL_AFALG_HASH) && !defined(WOLFSSL_DEVCRYPTO_HASH) static int InitSha256(wc_Sha256* sha256) { int ret = 0; @@ -444,6 +449,9 @@ static int InitSha256(wc_Sha256* sha256) #elif defined(WOLFSSL_AFALG_HASH) /* implemented in wolfcrypt/src/port/af_alg/afalg_hash.c */ +#elif defined(WOLFSSL_DEVCRYPTO_HASH) + /* implemented in wolfcrypt/src/port/devcrypto/devcrypt_hash.c */ + #else #define NEED_SOFT_SHA256 @@ -2581,6 +2589,9 @@ SHA256_NOINLINE static int Transform_Sha256_AVX2_RORX_Len(wc_Sha256* sha256, #elif defined(WOLFSSL_AFALG_HASH) #error SHA224 currently not supported with AF_ALG enabled +#elif defined(WOLFSSL_DEVCRYPTO_HASH) + /* implemented in wolfcrypt/src/port/devcrypto/devcrypt_hash.c */ + #else #define NEED_SOFT_SHA224 @@ -2764,6 +2775,9 @@ void wc_Sha256Free(wc_Sha256* sha256) } #endif #endif /* WOLFSSL_AFALG_HASH */ +#ifdef WOLFSSL_DEVCRYPTO_HASH + wc_DevCryptoFree(&sha256->ctx); +#endif /* WOLFSSL_DEVCRYPTO */ } #endif /* !WOLFSSL_TI_HASH */ @@ -2809,6 +2823,10 @@ void wc_Sha256Free(wc_Sha256* sha256) #ifdef WOLFSSL_AFALG_HASH /* implemented in wolfcrypt/src/port/af_alg/afalg_hash.c */ + +#elif defined(WOLFSSL_DEVCRYPTO_HASH) + /* implemented in wolfcrypt/src/port/devcrypto/devcrypt_hash.c */ + #else int wc_Sha256GetHash(wc_Sha256* sha256, byte* hash) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 51fa46e50..2154896aa 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -757,7 +757,7 @@ initDefaultName(); printf( "AES256 test passed!\n"); #endif #ifdef HAVE_AESGCM - #ifndef WOLFSSL_AFALG + #if !defined(WOLFSSL_AFALG) && !defined(WOLFSSL_DEVCRYPTO) if ( (ret = aesgcm_test()) != 0) return err_sys("AES-GCM test failed!\n", ret); else diff --git a/wolfssl/openssl/aes.h b/wolfssl/openssl/aes.h index 58d235f8c..13af80f3c 100644 --- a/wolfssl/openssl/aes.h +++ b/wolfssl/openssl/aes.h @@ -48,6 +48,10 @@ typedef struct WOLFSSL_AES_KEY { /* key-based fast multiplication table. */ ALIGN16 void* M0[4096 / sizeof(void*)]; #endif /* GCM_TABLE */ + #if defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC) + /* large enough for additional devcrypto information */ + void* devKey[288 / sizeof(void*)]; + #endif } WOLFSSL_AES_KEY; typedef WOLFSSL_AES_KEY AES_KEY; diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 6a423135a..123ee4135 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -73,6 +73,10 @@ #include #endif +#if defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC) +#include +#endif + #if defined(HAVE_AESGCM) && !defined(WC_NO_RNG) #include #endif @@ -161,6 +165,10 @@ typedef struct Aes { int rdFd; /* socket to read from */ struct msghdr msg; int dir; /* flag for encrpyt or decrypt */ +#endif +#if defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC) + word32 devKey[AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE/sizeof(word32)]; /* raw key */ + WC_CRYPTODEV ctx; #endif void* heap; /* memory hint to use */ } Aes; diff --git a/wolfssl/wolfcrypt/error-crypt.h b/wolfssl/wolfcrypt/error-crypt.h index 2a1963bfd..b55df1231 100644 --- a/wolfssl/wolfcrypt/error-crypt.h +++ b/wolfssl/wolfcrypt/error-crypt.h @@ -214,8 +214,9 @@ enum { DH_CHECK_PRIV_E = -263, /* DH Check Priv Key error */ WC_AFALG_SOCK_E = -264, /* AF_ALG socket error */ + WC_DEVCRYPTO_E = -265, /* /dev/crypto error */ - WC_LAST_E = -264, /* Update this to indicate last error */ + WC_LAST_E = -265, /* Update this to indicate last error */ MIN_CODE_E = -300 /* errors -101 - -299 */ /* add new companion error id strings for any new error codes diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index d335b5c0b..063f6c97b 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -81,6 +81,10 @@ noinst_HEADERS+= \ wolfssl/wolfcrypt/port/af_alg/afalg_hash.h \ wolfssl/wolfcrypt/port/af_alg/wc_afalg.h +if BUILD_DEVCRYPTO +nobase_include_HEADERS+= wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h +endif + if BUILD_ASYNCCRYPT nobase_include_HEADERS+= wolfssl/wolfcrypt/async.h endif diff --git a/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h b/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h new file mode 100644 index 000000000..ad63971d2 --- /dev/null +++ b/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h @@ -0,0 +1,50 @@ +/* wc_devcrypto.h + * + * Copyright (C) 2006-2017 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLFSSL_DEVCRYPTO_H +#define WOLFSSL_DEVCRYPTO_H + +#include + +#include +#include +#include +#include + +typedef struct WC_CRYPTODEV { + int cfd; + struct session_op sess; +} WC_CRYPTODEV; + +WOLFSSL_LOCAL int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz); +WOLFSSL_LOCAL void wc_DevCryptoFree(WC_CRYPTODEV* ctx); +WOLFSSL_LOCAL void wc_SetupCrypt(struct crypt_op* crt, WC_CRYPTODEV* dev, + byte* src, int srcSz, byte* dst, byte* dig, int flag); +WOLFSSL_LOCAL void wc_SetupCryptSym(struct crypt_op* crt, WC_CRYPTODEV* dev, + byte* src, word32 srcSz, byte* dst, byte* iv, int flag); +WOLFSSL_LOCAL void wc_SetupCryptAead(struct crypt_auth_op* crt, WC_CRYPTODEV* dev, + byte* src, word32 srcSz, byte* dst, byte* iv, word32 ivSz, int flag, + byte* authIn, word32 authInSz, byte* authTag, word32 authTagSz); + +#endif /* WOLFSSL_DEVCRYPTO_H */ + + diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index 6d535a8be..f65179f92 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -80,6 +80,9 @@ #ifdef WOLFSSL_ASYNC_CRYPT #include #endif +#ifdef WOLFSSL_DEVCRYPTO_HASH + #include +#endif #if defined(_MSC_VER) #define SHA256_NOINLINE __declspec(noinline) @@ -142,6 +145,12 @@ typedef struct wc_Sha256 { #ifdef WOLFSSL_SMALL_STACK_CACHE word32* W; #endif +#ifdef WOLFSSL_DEVCRYPTO_HASH + WC_CRYPTODEV ctx; + byte* msg; + word32 used; + word32 len; +#endif #endif } wc_Sha256; From 96a7e366bcfd2461a9a3c48148061fb134b7f84d Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 19 Sep 2018 14:29:33 -0600 Subject: [PATCH 2/3] testing with valgrind and static analysis tools --- wolfcrypt/src/aes.c | 3 +++ wolfcrypt/src/port/devcrypto/devcrypto_aes.c | 3 ++- wolfcrypt/src/port/devcrypto/devcrypto_hash.c | 4 ++++ wolfcrypt/src/sha256.c | 14 +++++++------- wolfcrypt/test/test.c | 9 +++++++++ 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 1638be621..495e03d7f 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -9457,6 +9457,9 @@ int wc_AesInit(Aes* aes, void* heap, int devId) aes->alFd = -1; aes->rdFd = -1; #endif +#if defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC) + aes->ctx.cfd = -1; +#endif return ret; } diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_aes.c b/wolfcrypt/src/port/devcrypto/devcrypto_aes.c index ea872f9db..930ab553f 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_aes.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_aes.c @@ -283,7 +283,7 @@ static int wc_DevCrypto_AesGcm(Aes* aes, byte* out, byte* in, word32 sz, const byte* authIn, word32 authInSz, int dir) { - struct crypt_auth_op crt; + struct crypt_auth_op crt = {0}; int ret; byte scratch[AES_BLOCK_SIZE]; @@ -299,6 +299,7 @@ static int wc_DevCrypto_AesGcm(Aes* aes, byte* out, byte* in, word32 sz, if (in == NULL) in = scratch; + XMEMSET(scratch, 0, AES_BLOCK_SIZE); if (aes->ctx.cfd == -1) { ret = wc_DevCryptoCreate(&aes->ctx, CRYPTO_AES_GCM, (byte*)aes->devKey, aes->keylen); diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c index 96a9cec8d..9e986336b 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c @@ -174,6 +174,8 @@ int wc_Sha256Final(wc_Sha256* sha, byte* hash) return BAD_FUNC_ARG; } + /* help static analysis tools out */ + XMEMSET(hash, 0, WC_SHA256_DIGEST_SIZE); #ifdef WOLFSSL_DEVCRYPTO_HASH_KEEP /* keep full message to hash at end instead of incremental updates */ if ((ret = HashUpdate(sha, CRYPTO_SHA2_256, sha->msg, sha->used)) < 0) { @@ -205,6 +207,8 @@ int wc_Sha256GetHash(wc_Sha256* sha, byte* hash) wc_Sha256Copy(sha, &cpy); if ((ret = HashUpdate(&cpy, CRYPTO_SHA2_256, cpy.msg, cpy.used)) == 0) { + /* help static analysis tools out */ + XMEMSET(hash, 0, WC_SHA256_DIGEST_SIZE); ret = GetDigest(&cpy, CRYPTO_SHA2_256, hash); } wc_Sha256Free(&cpy); diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 804b163d4..874a200f1 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -2767,17 +2767,17 @@ void wc_Sha256Free(wc_Sha256* sha256) close(sha256->rdFd); sha256->rdFd = -1; /* avoid possible double close on socket */ } - - #if defined(WOLFSSL_AFALG_HASH_KEEP) - if (sha256->msg != NULL) { - XFREE(sha256->msg, sha256->heap, DYNAMIC_TYPE_TMP_BUFFER); - sha256->msg = NULL; - } - #endif #endif /* WOLFSSL_AFALG_HASH */ #ifdef WOLFSSL_DEVCRYPTO_HASH wc_DevCryptoFree(&sha256->ctx); #endif /* WOLFSSL_DEVCRYPTO */ +#if defined(WOLFSSL_AFALG_HASH_KEEP) || \ + (defined(WOLFSSL_DEVCRYPTO_HASH) && defined(WOLFSSL_DEVCRYPTO_HASH_KEEP)) + if (sha256->msg != NULL) { + XFREE(sha256->msg, sha256->heap, DYNAMIC_TYPE_TMP_BUFFER); + sha256->msg = NULL; + } +#endif } #endif /* !WOLFSSL_TI_HASH */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 2154896aa..083c91af4 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -5821,6 +5821,9 @@ static int aes_cbc_test(void) byte key[] = "0123456789abcdef "; /* align */ byte iv[] = "1234567890abcdef "; /* align */ + XMEMSET(cipher, 0, AES_BLOCK_SIZE); + XMEMSET(plain, 0, AES_BLOCK_SIZE); + /* Parameter Validation testing. */ ret = wc_AesCbcEncryptWithKey(cipher, msg, AES_BLOCK_SIZE, key, 17, NULL); if (ret != BAD_FUNC_ARG) @@ -5894,6 +5897,7 @@ int aes_test(void) return -5403; #endif + XMEMSET(cipher, 0, AES_BLOCK_SIZE * 4); ret = wc_AesCbcEncrypt(&enc, cipher, msg, AES_BLOCK_SIZE); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE); @@ -5901,6 +5905,7 @@ int aes_test(void) if (ret != 0) return -5404; #ifdef HAVE_AES_DECRYPT + XMEMSET(plain, 0, AES_BLOCK_SIZE * 4); ret = wc_AesCbcDecrypt(&dec, plain, cipher, AES_BLOCK_SIZE); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &dec.asyncDev, WC_ASYNC_FLAG_NONE); @@ -6445,6 +6450,7 @@ int aes192_test(void) return -5503; #endif + XMEMSET(cipher, 0, AES_BLOCK_SIZE); ret = wc_AesCbcEncrypt(&enc, cipher, msg, (int) sizeof(msg)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE); @@ -6452,6 +6458,7 @@ int aes192_test(void) if (ret != 0) return -5504; #ifdef HAVE_AES_DECRYPT + XMEMSET(plain, 0, AES_BLOCK_SIZE); ret = wc_AesCbcDecrypt(&dec, plain, cipher, (int) sizeof(cipher)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &dec.asyncDev, WC_ASYNC_FLAG_NONE); @@ -6532,6 +6539,7 @@ int aes256_test(void) return -5603; #endif + XMEMSET(cipher, 0, AES_BLOCK_SIZE); ret = wc_AesCbcEncrypt(&enc, cipher, msg, (int) sizeof(msg)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE); @@ -6539,6 +6547,7 @@ int aes256_test(void) if (ret != 0) return -5604; #ifdef HAVE_AES_DECRYPT + XMEMSET(plain, 0, AES_BLOCK_SIZE); ret = wc_AesCbcDecrypt(&dec, plain, cipher, (int) sizeof(cipher)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &dec.asyncDev, WC_ASYNC_FLAG_NONE); From fe2f9d4aa4e4bbc818d6909da494d0d3d6f2aa14 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Thu, 20 Sep 2018 15:59:29 -0600 Subject: [PATCH 3/3] minor adjustments and add README --- wolfcrypt/src/aes.c | 9 ++-- wolfcrypt/src/include.am | 3 +- wolfcrypt/src/port/devcrypto/README.md | 43 +++++++++++++++++++ wolfcrypt/src/port/devcrypto/devcrypto_hash.c | 2 +- wolfcrypt/src/port/devcrypto/wc_devcrypto.c | 4 +- wolfssl/openssl/aes.h | 3 +- wolfssl/wolfcrypt/aes.h | 3 +- .../wolfcrypt/port/devcrypto/wc_devcrypto.h | 3 ++ wolfssl/wolfcrypt/sha256.h | 2 +- 9 files changed, 62 insertions(+), 10 deletions(-) create mode 100644 wolfcrypt/src/port/devcrypto/README.md diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 495e03d7f..53b2bf1f3 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -2176,7 +2176,8 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) ret = wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir); - #if defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC) + #if defined(WOLFSSL_DEVCRYPTO) && \ + (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC)) aes->ctx.cfd = -1; XMEMCPY(aes->devKey, userKey, keylen); #endif @@ -9457,7 +9458,8 @@ int wc_AesInit(Aes* aes, void* heap, int devId) aes->alFd = -1; aes->rdFd = -1; #endif -#if defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC) +#if defined(WOLFSSL_DEVCRYPTO) && \ + (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC)) aes->ctx.cfd = -1; #endif @@ -9481,7 +9483,8 @@ void wc_AesFree(Aes* aes) close(aes->alFd); } #endif /* WOLFSSL_AFALG */ -#if defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC) +#if defined(WOLFSSL_DEVCRYPTO) && \ + (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC)) wc_DevCryptoFree(&aes->ctx); ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE); #endif diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index 9ff96930e..0d7e8eb5b 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -67,7 +67,8 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \ wolfcrypt/src/port/af_alg/afalg_aes.c \ wolfcrypt/src/port/af_alg/afalg_hash.c \ wolfcrypt/src/port/devcrypto/devcrypto_hash.c \ - wolfcrypt/src/port/devcrypto/wc_devcrypto.c + wolfcrypt/src/port/devcrypto/wc_devcrypto.c \ + wolfcrypt/src/port/devcrypto/README.md if BUILD_CRYPTODEV src_libwolfssl_la_SOURCES += wolfcrypt/src/cryptodev.c diff --git a/wolfcrypt/src/port/devcrypto/README.md b/wolfcrypt/src/port/devcrypto/README.md new file mode 100644 index 000000000..7844dca86 --- /dev/null +++ b/wolfcrypt/src/port/devcrypto/README.md @@ -0,0 +1,43 @@ +# Description + +Used to build with cryptodev-linux library with Linux OS. + +# Quick Start + +## Installing cryptodev module + +If not already installed then the cryptodev-linux module will need installed. + +``` +git clone https://github.com/cryptodev-linux/cryptodev-linux.git +cd cryptodev-linux +make +sudo make install +modprobe cryptodev +``` + + +## Options for building wolfSSL + +For default build with all supported features use: + +``` +./configure --enable-cryptodev +``` + +Or for more control over features used: + +``` +./configure --enable-devcrypto=cbc +./configure --enable-devcrypto=hash +./configure --enable-devcrypto=aes +./configure --enable-devcrypto=all +``` + +Then build the wolfSSL library with: + +``` +make +sudo make install +./wolfcrypt/test/testwolfcrypt +``` diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c index 9e986336b..975c98567 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c @@ -61,7 +61,7 @@ static int HashInit(void* ctx, int type, byte* key, word32 keySz) WC_CRYPTODEV* cdev; if ((cdev = GetHashContext(ctx, type)) == NULL) { - WOLFSSL_MSG("Unsuported hash type"); + WOLFSSL_MSG("Unsupported hash type"); return BAD_FUNC_ARG; } diff --git a/wolfcrypt/src/port/devcrypto/wc_devcrypto.c b/wolfcrypt/src/port/devcrypto/wc_devcrypto.c index f8372f948..1fae9331b 100644 --- a/wolfcrypt/src/port/devcrypto/wc_devcrypto.c +++ b/wolfcrypt/src/port/devcrypto/wc_devcrypto.c @@ -47,7 +47,7 @@ int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz) XMEMSET(ctx, 0, sizeof(WC_CRYPTODEV)); switch (type) { case CRYPTO_SHA1: - case CRYPTO_SHA2_256: + case CRYPTO_SHA2_256: isHash = 1; break; @@ -128,7 +128,7 @@ void wc_SetupCrypt(struct crypt_op* crt, WC_CRYPTODEV* dev, } -/* setup crypt_op structure for symetric key operations */ +/* setup crypt_op structure for symmetric key operations */ void wc_SetupCryptSym(struct crypt_op* crt, WC_CRYPTODEV* dev, byte* src, word32 srcSz, byte* dst, byte* iv, int flag) diff --git a/wolfssl/openssl/aes.h b/wolfssl/openssl/aes.h index 13af80f3c..f6f45ae11 100644 --- a/wolfssl/openssl/aes.h +++ b/wolfssl/openssl/aes.h @@ -48,7 +48,8 @@ typedef struct WOLFSSL_AES_KEY { /* key-based fast multiplication table. */ ALIGN16 void* M0[4096 / sizeof(void*)]; #endif /* GCM_TABLE */ - #if defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC) + #if defined(WOLFSSL_DEVCRYPTO) && \ + (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC)) /* large enough for additional devcrypto information */ void* devKey[288 / sizeof(void*)]; #endif diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 123ee4135..40ada48fa 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -166,7 +166,8 @@ typedef struct Aes { struct msghdr msg; int dir; /* flag for encrpyt or decrypt */ #endif -#if defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC) +#if defined(WOLFSSL_DEVCRYPTO) && \ + (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC)) word32 devKey[AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE/sizeof(word32)]; /* raw key */ WC_CRYPTODEV ctx; #endif diff --git a/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h b/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h index ad63971d2..c3a1fab9f 100644 --- a/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h +++ b/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h @@ -25,6 +25,8 @@ #include +#ifdef WOLFSSL_DEVCRYPTO + #include #include #include @@ -45,6 +47,7 @@ WOLFSSL_LOCAL void wc_SetupCryptAead(struct crypt_auth_op* crt, WC_CRYPTODEV* de byte* src, word32 srcSz, byte* dst, byte* iv, word32 ivSz, int flag, byte* authIn, word32 authInSz, byte* authTag, word32 authTagSz); +#endif /* WOLFSSL_DEVCRYPTO */ #endif /* WOLFSSL_DEVCRYPTO_H */ diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index f65179f92..71f06e1f0 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -80,7 +80,7 @@ #ifdef WOLFSSL_ASYNC_CRYPT #include #endif -#ifdef WOLFSSL_DEVCRYPTO_HASH +#if defined(WOLFSSL_DEVCRYPTO) && defined(WOLFSSL_DEVCRYPTO_HASH) #include #endif