corecrypto/ccwrap/crypto_test/crypto_test_wrap.c

348 lines
12 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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) (2012,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 "testmore.h"
#include "testbyteBuffer.h"
static int verbose = 0;
#if (CCWRAP == 0)
entryPoint(ccwrap_tests, "ccwrap test")
#else
#include <corecrypto/ccmode.h>
#include <corecrypto/ccaes.h>
#include <corecrypto/ccwrap_priv.h>
#define KEY128 "000102030405060708090a0b0c0d0e0f"
#define KEY192 "000102030405060708090a0b0c0d0e0f0001020304050607"
#define KEY256 "000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f"
#define KEY512 \
"000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d" \
"0e0f000102030405060708090a0b0c0d0e0f"
struct ccwrap_vector {
size_t count;
const char *kek; // Key to encrypt the input
const char *key; // Input
const char *wrap; // Wrapped input
int error;
};
const struct ccwrap_vector ccwrap_aes_vectors[] = {
// Toy sample
{
.count = 0,
.kek = "f59782f1dceb0544a8da06b34969b9212b55ce6dcbdd0975a33f4b3f88b538da",
.key = "73d33060b5f9f2eb5785c0703ddfa704",
.wrap = "2e63946ea3c090902fa1558375fdb2907742ac74e39403fc",
.error = CCERR_OK,
},
// Test vectors
#include "../test_vectors/KW_AD_128.inc"
#include "../test_vectors/KW_AD_192.inc"
#include "../test_vectors/KW_AD_256.inc"
#include "../test_vectors/KW_AE_128.inc"
#include "../test_vectors/KW_AE_192.inc"
#include "../test_vectors/KW_AE_256.inc"
};
static int test_wrap(const struct ccmode_ecb *enc_ecb,
const struct ccmode_ecb *dec_ecb,
const char *keydata,
const char *kekdata)
{
ccecb_ctx_decl(enc_ecb->size, enc_ctx);
ccecb_ctx_decl(dec_ecb->size, dec_ctx);
byteBuffer kek = hexStringToBytes(kekdata);
ccecb_init(enc_ecb, enc_ctx, kek->len, kek->bytes);
ccecb_init(dec_ecb, dec_ctx, kek->len, kek->bytes);
byteBuffer key = hexStringToBytes(keydata);
size_t wrapped_size = ccwrap_wrapped_size(key->len);
byteBuffer wrapped_key = mallocByteBuffer(wrapped_size);
uint8_t iv[CCWRAP_SEMIBLOCK] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
is(ccwrap_auth_encrypt(
enc_ecb, enc_ctx, key->len, key->bytes, &wrapped_size, wrapped_key->bytes),
CCERR_OK,
"Wrapped Key");
size_t unwrapped_size = ccwrap_unwrapped_size(wrapped_size);
byteBuffer unwrapped_key = mallocByteBuffer(unwrapped_size);
is(ccwrap_auth_decrypt(dec_ecb,
dec_ctx,
wrapped_key->len,
wrapped_key->bytes,
&unwrapped_size,
unwrapped_key->bytes),
CCERR_OK,
"Unwrapped Key");
ok(bytesAreEqual(key, unwrapped_key), "Round Trip Success");
wrapped_key->bytes[0] ^= 1;
is(ccwrap_auth_decrypt(dec_ecb,
dec_ctx,
wrapped_key->len,
wrapped_key->bytes,
&unwrapped_size,
unwrapped_key->bytes),
CCERR_INTEGRITY,
"Integrity Check");
free(unwrapped_key);
is(ccwrap_auth_encrypt_withiv(enc_ecb,
enc_ctx,
key->len,
key->bytes,
&wrapped_size,
wrapped_key->bytes,
&iv),
CCERR_OK,
"Wrapped Key (with iv)");
unwrapped_size = ccwrap_unwrapped_size(wrapped_size);
unwrapped_key = mallocByteBuffer(unwrapped_size);
is(ccwrap_auth_decrypt_withiv(dec_ecb,
dec_ctx,
wrapped_key->len,
wrapped_key->bytes,
&unwrapped_size,
unwrapped_key->bytes,
&iv),
CCERR_OK,
"Unwrapped Key (with iv)");
ok(bytesAreEqual(key, unwrapped_key), "Round Trip Success (with iv)");
wrapped_key->bytes[0] ^= 1;
is(ccwrap_auth_decrypt_withiv(dec_ecb,
dec_ctx,
wrapped_key->len,
wrapped_key->bytes,
&unwrapped_size,
unwrapped_key->bytes,
&iv),
CCERR_INTEGRITY,
"Integrity Check (with iv)");
free(kek);
free(key);
free(wrapped_key);
free(unwrapped_key);
return 1;
}
static int test_kat_wrap(const struct ccmode_ecb *enc_ecb,
const struct ccmode_ecb *dec_ecb,
const struct ccwrap_vector *tv)
{
ccecb_ctx_decl(enc_ecb->size, enc_ctx);
ccecb_ctx_decl(dec_ecb->size, dec_ctx);
byteBuffer kek = hexStringToBytes(tv->kek);
byteBuffer key = hexStringToBytes(tv->key);
int rc = 1;
rc &= is(ccecb_init(enc_ecb, enc_ctx, kek->len, kek->bytes), CCERR_OK, "Enc init");
rc &= is(ccecb_init(dec_ecb, dec_ctx, kek->len, kek->bytes), CCERR_OK, "Dec init");
if (tv->error == CCERR_OK) {
size_t wrapped_size = ccwrap_wrapped_size(key->len);
size_t unwrapped_size = ccwrap_unwrapped_size(wrapped_size);
byteBuffer computed_wrapped_key = mallocByteBuffer(wrapped_size);
byteBuffer expected_wrapped_key = hexStringToBytes(tv->wrap);
byteBuffer unwrapped_key = mallocByteBuffer(unwrapped_size);
rc &= is(
ccwrap_auth_encrypt(
enc_ecb, enc_ctx, key->len, key->bytes, &wrapped_size, computed_wrapped_key->bytes),
CCERR_OK,
"Wrapped Key");
rc &= ok(bytesAreEqual(computed_wrapped_key, expected_wrapped_key), "Wrap Success");
rc &= is(ccwrap_auth_decrypt(dec_ecb,
dec_ctx,
wrapped_size,
computed_wrapped_key->bytes,
&unwrapped_size,
unwrapped_key->bytes),
CCERR_OK,
"Unwrapping");
rc &= ok(bytesAreEqual(key, unwrapped_key), "Round Trip Success");
free(computed_wrapped_key);
free(expected_wrapped_key);
free(unwrapped_key);
} else if (tv->error == CCERR_INTEGRITY) {
byteBuffer wrapped_key = hexStringToBytes(tv->wrap);
size_t unwrapped_size = ccwrap_unwrapped_size(wrapped_key->len);
byteBuffer unwrapped_key = mallocByteBuffer(unwrapped_size);
rc &= is(ccwrap_auth_decrypt(dec_ecb,
dec_ctx,
wrapped_key->len,
wrapped_key->bytes,
&unwrapped_size,
unwrapped_key->bytes),
CCERR_INTEGRITY,
"Integrity");
free(wrapped_key);
free(unwrapped_key);
} else {
fail("test_kat_wrap unknown error");
}
free(kek);
free(key);
return rc;
}
static int test_ccwrap_wrapped_size(void)
{
size_t i;
size_t vectors[][2] = {
{ CCWRAP_SEMIBLOCK * 2, CCWRAP_SEMIBLOCK * 3 },
{ 0, CCWRAP_SEMIBLOCK },
};
size_t nvectors = (sizeof vectors) / (sizeof vectors[0]);
int rc = 0;
for (i = 0; i < nvectors; i += 1) {
rc |= is(ccwrap_wrapped_size(vectors[i][0]), vectors[i][1], "Unwrapped size");
}
return rc;
}
static int test_ccwrap_unwrapped_size(void)
{
size_t i;
size_t vectors[][2] = {
{ CCWRAP_SEMIBLOCK * 3, CCWRAP_SEMIBLOCK * 2 },
{ CCWRAP_SEMIBLOCK, 0 },
{ CCWRAP_SEMIBLOCK - 1, 0 },
{ 0, 0 },
};
size_t nvectors = (sizeof vectors) / (sizeof vectors[0]);
int rc = 0;
for (i = 0; i < nvectors; i += 1) {
rc |= is(ccwrap_unwrapped_size(vectors[i][0]), vectors[i][1], "Unwrapped size");
}
return rc;
}
static int test_ccwrap_auth_encrypt_bad_nbytes(void)
{
int rc = 0;
const struct ccmode_ecb *enc_ecb = ccaes_ecb_encrypt_mode();
ccecb_ctx_decl(enc_ecb->size, enc_ctx);
byteBuffer kek = hexStringToBytes(KEY128);
ccecb_init(enc_ecb, enc_ctx, kek->len, kek->bytes);
size_t i;
size_t vectors[] = {
CCWRAP_SEMIBLOCK,
CCWRAP_SEMIBLOCK * 2 + 1,
// this amount is only valid in the unwrap direction
CCWRAP_SEMIBLOCK * CCWRAP_MAXSEMIBLOCKS,
};
size_t nvectors = sizeof vectors / sizeof vectors[0];
for (i = 0; i < nvectors; i += 1) {
size_t nbytes = vectors[i];
size_t obytes = ccwrap_wrapped_size(nbytes);
uint8_t key[nbytes];
uint8_t wrapped[obytes];
rc |= is(ccwrap_auth_encrypt(enc_ecb, enc_ctx, nbytes, key, &obytes, wrapped),
CCERR_PARAMETER,
"encrypt bad nbytes");
}
free(kek);
return rc;
}
static int test_ccwrap_auth_decrypt_bad_nbytes(void)
{
int rc = 0;
const struct ccmode_ecb *dec_ecb = ccaes_ecb_decrypt_mode();
ccecb_ctx_decl(dec_ecb->size, dec_ctx);
byteBuffer kek = hexStringToBytes(KEY128);
ccecb_init(dec_ecb, dec_ctx, kek->len, kek->bytes);
size_t i;
size_t vectors[] = {
CCWRAP_SEMIBLOCK * 2,
CCWRAP_SEMIBLOCK * 3 + 1,
CCWRAP_SEMIBLOCK * (CCWRAP_MAXSEMIBLOCKS + 1),
};
size_t nvectors = sizeof vectors / sizeof vectors[0];
for (i = 0; i < nvectors; i += 1) {
size_t nbytes = vectors[i];
size_t obytes = ccwrap_unwrapped_size(nbytes);
uint8_t wrapped[nbytes];
uint8_t key[obytes];
rc |= is(ccwrap_auth_decrypt(dec_ecb, dec_ctx, nbytes, wrapped, &obytes, key),
CCERR_PARAMETER,
"decrypt bad nbytes");
}
free(kek);
return rc;
}
int ccwrap_tests(TM_UNUSED int argc, TM_UNUSED char *const *argv)
{
plan_tests(20204);
if (verbose)
diag("Starting ccwrap tests\n");
const struct ccmode_ecb *enc_ecb = ccaes_ecb_encrypt_mode();
const struct ccmode_ecb *dec_ecb = ccaes_ecb_decrypt_mode();
for (size_t i = 0; i < sizeof(ccwrap_aes_vectors) / sizeof(struct ccwrap_vector); i++) {
ok(test_kat_wrap(enc_ecb, dec_ecb, &ccwrap_aes_vectors[i]),
"AES key size %u, plaintext size %u, count %d",
ccwrap_aes_vectors[i].kek == NULL ? 0 : strlen(ccwrap_aes_vectors[i].kek) / 2,
ccwrap_aes_vectors[i].key == NULL ? 0 : strlen(ccwrap_aes_vectors[i].key) / 2,
ccwrap_aes_vectors[i].count);
}
ok(test_wrap(enc_ecb, dec_ecb, KEY128, KEY128), "ccwrap of 128 bit key with 128 bit kek");
ok(test_wrap(enc_ecb, dec_ecb, KEY256, KEY128), "ccwrap of 256 bit key with 128 bit kek");
ok(test_wrap(enc_ecb, dec_ecb, KEY512, KEY128), "ccwrap of 512 bit key with 128 bit kek");
ok(test_wrap(enc_ecb, dec_ecb, KEY128, KEY192), "ccwrap of 128 bit key with 192 bit kek");
ok(test_wrap(enc_ecb, dec_ecb, KEY256, KEY192), "ccwrap of 256 bit key with 192 bit kek");
ok(test_wrap(enc_ecb, dec_ecb, KEY512, KEY192), "ccwrap of 512 bit key with 192 bit kek");
ok(test_wrap(enc_ecb, dec_ecb, KEY128, KEY256), "ccwrap of 128 bit key with 256 bit kek");
ok(test_wrap(enc_ecb, dec_ecb, KEY256, KEY256), "ccwrap of 256 bit key with 256 bit kek");
ok(test_wrap(enc_ecb, dec_ecb, KEY512, KEY256), "ccwrap of 512 bit key with 256 bit kek");
ok(test_ccwrap_wrapped_size(), "wrapped size");
ok(test_ccwrap_unwrapped_size(), "unwrapped size");
ok(test_ccwrap_auth_encrypt_bad_nbytes(), "encrypt bad nbytes");
ok(test_ccwrap_auth_decrypt_bad_nbytes(), "decrypt bad nbytes");
return 0;
}
#endif