/*
 * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

/*
 * CMAC low level APIs are deprecated for public use, but still ok for internal
 * use.
 */
#include "internal/deprecated.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "internal/nelem.h"

#include <openssl/cmac.h>
#include <openssl/aes.h>
#include <openssl/evp.h>

#include "testutil.h"

static const char xtskey[32] = {
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
    0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
};

static struct test_st {
    const char key[32];
    int key_len;
    const unsigned char data[64];
    int data_len;
    const char *mac;
} test[3] = {
    {
        {
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
            0x0b, 0x0c, 0x0d, 0x0e, 0x0f
        },
        16,
        "My test data",
        12,
        "29cec977c48f63c200bd5c4a6881b224"
    },
    {
        {
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
            0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
            0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
        },
        32,
        "My test data",
        12,
        "db6493aa04e4761f473b2b453c031c9a"
    },
    {
        {
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
            0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
            0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
        },
        32,
        "My test data again",
        18,
        "65c11c75ecf590badd0a5e56cbb8af60"
    },
};

static char *pt(unsigned char *md, unsigned int len);

static int test_cmac_bad(void)
{
    CMAC_CTX *ctx = NULL;
    int ret = 0;

    ctx = CMAC_CTX_new();
    if (!TEST_ptr(ctx)
        || !TEST_false(CMAC_Init(ctx, NULL, 0, NULL, NULL))
        || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len))
           /* Should be able to pass cipher first, and then key */
        || !TEST_true(CMAC_Init(ctx, NULL, 0, EVP_aes_128_cbc(), NULL))
           /* Must have a key */
        || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len))
           /* Now supply the key */
        || !TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len, NULL, NULL))
           /* Update should now work */
        || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len))
           /* XTS is not a suitable cipher to use */
        || !TEST_false(CMAC_Init(ctx, xtskey, sizeof(xtskey), EVP_aes_128_xts(),
                                 NULL))
        || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len)))
        goto err;

    ret = 1;
err:
    CMAC_CTX_free(ctx);
    return ret;
}

static int test_cmac_run(void)
{
    char *p;
    CMAC_CTX *ctx = NULL;
    unsigned char buf[AES_BLOCK_SIZE];
    size_t len;
    int ret = 0;

    ctx = CMAC_CTX_new();

    if (!TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len,
                             EVP_aes_128_cbc(), NULL))
        || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len))
        || !TEST_true(CMAC_Final(ctx, buf, &len)))
        goto err;

    p = pt(buf, len);
    if (!TEST_str_eq(p, test[0].mac))
        goto err;

    if (!TEST_true(CMAC_Init(ctx, test[1].key, test[1].key_len,
                             EVP_aes_256_cbc(), NULL))
        || !TEST_true(CMAC_Update(ctx, test[1].data, test[1].data_len))
        || !TEST_true(CMAC_Final(ctx, buf, &len)))
        goto err;

    p = pt(buf, len);
    if (!TEST_str_eq(p, test[1].mac))
        goto err;

    if (!TEST_true(CMAC_Init(ctx, test[2].key, test[2].key_len, NULL, NULL))
        || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len))
        || !TEST_true(CMAC_Final(ctx, buf, &len)))
        goto err;
    p = pt(buf, len);
    if (!TEST_str_eq(p, test[2].mac))
        goto err;
    /* Test reusing a key */
    if (!TEST_true(CMAC_Init(ctx, NULL, 0, NULL, NULL))
        || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len))
        || !TEST_true(CMAC_Final(ctx, buf, &len)))
        goto err;
    p = pt(buf, len);
    if (!TEST_str_eq(p, test[2].mac))
        goto err;

    /* Test setting the cipher and key separately */
    if (!TEST_true(CMAC_Init(ctx, NULL, 0, EVP_aes_256_cbc(), NULL))
        || !TEST_true(CMAC_Init(ctx, test[2].key, test[2].key_len, NULL, NULL))
        || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len))
        || !TEST_true(CMAC_Final(ctx, buf, &len)))
        goto err;
    p = pt(buf, len);
    if (!TEST_str_eq(p, test[2].mac))
        goto err;

    ret = 1;
err:
    CMAC_CTX_free(ctx);
    return ret;
}

static int test_cmac_copy(void)
{
    char *p;
    CMAC_CTX *ctx = NULL, *ctx2 = NULL;
    unsigned char buf[AES_BLOCK_SIZE];
    size_t len;
    int ret = 0;

    ctx = CMAC_CTX_new();
    ctx2 = CMAC_CTX_new();
    if (!TEST_ptr(ctx) || !TEST_ptr(ctx2))
        goto err;

    if (!TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len,
                             EVP_aes_128_cbc(), NULL))
        || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len))
        || !TEST_true(CMAC_CTX_copy(ctx2, ctx))
        || !TEST_true(CMAC_Final(ctx2, buf, &len)))
        goto err;

    p = pt(buf, len);
    if (!TEST_str_eq(p, test[0].mac))
        goto err;

    ret = 1;
err:
    CMAC_CTX_free(ctx2);
    CMAC_CTX_free(ctx);
    return ret;
}

static char *pt(unsigned char *md, unsigned int len)
{
    unsigned int i;
    static char buf[80];

    for (i = 0; i < len; i++)
        sprintf(&(buf[i * 2]), "%02x", md[i]);
    return buf;
}

int setup_tests(void)
{
    ADD_TEST(test_cmac_bad);
    ADD_TEST(test_cmac_run);
    ADD_TEST(test_cmac_copy);
    return 1;
}

