corecrypto/ccmode/xcunit/ccmode_test.c

752 lines
24 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Copyright (c) (2010,2011,2012,2013,2014,2015,2016,2017,2018,2019) 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/ccmode.h>
#include <corecrypto/ccpad.h>
#include "cctest.h"
#include <corecrypto/cc_priv.h>
#include "ccmode_test.h"
//#define _INTERNAL_DEBUG_ 1
//#define USE_COMMONCRYPTO_GCM 1
#ifdef _INTERNAL_DEBUG_
#include <stdio.h>
#endif
/* does one encryption or decryption in ECB mode and compare result */
int ccmode_ecb_test_one(const struct ccmode_ecb *ecb, size_t keylen, const void *keydata,
size_t nblocks, const void *in, const void *out)
{
unsigned char temp[nblocks*ecb->block_size];
ccecb_ctx_decl(ecb->size, key);
if (ecb->init(ecb, key, keylen, keydata)) {
return -1;
}
if (ecb->ecb(key, nblocks, in, temp)) {
return -1;
}
#ifdef _INTERNAL_DEBUG_
{
char k[keylen*2+1];
char i[ecb->block_size*nblocks*2+1];
char o[ecb->block_size*nblocks*2+1];
char t[ecb->block_size*nblocks*2+1];
cc_bin2hex(keylen, k, keydata);
cc_bin2hex(ecb->block_size*nblocks, i, in);
cc_bin2hex(ecb->block_size*nblocks, o, out);
cc_bin2hex(ecb->block_size*nblocks, t, temp);
fprintf(stderr, "k: %s, i: %s, o:%s, t:%s\n", k, i, o, t);
}
#endif
return memcmp(out, temp, ecb->block_size*nblocks);
}
/* Test one test vector - use dec=1 to reverse pt and ct */
int ccmode_ecb_test_one_vector(const struct ccmode_ecb *ecb, const struct ccmode_ecb_vector *v, int dec)
{
if (dec) {
return ccmode_ecb_test_one(ecb, v->keylen, v->key, v->nblocks, v->ct, v->pt);
} else {
return ccmode_ecb_test_one(ecb, v->keylen, v->key, v->nblocks, v->pt, v->ct);
}
}
/* Initialize a block of 'nblocks' of zeroes,
Does 'loops' consecutive encryption (ECB) in place,
then 'loops' decryption (ECB) in place,
result should be zeroes. */
int ccmode_ecb_test_key_self(const struct ccmode_ecb *encrypt, const struct ccmode_ecb *decrypt, size_t nblocks,
size_t keylen, const void *keydata, size_t loops)
{
unsigned char temp[nblocks*encrypt->block_size];
unsigned char zeroes[nblocks*encrypt->block_size];
ccecb_ctx_decl(decrypt->size, dkey);
ccecb_ctx_decl(encrypt->size, ekey);
cc_clear(nblocks*encrypt->block_size,temp);
cc_clear(nblocks*encrypt->block_size,zeroes);
if (encrypt->init(encrypt, ekey, keylen, keydata)) {
return -1;
}
if (decrypt->init(decrypt, dkey, keylen, keydata)) {
return -1;
}
for (size_t i=0; i<loops; i++) {
if (encrypt->ecb(ekey, nblocks, temp, temp)) {
return -1;
}
}
for (size_t i=0; i<loops; i++) {
if (decrypt->ecb(dkey, nblocks, temp, temp)) {
return -1;
}
}
return memcmp(zeroes, temp, encrypt->block_size*nblocks);
}
/* does one CBC encryption or decryption and compare result */
int ccmode_cbc_test_one(const struct ccmode_cbc *cbc, size_t keylen, const void *keydata,
const void *iv, size_t nblocks, const void *in, const void *out)
{
unsigned char temp[nblocks*cbc->block_size];
if (cccbc_one_shot(cbc, keylen, keydata, iv, nblocks, in, temp)) {
return -1;
}
return memcmp(out, temp, sizeof(temp));
}
/* Test one test vector - use dec=1 to reverse pt and ct */
int ccmode_cbc_test_one_vector(const struct ccmode_cbc *cbc, const struct ccmode_cbc_vector *v, int dec)
{
if (dec) {
return ccmode_cbc_test_one(cbc, v->keylen, v->key, v->iv, v->nblocks, v->ct, v->pt);
} else {
return ccmode_cbc_test_one(cbc, v->keylen, v->key, v->iv, v->nblocks, v->pt, v->ct);
}
}
/* Test one test vector, with unaligned data */
int ccmode_cbc_test_one_vector_unaligned(const struct ccmode_cbc *cbc, const struct ccmode_cbc_vector *v, int dec)
{
uint8_t pt[v->nblocks*cbc->block_size+1];
uint8_t ct[v->nblocks*cbc->block_size+1];
memcpy(pt+1, v->pt, v->nblocks*cbc->block_size);
memcpy(ct+1, v->ct, v->nblocks*cbc->block_size);
if (dec) {
return ccmode_cbc_test_one(cbc, v->keylen, v->key, v->iv, v->nblocks, ct+1, v->pt);
} else {
return ccmode_cbc_test_one(cbc, v->keylen, v->key, v->iv, v->nblocks, pt+1, v->ct);
}
}
/* Test one test vector, 1 block at a time */
int ccmode_cbc_test_one_chained(const struct ccmode_cbc *cbc, size_t keylen, const void *keydata,
const void *iv, size_t nblocks, const void *in, const void *out)
{
size_t i;
const unsigned char *input=in;
unsigned char temp[nblocks*cbc->block_size];
cccbc_ctx_decl(cbc->size, key);
cccbc_iv_decl(cbc->block_size, iv_ctx);
if (cccbc_init(cbc, key, keylen, keydata)) {
return -1;
}
if (cccbc_set_iv(cbc, iv_ctx, iv)) {
return -1;
}
for (i=0; i<nblocks; i++) {
if (cccbc_update(cbc, key, iv_ctx, 1, &input[i*cbc->block_size], &temp[i*cbc->block_size])) {
return -1;
}
}
return memcmp(out, temp, cbc->block_size*nblocks);
}
int ccmode_cbc_test_one_vector_chained(const struct ccmode_cbc *cbc, const struct ccmode_cbc_vector *v, int dec)
{
if (dec) {
return ccmode_cbc_test_one_chained(cbc, v->keylen, v->key, v->iv, v->nblocks, v->ct, v->pt);
} else {
return ccmode_cbc_test_one_chained(cbc, v->keylen, v->key, v->iv, v->nblocks, v->pt, v->ct);
}
}
/* Initialize a block of 'nblocks' of zeroes,
Does 'loops' consecutive encryption (CBC) in place,
then 'loops' decryption (CBC) in place,
using 0 for iv in each loop, result should be zeroes. */
int ccmode_cbc_test_key_self(const struct ccmode_cbc *encrypt,
const struct ccmode_cbc *decrypt,
size_t nblocks, size_t keylen,
const void *keydata, size_t loops)
{
unsigned char temp[nblocks*encrypt->block_size];
unsigned char zeroes[nblocks*encrypt->block_size];
cccbc_iv_decl(encrypt->block_size, iv); // we can use the same iv context for encrypt and decrypt
// as long as we are not chaining concurrently for both.
cccbc_ctx_decl(encrypt->size, ekey);
cccbc_ctx_decl(decrypt->size, dkey);
cc_clear(nblocks*encrypt->block_size,temp);
cc_clear(nblocks*encrypt->block_size,zeroes);
if (cccbc_init(encrypt, ekey, keylen, keydata)) {
return -1;
}
for (size_t i=0; i<loops; i++) {
if (cccbc_set_iv(encrypt, iv, NULL)) {
return -1;
}
if (cccbc_update(encrypt, ekey, iv, nblocks, temp, temp)) {
return -1;
}
}
if (cccbc_init(decrypt, dkey, keylen, keydata)) {
return -1;
}
for (size_t i=0; i<loops; i++) {
if (cccbc_set_iv(decrypt, iv, NULL)) {
return -1;
}
if (cccbc_update(decrypt, dkey, iv, nblocks, temp, temp)) {
return -1;
}
}
return memcmp(zeroes, temp, encrypt->block_size*nblocks);
}
/*
Encrypt and decrypt 'nblocks*loop' blocks of zeroes,
'nblocks' at a time.
*/
int ccmode_cbc_test_chaining_self(const struct ccmode_cbc *encrypt,
const struct ccmode_cbc *decrypt,
size_t nblocks, size_t keylen,
const void *keydata, size_t loops)
{
unsigned char temp[nblocks*encrypt->block_size];
unsigned char zeroes[nblocks*encrypt->block_size];
cccbc_ctx_decl(encrypt->size, ekey);
cccbc_ctx_decl(decrypt->size, dkey);
/* here we have to use two iv contexts */
cccbc_iv_decl(encrypt->block_size, eiv);
cccbc_iv_decl(decrypt->block_size, div);
cc_clear(nblocks*encrypt->block_size,temp);
cc_clear(nblocks*encrypt->block_size,zeroes);
if (cccbc_init(encrypt, ekey, keylen, keydata)) {
return -1;
}
if (cccbc_init(decrypt, dkey, keylen, keydata)) {
return -1;
}
if (cccbc_set_iv(encrypt, eiv, NULL)) {
return -1;
}
if (cccbc_set_iv(decrypt, div, NULL)) {
return -1;
}
for (size_t i=0; i<loops; i++) {
if (cccbc_update(encrypt, ekey, eiv, nblocks, temp, temp)) {
return -1;
}
if (cccbc_update(decrypt, dkey, div, nblocks, temp, temp)) {
return -1;
}
}
return memcmp(zeroes, temp, sizeof(temp));
}
/* OFB */
/* does one OFB encryption or decryption and compare result */
int ccmode_ofb_test_one(const struct ccmode_ofb *ofb, size_t keylen, const void *keydata,
const void *iv, size_t nbytes, const void *in, const void *out)
{
unsigned char temp[nbytes];
ccofb_ctx_decl(ofb->size, key);
if (ofb->init(ofb, key, keylen, keydata, iv)) {
return -1;
}
if (ofb->ofb(key, nbytes, in, temp)) {
return -1;
}
return memcmp(out, temp, nbytes);
}
/* Test one test vector - use dec=1 to reverse pt and ct */
int ccmode_ofb_test_one_vector(const struct ccmode_ofb *ofb, const struct ccmode_ofb_vector *v, int dec)
{
if (dec) {
return ccmode_ofb_test_one(ofb, v->keylen, v->key, v->iv, v->nbytes, v->ct, v->pt);
} else {
return ccmode_ofb_test_one(ofb, v->keylen, v->key, v->iv, v->nbytes, v->pt, v->ct);
}
}
/* Test one test vector, 1 byte at a time */
int ccmode_ofb_test_one_chained(const struct ccmode_ofb *ofb, size_t keylen, const void *keydata,
const void *iv, size_t nbytes, const void *in, const void *out)
{
size_t i;
const unsigned char *input=in;
unsigned char temp[nbytes];
ccofb_ctx_decl(ofb->size, key);
if (ofb->init(ofb, key, keylen, keydata, iv)) {
return -1;
}
for (i=0; i<nbytes; i++) {
if (ofb->ofb(key, 1, &input[i], &temp[i])) {
return -1;
}
}
return memcmp(out, temp, nbytes);
}
int ccmode_ofb_test_one_vector_chained(const struct ccmode_ofb *ofb, const struct ccmode_ofb_vector *v, int dec)
{
if (dec) {
return ccmode_ofb_test_one_chained(ofb, v->keylen, v->key, v->iv, v->nbytes, v->ct, v->pt);
} else {
return ccmode_ofb_test_one_chained(ofb, v->keylen, v->key, v->iv, v->nbytes, v->pt, v->ct);
}
}
/* does one CFB encryption or decryption and compare result */
int ccmode_cfb_test_one(const struct ccmode_cfb *cfb, size_t keylen, const void *keydata,
const void *iv, size_t nbytes, const void *in, const void *out)
{
unsigned char temp[nbytes];
cccfb_ctx_decl(cfb->size, key);
if (cfb->init(cfb, key, keylen, keydata, iv)) {
return -1;
}
if (cfb->cfb(key, nbytes, in, temp)) {
return -1;
}
return memcmp(out, temp, nbytes);
}
/* Test one test vector - use dec=1 to reverse pt and ct */
int ccmode_cfb_test_one_vector(const struct ccmode_cfb *cfb, const struct ccmode_cfb_vector *v, int dec)
{
if (dec) {
return ccmode_cfb_test_one(cfb, v->keylen, v->key, v->iv, v->nbytes, v->ct, v->pt);
} else {
return ccmode_cfb_test_one(cfb, v->keylen, v->key, v->iv, v->nbytes, v->pt, v->ct);
}
}
/* Test one test vector, 1 block at a time */
int ccmode_cfb_test_one_chained(const struct ccmode_cfb *cfb, size_t keylen, const void *keydata,
const void *iv, size_t nbytes, const void *in, const void *out)
{
size_t i;
const unsigned char *input=in;
unsigned char temp[nbytes];
cccfb_ctx_decl(cfb->size, key);
if (cfb->init(cfb, key, keylen, keydata, iv)) {
return -1;
}
for (i=0; i<nbytes; i++) {
if (cfb->cfb(key, 1, &input[i], &temp[i])) {
return -1;
}
}
return memcmp(out, temp, nbytes);
}
int ccmode_cfb_test_one_vector_chained(const struct ccmode_cfb *cfb, const struct ccmode_cfb_vector *v, int dec)
{
if (dec) {
return ccmode_cfb_test_one_chained(cfb, v->keylen, v->key, v->iv, v->nbytes, v->ct, v->pt);
} else {
return ccmode_cfb_test_one_chained(cfb, v->keylen, v->key, v->iv, v->nbytes, v->pt, v->ct);
}
}
/* CFB8 */
/* does one CFB8 encryption or decryption and compare result */
int ccmode_cfb8_test_one(const struct ccmode_cfb8 *cfb8, size_t keylen, const void *keydata,
const void *iv, size_t nbytes, const void *in, const void *out)
{
unsigned char temp[nbytes];
cccfb8_ctx_decl(cfb8->size, key);
if (cfb8->init(cfb8, key, keylen, keydata, iv)) {
return -1;
}
if (cfb8->cfb8(key, nbytes, in, temp)) {
return -1;
}
return memcmp(out, temp, nbytes);
}
/* Test one test vector - use dec=1 to reverse pt and ct */
int ccmode_cfb8_test_one_vector(const struct ccmode_cfb8 *cfb8, const struct ccmode_cfb8_vector *v, int dec)
{
if (dec) {
return ccmode_cfb8_test_one(cfb8, v->keylen, v->key, v->iv, v->nbytes, v->ct, v->pt);
} else {
return ccmode_cfb8_test_one(cfb8, v->keylen, v->key, v->iv, v->nbytes, v->pt, v->ct);
}
}
/* Test one test vector, 1 byte at a time */
int ccmode_cfb8_test_one_chained(const struct ccmode_cfb8 *cfb8, size_t keylen, const void *keydata,
const void *iv, size_t nbytes, const void *in, const void *out)
{
size_t i;
const unsigned char *input=in;
unsigned char temp[nbytes];
cccfb8_ctx_decl(cfb8->size, key);
if (cfb8->init(cfb8, key, keylen, keydata, iv)) {
return -1;
}
for (i=0; i<nbytes; i++) {
if (cfb8->cfb8(key, 1, &input[i], &temp[i])) {
return -1;
}
}
return memcmp(out, temp, nbytes);
}
int ccmode_cfb8_test_one_vector_chained(const struct ccmode_cfb8 *cfb8, const struct ccmode_cfb8_vector *v, int dec)
{
if (dec) {
return ccmode_cfb8_test_one_chained(cfb8, v->keylen, v->key, v->iv, v->nbytes, v->ct, v->pt);
} else {
return ccmode_cfb8_test_one_chained(cfb8, v->keylen, v->key, v->iv, v->nbytes, v->pt, v->ct);
}
}
/* GCM */
int ccmode_gcm_test_one_chained(const struct ccmode_gcm *gcm,
size_t keylen, const void *keydata,
size_t ivlen, const void *iv,
size_t adalen, const void *ada,
size_t nbytes, const void *in, const void *out,
size_t taglen, const void *tag)
{
/* mac and crypt one byte at a time */
size_t i;
unsigned char temp[nbytes];
unsigned char temptag[taglen];
ccgcm_ctx_decl(gcm->size, key);
if (gcm->init(gcm, key, keylen, keydata)) {
return -1;
}
if (gcm->set_iv(key, ivlen, iv)) {
return -1;
}
const unsigned char *p = ada;
if (adalen) {
for (i = 0; i < adalen; i++) {
if (gcm->gmac(key, 1, &p[i])) {
return -1;
}
}
} else {
if (gcm->gmac(key, 0, NULL)) {
return -1;
}
}
p = in;
if (nbytes) {
for (i = 0; i < nbytes; i++) {
if (gcm->gcm(key, 1, &p[i], &temp[i])) {
return -1;
}
}
} else {
if (gcm->gcm(key, 0, NULL, NULL)) {
return -1;
}
}
memcpy(temptag, tag, taglen);
int rc=gcm->finalize(key, taglen, temptag); //for decryption should return zero because we passed the correct tag
#ifdef _INTERNAL_DEBUG_
int r1, r2;
r1 = memcmp(out, temp, nbytes);
r2 = memcmp(tag, temptag, taglen);
if (r1 || r2)
cc_printf("ivlen: %lu adalen: %lu nbytes: %lu taglen: %lu crypt: %d tag: %d\n",
ivlen, adalen, nbytes, taglen, r1, r2);
return r1 != 0 ? r1 : r2;
#else
return rc || memcmp(out, temp, nbytes) || memcmp(tag, temptag, taglen);
#endif
}
int ccmode_gcm_test_one_vector(const struct ccmode_gcm *gcm, const struct ccmode_gcm_vector *v, int dec)
{
if (v->ptlen != v->ctlen) {
return -1;
}
char expected_tag[v->taglen];
int rc = 0;
if (dec) {
char pt_out[v->ptlen];
memcpy(expected_tag, v->tag, v->taglen);
rc = ccgcm_one_shot(gcm, v->keylen, v->key, v->ivlen, v->iv, v->adalen, v->ada, v->ctlen, v->ct, pt_out, v->taglen, expected_tag);
//this is not needed in practice, we do it because this is a test fucntion
rc = rc | memcmp(pt_out, v->pt, v->ptlen) | memcmp(expected_tag, v->tag, v->taglen);
}else{
char ct_out[v->ptlen];
rc = ccgcm_one_shot(gcm, v->keylen, v->key, v->ivlen, v->iv, v->adalen, v->ada, v->ptlen, v->pt, ct_out, v->taglen, expected_tag);
rc = rc | memcmp(ct_out, v->ct, v->ctlen) | memcmp(expected_tag, v->tag, v->taglen);
}
return rc;
}
int ccmode_gcm_test_one_vector_chained(const struct ccmode_gcm *gcm, const struct ccmode_gcm_vector *v, int dec)
{
if (v->ptlen != v->ctlen) {
return -1;
}
if (dec) {
return ccmode_gcm_test_one_chained(gcm, v->keylen, v->key, v->ivlen, v->iv, v->adalen, v->ada, v->ptlen, v->ct, v->pt, v->taglen, v->tag);
} else {
return ccmode_gcm_test_one_chained(gcm, v->keylen, v->key, v->ivlen, v->iv, v->adalen, v->ada, v->ptlen, v->pt, v->ct, v->taglen, v->tag);
}
}
/* does one XTS encryption or decryption and compare result */
int ccmode_xts_test_one(const struct ccmode_xts *xts, size_t keylen,
const void *dkey, const void *tkey, const void *iv,
size_t nbytes, const void *in, void *out,
int dec)
{
ccxts_ctx_decl(xts->size, key);
ccxts_tweak_decl(xts->tweak_size, tweak);
if (xts->init(xts, key, keylen, dkey, tkey)) {
return -1;
}
if (xts->set_tweak(key, tweak, iv)) {
return -1;
}
/* Use raw xex mode when nbytes is a multiple of the blocksize. */
if ((nbytes & 15) == 0) {
if (xts->xts(key, tweak, nbytes >> 4, in, out) == NULL) {
return -1;
}
} else {
if (dec) {
if (ccpad_xts_decrypt(xts, key, tweak, nbytes, in, out) != nbytes) {
return -1;
}
} else {
ccpad_xts_encrypt(xts, key, tweak, nbytes, in, out);
}
}
return 0;
}
/* Test one test vector - use dec=1 to reverse pt and ct */
int ccmode_xts_test_one_vector(const struct ccmode_xts *xts,
const struct ccmode_xts_vector *v, void *out,
int dec)
{
if (dec) {
return ccmode_xts_test_one(xts, v->keylen, v->dkey, v->tkey, v->tweak,
v->nbytes, v->ct, out, dec);
} else {
return ccmode_xts_test_one(xts, v->keylen, v->dkey, v->tkey, v->tweak,
v->nbytes, v->pt, out, dec);
}
}
/* Test one test vector, 1 block at a time */
int ccmode_xts_test_one_chained(const struct ccmode_xts *xts,
size_t keylen, const void *dkey,
const void *tkey, const void *iv,
size_t nbytes, const void *in,
void *out, int dec)
{
size_t i;
const unsigned char *input=in;
unsigned char *output=out;
ccxts_ctx_decl(xts->size, key);
ccxts_tweak_decl(xts->tweak_size, tweak);
if (xts->init(xts, key, keylen, dkey, tkey) != 0) {
return -1;
}
if (xts->set_tweak(key, tweak, iv)) {
return -1;
}
size_t nblocks = nbytes >> 4;
if (nbytes & 15) {
nblocks -= 1;
}
for (i=0; i < nblocks; i++) {
if (xts->xts(key, tweak, 1, &input[i*xts->block_size], &output[i*xts->block_size]) == NULL) {
return -1;
}
}
if (nbytes & 15) {
nbytes -= nblocks * xts->block_size;
if (dec) {
if (ccpad_xts_decrypt(xts, key, tweak, nbytes, &input[nblocks*xts->block_size],
&output[nblocks*xts->block_size]) != nbytes) {
return -1;
}
} else {
ccpad_xts_encrypt(xts, key, tweak, nbytes, &input[nblocks*xts->block_size],
&output[nblocks*xts->block_size]);
}
}
return 0;
}
int ccmode_xts_test_one_vector_chained(const struct ccmode_xts *xts,
const struct ccmode_xts_vector *v,
void *out, int dec)
{
if (dec) {
return ccmode_xts_test_one_chained(xts, v->keylen, v->dkey, v->tkey, v->tweak,
v->nbytes, v->ct, out, dec);
} else {
return ccmode_xts_test_one_chained(xts, v->keylen, v->dkey, v->tkey, v->tweak,
v->nbytes, v->pt, out, dec);
}
}
/* CCM */
int ccmode_ccm_test_one(const struct ccmode_ccm *ccm, size_t keylen, const void *keydata,
size_t noncelen, const void *noncedata, size_t adalen, const void *ada,
size_t nbytes, const void *in, const void *out,
size_t mac_size, const void *mac, int chained)
{
unsigned char temp[nbytes];
unsigned char tempmac[mac_size];
ccccm_ctx_decl(ccm->size, key);
ccccm_nonce_decl(ccm->nonce_size, nonce);
/* mac and crypt one byte at a time */
if (chained) {
if (ccm->init(ccm, key, keylen, keydata)) {
return -1;
}
if (ccm->set_iv(key, nonce, noncelen, noncedata, mac_size, adalen, nbytes)) {
return -1;
}
const unsigned char *p = ada;
if (adalen) {
for (unsigned i = 0; i < adalen; i++) {
if (ccm->cbcmac(key, nonce, 1, &p[i])) {
return -1;
}
}
} else {
if (ccm->cbcmac(key, nonce, 0, NULL)) {
return -1;
}
}
p = in;
if (nbytes) {
for (unsigned i = 0; i < nbytes; i++) {
if (ccm->ccm(key, nonce, 1, &p[i], &temp[i])) {
return -1;
}
}
} else {
if (ccm->ccm(key, nonce, 0, NULL, NULL)) {
return -1;
}
}
if (ccm->finalize(key, nonce, tempmac)) {
return -1;
}
} else {
if (ccccm_one_shot(ccm, keylen, keydata, noncelen, noncedata, nbytes, in, temp, adalen, ada, mac_size, tempmac)) {
return -1;
}
}
#ifdef _INTERNAL_DEBUG_
int r1, r2;
r1 = memcmp(out, temp, nbytes);
r2 = memcmp(mac, tempmac, mac_size);
if (r1 || r2)
printf("nonce_len: %u adalen: %lu nbytes: %lu taglen: %u crypt: %d tag: %d\n",
nonce_len, adalen, nbytes, mac_size, r1, r2);
return r1 != 0 ? r1 : r2;
#else
return memcmp(out, temp, nbytes) || memcmp(mac, tempmac, mac_size);
#endif
}
/* Test one test vector - use dec=1 to reverse pt and ct */
int ccmode_ccm_test_one_vector(const struct ccmode_ccm *ccm,
const struct ccmode_ccm_vector *v,
int dec, int chained)
{
if (dec) {
return ccmode_ccm_test_one(ccm, v->keylen, v->key, v->noncelen, v->nonce, v->adalen, v->ada, v->ptlen, v->ct, v->pt, (unsigned)(v->ctlen - v->ptlen), v->ct + v->ptlen, chained);
} else {
return ccmode_ccm_test_one(ccm, v->keylen, v->key, v->noncelen, v->nonce, v->adalen, v->ada, v->ptlen, v->pt, v->ct, (unsigned)(v->ctlen - v->ptlen), v->ct + v->ptlen, chained);
}
}