Blame src/lib/crypto/crypto_tests/t_cmac.c

Packit fd8b60
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
Packit fd8b60
/* lib/crypto/crypto_tests/t_cmac.c */
Packit fd8b60
/*
Packit fd8b60
 * Copyright 2010 by the Massachusetts Institute of Technology.
Packit fd8b60
 * All Rights Reserved.
Packit fd8b60
 *
Packit fd8b60
 * Export of this software from the United States of America may
Packit fd8b60
 *   require a specific license from the United States Government.
Packit fd8b60
 *   It is the responsibility of any person or organization contemplating
Packit fd8b60
 *   export to obtain such a license before exporting.
Packit fd8b60
 *
Packit fd8b60
 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
Packit fd8b60
 * distribute this software and its documentation for any purpose and
Packit fd8b60
 * without fee is hereby granted, provided that the above copyright
Packit fd8b60
 * notice appear in all copies and that both that copyright notice and
Packit fd8b60
 * this permission notice appear in supporting documentation, and that
Packit fd8b60
 * the name of M.I.T. not be used in advertising or publicity pertaining
Packit fd8b60
 * to distribution of the software without specific, written prior
Packit fd8b60
 * permission.  Furthermore if you modify this software you must label
Packit fd8b60
 * your software as modified software and not distribute it in such a
Packit fd8b60
 * fashion that it might be confused with the original M.I.T. software.
Packit fd8b60
 * M.I.T. makes no representations about the suitability of
Packit fd8b60
 * this software for any purpose.  It is provided "as is" without express
Packit fd8b60
 * or implied warranty.
Packit fd8b60
 */
Packit fd8b60
Packit fd8b60
/*
Packit fd8b60
 * Test vectors for CMAC.  Inputs are taken from RFC 4493 section 4.  Outputs
Packit fd8b60
 * are changed for the use of Camellia-128 in place of AES-128.
Packit fd8b60
 *
Packit fd8b60
 * Ideally we would double-check subkey values, but we have no easy way to see
Packit fd8b60
 * them.
Packit fd8b60
 *
Packit fd8b60
 * Ideally we would test AES-CMAC against the expected results in RFC 4493,
Packit fd8b60
 * instead of Camellia-CMAC against results we generated ourselves.  This has
Packit fd8b60
 * been done manually, but is not convenient to do automatically since the
Packit fd8b60
 * AES-128 enc provider has no cbc_mac method and therefore cannot be used with
Packit fd8b60
 * krb5int_cmac_checksum.
Packit fd8b60
 */
Packit fd8b60
Packit fd8b60
#include "crypto_int.h"
Packit fd8b60
Packit fd8b60
/* All examples use the following Camellia-128 key. */
Packit fd8b60
static unsigned char keybytes[] = {
Packit fd8b60
    0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
Packit fd8b60
    0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
Packit fd8b60
};
Packit fd8b60
Packit fd8b60
/* Example inputs are this message truncated to 0, 16, 40, and 64 bytes. */
Packit fd8b60
unsigned char input[] = {
Packit fd8b60
    0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
Packit fd8b60
    0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
Packit fd8b60
    0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
Packit fd8b60
    0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
Packit fd8b60
    0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
Packit fd8b60
    0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
Packit fd8b60
    0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
Packit fd8b60
    0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
Packit fd8b60
};
Packit fd8b60
Packit fd8b60
/* Expected result of CMAC on empty input. */
Packit fd8b60
static unsigned char cmac1[] = {
Packit fd8b60
    0xba, 0x92, 0x57, 0x82, 0xaa, 0xa1, 0xf5, 0xd9,
Packit fd8b60
    0xa0, 0x0f, 0x89, 0x64, 0x80, 0x94, 0xfc, 0x71
Packit fd8b60
};
Packit fd8b60
Packit fd8b60
/* Expected result of CMAC on first 16 bytes of input. */
Packit fd8b60
static unsigned char cmac2[] = {
Packit fd8b60
    0x6d, 0x96, 0x28, 0x54, 0xa3, 0xb9, 0xfd, 0xa5,
Packit fd8b60
    0x6d, 0x7d, 0x45, 0xa9, 0x5e, 0xe1, 0x79, 0x93
Packit fd8b60
};
Packit fd8b60
Packit fd8b60
/* Expected result of CMAC on first 40 bytes of input. */
Packit fd8b60
static unsigned char cmac3[] = {
Packit fd8b60
    0x5c, 0x18, 0xd1, 0x19, 0xcc, 0xd6, 0x76, 0x61,
Packit fd8b60
    0x44, 0xac, 0x18, 0x66, 0x13, 0x1d, 0x9f, 0x22
Packit fd8b60
};
Packit fd8b60
Packit fd8b60
/* Expected result of CMAC on all 64 bytes of input. */
Packit fd8b60
static unsigned char cmac4[] = {
Packit fd8b60
    0xc2, 0x69, 0x9a, 0x6e, 0xba, 0x55, 0xce, 0x9d,
Packit fd8b60
    0x93, 0x9a, 0x8a, 0x4e, 0x19, 0x46, 0x6e, 0xe9
Packit fd8b60
};
Packit fd8b60
Packit fd8b60
static void
Packit fd8b60
check_result(const char *name, const unsigned char *result,
Packit fd8b60
             const unsigned char *expected)
