mirror of https://github.com/wolfSSL/wolfssl
Merge pull request #648 from cconlon/keywrap
add AES key wrap support, RFC 3394
This commit is contained in:
commit
ad2b0810c6
14
configure.ac
14
configure.ac
|
@ -2876,6 +2876,19 @@ then
|
|||
fi
|
||||
|
||||
|
||||
# AES key wrap
|
||||
AC_ARG_ENABLE([aeskeywrap],
|
||||
[AS_HELP_STRING([--enable-aeskeywrap],[Enable AES key wrap support (default: disabled)])],
|
||||
[ ENABLED_AESKEYWRAP=$enableval ],
|
||||
[ ENABLED_AESKEYWRAP=no ]
|
||||
)
|
||||
|
||||
if test "$ENABLED_AESKEYWRAP" = "yes"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DHAVE_AES_KEYWRAP -DWOLFSSL_AES_DIRECT"
|
||||
fi
|
||||
|
||||
|
||||
# check if PSK was enabled for conditionally running psk.test script
|
||||
AM_CONDITIONAL([BUILD_PSK], [test "x$ENABLED_PSK" = "xyes"])
|
||||
|
||||
|
@ -3324,6 +3337,7 @@ echo " * Fast RSA: $ENABLED_FAST_RSA"
|
|||
echo " * Async Crypto: $ENABLED_ASYNCCRYPT"
|
||||
echo " * Cavium: $ENABLED_CAVIUM"
|
||||
echo " * ARM ASM: $ENABLED_ARMASM"
|
||||
echo " * AES Key Wrap: $ENABLED_AESKEYWRAP"
|
||||
echo ""
|
||||
echo "---"
|
||||
|
||||
|
|
|
@ -4715,6 +4715,178 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
|
|||
#endif /* HAVE_AESCCM */
|
||||
|
||||
|
||||
#ifdef HAVE_AES_KEYWRAP
|
||||
|
||||
/* Initialize key wrap counter with value */
|
||||
static INLINE void InitKeyWrapCounter(byte* inOutCtr, word32 value)
|
||||
{
|
||||
int i;
|
||||
word32 bytes;
|
||||
|
||||
bytes = sizeof(word32);
|
||||
for (i = 0; i < (int)sizeof(word32); i++) {
|
||||
inOutCtr[i+sizeof(word32)] = (value >> ((bytes - 1) * 8)) & 0xFF;
|
||||
bytes--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Increment key wrap counter */
|
||||
static INLINE void IncrementKeyWrapCounter(byte* inOutCtr)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* in network byte order so start at end and work back */
|
||||
for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
|
||||
if (++inOutCtr[i]) /* we're done unless we overflow */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Decrement key wrap counter */
|
||||
static INLINE void DecrementKeyWrapCounter(byte* inOutCtr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
|
||||
if (--inOutCtr[i] != 0xFF) /* we're done unless we underflow */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* perform AES key wrap (RFC3394), return out sz on success, negative on err */
|
||||
int wc_AesKeyWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
|
||||
byte* out, word32 outSz, const byte* iv)
|
||||
{
|
||||
Aes aes;
|
||||
byte* r;
|
||||
word32 i;
|
||||
int ret, j;
|
||||
|
||||
byte t[KEYWRAP_BLOCK_SIZE];
|
||||
byte tmp[AES_BLOCK_SIZE];
|
||||
|
||||
/* n must be at least 2, output size is n + 8 bytes */
|
||||
if (key == NULL || in == NULL || inSz < 2 ||
|
||||
out == NULL || outSz < (inSz + KEYWRAP_BLOCK_SIZE))
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* input must be multiple of 64-bits */
|
||||
if (inSz % KEYWRAP_BLOCK_SIZE != 0)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* user IV is optional */
|
||||
if (iv == NULL) {
|
||||
XMEMSET(tmp, 0xA6, KEYWRAP_BLOCK_SIZE);
|
||||
} else {
|
||||
XMEMCPY(tmp, iv, KEYWRAP_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
r = out + 8;
|
||||
XMEMCPY(r, in, inSz);
|
||||
XMEMSET(t, 0, sizeof(t));
|
||||
|
||||
ret = wc_AesSetKey(&aes, key, keySz, NULL, AES_ENCRYPTION);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
for (j = 0; j <= 5; j++) {
|
||||
for (i = 1; i <= inSz / KEYWRAP_BLOCK_SIZE; i++) {
|
||||
|
||||
/* load R[i] */
|
||||
XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
|
||||
|
||||
wc_AesEncryptDirect(&aes, tmp, tmp);
|
||||
|
||||
/* calculate new A */
|
||||
IncrementKeyWrapCounter(t);
|
||||
xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
|
||||
|
||||
/* save R[i] */
|
||||
XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
|
||||
r += KEYWRAP_BLOCK_SIZE;
|
||||
}
|
||||
r = out + KEYWRAP_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
/* C[0] = A */
|
||||
XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE);
|
||||
|
||||
return inSz + KEYWRAP_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
|
||||
byte* out, word32 outSz, const byte* iv)
|
||||
{
|
||||
(void)iv;
|
||||
|
||||
Aes aes;
|
||||
byte* r;
|
||||
word32 i, n;
|
||||
int ret, j;
|
||||
|
||||
byte t[KEYWRAP_BLOCK_SIZE];
|
||||
byte tmp[AES_BLOCK_SIZE];
|
||||
|
||||
const byte* expIv;
|
||||
const byte defaultIV[] = {
|
||||
0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6
|
||||
};
|
||||
|
||||
if (key == NULL || in == NULL || inSz < 3 ||
|
||||
out == NULL || outSz < (inSz - KEYWRAP_BLOCK_SIZE))
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* input must be multiple of 64-bits */
|
||||
if (inSz % KEYWRAP_BLOCK_SIZE != 0)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* user IV optional */
|
||||
if (iv != NULL) {
|
||||
expIv = iv;
|
||||
} else {
|
||||
expIv = defaultIV;
|
||||
}
|
||||
|
||||
/* A = C[0], R[i] = C[i] */
|
||||
XMEMCPY(tmp, in, KEYWRAP_BLOCK_SIZE);
|
||||
XMEMCPY(out, in + KEYWRAP_BLOCK_SIZE, inSz - KEYWRAP_BLOCK_SIZE);
|
||||
XMEMSET(t, 0, sizeof(t));
|
||||
|
||||
ret = wc_AesSetKey(&aes, key, keySz, NULL, AES_DECRYPTION);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
/* initialize counter to 6n */
|
||||
n = (inSz - 1) / KEYWRAP_BLOCK_SIZE;
|
||||
InitKeyWrapCounter(t, 6 * n);
|
||||
|
||||
for (j = 5; j >= 0; j--) {
|
||||
for (i = n; i >= 1; i--) {
|
||||
|
||||
/* calculate A */
|
||||
xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
|
||||
DecrementKeyWrapCounter(t);
|
||||
|
||||
/* load R[i], starting at end of R */
|
||||
r = out + ((i - 1) * KEYWRAP_BLOCK_SIZE);
|
||||
XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
|
||||
wc_AesDecryptDirect(&aes, tmp, tmp);
|
||||
|
||||
/* save R[i] */
|
||||
XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
/* verify IV */
|
||||
if (XMEMCMP(tmp, expIv, KEYWRAP_BLOCK_SIZE) != 0)
|
||||
return BAD_KEYWRAP_IV_E;
|
||||
|
||||
return inSz - KEYWRAP_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
#endif /* HAVE_AES_KEYWRAP */
|
||||
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
|
||||
/* Initialize Aes for use with Nitrox device */
|
||||
|
|
|
@ -401,6 +401,9 @@ const char* wc_GetErrorString(int error)
|
|||
case ASN_PATHLEN_INV_E:
|
||||
return "ASN CA path length larger than signer error";
|
||||
|
||||
case BAD_KEYWRAP_IV_E:
|
||||
return "Decrypted AES key wrap IV does not match expected";
|
||||
|
||||
default:
|
||||
return "unknown error number";
|
||||
|
||||
|
|
|
@ -198,6 +198,7 @@ int poly1305_test(void);
|
|||
int aesgcm_test(void);
|
||||
int gmac_test(void);
|
||||
int aesccm_test(void);
|
||||
int aeskeywrap_test(void);
|
||||
int camellia_test(void);
|
||||
int rsa_test(void);
|
||||
int dh_test(void);
|
||||
|
@ -556,6 +557,12 @@ int wolfcrypt_test(void* args)
|
|||
else
|
||||
printf( "AES-CCM test passed!\n");
|
||||
#endif
|
||||
#ifdef HAVE_AES_KEYWRAP
|
||||
if ( (ret = aeskeywrap_test()) != 0)
|
||||
return err_sys("AES Key Wrap test failed!\n", ret);
|
||||
else
|
||||
printf( "AES Key Wrap test passed!\n");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CAMELLIA
|
||||
|
@ -3526,6 +3533,189 @@ int aesccm_test(void)
|
|||
#endif /* HAVE_AESCCM */
|
||||
|
||||
|
||||
#ifdef HAVE_AES_KEYWRAP
|
||||
|
||||
#define MAX_KEYWRAP_TEST_OUTLEN 40
|
||||
#define MAX_KEYWRAP_TEST_PLAINLEN 32
|
||||
|
||||
typedef struct keywrapVector {
|
||||
const byte* kek;
|
||||
const byte* data;
|
||||
const byte* verify;
|
||||
word32 kekLen;
|
||||
word32 dataLen;
|
||||
word32 verifyLen;
|
||||
} keywrapVector;
|
||||
|
||||
int aeskeywrap_test(void)
|
||||
{
|
||||
int wrapSz, plainSz, testSz, i;
|
||||
|
||||
/* test vectors from RFC 3394 (kek, data, verify) */
|
||||
|
||||
/* Wrap 128 bits of Key Data with a 128-bit KEK */
|
||||
const byte k1[] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
|
||||
};
|
||||
|
||||
const byte d1[] = {
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
|
||||
};
|
||||
|
||||
const byte v1[] = {
|
||||
0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47,
|
||||
0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82,
|
||||
0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5
|
||||
};
|
||||
|
||||
/* Wrap 128 bits of Key Data with a 192-bit KEK */
|
||||
const byte k2[] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17
|
||||
};
|
||||
|
||||
const byte d2[] = {
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
|
||||
};
|
||||
|
||||
const byte v2[] = {
|
||||
0x96, 0x77, 0x8B, 0x25, 0xAE, 0x6C, 0xA4, 0x35,
|
||||
0xF9, 0x2B, 0x5B, 0x97, 0xC0, 0x50, 0xAE, 0xD2,
|
||||
0x46, 0x8A, 0xB8, 0xA1, 0x7A, 0xD8, 0x4E, 0x5D
|
||||
};
|
||||
|
||||
/* Wrap 128 bits of Key Data with a 256-bit KEK */
|
||||
const byte k3[] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
|
||||
};
|
||||
|
||||
const byte d3[] = {
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
|
||||
};
|
||||
|
||||
const byte v3[] = {
|
||||
0x64, 0xE8, 0xC3, 0xF9, 0xCE, 0x0F, 0x5B, 0xA2,
|
||||
0x63, 0xE9, 0x77, 0x79, 0x05, 0x81, 0x8A, 0x2A,
|
||||
0x93, 0xC8, 0x19, 0x1E, 0x7D, 0x6E, 0x8A, 0xE7
|
||||
};
|
||||
|
||||
/* Wrap 192 bits of Key Data with a 192-bit KEK */
|
||||
const byte k4[] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17
|
||||
};
|
||||
|
||||
const byte d4[] = {
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
|
||||
};
|
||||
|
||||
const byte v4[] = {
|
||||
0x03, 0x1D, 0x33, 0x26, 0x4E, 0x15, 0xD3, 0x32,
|
||||
0x68, 0xF2, 0x4E, 0xC2, 0x60, 0x74, 0x3E, 0xDC,
|
||||
0xE1, 0xC6, 0xC7, 0xDD, 0xEE, 0x72, 0x5A, 0x93,
|
||||
0x6B, 0xA8, 0x14, 0x91, 0x5C, 0x67, 0x62, 0xD2
|
||||
};
|
||||
|
||||
/* Wrap 192 bits of Key Data with a 256-bit KEK */
|
||||
const byte k5[] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
|
||||
};
|
||||
|
||||
const byte d5[] = {
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
|
||||
};
|
||||
|
||||
const byte v5[] = {
|
||||
0xA8, 0xF9, 0xBC, 0x16, 0x12, 0xC6, 0x8B, 0x3F,
|
||||
0xF6, 0xE6, 0xF4, 0xFB, 0xE3, 0x0E, 0x71, 0xE4,
|
||||
0x76, 0x9C, 0x8B, 0x80, 0xA3, 0x2C, 0xB8, 0x95,
|
||||
0x8C, 0xD5, 0xD1, 0x7D, 0x6B, 0x25, 0x4D, 0xA1
|
||||
};
|
||||
|
||||
/* Wrap 256 bits of Key Data with a 256-bit KEK */
|
||||
const byte k6[] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
|
||||
};
|
||||
|
||||
const byte d6[] = {
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
|
||||
};
|
||||
|
||||
const byte v6[] = {
|
||||
0x28, 0xC9, 0xF4, 0x04, 0xC4, 0xB8, 0x10, 0xF4,
|
||||
0xCB, 0xCC, 0xB3, 0x5C, 0xFB, 0x87, 0xF8, 0x26,
|
||||
0x3F, 0x57, 0x86, 0xE2, 0xD8, 0x0E, 0xD3, 0x26,
|
||||
0xCB, 0xC7, 0xF0, 0xE7, 0x1A, 0x99, 0xF4, 0x3B,
|
||||
0xFB, 0x98, 0x8B, 0x9B, 0x7A, 0x02, 0xDD, 0x21
|
||||
};
|
||||
|
||||
byte output[MAX_KEYWRAP_TEST_OUTLEN];
|
||||
byte plain [MAX_KEYWRAP_TEST_PLAINLEN];
|
||||
|
||||
const keywrapVector test_wrap[] =
|
||||
{
|
||||
{k1, d1, v1, sizeof(k1), sizeof(d1), sizeof(v1)},
|
||||
{k2, d2, v2, sizeof(k2), sizeof(d2), sizeof(v2)},
|
||||
{k3, d3, v3, sizeof(k3), sizeof(d3), sizeof(v3)},
|
||||
{k4, d4, v4, sizeof(k4), sizeof(d4), sizeof(v4)},
|
||||
{k5, d5, v5, sizeof(k5), sizeof(d5), sizeof(v5)},
|
||||
{k6, d6, v6, sizeof(k6), sizeof(d6), sizeof(v6)}
|
||||
};
|
||||
testSz = sizeof(test_wrap) / sizeof(keywrapVector);
|
||||
|
||||
XMEMSET(output, 0, sizeof(output));
|
||||
XMEMSET(plain, 0, sizeof(plain));
|
||||
|
||||
for (i = 0; i < testSz; i++) {
|
||||
|
||||
wrapSz = wc_AesKeyWrap(test_wrap[i].kek, test_wrap[i].kekLen,
|
||||
test_wrap[i].data, test_wrap[i].dataLen,
|
||||
output, sizeof(output), NULL);
|
||||
|
||||
if ( (wrapSz < 0) || (wrapSz != (int)test_wrap[i].verifyLen) )
|
||||
return -101;
|
||||
|
||||
if (XMEMCMP(output, test_wrap[i].verify, test_wrap[i].verifyLen) != 0)
|
||||
return -102;
|
||||
|
||||
plainSz = wc_AesKeyUnWrap((byte*)test_wrap[i].kek, test_wrap[i].kekLen,
|
||||
output, wrapSz,
|
||||
plain, sizeof(plain), NULL);
|
||||
|
||||
if ( (plainSz < 0) || (plainSz != (int)test_wrap[i].dataLen) )
|
||||
return -103;
|
||||
|
||||
if (XMEMCMP(plain, test_wrap[i].data, test_wrap[i].dataLen) != 0)
|
||||
return -104;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_AES_KEYWRAP */
|
||||
|
||||
|
||||
#endif /* NO_AES */
|
||||
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ enum {
|
|||
AES_ENC_TYPE = 1, /* cipher unique type */
|
||||
AES_ENCRYPTION = 0,
|
||||
AES_DECRYPTION = 1,
|
||||
KEYWRAP_BLOCK_SIZE = 8,
|
||||
AES_BLOCK_SIZE = 16
|
||||
};
|
||||
|
||||
|
@ -166,6 +167,16 @@ WOLFSSL_API int wc_AesCbcDecrypt(Aes* aes, byte* out,
|
|||
const byte* authTag, word32 authTagSz,
|
||||
const byte* authIn, word32 authInSz);
|
||||
#endif /* HAVE_AESCCM */
|
||||
#ifdef HAVE_AES_KEYWRAP
|
||||
WOLFSSL_API int wc_AesKeyWrap(const byte* key, word32 keySz,
|
||||
const byte* in, word32 inSz,
|
||||
byte* out, word32 outSz,
|
||||
const byte* iv);
|
||||
WOLFSSL_API int wc_AesKeyUnWrap(const byte* key, word32 keySz,
|
||||
const byte* in, word32 inSz,
|
||||
byte* out, word32 outSz,
|
||||
const byte* iv);
|
||||
#endif /* HAVE_AES_KEYWRAP */
|
||||
|
||||
WOLFSSL_API int wc_AesGetKeySize(Aes* aes, word32* keySize);
|
||||
|
||||
|
|
|
@ -178,6 +178,8 @@ enum {
|
|||
ASN_PATHLEN_SIZE_E = -237, /* ASN CA path length too large error */
|
||||
ASN_PATHLEN_INV_E = -238, /* ASN CA path length inversion error */
|
||||
|
||||
BAD_KEYWRAP_IV_E = -239, /* Decrypted AES key wrap IV incorrect */
|
||||
|
||||
MIN_CODE_E = -300 /* errors -101 - -299 */
|
||||
|
||||
/* add new companion error id strings for any new error codes
|
||||
|
|
|
@ -1442,6 +1442,12 @@ static char *fgets(char *buff, int sz, FILE *fp)
|
|||
#endif
|
||||
#endif /* WOLFSSL_STATIC_MEMORY */
|
||||
|
||||
#ifdef HAVE_AES_KEYWRAP
|
||||
#ifndef WOLFSSL_AES_DIRECT
|
||||
#error AES key wrap requires AES direct please define WOLFSSL_AES_DIRECT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Place any other flags or defines here */
|
||||
|
||||
|
|
Loading…
Reference in New Issue