Merge branch 'master' of github.com:cyassl/cyassl
This commit is contained in:
commit
aecdb33e4e
@ -186,8 +186,8 @@ void bench_aesgcm()
|
||||
double start, total, persec;
|
||||
int i;
|
||||
|
||||
AesGcmSetKey(&enc, key, 16);
|
||||
AesSetIV(&enc, iv);
|
||||
AesGcmSetKey(&enc, key, 16, iv);
|
||||
AesGcmSetExpIV(&enc, iv+4);
|
||||
start = current_time();
|
||||
|
||||
for(i = 0; i < megs; i++)
|
||||
|
@ -1407,6 +1407,25 @@ void AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
||||
|
||||
#ifdef HAVE_AESGCM
|
||||
|
||||
/*
|
||||
* The IV for AES GCM, stored in struct Aes's member reg, is comprised of
|
||||
* three parts in order:
|
||||
* 1. The implicit IV. This is generated from the PRF using the shared
|
||||
* secrets between endpoints. It is 4 bytes long.
|
||||
* 2. The explicit IV. This is set by the user of the AES. It needs to be
|
||||
* unique for each call to encrypt. The explicit IV is shared with the
|
||||
* other end of the transaction in the clear.
|
||||
* 3. The counter. Each block of data is encrypted with its own sequence
|
||||
* number counter.
|
||||
*/
|
||||
|
||||
enum {
|
||||
IMPLICIT_IV_SZ = 4,
|
||||
EXPLICIT_IV_SZ = 8,
|
||||
CTR_SZ = 4
|
||||
};
|
||||
|
||||
|
||||
static INLINE void InitGcmCounter(byte* inOutCtr)
|
||||
{
|
||||
inOutCtr[AES_BLOCK_SIZE - 4] = 0;
|
||||
@ -1421,13 +1440,43 @@ static INLINE void IncrementGcmCounter(byte* inOutCtr)
|
||||
int i;
|
||||
|
||||
/* in network byte order so start at end and work back */
|
||||
for (i = AES_BLOCK_SIZE - 1; i >= AES_BLOCK_SIZE - 4; i--) {
|
||||
for (i = AES_BLOCK_SIZE - 1; i >= AES_BLOCK_SIZE - CTR_SZ; i--) {
|
||||
if (++inOutCtr[i]) /* we're done unless we overflow */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The explicit IV is set by the caller. A common practice is to treat it as
|
||||
* a sequence number seeded with a random number. The caller manages
|
||||
* incrementing the explicit IV when appropriate.
|
||||
*/
|
||||
|
||||
void AesGcmSetExpIV(Aes* aes, const byte* iv)
|
||||
{
|
||||
XMEMCPY((byte*)aes->reg + IMPLICIT_IV_SZ, iv, EXPLICIT_IV_SZ);
|
||||
}
|
||||
|
||||
|
||||
void AesGcmGetExpIV(Aes* aes, byte* iv)
|
||||
{
|
||||
XMEMCPY(iv, (byte*)aes->reg + IMPLICIT_IV_SZ, EXPLICIT_IV_SZ);
|
||||
}
|
||||
|
||||
|
||||
void AesGcmIncExpIV(Aes* aes)
|
||||
{
|
||||
int i;
|
||||
byte* iv = (byte*)aes->reg + IMPLICIT_IV_SZ;
|
||||
|
||||
for (i = EXPLICIT_IV_SZ - 1; i >= 0; i--) {
|
||||
if (++iv[i])
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(GCM_SMALL) || defined(GCM_TABLE)
|
||||
|
||||
static INLINE void FlattenSzInBits(byte* buf, word32 sz)
|
||||
@ -1493,13 +1542,17 @@ static void GenerateM0(Aes* aes)
|
||||
#endif /* GCM_TABLE */
|
||||
|
||||
|
||||
void AesGcmSetKey(Aes* aes, const byte* key, word32 len)
|
||||
void AesGcmSetKey(Aes* aes, const byte* key, word32 len,
|
||||
const byte* implicitIV)
|
||||
{
|
||||
byte iv[AES_BLOCK_SIZE];
|
||||
byte fullIV[AES_BLOCK_SIZE];
|
||||
|
||||
XMEMSET(iv, 0, AES_BLOCK_SIZE);
|
||||
AesSetKey(aes, key, len, iv, AES_ENCRYPTION);
|
||||
AesEncrypt(aes, iv, aes->H);
|
||||
XMEMSET(fullIV, 0, AES_BLOCK_SIZE);
|
||||
XMEMCPY(fullIV, implicitIV, IMPLICIT_IV_SZ);
|
||||
AesSetKey(aes, key, len, fullIV, AES_ENCRYPTION);
|
||||
|
||||
XMEMSET(fullIV, 0, AES_BLOCK_SIZE);
|
||||
AesEncrypt(aes, fullIV, aes->H);
|
||||
#ifdef GCM_TABLE
|
||||
GenerateM0(aes);
|
||||
#endif /* GCM_TABLE */
|
||||
|
@ -1312,8 +1312,8 @@ int aesgcm_test()
|
||||
memset(c2, 0, 60);
|
||||
memset(p2, 0, 60);
|
||||
|
||||
AesGcmSetKey(&enc, k, sizeof(k));
|
||||
AesSetIV(&enc, iv);
|
||||
AesGcmSetKey(&enc, k, sizeof(k), iv);
|
||||
AesGcmSetExpIV(&enc, iv + /*AES_GCM_IMP_IV_SZ*/ 4);
|
||||
/* AES-GCM encrypt and decrypt both use AES encrypt internally */
|
||||
AesGcmEncrypt(&enc, c2, p, sizeof(c2), t2, sizeof(t2), a, sizeof(a));
|
||||
if (memcmp(c, c2, sizeof(c2)))
|
||||
|
@ -89,7 +89,11 @@ CYASSL_API void AesEncryptDirect(Aes* aes, byte* out, const byte* in);
|
||||
CYASSL_API void AesDecryptDirect(Aes* aes, byte* out, const byte* in);
|
||||
|
||||
#ifdef HAVE_AESGCM
|
||||
CYASSL_API void AesGcmSetKey(Aes* aes, const byte* key, word32 len);
|
||||
CYASSL_API void AesGcmSetKey(Aes* aes, const byte* key, word32 len,
|
||||
const byte* implicitIV);
|
||||
CYASSL_API void AesGcmSetExpIV(Aes* aes, const byte* iv);
|
||||
CYASSL_API void AesGcmGetExpIV(Aes* aes, byte* iv);
|
||||
CYASSL_API void AesGcmIncExpIV(Aes* aes);
|
||||
CYASSL_API void AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
byte* authTag, word32 authTagSz,
|
||||
const byte* authIn, word32 authInSz);
|
||||
|
@ -233,8 +233,7 @@ void c32to24(word32 in, word24 out);
|
||||
#define BUILD_AES
|
||||
#endif
|
||||
|
||||
#if defined(BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256) || \
|
||||
defined(BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)
|
||||
#if defined(BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256)
|
||||
#define BUILD_AESGCM
|
||||
#endif
|
||||
|
||||
|
@ -2235,22 +2235,6 @@ static INLINE void Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz)
|
||||
case aes_gcm:
|
||||
{
|
||||
byte additional[AES_BLOCK_SIZE];
|
||||
byte nonce[AES_BLOCK_SIZE];
|
||||
|
||||
/* use this side's IV */
|
||||
if (ssl->options.side == SERVER_END) {
|
||||
XMEMCPY(nonce, ssl->keys.server_write_IV,
|
||||
AES_GCM_IMP_IV_SZ);
|
||||
}
|
||||
else {
|
||||
XMEMCPY(nonce, ssl->keys.client_write_IV,
|
||||
AES_GCM_IMP_IV_SZ);
|
||||
}
|
||||
XMEMCPY(nonce + AES_GCM_IMP_IV_SZ,
|
||||
input, AES_GCM_EXP_IV_SZ);
|
||||
XMEMSET(nonce + AES_GCM_IMP_IV_SZ + AES_GCM_EXP_IV_SZ,
|
||||
0, AES_GCM_CTR_IV_SZ);
|
||||
AesSetIV(&ssl->encrypt.aes, nonce);
|
||||
|
||||
XMEMSET(additional, 0, AES_BLOCK_SIZE);
|
||||
|
||||
@ -2271,6 +2255,7 @@ static INLINE void Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz)
|
||||
sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
|
||||
out + sz - AEAD_AUTH_TAG_SZ, AEAD_AUTH_TAG_SZ,
|
||||
additional, AEAD_AUTH_DATA_SZ);
|
||||
AesGcmIncExpIV(&ssl->encrypt.aes);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@ -2319,23 +2304,8 @@ static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input,
|
||||
case aes_gcm:
|
||||
{
|
||||
byte additional[AES_BLOCK_SIZE];
|
||||
byte nonce[AES_BLOCK_SIZE];
|
||||
|
||||
/* use the other side's IV */
|
||||
if (ssl->options.side == SERVER_END) {
|
||||
XMEMCPY(nonce, ssl->keys.client_write_IV,
|
||||
AES_GCM_IMP_IV_SZ);
|
||||
}
|
||||
else {
|
||||
XMEMCPY(nonce, ssl->keys.server_write_IV,
|
||||
AES_GCM_IMP_IV_SZ);
|
||||
}
|
||||
XMEMCPY(nonce + AES_GCM_IMP_IV_SZ,
|
||||
input, AES_GCM_EXP_IV_SZ);
|
||||
XMEMSET(nonce + AES_GCM_IMP_IV_SZ + AES_GCM_EXP_IV_SZ,
|
||||
0, AES_GCM_CTR_IV_SZ);
|
||||
AesSetIV(&ssl->decrypt.aes, nonce);
|
||||
|
||||
AesGcmSetExpIV(&ssl->decrypt.aes, input);
|
||||
XMEMSET(additional, 0, AES_BLOCK_SIZE);
|
||||
|
||||
/* sequence number field is 64-bits, we only use 32-bits */
|
||||
@ -3044,11 +3014,13 @@ static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz,
|
||||
sz += pad;
|
||||
}
|
||||
|
||||
#ifdef BUILD_AESGCM
|
||||
if (ssl->specs.cipher_type == aead) {
|
||||
ivSz = AES_GCM_EXP_IV_SZ;
|
||||
sz += (ivSz + 16 - digestSz);
|
||||
RNG_GenerateBlock(&ssl->rng, iv, ivSz);
|
||||
AesGcmGetExpIV(&ssl->encrypt.aes, iv);
|
||||
}
|
||||
#endif
|
||||
size = (word16)(sz - headerSz); /* include mac and digest */
|
||||
AddRecordHeader(output, size, (byte)type, ssl);
|
||||
|
||||
|
21
src/keys.c
21
src/keys.c
@ -1009,12 +1009,16 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
|
||||
#ifdef BUILD_AESGCM
|
||||
if (specs->bulk_cipher_algorithm == aes_gcm) {
|
||||
if (side == CLIENT_END) {
|
||||
AesGcmSetKey(&enc->aes, keys->client_write_key, specs->key_size);
|
||||
AesGcmSetKey(&dec->aes, keys->server_write_key, specs->key_size);
|
||||
AesGcmSetKey(&enc->aes, keys->client_write_key, specs->key_size,
|
||||
keys->client_write_IV);
|
||||
AesGcmSetKey(&dec->aes, keys->server_write_key, specs->key_size,
|
||||
keys->server_write_IV);
|
||||
}
|
||||
else {
|
||||
AesGcmSetKey(&enc->aes, keys->server_write_key, specs->key_size);
|
||||
AesGcmSetKey(&dec->aes, keys->client_write_key, specs->key_size);
|
||||
AesGcmSetKey(&enc->aes, keys->server_write_key, specs->key_size,
|
||||
keys->server_write_IV);
|
||||
AesGcmSetKey(&dec->aes, keys->client_write_key, specs->key_size,
|
||||
keys->client_write_IV);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1039,6 +1043,15 @@ int StoreKeys(CYASSL* ssl, const byte* keyData)
|
||||
XMEMCPY(ssl->keys.server_write_MAC_secret,&keyData[i], sz);
|
||||
i += sz;
|
||||
}
|
||||
#ifdef BUILD_AESGCM
|
||||
else if (ssl->specs.bulk_cipher_algorithm == aes_gcm) {
|
||||
byte iv[AES_GCM_EXP_IV_SZ];
|
||||
|
||||
/* Initialize the AES-GCM explicit IV to a random number. */
|
||||
RNG_GenerateBlock(&ssl->rng, iv, sizeof(iv));
|
||||
AesGcmSetExpIV(&ssl->encrypt.aes, iv);
|
||||
}
|
||||
#endif
|
||||
|
||||
sz = ssl->specs.key_size;
|
||||
XMEMCPY(ssl->keys.client_write_key, &keyData[i], sz);
|
||||
|
Loading…
Reference in New Issue
Block a user