mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-02 12:14:38 +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
|
#endif
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
NONCE_SZ = 12,
|
||||||
CTR_SZ = 4
|
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)
|
static INLINE void IncrementGcmCounter(byte* inOutCtr)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -2752,6 +2744,12 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
|
|||||||
XMEMSET(iv, 0, AES_BLOCK_SIZE);
|
XMEMSET(iv, 0, AES_BLOCK_SIZE);
|
||||||
ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION);
|
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) {
|
if (ret == 0) {
|
||||||
wc_AesEncrypt(aes, iv, aes->H);
|
wc_AesEncrypt(aes, iv, aes->H);
|
||||||
#ifdef GCM_TABLE
|
#ifdef GCM_TABLE
|
||||||
@@ -3696,6 +3694,7 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
|
|||||||
const byte* p = in;
|
const byte* p = in;
|
||||||
byte* c = out;
|
byte* c = out;
|
||||||
byte counter[AES_BLOCK_SIZE];
|
byte counter[AES_BLOCK_SIZE];
|
||||||
|
byte initialCounter[AES_BLOCK_SIZE];
|
||||||
byte *ctr ;
|
byte *ctr ;
|
||||||
byte scratch[AES_BLOCK_SIZE];
|
byte scratch[AES_BLOCK_SIZE];
|
||||||
|
|
||||||
@@ -3715,9 +3714,15 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
|
|||||||
ctr = counter ;
|
ctr = counter ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
XMEMSET(ctr, 0, AES_BLOCK_SIZE);
|
XMEMSET(initialCounter, 0, AES_BLOCK_SIZE);
|
||||||
XMEMCPY(ctr, iv, ivSz);
|
if (ivSz == NONCE_SZ) {
|
||||||
InitGcmCounter(ctr);
|
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
|
#ifdef WOLFSSL_PIC32MZ_CRYPT
|
||||||
if(blocks)
|
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);
|
GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz);
|
||||||
InitGcmCounter(ctr);
|
wc_AesEncrypt(aes, initialCounter, scratch);
|
||||||
wc_AesEncrypt(aes, ctr, scratch);
|
|
||||||
xorbuf(authTag, scratch, authTagSz);
|
xorbuf(authTag, scratch, authTagSz);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -3762,6 +3766,7 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
|
|||||||
const byte* c = in;
|
const byte* c = in;
|
||||||
byte* p = out;
|
byte* p = out;
|
||||||
byte counter[AES_BLOCK_SIZE];
|
byte counter[AES_BLOCK_SIZE];
|
||||||
|
byte initialCounter[AES_BLOCK_SIZE];
|
||||||
byte *ctr ;
|
byte *ctr ;
|
||||||
byte scratch[AES_BLOCK_SIZE];
|
byte scratch[AES_BLOCK_SIZE];
|
||||||
|
|
||||||
@@ -3782,9 +3787,15 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
|
|||||||
ctr = counter ;
|
ctr = counter ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
XMEMSET(ctr, 0, AES_BLOCK_SIZE);
|
XMEMSET(initialCounter, 0, AES_BLOCK_SIZE);
|
||||||
XMEMCPY(ctr, iv, ivSz);
|
if (ivSz == NONCE_SZ) {
|
||||||
InitGcmCounter(ctr);
|
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
|
/* Calculate the authTag again using the received auth data and the
|
||||||
* cipher text. */
|
* cipher text. */
|
||||||
|
@@ -2729,20 +2729,6 @@ int aesgcm_test(void)
|
|||||||
* Counter Mode of Operation (GCM) by McGrew and
|
* Counter Mode of Operation (GCM) by McGrew and
|
||||||
* Viega.
|
* 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[] =
|
const byte p[] =
|
||||||
{
|
{
|
||||||
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
|
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
|
||||||
@@ -2762,7 +2748,21 @@ int aesgcm_test(void)
|
|||||||
0xab, 0xad, 0xda, 0xd2
|
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,
|
0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
|
||||||
0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
|
0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
|
||||||
@@ -2774,38 +2774,95 @@ int aesgcm_test(void)
|
|||||||
0xbc, 0xc9, 0xf6, 0x62
|
0xbc, 0xc9, 0xf6, 0x62
|
||||||
};
|
};
|
||||||
|
|
||||||
const byte t[] =
|
const byte t1[] =
|
||||||
{
|
{
|
||||||
0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
|
0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
|
||||||
0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b
|
0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b
|
||||||
};
|
};
|
||||||
|
|
||||||
byte t2[sizeof(t)];
|
/* Test Case 12, uses same plaintext and AAD data. */
|
||||||
byte p2[sizeof(c)];
|
const byte k2[] =
|
||||||
byte c2[sizeof(p)];
|
{
|
||||||
|
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
|
||||||
|
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
|
||||||
|
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
int result;
|
||||||
|
|
||||||
memset(t2, 0, sizeof(t2));
|
memset(resultT, 0, sizeof(resultT));
|
||||||
memset(c2, 0, sizeof(c2));
|
memset(resultC, 0, sizeof(resultC));
|
||||||
memset(p2, 0, sizeof(p2));
|
memset(resultP, 0, sizeof(resultP));
|
||||||
|
|
||||||
wc_AesGcmSetKey(&enc, k, sizeof(k));
|
wc_AesGcmSetKey(&enc, k1, sizeof(k1));
|
||||||
/* AES-GCM encrypt and decrypt both use AES encrypt internally */
|
/* AES-GCM encrypt and decrypt both use AES encrypt internally */
|
||||||
wc_AesGcmEncrypt(&enc, c2, p, sizeof(c2), iv, sizeof(iv),
|
wc_AesGcmEncrypt(&enc, resultC, p, sizeof(p), iv1, sizeof(iv1),
|
||||||
t2, sizeof(t2), a, sizeof(a));
|
resultT, sizeof(resultT), a, sizeof(a));
|
||||||
if (memcmp(c, c2, sizeof(c2)))
|
if (memcmp(c1, resultC, sizeof(resultC)))
|
||||||
return -68;
|
return -68;
|
||||||
if (memcmp(t, t2, sizeof(t2)))
|
if (memcmp(t1, resultT, sizeof(resultT)))
|
||||||
return -69;
|
return -69;
|
||||||
|
|
||||||
result = wc_AesGcmDecrypt(&enc, p2, c2, sizeof(p2), iv, sizeof(iv),
|
result = wc_AesGcmDecrypt(&enc, resultP, resultC, sizeof(resultC),
|
||||||
t2, sizeof(t2), a, sizeof(a));
|
iv1, sizeof(iv1), resultT, sizeof(resultT), a, sizeof(a));
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
return -70;
|
return -70;
|
||||||
if (memcmp(p, p2, sizeof(p2)))
|
if (memcmp(p, resultP, sizeof(resultP)))
|
||||||
return -71;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user