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
This commit is contained in:
Jacob Barthelmeh
2018-08-17 09:46:16 -06:00
parent 085daa78cd
commit 2e88151cfd
16 changed files with 990 additions and 7 deletions

View File

@@ -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 "---"

View File

@@ -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[] =

View File

@@ -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 */

View File

@@ -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";

View File

@@ -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

View File

@@ -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 <config.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#if !defined(NO_AES) && defined(WOLFSSL_DEVCRYPTO)
#include <wolfssl/wolfcrypt/aes.h>
#include <wolfssl/wolfcrypt/logging.h>
#include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h>
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#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 */

View File

@@ -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 <config.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
#if defined(WOLFSSL_DEVCRYPTO_HASH)
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/logging.h>
#include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h>
#if !defined(NO_SHA256)
#include <wolfssl/wolfcrypt/sha256.h>
#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 */

View File

@@ -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 <config.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
#if defined(WOLFSSL_DEVCRYPTO)
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/logging.h>
#include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h>
/* 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 */

View File

@@ -108,6 +108,11 @@
#include <wolfcrypt/src/misc.c>
#endif
#ifdef WOLFSSL_DEVCRYPTO_HASH
#include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h>
#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)

View File

@@ -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

View File

@@ -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;

View File

@@ -73,6 +73,10 @@
#include <sys/socket.h>
#endif
#if defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC)
#include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h>
#endif
#if defined(HAVE_AESGCM) && !defined(WC_NO_RNG)
#include <wolfssl/wolfcrypt/random.h>
#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;

View File

@@ -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

View File

@@ -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

View File

@@ -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 <wolfssl/wolfcrypt/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <crypto/cryptodev.h>
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 */

View File

@@ -80,6 +80,9 @@
#ifdef WOLFSSL_ASYNC_CRYPT
#include <wolfssl/wolfcrypt/async.h>
#endif
#ifdef WOLFSSL_DEVCRYPTO_HASH
#include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h>
#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;