Add support for using 192-bit and 256-bit keys with AES-GCM
This adds 192-bit and 256-bit key support to the internal AES implementation and extends the AES-GCM functions to accept key length to enable longer AES key use. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
af0963fab4
commit
d140db6adf
8 changed files with 258 additions and 65 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Galois/Counter Mode (GCM) and GMAC with AES-128
|
* Galois/Counter Mode (GCM) and GMAC with AES
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2012, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
|
@ -173,18 +173,18 @@ static void aes_gctr(void *aes, const u8 *icb, const u8 *x, size_t xlen, u8 *y)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* aes_128_gcm_ae - GCM-AE_K(IV, P, A)
|
* aes_gcm_ae - GCM-AE_K(IV, P, A)
|
||||||
*/
|
*/
|
||||||
int aes_128_gcm_ae(const u8 *key, const u8 *iv, size_t iv_len,
|
int aes_gcm_ae(const u8 *key, size_t key_len, const u8 *iv, size_t iv_len,
|
||||||
const u8 *plain, size_t plain_len,
|
const u8 *plain, size_t plain_len,
|
||||||
const u8 *aad, size_t aad_len, u8 *crypt, u8 *tag)
|
const u8 *aad, size_t aad_len, u8 *crypt, u8 *tag)
|
||||||
{
|
{
|
||||||
u8 H[AES_BLOCK_SIZE];
|
u8 H[AES_BLOCK_SIZE];
|
||||||
u8 J0[AES_BLOCK_SIZE], J0inc[AES_BLOCK_SIZE];
|
u8 J0[AES_BLOCK_SIZE], J0inc[AES_BLOCK_SIZE];
|
||||||
u8 S[16], len_buf[16];
|
u8 S[16], len_buf[16];
|
||||||
void *aes;
|
void *aes;
|
||||||
|
|
||||||
aes = aes_encrypt_init(key, 16);
|
aes = aes_encrypt_init(key, key_len);
|
||||||
if (aes == NULL)
|
if (aes == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -242,18 +242,18 @@ int aes_128_gcm_ae(const u8 *key, const u8 *iv, size_t iv_len,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* aes_128_gcm_ad - GCM-AD_K(IV, C, A, T)
|
* aes_gcm_ad - GCM-AD_K(IV, C, A, T)
|
||||||
*/
|
*/
|
||||||
int aes_128_gcm_ad(const u8 *key, const u8 *iv, size_t iv_len,
|
int aes_gcm_ad(const u8 *key, size_t key_len, const u8 *iv, size_t iv_len,
|
||||||
const u8 *crypt, size_t crypt_len,
|
const u8 *crypt, size_t crypt_len,
|
||||||
const u8 *aad, size_t aad_len, const u8 *tag, u8 *plain)
|
const u8 *aad, size_t aad_len, const u8 *tag, u8 *plain)
|
||||||
{
|
{
|
||||||
u8 H[AES_BLOCK_SIZE];
|
u8 H[AES_BLOCK_SIZE];
|
||||||
u8 J0[AES_BLOCK_SIZE], J0inc[AES_BLOCK_SIZE];
|
u8 J0[AES_BLOCK_SIZE], J0inc[AES_BLOCK_SIZE];
|
||||||
u8 S[16], T[16], len_buf[16];
|
u8 S[16], T[16], len_buf[16];
|
||||||
void *aes;
|
void *aes;
|
||||||
|
|
||||||
aes = aes_encrypt_init(key, 16);
|
aes = aes_encrypt_init(key, key_len);
|
||||||
if (aes == NULL)
|
if (aes == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,13 @@
|
||||||
* AES (Rijndael) cipher - decrypt
|
* AES (Rijndael) cipher - decrypt
|
||||||
*
|
*
|
||||||
* Modifications to public domain implementation:
|
* Modifications to public domain implementation:
|
||||||
* - support only 128-bit keys
|
|
||||||
* - cleanup
|
* - cleanup
|
||||||
* - use C pre-processor to make it easier to change S table access
|
* - use C pre-processor to make it easier to change S table access
|
||||||
* - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at
|
* - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at
|
||||||
* cost of reduced throughput (quite small difference on Pentium 4,
|
* cost of reduced throughput (quite small difference on Pentium 4,
|
||||||
* 10-25% when using -O1 or -O2 optimization)
|
* 10-25% when using -O1 or -O2 optimization)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -26,13 +25,15 @@
|
||||||
*
|
*
|
||||||
* @return the number of rounds for the given cipher key size.
|
* @return the number of rounds for the given cipher key size.
|
||||||
*/
|
*/
|
||||||
static void rijndaelKeySetupDec(u32 rk[/*44*/], const u8 cipherKey[])
|
static int rijndaelKeySetupDec(u32 rk[], const u8 cipherKey[], int keyBits)
|
||||||
{
|
{
|
||||||
int Nr = 10, i, j;
|
int Nr, i, j;
|
||||||
u32 temp;
|
u32 temp;
|
||||||
|
|
||||||
/* expand the cipher key: */
|
/* expand the cipher key: */
|
||||||
rijndaelKeySetupEnc(rk, cipherKey);
|
Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits);
|
||||||
|
if (Nr < 0)
|
||||||
|
return Nr;
|
||||||
/* invert the order of the round keys: */
|
/* invert the order of the round keys: */
|
||||||
for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) {
|
for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) {
|
||||||
temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
|
temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
|
||||||
|
@ -51,24 +52,30 @@ static void rijndaelKeySetupDec(u32 rk[/*44*/], const u8 cipherKey[])
|
||||||
TD3_(TE4((rk[j] ) & 0xff));
|
TD3_(TE4((rk[j] ) & 0xff));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Nr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void * aes_decrypt_init(const u8 *key, size_t len)
|
void * aes_decrypt_init(const u8 *key, size_t len)
|
||||||
{
|
{
|
||||||
u32 *rk;
|
u32 *rk;
|
||||||
if (len != 16)
|
int res;
|
||||||
return NULL;
|
|
||||||
rk = os_malloc(AES_PRIV_SIZE);
|
rk = os_malloc(AES_PRIV_SIZE);
|
||||||
if (rk == NULL)
|
if (rk == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
rijndaelKeySetupDec(rk, key);
|
res = rijndaelKeySetupDec(rk, key, len * 8);
|
||||||
|
if (res < 0) {
|
||||||
|
os_free(rk);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
rk[AES_PRIV_NR_POS] = res;
|
||||||
return rk;
|
return rk;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rijndaelDecrypt(const u32 rk[/*44*/], const u8 ct[16], u8 pt[16])
|
static void rijndaelDecrypt(const u32 rk[/*44*/], int Nr, const u8 ct[16],
|
||||||
|
u8 pt[16])
|
||||||
{
|
{
|
||||||
u32 s0, s1, s2, s3, t0, t1, t2, t3;
|
u32 s0, s1, s2, s3, t0, t1, t2, t3;
|
||||||
const int Nr = 10;
|
|
||||||
#ifndef FULL_UNROLL
|
#ifndef FULL_UNROLL
|
||||||
int r;
|
int r;
|
||||||
#endif /* ?FULL_UNROLL */
|
#endif /* ?FULL_UNROLL */
|
||||||
|
@ -99,6 +106,14 @@ d##3 = TD0(s##3) ^ TD1(s##2) ^ TD2(s##1) ^ TD3(s##0) ^ rk[4 * i + 3]
|
||||||
ROUND(7,t,s);
|
ROUND(7,t,s);
|
||||||
ROUND(8,s,t);
|
ROUND(8,s,t);
|
||||||
ROUND(9,t,s);
|
ROUND(9,t,s);
|
||||||
|
if (Nr > 10) {
|
||||||
|
ROUND(10,s,t);
|
||||||
|
ROUND(11,t,s);
|
||||||
|
if (Nr > 12) {
|
||||||
|
ROUND(12,s,t);
|
||||||
|
ROUND(13,t,s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rk += Nr << 2;
|
rk += Nr << 2;
|
||||||
|
|
||||||
|
@ -134,7 +149,8 @@ d##3 = TD0(s##3) ^ TD1(s##2) ^ TD2(s##1) ^ TD3(s##0) ^ rk[4 * i + 3]
|
||||||
|
|
||||||
void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
|
void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
|
||||||
{
|
{
|
||||||
rijndaelDecrypt(ctx, crypt, plain);
|
u32 *rk = ctx;
|
||||||
|
rijndaelDecrypt(ctx, rk[AES_PRIV_NR_POS], crypt, plain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,13 @@
|
||||||
* AES (Rijndael) cipher - encrypt
|
* AES (Rijndael) cipher - encrypt
|
||||||
*
|
*
|
||||||
* Modifications to public domain implementation:
|
* Modifications to public domain implementation:
|
||||||
* - support only 128-bit keys
|
|
||||||
* - cleanup
|
* - cleanup
|
||||||
* - use C pre-processor to make it easier to change S table access
|
* - use C pre-processor to make it easier to change S table access
|
||||||
* - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at
|
* - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at
|
||||||
* cost of reduced throughput (quite small difference on Pentium 4,
|
* cost of reduced throughput (quite small difference on Pentium 4,
|
||||||
* 10-25% when using -O1 or -O2 optimization)
|
* 10-25% when using -O1 or -O2 optimization)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -21,10 +20,9 @@
|
||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
#include "aes_i.h"
|
#include "aes_i.h"
|
||||||
|
|
||||||
static void rijndaelEncrypt(const u32 rk[/*44*/], const u8 pt[16], u8 ct[16])
|
static void rijndaelEncrypt(const u32 rk[], int Nr, const u8 pt[16], u8 ct[16])
|
||||||
{
|
{
|
||||||
u32 s0, s1, s2, s3, t0, t1, t2, t3;
|
u32 s0, s1, s2, s3, t0, t1, t2, t3;
|
||||||
const int Nr = 10;
|
|
||||||
#ifndef FULL_UNROLL
|
#ifndef FULL_UNROLL
|
||||||
int r;
|
int r;
|
||||||
#endif /* ?FULL_UNROLL */
|
#endif /* ?FULL_UNROLL */
|
||||||
|
@ -55,6 +53,14 @@ d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3]
|
||||||
ROUND(7,t,s);
|
ROUND(7,t,s);
|
||||||
ROUND(8,s,t);
|
ROUND(8,s,t);
|
||||||
ROUND(9,t,s);
|
ROUND(9,t,s);
|
||||||
|
if (Nr > 10) {
|
||||||
|
ROUND(10,s,t);
|
||||||
|
ROUND(11,t,s);
|
||||||
|
if (Nr > 12) {
|
||||||
|
ROUND(12,s,t);
|
||||||
|
ROUND(13,t,s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rk += Nr << 2;
|
rk += Nr << 2;
|
||||||
|
|
||||||
|
@ -92,19 +98,24 @@ d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3]
|
||||||
void * aes_encrypt_init(const u8 *key, size_t len)
|
void * aes_encrypt_init(const u8 *key, size_t len)
|
||||||
{
|
{
|
||||||
u32 *rk;
|
u32 *rk;
|
||||||
if (len != 16)
|
int res;
|
||||||
return NULL;
|
|
||||||
rk = os_malloc(AES_PRIV_SIZE);
|
rk = os_malloc(AES_PRIV_SIZE);
|
||||||
if (rk == NULL)
|
if (rk == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
rijndaelKeySetupEnc(rk, key);
|
res = rijndaelKeySetupEnc(rk, key, len * 8);
|
||||||
|
if (res < 0) {
|
||||||
|
os_free(rk);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
rk[AES_PRIV_NR_POS] = res;
|
||||||
return rk;
|
return rk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
|
void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
|
||||||
{
|
{
|
||||||
rijndaelEncrypt(ctx, plain, crypt);
|
u32 *rk = ctx;
|
||||||
|
rijndaelEncrypt(ctx, rk[AES_PRIV_NR_POS], plain, crypt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,13 @@
|
||||||
* AES (Rijndael) cipher
|
* AES (Rijndael) cipher
|
||||||
*
|
*
|
||||||
* Modifications to public domain implementation:
|
* Modifications to public domain implementation:
|
||||||
* - support only 128-bit keys
|
|
||||||
* - cleanup
|
* - cleanup
|
||||||
* - use C pre-processor to make it easier to change S table access
|
* - use C pre-processor to make it easier to change S table access
|
||||||
* - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at
|
* - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at
|
||||||
* cost of reduced throughput (quite small difference on Pentium 4,
|
* cost of reduced throughput (quite small difference on Pentium 4,
|
||||||
* 10-25% when using -O1 or -O2 optimization)
|
* 10-25% when using -O1 or -O2 optimization)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -777,7 +776,7 @@ const u8 rcons[] = {
|
||||||
*
|
*
|
||||||
* @return the number of rounds for the given cipher key size.
|
* @return the number of rounds for the given cipher key size.
|
||||||
*/
|
*/
|
||||||
void rijndaelKeySetupEnc(u32 rk[/*44*/], const u8 cipherKey[])
|
int rijndaelKeySetupEnc(u32 rk[], const u8 cipherKey[], int keyBits)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
u32 temp;
|
u32 temp;
|
||||||
|
@ -786,14 +785,61 @@ void rijndaelKeySetupEnc(u32 rk[/*44*/], const u8 cipherKey[])
|
||||||
rk[1] = GETU32(cipherKey + 4);
|
rk[1] = GETU32(cipherKey + 4);
|
||||||
rk[2] = GETU32(cipherKey + 8);
|
rk[2] = GETU32(cipherKey + 8);
|
||||||
rk[3] = GETU32(cipherKey + 12);
|
rk[3] = GETU32(cipherKey + 12);
|
||||||
for (i = 0; i < 10; i++) {
|
|
||||||
temp = rk[3];
|
if (keyBits == 128) {
|
||||||
rk[4] = rk[0] ^
|
for (i = 0; i < 10; i++) {
|
||||||
TE421(temp) ^ TE432(temp) ^ TE443(temp) ^ TE414(temp) ^
|
temp = rk[3];
|
||||||
RCON(i);
|
rk[4] = rk[0] ^ TE421(temp) ^ TE432(temp) ^
|
||||||
rk[5] = rk[1] ^ rk[4];
|
TE443(temp) ^ TE414(temp) ^ RCON(i);
|
||||||
rk[6] = rk[2] ^ rk[5];
|
rk[5] = rk[1] ^ rk[4];
|
||||||
rk[7] = rk[3] ^ rk[6];
|
rk[6] = rk[2] ^ rk[5];
|
||||||
rk += 4;
|
rk[7] = rk[3] ^ rk[6];
|
||||||
|
rk += 4;
|
||||||
|
}
|
||||||
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rk[4] = GETU32(cipherKey + 16);
|
||||||
|
rk[5] = GETU32(cipherKey + 20);
|
||||||
|
|
||||||
|
if (keyBits == 192) {
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
temp = rk[5];
|
||||||
|
rk[6] = rk[0] ^ TE421(temp) ^ TE432(temp) ^
|
||||||
|
TE443(temp) ^ TE414(temp) ^ RCON(i);
|
||||||
|
rk[7] = rk[1] ^ rk[6];
|
||||||
|
rk[8] = rk[2] ^ rk[7];
|
||||||
|
rk[9] = rk[3] ^ rk[8];
|
||||||
|
if (i == 7)
|
||||||
|
return 12;
|
||||||
|
rk[10] = rk[4] ^ rk[9];
|
||||||
|
rk[11] = rk[5] ^ rk[10];
|
||||||
|
rk += 6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rk[6] = GETU32(cipherKey + 24);
|
||||||
|
rk[7] = GETU32(cipherKey + 28);
|
||||||
|
|
||||||
|
if (keyBits == 256) {
|
||||||
|
for (i = 0; i < 7; i++) {
|
||||||
|
temp = rk[7];
|
||||||
|
rk[8] = rk[0] ^ TE421(temp) ^ TE432(temp) ^
|
||||||
|
TE443(temp) ^ TE414(temp) ^ RCON(i);
|
||||||
|
rk[9] = rk[1] ^ rk[8];
|
||||||
|
rk[10] = rk[2] ^ rk[9];
|
||||||
|
rk[11] = rk[3] ^ rk[10];
|
||||||
|
if (i == 6)
|
||||||
|
return 14;
|
||||||
|
temp = rk[11];
|
||||||
|
rk[12] = rk[4] ^ TE411(temp) ^ TE422(temp) ^
|
||||||
|
TE433(temp) ^ TE444(temp);
|
||||||
|
rk[13] = rk[5] ^ rk[12];
|
||||||
|
rk[14] = rk[6] ^ rk[13];
|
||||||
|
rk[15] = rk[7] ^ rk[14];
|
||||||
|
rk += 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* AES (Rijndael) cipher
|
* AES (Rijndael) cipher
|
||||||
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -44,6 +44,10 @@ extern const u8 rcons[10];
|
||||||
#define TE432(i) (Te4[((i) >> 8) & 0xff] & 0x00ff0000)
|
#define TE432(i) (Te4[((i) >> 8) & 0xff] & 0x00ff0000)
|
||||||
#define TE443(i) (Te4[(i) & 0xff] & 0x0000ff00)
|
#define TE443(i) (Te4[(i) & 0xff] & 0x0000ff00)
|
||||||
#define TE414(i) (Te4[((i) >> 24) & 0xff] & 0x000000ff)
|
#define TE414(i) (Te4[((i) >> 24) & 0xff] & 0x000000ff)
|
||||||
|
#define TE411(i) (Te4[((i) >> 24) & 0xff] & 0xff000000)
|
||||||
|
#define TE422(i) (Te4[((i) >> 16) & 0xff] & 0x00ff0000)
|
||||||
|
#define TE433(i) (Te4[((i) >> 8) & 0xff] & 0x0000ff00)
|
||||||
|
#define TE444(i) (Te4[(i) & 0xff] & 0x000000ff)
|
||||||
#define TE4(i) (Te4[(i)] & 0x000000ff)
|
#define TE4(i) (Te4[(i)] & 0x000000ff)
|
||||||
|
|
||||||
#define TD0(i) Td0[((i) >> 24) & 0xff]
|
#define TD0(i) Td0[((i) >> 24) & 0xff]
|
||||||
|
@ -80,6 +84,10 @@ static inline u32 rotr(u32 val, int bits)
|
||||||
#define TE432(i) (Te0[((i) >> 8) & 0xff] & 0x00ff0000)
|
#define TE432(i) (Te0[((i) >> 8) & 0xff] & 0x00ff0000)
|
||||||
#define TE443(i) (Te0[(i) & 0xff] & 0x0000ff00)
|
#define TE443(i) (Te0[(i) & 0xff] & 0x0000ff00)
|
||||||
#define TE414(i) ((Te0[((i) >> 24) & 0xff] >> 8) & 0x000000ff)
|
#define TE414(i) ((Te0[((i) >> 24) & 0xff] >> 8) & 0x000000ff)
|
||||||
|
#define TE411(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000)
|
||||||
|
#define TE422(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000)
|
||||||
|
#define TE433(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00)
|
||||||
|
#define TE444(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff)
|
||||||
#define TE4(i) ((Te0[(i)] >> 8) & 0x000000ff)
|
#define TE4(i) ((Te0[(i)] >> 8) & 0x000000ff)
|
||||||
|
|
||||||
#define TD0(i) Td0[((i) >> 24) & 0xff]
|
#define TD0(i) Td0[((i) >> 24) & 0xff]
|
||||||
|
@ -109,8 +117,9 @@ static inline u32 rotr(u32 val, int bits)
|
||||||
(ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
|
(ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define AES_PRIV_SIZE (4 * 44)
|
#define AES_PRIV_SIZE (4 * 4 * 15 + 4)
|
||||||
|
#define AES_PRIV_NR_POS (4 * 15)
|
||||||
|
|
||||||
void rijndaelKeySetupEnc(u32 rk[/*44*/], const u8 cipherKey[]);
|
int rijndaelKeySetupEnc(u32 rk[], const u8 cipherKey[], int keyBits);
|
||||||
|
|
||||||
#endif /* AES_I_H */
|
#endif /* AES_I_H */
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* - AES-128 CTR mode encryption
|
* - AES-128 CTR mode encryption
|
||||||
* - AES-128 EAX mode encryption/decryption
|
* - AES-128 EAX mode encryption/decryption
|
||||||
* - AES-128 CBC
|
* - AES-128 CBC
|
||||||
* - AES-128 GCM
|
* - AES-GCM
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
|
@ -39,13 +39,15 @@ int __must_check aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data,
|
||||||
size_t data_len);
|
size_t data_len);
|
||||||
int __must_check aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data,
|
int __must_check aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data,
|
||||||
size_t data_len);
|
size_t data_len);
|
||||||
int __must_check aes_128_gcm_ae(const u8 *key, const u8 *iv, size_t iv_len,
|
int __must_check aes_gcm_ae(const u8 *key, size_t key_len,
|
||||||
const u8 *plain, size_t plain_len,
|
const u8 *iv, size_t iv_len,
|
||||||
const u8 *aad, size_t aad_len,
|
const u8 *plain, size_t plain_len,
|
||||||
u8 *crypt, u8 *tag);
|
const u8 *aad, size_t aad_len,
|
||||||
int __must_check aes_128_gcm_ad(const u8 *key, const u8 *iv, size_t iv_len,
|
u8 *crypt, u8 *tag);
|
||||||
const u8 *crypt, size_t crypt_len,
|
int __must_check aes_gcm_ad(const u8 *key, size_t key_len,
|
||||||
const u8 *aad, size_t aad_len, const u8 *tag,
|
const u8 *iv, size_t iv_len,
|
||||||
u8 *plain);
|
const u8 *crypt, size_t crypt_len,
|
||||||
|
const u8 *aad, size_t aad_len, const u8 *tag,
|
||||||
|
u8 *plain);
|
||||||
|
|
||||||
#endif /* AES_WRAP_H */
|
#endif /* AES_WRAP_H */
|
||||||
|
|
123
tests/test-aes.c
123
tests/test-aes.c
|
@ -227,6 +227,114 @@ static const struct gcm_test_vector gcm_tests[] = {
|
||||||
"9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b",
|
"9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b",
|
||||||
"8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5",
|
"8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5",
|
||||||
"619cc5aefffe0bfa462af43c1699d050"
|
"619cc5aefffe0bfa462af43c1699d050"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Test Case 7 */
|
||||||
|
"000000000000000000000000000000000000000000000000",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"000000000000000000000000",
|
||||||
|
"",
|
||||||
|
"cd33b28ac773f74ba00ed1f312572435"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Test Case 8 */
|
||||||
|
"000000000000000000000000000000000000000000000000",
|
||||||
|
"00000000000000000000000000000000",
|
||||||
|
"",
|
||||||
|
"000000000000000000000000",
|
||||||
|
"98e7247c07f0fe411c267e4384b0f600",
|
||||||
|
"2ff58d80033927ab8ef4d4587514f0fb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Test Case 9 */
|
||||||
|
"feffe9928665731c6d6a8f9467308308feffe9928665731c",
|
||||||
|
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255",
|
||||||
|
"",
|
||||||
|
"cafebabefacedbaddecaf888",
|
||||||
|
"3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade256",
|
||||||
|
"9924a7c8587336bfb118024db8674a14"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Test Case 10 */
|
||||||
|
"feffe9928665731c6d6a8f9467308308feffe9928665731c",
|
||||||
|
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
|
||||||
|
"feedfacedeadbeeffeedfacedeadbeefabaddad2",
|
||||||
|
"cafebabefacedbaddecaf888",
|
||||||
|
"3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710",
|
||||||
|
"2519498e80f1478f37ba55bd6d27618c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Test Case 11 */
|
||||||
|
"feffe9928665731c6d6a8f9467308308feffe9928665731c",
|
||||||
|
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
|
||||||
|
"feedfacedeadbeeffeedfacedeadbeefabaddad2",
|
||||||
|
"cafebabefacedbad",
|
||||||
|
"0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f7",
|
||||||
|
"65dcc57fcf623a24094fcca40d3533f8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Test Case 12 */
|
||||||
|
"feffe9928665731c6d6a8f9467308308feffe9928665731c",
|
||||||
|
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
|
||||||
|
"feedfacedeadbeeffeedfacedeadbeefabaddad2",
|
||||||
|
"9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b",
|
||||||
|
"d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b",
|
||||||
|
"dcf566ff291c25bbb8568fc3d376a6d9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Test Case 13 */
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"000000000000000000000000",
|
||||||
|
"",
|
||||||
|
"530f8afbc74536b9a963b4f1c4cb738b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Test Case 14 */
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"00000000000000000000000000000000",
|
||||||
|
"",
|
||||||
|
"000000000000000000000000",
|
||||||
|
"cea7403d4d606b6e074ec5d3baf39d18",
|
||||||
|
"d0d1c8a799996bf0265b98b5d48ab919"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Test Case 15 */
|
||||||
|
"feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
|
||||||
|
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255",
|
||||||
|
"",
|
||||||
|
"cafebabefacedbaddecaf888",
|
||||||
|
"522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad",
|
||||||
|
"b094dac5d93471bdec1a502270e3cc6c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Test Case 16 */
|
||||||
|
"feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
|
||||||
|
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
|
||||||
|
"feedfacedeadbeeffeedfacedeadbeefabaddad2",
|
||||||
|
"cafebabefacedbaddecaf888",
|
||||||
|
"522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662",
|
||||||
|
"76fc6ece0f4e1768cddf8853bb2d551b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Test Case 17 */
|
||||||
|
"feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
|
||||||
|
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
|
||||||
|
"feedfacedeadbeeffeedfacedeadbeefabaddad2",
|
||||||
|
"cafebabefacedbad",
|
||||||
|
"c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f",
|
||||||
|
"3a337dbf46a792c45e454913fe2ea8f2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Test Case 18 */
|
||||||
|
"feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
|
||||||
|
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
|
||||||
|
"feedfacedeadbeeffeedfacedeadbeefabaddad2",
|
||||||
|
"9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b",
|
||||||
|
"5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f",
|
||||||
|
"a44a8266ee1c8eb0c8b5d4cf5ae9f19a"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -235,14 +343,15 @@ static int test_gcm(void)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int i;
|
int i;
|
||||||
u8 k[16], aad[32], iv[64], t[16], tag[16];
|
u8 k[32], aad[32], iv[64], t[16], tag[16];
|
||||||
u8 p[64], c[64], tmp[64];
|
u8 p[64], c[64], tmp[64];
|
||||||
size_t p_len, aad_len, iv_len;
|
size_t k_len, p_len, aad_len, iv_len;
|
||||||
|
|
||||||
for (i = 0; i < sizeof(gcm_tests) / sizeof(gcm_tests[0]); i++) {
|
for (i = 0; i < sizeof(gcm_tests) / sizeof(gcm_tests[0]); i++) {
|
||||||
const struct gcm_test_vector *tc = &gcm_tests[i];
|
const struct gcm_test_vector *tc = &gcm_tests[i];
|
||||||
|
|
||||||
if (hexstr2bin(tc->k, k, sizeof(k))) {
|
k_len = os_strlen(tc->k) / 2;
|
||||||
|
if (hexstr2bin(tc->k, k, k_len)) {
|
||||||
printf("Invalid GCM test vector %d (k)\n", i);
|
printf("Invalid GCM test vector %d (k)\n", i);
|
||||||
ret++;
|
ret++;
|
||||||
continue;
|
continue;
|
||||||
|
@ -281,8 +390,8 @@ static int test_gcm(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aes_128_gcm_ae(k, iv, iv_len, p, p_len, aad, aad_len, tmp,
|
if (aes_gcm_ae(k, k_len, iv, iv_len, p, p_len, aad, aad_len,
|
||||||
tag) < 0) {
|
tmp, tag) < 0) {
|
||||||
printf("GCM-AE failed (test case %d)\n", i);
|
printf("GCM-AE failed (test case %d)\n", i);
|
||||||
ret++;
|
ret++;
|
||||||
continue;
|
continue;
|
||||||
|
@ -298,8 +407,8 @@ static int test_gcm(void)
|
||||||
ret++;
|
ret++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aes_128_gcm_ad(k, iv, iv_len, c, p_len, aad, aad_len, t,
|
if (aes_gcm_ad(k, k_len, iv, iv_len, c, p_len, aad, aad_len,
|
||||||
tmp) < 0) {
|
t, tmp) < 0) {
|
||||||
printf("GCM-AD failed (test case %d)\n", i);
|
printf("GCM-AD failed (test case %d)\n", i);
|
||||||
ret++;
|
ret++;
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -95,8 +95,8 @@ u8 * gcmp_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr,
|
||||||
wpa_hexdump(MSG_EXCESSIVE, "GCMP AAD", aad, aad_len);
|
wpa_hexdump(MSG_EXCESSIVE, "GCMP AAD", aad, aad_len);
|
||||||
wpa_hexdump(MSG_EXCESSIVE, "GCMP nonce", nonce, sizeof(nonce));
|
wpa_hexdump(MSG_EXCESSIVE, "GCMP nonce", nonce, sizeof(nonce));
|
||||||
|
|
||||||
if (aes_128_gcm_ad(tk, nonce, sizeof(nonce), m, mlen, aad, aad_len,
|
if (aes_gcm_ad(tk, 16, nonce, sizeof(nonce), m, mlen, aad, aad_len,
|
||||||
m + mlen, plain) < 0) {
|
m + mlen, plain) < 0) {
|
||||||
u16 seq_ctrl = le_to_host16(hdr->seq_ctrl);
|
u16 seq_ctrl = le_to_host16(hdr->seq_ctrl);
|
||||||
wpa_printf(MSG_INFO, "Invalid GCMP frame: A1=" MACSTR
|
wpa_printf(MSG_INFO, "Invalid GCMP frame: A1=" MACSTR
|
||||||
" A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u",
|
" A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u",
|
||||||
|
@ -146,8 +146,8 @@ u8 * gcmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos,
|
||||||
wpa_hexdump(MSG_EXCESSIVE, "GCMP AAD", aad, aad_len);
|
wpa_hexdump(MSG_EXCESSIVE, "GCMP AAD", aad, aad_len);
|
||||||
wpa_hexdump(MSG_EXCESSIVE, "GCMP nonce", nonce, sizeof(nonce));
|
wpa_hexdump(MSG_EXCESSIVE, "GCMP nonce", nonce, sizeof(nonce));
|
||||||
|
|
||||||
if (aes_128_gcm_ae(tk, nonce, sizeof(nonce), frame + hdrlen, plen, aad,
|
if (aes_gcm_ae(tk, 16, nonce, sizeof(nonce), frame + hdrlen, plen, aad,
|
||||||
aad_len, pos, pos + plen) < 0) {
|
aad_len, pos, pos + plen) < 0) {
|
||||||
os_free(crypt);
|
os_free(crypt);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue