Add support for 16-byte auth tag for AES GCM mode.

This commit is contained in:
jfigus
2014-06-30 19:18:20 +00:00
committed by Travis Cross
parent b9da5149e2
commit 024162cfc9
15 changed files with 275 additions and 39 deletions
+5 -1
View File
@@ -55,7 +55,7 @@ debug_module_t mod_aes_cbc = {
err_status_t
aes_cbc_alloc(cipher_t **c, int key_len) {
aes_cbc_alloc(cipher_t **c, int key_len, int tlen) {
extern cipher_type_t aes_cbc;
uint8_t *pointer;
int tmp;
@@ -384,6 +384,7 @@ cipher_test_case_t aes_cbc_test_case_0 = {
aes_cbc_test_case_0_ciphertext, /* ciphertext */
0,
NULL,
0,
NULL /* pointer to next testcase */
};
@@ -437,6 +438,7 @@ cipher_test_case_t aes_cbc_test_case_1 = {
aes_cbc_test_case_1_ciphertext, /* ciphertext */
0,
NULL,
0,
&aes_cbc_test_case_0 /* pointer to next testcase */
};
@@ -480,6 +482,7 @@ cipher_test_case_t aes_cbc_test_case_2 = {
aes_cbc_test_case_2_ciphertext, /* ciphertext */
0,
NULL,
0,
&aes_cbc_test_case_1 /* pointer to next testcase */
};
@@ -535,6 +538,7 @@ cipher_test_case_t aes_cbc_test_case_3 = {
aes_cbc_test_case_3_ciphertext, /* ciphertext */
0,
NULL,
0,
&aes_cbc_test_case_2 /* pointer to next testcase */
};
+51 -13
View File
@@ -64,11 +64,11 @@ extern cipher_type_t aes_gcm_128_openssl;
extern cipher_type_t aes_gcm_256_openssl;
/*
* For now we only support 8 octet tags. The spec allows for
* optional 12 and 16 byte tags. These longer tag lengths may
* be implemented in the future.
* For now we only support 8 and 16 octet tags. The spec allows for
* optional 12 byte tag, which may be supported in the future.
*/
#define GCM_AUTH_TAG_LEN 8
#define GCM_AUTH_TAG_LEN 16
#define GCM_AUTH_TAG_LEN_8 8
/*
@@ -78,13 +78,14 @@ extern cipher_type_t aes_gcm_256_openssl;
* key length includes the 14 byte salt value that is used when
* initializing the KDF.
*/
err_status_t aes_gcm_openssl_alloc (cipher_t **c, int key_len)
err_status_t aes_gcm_openssl_alloc (cipher_t **c, int key_len, int tlen)
{
aes_gcm_ctx_t *gcm;
int tmp;
uint8_t *allptr;
debug_print(mod_aes_gcm, "allocating cipher with key length %d", key_len);
debug_print(mod_aes_gcm, "allocating cipher with tag length %d", tlen);
/*
* Verify the key_len is valid for one of: AES-128/256
@@ -94,6 +95,11 @@ err_status_t aes_gcm_openssl_alloc (cipher_t **c, int key_len)
return (err_status_bad_param);
}
if (tlen != GCM_AUTH_TAG_LEN &&
tlen != GCM_AUTH_TAG_LEN_8) {
return (err_status_bad_param);
}
/* allocate memory a cipher of type aes_gcm */
tmp = sizeof(cipher_t) + sizeof(aes_gcm_ctx_t);
allptr = crypto_alloc(tmp);
@@ -113,14 +119,14 @@ err_status_t aes_gcm_openssl_alloc (cipher_t **c, int key_len)
(*c)->algorithm = AES_128_GCM;
aes_gcm_128_openssl.ref_count++;
((aes_gcm_ctx_t*)(*c)->state)->key_size = AES_128_KEYSIZE;
((aes_gcm_ctx_t*)(*c)->state)->tag_len = GCM_AUTH_TAG_LEN;
((aes_gcm_ctx_t*)(*c)->state)->tag_len = tlen;
break;
case AES_256_GCM_KEYSIZE_WSALT:
(*c)->type = &aes_gcm_256_openssl;
(*c)->algorithm = AES_256_GCM;
aes_gcm_256_openssl.ref_count++;
((aes_gcm_ctx_t*)(*c)->state)->key_size = AES_256_KEYSIZE;
((aes_gcm_ctx_t*)(*c)->state)->tag_len = GCM_AUTH_TAG_LEN;
((aes_gcm_ctx_t*)(*c)->state)->tag_len = tlen;
break;
}
@@ -405,7 +411,7 @@ uint8_t aes_gcm_test_case_0_aad[20] = {
0xab, 0xad, 0xda, 0xd2
};
uint8_t aes_gcm_test_case_0_ciphertext[68] = {
uint8_t aes_gcm_test_case_0_ciphertext[76] = {
0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
@@ -414,11 +420,12 @@ uint8_t aes_gcm_test_case_0_ciphertext[68] = {
0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
0x3d, 0x58, 0xe0, 0x91,
/* the last 8 bytes are the tag */
/* the last 16 bytes are the tag */
0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47,
};
cipher_test_case_t aes_gcm_test_case_0 = {
cipher_test_case_t aes_gcm_test_case_0a = {
AES_128_GCM_KEYSIZE_WSALT, /* octets in key */
aes_gcm_test_case_0_key, /* key */
aes_gcm_test_case_0_iv, /* packet index */
@@ -428,9 +435,24 @@ cipher_test_case_t aes_gcm_test_case_0 = {
aes_gcm_test_case_0_ciphertext, /* ciphertext + tag */
20, /* octets in AAD */
aes_gcm_test_case_0_aad, /* AAD */
GCM_AUTH_TAG_LEN_8,
NULL /* pointer to next testcase */
};
cipher_test_case_t aes_gcm_test_case_0 = {
AES_128_GCM_KEYSIZE_WSALT, /* octets in key */
aes_gcm_test_case_0_key, /* key */
aes_gcm_test_case_0_iv, /* packet index */
60, /* octets in plaintext */
aes_gcm_test_case_0_plaintext, /* plaintext */
76, /* octets in ciphertext */
aes_gcm_test_case_0_ciphertext, /* ciphertext + tag */
20, /* octets in AAD */
aes_gcm_test_case_0_aad, /* AAD */
GCM_AUTH_TAG_LEN,
&aes_gcm_test_case_0a /* pointer to next testcase */
};
uint8_t aes_gcm_test_case_1_key[AES_256_GCM_KEYSIZE_WSALT] = {
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
0xa5, 0x59, 0x09, 0xc5, 0x54, 0x66, 0x93, 0x1c,
@@ -463,7 +485,7 @@ uint8_t aes_gcm_test_case_1_aad[20] = {
0xab, 0xad, 0xda, 0xd2
};
uint8_t aes_gcm_test_case_1_ciphertext[68] = {
uint8_t aes_gcm_test_case_1_ciphertext[76] = {
0x0b, 0x11, 0xcf, 0xaf, 0x68, 0x4d, 0xae, 0x46,
0xc7, 0x90, 0xb8, 0x8e, 0xb7, 0x6a, 0x76, 0x2a,
0x94, 0x82, 0xca, 0xab, 0x3e, 0x39, 0xd7, 0x86,
@@ -472,11 +494,12 @@ uint8_t aes_gcm_test_case_1_ciphertext[68] = {
0x6d, 0xd7, 0xe2, 0x6a, 0x7d, 0x5f, 0xb4, 0x80,
0xef, 0xef, 0xc5, 0x29, 0x12, 0xd1, 0xaa, 0x10,
0x09, 0xc9, 0x86, 0xc1,
/* the last 8 bytes are the tag */
/* the last 16 bytes are the tag */
0x45, 0xbc, 0x03, 0xe6, 0xe1, 0xac, 0x0a, 0x9f,
0x81, 0xcb, 0x8e, 0x5b, 0x46, 0x65, 0x63, 0x1d,
};
cipher_test_case_t aes_gcm_test_case_1 = {
cipher_test_case_t aes_gcm_test_case_1a = {
AES_256_GCM_KEYSIZE_WSALT, /* octets in key */
aes_gcm_test_case_1_key, /* key */
aes_gcm_test_case_1_iv, /* packet index */
@@ -486,9 +509,24 @@ cipher_test_case_t aes_gcm_test_case_1 = {
aes_gcm_test_case_1_ciphertext, /* ciphertext + tag */
20, /* octets in AAD */
aes_gcm_test_case_1_aad, /* AAD */
GCM_AUTH_TAG_LEN_8,
NULL /* pointer to next testcase */
};
cipher_test_case_t aes_gcm_test_case_1 = {
AES_256_GCM_KEYSIZE_WSALT, /* octets in key */
aes_gcm_test_case_1_key, /* key */
aes_gcm_test_case_1_iv, /* packet index */
60, /* octets in plaintext */
aes_gcm_test_case_1_plaintext, /* plaintext */
76, /* octets in ciphertext */
aes_gcm_test_case_1_ciphertext, /* ciphertext + tag */
20, /* octets in AAD */
aes_gcm_test_case_1_aad, /* AAD */
GCM_AUTH_TAG_LEN,
&aes_gcm_test_case_1a /* pointer to next testcase */
};
/*
* This is the vector function table for this crypto engine.
*/
+2
View File
@@ -516,6 +516,7 @@ cipher_test_case_t aes_icm_test_case_0 = {
aes_icm_test_case_0_ciphertext, /* ciphertext */
0,
NULL,
0,
NULL /* pointer to next testcase */
};
@@ -557,6 +558,7 @@ cipher_test_case_t aes_icm_test_case_1 = {
aes_icm_test_case_1_ciphertext, /* ciphertext */
0,
NULL,
0,
&aes_icm_test_case_0 /* pointer to next testcase */
};
+6 -2
View File
@@ -103,9 +103,10 @@ extern cipher_type_t aes_icm_256;
* The key_len parameter should be one of 30, 38, or 46 for
* AES-128, AES-192, and AES-256 respectively. Note, this key_len
* value is inflated, as it also accounts for the 112 bit salt
* value.
* value. The tlen argument is for the AEAD tag length, which
* isn't used in counter mode.
*/
err_status_t aes_icm_openssl_alloc (cipher_t **c, int key_len, int x)
err_status_t aes_icm_openssl_alloc (cipher_t **c, int key_len, int tlen)
{
aes_icm_ctx_t *icm;
int tmp;
@@ -382,6 +383,7 @@ cipher_test_case_t aes_icm_test_case_0 = {
aes_icm_test_case_0_ciphertext, /* ciphertext */
0,
NULL,
0,
NULL /* pointer to next testcase */
};
@@ -426,6 +428,7 @@ cipher_test_case_t aes_icm_192_test_case_1 = {
aes_icm_192_test_case_1_ciphertext, /* ciphertext */
0,
NULL,
0,
NULL /* pointer to next testcase */
};
@@ -472,6 +475,7 @@ cipher_test_case_t aes_icm_256_test_case_2 = {
aes_icm_256_test_case_2_ciphertext, /* ciphertext */
0,
NULL,
0,
NULL /* pointer to next testcase */
};
+2 -2
View File
@@ -108,7 +108,7 @@ cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data) {
*/
while (test_case != NULL) {
/* allocate cipher */
status = cipher_type_alloc(ct, &c, test_case->key_length_octets);
status = cipher_type_alloc(ct, &c, test_case->key_length_octets, test_case->tag_length_octets);
if (status)
return status;
@@ -307,7 +307,7 @@ cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data) {
/* allocate cipher, using paramaters from the first test case */
test_case = test_data;
status = cipher_type_alloc(ct, &c, test_case->key_length_octets);
status = cipher_type_alloc(ct, &c, test_case->key_length_octets, test_case->tag_length_octets);
if (status)
return status;
+2 -1
View File
@@ -54,7 +54,7 @@
extern debug_module_t mod_cipher;
err_status_t
null_cipher_alloc(cipher_t **c, int key_len) {
null_cipher_alloc(cipher_t **c, int key_len, int tlen) {
extern cipher_type_t null_cipher;
uint8_t *pointer;
@@ -133,6 +133,7 @@ null_cipher_test_0 = {
NULL, /* ciphertext */
0,
NULL,
0,
NULL /* pointer to next testcase */
};
+3 -2
View File
@@ -80,7 +80,7 @@ typedef struct cipher_t *cipher_pointer_t;
*/
typedef err_status_t (*cipher_alloc_func_t)
(cipher_pointer_t *cp, int key_len);
(cipher_pointer_t *cp, int key_len, int tag_len);
/*
* a cipher_init_func_t [re-]initializes a cipher_t with a given key
@@ -148,6 +148,7 @@ typedef struct cipher_test_case_t {
uint8_t *ciphertext; /* ciphertext */
int aad_length_octets; /* octets in AAD */
uint8_t *aad; /* AAD */
int tag_length_octets; /* Length of AEAD tag */
struct cipher_test_case_t *next_test_case; /* pointer to next testcase */
} cipher_test_case_t;
@@ -183,7 +184,7 @@ typedef struct cipher_t {
/* some syntactic sugar on these function types */
#define cipher_type_alloc(ct, c, klen) ((ct)->alloc((c), (klen)))
#define cipher_type_alloc(ct, c, klen, tlen) ((ct)->alloc((c), (klen), (tlen)))
#define cipher_dealloc(c) (((c)->type)->dealloc(c))
+2 -1
View File
@@ -221,7 +221,8 @@ crypto_kernel_load_debug_module(debug_module_t *new_dm);
err_status_t
crypto_kernel_alloc_cipher(cipher_type_id_t id,
cipher_pointer_t *cp,
int key_len);
int key_len,
int tag_len);
/*
* crypto_kernel_alloc_auth(id, ap, key_len, tag_len);
+3 -2
View File
@@ -477,7 +477,8 @@ crypto_kernel_get_cipher_type(cipher_type_id_t id) {
err_status_t
crypto_kernel_alloc_cipher(cipher_type_id_t id,
cipher_pointer_t *cp,
int key_len) {
int key_len,
int tag_len) {
cipher_type_t *ct;
/*
@@ -491,7 +492,7 @@ crypto_kernel_alloc_cipher(cipher_type_id_t id,
if (!ct)
return err_status_fail;
return ((ct)->alloc(cp, key_len));
return ((ct)->alloc(cp, key_len, tag_len));
}
+7 -7
View File
@@ -223,7 +223,7 @@ main(int argc, char *argv[]) {
}
/* do timing and/or buffer_test on null_cipher */
status = cipher_type_alloc(&null_cipher, &c, 0);
status = cipher_type_alloc(&null_cipher, &c, 0, 0);
check_status(status);
status = cipher_init(c, NULL);
@@ -240,7 +240,7 @@ main(int argc, char *argv[]) {
/* run the throughput test on the aes_icm cipher (128-bit key) */
status = cipher_type_alloc(&aes_icm, &c, 30);
status = cipher_type_alloc(&aes_icm, &c, 30, 0);
if (status) {
fprintf(stderr, "error: can't allocate cipher\n");
exit(status);
@@ -262,9 +262,9 @@ main(int argc, char *argv[]) {
/* repeat the tests with 256-bit keys */
#ifndef OPENSSL
status = cipher_type_alloc(&aes_icm, &c, 46);
status = cipher_type_alloc(&aes_icm, &c, 46, 0);
#else
status = cipher_type_alloc(&aes_icm_256, &c, 46);
status = cipher_type_alloc(&aes_icm_256, &c, 46, 0);
#endif
if (status) {
fprintf(stderr, "error: can't allocate cipher\n");
@@ -287,7 +287,7 @@ main(int argc, char *argv[]) {
#ifdef OPENSSL
/* run the throughput test on the aes_gcm_128_openssl cipher */
status = cipher_type_alloc(&aes_gcm_128_openssl, &c, AES_128_GCM_KEYSIZE_WSALT);
status = cipher_type_alloc(&aes_gcm_128_openssl, &c, AES_128_GCM_KEYSIZE_WSALT, 8);
if (status) {
fprintf(stderr, "error: can't allocate GCM 128 cipher\n");
exit(status);
@@ -306,7 +306,7 @@ main(int argc, char *argv[]) {
check_status(status);
/* run the throughput test on the aes_gcm_256_openssl cipher */
status = cipher_type_alloc(&aes_gcm_256_openssl, &c, AES_256_GCM_KEYSIZE_WSALT);
status = cipher_type_alloc(&aes_gcm_256_openssl, &c, AES_256_GCM_KEYSIZE_WSALT, 16);
if (status) {
fprintf(stderr, "error: can't allocate GCM 256 cipher\n");
exit(status);
@@ -479,7 +479,7 @@ cipher_array_alloc_init(cipher_t ***ca, int num_ciphers,
for (i=0; i < num_ciphers; i++) {
/* allocate cipher */
status = cipher_type_alloc(ctype, cipher_array, klen);
status = cipher_type_alloc(ctype, cipher_array, klen, 16);
if (status)
return status;
+4 -4
View File
@@ -77,7 +77,7 @@ main (int argc, char *argv[]) {
/* set buffer to cipher output */
for (i=0; i < 2500; i++)
buffer[i] = 0;
err_check(cipher_type_alloc(&aes_icm, &c, 30));
err_check(cipher_type_alloc(&aes_icm, &c, 30, 0));
err_check(cipher_init(c, key));
err_check(cipher_set_iv(c, &nonce, direction_encrypt));
err_check(cipher_encrypt(c, buffer, &buf_len));
@@ -111,7 +111,7 @@ main (int argc, char *argv[]) {
/* set buffer to cipher output */
for (i=0; i < 2500; i++)
buffer[i] = 0;
err_check(cipher_type_alloc(&aes_icm, &c, 46));
err_check(cipher_type_alloc(&aes_icm, &c, 46, 0));
err_check(cipher_init(c, key));
err_check(cipher_set_iv(c, &nonce, direction_encrypt));
err_check(cipher_encrypt(c, buffer, &buf_len));
@@ -142,7 +142,7 @@ main (int argc, char *argv[]) {
for (i=0; i < 2500; i++) {
buffer[i] = 0;
}
err_check(cipher_type_alloc(&aes_gcm_128_openssl, &c, AES_128_GCM_KEYSIZE_WSALT));
err_check(cipher_type_alloc(&aes_gcm_128_openssl, &c, AES_128_GCM_KEYSIZE_WSALT, 8));
err_check(cipher_init(c, key));
err_check(cipher_set_iv(c, &nonce, direction_encrypt));
err_check(cipher_encrypt(c, buffer, &buf_len));
@@ -171,7 +171,7 @@ main (int argc, char *argv[]) {
for (i=0; i < 2500; i++) {
buffer[i] = 0;
}
err_check(cipher_type_alloc(&aes_gcm_256_openssl, &c, AES_256_GCM_KEYSIZE_WSALT));
err_check(cipher_type_alloc(&aes_gcm_256_openssl, &c, AES_256_GCM_KEYSIZE_WSALT, 16));
err_check(cipher_init(c, key));
err_check(cipher_set_iv(c, &nonce, direction_encrypt));
err_check(cipher_encrypt(c, buffer, &buf_len));