mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-01 03:34:39 +02:00
1. Fixed bug where AES-GCM IVs had to only be 12 bytes. Now
accepts any length. 2. Added test case for AES-GCM using an 60 byte IV. 3. AesGcmSetKey doesn't calculate H value in AES-NI mode.
This commit is contained in:
@@ -2651,19 +2651,11 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
|
||||
#endif
|
||||
|
||||
enum {
|
||||
CTR_SZ = 4
|
||||
NONCE_SZ = 12,
|
||||
CTR_SZ = 4
|
||||
};
|
||||
|
||||
|
||||
static INLINE void InitGcmCounter(byte* inOutCtr)
|
||||
{
|
||||
inOutCtr[AES_BLOCK_SIZE - 4] = 0;
|
||||
inOutCtr[AES_BLOCK_SIZE - 3] = 0;
|
||||
inOutCtr[AES_BLOCK_SIZE - 2] = 0;
|
||||
inOutCtr[AES_BLOCK_SIZE - 1] = 1;
|
||||
}
|
||||
|
||||
|
||||
static INLINE void IncrementGcmCounter(byte* inOutCtr)
|
||||
{
|
||||
int i;
|
||||
@@ -2752,6 +2744,12 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
|
||||
XMEMSET(iv, 0, AES_BLOCK_SIZE);
|
||||
ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION);
|
||||
|
||||
#ifdef WOLFSSL_AESNI
|
||||
/* AES-NI code generates its own H value. */
|
||||
if (haveAESNI)
|
||||
return ret;
|
||||
#endif /* WOLFSSL_AESNI */
|
||||
|
||||
if (ret == 0) {
|
||||
wc_AesEncrypt(aes, iv, aes->H);
|
||||
#ifdef GCM_TABLE
|
||||
@@ -3696,6 +3694,7 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
const byte* p = in;
|
||||
byte* c = out;
|
||||
byte counter[AES_BLOCK_SIZE];
|
||||
byte initialCounter[AES_BLOCK_SIZE];
|
||||
byte *ctr ;
|
||||
byte scratch[AES_BLOCK_SIZE];
|
||||
|
||||
@@ -3715,9 +3714,15 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
ctr = counter ;
|
||||
#endif
|
||||
|
||||
XMEMSET(ctr, 0, AES_BLOCK_SIZE);
|
||||
XMEMCPY(ctr, iv, ivSz);
|
||||
InitGcmCounter(ctr);
|
||||
XMEMSET(initialCounter, 0, AES_BLOCK_SIZE);
|
||||
if (ivSz == NONCE_SZ) {
|
||||
XMEMCPY(initialCounter, iv, ivSz);
|
||||
initialCounter[AES_BLOCK_SIZE - 1] = 1;
|
||||
}
|
||||
else {
|
||||
GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE);
|
||||
}
|
||||
XMEMCPY(ctr, initialCounter, AES_BLOCK_SIZE);
|
||||
|
||||
#ifdef WOLFSSL_PIC32MZ_CRYPT
|
||||
if(blocks)
|
||||
@@ -3744,8 +3749,7 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
}
|
||||
|
||||
GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz);
|
||||
InitGcmCounter(ctr);
|
||||
wc_AesEncrypt(aes, ctr, scratch);
|
||||
wc_AesEncrypt(aes, initialCounter, scratch);
|
||||
xorbuf(authTag, scratch, authTagSz);
|
||||
|
||||
return 0;
|
||||
@@ -3762,6 +3766,7 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
const byte* c = in;
|
||||
byte* p = out;
|
||||
byte counter[AES_BLOCK_SIZE];
|
||||
byte initialCounter[AES_BLOCK_SIZE];
|
||||
byte *ctr ;
|
||||
byte scratch[AES_BLOCK_SIZE];
|
||||
|
||||
@@ -3782,9 +3787,15 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
ctr = counter ;
|
||||
#endif
|
||||
|
||||
XMEMSET(ctr, 0, AES_BLOCK_SIZE);
|
||||
XMEMCPY(ctr, iv, ivSz);
|
||||
InitGcmCounter(ctr);
|
||||
XMEMSET(initialCounter, 0, AES_BLOCK_SIZE);
|
||||
if (ivSz == NONCE_SZ) {
|
||||
XMEMCPY(initialCounter, iv, ivSz);
|
||||
initialCounter[AES_BLOCK_SIZE - 1] = 1;
|
||||
}
|
||||
else {
|
||||
GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE);
|
||||
}
|
||||
XMEMCPY(ctr, initialCounter, AES_BLOCK_SIZE);
|
||||
|
||||
/* Calculate the authTag again using the received auth data and the
|
||||
* cipher text. */
|
||||
|
@@ -2729,20 +2729,6 @@ int aesgcm_test(void)
|
||||
* Counter Mode of Operation (GCM) by McGrew and
|
||||
* Viega.
|
||||
*/
|
||||
const byte k[] =
|
||||
{
|
||||
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
|
||||
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
|
||||
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
|
||||
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08
|
||||
};
|
||||
|
||||
const byte iv[] =
|
||||
{
|
||||
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
|
||||
0xde, 0xca, 0xf8, 0x88
|
||||
};
|
||||
|
||||
const byte p[] =
|
||||
{
|
||||
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
|
||||
@@ -2762,7 +2748,21 @@ int aesgcm_test(void)
|
||||
0xab, 0xad, 0xda, 0xd2
|
||||
};
|
||||
|
||||
const byte c[] =
|
||||
const byte k1[] =
|
||||
{
|
||||
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
|
||||
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
|
||||
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
|
||||
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08
|
||||
};
|
||||
|
||||
const byte iv1[] =
|
||||
{
|
||||
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
|
||||
0xde, 0xca, 0xf8, 0x88
|
||||
};
|
||||
|
||||
const byte c1[] =
|
||||
{
|
||||
0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
|
||||
0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
|
||||
@@ -2774,38 +2774,95 @@ int aesgcm_test(void)
|
||||
0xbc, 0xc9, 0xf6, 0x62
|
||||
};
|
||||
|
||||
const byte t[] =
|
||||
const byte t1[] =
|
||||
{
|
||||
0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
|
||||
0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b
|
||||
};
|
||||
|
||||
byte t2[sizeof(t)];
|
||||
byte p2[sizeof(c)];
|
||||
byte c2[sizeof(p)];
|
||||
/* Test Case 12, uses same plaintext and AAD data. */
|
||||
const byte k2[] =
|
||||
{
|
||||
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
|
||||
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
|
||||
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c
|
||||
};
|
||||
|
||||
int result;
|
||||
const byte iv2[] =
|
||||
{
|
||||
0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
|
||||
0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
|
||||
0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
|
||||
0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
|
||||
0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
|
||||
0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
|
||||
0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
|
||||
0xa6, 0x37, 0xb3, 0x9b
|
||||
};
|
||||
|
||||
memset(t2, 0, sizeof(t2));
|
||||
memset(c2, 0, sizeof(c2));
|
||||
memset(p2, 0, sizeof(p2));
|
||||
const byte c2[] =
|
||||
{
|
||||
0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
|
||||
0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
|
||||
0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
|
||||
0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
|
||||
0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
|
||||
0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
|
||||
0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
|
||||
0xe9, 0xb7, 0x37, 0x3b
|
||||
};
|
||||
|
||||
wc_AesGcmSetKey(&enc, k, sizeof(k));
|
||||
const byte t2[] =
|
||||
{
|
||||
0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
|
||||
0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9
|
||||
};
|
||||
|
||||
byte resultT[sizeof(t1)];
|
||||
byte resultP[sizeof(p)];
|
||||
byte resultC[sizeof(p)];
|
||||
int result;
|
||||
|
||||
memset(resultT, 0, sizeof(resultT));
|
||||
memset(resultC, 0, sizeof(resultC));
|
||||
memset(resultP, 0, sizeof(resultP));
|
||||
|
||||
wc_AesGcmSetKey(&enc, k1, sizeof(k1));
|
||||
/* AES-GCM encrypt and decrypt both use AES encrypt internally */
|
||||
wc_AesGcmEncrypt(&enc, c2, p, sizeof(c2), iv, sizeof(iv),
|
||||
t2, sizeof(t2), a, sizeof(a));
|
||||
if (memcmp(c, c2, sizeof(c2)))
|
||||
wc_AesGcmEncrypt(&enc, resultC, p, sizeof(p), iv1, sizeof(iv1),
|
||||
resultT, sizeof(resultT), a, sizeof(a));
|
||||
if (memcmp(c1, resultC, sizeof(resultC)))
|
||||
return -68;
|
||||
if (memcmp(t, t2, sizeof(t2)))
|
||||
if (memcmp(t1, resultT, sizeof(resultT)))
|
||||
return -69;
|
||||
|
||||
result = wc_AesGcmDecrypt(&enc, p2, c2, sizeof(p2), iv, sizeof(iv),
|
||||
t2, sizeof(t2), a, sizeof(a));
|
||||
result = wc_AesGcmDecrypt(&enc, resultP, resultC, sizeof(resultC),
|
||||
iv1, sizeof(iv1), resultT, sizeof(resultT), a, sizeof(a));
|
||||
if (result != 0)
|
||||
return -70;
|
||||
if (memcmp(p, p2, sizeof(p2)))
|
||||
if (memcmp(p, resultP, sizeof(resultP)))
|
||||
return -71;
|
||||
|
||||
memset(resultT, 0, sizeof(resultT));
|
||||
memset(resultC, 0, sizeof(resultC));
|
||||
memset(resultP, 0, sizeof(resultP));
|
||||
|
||||
wc_AesGcmSetKey(&enc, k2, sizeof(k2));
|
||||
/* AES-GCM encrypt and decrypt both use AES encrypt internally */
|
||||
wc_AesGcmEncrypt(&enc, resultC, p, sizeof(p), iv2, sizeof(iv2),
|
||||
resultT, sizeof(resultT), a, sizeof(a));
|
||||
if (memcmp(c2, resultC, sizeof(resultC)))
|
||||
return -230;
|
||||
if (memcmp(t2, resultT, sizeof(resultT)))
|
||||
return -231;
|
||||
|
||||
result = wc_AesGcmDecrypt(&enc, resultP, resultC, sizeof(resultC),
|
||||
iv2, sizeof(iv2), resultT, sizeof(resultT), a, sizeof(a));
|
||||
if (result != 0)
|
||||
return -232;
|
||||
if (memcmp(p, resultP, sizeof(resultP)))
|
||||
return -233;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user