Packit fd8b60
{
Packit fd8b60
    int i;
Packit fd8b60
Packit fd8b60
    for (i = 0; i < 16; i++) {
Packit fd8b60
        if (result[i] != expected[i]) {
Packit fd8b60
            fprintf(stderr, "CMAC test vector failure: %s\n", name);
Packit fd8b60
            exit(1);
Packit fd8b60
        }
Packit fd8b60
    }
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
int
Packit fd8b60
main(int argc, char **argv)
Packit fd8b60
{
Packit fd8b60
    krb5_error_code ret;
Packit fd8b60
    krb5_context context = NULL;
Packit fd8b60
    krb5_keyblock keyblock;
Packit fd8b60
    krb5_key key;
Packit fd8b60
    const struct krb5_enc_provider *enc = &krb5int_enc_camellia128;
Packit fd8b60
    krb5_crypto_iov iov;
Packit fd8b60
    unsigned char resultbuf[16];
Packit fd8b60
    krb5_data result = make_data(resultbuf, 16);
Packit fd8b60
Packit fd8b60
    /* Create the example key. */
Packit fd8b60
    keyblock.magic = KV5M_KEYBLOCK;
Packit fd8b60
    keyblock.enctype = ENCTYPE_CAMELLIA128_CTS_CMAC;
Packit fd8b60
    keyblock.length = 16;
Packit fd8b60
    keyblock.contents = keybytes;
Packit fd8b60
    ret = krb5_k_create_key(context, &keyblock, &key);
Packit fd8b60
    assert(!ret);
Packit fd8b60
Packit fd8b60
    /* Example 1. */
Packit fd8b60
    iov.flags = KRB5_CRYPTO_TYPE_DATA;
Packit fd8b60
    iov.data = make_data(input, 0);
Packit fd8b60
    ret = krb5int_cmac_checksum(enc, key, &iov, 1, &result);
Packit fd8b60
    assert(!ret);
Packit fd8b60
    check_result("example 1", resultbuf, cmac1);
Packit fd8b60
Packit fd8b60
    /* Example 2. */
Packit fd8b60
    iov.data.length = 16;
Packit fd8b60
    ret = krb5int_cmac_checksum(enc, key, &iov, 1, &result);
Packit fd8b60
    assert(!ret);
Packit fd8b60
    check_result("example 2", resultbuf, cmac2);
Packit fd8b60
Packit fd8b60
    /* Example 3. */
Packit fd8b60
    iov.data.length = 40;
Packit fd8b60
    ret = krb5int_cmac_checksum(enc, key, &iov, 1, &result);
Packit fd8b60
    assert(!ret);
Packit fd8b60
    check_result("example 3", resultbuf, cmac3);
Packit fd8b60
Packit fd8b60
    /* Example 4. */
Packit fd8b60
    iov.data.length = 64;
Packit fd8b60
    ret = krb5int_cmac_checksum(enc, key, &iov, 1, &result);
Packit fd8b60
    assert(!ret);
Packit fd8b60
    check_result("example 4", resultbuf, cmac4);
Packit fd8b60
Packit fd8b60
    printf("All CMAC tests passed.\n");
Packit fd8b60
    krb5_k_free_key(context, key);
Packit fd8b60
    return 0;
Packit fd8b60
}