Home | History | Annotate | Line # | Download | only in test
cmactest.c revision 1.1
      1  1.1  christos /*
      2  1.1  christos  * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
      3  1.1  christos  *
      4  1.1  christos  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  1.1  christos  * this file except in compliance with the License.  You can obtain a copy
      6  1.1  christos  * in the file LICENSE in the source distribution or at
      7  1.1  christos  * https://www.openssl.org/source/license.html
      8  1.1  christos  */
      9  1.1  christos 
     10  1.1  christos /*
     11  1.1  christos  * CMAC low level APIs are deprecated for public use, but still ok for internal
     12  1.1  christos  * use.
     13  1.1  christos  */
     14  1.1  christos #include "internal/deprecated.h"
     15  1.1  christos 
     16  1.1  christos #include <stdio.h>
     17  1.1  christos #include <string.h>
     18  1.1  christos #include <stdlib.h>
     19  1.1  christos 
     20  1.1  christos #include "internal/nelem.h"
     21  1.1  christos 
     22  1.1  christos #include <openssl/cmac.h>
     23  1.1  christos #include <openssl/aes.h>
     24  1.1  christos #include <openssl/evp.h>
     25  1.1  christos 
     26  1.1  christos #include "testutil.h"
     27  1.1  christos 
     28  1.1  christos static const char xtskey[32] = {
     29  1.1  christos     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
     30  1.1  christos     0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
     31  1.1  christos     0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
     32  1.1  christos };
     33  1.1  christos 
     34  1.1  christos static struct test_st {
     35  1.1  christos     const char key[32];
     36  1.1  christos     int key_len;
     37  1.1  christos     unsigned char data[4096];
     38  1.1  christos     int data_len;
     39  1.1  christos     const char *mac;
     40  1.1  christos } test[] = {
     41  1.1  christos     {
     42  1.1  christos         {
     43  1.1  christos             0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
     44  1.1  christos             0x0b, 0x0c, 0x0d, 0x0e, 0x0f
     45  1.1  christos         },
     46  1.1  christos         16,
     47  1.1  christos         "My test data",
     48  1.1  christos         12,
     49  1.1  christos         "29cec977c48f63c200bd5c4a6881b224"
     50  1.1  christos     },
     51  1.1  christos     {
     52  1.1  christos         {
     53  1.1  christos             0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
     54  1.1  christos             0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
     55  1.1  christos             0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
     56  1.1  christos         },
     57  1.1  christos         32,
     58  1.1  christos         "My test data",
     59  1.1  christos         12,
     60  1.1  christos         "db6493aa04e4761f473b2b453c031c9a"
     61  1.1  christos     },
     62  1.1  christos     {
     63  1.1  christos         {
     64  1.1  christos             0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
     65  1.1  christos             0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
     66  1.1  christos             0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
     67  1.1  christos         },
     68  1.1  christos         32,
     69  1.1  christos         "My test data again",
     70  1.1  christos         18,
     71  1.1  christos         "65c11c75ecf590badd0a5e56cbb8af60"
     72  1.1  christos     },
     73  1.1  christos     /* for aes-128-cbc */
     74  1.1  christos     {
     75  1.1  christos         {
     76  1.1  christos             0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
     77  1.1  christos             0x0b, 0x0c, 0x0d, 0x0e, 0x0f
     78  1.1  christos         },
     79  1.1  christos         16,
     80  1.1  christos         /* repeat the string below until filling 3072 bytes */
     81  1.1  christos         "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#",
     82  1.1  christos         3072,
     83  1.1  christos         "35da8a02a7afce90e5b711308cee2dee"
     84  1.1  christos     },
     85  1.1  christos     /* for aes-192-cbc */
     86  1.1  christos     {
     87  1.1  christos         {
     88  1.1  christos             0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
     89  1.1  christos             0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
     90  1.1  christos             0x16, 0x17
     91  1.1  christos         },
     92  1.1  christos         24,
     93  1.1  christos         /* repeat the string below until filling 4095 bytes */
     94  1.1  christos         "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#",
     95  1.1  christos         4095,
     96  1.1  christos         "59053f4e81f3593610f987adb547c5b2"
     97  1.1  christos     },
     98  1.1  christos     /* for aes-256-cbc */
     99  1.1  christos     {
    100  1.1  christos         {
    101  1.1  christos             0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
    102  1.1  christos             0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
    103  1.1  christos             0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
    104  1.1  christos         },
    105  1.1  christos         32,
    106  1.1  christos         /* repeat the string below until filling 2560 bytes */
    107  1.1  christos         "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#",
    108  1.1  christos         2560,
    109  1.1  christos         "9c6cf85f7f4baca99725764a0df973a9"
    110  1.1  christos     },
    111  1.1  christos     /* for des-ede3-cbc */
    112  1.1  christos     {
    113  1.1  christos         {
    114  1.1  christos             0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
    115  1.1  christos             0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
    116  1.1  christos             0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
    117  1.1  christos         },
    118  1.1  christos         24,
    119  1.1  christos         /* repeat the string below until filling 2048 bytes */
    120  1.1  christos         "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#",
    121  1.1  christos         2048,
    122  1.1  christos         "2c2fccc7fcc5d98a"
    123  1.1  christos     },
    124  1.1  christos     /* for sm4-cbc */
    125  1.1  christos     {
    126  1.1  christos         {
    127  1.1  christos             0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
    128  1.1  christos             0x0b, 0x0c, 0x0d, 0x0e, 0x0f
    129  1.1  christos         },
    130  1.1  christos         16,
    131  1.1  christos         /* repeat the string below until filling 2049 bytes */
    132  1.1  christos         "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#",
    133  1.1  christos         2049,
    134  1.1  christos         "c9a9cbc82a3b2d96074e386fce1216f2"
    135  1.1  christos     },
    136  1.1  christos };
    137  1.1  christos 
    138  1.1  christos static char *pt(unsigned char *md, unsigned int len);
    139  1.1  christos 
    140  1.1  christos static int test_cmac_bad(void)
    141  1.1  christos {
    142  1.1  christos     CMAC_CTX *ctx = NULL;
    143  1.1  christos     int ret = 0;
    144  1.1  christos 
    145  1.1  christos     ctx = CMAC_CTX_new();
    146  1.1  christos     if (!TEST_ptr(ctx)
    147  1.1  christos         || !TEST_false(CMAC_Init(ctx, NULL, 0, NULL, NULL))
    148  1.1  christos         || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len))
    149  1.1  christos            /* Should be able to pass cipher first, and then key */
    150  1.1  christos         || !TEST_true(CMAC_Init(ctx, NULL, 0, EVP_aes_128_cbc(), NULL))
    151  1.1  christos            /* Must have a key */
    152  1.1  christos         || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len))
    153  1.1  christos            /* Now supply the key */
    154  1.1  christos         || !TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len, NULL, NULL))
    155  1.1  christos            /* Update should now work */
    156  1.1  christos         || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len))
    157  1.1  christos            /* XTS is not a suitable cipher to use */
    158  1.1  christos         || !TEST_false(CMAC_Init(ctx, xtskey, sizeof(xtskey), EVP_aes_128_xts(),
    159  1.1  christos                                  NULL))
    160  1.1  christos         || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len)))
    161  1.1  christos         goto err;
    162  1.1  christos 
    163  1.1  christos     ret = 1;
    164  1.1  christos err:
    165  1.1  christos     CMAC_CTX_free(ctx);
    166  1.1  christos     return ret;
    167  1.1  christos }
    168  1.1  christos 
    169  1.1  christos static int test_cmac_run(void)
    170  1.1  christos {
    171  1.1  christos     char *p;
    172  1.1  christos     CMAC_CTX *ctx = NULL;
    173  1.1  christos     unsigned char buf[AES_BLOCK_SIZE];
    174  1.1  christos     size_t len;
    175  1.1  christos     int ret = 0;
    176  1.1  christos     size_t case_idx = 0;
    177  1.1  christos 
    178  1.1  christos     ctx = CMAC_CTX_new();
    179  1.1  christos 
    180  1.1  christos     /* Construct input data, fill repeatedly until reaching data length */
    181  1.1  christos     for (case_idx = 0; case_idx < OSSL_NELEM(test); case_idx++) {
    182  1.1  christos         size_t str_len = strlen((char *)test[case_idx].data);
    183  1.1  christos         size_t fill_len = test[case_idx].data_len - str_len;
    184  1.1  christos         size_t fill_idx = str_len;
    185  1.1  christos         while (fill_len > 0) {
    186  1.1  christos             if (fill_len > str_len) {
    187  1.1  christos                 memcpy(&test[case_idx].data[fill_idx], test[case_idx].data, str_len);
    188  1.1  christos                 fill_len -= str_len;
    189  1.1  christos                 fill_idx += str_len;
    190  1.1  christos             } else {
    191  1.1  christos                 memcpy(&test[case_idx].data[fill_idx], test[case_idx].data, fill_len);
    192  1.1  christos                 fill_len = 0;
    193  1.1  christos             }
    194  1.1  christos         }
    195  1.1  christos     }
    196  1.1  christos 
    197  1.1  christos     if (!TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len,
    198  1.1  christos                              EVP_aes_128_cbc(), NULL))
    199  1.1  christos         || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len))
    200  1.1  christos         || !TEST_true(CMAC_Final(ctx, buf, &len)))
    201  1.1  christos         goto err;
    202  1.1  christos 
    203  1.1  christos     p = pt(buf, len);
    204  1.1  christos     if (!TEST_str_eq(p, test[0].mac))
    205  1.1  christos         goto err;
    206  1.1  christos 
    207  1.1  christos     if (!TEST_true(CMAC_Init(ctx, test[1].key, test[1].key_len,
    208  1.1  christos                              EVP_aes_256_cbc(), NULL))
    209  1.1  christos         || !TEST_true(CMAC_Update(ctx, test[1].data, test[1].data_len))
    210  1.1  christos         || !TEST_true(CMAC_Final(ctx, buf, &len)))
    211  1.1  christos         goto err;
    212  1.1  christos 
    213  1.1  christos     p = pt(buf, len);
    214  1.1  christos     if (!TEST_str_eq(p, test[1].mac))
    215  1.1  christos         goto err;
    216  1.1  christos 
    217  1.1  christos     if (!TEST_true(CMAC_Init(ctx, test[2].key, test[2].key_len, NULL, NULL))
    218  1.1  christos         || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len))
    219  1.1  christos         || !TEST_true(CMAC_Final(ctx, buf, &len)))
    220  1.1  christos         goto err;
    221  1.1  christos     p = pt(buf, len);
    222  1.1  christos     if (!TEST_str_eq(p, test[2].mac))
    223  1.1  christos         goto err;
    224  1.1  christos     /* Test reusing a key */
    225  1.1  christos     if (!TEST_true(CMAC_Init(ctx, NULL, 0, NULL, NULL))
    226  1.1  christos         || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len))
    227  1.1  christos         || !TEST_true(CMAC_Final(ctx, buf, &len)))
    228  1.1  christos         goto err;
    229  1.1  christos     p = pt(buf, len);
    230  1.1  christos     if (!TEST_str_eq(p, test[2].mac))
    231  1.1  christos         goto err;
    232  1.1  christos 
    233  1.1  christos     /* Test setting the cipher and key separately */
    234  1.1  christos     if (!TEST_true(CMAC_Init(ctx, NULL, 0, EVP_aes_256_cbc(), NULL))
    235  1.1  christos         || !TEST_true(CMAC_Init(ctx, test[2].key, test[2].key_len, NULL, NULL))
    236  1.1  christos         || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len))
    237  1.1  christos         || !TEST_true(CMAC_Final(ctx, buf, &len)))
    238  1.1  christos         goto err;
    239  1.1  christos     p = pt(buf, len);
    240  1.1  christos     if (!TEST_str_eq(p, test[2].mac))
    241  1.1  christos         goto err;
    242  1.1  christos 
    243  1.1  christos     /* Test data length is greater than 1 block length */
    244  1.1  christos     if (!TEST_true(CMAC_Init(ctx, test[3].key, test[3].key_len,
    245  1.1  christos                              EVP_aes_128_cbc(), NULL))
    246  1.1  christos         || !TEST_true(CMAC_Update(ctx, test[3].data, test[3].data_len))
    247  1.1  christos         || !TEST_true(CMAC_Final(ctx, buf, &len)))
    248  1.1  christos         goto err;
    249  1.1  christos     p = pt(buf, len);
    250  1.1  christos     if (!TEST_str_eq(p, test[3].mac))
    251  1.1  christos         goto err;
    252  1.1  christos 
    253  1.1  christos     if (!TEST_true(CMAC_Init(ctx, test[4].key, test[4].key_len,
    254  1.1  christos                              EVP_aes_192_cbc(), NULL))
    255  1.1  christos         || !TEST_true(CMAC_Update(ctx, test[4].data, test[4].data_len))
    256  1.1  christos         || !TEST_true(CMAC_Final(ctx, buf, &len)))
    257  1.1  christos         goto err;
    258  1.1  christos     p = pt(buf, len);
    259  1.1  christos     if (!TEST_str_eq(p, test[4].mac))
    260  1.1  christos         goto err;
    261  1.1  christos 
    262  1.1  christos     if (!TEST_true(CMAC_Init(ctx, test[5].key, test[5].key_len,
    263  1.1  christos                              EVP_aes_256_cbc(), NULL))
    264  1.1  christos         || !TEST_true(CMAC_Update(ctx, test[5].data, test[5].data_len))
    265  1.1  christos         || !TEST_true(CMAC_Final(ctx, buf, &len)))
    266  1.1  christos         goto err;
    267  1.1  christos     p = pt(buf, len);
    268  1.1  christos     if (!TEST_str_eq(p, test[5].mac))
    269  1.1  christos         goto err;
    270  1.1  christos 
    271  1.1  christos #ifndef OPENSSL_NO_DES
    272  1.1  christos     if (!TEST_true(CMAC_Init(ctx, test[6].key, test[6].key_len,
    273  1.1  christos                              EVP_des_ede3_cbc(), NULL))
    274  1.1  christos         || !TEST_true(CMAC_Update(ctx, test[6].data, test[6].data_len))
    275  1.1  christos         || !TEST_true(CMAC_Final(ctx, buf, &len)))
    276  1.1  christos         goto err;
    277  1.1  christos     p = pt(buf, len);
    278  1.1  christos     if (!TEST_str_eq(p, test[6].mac))
    279  1.1  christos         goto err;
    280  1.1  christos #endif
    281  1.1  christos 
    282  1.1  christos #ifndef OPENSSL_NO_SM4
    283  1.1  christos     if (!TEST_true(CMAC_Init(ctx, test[7].key, test[7].key_len,
    284  1.1  christos                              EVP_sm4_cbc(), NULL))
    285  1.1  christos         || !TEST_true(CMAC_Update(ctx, test[7].data, test[7].data_len))
    286  1.1  christos         || !TEST_true(CMAC_Final(ctx, buf, &len)))
    287  1.1  christos         goto err;
    288  1.1  christos     p = pt(buf, len);
    289  1.1  christos     if (!TEST_str_eq(p, test[7].mac))
    290  1.1  christos         goto err;
    291  1.1  christos #endif
    292  1.1  christos 
    293  1.1  christos     ret = 1;
    294  1.1  christos err:
    295  1.1  christos     CMAC_CTX_free(ctx);
    296  1.1  christos     return ret;
    297  1.1  christos }
    298  1.1  christos 
    299  1.1  christos static int test_cmac_copy(void)
    300  1.1  christos {
    301  1.1  christos     char *p;
    302  1.1  christos     CMAC_CTX *ctx = NULL, *ctx2 = NULL;
    303  1.1  christos     unsigned char buf[AES_BLOCK_SIZE];
    304  1.1  christos     size_t len;
    305  1.1  christos     int ret = 0;
    306  1.1  christos 
    307  1.1  christos     ctx = CMAC_CTX_new();
    308  1.1  christos     ctx2 = CMAC_CTX_new();
    309  1.1  christos     if (!TEST_ptr(ctx) || !TEST_ptr(ctx2))
    310  1.1  christos         goto err;
    311  1.1  christos 
    312  1.1  christos     if (!TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len,
    313  1.1  christos                              EVP_aes_128_cbc(), NULL))
    314  1.1  christos         || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len))
    315  1.1  christos         || !TEST_true(CMAC_CTX_copy(ctx2, ctx))
    316  1.1  christos         || !TEST_true(CMAC_Final(ctx2, buf, &len)))
    317  1.1  christos         goto err;
    318  1.1  christos 
    319  1.1  christos     p = pt(buf, len);
    320  1.1  christos     if (!TEST_str_eq(p, test[0].mac))
    321  1.1  christos         goto err;
    322  1.1  christos 
    323  1.1  christos     ret = 1;
    324  1.1  christos err:
    325  1.1  christos     CMAC_CTX_free(ctx2);
    326  1.1  christos     CMAC_CTX_free(ctx);
    327  1.1  christos     return ret;
    328  1.1  christos }
    329  1.1  christos 
    330  1.1  christos #define OSSL_HEX_CHARS_PER_BYTE 2
    331  1.1  christos static char *pt(unsigned char *md, unsigned int len)
    332  1.1  christos {
    333  1.1  christos     unsigned int i;
    334  1.1  christos     static char buf[81];
    335  1.1  christos 
    336  1.1  christos     for (i = 0; i < len && (i + 1) * OSSL_HEX_CHARS_PER_BYTE < sizeof(buf); i++)
    337  1.1  christos         BIO_snprintf(buf + i * OSSL_HEX_CHARS_PER_BYTE,
    338  1.1  christos                      OSSL_HEX_CHARS_PER_BYTE + 1, "%02x", md[i]);
    339  1.1  christos     return buf;
    340  1.1  christos }
    341  1.1  christos 
    342  1.1  christos int setup_tests(void)
    343  1.1  christos {
    344  1.1  christos     ADD_TEST(test_cmac_bad);
    345  1.1  christos     ADD_TEST(test_cmac_run);
    346  1.1  christos     ADD_TEST(test_cmac_copy);
    347  1.1  christos     return 1;
    348  1.1  christos }
    349  1.1  christos 
    350