/********************************************************************** Copyright(c) 2011-2016 Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **********************************************************************/ #include #include #include #include // for memcmp #include #include #include "gcm_vectors.h" #include "ossl_helper.h" #include "types.h" //#define GCM_VECTORS_VERBOSE //#define GCM_VECTORS_EXTRA_VERBOSE #ifndef TEST_SEED # define TEST_SEED 0x1234 #endif #ifndef RANDOMS # define RANDOMS 200 #endif #ifndef TEST_LEN # define TEST_LEN 32*1024 #endif #ifndef PAGE_LEN # define PAGE_LEN (4*1024) #endif #if defined(NT_LD) || defined(NT_ST) || defined(NT_LDST) # define ALIGNMENT_MASK (~15) # define OFFSET_BASE_VALUE 16 #ifndef MAX_UNALIGNED # define MAX_UNALIGNED (1) #endif #else # define ALIGNMENT_MASK (~0) # define OFFSET_BASE_VALUE 1 #ifndef MAX_UNALIGNED # define MAX_UNALIGNED (16) #endif #endif void dump_table(char *title, uint8_t * table, uint8_t count) { int i; char const *space = " "; printf("%s%s => {\n", space, title); for (i = 0; i < count; i++) { if (0 == (i & 15)) printf("%s%s", space, space); printf("%2x, ", table[i]); if (15 == (i & 15)) printf("\n"); } printf("%s}\n", space); } void dump_gcm_data(struct gcm_key_data *gkey) { #ifdef GCM_VECTORS_EXTRA_VERBOSE printf("gcm_data {\n"); dump_table("expanded_keys", gkey->expanded_keys, (16 * 11)); dump_table("shifted_hkey_1", gkey->shifted_hkey_1, 16); dump_table("shifted_hkey_2", gkey->shifted_hkey_2, 16); dump_table("shifted_hkey_3", gkey->shifted_hkey_3, 16); dump_table("shifted_hkey_4", gkey->shifted_hkey_4, 16); dump_table("shifted_hkey_5", gkey->shifted_hkey_5, 16); dump_table("shifted_hkey_6", gkey->shifted_hkey_6, 16); dump_table("shifted_hkey_7", gkey->shifted_hkey_7, 16); dump_table("shifted_hkey_8", gkey->shifted_hkey_8, 16); dump_table("shifted_hkey_1_k", gkey->shifted_hkey_1_k, 16); dump_table("shifted_hkey_2_k", gkey->shifted_hkey_2_k, 16); dump_table("shifted_hkey_3_k", gkey->shifted_hkey_3_k, 16); dump_table("shifted_hkey_4_k", gkey->shifted_hkey_4_k, 16); dump_table("shifted_hkey_5_k", gkey->shifted_hkey_5_k, 16); dump_table("shifted_hkey_6_k", gkey->shifted_hkey_6_k, 16); dump_table("shifted_hkey_7_k", gkey->shifted_hkey_7_k, 16); dump_table("shifted_hkey_8_k", gkey->shifted_hkey_8_k, 16); printf("}\n"); #endif //GCM_VECTORS_VERBOSE } void mk_rand_data(uint8_t * data, uint32_t size) { int i; for (i = 0; i < size; i++) { *data++ = rand(); } } int check_data(uint8_t * test, uint8_t * expected, uint64_t len, char *data_name) { int mismatch; int OK = 0; mismatch = memcmp(test, expected, len); if (mismatch) { OK = 1; printf(" expected results don't match %s \t\t", data_name); { uint64_t a; for (a = 0; a < len; a++) { if (test[a] != expected[a]) { printf(" '%x' != '%x' at %lx of %lx\n", test[a], expected[a], a, len); break; } } } } return OK; } int check_vector(struct gcm_key_data *gkey, struct gcm_context_data *gctx, gcm_vector * vector) { uint8_t *pt_test = NULL; uint8_t *ct_test = NULL; uint8_t *o_ct_test = NULL; uint8_t *IV_c = NULL; uint8_t *T_test = NULL; uint8_t *o_T_test = NULL; uint64_t IV_alloc_len = 0; int result; int OK = 0; #ifdef GCM_VECTORS_VERBOSE printf("combination vector Keylen:%d IVlen:%d PTLen:%d AADlen:%d Tlen:%d\n", (int)vector->Klen, (int)vector->IVlen, (int)vector->Plen, (int)vector->Alen, (int)vector->Tlen); #else printf("."); #endif // Allocate space for the calculated ciphertext if (vector->Plen != 0) { pt_test = malloc(vector->Plen); ct_test = malloc(vector->Plen); o_ct_test = malloc(vector->Plen); if ((pt_test == NULL) || (ct_test == NULL) || (o_ct_test == NULL)) { fprintf(stderr, "Can't allocate ciphertext memory\n"); return 1; } } IV_alloc_len = vector->IVlen; // Allocate space for the calculated ciphertext IV_c = malloc(IV_alloc_len); if (IV_c == NULL) { fprintf(stderr, "Can't allocate ciphertext memory\n"); return 1; } memcpy(IV_c, vector->IV, vector->IVlen); T_test = malloc(vector->Tlen); o_T_test = malloc(vector->Tlen); if ((T_test == NULL) || (o_T_test == NULL)) { fprintf(stderr, "Can't allocate tag memory\n"); return 1; } // This is only required once for a given key aes_gcm_pre_128(vector->K, gkey); //// // ISA-l Encrypt //// aes_gcm_enc_128(gkey, gctx, vector->C, vector->P, vector->Plen, IV_c, vector->A, vector->Alen, vector->T, vector->Tlen); openssl_aes_gcm_enc(vector->K, vector->IV, vector->IVlen, vector->A, vector->Alen, o_T_test, vector->Tlen, vector->P, vector->Plen, o_ct_test); OK |= check_data(vector->C, o_ct_test, vector->Plen, "OpenSSL vs ISA-L cypher text (C)"); OK |= check_data(vector->T, o_T_test, vector->Tlen, "OpenSSL vs ISA-L encrypt tag (T)"); memcpy(ct_test, vector->C, vector->Plen); memcpy(pt_test, vector->P, vector->Plen); memset(vector->P, 0, vector->Plen); memcpy(T_test, vector->T, vector->Tlen); memset(vector->T, 0, vector->Tlen); //// // ISA-l Decrypt //// aes_gcm_dec_128(gkey, gctx, vector->P, vector->C, vector->Plen, IV_c, vector->A, vector->Alen, vector->T, vector->Tlen); OK |= check_data(vector->T, o_T_test, vector->Tlen, "OpenSSL vs ISA-L decrypt tag (T)"); OK |= check_data(pt_test, vector->P, vector->Plen, "ISA-L decrypted plain text (P)"); memset(vector->P, 0, vector->Plen); aes_gcm_dec_128(gkey, gctx, vector->P, o_ct_test, vector->Plen, IV_c, vector->A, vector->Alen, vector->T, vector->Tlen); OK |= check_data(pt_test, vector->P, vector->Plen, "ISA-L decrypted plain text (P)"); result = openssl_aes_gcm_dec(vector->K, vector->IV, vector->IVlen, vector->A, vector->Alen, vector->T, vector->Tlen, vector->C, vector->Plen, pt_test); if (-1 == result) printf(" ISA-L->OpenSSL decryption failed Authentication\n"); OK |= (-1 == result); free(T_test); free(o_T_test); free(IV_c); free(pt_test); free(ct_test); free(o_ct_test); return OK; } int check_strm_vector(struct gcm_key_data *gkey, struct gcm_context_data *gctx, gcm_vector * vector, int test_len) { uint8_t *pt_test = NULL; uint8_t *ct_test = NULL; uint8_t *o_ct_test = NULL; uint8_t *IV_c = NULL; uint8_t *T_test = NULL; uint8_t *o_T_test = NULL; uint8_t *stream = NULL; uint64_t IV_alloc_len = 0; int result; int OK = 0; uint32_t last_break; int i; uint8_t *rand_data = NULL; uint64_t length; rand_data = malloc(100); #ifdef GCM_VECTORS_VERBOSE printf("combination vector Keylen:%d IVlen:%d PTLen:%d AADlen:%d Tlen:%d\n", (int)vector->Klen, (int)vector->IVlen, (int)vector->Plen, (int)vector->Alen, (int)vector->Tlen); #else printf("."); #endif // Allocate space for the calculated ciphertext if (vector->Plen != 0) { pt_test = malloc(vector->Plen); ct_test = malloc(vector->Plen); o_ct_test = malloc(vector->Plen); if ((pt_test == NULL) || (ct_test == NULL) || (o_ct_test == NULL)) { fprintf(stderr, "Can't allocate ciphertext memory\n"); return 1; } } IV_alloc_len = vector->IVlen; // Allocate space for the calculated ciphertext IV_c = malloc(IV_alloc_len); if (IV_c == NULL) { fprintf(stderr, "Can't allocate ciphertext memory\n"); return 1; } memcpy(IV_c, vector->IV, vector->IVlen); T_test = malloc(vector->Tlen); o_T_test = malloc(vector->Tlen); if ((T_test == NULL) || (o_T_test == NULL)) { fprintf(stderr, "Can't allocate tag memory\n"); return 1; } // This is only required once for a given key aes_gcm_pre_128(vector->K, gkey); //// // ISA-l Encrypt //// aes_gcm_init_128(gkey, gctx, IV_c, vector->A, vector->Alen); last_break = 0; i = (rand() % test_len / 32) & ALIGNMENT_MASK; while (i < (vector->Plen)) { if (i - last_break != 0) { stream = malloc(i - last_break); memcpy(stream, vector->P + last_break, i - last_break); } aes_gcm_enc_128_update(gkey, gctx, vector->C + last_break, stream, i - last_break); if (i - last_break != 0) free(stream); if (rand() % 1024 == 0) { length = rand() % 100; mk_rand_data(rand_data, length); SHA1(rand_data, length, rand_data); } last_break = i; i = (rand() % test_len / 32) & ALIGNMENT_MASK; } aes_gcm_enc_128_update(gkey, gctx, vector->C + last_break, vector->P + last_break, vector->Plen - last_break); if (gctx->in_length != vector->Plen) printf("%lu, %lu\n", gctx->in_length, vector->Plen); aes_gcm_enc_128_finalize(gkey, gctx, vector->T, vector->Tlen); openssl_aes_gcm_enc(vector->K, vector->IV, vector->IVlen, vector->A, vector->Alen, o_T_test, vector->Tlen, vector->P, vector->Plen, o_ct_test); OK |= check_data(vector->C, o_ct_test, vector->Plen, "OpenSSL vs ISA-L cypher text (C)"); OK |= check_data(vector->T, o_T_test, vector->Tlen, "OpenSSL vs ISA-L encrypt tag (T)"); memcpy(ct_test, vector->C, vector->Plen); memcpy(pt_test, vector->P, vector->Plen); memset(vector->P, 0, vector->Plen); memcpy(T_test, vector->T, vector->Tlen); memset(vector->T, 0, vector->Tlen); //// // ISA-l Decrypt //// last_break = 0; i = 0; aes_gcm_init_128(gkey, gctx, IV_c, vector->A, vector->Alen); while (i < (vector->Plen)) { if (rand() % (test_len / 64) == 0) { if (i - last_break != 0) { stream = malloc(i - last_break); memcpy(stream, vector->C + last_break, i - last_break); } aes_gcm_dec_128_update(gkey, gctx, vector->P + last_break, stream, i - last_break); if (i - last_break != 0) free(stream); if (rand() % 1024 == 0) { length = rand() % 100; mk_rand_data(rand_data, length); SHA1(rand_data, length, rand_data); } last_break = i; } if (rand() % 1024 != 0) i++; } aes_gcm_dec_128_update(gkey, gctx, vector->P + last_break, vector->C + last_break, vector->Plen - last_break); aes_gcm_dec_128_finalize(gkey, gctx, vector->T, vector->Tlen); OK |= check_data(vector->T, o_T_test, vector->Tlen, "OpenSSL vs ISA-L decrypt tag (T)"); OK |= check_data(pt_test, vector->P, vector->Plen, "ISA-L decrypted plain text (P)"); memset(vector->P, 0, vector->Plen); aes_gcm_dec_128(gkey, gctx, vector->P, o_ct_test, vector->Plen, IV_c, vector->A, vector->Alen, vector->T, vector->Tlen); OK |= check_data(pt_test, vector->P, vector->Plen, "ISA-L decrypted plain text (P)"); result = openssl_aes_gcm_dec(vector->K, vector->IV, vector->IVlen, vector->A, vector->Alen, vector->T, vector->Tlen, vector->C, vector->Plen, pt_test); if (-1 == result) printf(" ISA-L->OpenSSL decryption failed Authentication\n"); OK |= (-1 == result); free(T_test); free(o_T_test); free(IV_c); free(pt_test); free(ct_test); free(o_ct_test); free(rand_data); return OK; } int check_strm_vector2(struct gcm_key_data *gkey, struct gcm_context_data *gctx, gcm_vector * vector, int length, int start, int breaks) { uint8_t *pt_test = NULL; uint8_t *ct_test = NULL; uint8_t *o_ct_test = NULL; uint8_t *IV_c = NULL; uint8_t *T_test = NULL; uint8_t *o_T_test = NULL; uint8_t *stream = NULL; uint64_t IV_alloc_len = 0; int result; int OK = 0; uint32_t last_break = 0; int i = length; uint8_t *rand_data = NULL; rand_data = malloc(100); #ifdef GCM_VECTORS_VERBOSE printf("combination vector Keylen:%d IVlen:%d PTLen:%d AADlen:%d Tlen:%d\n", (int)vector->Klen, (int)vector->IVlen, (int)vector->Plen, (int)vector->Alen, (int)vector->Tlen); #else printf("."); #endif // Allocate space for the calculated ciphertext if (vector->Plen != 0) { pt_test = malloc(vector->Plen); ct_test = malloc(vector->Plen); o_ct_test = malloc(vector->Plen); if ((pt_test == NULL) || (ct_test == NULL) || (o_ct_test == NULL)) { fprintf(stderr, "Can't allocate ciphertext memory\n"); return 1; } } IV_alloc_len = vector->IVlen; // Allocate space for the calculated ciphertext IV_c = malloc(IV_alloc_len); if (IV_c == NULL) { fprintf(stderr, "Can't allocate ciphertext memory\n"); return 1; } memcpy(IV_c, vector->IV, vector->IVlen); T_test = malloc(vector->Tlen); o_T_test = malloc(vector->Tlen); if ((T_test == NULL) || (o_T_test == NULL)) { fprintf(stderr, "Can't allocate tag memory\n"); return 1; } // This is only required once for a given key aes_gcm_pre_128(vector->K, gkey); //// // ISA-l Encrypt //// aes_gcm_enc_128(gkey, gctx, vector->C, vector->P, vector->Plen, IV_c, vector->A, vector->Alen, vector->T, vector->Tlen); aes_gcm_init_128(gkey, gctx, IV_c, vector->A, vector->Alen); while (i < (vector->Plen)) { if (i - last_break != 0) { stream = malloc(i - last_break); memcpy(stream, vector->P + last_break, i - last_break); } aes_gcm_enc_128_update(gkey, gctx, vector->C + last_break, stream, i - last_break); if (i - last_break != 0) free(stream); last_break = i; i = i + (length - start) / breaks; } aes_gcm_enc_128_update(gkey, gctx, vector->C + last_break, vector->P + last_break, vector->Plen - last_break); aes_gcm_enc_128_finalize(gkey, gctx, vector->T, vector->Tlen); openssl_aes_gcm_enc(vector->K, vector->IV, vector->IVlen, vector->A, vector->Alen, o_T_test, vector->Tlen, vector->P, vector->Plen, o_ct_test); OK |= check_data(vector->C, o_ct_test, vector->Plen, "OpenSSL vs ISA-L cypher text (C)"); OK |= check_data(vector->T, o_T_test, vector->Tlen, "OpenSSL vs ISA-L encrypt tag (T)"); memcpy(ct_test, vector->C, vector->Plen); memcpy(pt_test, vector->P, vector->Plen); memset(vector->P, 0, vector->Plen); memcpy(T_test, vector->T, vector->Tlen); memset(vector->T, 0, vector->Tlen); //// // ISA-l Decrypt //// last_break = 0; i = length; aes_gcm_init_128(gkey, gctx, IV_c, vector->A, vector->Alen); while (i < (vector->Plen)) { if (i - last_break != 0) { stream = malloc(i - last_break); memcpy(stream, vector->C + last_break, i - last_break); } aes_gcm_dec_128_update(gkey, gctx, vector->P + last_break, stream, i - last_break); if (i - last_break != 0) free(stream); last_break = i; i = i + (length - start) / breaks; } aes_gcm_dec_128_update(gkey, gctx, vector->P + last_break, vector->C + last_break, vector->Plen - last_break); aes_gcm_dec_128_finalize(gkey, gctx, vector->T, vector->Tlen); OK |= check_data(vector->T, o_T_test, vector->Tlen, "OpenSSL vs ISA-L decrypt tag (T)"); OK |= check_data(pt_test, vector->P, vector->Plen, "ISA-L decrypted plain text (P)"); memset(vector->P, 0, vector->Plen); aes_gcm_dec_128(gkey, gctx, vector->P, o_ct_test, vector->Plen, IV_c, vector->A, vector->Alen, vector->T, vector->Tlen); OK |= check_data(pt_test, vector->P, vector->Plen, "ISA-L decrypted plain text (P)"); result = openssl_aes_gcm_dec(vector->K, vector->IV, vector->IVlen, vector->A, vector->Alen, vector->T, vector->Tlen, vector->C, vector->Plen, pt_test); if (-1 == result) printf(" ISA-L->OpenSSL decryption failed Authentication\n"); OK |= (-1 == result); free(rand_data); return OK; } int check_strm_vector_efence(struct gcm_key_data *gkey, struct gcm_context_data *gctx, gcm_vector * vector) { uint8_t *pt_test = NULL; uint8_t *ct_test = NULL; uint8_t *o_ct_test = NULL; uint8_t *IV_c = NULL; uint8_t *T_test = NULL; uint8_t *o_T_test = NULL; uint8_t *stream = NULL; uint64_t IV_alloc_len = 0; int result; int OK = 0; uint32_t last_break = 0; int i = 1; uint8_t *rand_data = NULL; uint64_t length; rand_data = malloc(100); #ifdef GCM_VECTORS_VERBOSE printf("combination vector Keylen:%d IVlen:%d PTLen:%d AADlen:%d Tlen:%d\n", (int)vector->Klen, (int)vector->IVlen, (int)vector->Plen, (int)vector->Alen, (int)vector->Tlen); #else printf("."); #endif // Allocate space for the calculated ciphertext if (vector->Plen != 0) { pt_test = malloc(vector->Plen); ct_test = malloc(vector->Plen); o_ct_test = malloc(vector->Plen); if ((pt_test == NULL) || (ct_test == NULL) || (o_ct_test == NULL)) { fprintf(stderr, "Can't allocate ciphertext memory\n"); return 1; } } IV_alloc_len = vector->IVlen; // Allocate space for the calculated ciphertext IV_c = malloc(IV_alloc_len); if (IV_c == NULL) { fprintf(stderr, "Can't allocate ciphertext memory\n"); return 1; } memcpy(IV_c, vector->IV, vector->IVlen); T_test = malloc(vector->Tlen); o_T_test = malloc(vector->Tlen); if ((T_test == NULL) || (o_T_test == NULL)) { fprintf(stderr, "Can't allocate tag memory\n"); return 1; } // This is only required once for a given key aes_gcm_pre_128(vector->K, gkey); //// // ISA-l Encrypt //// aes_gcm_init_128(gkey, gctx, IV_c, vector->A, vector->Alen); while (i < vector->Plen) { if (rand() % 2000 == 0 || i - last_break > PAGE_LEN / 2) { stream = malloc(PAGE_LEN); i = i & ALIGNMENT_MASK; memcpy(stream + PAGE_LEN - (i - last_break), vector->P + last_break, i - last_break); aes_gcm_enc_128_update(gkey, gctx, vector->C + last_break, stream + PAGE_LEN - (i - last_break), i - last_break); free(stream); if (rand() % 1024 == 0) { length = rand() % 100; mk_rand_data(rand_data, length); SHA1(rand_data, length, rand_data); } last_break = i; } if (rand() % 1024 != 0) i++; } aes_gcm_enc_128_update(gkey, gctx, vector->C + last_break, vector->P + last_break, vector->Plen - last_break); aes_gcm_enc_128_finalize(gkey, gctx, vector->T, vector->Tlen); openssl_aes_gcm_enc(vector->K, vector->IV, vector->IVlen, vector->A, vector->Alen, o_T_test, vector->Tlen, vector->P, vector->Plen, o_ct_test); OK |= check_data(vector->C, o_ct_test, vector->Plen, "OpenSSL vs ISA-L cypher text (C)"); OK |= check_data(vector->T, o_T_test, vector->Tlen, "OpenSSL vs ISA-L encrypt tag (T)"); memcpy(ct_test, vector->C, vector->Plen); memcpy(pt_test, vector->P, vector->Plen); memset(vector->P, 0, vector->Plen); memcpy(T_test, vector->T, vector->Tlen); memset(vector->T, 0, vector->Tlen); //// // ISA-l Decrypt //// last_break = 0; i = 0; aes_gcm_init_128(gkey, gctx, IV_c, vector->A, vector->Alen); while (i < vector->Plen) { if (rand() % 2000 == 0 || i - last_break > PAGE_LEN / 2) { stream = malloc(PAGE_LEN); i = i & ALIGNMENT_MASK; memcpy(stream + PAGE_LEN - (i - last_break), vector->C + last_break, i - last_break); aes_gcm_dec_128_update(gkey, gctx, vector->P + last_break, stream + PAGE_LEN - (i - last_break), i - last_break); free(stream); if (rand() % 1024 == 0) { length = rand() % 100; mk_rand_data(rand_data, length); SHA1(rand_data, length, rand_data); } last_break = i; } if (rand() % 1024 != 0) i++; } aes_gcm_dec_128_update(gkey, gctx, vector->P + last_break, vector->C + last_break, vector->Plen - last_break); aes_gcm_dec_128_finalize(gkey, gctx, vector->T, vector->Tlen); OK |= check_data(vector->T, o_T_test, vector->Tlen, "OpenSSL vs ISA-L decrypt tag (T)"); OK |= check_data(pt_test, vector->P, vector->Plen, "ISA-L decrypted plain text (P)"); memset(vector->P, 0, vector->Plen); aes_gcm_dec_128(gkey, gctx, vector->P, o_ct_test, vector->Plen, IV_c, vector->A, vector->Alen, vector->T, vector->Tlen); OK |= check_data(pt_test, vector->P, vector->Plen, "ISA-L decrypted plain text (P)"); result = openssl_aes_gcm_dec(vector->K, vector->IV, vector->IVlen, vector->A, vector->Alen, vector->T, vector->Tlen, vector->C, vector->Plen, pt_test); if (-1 == result) printf(" ISA-L->OpenSSL decryption failed Authentication\n"); OK |= (-1 == result); free(T_test); free(o_T_test); free(IV_c); free(pt_test); free(ct_test); free(o_ct_test); free(rand_data); return OK; } int check_256_vector(struct gcm_key_data *gkey, struct gcm_context_data *gctx, gcm_vector * vector) { uint8_t *pt_test = NULL; uint8_t *ct_test = NULL; uint8_t *o_ct_test = NULL; uint8_t *IV_c = NULL; uint8_t *T_test = NULL; uint8_t *o_T_test = NULL; uint64_t IV_alloc_len = 0; int result; int OK = 0; #ifdef GCM_VECTORS_VERBOSE printf("combination vector Keylen:%d IVlen:%d PTLen:%d AADlen:%d Tlen:%d\n", (int)vector->Klen, (int)vector->IVlen, (int)vector->Plen, (int)vector->Alen, (int)vector->Tlen); #else printf("."); #endif // Allocate space for the calculated ciphertext if (vector->Plen != 0) { pt_test = malloc(vector->Plen); ct_test = malloc(vector->Plen); o_ct_test = malloc(vector->Plen); if ((pt_test == NULL) || (ct_test == NULL) || (o_ct_test == NULL)) { fprintf(stderr, "Can't allocate ciphertext memory\n"); return 1; } } IV_alloc_len = vector->IVlen; // Allocate space for the calculated ciphertext IV_c = malloc(IV_alloc_len); if (IV_c == NULL) { fprintf(stderr, "Can't allocate ciphertext memory\n"); return 1; } memcpy(IV_c, vector->IV, vector->IVlen); T_test = malloc(vector->Tlen); o_T_test = malloc(vector->Tlen); if ((T_test == NULL) || (o_T_test == NULL)) { fprintf(stderr, "Can't allocate tag memory\n"); return 1; } // This is only required once for a given key aes_gcm_pre_256(vector->K, gkey); //// // ISA-l Encrypt //// aes_gcm_enc_256(gkey, gctx, vector->C, vector->P, vector->Plen, IV_c, vector->A, vector->Alen, vector->T, vector->Tlen); openssl_aes_256_gcm_enc(vector->K, vector->IV, vector->IVlen, vector->A, vector->Alen, o_T_test, vector->Tlen, vector->P, vector->Plen, o_ct_test); OK |= check_data(vector->C, o_ct_test, vector->Plen, "OpenSSL vs ISA-L cypher text (C)"); OK |= check_data(vector->T, o_T_test, vector->Tlen, "OpenSSL vs ISA-L encrypt tag (T)"); memcpy(ct_test, vector->C, vector->Plen); memcpy(pt_test, vector->P, vector->Plen); memset(vector->P, 0, vector->Plen); memcpy(T_test, vector->T, vector->Tlen); memset(vector->T, 0, vector->Tlen); //// // ISA-l Decrypt //// aes_gcm_dec_256(gkey, gctx, vector->P, vector->C, vector->Plen, IV_c, vector->A, vector->Alen, vector->T, vector->Tlen); OK |= check_data(vector->T, T_test, vector->Tlen, "ISA-L decrypt vs encrypt tag (T)"); OK |= check_data(vector->T, o_T_test, vector->Tlen, "OpenSSL vs ISA-L decrypt tag (T)"); OK |= check_data(pt_test, vector->P, vector->Plen, "ISA-L decrypted ISA-L plain text (P)"); memset(vector->P, 0, vector->Plen); aes_gcm_dec_256(gkey, gctx, vector->P, o_ct_test, vector->Plen, IV_c, vector->A, vector->Alen, vector->T, vector->Tlen); OK |= check_data(pt_test, vector->P, vector->Plen, "ISA-L decrypted OpenSSL plain text (P)"); result = openssl_aes_256_gcm_dec(vector->K, vector->IV, vector->IVlen, vector->A, vector->Alen, vector->T, vector->Tlen, vector->C, vector->Plen, pt_test); if (-1 == result) printf(" ISA-L->OpenSSL decryption failed Authentication\n"); OK |= (-1 == result); free(T_test); free(o_T_test); free(IV_c); free(pt_test); free(ct_test); free(o_ct_test); return OK; } int check_256_strm_vector(struct gcm_key_data *gkey, struct gcm_context_data *gctx, gcm_vector * vector, int test_len) { uint8_t *pt_test = NULL; uint8_t *ct_test = NULL; uint8_t *o_ct_test = NULL; uint8_t *IV_c = NULL; uint8_t *T_test = NULL; uint8_t *o_T_test = NULL; uint8_t *stream = NULL; uint64_t IV_alloc_len = 0; int result; int OK = 0; uint32_t last_break; int i; uint8_t *rand_data = NULL; uint64_t length; rand_data = malloc(100); #ifdef GCM_VECTORS_VERBOSE printf("combination vector Keylen:%d IVlen:%d PTLen:%d AADlen:%d Tlen:%d\n", (int)vector->Klen, (int)vector->IVlen, (int)vector->Plen, (int)vector->Alen, (int)vector->Tlen); #else printf("."); #endif // Allocate space for the calculated ciphertext if (vector->Plen != 0) { pt_test = malloc(vector->Plen); ct_test = malloc(vector->Plen); o_ct_test = malloc(vector->Plen); if ((pt_test == NULL) || (ct_test == NULL) || (o_ct_test == NULL)) { fprintf(stderr, "Can't allocate ciphertext memory\n"); return 1; } } IV_alloc_len = vector->IVlen; // Allocate space for the calculated ciphertext IV_c = malloc(IV_alloc_len); if (IV_c == NULL) { fprintf(stderr, "Can't allocate ciphertext memory\n"); return 1; } memcpy(IV_c, vector->IV, vector->IVlen); T_test = malloc(vector->Tlen); o_T_test = malloc(vector->Tlen); if ((T_test == NULL) || (o_T_test == NULL)) { fprintf(stderr, "Can't allocate tag memory\n"); return 1; } // This is only required once for a given key aes_gcm_pre_256(vector->K, gkey); //// // ISA-l Encrypt //// aes_gcm_init_256(gkey, gctx, IV_c, vector->A, vector->Alen); last_break = 0; i = (rand() % test_len / 32) & ALIGNMENT_MASK; while (i < (vector->Plen)) { if (i - last_break != 0) { stream = malloc(i - last_break); memcpy(stream, vector->P + last_break, i - last_break); } aes_gcm_enc_256_update(gkey, gctx, vector->C + last_break, stream, i - last_break); if (i - last_break != 0) free(stream); if (rand() % 1024 == 0) { length = rand() % 100; mk_rand_data(rand_data, length); SHA1(rand_data, length, rand_data); } last_break = i; i += (rand() % test_len / 32) & ALIGNMENT_MASK; } aes_gcm_enc_256_update(gkey, gctx, vector->C + last_break, vector->P + last_break, vector->Plen - last_break); if (gctx->in_length != vector->Plen) printf("%lu, %lu\n", gctx->in_length, vector->Plen); aes_gcm_enc_256_finalize(gkey, gctx, vector->T, vector->Tlen); openssl_aes_256_gcm_enc(vector->K, vector->IV, vector->IVlen, vector->A, vector->Alen, o_T_test, vector->Tlen, vector->P, vector->Plen, o_ct_test); OK |= check_data(vector->C, o_ct_test, vector->Plen, "OpenSSL vs ISA-L cypher text (C)"); OK |= check_data(vector->T, o_T_test, vector->Tlen, "OpenSSL vs ISA-L encrypt tag (T)"); memcpy(ct_test, vector->C, vector->Plen); memcpy(pt_test, vector->P, vector->Plen); memset(vector->P, 0, vector->Plen); memcpy(T_test, vector->T, vector->Tlen); memset(vector->T, 0, vector->Tlen); //// // ISA-l Decrypt //// last_break = 0; i += (rand() % test_len / 32) & ALIGNMENT_MASK; aes_gcm_init_256(gkey, gctx, IV_c, vector->A, vector->Alen); while (i < (vector->Plen)) { if (i - last_break != 0) { stream = malloc(i - last_break); memcpy(stream, vector->C + last_break, i - last_break); } aes_gcm_dec_256_update(gkey, gctx, vector->P + last_break, stream, i - last_break); if (i - last_break != 0) free(stream); if (rand() % 1024 == 0) { length = rand() % 100; mk_rand_data(rand_data, length); SHA1(rand_data, length, rand_data); } last_break = i; i += (rand() % test_len / 32) & ALIGNMENT_MASK; } aes_gcm_dec_256_update(gkey, gctx, vector->P + last_break, vector->C + last_break, vector->Plen - last_break); aes_gcm_dec_256_finalize(gkey, gctx, vector->T, vector->Tlen); OK |= check_data(vector->T, T_test, vector->Tlen, "ISA-L decrypt vs encrypt tag (T)"); OK |= check_data(vector->T, o_T_test, vector->Tlen, "OpenSSL vs ISA-L decrypt tag (T)"); OK |= check_data(pt_test, vector->P, vector->Plen, "ISA-L decrypted ISA-L plain text (P)"); memset(vector->P, 0, vector->Plen); aes_gcm_dec_256(gkey, gctx, vector->P, o_ct_test, vector->Plen, IV_c, vector->A, vector->Alen, vector->T, vector->Tlen); OK |= check_data(pt_test, vector->P, vector->Plen, "ISA-L decrypted OpenSSL plain text (P)"); result = openssl_aes_256_gcm_dec(vector->K, vector->IV, vector->IVlen, vector->A, vector->Alen, vector->T, vector->Tlen, vector->C, vector->Plen, pt_test); if (-1 == result) printf(" ISA-L->OpenSSL decryption failed Authentication\n"); OK |= (-1 == result); free(T_test); free(o_T_test); free(IV_c); free(pt_test); free(ct_test); free(o_ct_test); return OK; } int test_gcm_strm_efence(void) { gcm_vector test; int tag_len = 8; int t = 0; struct gcm_key_data *gkey = NULL; struct gcm_context_data *gctx = NULL; gkey = malloc(sizeof(struct gcm_key_data)); gctx = malloc(sizeof(struct gcm_context_data)); if (NULL == gkey || NULL == gctx) return 1; printf("AES GCM random efence test vectors with random stream:"); for (t = 0; RANDOMS > t; t++) { int Plen = (rand() % TEST_LEN); //lengths must be a multiple of 4 bytes int aad_len = (rand() % TEST_LEN); int offset = (rand() % MAX_UNALIGNED); if (offset == 0 && aad_len == 0) offset = OFFSET_BASE_VALUE; if (0 == (t % 25)) printf("\n"); if (0 == (t % 10)) fflush(0); test.P = NULL; test.C = NULL; test.A = NULL; test.T = NULL; test.Plen = Plen; if (test.Plen + offset != 0) { test.P = malloc(test.Plen + offset); test.C = malloc(test.Plen + offset); } else { //This else clause is here because openssl 1.0.1k does not handle NULL pointers test.P = malloc(16); test.C = malloc(16); } test.K = malloc(GCM_128_KEY_LEN + offset); test.Klen = GCM_128_KEY_LEN; test.IV = malloc(GCM_IV_DATA_LEN + offset); test.IVlen = GCM_IV_DATA_LEN; test.A = malloc(aad_len + offset); test.Alen = aad_len; test.T = malloc(MAX_TAG_LEN + offset); if ((NULL == test.P && test.Plen != 0) || (NULL == test.K) || (NULL == test.IV)) { printf("malloc of testsize:0x%x failed\n", Plen); return 1; } test.P += offset; test.C += offset; test.K += offset; test.IV += offset; test.A += offset; test.T += offset; mk_rand_data(test.P, test.Plen); mk_rand_data(test.K, test.Klen); mk_rand_data(test.IV, test.IVlen); mk_rand_data(test.A, test.Alen); // single Key length of 128bits/16bytes supported // single IV length of 96bits/12bytes supported // Tag lengths of 8, 12 or 16 for (tag_len = 8; tag_len <= MAX_TAG_LEN;) { test.Tlen = tag_len; if (0 != check_strm_vector_efence(gkey, gctx, &test)) return 1; tag_len += 4; //supported lengths are 8, 12 or 16 } test.A -= offset; free(test.A); test.C -= offset; free(test.C); test.IV -= offset; free(test.IV); test.K -= offset; free(test.K); test.P -= offset; free(test.P); test.T -= offset; free(test.T); } printf("\n"); free(gkey); free(gctx); return 0; } int test_gcm_strm_combinations(int test_len) { gcm_vector test; int tag_len = 8; int t = 0; uint8_t *gkeytemp = NULL; struct gcm_key_data *gkey = NULL; struct gcm_context_data *gctx = NULL; gkeytemp = malloc(sizeof(struct gcm_key_data) + 16); gctx = malloc(sizeof(struct gcm_context_data)); gkey = (struct gcm_key_data *)(gkeytemp + rand() % 16); if (NULL == gkey || NULL == gctx) return 1; printf("AES GCM random test vectors with random stream of average size %d:", test_len / 64); for (t = 0; RANDOMS > t; t++) { int Plen = 0; // (rand() % test_len); //lengths must be a multiple of 4 bytes int aad_len = (rand() % test_len); int offset = (rand() % MAX_UNALIGNED); if (offset == 0 && aad_len == 0) offset = OFFSET_BASE_VALUE; if (0 == (t % 25)) printf("\n"); if (0 == (t % 10)) fflush(0); test.P = NULL; test.C = NULL; test.A = NULL; test.T = NULL; test.Plen = Plen; if (test.Plen + offset != 0) { test.P = malloc(test.Plen + offset); test.C = malloc(test.Plen + offset); } else { //This else clause is here because openssl 1.0.1k does not handle NULL pointers test.P = malloc(16); test.C = malloc(16); } test.K = malloc(GCM_128_KEY_LEN + offset); test.Klen = GCM_128_KEY_LEN; test.IV = malloc(GCM_IV_DATA_LEN + offset); test.IVlen = GCM_IV_DATA_LEN; test.A = malloc(aad_len + offset); test.Alen = aad_len; test.T = malloc(MAX_TAG_LEN + offset); if ((NULL == test.P && test.Plen != 0) || (NULL == test.K) || (NULL == test.IV)) { printf("malloc of testsize:0x%x failed\n", Plen); return 1; } test.P += offset; test.C += offset; test.K += offset; test.IV += offset; test.A += offset; test.T += offset; mk_rand_data(test.P, test.Plen); mk_rand_data(test.K, test.Klen); mk_rand_data(test.IV, test.IVlen); mk_rand_data(test.A, test.Alen); // single Key length of 128bits/16bytes supported // single IV length of 96bits/12bytes supported // Tag lengths of 8, 12 or 16 for (tag_len = 8; tag_len <= MAX_TAG_LEN;) { test.Tlen = tag_len; if (0 != check_strm_vector(gkey, gctx, &test, test_len)) return 1; tag_len += 4; //supported lengths are 8, 12 or 16 } test.A -= offset; free(test.A); test.C -= offset; free(test.C); test.IV -= offset; free(test.IV); test.K -= offset; free(test.K); test.P -= offset; free(test.P); test.T -= offset; free(test.T); } printf("\n"); free(gkeytemp); free(gctx); return 0; } int test_gcm_combinations(void) { gcm_vector test; int tag_len = 8; int t = 0; struct gcm_key_data *gkey = NULL; struct gcm_context_data *gctx = NULL; gkey = malloc(sizeof(struct gcm_key_data)); gctx = malloc(sizeof(struct gcm_context_data)); if (NULL == gkey || NULL == gctx) return 1; printf("AES GCM random test vectors:"); for (t = 0; RANDOMS > t; t++) { int Plen = (rand() % TEST_LEN); //lengths must be a multiple of 4 bytes int aad_len = (rand() % TEST_LEN); int offset = (rand() % MAX_UNALIGNED); if (offset == 0 && aad_len == 0) offset = OFFSET_BASE_VALUE; if (0 == (t % 25)) printf("\n"); if (0 == (t % 10)) fflush(0); test.P = NULL; test.C = NULL; test.A = NULL; test.T = NULL; test.Plen = Plen; if (test.Plen + offset != 0) { test.P = malloc(test.Plen + offset); test.C = malloc(test.Plen + offset); } else { //This else clause is here because openssl 1.0.1k does not handle NULL pointers test.P = malloc(16); test.C = malloc(16); } test.K = malloc(GCM_128_KEY_LEN + offset); test.Klen = GCM_128_KEY_LEN; test.IV = malloc(GCM_IV_DATA_LEN + offset); test.IVlen = GCM_IV_DATA_LEN; test.A = malloc(aad_len + offset); test.Alen = aad_len; test.T = malloc(MAX_TAG_LEN + offset); if ((NULL == test.P && test.Plen != 0) || (NULL == test.K) || (NULL == test.IV)) { printf("malloc of testsize:0x%x failed\n", Plen); return 1; } test.P += offset; test.C += offset; test.K += offset; test.IV += offset; test.A += offset; test.T += offset; mk_rand_data(test.P, test.Plen); mk_rand_data(test.K, test.Klen); mk_rand_data(test.IV, test.IVlen); mk_rand_data(test.A, test.Alen); // single Key length of 128bits/16bytes supported // single IV length of 96bits/12bytes supported // Tag lengths of 8, 12 or 16 for (tag_len = 8; tag_len <= MAX_TAG_LEN;) { test.Tlen = tag_len; if (0 != check_vector(gkey, gctx, &test)) return 1; tag_len += 4; //supported lengths are 8, 12 or 16 } test.A -= offset; free(test.A); test.C -= offset; free(test.C); test.IV -= offset; free(test.IV); test.K -= offset; free(test.K); test.P -= offset; free(test.P); test.T -= offset; free(test.T); } printf("\n"); free(gkey); free(gctx); return 0; } int test_gcm256_combinations(void) { gcm_vector test; int tag_len = 8; int t = 0; struct gcm_key_data *gkey = NULL; struct gcm_context_data *gctx = NULL; gkey = malloc(sizeof(struct gcm_key_data)); gctx = malloc(sizeof(struct gcm_context_data)); if (NULL == gkey || NULL == gctx) return 1; printf("AES-GCM-256 random test vectors:"); for (t = 0; RANDOMS > t; t++) { int Plen = (rand() % TEST_LEN); //lengths must be a multiple of 4 bytes int aad_len = (rand() % TEST_LEN); int offset = (rand() % MAX_UNALIGNED); if (offset == 0 && aad_len == 0) offset = OFFSET_BASE_VALUE; if (0 == (t % 25)) printf("\n"); if (0 == (t % 10)) fflush(0); test.P = NULL; test.C = NULL; test.A = NULL; test.T = NULL; test.Plen = Plen; if (test.Plen + offset != 0) { test.P = malloc(test.Plen + offset); test.C = malloc(test.Plen + offset); } else { //This else clause is here because openssl 1.0.1k does not handle NULL pointers test.P = malloc(16); test.C = malloc(16); } test.K = malloc(GCM_256_KEY_LEN + offset); test.Klen = GCM_256_KEY_LEN; test.IV = malloc(GCM_IV_DATA_LEN + offset); test.IVlen = GCM_IV_DATA_LEN; test.A = malloc(aad_len + offset); test.Alen = aad_len; test.T = malloc(MAX_TAG_LEN + offset); if ((NULL == test.P && test.Plen != 0) || (NULL == test.K) || (NULL == test.IV)) { printf("malloc of testsize:0x%x failed\n", Plen); return 1; } test.P += offset; test.C += offset; test.K += offset; test.IV += offset; test.A += offset; test.T += offset; mk_rand_data(test.P, test.Plen); mk_rand_data(test.K, test.Klen); mk_rand_data(test.IV, test.IVlen); mk_rand_data(test.A, test.Alen); // single Key length of 128bits/16bytes supported // single IV length of 96bits/12bytes supported // Tag lengths of 8, 12 or 16 for (tag_len = 8; tag_len <= MAX_TAG_LEN;) { test.Tlen = tag_len; if (0 != check_256_vector(gkey, gctx, &test)) return 1; tag_len += 4; //supported lengths are 8, 12 or 16 } test.A -= offset; free(test.A); test.C -= offset; free(test.C); test.IV -= offset; free(test.IV); test.K -= offset; free(test.K); test.P -= offset; free(test.P); test.T -= offset; free(test.T); } printf("\n"); free(gkey); free(gctx); return 0; } int test_gcm256_strm_combinations(int test_len) { gcm_vector test; int tag_len = 8; int t = 0; uint8_t *gkeytemp = NULL; struct gcm_key_data *gkey = NULL; struct gcm_context_data *gctx = NULL; gkeytemp = malloc(sizeof(struct gcm_key_data) + 16); gctx = malloc(sizeof(struct gcm_context_data)); gkey = (struct gcm_key_data *)(gkeytemp + rand() % 16); if (NULL == gkey || NULL == gctx) return 1; printf("AES-GCM-256 random test vectors with random stream of average size %d:", test_len / 64); for (t = 0; RANDOMS > t; t++) { int Plen = (rand() % test_len); //lengths must be a multiple of 4 bytes int aad_len = (rand() % test_len); int offset = (rand() % MAX_UNALIGNED); if (offset == 0 && aad_len == 0) offset = OFFSET_BASE_VALUE; if (0 == (t % 25)) printf("\n"); if (0 == (t % 10)) fflush(0); test.P = NULL; test.C = NULL; test.A = NULL; test.T = NULL; test.Plen = Plen; if (test.Plen + offset != 0) { test.P = malloc(test.Plen + offset); test.C = malloc(test.Plen + offset); } else { //This else clause is here because openssl 1.0.1k does not handle NULL pointers test.P = malloc(16); test.C = malloc(16); } test.K = malloc(GCM_256_KEY_LEN + offset); test.Klen = GCM_256_KEY_LEN; test.IV = malloc(GCM_IV_DATA_LEN + offset); test.IVlen = GCM_IV_DATA_LEN; test.A = malloc(aad_len + offset); test.Alen = aad_len; test.T = malloc(MAX_TAG_LEN + offset); if ((NULL == test.P && test.Plen != 0) || (NULL == test.K) || (NULL == test.IV)) { printf("malloc of testsize:0x%x failed\n", Plen); return 1; } test.P += offset; test.C += offset; test.K += offset; test.IV += offset; test.A += offset; test.T += offset; mk_rand_data(test.P, test.Plen); mk_rand_data(test.K, test.Klen); mk_rand_data(test.IV, test.IVlen); mk_rand_data(test.A, test.Alen); // single Key length of 128bits/16bytes supported // single IV length of 96bits/12bytes supported // Tag lengths of 8, 12 or 16 for (tag_len = 8; tag_len <= MAX_TAG_LEN;) { test.Tlen = tag_len; if (0 != check_256_strm_vector(gkey, gctx, &test, test_len)) return 1; tag_len += 4; //supported lengths are 8, 12 or 16 } test.A -= offset; free(test.A); test.C -= offset; free(test.C); test.IV -= offset; free(test.IV); test.K -= offset; free(test.K); test.P -= offset; free(test.P); test.T -= offset; free(test.T); } printf("\n"); free(gkeytemp); free(gctx); return 0; } // // place all data to end at a page boundary to check for read past the end // int test_gcm_efence(void) { gcm_vector test; int offset = 0; gcm_key_size key_len; struct gcm_key_data *gkey = NULL; struct gcm_context_data *gctx = NULL; uint8_t *P, *C, *K, *IV, *A, *T; gkey = malloc(sizeof(struct gcm_key_data)); gctx = malloc(sizeof(struct gcm_context_data)); P = malloc(PAGE_LEN); C = malloc(PAGE_LEN); K = malloc(PAGE_LEN); IV = malloc(PAGE_LEN); A = malloc(PAGE_LEN); T = malloc(PAGE_LEN); if ((NULL == P) || (NULL == C) || (NULL == K) || (NULL == IV) || (NULL == A) || (NULL == T) || (NULL == gkey) || (NULL == gctx)) { printf("malloc of testsize:0x%x failed\n", PAGE_LEN); return -1; } test.Plen = PAGE_LEN / 2; // place buffers to end at page boundary test.IVlen = GCM_IV_DATA_LEN; test.Alen = test.Plen; test.Tlen = MAX_TAG_LEN; printf("AES GCM efence test vectors:"); for (key_len = GCM_128_KEY_LEN; GCM_256_KEY_LEN >= key_len; key_len += (GCM_256_KEY_LEN - GCM_128_KEY_LEN)) { test.Klen = key_len; for (offset = 0; MAX_UNALIGNED > offset; offset++) { if (0 == (offset % 80)) printf("\n"); // move the start and size of the data block towards the end of the page test.Plen = (PAGE_LEN / 2) - offset; test.Alen = (PAGE_LEN / 4) - (offset * 4); //lengths must be a multiple of 4 bytes //Place data at end of page test.P = P + PAGE_LEN - test.Plen; test.C = C + PAGE_LEN - test.Plen; test.K = K + PAGE_LEN - test.Klen; test.IV = IV + PAGE_LEN - test.IVlen; test.A = A + PAGE_LEN - test.Alen; test.T = T + PAGE_LEN - test.Tlen; mk_rand_data(test.P, test.Plen); mk_rand_data(test.K, test.Klen); mk_rand_data(test.IV, test.IVlen); mk_rand_data(test.A, test.Alen); if (GCM_128_KEY_LEN == key_len) { if (0 != check_vector(gkey, gctx, &test)) return 1; } else { if (0 != check_256_vector(gkey, gctx, &test)) return 1; } } } free(gkey); free(gctx); free(P); free(C); free(K); free(IV); free(A); free(T); printf("\n"); return 0; } int test_gcm128_std_vectors(gcm_vector const *vector) { struct gcm_key_data gkey; struct gcm_context_data gctx; int OK = 0; // Temporary array for the calculated vectors uint8_t *ct_test = NULL; uint8_t *pt_test = NULL; uint8_t *IV_c = NULL; uint8_t *T_test = NULL; uint8_t *T2_test = NULL; uint64_t IV_alloc_len = 0; int result; #ifdef GCM_VECTORS_VERBOSE printf("AES-GCM-128:\n"); #endif // Allocate space for the calculated ciphertext ct_test = malloc(vector->Plen); if (ct_test == NULL) { fprintf(stderr, "Can't allocate ciphertext memory\n"); return 1; } // Allocate space for the calculated ciphertext pt_test = malloc(vector->Plen); if (pt_test == NULL) { fprintf(stderr, "Can't allocate plaintext memory\n"); return 1; } IV_alloc_len = vector->IVlen; // Allocate space for the calculated ciphertext IV_c = malloc(IV_alloc_len); if (IV_c == NULL) { fprintf(stderr, "Can't allocate ciphertext memory\n"); return 1; } memcpy(IV_c, vector->IV, vector->IVlen); T_test = malloc(vector->Tlen); T2_test = malloc(vector->Tlen); if ((T_test == NULL) || (T2_test == NULL)) { fprintf(stderr, "Can't allocate tag memory\n"); return 1; } // This is only required once for a given key aes_gcm_pre_128(vector->K, &gkey); #ifdef GCM_VECTORS_VERBOSE dump_gcm_data(&gkey); #endif //// // ISA-l Encrypt //// aes_gcm_enc_128(&gkey, &gctx, ct_test, vector->P, vector->Plen, IV_c, vector->A, vector->Alen, T_test, vector->Tlen); OK |= check_data(ct_test, vector->C, vector->Plen, "ISA-L encrypted cypher text (C)"); OK |= check_data(T_test, vector->T, vector->Tlen, "ISA-L tag (T)"); openssl_aes_gcm_enc(vector->K, vector->IV, vector->IVlen, vector->A, vector->Alen, pt_test, vector->Tlen, vector->P, vector->Plen, ct_test); OK |= check_data(pt_test, T_test, vector->Tlen, "OpenSSL vs ISA-L tag (T)"); // test of in-place encrypt memcpy(pt_test, vector->P, vector->Plen); aes_gcm_enc_128(&gkey, &gctx, pt_test, pt_test, vector->Plen, IV_c, vector->A, vector->Alen, T_test, vector->Tlen); OK |= check_data(pt_test, vector->C, vector->Plen, "ISA-L encrypted cypher text(in-place)"); memset(ct_test, 0, vector->Plen); memset(T_test, 0, vector->Tlen); //// // ISA-l Decrypt //// aes_gcm_dec_128(&gkey, &gctx, pt_test, vector->C, vector->Plen, IV_c, vector->A, vector->Alen, T_test, vector->Tlen); OK |= check_data(pt_test, vector->P, vector->Plen, "ISA-L decrypted plain text (P)"); // GCM decryption outputs a 16 byte tag value that must be verified against the expected tag value OK |= check_data(T_test, vector->T, vector->Tlen, "ISA-L decrypted tag (T)"); // test in in-place decrypt memcpy(ct_test, vector->C, vector->Plen); aes_gcm_dec_128(&gkey, &gctx, ct_test, ct_test, vector->Plen, IV_c, vector->A, vector->Alen, T_test, vector->Tlen); OK |= check_data(ct_test, vector->P, vector->Plen, "ISA-L plain text (P) - in-place"); OK |= check_data(T_test, vector->T, vector->Tlen, "ISA-L decrypted tag (T) - in-place"); // ISA-L enc -> ISA-L dec aes_gcm_enc_128(&gkey, &gctx, ct_test, vector->P, vector->Plen, IV_c, vector->A, vector->Alen, T_test, vector->Tlen); memset(pt_test, 0, vector->Plen); aes_gcm_dec_128(&gkey, &gctx, pt_test, ct_test, vector->Plen, IV_c, vector->A, vector->Alen, T2_test, vector->Tlen); OK |= check_data(pt_test, vector->P, vector->Plen, "ISA-L self decrypted plain text (P)"); OK |= check_data(T_test, T2_test, vector->Tlen, "ISA-L self decrypted tag (T)"); // OpenSSl enc -> ISA-L dec openssl_aes_gcm_enc(vector->K, vector->IV, vector->IVlen, vector->A, vector->Alen, T_test, vector->Tlen, vector->P, vector->Plen, ct_test); OK |= check_data(ct_test, vector->C, vector->Plen, "OpenSSL encrypted cypher text (C)"); memset(pt_test, 0, vector->Plen); aes_gcm_dec_128(&gkey, &gctx, pt_test, ct_test, vector->Plen, IV_c, vector->A, vector->Alen, T2_test, vector->Tlen); OK |= check_data(pt_test, vector->P, vector->Plen, "OpenSSL->ISA-L decrypted plain text (P)"); OK |= check_data(T_test, T2_test, vector->Tlen, "OpenSSL->ISA-L decrypted tag (T)"); // ISA-L enc -> OpenSSl dec aes_gcm_enc_128(&gkey, &gctx, ct_test, vector->P, vector->Plen, IV_c, vector->A, vector->Alen, T_test, vector->Tlen); memset(pt_test, 0, vector->Plen); result = openssl_aes_gcm_dec(vector->K, vector->IV, vector->IVlen, vector->A, vector->Alen, T_test, vector->Tlen, ct_test, vector->Plen, pt_test); if (-1 == result) printf(" ISA-L->OpenSSL decryption failed Authentication\n"); OK |= (-1 == result); OK |= check_data(pt_test, vector->P, vector->Plen, "OSSL decrypted plain text (C)"); if (NULL != ct_test) free(ct_test); if (NULL != pt_test) free(pt_test); if (NULL != IV_c) free(IV_c); if (NULL != T_test) free(T_test); if (NULL != T2_test) free(T2_test); return OK; } int test_gcm256_std_vectors(gcm_vector const *vector) { struct gcm_key_data gkey; struct gcm_context_data gctx; int OK = 0; // Temporary array for the calculated vectors uint8_t *ct_test = NULL; uint8_t *pt_test = NULL; uint8_t *IV_c = NULL; uint8_t *T_test = NULL; uint8_t *T2_test = NULL; uint64_t IV_alloc_len = 0; int result; #ifdef GCM_VECTORS_VERBOSE printf("AES-GCM-256:\n"); #endif // Allocate space for the calculated ciphertext ct_test = malloc(vector->Plen); // Allocate space for the calculated ciphertext pt_test = malloc(vector->Plen); if ((ct_test == NULL) || (pt_test == NULL)) { fprintf(stderr, "Can't allocate ciphertext or plaintext memory\n"); return 1; } IV_alloc_len = vector->IVlen; // Allocate space for the calculated ciphertext IV_c = malloc(IV_alloc_len); if (IV_c == NULL) { fprintf(stderr, "Can't allocate ciphertext memory\n"); return 1; } memcpy(IV_c, vector->IV, vector->IVlen); T_test = malloc(vector->Tlen); T2_test = malloc(vector->Tlen); if (T_test == NULL) { fprintf(stderr, "Can't allocate tag memory\n"); return 1; } // This is only required once for a given key aes_gcm_pre_256(vector->K, &gkey); #ifdef GCM_VECTORS_VERBOSE dump_gcm_data(&gkey); #endif //// // ISA-l Encrypt //// memset(ct_test, 0, vector->Plen); aes_gcm_enc_256(&gkey, &gctx, ct_test, vector->P, vector->Plen, IV_c, vector->A, vector->Alen, T_test, vector->Tlen); OK |= check_data(ct_test, vector->C, vector->Plen, "ISA-L encrypted cypher text (C)"); OK |= check_data(T_test, vector->T, vector->Tlen, "ISA-L tag (T)"); openssl_aes_256_gcm_enc(vector->K, vector->IV, vector->IVlen, vector->A, vector->Alen, pt_test, vector->Tlen, vector->P, vector->Plen, ct_test); OK |= check_data(ct_test, vector->C, vector->Tlen, "OpenSSL vs KA - cypher text (C)"); OK |= check_data(pt_test, vector->T, vector->Tlen, "OpenSSL vs KA - tag (T)"); OK |= check_data(pt_test, T_test, vector->Tlen, "OpenSSL vs ISA-L - tag (T)"); // test of in-place encrypt memcpy(pt_test, vector->P, vector->Plen); aes_gcm_enc_256(&gkey, &gctx, pt_test, pt_test, vector->Plen, IV_c, vector->A, vector->Alen, T_test, vector->Tlen); OK |= check_data(pt_test, vector->C, vector->Plen, "ISA-L encrypted cypher text(in-place)"); memset(ct_test, 0, vector->Plen); memset(T_test, 0, vector->Tlen); //// // ISA-l Decrypt //// aes_gcm_dec_256(&gkey, &gctx, pt_test, vector->C, vector->Plen, IV_c, vector->A, vector->Alen, T_test, vector->Tlen); OK |= check_data(pt_test, vector->P, vector->Plen, "ISA-L decrypted plain text (P)"); // GCM decryption outputs a 16 byte tag value that must be verified against the expected tag value OK |= check_data(T_test, vector->T, vector->Tlen, "ISA-L decrypted tag (T)"); // test in in-place decrypt memcpy(ct_test, vector->C, vector->Plen); aes_gcm_dec_256(&gkey, &gctx, ct_test, ct_test, vector->Plen, IV_c, vector->A, vector->Alen, T_test, vector->Tlen); OK |= check_data(ct_test, vector->P, vector->Plen, "ISA-L plain text (P) - in-place"); OK |= check_data(T_test, vector->T, vector->Tlen, "ISA-L decrypted tag (T) - in-place"); // ISA-L enc -> ISA-L dec aes_gcm_enc_256(&gkey, &gctx, ct_test, vector->P, vector->Plen, IV_c, vector->A, vector->Alen, T_test, vector->Tlen); memset(pt_test, 0, vector->Plen); aes_gcm_dec_256(&gkey, &gctx, pt_test, ct_test, vector->Plen, IV_c, vector->A, vector->Alen, T2_test, vector->Tlen); OK |= check_data(pt_test, vector->P, vector->Plen, "ISA-L self decrypted plain text (P)"); OK |= check_data(T_test, T2_test, vector->Tlen, "ISA-L self decrypted tag (T)"); // OpenSSl enc -> ISA-L dec openssl_aes_256_gcm_enc(vector->K, vector->IV, vector->IVlen, vector->A, vector->Alen, T_test, vector->Tlen, vector->P, vector->Plen, ct_test); OK |= check_data(ct_test, vector->C, vector->Plen, "OpenSSL encrypted cypher text (C)"); memset(pt_test, 0, vector->Plen); aes_gcm_dec_256(&gkey, &gctx, pt_test, ct_test, vector->Plen, IV_c, vector->A, vector->Alen, T2_test, vector->Tlen); OK |= check_data(pt_test, vector->P, vector->Plen, "OpenSSL->ISA-L decrypted plain text (P)"); OK |= check_data(T_test, T2_test, vector->Tlen, "OpenSSL->ISA-L decrypted tag (T)"); // ISA-L enc -> OpenSSl dec aes_gcm_enc_256(&gkey, &gctx, ct_test, vector->P, vector->Plen, IV_c, vector->A, vector->Alen, T_test, vector->Tlen); memset(pt_test, 0, vector->Plen); result = openssl_aes_256_gcm_dec(vector->K, vector->IV, vector->IVlen, vector->A, vector->Alen, T_test, vector->Tlen, ct_test, vector->Plen, pt_test); if (-1 == result) printf(" ISA-L->OpenSSL decryption failed Authentication\n"); OK |= (-1 == result); OK |= check_data(pt_test, vector->P, vector->Plen, "OSSL decrypted plain text (C)"); if (NULL != ct_test) free(ct_test); if (NULL != pt_test) free(pt_test); if (NULL != IV_c) free(IV_c); if (NULL != T_test) free(T_test); if (NULL != T2_test) free(T2_test); return OK; } int test_gcm_std_vectors(void) { int const vectors_cnt = sizeof(gcm_vectors) / sizeof(gcm_vectors[0]); int vect; int OK = 0; printf("AES-GCM standard test vectors:\n"); for (vect = 0; vect < vectors_cnt; vect++) { #ifdef GCM_VECTORS_VERBOSE printf ("Standard vector %d/%d Keylen:%d IVlen:%d PTLen:%d AADlen:%d Tlen:%d\n", vect, vectors_cnt - 1, (int)gcm_vectors[vect].Klen, (int)gcm_vectors[vect].IVlen, (int)gcm_vectors[vect].Plen, (int)gcm_vectors[vect].Alen, (int)gcm_vectors[vect].Tlen); #else printf("."); #endif if (BITS_128 == gcm_vectors[vect].Klen) { OK |= test_gcm128_std_vectors(&gcm_vectors[vect]); } else { OK |= test_gcm256_std_vectors(&gcm_vectors[vect]); } if (0 != OK) return OK; } printf("\n"); return OK; } // The length of the data is set to length. The first stream is from 0 to start. After // that the data is broken into breaks chunks of equal size (except possibly the last // one due to divisibility). int test_gcm_strm_combinations2(int length, int start, int breaks) { gcm_vector test; int tag_len = 8; int t = 0; struct gcm_key_data *gkey = NULL; struct gcm_context_data *gctx = NULL; gkey = malloc(sizeof(struct gcm_key_data)); gctx = malloc(sizeof(struct gcm_context_data)); if (NULL == gkey || NULL == gctx) return 1; printf("AES GCM random test vectors of length %d and stream with %d breaks:", length, breaks + 1); for (t = 0; RANDOMS > t; t++) { int Plen = length; //lengths must be a multiple of 4 bytes int aad_len = (rand() % TEST_LEN); int offset = (rand() % MAX_UNALIGNED); if (offset == 0 && aad_len == 0) offset = OFFSET_BASE_VALUE; if (0 == (t % 25)) printf("\n"); if (0 == (t % 10)) fflush(0); test.P = NULL; test.C = NULL; test.A = NULL; test.T = NULL; test.Plen = Plen; if (test.Plen + offset != 0) { test.P = malloc(test.Plen + offset); test.C = malloc(test.Plen + offset); } else { //This else clause is here because openssl 1.0.1k does not handle NULL pointers test.P = malloc(16); test.C = malloc(16); } test.K = malloc(GCM_128_KEY_LEN + offset); test.Klen = GCM_128_KEY_LEN; test.IV = malloc(GCM_IV_DATA_LEN + offset); test.IVlen = GCM_IV_DATA_LEN; test.A = malloc(aad_len + offset); test.Alen = aad_len; test.T = malloc(MAX_TAG_LEN + offset); if ((NULL == test.P && test.Plen != 0) || (NULL == test.K) || (NULL == test.IV)) { printf("malloc of testsize:0x%x failed\n", Plen); return 1; } test.P += offset; test.C += offset; test.K += offset; test.IV += offset; test.A += offset; test.T += offset; mk_rand_data(test.P, test.Plen); mk_rand_data(test.K, test.Klen); mk_rand_data(test.IV, test.IVlen); mk_rand_data(test.A, test.Alen); // single Key length of 128bits/16bytes supported // single IV length of 96bits/12bytes supported // Tag lengths of 8, 12 or 16 for (tag_len = 8; tag_len <= MAX_TAG_LEN;) { test.Tlen = tag_len; if (0 != check_strm_vector2(gkey, gctx, &test, length, start, breaks)) return 1; tag_len += 4; //supported lengths are 8, 12 or 16 } test.A -= offset; free(test.A); test.C -= offset; free(test.C); test.IV -= offset; free(test.IV); test.K -= offset; free(test.K); test.P -= offset; free(test.P); test.T -= offset; free(test.T); } printf("\n"); free(gkey); free(gctx); return 0; } int main(int argc, char **argv) { int errors = 0; int seed; if (argc == 1) seed = TEST_SEED; else seed = atoi(argv[1]); srand(seed); printf("SEED: %d\n", seed); errors += test_gcm_std_vectors(); errors += test_gcm256_combinations(); errors += test_gcm_combinations(); errors += test_gcm_efence(); errors += test_gcm256_strm_combinations(TEST_LEN); errors += test_gcm_strm_combinations(TEST_LEN); errors += test_gcm256_strm_combinations(1024); errors += test_gcm_strm_combinations(1024); errors += test_gcm_strm_efence(); errors += test_gcm_strm_combinations2(1024, 0, 1024); if (0 == errors) printf("...Pass\n"); else printf("...Fail\n"); return errors; }