mirror of https://github.com/openssl/openssl.git
				
				
				
			
		
			
	
	
		
			217 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C
		
	
	
	
		
		
			
		
	
	
			217 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C
		
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * 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;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 |