369 lines
18 KiB
C
369 lines
18 KiB
C
/* Copyright (c) (2014-2020) Apple Inc. All rights reserved.
|
||
*
|
||
* corecrypto is licensed under Apple Inc.’s Internal Use License Agreement (which
|
||
* is contained in the License.txt file distributed with corecrypto) and only to
|
||
* people who accept that license. IMPORTANT: Any license rights granted to you by
|
||
* Apple Inc. (if any) are limited to internal use within your organization only on
|
||
* devices and computers you own or control, for the sole purpose of verifying the
|
||
* security characteristics and correct functioning of the Apple Software. You may
|
||
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
|
||
*/
|
||
|
||
#include <corecrypto/ccaes.h>
|
||
#include <corecrypto/ccmode.h>
|
||
#include <corecrypto/ccn.h>
|
||
|
||
#include "ccmode_internal.h"
|
||
#include "crypto_test_modes.h"
|
||
#include "testbyteBuffer.h"
|
||
#include "testmore.h"
|
||
|
||
static int verbose = 0;
|
||
|
||
typedef struct ccgcm_test_t {
|
||
char *keyStr; //key
|
||
char *aDataStr; //additional data
|
||
char *init_ivStr; //initialization vector
|
||
char *ptStr; //plain text
|
||
char *ctStr; //cipher text
|
||
char *tagStr; //tag
|
||
} ccgcm_test_vector;
|
||
|
||
// Redundant tests, there are already run as part of crypto_test_modes.c
|
||
// however, this file does testing that crypto_test_modes does not support
|
||
// This file looks generic but gcm_vectors only contains test for AES
|
||
// and there is no way to specify another block cipher.
|
||
// crypto_test_modes is really generic.
|
||
|
||
ccgcm_test_vector gcm_vectors[] = {
|
||
#include "../test_vectors/aes_gcm_test_vectors_ossl.inc"
|
||
#include "../test_vectors/aes_gcm_test_vectors.inc"
|
||
};
|
||
|
||
size_t nvectors = sizeof(gcm_vectors) / sizeof(ccgcm_test_vector);
|
||
|
||
static int ccgcm_discrete(const struct ccmode_gcm *mode,
|
||
size_t key_len, const void *key,
|
||
size_t iv_len, const void *iv,
|
||
size_t adata_len, const void *adata,
|
||
size_t nbytes, const void *in, void *out,
|
||
size_t tag_len, void *tag)
|
||
{
|
||
size_t max_block_len = cc_rand(19); if(max_block_len==0) max_block_len=1;
|
||
if(verbose) printf("\n------max_block_len=%zu\n", max_block_len);
|
||
int rc = 0;
|
||
|
||
ccgcm_ctx_decl(mode->size, ctx);
|
||
mode->init(mode, ctx, key_len, key);
|
||
|
||
if(iv_len > 0 && iv != NULL) {
|
||
rc |= mode->set_iv(ctx, iv_len, iv);
|
||
}
|
||
|
||
if(adata_len > 0 && adata != NULL) {
|
||
if (adata_len>max_block_len) {
|
||
size_t d1 = adata_len-max_block_len;
|
||
rc |= mode->gmac(ctx, max_block_len, adata);
|
||
rc |= mode->gmac(ctx, d1, adata+max_block_len);
|
||
} else {
|
||
rc |= mode->gmac(ctx, adata_len, adata);
|
||
}
|
||
} else {
|
||
if(verbose) printf("Skipping added AAD\n");
|
||
}
|
||
|
||
if(nbytes > 0) {
|
||
rc |= mode->gcm(ctx, nbytes, in, out);
|
||
} else {
|
||
if(verbose) printf("Skipping data\n");
|
||
}
|
||
|
||
rc |= mode->finalize(ctx, tag_len, tag);
|
||
ccgcm_ctx_clear(mode->size, ctx);
|
||
|
||
return rc;
|
||
}
|
||
|
||
typedef int (*ccgcm_test_func_t)(const struct ccmode_gcm *mode,
|
||
size_t key_len, const void *key,
|
||
size_t iv_len, const void *iv,
|
||
size_t adata_len, const void *adata,
|
||
size_t nbytes, const void *in, void *out,
|
||
size_t tag_len, void *tag);
|
||
|
||
|
||
|
||
static int gcm_test_a_function(const struct ccmode_gcm *em, const struct ccmode_gcm *dm,
|
||
size_t key_len, const void *key,
|
||
size_t iv_len, const void *iv,
|
||
size_t adata_len, const void *adata,
|
||
size_t nbytes, const void *plaintext, void *ciphertext,
|
||
size_t tag_len, void *tag,
|
||
ccgcm_test_func_t func)
|
||
{
|
||
|
||
uint8_t cipher_result[nbytes], plain_result[nbytes];
|
||
uint8_t cipher_tag[tag_len], plain_tag[tag_len];
|
||
int rc;
|
||
|
||
rc = func(em, key_len, key, iv_len, iv, adata_len, adata, nbytes, plaintext, cipher_result, tag_len, cipher_tag);
|
||
ok_or_fail(rc==0, "gcm encryption failed");
|
||
memcpy(plain_tag, tag, tag_len); //set the expected tag for decryption
|
||
rc = func(dm, key_len, key, iv_len, iv, adata_len, adata, nbytes, cipher_result, plain_result, tag_len, plain_tag );
|
||
ok_or_fail(rc==0, "gcm decryption failed");
|
||
|
||
ok_memcmp_or_fail(plaintext, plain_result, nbytes,"Round Trip Encrypt/Decrypt works");
|
||
ok_memcmp_or_fail(tag, cipher_tag, tag_len, "tags match on encrypt");
|
||
ok_memcmp_or_fail(tag, plain_tag, tag_len, "tags match on decrypt");
|
||
ok_memcmp_or_fail(ciphertext, cipher_result, nbytes, "Ciphertext matches known answer");
|
||
|
||
plain_tag[0] ^= 1;
|
||
rc = func(dm, key_len, key, iv_len, iv, adata_len, adata, nbytes, cipher_result, plain_result, tag_len, plain_tag );
|
||
ok_or_fail(rc != 0, "gcm authentication failed");
|
||
|
||
return 1;
|
||
}
|
||
|
||
static int gcm_testcase(const struct ccmode_gcm *encrypt_ciphermode, const struct ccmode_gcm *decrypt_ciphermode, size_t casenum)
|
||
{
|
||
size_t i=casenum;
|
||
byteBuffer key = hexStringToBytes(gcm_vectors[i].keyStr);
|
||
byteBuffer iv = hexStringToBytes(gcm_vectors[i].init_ivStr);
|
||
byteBuffer adata = hexStringToBytes(gcm_vectors[i].aDataStr);
|
||
byteBuffer plaintext = hexStringToBytes(gcm_vectors[i].ptStr);
|
||
byteBuffer ciphertext = hexStringToBytes(gcm_vectors[i].ctStr);
|
||
byteBuffer tag = hexStringToBytes(gcm_vectors[i].tagStr);
|
||
|
||
if(verbose) printf("GCM Case %zu\n", casenum);
|
||
|
||
gcm_test_a_function(encrypt_ciphermode, decrypt_ciphermode,
|
||
key->len, key->bytes,
|
||
iv->len, iv->bytes,
|
||
adata->len, adata->bytes,
|
||
plaintext->len,
|
||
plaintext->bytes, ciphertext->bytes,
|
||
tag->len, tag->bytes,
|
||
ccgcm_discrete);
|
||
|
||
gcm_test_a_function(encrypt_ciphermode, decrypt_ciphermode,
|
||
key->len, key->bytes,
|
||
iv->len, iv->bytes,
|
||
adata->len, adata->bytes,
|
||
plaintext->len,
|
||
plaintext->bytes, ciphertext->bytes,
|
||
tag->len, tag->bytes,
|
||
ccgcm_one_shot);
|
||
|
||
gcm_test_a_function(encrypt_ciphermode, decrypt_ciphermode,
|
||
key->len, key->bytes,
|
||
iv->len, iv->bytes,
|
||
adata->len, adata->bytes,
|
||
plaintext->len,
|
||
plaintext->bytes, ciphertext->bytes,
|
||
tag->len, tag->bytes,
|
||
ccgcm_one_shot_legacy);
|
||
|
||
free(key);
|
||
free(iv);
|
||
free(adata);
|
||
free(plaintext);
|
||
free(ciphertext);
|
||
free(tag);
|
||
return 1;
|
||
|
||
}
|
||
|
||
static int gcm_test_zerolen_iv(const struct ccmode_gcm *encrypt_ciphermode, const struct ccmode_gcm *decrypt_ciphermode)
|
||
{
|
||
int rc;
|
||
|
||
byteBuffer key = hexStringToBytes("59454c4c4f57205355424d4152494e45");
|
||
byteBuffer ad = hexStringToBytes("0000005a");
|
||
byteBuffer ptext = hexStringToBytes("506f69736f6e6f7573207061726167726170687320736d61736820796f75722070686f6e6f677261706820696e2068616c660a49742062652074686520496e73706563746168204465636b206f6e207468652077617270617468");
|
||
byteBuffer ctext = hexStringToBytes("3a8fbd9d5e5d53663664c8a67ca82c22d09b932a18fb18a37814330955bf55b73aef15a678182f42b9b0f7d8137b7c30dc09123ab9b150b8e04d65532e223e6a4eacc98275f75e113e9daf8598b7445fe04ec754bfe914bd65e8");
|
||
byteBuffer tag = hexStringToBytes("226a3338b54f22819e933c242746f303");
|
||
|
||
uint8_t textout[ptext->len];
|
||
uint8_t tagout[tag->len];
|
||
|
||
rc = ccgcm_one_shot(encrypt_ciphermode, key->len, key->bytes, 0, NULL, ad->len, ad->bytes, ptext->len, ptext->bytes, textout, sizeof (tagout), tagout);
|
||
ok_or_fail(rc != 0, "gcm one-shot encryption accepted zero-length iv");
|
||
|
||
rc = ccgcm_discrete(encrypt_ciphermode, key->len, key->bytes, 0, NULL, ad->len, ad->bytes, ptext->len, ptext->bytes, textout, sizeof (tagout), tagout);
|
||
ok_or_fail(rc != 0, "gcm discrete encryption accepted zero-length iv");
|
||
|
||
rc = ccgcm_one_shot_legacy(encrypt_ciphermode, key->len, key->bytes, 0, NULL, ad->len, ad->bytes, ptext->len, ptext->bytes, textout, sizeof (tagout), tagout);
|
||
ok_or_fail(rc == 0, "gcm one-shot legacy encryption failed");
|
||
ok_memcmp_or_fail(ctext->bytes, textout, ctext->len, "gcm one-shot legacy encryption text mismatch");
|
||
ok_memcmp_or_fail(tag->bytes, tagout, tag->len, "gcm one-shot legacy encryption tag mismatch");
|
||
|
||
rc = ccgcm_one_shot(decrypt_ciphermode, key->len, key->bytes, 0, NULL, ad->len, ad->bytes, ctext->len, ctext->bytes, textout, sizeof (tagout), tagout);
|
||
ok_or_fail(rc != 0, "gcm one-shot decryption accepted zero-length iv");
|
||
|
||
rc = ccgcm_discrete(decrypt_ciphermode, key->len, key->bytes, 0, NULL, ad->len, ad->bytes, ctext->len, ctext->bytes, textout, sizeof (tagout), tagout);
|
||
ok_or_fail(rc != 0, "gcm discrete decryption accepted zero-length iv");
|
||
|
||
rc = ccgcm_one_shot_legacy(decrypt_ciphermode, key->len, key->bytes, 0, NULL, ad->len, ad->bytes, ctext->len, ctext->bytes, textout, sizeof (tagout), tagout);
|
||
ok_or_fail(rc == 0, "gcm legacy decryption failed");
|
||
ok_memcmp_or_fail(ptext->bytes, textout, ptext->len, "gcm one-shot legacy decryption text mismatch");
|
||
ok_memcmp_or_fail(tag->bytes, tagout, tag->len, "gcm one-shot legacy decryption tag mismatch");
|
||
|
||
free(key);
|
||
free(tag);
|
||
free(ad);
|
||
free(ptext);
|
||
free(ctext);
|
||
return 1;
|
||
}
|
||
|
||
static int gcm_test_init_with_iv(const struct ccmode_gcm *encrypt_ciphermode, const struct ccmode_gcm *decrypt_ciphermode)
|
||
{
|
||
// int rc;
|
||
|
||
byteBuffer key = hexStringToBytes("e792232af1917965d75fc9b65a87f656");
|
||
byteBuffer iv1 = hexStringToBytes("c7ccdafe0000000000000000");
|
||
byteBuffer iv2 = hexStringToBytes("c7ccdafe0000000000000001");
|
||
byteBuffer ad = hexStringToBytes("04d7e6bd00cca0947da2");
|
||
byteBuffer ptext = hexStringToBytes("576f772c20746865205368616f6c696e207374796c6520697320616c6c20696e206d650a4368696c642c207468652077686f6c652064616d6e2069736c652069732063616c6c696e206d650a");
|
||
byteBuffer ctext1 = hexStringToBytes("f90a4f9c1250849af5289066aad8c10f67ffc2ca5799e58d8b49cc6f22c495f56f46adb18c3b21b4710306dffc88ce9a7252ba92b74b35db08221d8dca7aed27105b0d1a812bd10e49af2345");
|
||
byteBuffer tag1 = hexStringToBytes("73d833e2d55d741743b09e0e07c6d610");
|
||
byteBuffer ctext2 = hexStringToBytes("d075317f57fc20ff37832f507e90c84fd311a0a160b59084217b642829028dcef56ffa73db659bf250ab97eda2df50635d1fc29f6e2dbbc651acd4e747ed7577805a61708bec9ad8e272cce4");
|
||
byteBuffer tag2 = hexStringToBytes("298184a805bede8490c0da2cf19e7b0e");
|
||
|
||
uint8_t ivout[iv1->len];
|
||
uint8_t textout[ptext->len];
|
||
uint8_t tagout[tag1->len];
|
||
|
||
ccgcm_ctx_decl(ccgcm_context_size(encrypt_ciphermode), encrypt_ctx);
|
||
ccgcm_ctx_decl(ccgcm_context_size(decrypt_ciphermode), decrypt_ctx);
|
||
|
||
ok_or_fail(ccgcm_init_with_iv(encrypt_ciphermode, encrypt_ctx, key->len, key->bytes, iv1->bytes) == 0, "ccgcm_init_with_iv encrypt1");
|
||
ok_or_fail(ccgcm_aad(encrypt_ciphermode, encrypt_ctx, ad->len, ad->bytes) == 0, "ccgcm_aad encrypt1");
|
||
ok_or_fail(ccgcm_update(encrypt_ciphermode, encrypt_ctx, ptext->len, ptext->bytes, textout) == 0, "ccgcm_update encrypt1");
|
||
ok_or_fail(ccgcm_finalize(encrypt_ciphermode, encrypt_ctx, tag1->len, tagout) == 0, "ccgcm_finalize encrypt1");
|
||
ok_memcmp(ctext1->bytes, textout, ctext1->len, "ctext1 encrypt1");
|
||
ok_memcmp(tag1->bytes, tagout, tag1->len, "tag1 encrypt1");
|
||
|
||
ok_or_fail(ccgcm_init_with_iv(decrypt_ciphermode, decrypt_ctx, key->len, key->bytes, iv1->bytes) == 0, "ccgcm_init_with_iv decrypt1");
|
||
ok_or_fail(ccgcm_aad(decrypt_ciphermode, decrypt_ctx, ad->len, ad->bytes) == 0, "ccgcm_aad decrypt1");
|
||
ok_or_fail(ccgcm_update(decrypt_ciphermode, decrypt_ctx, ctext1->len, ctext1->bytes, textout) == 0, "ccgcm_update decrypt1");
|
||
ok_or_fail(ccgcm_finalize(decrypt_ciphermode, decrypt_ctx, tag1->len, tagout) == 0, "ccgcm_finalize decrypt1");
|
||
ok_memcmp(ptext->bytes, textout, ptext->len, "ptext decrypt1");
|
||
ok_memcmp(tag1->bytes, tagout, tag1->len, "tag1 decrypt1");
|
||
|
||
ok_or_fail(ccgcm_reset(encrypt_ciphermode, encrypt_ctx) == 0, "ccgcm_reset encrypt2");
|
||
ok_or_fail(ccgcm_inc_iv(encrypt_ciphermode, encrypt_ctx, ivout) == 0, "ccgcm_inc_iv encrypt2");
|
||
ok_or_fail(ccgcm_aad(encrypt_ciphermode, encrypt_ctx, ad->len, ad->bytes) == 0, "ccgcm_aad encrypt2");
|
||
ok_or_fail(ccgcm_update(encrypt_ciphermode, encrypt_ctx, ptext->len, ptext->bytes, textout) == 0, "ccgcm_update encrypt2");
|
||
ok_or_fail(ccgcm_finalize(encrypt_ciphermode, encrypt_ctx, tag2->len, tagout) == 0, "ccgcm_finalize encrypt2");
|
||
ok_memcmp(iv2->bytes, ivout, iv2->len, "iv2 encrypt2");
|
||
ok_memcmp(ctext2->bytes, textout, ctext2->len, "ctext2 encrypt2");
|
||
ok_memcmp(tag2->bytes, tagout, tag2->len, "tag2 encrypt2");
|
||
|
||
ok_or_fail(ccgcm_reset(decrypt_ciphermode, decrypt_ctx) == 0, "ccgcm_reset decrypt2");
|
||
ok_or_fail(ccgcm_inc_iv(decrypt_ciphermode, decrypt_ctx, ivout) == 0, "ccgcm_inc_iv decrypt2");
|
||
ok_or_fail(ccgcm_aad(decrypt_ciphermode, decrypt_ctx, ad->len, ad->bytes) == 0, "ccgcm_aad decrypt2");
|
||
ok_or_fail(ccgcm_update(decrypt_ciphermode, decrypt_ctx, ctext2->len, ctext2->bytes, textout) == 0, "ccgcm_update decrypt2");
|
||
ok_or_fail(ccgcm_finalize(decrypt_ciphermode, decrypt_ctx, tag2->len, tagout) == 0, "ccgcm_finalize decrypt2");
|
||
ok_memcmp(iv2->bytes, ivout, iv2->len, "iv2 decrypt2");
|
||
ok_memcmp(ptext->bytes, textout, ptext->len, "ptext decrypt2");
|
||
ok_memcmp(tag2->bytes, tagout, tag2->len, "tag2 decrypt2");
|
||
|
||
ok_or_fail(ccgcm_init_with_iv(encrypt_ciphermode, encrypt_ctx, key->len, key->bytes, iv1->bytes) == 0, "ccgcm_init_with_iv encrypt no-set-iv");
|
||
ok_or_fail(ccgcm_reset(encrypt_ciphermode, encrypt_ctx) == 0, "ccgcm_reset encrypt no-set-iv");
|
||
ok_or_fail(ccgcm_set_iv(encrypt_ciphermode, encrypt_ctx, iv2->len, iv2->bytes) != 0, "ccgcm_set_iv encrypt no-set-iv");
|
||
|
||
ok_or_fail(ccgcm_init_with_iv(decrypt_ciphermode, decrypt_ctx, key->len, key->bytes, iv1->bytes) == 0, "ccgcm_init_with_iv decrypt no-set-iv");
|
||
ok_or_fail(ccgcm_reset(decrypt_ciphermode, decrypt_ctx) == 0, "ccgcm_reset decrypt no-set-iv");
|
||
ok_or_fail(ccgcm_set_iv(decrypt_ciphermode, decrypt_ctx, iv2->len, iv2->bytes) != 0, "ccgcm_set_iv decrypt no-set-iv");
|
||
|
||
ok_or_fail(ccgcm_init(encrypt_ciphermode, encrypt_ctx, key->len, key->bytes) == 0, "ccgcm_init_with_iv encrypt no-inc-iv");
|
||
ok_or_fail(ccgcm_set_iv(encrypt_ciphermode, encrypt_ctx, iv1->len, iv1->bytes) == 0, "ccgcm_set_iv encrypt no-inc-iv");
|
||
ok_or_fail(ccgcm_reset(encrypt_ciphermode, encrypt_ctx) == 0, "ccgcm_reset encrypt no-inc-iv");
|
||
ok_or_fail(ccgcm_inc_iv(encrypt_ciphermode, encrypt_ctx, ivout) != 0, "ccgcm_set_iv encrypt no-inc-iv");
|
||
|
||
ok_or_fail(ccgcm_init(decrypt_ciphermode, decrypt_ctx, key->len, key->bytes) == 0, "ccgcm_init_with_iv decrypt no-inc-iv");
|
||
ok_or_fail(ccgcm_set_iv(decrypt_ciphermode, decrypt_ctx, iv1->len, iv1->bytes) == 0, "ccgcm_set_iv decrypt no-inc-iv");
|
||
ok_or_fail(ccgcm_reset(decrypt_ciphermode, decrypt_ctx) == 0, "ccgcm_reset decrypt no-inc-iv");
|
||
ok_or_fail(ccgcm_inc_iv(decrypt_ciphermode, decrypt_ctx, ivout) != 0, "ccgcm_set_iv decrypt no-inc-iv");
|
||
|
||
|
||
free(key);
|
||
free(iv1);
|
||
free(iv2);
|
||
free(ad);
|
||
free(ptext);
|
||
free(ctext1);
|
||
free(tag1);
|
||
free(ctext2);
|
||
free(tag2);
|
||
|
||
|
||
|
||
return 1;
|
||
}
|
||
|
||
/* In this test we reach into the internal state to trigger the validation error on long messages. */
|
||
static int gcm_test_counter_wrap(const struct ccmode_gcm *encrypt_ciphermode, const struct ccmode_gcm *decrypt_ciphermode)
|
||
{
|
||
uint8_t buf[CCGCM_BLOCK_NBYTES] = { 0 };
|
||
|
||
ccgcm_ctx_decl(ccgcm_context_size(encrypt_ciphermode), encrypt_ctx);
|
||
ccgcm_ctx_decl(ccgcm_context_size(decrypt_ciphermode), decrypt_ctx);
|
||
|
||
ok_or_fail(ccgcm_init(encrypt_ciphermode, encrypt_ctx, CCAES_KEY_SIZE_128, buf) == 0, "ccgcm_init encrypt counter wrap");
|
||
ok_or_fail(ccgcm_set_iv(encrypt_ciphermode, encrypt_ctx, CCGCM_IV_NBYTES, buf) == 0, "ccgcm_set encrypt counter wrap");
|
||
ok_or_fail(ccgcm_update(encrypt_ciphermode, encrypt_ctx, sizeof (buf), buf, buf) == 0, "ccgcm_update (begin) encrypt counter wrap");
|
||
((struct _ccmode_gcm_key *)encrypt_ctx)->text_nbytes = CCGCM_TEXT_MAX_NBYTES - CCGCM_BLOCK_NBYTES;
|
||
ok_or_fail(ccgcm_update(encrypt_ciphermode, encrypt_ctx, sizeof (buf), buf, buf) == 0, "ccgcm_update (end) encrypt counter wrap");
|
||
ok_or_fail(ccgcm_update(encrypt_ciphermode, encrypt_ctx, 1, buf, buf) == CCMODE_INVALID_INPUT, "ccgcm_update (overflow) encrypt counter wrap");
|
||
|
||
ok_or_fail(ccgcm_init(decrypt_ciphermode, decrypt_ctx, CCAES_KEY_SIZE_128, buf) == 0, "ccgcm_init decrypt counter wrap");
|
||
ok_or_fail(ccgcm_set_iv(decrypt_ciphermode, decrypt_ctx, CCGCM_IV_NBYTES, buf) == 0, "ccgcm_set decrypt counter wrap");
|
||
ok_or_fail(ccgcm_update(decrypt_ciphermode, decrypt_ctx, sizeof (buf), buf, buf) == 0, "ccgcm_update (begin) decrypt counter wrap");
|
||
((struct _ccmode_gcm_key *)decrypt_ctx)->text_nbytes = CCGCM_TEXT_MAX_NBYTES - CCGCM_BLOCK_NBYTES;
|
||
ok_or_fail(ccgcm_update(decrypt_ciphermode, decrypt_ctx, sizeof (buf), buf, buf) == 0, "ccgcm_update (end) decrypt counter wrap");
|
||
ok_or_fail(ccgcm_update(decrypt_ciphermode, decrypt_ctx, 1, buf, buf) == CCMODE_INVALID_INPUT, "ccgcm_update (overflow) decrypt counter wrap");
|
||
|
||
return 1;
|
||
}
|
||
|
||
static int
|
||
gcm_test_gf_mult(void)
|
||
{
|
||
uint8_t keyA[16];
|
||
uint8_t stateA[16];
|
||
uint8_t outA[16];
|
||
uint8_t keyB[16];
|
||
uint8_t stateB[16];
|
||
uint8_t outB[16];
|
||
|
||
for (size_t i = 0; i < sizeof(keyA); i++) {
|
||
keyA[i] = 0xDE;
|
||
keyB[i] = 0xDE;
|
||
stateA[i] = 0xED;
|
||
stateB[i] = 0xED;
|
||
}
|
||
|
||
ccmode_gcm_gf_mult_table(keyA, stateA, outA);
|
||
ccmode_gcm_gf_mult_compute(keyA, stateB, outB);
|
||
|
||
ok_memcmp_or_fail(outA, outB, sizeof(outA), "ccmode_gcm_gf_mult_table and ccmode_gcm_gf_mult_compute computed different results");
|
||
|
||
return 1;
|
||
}
|
||
|
||
int test_gcm(const struct ccmode_gcm *encrypt_ciphermode, const struct ccmode_gcm *decrypt_ciphermode)
|
||
{
|
||
|
||
for (size_t i = 0; i < nvectors; i++) {
|
||
gcm_testcase(encrypt_ciphermode, decrypt_ciphermode, i);
|
||
}
|
||
|
||
gcm_test_zerolen_iv(encrypt_ciphermode, decrypt_ciphermode);
|
||
gcm_test_init_with_iv(encrypt_ciphermode, decrypt_ciphermode);
|
||
gcm_test_counter_wrap(encrypt_ciphermode, decrypt_ciphermode);
|
||
|
||
return gcm_test_gf_mult();
|
||
}
|