mirror of https://github.com/wolfSSL/wolfssl.git
inital AES-CBC with af_alg
progress on AES-GCM with AF_ALG and add SHA256 add aes-gcm test cases and finish logic of aes-gcm with AF_ALG formating of tabs and white space add files to dist adding ecb and ctr mode with af_alg make length of buffers for ctr be AES_BLOCK_SIZE formating and add support for sha256 copy/gethash sanity checks on arguments cast return values and valgrind tests make it easier to use sha256 with af_alg remove hard tabs add endif for after rebasepull/1728/head
parent
2b3f94944d
commit
cb756397b3
29
configure.ac
29
configure.ac
|
@ -977,6 +977,22 @@ fi
|
|||
AM_CONDITIONAL([BUILD_AESNI], [test "x$ENABLED_AESNI" = "xyes"])
|
||||
|
||||
|
||||
# Linux af_alg
|
||||
AC_ARG_ENABLE([afalg],
|
||||
[AS_HELP_STRING([--enable-afalg],[Enable Linux af_alg use for crypto (default: disabled)])],
|
||||
[ ENABLED_AFALG=$enableval ],
|
||||
[ ENABLED_AFALG=no ]
|
||||
)
|
||||
|
||||
if test "$ENABLED_AFALG" = "yes"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AFALG"
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AFALG_HASH"
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL([BUILD_AFALG], [test "x$ENABLED_AFALG" = "xyes"])
|
||||
|
||||
|
||||
# Camellia
|
||||
AC_ARG_ENABLE([camellia],
|
||||
[AS_HELP_STRING([--enable-camellia],[Enable wolfSSL Camellia support (default: disabled)])],
|
||||
|
@ -2114,7 +2130,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_FIPS" = "xno" || test "x$FIPS_VERSION" = "xv2"
|
||||
if test "x$ENABLED_AFALG" = "xno" && ( test "x$ENABLED_FIPS" = "xno" || test "x$FIPS_VERSION" = "xv2" )
|
||||
then
|
||||
SHA224_DEFAULT=yes
|
||||
fi
|
||||
|
@ -3276,6 +3292,12 @@ then
|
|||
then
|
||||
AC_MSG_ERROR([please disable ecc if disabling asn.])
|
||||
fi
|
||||
|
||||
if test "$ENABLED_AFALG" = "yes"
|
||||
then
|
||||
# for TLS connections the intermediate hash needs to store buffer
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AFALG_HASH_KEEP"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
|
@ -4211,6 +4233,10 @@ AS_IF([test "x$ENABLED_SCTP" = "xyes"],
|
|||
AS_IF([test "x$ENABLED_MCAST" = "xyes"],
|
||||
[AM_CFLAGS="-DWOLFSSL_MULTICAST $AM_CFLAGS"])
|
||||
|
||||
# WOLFSSL_AFALG does not support SHA224 yet
|
||||
AS_IF([(test "x$ENABLED_AFALG" = "xyes") && (test "x$ENABLED_SHA224" = "xyes")],
|
||||
[AC_MSG_ERROR([--enable-sha224 with --enable-afalg 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")],
|
||||
|
@ -4564,6 +4590,7 @@ echo " * Write duplicate: $ENABLED_WRITEDUP"
|
|||
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 ""
|
||||
echo "---"
|
||||
|
||||
|
|
|
@ -148,6 +148,10 @@ src_libwolfssl_la_SOURCES += wolfcrypt/src/sha256.c
|
|||
endif
|
||||
endif
|
||||
|
||||
if BUILD_AFALG
|
||||
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/af_alg/afalg_hash.c
|
||||
endif
|
||||
|
||||
if BUILD_WOLFEVENT
|
||||
src_libwolfssl_la_SOURCES += wolfcrypt/src/wolfevent.c
|
||||
endif
|
||||
|
@ -193,6 +197,9 @@ src_libwolfssl_la_SOURCES += wolfcrypt/src/aes.c
|
|||
if BUILD_ARMASM
|
||||
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/arm/armv8-aes.c
|
||||
endif
|
||||
if BUILD_AFALG
|
||||
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/af_alg/afalg_aes.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -375,6 +382,10 @@ if BUILD_IDEA
|
|||
src_libwolfssl_la_SOURCES += wolfcrypt/src/idea.c
|
||||
endif
|
||||
|
||||
if BUILD_AFALG
|
||||
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/af_alg/wc_afalg.c
|
||||
endif
|
||||
|
||||
if !BUILD_CRYPTONLY
|
||||
# ssl files
|
||||
src_libwolfssl_la_SOURCES += \
|
||||
|
|
|
@ -8697,7 +8697,9 @@ static int test_wc_AesGcmSetKey (void)
|
|||
static int test_wc_AesGcmEncryptDecrypt (void)
|
||||
{
|
||||
int ret = 0;
|
||||
#if !defined(NO_AES) && defined(HAVE_AESGCM) && defined(WOLFSSL_AES_256)
|
||||
/* WOLFSSL_AFALG requires 12 byte IV */
|
||||
#if !defined(NO_AES) && defined(HAVE_AESGCM) && defined(WOLFSSL_AES_256) && \
|
||||
!defined(WOLFSSL_AFALG)
|
||||
|
||||
Aes aes;
|
||||
byte key32[] =
|
||||
|
|
|
@ -1733,6 +1733,7 @@ static void bench_aesgcm_internal(int doAsync, const byte* key, word32 keySz,
|
|||
{
|
||||
int ret = 0, i, count = 0, times, pending = 0;
|
||||
Aes enc[BENCH_MAX_PENDING];
|
||||
Aes dec[BENCH_MAX_PENDING];
|
||||
double start;
|
||||
|
||||
DECLARE_VAR(bench_additional, byte, AES_AUTH_ADD_SZ, HEAP_HINT);
|
||||
|
@ -1789,7 +1790,21 @@ exit_aes_gcm:
|
|||
bench_stats_sym_finish(encLabel, doAsync, count, bench_size, start, ret);
|
||||
|
||||
#ifdef HAVE_AES_DECRYPT
|
||||
/* GCM uses same routine in backend for both encrypt and decrypt */
|
||||
/* init keys */
|
||||
for (i = 0; i < BENCH_MAX_PENDING; i++) {
|
||||
if ((ret = wc_AesInit(&dec[i], HEAP_HINT,
|
||||
doAsync ? devId : INVALID_DEVID)) != 0) {
|
||||
printf("AesInit failed, ret = %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = wc_AesGcmSetKey(&dec[i], key, keySz);
|
||||
if (ret != 0) {
|
||||
printf("AesGcmSetKey failed, ret = %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
bench_stats_start(&count, &start);
|
||||
do {
|
||||
for (times = 0; times < numBlocks || pending > 0; ) {
|
||||
|
@ -1797,12 +1812,12 @@ exit_aes_gcm:
|
|||
|
||||
/* while free pending slots in queue, submit ops */
|
||||
for (i = 0; i < BENCH_MAX_PENDING; i++) {
|
||||
if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, ×, numBlocks, &pending)) {
|
||||
ret = wc_AesGcmDecrypt(&enc[i], bench_plain,
|
||||
if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&dec[i]), 0, ×, numBlocks, &pending)) {
|
||||
ret = wc_AesGcmDecrypt(&dec[i], bench_plain,
|
||||
bench_cipher, BENCH_SIZE,
|
||||
iv, ivSz, bench_tag, AES_AUTH_TAG_SZ,
|
||||
bench_additional, aesAuthAddSz);
|
||||
if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, ×, &pending)) {
|
||||
if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&dec[i]), 0, ×, &pending)) {
|
||||
goto exit_aes_gcm_dec;
|
||||
}
|
||||
}
|
||||
|
@ -1812,6 +1827,10 @@ exit_aes_gcm:
|
|||
} while (bench_stats_sym_check(start));
|
||||
exit_aes_gcm_dec:
|
||||
bench_stats_sym_finish(decLabel, doAsync, count, bench_size, start, ret);
|
||||
|
||||
for (i = 0; i < BENCH_MAX_PENDING; i++) {
|
||||
wc_AesFree(&dec[i]);
|
||||
}
|
||||
#endif /* HAVE_AES_DECRYPT */
|
||||
|
||||
(void)decLabel;
|
||||
|
|
|
@ -726,6 +726,9 @@
|
|||
wc_AesEncryptDirect(aes, outBlock, inBlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(WOLFSSL_AFALG)
|
||||
|
||||
#else
|
||||
|
||||
/* using wolfCrypt software AES implementation */
|
||||
|
@ -1936,6 +1939,9 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
|
|||
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
|
||||
/* implemented in wolfcrypt/src/port/caam/caam_aes.c */
|
||||
|
||||
#elif defined(WOLFSSL_AFALG)
|
||||
/* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
|
||||
|
||||
#else
|
||||
static int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
|
||||
const byte* iv, int dir)
|
||||
|
@ -2253,6 +2259,9 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
|
|||
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
|
||||
/* implemented in wolfcrypt/src/port/caam/caam_aes.c */
|
||||
|
||||
#elif defined(WOLFSSL_AFALG)
|
||||
/* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
|
||||
|
||||
#else
|
||||
/* Allow direct access to one block encrypt */
|
||||
void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
|
||||
|
@ -2775,6 +2784,9 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
|
|||
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
|
||||
/* implemented in wolfcrypt/src/port/caam/caam_aes.c */
|
||||
|
||||
#elif defined(WOLFSSL_AFALG)
|
||||
/* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
|
||||
|
||||
#else
|
||||
|
||||
int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
||||
|
@ -3096,6 +3108,9 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
|
|||
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
|
||||
/* implemented in wolfcrypt/src/port/caam/caam_aes.c */
|
||||
|
||||
#elif defined(WOLFSSL_AFALG)
|
||||
/* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
|
||||
|
||||
#else
|
||||
|
||||
/* Use software based AES counter */
|
||||
|
@ -3205,6 +3220,10 @@ static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz)
|
|||
|
||||
#ifdef WOLFSSL_ARMASM
|
||||
/* implementation is located in wolfcrypt/src/port/arm/armv8-aes.c */
|
||||
|
||||
#elif defined(WOLFSSL_AFALG)
|
||||
/* implemented in wolfcrypt/src/port/afalg/afalg_aes.c */
|
||||
|
||||
#else /* software + AESNI implementation */
|
||||
|
||||
#if !defined(FREESCALE_LTC_AES_GCM)
|
||||
|
@ -8932,6 +8951,7 @@ int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,
|
|||
if (ret == 0)
|
||||
ret = wc_AesGcmEncrypt_ex(&aes, NULL, NULL, 0, iv, ivSz,
|
||||
authTag, authTagSz, authIn, authInSz);
|
||||
wc_AesFree(&aes);
|
||||
ForceZero(&aes, sizeof(aes));
|
||||
|
||||
return ret;
|
||||
|
@ -8956,6 +8976,7 @@ int wc_GmacVerify(const byte* key, word32 keySz,
|
|||
if (ret == 0)
|
||||
ret = wc_AesGcmDecrypt(&aes, NULL, NULL, 0, iv, ivSz,
|
||||
authTag, authTagSz, authIn, authInSz);
|
||||
wc_AesFree(&aes);
|
||||
ForceZero(&aes, sizeof(aes));
|
||||
|
||||
return ret;
|
||||
|
@ -9390,6 +9411,11 @@ int wc_AesInit(Aes* aes, void* heap, int devId)
|
|||
(void)devId;
|
||||
#endif /* WOLFSSL_ASYNC_CRYPT */
|
||||
|
||||
#ifdef WOLFSSL_AFALG
|
||||
aes->alFd = -1;
|
||||
aes->rdFd = -1;
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -9402,6 +9428,14 @@ void wc_AesFree(Aes* aes)
|
|||
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
|
||||
wolfAsync_DevCtxFree(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES);
|
||||
#endif /* WOLFSSL_ASYNC_CRYPT */
|
||||
#ifdef WOLFSSL_AFALG
|
||||
if (aes->rdFd > 0) { /* negative is error case */
|
||||
close(aes->rdFd);
|
||||
}
|
||||
if (aes->alFd > 0) {
|
||||
close(aes->alFd);
|
||||
}
|
||||
#endif /* WOLFSSL_AFALG */
|
||||
}
|
||||
|
||||
|
||||
|
@ -9442,6 +9476,10 @@ int wc_AesGetKeySize(Aes* aes, word32* keySize)
|
|||
#ifdef HAVE_AES_ECB
|
||||
#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
|
||||
/* implemented in wolfcrypt/src/port/caam/caam_aes.c */
|
||||
|
||||
#elif defined(WOLFSSL_AFALG)
|
||||
/* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
|
||||
|
||||
#else
|
||||
|
||||
/* software implementation */
|
||||
|
|
|
@ -482,6 +482,9 @@ const char* wc_GetErrorString(int error)
|
|||
case DH_CHECK_PRIV_E:
|
||||
return "DH Check Private Key failure";
|
||||
|
||||
case WC_AFALG_SOCK_E:
|
||||
return "AF_ALG socket error";
|
||||
|
||||
default:
|
||||
return "unknown error number";
|
||||
|
||||
|
|
|
@ -840,6 +840,7 @@ int wc_HashFree(wc_HashAlg* hash, enum wc_HashType type)
|
|||
}
|
||||
wc_Sha256Free(sha256);
|
||||
}
|
||||
wc_Sha256Free(sha256);
|
||||
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
|
|
|
@ -1070,6 +1070,43 @@ void wc_HmacFree(Hmac* hmac)
|
|||
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
|
||||
wolfAsync_DevCtxFree(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC);
|
||||
#endif /* WOLFSSL_ASYNC_CRYPT */
|
||||
|
||||
switch (hmac->macType) {
|
||||
#ifndef NO_MD5
|
||||
case WC_MD5:
|
||||
wc_Md5Free(&hmac->hash.md5);
|
||||
break;
|
||||
#endif /* !NO_MD5 */
|
||||
|
||||
#ifndef NO_SHA
|
||||
case WC_SHA:
|
||||
wc_ShaFree(&hmac->hash.sha);
|
||||
break;
|
||||
#endif /* !NO_SHA */
|
||||
|
||||
#ifdef WOLFSSL_SHA224
|
||||
case WC_SHA224:
|
||||
wc_Sha224Free(&hmac->hash.sha224);
|
||||
break;
|
||||
#endif /* WOLFSSL_SHA224 */
|
||||
|
||||
#ifndef NO_SHA256
|
||||
case WC_SHA256:
|
||||
wc_Sha256Free(&hmac->hash.sha256);
|
||||
break;
|
||||
#endif /* !NO_SHA256 */
|
||||
|
||||
#ifdef WOLFSSL_SHA512
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case WC_SHA384:
|
||||
wc_Sha384Free(&hmac->hash.sha384);
|
||||
break;
|
||||
#endif /* WOLFSSL_SHA384 */
|
||||
case WC_SHA512:
|
||||
wc_Sha512Free(&hmac->hash.sha512);
|
||||
break;
|
||||
#endif /* WOLFSSL_SHA512 */
|
||||
}
|
||||
}
|
||||
|
||||
int wolfSSL_GetHmacMaxSize(void)
|
||||
|
|
|
@ -62,7 +62,9 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \
|
|||
wolfcrypt/src/port/caam/caam_sha.c \
|
||||
wolfcrypt/src/port/caam/caam_doc.pdf \
|
||||
wolfcrypt/src/port/st/stm32.c \
|
||||
wolfcrypt/src/port/st/stsafe.c
|
||||
wolfcrypt/src/port/st/stsafe.c \
|
||||
wolfcrypt/src/port/af_alg/afalg_aes.c \
|
||||
wolfcrypt/src/port/af_alg/afalg_hash.c
|
||||
|
||||
if BUILD_CRYPTODEV
|
||||
src_libwolfssl_la_SOURCES += wolfcrypt/src/cryptodev.c
|
||||
|
|
|
@ -0,0 +1,691 @@
|
|||
/* afalg_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_AFALG)
|
||||
|
||||
#include <wolfssl/wolfcrypt/aes.h>
|
||||
#include <wolfssl/wolfcrypt/logging.h>
|
||||
#include <wolfssl/wolfcrypt/port/af_alg/wc_afalg.h>
|
||||
|
||||
#include <sys/uio.h> /* for readv */
|
||||
|
||||
#ifdef NO_INLINE
|
||||
#include <wolfssl/wolfcrypt/misc.h>
|
||||
#else
|
||||
#define WOLFSSL_MISC_INCLUDED
|
||||
#include <wolfcrypt/src/misc.c>
|
||||
#endif
|
||||
|
||||
static const char WC_TYPE_SYMKEY[] = "skcipher";
|
||||
static const char WC_NAME_AESCBC[] = "cbc(aes)";
|
||||
|
||||
static int wc_AesSetup(Aes* aes, const char* type, const char* name, int ivSz, int aadSz)
|
||||
{
|
||||
aes->rdFd = wc_Afalg_CreateRead(aes->alFd, type, name);
|
||||
if (aes->rdFd < 0) {
|
||||
WOLFSSL_MSG("Unable to accept and get AF_ALG read socket");
|
||||
aes->rdFd = WC_SOCK_NOTSET;
|
||||
return aes->rdFd;
|
||||
}
|
||||
|
||||
if (setsockopt(aes->alFd, SOL_ALG, ALG_SET_KEY, (byte*)aes->key, aes->keylen) != 0) {
|
||||
WOLFSSL_MSG("Unable to set AF_ALG key");
|
||||
aes->rdFd = WC_SOCK_NOTSET;
|
||||
return WC_AFALG_SOCK_E;
|
||||
}
|
||||
ForceZero((byte*)aes->key, sizeof(aes->key));
|
||||
|
||||
/* set up CMSG headers */
|
||||
XMEMSET((byte*)&(aes->msg), 0, sizeof(struct msghdr));
|
||||
|
||||
aes->msg.msg_control = (byte*)(aes->key); /* use existing key buffer for
|
||||
* control buffer */
|
||||
aes->msg.msg_controllen = CMSG_SPACE(4);
|
||||
if (aadSz > 0) {
|
||||
aes->msg.msg_controllen += CMSG_SPACE(4);
|
||||
}
|
||||
if (ivSz > 0) {
|
||||
aes->msg.msg_controllen += CMSG_SPACE((sizeof(struct af_alg_iv) + ivSz));
|
||||
}
|
||||
|
||||
if (wc_Afalg_SetOp(CMSG_FIRSTHDR(&(aes->msg)), aes->dir) < 0) {
|
||||
WOLFSSL_MSG("Error with setting AF_ALG operation");
|
||||
aes->rdFd = WC_SOCK_NOTSET;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
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->rdFd = WC_SOCK_NOTSET;
|
||||
aes->alFd = wc_Afalg_Socket();
|
||||
if (aes->alFd < 0) {
|
||||
WOLFSSL_MSG("Unable to open an AF_ALG socket");
|
||||
return WC_AFALG_SOCK_E;
|
||||
}
|
||||
|
||||
/* save key until type is known i.e. CBC, ECB, ... */
|
||||
XMEMCPY((byte*)(aes->key), userKey, keylen);
|
||||
aes->dir = dir;
|
||||
|
||||
return wc_AesSetIV(aes, iv);
|
||||
}
|
||||
|
||||
|
||||
/* AES-CBC */
|
||||
#ifdef HAVE_AES_CBC
|
||||
int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
||||
{
|
||||
struct cmsghdr* cmsg;
|
||||
struct iovec iov;
|
||||
int ret;
|
||||
|
||||
if (aes == NULL || out == NULL || in == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (aes->rdFd == WC_SOCK_NOTSET) {
|
||||
if ((ret = wc_AesSetup(aes, WC_TYPE_SYMKEY, WC_NAME_AESCBC,
|
||||
AES_IV_SIZE, 0)) != 0) {
|
||||
WOLFSSL_MSG("Error with first time setup of AF_ALG socket");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
sz = sz - (sz % AES_BLOCK_SIZE);
|
||||
if ((sz / AES_BLOCK_SIZE) > 0) {
|
||||
/* update IV */
|
||||
cmsg = CMSG_FIRSTHDR(&(aes->msg));
|
||||
ret = wc_Afalg_SetIv(CMSG_NXTHDR(&(aes->msg), cmsg),
|
||||
(byte*)(aes->reg), AES_IV_SIZE);
|
||||
if (ret < 0) {
|
||||
WOLFSSL_MSG("Error setting IV");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* set data to be encrypted */
|
||||
iov.iov_base = (byte*)in;
|
||||
iov.iov_len = sz;
|
||||
|
||||
aes->msg.msg_iov = &iov;
|
||||
aes->msg.msg_iovlen = 1; /* # of iov structures */
|
||||
|
||||
ret = (int)sendmsg(aes->rdFd, &(aes->msg), 0);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = (int)read(aes->rdFd, out, sz);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* set IV for next CBC 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 cmsghdr* cmsg;
|
||||
struct iovec iov;
|
||||
int ret;
|
||||
|
||||
if (aes == NULL || out == NULL || in == NULL
|
||||
|| sz % AES_BLOCK_SIZE != 0) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (aes->rdFd == WC_SOCK_NOTSET) {
|
||||
if ((ret = wc_AesSetup(aes, WC_TYPE_SYMKEY, WC_NAME_AESCBC,
|
||||
AES_IV_SIZE, 0)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if ((sz / AES_BLOCK_SIZE) > 0) {
|
||||
/* update IV */
|
||||
cmsg = CMSG_FIRSTHDR(&(aes->msg));
|
||||
ret = wc_Afalg_SetIv(CMSG_NXTHDR(&(aes->msg), cmsg),
|
||||
(byte*)(aes->reg), AES_IV_SIZE);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* set data to be decrypted */
|
||||
iov.iov_base = (byte*)in;
|
||||
iov.iov_len = sz;
|
||||
|
||||
aes->msg.msg_iov = &iov;
|
||||
aes->msg.msg_iovlen = 1; /* # of iov structures */
|
||||
|
||||
/* set IV for next CBC call */
|
||||
XMEMCPY(aes->reg, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
|
||||
|
||||
ret = (int)sendmsg(aes->rdFd, &(aes->msg), 0);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = (int)read(aes->rdFd, out, sz);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_AES_CBC */
|
||||
|
||||
|
||||
/* AES-DIRECT */
|
||||
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AES_ECB)
|
||||
|
||||
static const char WC_NAME_AESECB[] = "ecb(aes)";
|
||||
|
||||
/* common code between ECB encrypt and decrypt
|
||||
* returns 0 on success */
|
||||
static int wc_Afalg_AesDirect(Aes* aes, byte* out, const byte* in, word32 sz)
|
||||
{
|
||||
struct iovec iov;
|
||||
int ret;
|
||||
|
||||
if (aes == NULL || out == NULL || in == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (aes->rdFd == WC_SOCK_NOTSET) {
|
||||
if ((ret = wc_AesSetup(aes, WC_TYPE_SYMKEY, WC_NAME_AESECB,
|
||||
0, 0)) != 0) {
|
||||
WOLFSSL_MSG("Error with first time setup of AF_ALG socket");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* set data to be encrypted */
|
||||
iov.iov_base = (byte*)in;
|
||||
iov.iov_len = sz;
|
||||
|
||||
aes->msg.msg_iov = &iov;
|
||||
aes->msg.msg_iovlen = 1; /* # of iov structures */
|
||||
|
||||
ret = (int)sendmsg(aes->rdFd, &(aes->msg), 0);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = (int)read(aes->rdFd, out, sz);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(WOLFSSL_AES_DIRECT)
|
||||
void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
|
||||
{
|
||||
if (wc_Afalg_AesDirect(aes, out, in, AES_BLOCK_SIZE) != 0) {
|
||||
WOLFSSL_MSG("Error with AES encrypt direct call");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
|
||||
{
|
||||
if (wc_Afalg_AesDirect(aes, out, in, AES_BLOCK_SIZE) != 0) {
|
||||
WOLFSSL_MSG("Error with AES decrypt direct call");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
static const char WC_NAME_AESCTR[] = "ctr(aes)";
|
||||
|
||||
/* 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)
|
||||
{
|
||||
struct cmsghdr* cmsg;
|
||||
struct iovec iov[2];
|
||||
int ret;
|
||||
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->rdFd == WC_SOCK_NOTSET) {
|
||||
if ((ret = wc_AesSetup(aes, WC_TYPE_SYMKEY, WC_NAME_AESCTR,
|
||||
AES_IV_SIZE, 0)) != 0) {
|
||||
WOLFSSL_MSG("Error with first time setup of AF_ALG socket");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (sz > 0) {
|
||||
aes->left = sz % AES_BLOCK_SIZE;
|
||||
|
||||
/* clear previously leftover data */
|
||||
tmp = (byte*)aes->tmp;
|
||||
XMEMSET(tmp, 0, AES_BLOCK_SIZE);
|
||||
|
||||
/* update IV */
|
||||
cmsg = CMSG_FIRSTHDR(&(aes->msg));
|
||||
ret = wc_Afalg_SetIv(CMSG_NXTHDR(&(aes->msg), cmsg),
|
||||
(byte*)(aes->reg), AES_IV_SIZE);
|
||||
if (ret < 0) {
|
||||
WOLFSSL_MSG("Error setting IV");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* set data to be encrypted */
|
||||
iov[0].iov_base = (byte*)in;
|
||||
iov[0].iov_len = sz - aes->left;
|
||||
|
||||
iov[1].iov_base = tmp;
|
||||
if (aes->left > 0) {
|
||||
XMEMCPY(tmp, in + sz - aes->left, aes->left);
|
||||
iov[1].iov_len = AES_BLOCK_SIZE;
|
||||
}
|
||||
else {
|
||||
iov[1].iov_len = 0;
|
||||
}
|
||||
|
||||
aes->msg.msg_iov = iov;
|
||||
aes->msg.msg_iovlen = 2; /* # of iov structures */
|
||||
|
||||
ret = (int)sendmsg(aes->rdFd, &(aes->msg), 0);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* set buffers to hold result and left over stream */
|
||||
iov[0].iov_base = (byte*)out;
|
||||
iov[0].iov_len = sz - aes->left;
|
||||
|
||||
iov[1].iov_base = tmp;
|
||||
if (aes->left > 0) {
|
||||
iov[1].iov_len = AES_BLOCK_SIZE;
|
||||
}
|
||||
else {
|
||||
iov[1].iov_len = 0;
|
||||
}
|
||||
|
||||
ret = (int)readv(aes->rdFd, iov, 2);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (aes->left > 0) {
|
||||
XMEMCPY(out + sz - aes->left, tmp, aes->left);
|
||||
aes->left = AES_BLOCK_SIZE - aes->left;
|
||||
}
|
||||
}
|
||||
|
||||
/* adjust counter after call to hardware */
|
||||
while (sz >= AES_BLOCK_SIZE) {
|
||||
IncrementAesCounter((byte*)aes->reg);
|
||||
sz -= AES_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
if (aes->left > 0) {
|
||||
IncrementAesCounter((byte*)aes->reg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* WOLFSSL_AES_COUNTER */
|
||||
|
||||
|
||||
#ifdef HAVE_AESGCM
|
||||
|
||||
static const char WC_TYPE_AEAD[] = "aead";
|
||||
static const char WC_NAME_AESGCM[] = "gcm(aes)";
|
||||
|
||||
#ifndef WC_SYSTEM_AESGCM_IV
|
||||
/* size of IV allowed on system for AES-GCM */
|
||||
#define WC_SYSTEM_AESGCM_IV 12
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_MAX_AUTH_TAG_SZ
|
||||
/* size of tag is restricted by system for AES-GCM
|
||||
* check 'cat /proc/crypto' to see restricted size */
|
||||
#define WOLFSSL_MAX_AUTH_TAG_SZ 16
|
||||
#endif
|
||||
|
||||
int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
|
||||
{
|
||||
#if defined(AES_MAX_KEY_SIZE)
|
||||
const word32 max_key_len = (AES_MAX_KEY_SIZE / 8);
|
||||
#endif
|
||||
|
||||
if (aes == NULL ||
|
||||
!((len == 16) || (len == 24) || (len == 32))) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#if defined(AES_MAX_KEY_SIZE)
|
||||
/* Check key length */
|
||||
if (len > max_key_len) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
#endif
|
||||
aes->keylen = len;
|
||||
aes->rounds = len/4 + 6;
|
||||
|
||||
aes->rdFd = WC_SOCK_NOTSET;
|
||||
aes->alFd = wc_Afalg_Socket();
|
||||
if (aes->alFd < 0) {
|
||||
WOLFSSL_MSG("Unable to open an AF_ALG socket");
|
||||
return WC_AFALG_SOCK_E;
|
||||
}
|
||||
|
||||
/* save key until direction is known i.e. encrypt or decrypt */
|
||||
XMEMCPY((byte*)(aes->key), key, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
struct cmsghdr* cmsg;
|
||||
struct iovec iov[3];
|
||||
int ret;
|
||||
struct msghdr* msg;
|
||||
byte scratch[16];
|
||||
|
||||
/* argument checks */
|
||||
if (aes == NULL || authTagSz > AES_BLOCK_SIZE) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (ivSz != WC_SYSTEM_AESGCM_IV || authTagSz > WOLFSSL_MAX_AUTH_TAG_SZ) {
|
||||
WOLFSSL_MSG("IV/AAD size not supported on system");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
|
||||
WOLFSSL_MSG("GcmEncrypt authTagSz too small error");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (aes->rdFd == WC_SOCK_NOTSET) {
|
||||
aes->dir = AES_ENCRYPTION;
|
||||
if ((ret = wc_AesSetup(aes, WC_TYPE_AEAD, WC_NAME_AESGCM, ivSz,
|
||||
authInSz)) != 0) {
|
||||
WOLFSSL_MSG("Error with first time setup of AF_ALG socket");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* note that if the ivSz was to change, the msg_controllen would need
|
||||
reset */
|
||||
|
||||
/* set auth tag
|
||||
* @TODO case where tag size changes between calls? */
|
||||
ret = setsockopt(aes->alFd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL,
|
||||
authTagSz);
|
||||
if (ret != 0) {
|
||||
perror("set tag");
|
||||
WOLFSSL_MSG("Unable to set AF_ALG tag size ");
|
||||
return WC_AFALG_SOCK_E;
|
||||
}
|
||||
}
|
||||
|
||||
msg = &(aes->msg);
|
||||
cmsg = CMSG_FIRSTHDR(msg);
|
||||
cmsg = CMSG_NXTHDR(msg, cmsg);
|
||||
|
||||
/* set IV and AAD size */
|
||||
ret = wc_Afalg_SetIv(cmsg, (byte*)iv, ivSz);
|
||||
if (ret < 0) {
|
||||
WOLFSSL_MSG("Error setting IV");
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
if (authInSz > 0) {
|
||||
cmsg = CMSG_NXTHDR(msg, cmsg);
|
||||
ret = wc_Afalg_SetAad(cmsg, authInSz);
|
||||
if (ret < 0) {
|
||||
WOLFSSL_MSG("Unable to set AAD size");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* set data to be encrypted*/
|
||||
iov[0].iov_base = (byte*)authIn;
|
||||
iov[0].iov_len = authInSz;
|
||||
|
||||
iov[1].iov_base = (byte*)in;
|
||||
iov[1].iov_len = sz;
|
||||
|
||||
aes->msg.msg_iov = iov;
|
||||
aes->msg.msg_iovlen = 2; /* # of iov structures */
|
||||
|
||||
ret = (int)sendmsg(aes->rdFd, &(aes->msg), 0);
|
||||
if (ret < 0) {
|
||||
perror("sendmsg error");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* first 16 bytes was all 0's */
|
||||
iov[0].iov_base = scratch;
|
||||
iov[0].iov_len = authInSz;
|
||||
|
||||
iov[1].iov_base = out;
|
||||
iov[1].iov_len = sz;
|
||||
|
||||
iov[2].iov_base = authTag;
|
||||
iov[2].iov_len = authTagSz;
|
||||
|
||||
ret = (int)readv(aes->rdFd, iov, 3);
|
||||
if (ret < 0) {
|
||||
perror("read error");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
|
||||
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)
|
||||
{
|
||||
struct cmsghdr* cmsg;
|
||||
struct iovec iov[3];
|
||||
int ret;
|
||||
struct msghdr* msg;
|
||||
byte scratch[16];
|
||||
|
||||
/* argument checks */
|
||||
if (aes == NULL || authTagSz > AES_BLOCK_SIZE) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (ivSz != WC_SYSTEM_AESGCM_IV || authTagSz > WOLFSSL_MAX_AUTH_TAG_SZ) {
|
||||
WOLFSSL_MSG("IV/AAD size not supported on system");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
|
||||
WOLFSSL_MSG("GcmEncrypt authTagSz too small error");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (aes->rdFd == WC_SOCK_NOTSET) {
|
||||
aes->dir = AES_DECRYPTION;
|
||||
if ((ret = wc_AesSetup(aes, WC_TYPE_AEAD, WC_NAME_AESGCM, ivSz,
|
||||
authInSz)) != 0) {
|
||||
WOLFSSL_MSG("Error with first time setup of AF_ALG socket");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* set auth tag
|
||||
* @TODO case where tag size changes between calls? */
|
||||
ret = setsockopt(aes->alFd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL,
|
||||
authTagSz);
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("Unable to set AF_ALG tag size ");
|
||||
return WC_AFALG_SOCK_E;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* set IV and AAD size */
|
||||
msg = &(aes->msg);
|
||||
cmsg = CMSG_FIRSTHDR(msg);
|
||||
cmsg = CMSG_NXTHDR(msg, cmsg);
|
||||
ret = wc_Afalg_SetIv(cmsg, (byte*)iv, ivSz);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (authInSz > 0) {
|
||||
cmsg = CMSG_NXTHDR(msg, cmsg);
|
||||
ret = wc_Afalg_SetAad(cmsg, authInSz);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* set data to be decrypted*/
|
||||
iov[0].iov_base = (byte*)authIn;
|
||||
iov[0].iov_len = authInSz;
|
||||
|
||||
iov[1].iov_base = (byte*)in;
|
||||
iov[1].iov_len = sz;
|
||||
|
||||
iov[2].iov_base = (byte*)authTag;
|
||||
iov[2].iov_len = authTagSz;
|
||||
|
||||
aes->msg.msg_iov = iov;
|
||||
aes->msg.msg_iovlen = 3; /* # of iov structures */
|
||||
|
||||
ret = (int)sendmsg(aes->rdFd, &(aes->msg), 0);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
iov[0].iov_base = scratch;
|
||||
iov[0].iov_len = authInSz;
|
||||
|
||||
iov[1].iov_base = out;
|
||||
iov[1].iov_len = sz;
|
||||
|
||||
ret = (int)readv(aes->rdFd, iov, 2);
|
||||
if (ret < 0) {
|
||||
return AES_GCM_AUTH_E;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#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_Afalg_AesDirect(aes, out, in, sz);
|
||||
}
|
||||
|
||||
|
||||
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
||||
{
|
||||
return wc_Afalg_AesDirect(aes, out, in, sz);
|
||||
}
|
||||
#endif /* HAVE_AES_ECB */
|
||||
#endif /* !NO_AES && WOLFSSL_AFALG */
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
/* afalg_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_AFALG_HASH)
|
||||
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
#include <wolfssl/wolfcrypt/logging.h>
|
||||
#include <wolfssl/wolfcrypt/port/af_alg/wc_afalg.h>
|
||||
|
||||
static const char WC_TYPE_HASH[] = "hash";
|
||||
|
||||
#if !defined(NO_SHA256)
|
||||
#include <wolfssl/wolfcrypt/sha256.h>
|
||||
|
||||
static const char WC_NAME_SHA256[] = "sha256";
|
||||
|
||||
|
||||
/* create AF_ALG sockets for SHA256 operation */
|
||||
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;
|
||||
|
||||
sha->len = 0;
|
||||
sha->used = 0;
|
||||
sha->msg = NULL;
|
||||
sha->alFd = -1;
|
||||
sha->rdFd = -1;
|
||||
|
||||
sha->alFd = wc_Afalg_Socket();
|
||||
if (sha->alFd < 0) {
|
||||
return WC_AFALG_SOCK_E;
|
||||
}
|
||||
|
||||
sha->rdFd = wc_Afalg_CreateRead(sha->alFd, WC_TYPE_HASH, WC_NAME_SHA256);
|
||||
if (sha->rdFd < 0) {
|
||||
return WC_AFALG_SOCK_E;
|
||||
}
|
||||
|
||||
return 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_AFALG_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;
|
||||
#else
|
||||
int ret;
|
||||
|
||||
if ((ret = (int)send(sha->rdFd, in, sz, MSG_MORE)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int wc_Sha256Final(wc_Sha256* sha, byte* hash)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (sha == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_AFALG_HASH_KEEP
|
||||
/* keep full message to hash at end instead of incremental updates */
|
||||
if ((ret = (int)send(sha->rdFd, sha->msg, sha->used, 0)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
XFREE(sha->msg, sha->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
sha->msg = NULL;
|
||||
#else
|
||||
if ((ret = (int)send(sha->rdFd, NULL, 0, 0)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((ret = (int)read(sha->rdFd, hash, WC_SHA256_DIGEST_SIZE)) !=
|
||||
WC_SHA256_DIGEST_SIZE) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
wc_Sha256Free(sha);
|
||||
return wc_InitSha256_ex(sha, sha->heap, 0);
|
||||
}
|
||||
|
||||
|
||||
int wc_Sha256GetHash(wc_Sha256* sha, byte* hash)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (sha == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
(void)ret;
|
||||
#ifdef WOLFSSL_AFALG_HASH_KEEP
|
||||
if ((ret = (int)send(sha->rdFd, sha->msg, sha->used, 0)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = (int)read(sha->rdFd, hash, WC_SHA256_DIGEST_SIZE)) !=
|
||||
WC_SHA256_DIGEST_SIZE) {
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
(void)sha;
|
||||
(void)hash;
|
||||
|
||||
WOLFSSL_MSG("Compile with WOLFSSL_AFALG_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;
|
||||
}
|
||||
|
||||
XMEMCPY(dst, src, sizeof(wc_Sha256));
|
||||
dst->rdFd = accept(src->rdFd, NULL, 0);
|
||||
dst->alFd = accept(src->alFd, NULL, 0);
|
||||
|
||||
if (dst->rdFd == -1 || dst->alFd == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* !NO_SHA256 */
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* WOLFSSL_AFALG */
|
|
@ -0,0 +1,141 @@
|
|||
/* wc_afalg.c
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
#include <wolfssl/wolfcrypt/logging.h>
|
||||
|
||||
#if !defined(NO_AES) && defined(WOLFSSL_AFALG)
|
||||
|
||||
#include <wolfssl/wolfcrypt/port/af_alg/wc_afalg.h>
|
||||
#include <linux/if_alg.h>
|
||||
|
||||
|
||||
/* Sets the type of socket address to use */
|
||||
void wc_Afalg_SockAddr(struct sockaddr_alg* in, const char* type, const char* name)
|
||||
{
|
||||
in->salg_family = AF_ALG;
|
||||
XSTRNCPY((char*)in->salg_type, type, XSTRLEN(type));
|
||||
in->salg_type[XSTRLEN(type)] = '\0';
|
||||
XSTRNCPY((char*)in->salg_name, name, XSTRLEN(name));
|
||||
in->salg_name[XSTRLEN(name)] = '\0';
|
||||
}
|
||||
|
||||
|
||||
/* returns the socket accepting on with success
|
||||
* negative values are returned in fail cases */
|
||||
int wc_Afalg_Accept(struct sockaddr_alg* in, int inSz, int sock)
|
||||
{
|
||||
if (bind(sock, (const struct sockaddr*)in, inSz) < 0) {
|
||||
WOLFSSL_MSG("Failed to bind with AF_ALG");
|
||||
return WC_AFALG_SOCK_E;
|
||||
}
|
||||
|
||||
return accept(sock, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
/* creates a new AF_ALG socket and returns it
|
||||
* negative values are returned in fail cases */
|
||||
int wc_Afalg_Socket(void)
|
||||
{
|
||||
int sock;
|
||||
|
||||
if ((sock = socket(AF_ALG, SOCK_SEQPACKET, 0)) < 0) {
|
||||
WOLFSSL_MSG("Failed to get AF_ALG socket");
|
||||
return WC_AFALG_SOCK_E;
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
|
||||
/* binds and creates the read fd */
|
||||
int wc_Afalg_CreateRead(int sock, const char* type, const char* name)
|
||||
{
|
||||
struct sockaddr_alg sa = {};
|
||||
wc_Afalg_SockAddr(&sa, type, name);
|
||||
return wc_Afalg_Accept(&sa, sizeof(sa), sock);
|
||||
}
|
||||
|
||||
|
||||
/* sets the IV in CMSG structure, returns 0 on success */
|
||||
int wc_Afalg_SetIv(struct cmsghdr* cmsg, byte* iv, word32 ivSz)
|
||||
{
|
||||
struct af_alg_iv* afIv;
|
||||
|
||||
if (cmsg == NULL || iv == NULL) {
|
||||
WOLFSSL_MSG("Null cmsg or iv passed in");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
cmsg->cmsg_level = SOL_ALG;
|
||||
cmsg->cmsg_type = ALG_SET_IV;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct af_alg_iv) + ivSz);
|
||||
afIv = (void*)CMSG_DATA(cmsg);
|
||||
afIv->ivlen = ivSz;
|
||||
XMEMCPY(afIv->iv, iv, ivSz);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* sets the AAD size in CMSG structure, returns 0 on success */
|
||||
int wc_Afalg_SetAad(struct cmsghdr* cmsg, word32 sz)
|
||||
{
|
||||
if (cmsg == NULL) {
|
||||
WOLFSSL_MSG("Null cmsg passed in");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
cmsg->cmsg_level = SOL_ALG;
|
||||
cmsg->cmsg_type = ALG_SET_AEAD_ASSOCLEN;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(word32));
|
||||
*((word32*)CMSG_DATA(cmsg)) = sz;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* sets the operation type in CMSG structure, returns 0 on success
|
||||
*
|
||||
* dir 0 is encryption 1 is decryption
|
||||
*/
|
||||
int wc_Afalg_SetOp(struct cmsghdr* cmsg, int dir)
|
||||
{
|
||||
if (cmsg == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
cmsg->cmsg_level = SOL_ALG;
|
||||
cmsg->cmsg_type = ALG_SET_OP;
|
||||
cmsg->cmsg_len = CMSG_LEN(4);
|
||||
*((word32*)CMSG_DATA(cmsg)) = (dir == 1)? ALG_OP_DECRYPT : ALG_OP_ENCRYPT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* !NO_AES && WOLFSSL_AFALG */
|
||||
|
|
@ -135,7 +135,8 @@
|
|||
|
||||
|
||||
#if !defined(WOLFSSL_PIC32MZ_HASH) && !defined(STM32_HASH_SHA2) && \
|
||||
(!defined(WOLFSSL_IMX6_CAAM) || defined(NO_IMX6_CAAM_HASH))
|
||||
(!defined(WOLFSSL_IMX6_CAAM) || defined(NO_IMX6_CAAM_HASH)) && \
|
||||
!defined(WOLFSSL_AFALG_HASH)
|
||||
static int InitSha256(wc_Sha256* sha256)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -439,6 +440,10 @@ static int InitSha256(wc_Sha256* sha256)
|
|||
|
||||
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH)
|
||||
/* functions defined in wolfcrypt/src/port/caam/caam_sha256.c */
|
||||
|
||||
#elif defined(WOLFSSL_AFALG_HASH)
|
||||
/* implemented in wolfcrypt/src/port/af_alg/afalg_hash.c */
|
||||
|
||||
#else
|
||||
#define NEED_SOFT_SHA256
|
||||
|
||||
|
@ -2572,6 +2577,10 @@ SHA256_NOINLINE static int Transform_Sha256_AVX2_RORX_Len(wc_Sha256* sha256,
|
|||
|
||||
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH)
|
||||
/* functions defined in wolfcrypt/src/port/caam/caam_sha256.c */
|
||||
|
||||
//#elif defined(WOLFSSL_AFALG_HASH)
|
||||
// /* implemented in wolfcrypt/src/port/af_alg/afalg_hash.c */
|
||||
|
||||
#else
|
||||
|
||||
#define NEED_SOFT_SHA224
|
||||
|
@ -2735,10 +2744,24 @@ void wc_Sha256Free(wc_Sha256* sha256)
|
|||
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
|
||||
wolfAsync_DevCtxFree(&sha256->asyncDev, WOLFSSL_ASYNC_MARKER_SHA256);
|
||||
#endif /* WOLFSSL_ASYNC_CRYPT */
|
||||
|
||||
#ifdef WOLFSSL_PIC32MZ_HASH
|
||||
wc_Sha256Pic32Free(sha256);
|
||||
#endif
|
||||
#if defined(WOLFSSL_AFALG_HASH)
|
||||
if (sha256->alFd > 0) {
|
||||
close(sha256->alFd);
|
||||
}
|
||||
if (sha256->rdFd > 0) {
|
||||
close(sha256->rdFd);
|
||||
}
|
||||
|
||||
#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 */
|
||||
}
|
||||
|
||||
#endif /* !WOLFSSL_TI_HASH */
|
||||
|
@ -2782,6 +2805,10 @@ void wc_Sha256Free(wc_Sha256* sha256)
|
|||
}
|
||||
#endif /* WOLFSSL_SHA224 */
|
||||
|
||||
#ifdef WOLFSSL_AFALG_HASH
|
||||
/* implemented in wolfcrypt/src/port/af_alg/afalg_hash.c */
|
||||
#else
|
||||
|
||||
int wc_Sha256GetHash(wc_Sha256* sha256, byte* hash)
|
||||
{
|
||||
int ret;
|
||||
|
@ -2818,6 +2845,7 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst)
|
|||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#endif /* !WOLFSSL_TI_HASH */
|
||||
|
||||
#endif /* NO_SHA256 */
|
||||
|
|
|
@ -164,6 +164,10 @@ int wolfCrypt_Init(void)
|
|||
WOLFSSL_MSG("Using ARM hardware acceleration");
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_AFALG
|
||||
WOLFSSL_MSG("Using AF_ALG for crypto acceleration");
|
||||
#endif
|
||||
|
||||
#if !defined(WOLFCRYPT_ONLY) && \
|
||||
( defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) )
|
||||
wolfSSL_EVP_init();
|
||||
|
|
|
@ -270,6 +270,7 @@ int aes256_test(void);
|
|||
int cmac_test(void);
|
||||
int poly1305_test(void);
|
||||
int aesgcm_test(void);
|
||||
int aesgcm_default_test(void);
|
||||
int gmac_test(void);
|
||||
int aesccm_test(void);
|
||||
int aeskeywrap_test(void);
|
||||
|
@ -751,10 +752,19 @@ initDefaultName();
|
|||
printf( "AES256 test passed!\n");
|
||||
#endif
|
||||
#ifdef HAVE_AESGCM
|
||||
#ifndef WOLFSSL_AFALG
|
||||
if ( (ret = aesgcm_test()) != 0)
|
||||
return err_sys("AES-GCM test failed!\n", ret);
|
||||
else
|
||||
printf( "AES-GCM test passed!\n");
|
||||
#endif
|
||||
{
|
||||
if ((ret = aesgcm_default_test()) != 0) {
|
||||
return err_sys("AES-GCM test failed!\n", ret);
|
||||
}
|
||||
else {
|
||||
printf( "AES-GCM test passed!\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_AESCCM) && defined(WOLFSSL_AES_128)
|
||||
|
@ -2045,8 +2055,9 @@ int sha256_test(void)
|
|||
for (i = 0; i < times; ++i) {
|
||||
ret = wc_Sha256Update(&sha, (byte*)test_sha[i].input,
|
||||
(word32)test_sha[i].inLen);
|
||||
if (ret != 0)
|
||||
if (ret != 0) {
|
||||
ERROR_OUT(-2202 - i, exit);
|
||||
}
|
||||
ret = wc_Sha256GetHash(&sha, hashcopy);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(-2203 - i, exit);
|
||||
|
@ -6542,6 +6553,173 @@ int aes256_test(void)
|
|||
|
||||
|
||||
#ifdef HAVE_AESGCM
|
||||
|
||||
static int aesgcm_default_test_helper(byte* key, int keySz, byte* iv, int ivSz,
|
||||
byte* plain, int plainSz, byte* cipher, int cipherSz,
|
||||
byte* aad, int aadSz, byte* tag, int tagSz)
|
||||
{
|
||||
Aes enc;
|
||||
Aes dec;
|
||||
|
||||
byte resultT[AES_BLOCK_SIZE];
|
||||
byte resultP[AES_BLOCK_SIZE * 3];
|
||||
byte resultC[AES_BLOCK_SIZE * 3];
|
||||
int result;
|
||||
|
||||
XMEMSET(resultT, 0, sizeof(resultT));
|
||||
XMEMSET(resultC, 0, sizeof(resultC));
|
||||
XMEMSET(resultP, 0, sizeof(resultP));
|
||||
|
||||
if (wc_AesInit(&enc, HEAP_HINT, devId) != 0) {
|
||||
return -5700;
|
||||
}
|
||||
|
||||
result = wc_AesGcmSetKey(&enc, key, keySz);
|
||||
if (result != 0)
|
||||
return -4701;
|
||||
|
||||
/* AES-GCM encrypt and decrypt both use AES encrypt internally */
|
||||
result = wc_AesGcmEncrypt(&enc, resultC, plain, plainSz, iv, ivSz,
|
||||
resultT, tagSz, aad, aadSz);
|
||||
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
result = wc_AsyncWait(result, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (result != 0)
|
||||
return -4702;
|
||||
if (XMEMCMP(cipher, resultC, cipherSz))
|
||||
return -4703;
|
||||
if (XMEMCMP(tag, resultT, tagSz))
|
||||
return -4704;
|
||||
|
||||
wc_AesFree(&enc);
|
||||
|
||||
#ifdef HAVE_AES_DECRYPT
|
||||
result = wc_AesGcmSetKey(&dec, key, keySz);
|
||||
if (result != 0)
|
||||
return -4705;
|
||||
|
||||
result = wc_AesGcmDecrypt(&dec, resultP, resultC, cipherSz,
|
||||
iv, ivSz, resultT, tagSz, aad, aadSz);
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
result = wc_AsyncWait(result, &dec.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (result != 0)
|
||||
return -4706;
|
||||
if (XMEMCMP(plain, resultP, plainSz))
|
||||
return -4707;
|
||||
|
||||
wc_AesFree(&dec);
|
||||
#endif /* HAVE_AES_DECRYPT */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* tests that only use 12 byte IV and 16 or less byte AAD
|
||||
* test vectors are from NIST SP 800-38D
|
||||
* https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES*/
|
||||
int aesgcm_default_test(void)
|
||||
{
|
||||
byte key1[] = {
|
||||
0x29, 0x8e, 0xfa, 0x1c, 0xcf, 0x29, 0xcf, 0x62,
|
||||
0xae, 0x68, 0x24, 0xbf, 0xc1, 0x95, 0x57, 0xfc
|
||||
};
|
||||
|
||||
byte iv1[] = {
|
||||
0x6f, 0x58, 0xa9, 0x3f, 0xe1, 0xd2, 0x07, 0xfa,
|
||||
0xe4, 0xed, 0x2f, 0x6d
|
||||
};
|
||||
|
||||
byte plain1[] = {
|
||||
0xcc, 0x38, 0xbc, 0xcd, 0x6b, 0xc5, 0x36, 0xad,
|
||||
0x91, 0x9b, 0x13, 0x95, 0xf5, 0xd6, 0x38, 0x01,
|
||||
0xf9, 0x9f, 0x80, 0x68, 0xd6, 0x5c, 0xa5, 0xac,
|
||||
0x63, 0x87, 0x2d, 0xaf, 0x16, 0xb9, 0x39, 0x01
|
||||
};
|
||||
|
||||
byte aad1[] = {
|
||||
0x02, 0x1f, 0xaf, 0xd2, 0x38, 0x46, 0x39, 0x73,
|
||||
0xff, 0xe8, 0x02, 0x56, 0xe5, 0xb1, 0xc6, 0xb1
|
||||
};
|
||||
|
||||
byte cipher1[] = {
|
||||
0xdf, 0xce, 0x4e, 0x9c, 0xd2, 0x91, 0x10, 0x3d,
|
||||
0x7f, 0xe4, 0xe6, 0x33, 0x51, 0xd9, 0xe7, 0x9d,
|
||||
0x3d, 0xfd, 0x39, 0x1e, 0x32, 0x67, 0x10, 0x46,
|
||||
0x58, 0x21, 0x2d, 0xa9, 0x65, 0x21, 0xb7, 0xdb
|
||||
};
|
||||
|
||||
byte tag1[] = {
|
||||
0x54, 0x24, 0x65, 0xef, 0x59, 0x93, 0x16, 0xf7,
|
||||
0x3a, 0x7a, 0x56, 0x05, 0x09, 0xa2, 0xd9, 0xf2
|
||||
};
|
||||
|
||||
|
||||
byte key2[] = {
|
||||
0x01, 0x6d, 0xbb, 0x38, 0xda, 0xa7, 0x6d, 0xfe,
|
||||
0x7d, 0xa3, 0x84, 0xeb, 0xf1, 0x24, 0x03, 0x64
|
||||
};
|
||||
|
||||
byte iv2[] = {
|
||||
0x07, 0x93, 0xef, 0x3a, 0xda, 0x78, 0x2f, 0x78,
|
||||
0xc9, 0x8a, 0xff, 0xe3
|
||||
};
|
||||
|
||||
byte plain2[] = {
|
||||
0x4b, 0x34, 0xa9, 0xec, 0x57, 0x63, 0x52, 0x4b,
|
||||
0x19, 0x1d, 0x56, 0x16, 0xc5, 0x47, 0xf6, 0xb7
|
||||
};
|
||||
|
||||
byte cipher2[] = {
|
||||
0x60, 0x9a, 0xa3, 0xf4, 0x54, 0x1b, 0xc0, 0xfe,
|
||||
0x99, 0x31, 0xda, 0xad, 0x2e, 0xe1, 0x5d, 0x0c
|
||||
};
|
||||
|
||||
byte tag2[] = {
|
||||
0x33, 0xaf, 0xec, 0x59, 0xc4, 0x5b, 0xaf, 0x68,
|
||||
0x9a, 0x5e, 0x1b, 0x13, 0xae, 0x42, 0x36, 0x19
|
||||
};
|
||||
|
||||
byte key3[] = {
|
||||
0xb0, 0x1e, 0x45, 0xcc, 0x30, 0x88, 0xaa, 0xba,
|
||||
0x9f, 0xa4, 0x3d, 0x81, 0xd4, 0x81, 0x82, 0x3f
|
||||
};
|
||||
|
||||
byte iv3[] = {
|
||||
0x5a, 0x2c, 0x4a, 0x66, 0x46, 0x87, 0x13, 0x45,
|
||||
0x6a, 0x4b, 0xd5, 0xe1
|
||||
};
|
||||
|
||||
byte tag3[] = {
|
||||
0x01, 0x42, 0x80, 0xf9, 0x44, 0xf5, 0x3c, 0x68,
|
||||
0x11, 0x64, 0xb2, 0xff
|
||||
};
|
||||
|
||||
int ret;
|
||||
ret = aesgcm_default_test_helper(key1, sizeof(key1), iv1, sizeof(iv1),
|
||||
plain1, sizeof(plain1), cipher1, sizeof(cipher1),
|
||||
aad1, sizeof(aad1), tag1, sizeof(tag1));
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = aesgcm_default_test_helper(key2, sizeof(key2), iv2, sizeof(iv2),
|
||||
plain2, sizeof(plain2), cipher2, sizeof(cipher2),
|
||||
NULL, 0, tag2, sizeof(tag2));
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = aesgcm_default_test_helper(key3, sizeof(key3), iv3, sizeof(iv3),
|
||||
NULL, 0, NULL, 0,
|
||||
NULL, 0, tag3, sizeof(tag3));
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aesgcm_test(void)
|
||||
{
|
||||
Aes enc;
|
||||
|
|
|
@ -68,6 +68,11 @@
|
|||
#include "xsecure_aes.h"
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_AFALG
|
||||
/* included for struct msghdr */
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_AESGCM) && !defined(WC_NO_RNG)
|
||||
#include <wolfssl/wolfcrypt/random.h>
|
||||
#endif
|
||||
|
@ -150,6 +155,12 @@ typedef struct Aes {
|
|||
XCsuDma dma;
|
||||
word32 key_init[8];
|
||||
word32 kup;
|
||||
#endif
|
||||
#ifdef WOLFSSL_AFALG
|
||||
int alFd; /* server socket to bind to */
|
||||
int rdFd; /* socket to read from */
|
||||
struct msghdr msg;
|
||||
int dir; /* flag for encrpyt or decrypt */
|
||||
#endif
|
||||
void* heap; /* memory hint to use */
|
||||
} Aes;
|
||||
|
|
|
@ -213,7 +213,9 @@ enum {
|
|||
RSA_KEY_PAIR_E = -262, /* RSA Key Pair-Wise Consistency check fail. */
|
||||
DH_CHECK_PRIV_E = -263, /* DH Check Priv Key error */
|
||||
|
||||
WC_LAST_E = -263, /* Update this to indicate last error */
|
||||
WC_AFALG_SOCK_E = -264, /* AF_ALG socket error */
|
||||
|
||||
WC_LAST_E = -264, /* Update this to indicate last error */
|
||||
MIN_CODE_E = -300 /* errors -101 - -299 */
|
||||
|
||||
/* add new companion error id strings for any new error codes
|
||||
|
|
|
@ -77,7 +77,9 @@ noinst_HEADERS+= \
|
|||
wolfssl/wolfcrypt/port/caam/wolfcaam.h \
|
||||
wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h \
|
||||
wolfssl/wolfcrypt/port/st/stm32.h \
|
||||
wolfssl/wolfcrypt/port/st/stsafe.h
|
||||
wolfssl/wolfcrypt/port/st/stsafe.h \
|
||||
wolfssl/wolfcrypt/port/af_alg/afalg_hash.h \
|
||||
wolfssl/wolfcrypt/port/af_alg/wc_afalg.h
|
||||
|
||||
if BUILD_ASYNCCRYPT
|
||||
nobase_include_HEADERS+= wolfssl/wolfcrypt/async.h
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/* afalg_hash.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 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 WOLF_CRYPT_AFALG_HASH_H
|
||||
#define WOLF_CRYPT_AFALG_HASH_H
|
||||
|
||||
#include <wolfssl/wolfcrypt/types.h>
|
||||
|
||||
#undef WOLFSSL_NO_HASH_RAW
|
||||
#define WOLFSSL_NO_HASH_RAW
|
||||
|
||||
typedef struct {
|
||||
byte* msg;
|
||||
void* heap;
|
||||
word32 used;
|
||||
word32 len;
|
||||
int alFd;
|
||||
int rdFd;
|
||||
} wolfssl_AFALG_Hash;
|
||||
|
||||
|
||||
|
||||
#if !defined(NO_SHA256)
|
||||
typedef wolfssl_AFALG_Hash wc_Sha256;
|
||||
#endif
|
||||
|
||||
#endif /* WOLF_CRYPT_AFALG_HASH_H */
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/* wc_afalg.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_AFALG_H
|
||||
#define WOLFSSL_AFALG_H
|
||||
|
||||
#include <wolfssl/wolfcrypt/types.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <linux/if_alg.h>
|
||||
#include <linux/socket.h>
|
||||
|
||||
#define WC_SOCK_NOTSET -1
|
||||
|
||||
|
||||
WOLFSSL_LOCAL void wc_Afalg_SockAddr(struct sockaddr_alg* in, const char* type, const char* name);
|
||||
WOLFSSL_LOCAL int wc_Afalg_Accept(struct sockaddr_alg* in, int inSz, int sock);
|
||||
WOLFSSL_LOCAL int wc_Afalg_Socket(void);
|
||||
WOLFSSL_LOCAL int wc_Afalg_CreateRead(int sock, const char* type, const char* name);
|
||||
WOLFSSL_LOCAL int wc_Afalg_SetIv(struct cmsghdr* cmsg, byte* iv, word32 ivSz);
|
||||
WOLFSSL_LOCAL int wc_Afalg_SetOp(struct cmsghdr* cmsg, int dir);
|
||||
WOLFSSL_LOCAL int wc_Afalg_SetAad(struct cmsghdr* cmsg, word32 sz);
|
||||
|
||||
#endif /* WOLFSSL_AFALG_H */
|
||||
|
|
@ -113,6 +113,8 @@ enum {
|
|||
#include "wolfssl/wolfcrypt/port/ti/ti-hash.h"
|
||||
#elif defined(WOLFSSL_IMX6_CAAM)
|
||||
#include "wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h"
|
||||
#elif defined(WOLFSSL_AFALG_HASH)
|
||||
#include "wolfssl/wolfcrypt/port/af_alg/afalg_hash.h"
|
||||
#else
|
||||
/* wc_Sha256 digest */
|
||||
typedef struct wc_Sha256 {
|
||||
|
|
Loading…
Reference in New Issue