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