Home | History | Annotate | Line # | Download | only in test
      1      1.1  christos /*
      2      1.1  christos  * Copyright 2023-2024 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 #include <openssl/evp.h>
     11      1.1  christos #include <openssl/rand.h>
     12      1.1  christos #include <openssl/core_names.h>
     13      1.1  christos #include "testutil.h"
     14      1.1  christos #include "internal/nelem.h"
     15      1.1  christos 
     16      1.1  christos static const unsigned char shake256_input[] = {
     17      1.1  christos     0x8d, 0x80, 0x01, 0xe2, 0xc0, 0x96, 0xf1, 0xb8,
     18      1.1  christos     0x8e, 0x7c, 0x92, 0x24, 0xa0, 0x86, 0xef, 0xd4,
     19      1.1  christos     0x79, 0x7f, 0xbf, 0x74, 0xa8, 0x03, 0x3a, 0x2d,
     20      1.1  christos     0x42, 0x2a, 0x2b, 0x6b, 0x8f, 0x67, 0x47, 0xe4
     21      1.1  christos };
     22      1.1  christos 
     23      1.1  christos /*
     24      1.1  christos  * This KAT output is 250 bytes, which is more than
     25      1.1  christos  * the SHAKE256 block size (136 bytes).
     26      1.1  christos  */
     27      1.1  christos static const unsigned char shake256_output[] = {
     28      1.1  christos     0x2e, 0x97, 0x5f, 0x6a, 0x8a, 0x14, 0xf0, 0x70,
     29      1.1  christos     0x4d, 0x51, 0xb1, 0x36, 0x67, 0xd8, 0x19, 0x5c,
     30      1.1  christos     0x21, 0x9f, 0x71, 0xe6, 0x34, 0x56, 0x96, 0xc4,
     31      1.1  christos     0x9f, 0xa4, 0xb9, 0xd0, 0x8e, 0x92, 0x25, 0xd3,
     32      1.1  christos     0xd3, 0x93, 0x93, 0x42, 0x51, 0x52, 0xc9, 0x7e,
     33      1.1  christos     0x71, 0xdd, 0x24, 0x60, 0x1c, 0x11, 0xab, 0xcf,
     34      1.1  christos     0xa0, 0xf1, 0x2f, 0x53, 0xc6, 0x80, 0xbd, 0x3a,
     35      1.1  christos     0xe7, 0x57, 0xb8, 0x13, 0x4a, 0x9c, 0x10, 0xd4,
     36      1.1  christos     0x29, 0x61, 0x58, 0x69, 0x21, 0x7f, 0xdd, 0x58,
     37      1.1  christos     0x85, 0xc4, 0xdb, 0x17, 0x49, 0x85, 0x70, 0x3a,
     38      1.1  christos     0x6d, 0x6d, 0xe9, 0x4a, 0x66, 0x7e, 0xac, 0x30,
     39      1.1  christos     0x23, 0x44, 0x3a, 0x83, 0x37, 0xae, 0x1b, 0xc6,
     40      1.1  christos     0x01, 0xb7, 0x6d, 0x7d, 0x38, 0xec, 0x3c, 0x34,
     41      1.1  christos     0x46, 0x31, 0x05, 0xf0, 0xd3, 0x94, 0x9d, 0x78,
     42      1.1  christos     0xe5, 0x62, 0xa0, 0x39, 0xe4, 0x46, 0x95, 0x48,
     43      1.1  christos     0xb6, 0x09, 0x39, 0x5d, 0xe5, 0xa4, 0xfd, 0x43,
     44      1.1  christos     0xc4, 0x6c, 0xa9, 0xfd, 0x6e, 0xe2, 0x9a, 0xda,
     45      1.1  christos     0x5e, 0xfc, 0x07, 0xd8, 0x4d, 0x55, 0x32, 0x49,
     46      1.1  christos     0x45, 0x0d, 0xab, 0x4a, 0x49, 0xc4, 0x83, 0xde,
     47      1.1  christos     0xd2, 0x50, 0xc9, 0x33, 0x8f, 0x85, 0xcd, 0x93,
     48      1.1  christos     0x7a, 0xe6, 0x6b, 0xb4, 0x36, 0xf3, 0xb4, 0x02,
     49      1.1  christos     0x6e, 0x85, 0x9f, 0xda, 0x1c, 0xa5, 0x71, 0x43,
     50      1.1  christos     0x2f, 0x3b, 0xfc, 0x09, 0xe7, 0xc0, 0x3c, 0xa4,
     51      1.1  christos     0xd1, 0x83, 0xb7, 0x41, 0x11, 0x1c, 0xa0, 0x48,
     52      1.1  christos     0x3d, 0x0e, 0xda, 0xbc, 0x03, 0xfe, 0xb2, 0x3b,
     53      1.1  christos     0x17, 0xee, 0x48, 0xe8, 0x44, 0xba, 0x24, 0x08,
     54      1.1  christos     0xd9, 0xdc, 0xfd, 0x01, 0x39, 0xd2, 0xe8, 0xc7,
     55      1.1  christos     0x31, 0x01, 0x25, 0xae, 0xe8, 0x01, 0xc6, 0x1a,
     56      1.1  christos     0xb7, 0x90, 0x0d, 0x1e, 0xfc, 0x47, 0xc0, 0x78,
     57      1.1  christos     0x28, 0x17, 0x66, 0xf3, 0x61, 0xc5, 0xe6, 0x11,
     58      1.1  christos     0x13, 0x46, 0x23, 0x5e, 0x1d, 0xc3, 0x83, 0x25,
     59      1.1  christos     0x66, 0x6c
     60      1.1  christos };
     61      1.1  christos 
     62      1.1  christos static const unsigned char shake256_largemsg_input[] = {
     63      1.1  christos     0xb2, 0xd2, 0x38, 0x65, 0xaf, 0x8f, 0x25, 0x6e,
     64      1.1  christos     0x64, 0x40, 0xe2, 0x0d, 0x49, 0x8e, 0x3e, 0x64,
     65      1.1  christos     0x46, 0xd2, 0x03, 0xa4, 0x19, 0xe3, 0x7b, 0x80,
     66      1.1  christos     0xf7, 0x2b, 0x32, 0xe2, 0x76, 0x01, 0xfe, 0xdd,
     67      1.1  christos     0xaa, 0x33, 0x3d, 0xe4, 0x8e, 0xe1, 0x5e, 0x39,
     68      1.1  christos     0xa6, 0x92, 0xa3, 0xa7, 0xe3, 0x81, 0x24, 0x74,
     69      1.1  christos     0xc7, 0x38, 0x18, 0x92, 0xc9, 0x60, 0x50, 0x15,
     70      1.1  christos     0xfb, 0xd8, 0x04, 0xea, 0xea, 0x04, 0xd2, 0xc5,
     71      1.1  christos     0xc6, 0x68, 0x04, 0x5b, 0xc3, 0x75, 0x12, 0xd2,
     72      1.1  christos     0xbe, 0xa2, 0x67, 0x75, 0x24, 0xbf, 0x68, 0xad,
     73      1.1  christos     0x10, 0x86, 0xb3, 0x2c, 0xb3, 0x74, 0xa4, 0x6c,
     74      1.1  christos     0xf9, 0xd7, 0x1e, 0x58, 0x69, 0x27, 0x88, 0x49,
     75      1.1  christos     0x4e, 0x99, 0x15, 0x33, 0x14, 0xf2, 0x49, 0x21,
     76      1.1  christos     0xf4, 0x99, 0xb9, 0xde, 0xd4, 0xf1, 0x12, 0xf5,
     77      1.1  christos     0x68, 0xe5, 0x5c, 0xdc, 0x9e, 0xc5, 0x80, 0x6d,
     78      1.1  christos     0x39, 0x50, 0x08, 0x95, 0xbb, 0x12, 0x27, 0x50,
     79      1.1  christos     0x89, 0xf0, 0xf9, 0xd5, 0x4a, 0x01, 0x0b, 0x0d,
     80      1.1  christos     0x90, 0x9f, 0x1e, 0x4a, 0xba, 0xbe, 0x28, 0x36,
     81      1.1  christos     0x19, 0x7d, 0x9c, 0x0a, 0x51, 0xfb, 0xeb, 0x00,
     82      1.1  christos     0x02, 0x6c, 0x4b, 0x0a, 0xa8, 0x6c, 0xb7, 0xc4,
     83      1.1  christos     0xc0, 0x92, 0x37, 0xa7, 0x2d, 0x49, 0x61, 0x80,
     84      1.1  christos     0xd9, 0xdb, 0x20, 0x21, 0x9f, 0xcf, 0xb4, 0x57,
     85      1.1  christos     0x69, 0x75, 0xfa, 0x1c, 0x95, 0xbf, 0xee, 0x0d,
     86      1.1  christos     0x9e, 0x52, 0x6e, 0x1e, 0xf8, 0xdd, 0x41, 0x8c,
     87      1.1  christos     0x3b, 0xaa, 0x57, 0x13, 0x84, 0x73, 0x52, 0x62,
     88      1.1  christos     0x18, 0x76, 0x46, 0xcc, 0x4b, 0xcb, 0xbd, 0x40,
     89      1.1  christos     0xa1, 0xf6, 0xff, 0x7b, 0x32, 0xb9, 0x90, 0x7c,
     90      1.1  christos     0x53, 0x2c, 0xf9, 0x38, 0x72, 0x0f, 0xcb, 0x90,
     91      1.1  christos     0x42, 0x5e, 0xe2, 0x80, 0x19, 0x26, 0xe7, 0x99,
     92      1.1  christos     0x96, 0x98, 0x18, 0xb1, 0x86, 0x5b, 0x4c, 0xd9,
     93      1.1  christos     0x08, 0x27, 0x31, 0x8f, 0xf0, 0x90, 0xd9, 0x35,
     94      1.1  christos     0x6a, 0x1f, 0x75, 0xc2, 0xe0, 0xa7, 0x60, 0xb8,
     95      1.1  christos     0x1d, 0xd6, 0x5f, 0x56, 0xb2, 0x0b, 0x27, 0x0e,
     96      1.1  christos     0x98, 0x67, 0x1f, 0x39, 0x18, 0x27, 0x68, 0x0a,
     97      1.1  christos     0xe8, 0x31, 0x1b, 0xc0, 0x97, 0xec, 0xd1, 0x20,
     98      1.1  christos     0x2a, 0x55, 0x69, 0x23, 0x08, 0x50, 0x05, 0xec,
     99      1.1  christos     0x13, 0x3b, 0x56, 0xfc, 0x18, 0xc9, 0x1a, 0xa9,
    100      1.1  christos     0x69, 0x0e, 0xe2, 0xcc, 0xc8, 0xd6, 0x19, 0xbb,
    101      1.1  christos     0x87, 0x3b, 0x42, 0x77, 0xee, 0x77, 0x81, 0x26,
    102      1.1  christos     0xdd, 0xf6, 0x5d, 0xc3, 0xb2, 0xb0, 0xc4, 0x14,
    103      1.1  christos     0x6d, 0xb5, 0x4f, 0xdc, 0x13, 0x09, 0xc8, 0x53,
    104      1.1  christos     0x50, 0xb3, 0xea, 0xd3, 0x5f, 0x11, 0x67, 0xd4,
    105      1.1  christos     0x2f, 0x6e, 0x30, 0x1a, 0xbe, 0xd6, 0xf0, 0x2d,
    106      1.1  christos     0xc9, 0x29, 0xd9, 0x0a, 0xa8, 0x6f, 0xa4, 0x18,
    107      1.1  christos     0x74, 0x6b, 0xd3, 0x5d, 0x6a, 0x73, 0x3a, 0xf2,
    108      1.1  christos     0x94, 0x7f, 0xbd, 0xb4, 0xa6, 0x7f, 0x5b, 0x3d,
    109      1.1  christos     0x26, 0xf2, 0x6c, 0x13, 0xcf, 0xb4, 0x26, 0x1e,
    110      1.1  christos     0x38, 0x17, 0x66, 0x60, 0xb1, 0x36, 0xae, 0xe0,
    111      1.1  christos     0x6d, 0x86, 0x69, 0xe7, 0xe7, 0xae, 0x77, 0x6f,
    112      1.1  christos     0x7e, 0x99, 0xe5, 0xd9, 0x62, 0xc9, 0xfc, 0xde,
    113      1.1  christos     0xb4, 0xee, 0x7e, 0xc8, 0xe9, 0xb7, 0x2c, 0xe2,
    114      1.1  christos     0x70, 0xe8, 0x8b, 0x2d, 0x94, 0xad, 0xe8, 0x54,
    115      1.1  christos     0xa3, 0x2d, 0x9a, 0xe2, 0x50, 0x63, 0x87, 0xb3,
    116      1.1  christos     0x56, 0x29, 0xea, 0xa8, 0x5e, 0x96, 0x53, 0x9f,
    117      1.1  christos     0x23, 0x8a, 0xef, 0xa3, 0xd4, 0x87, 0x09, 0x5f,
    118      1.1  christos     0xba, 0xc3, 0xd1, 0xd9, 0x1a, 0x7b, 0x5c, 0x5d,
    119      1.1  christos     0x5d, 0x89, 0xed, 0xb6, 0x6e, 0x39, 0x73, 0xa5,
    120      1.1  christos     0x64, 0x59, 0x52, 0x8b, 0x61, 0x8f, 0x66, 0x69,
    121      1.1  christos     0xb9, 0xf0, 0x45, 0x0a, 0x57, 0xcd, 0xc5, 0x7f,
    122      1.1  christos     0x5d, 0xd0, 0xbf, 0xcc, 0x0b, 0x48, 0x12, 0xe1,
    123      1.1  christos     0xe2, 0xc2, 0xea, 0xcc, 0x09, 0xd9, 0x42, 0x2c,
    124      1.1  christos     0xef, 0x4f, 0xa7, 0xe9, 0x32, 0x5c, 0x3f, 0x22,
    125      1.1  christos     0xc0, 0x45, 0x0b, 0x67, 0x3c, 0x31, 0x69, 0x29,
    126      1.1  christos     0xa3, 0x39, 0xdd, 0x6e, 0x2f, 0xbe, 0x10, 0xc9,
    127      1.1  christos     0x7b, 0xff, 0x19, 0x8a, 0xe9, 0xea, 0xfc, 0x32,
    128      1.1  christos     0x41, 0x33, 0x70, 0x2a, 0x9a, 0xa4, 0xe6, 0xb4,
    129      1.1  christos     0x7e, 0xb4, 0xc6, 0x21, 0x49, 0x5a, 0xfc, 0x45,
    130      1.1  christos     0xd2, 0x23, 0xb3, 0x28, 0x4d, 0x83, 0x60, 0xfe,
    131      1.1  christos     0x70, 0x68, 0x03, 0x59, 0xd5, 0x15, 0xaa, 0x9e,
    132      1.1  christos     0xa0, 0x2e, 0x36, 0xb5, 0x61, 0x0f, 0x61, 0x05,
    133      1.1  christos     0x3c, 0x62, 0x00, 0xa0, 0x47, 0xf1, 0x86, 0xba,
    134      1.1  christos     0x33, 0xb8, 0xca, 0x60, 0x2f, 0x3f, 0x0a, 0x67,
    135      1.1  christos     0x09, 0x27, 0x2f, 0xa2, 0x96, 0x02, 0x52, 0x58,
    136      1.1  christos     0x55, 0x68, 0x80, 0xf4, 0x4f, 0x47, 0xba, 0xff,
    137      1.1  christos     0x41, 0x7a, 0x40, 0x4c, 0xfd, 0x9d, 0x10, 0x72,
    138      1.1  christos     0x0e, 0x20, 0xa9, 0x7f, 0x9b, 0x9b, 0x14, 0xeb,
    139      1.1  christos     0x8e, 0x61, 0x25, 0xcb, 0xf4, 0x58, 0xff, 0x47,
    140      1.1  christos     0xa7, 0x08, 0xd6, 0x4e, 0x2b, 0xf1, 0xf9, 0x89,
    141      1.1  christos     0xd7, 0x22, 0x0f, 0x8d, 0x35, 0x07, 0xa0, 0x54,
    142      1.1  christos     0xab, 0x83, 0xd8, 0xee, 0x5a, 0x3e, 0x88, 0x74,
    143      1.1  christos     0x46, 0x41, 0x6e, 0x3e, 0xb7, 0xc0, 0xb6, 0x55,
    144      1.1  christos     0xe0, 0x36, 0xc0, 0x2b, 0xbf, 0xb8, 0x24, 0x8a,
    145      1.1  christos     0x44, 0x82, 0xf4, 0xcb, 0xb5, 0xd7, 0x41, 0x48,
    146      1.1  christos     0x51, 0x08, 0xe0, 0x14, 0x34, 0xd2, 0x6d, 0xe9,
    147      1.1  christos     0x7a, 0xec, 0x91, 0x61, 0xa7, 0xe1, 0x81, 0x69,
    148      1.1  christos     0x47, 0x1c, 0xc7, 0xf3
    149      1.1  christos };
    150      1.1  christos 
    151      1.1  christos static const unsigned char shake256_largemsg_output[] = {
    152  1.1.1.2  christos     0x64,
    153  1.1.1.2  christos     0xea,
    154  1.1.1.2  christos     0x24,
    155  1.1.1.2  christos     0x6a,
    156  1.1.1.2  christos     0xab,
    157  1.1.1.2  christos     0x80,
    158  1.1.1.2  christos     0x37,
    159  1.1.1.2  christos     0x9e,
    160  1.1.1.2  christos     0x08,
    161  1.1.1.2  christos     0xe2,
    162  1.1.1.2  christos     0x19,
    163  1.1.1.2  christos     0x9e,
    164  1.1.1.2  christos     0x09,
    165  1.1.1.2  christos     0x69,
    166  1.1.1.2  christos     0xe2,
    167  1.1.1.2  christos     0xee,
    168  1.1.1.2  christos     0x1a,
    169  1.1.1.2  christos     0x5d,
    170  1.1.1.2  christos     0xd1,
    171  1.1.1.2  christos     0x68,
    172  1.1.1.2  christos     0x68,
    173  1.1.1.2  christos     0xec,
    174  1.1.1.2  christos     0x8d,
    175  1.1.1.2  christos     0x42,
    176  1.1.1.2  christos     0xd0,
    177  1.1.1.2  christos     0xf8,
    178  1.1.1.2  christos     0xb8,
    179  1.1.1.2  christos     0x44,
    180  1.1.1.2  christos     0x74,
    181  1.1.1.2  christos     0x54,
    182  1.1.1.2  christos     0x87,
    183  1.1.1.2  christos     0x3e,
    184      1.1  christos };
    185      1.1  christos 
    186      1.1  christos static EVP_MD_CTX *shake_setup(const char *name)
    187      1.1  christos {
    188      1.1  christos     EVP_MD_CTX *ctx = NULL;
    189      1.1  christos     EVP_MD *md = NULL;
    190      1.1  christos 
    191      1.1  christos     if (!TEST_ptr(md = EVP_MD_fetch(NULL, name, NULL)))
    192      1.1  christos         return NULL;
    193      1.1  christos 
    194      1.1  christos     if (!TEST_ptr(ctx = EVP_MD_CTX_new()))
    195      1.1  christos         goto err;
    196      1.1  christos     if (!TEST_true(EVP_DigestInit_ex2(ctx, md, NULL)))
    197      1.1  christos         goto err;
    198      1.1  christos     EVP_MD_free(md);
    199      1.1  christos     return ctx;
    200      1.1  christos err:
    201      1.1  christos     EVP_MD_free(md);
    202      1.1  christos     EVP_MD_CTX_free(ctx);
    203      1.1  christos     return NULL;
    204      1.1  christos }
    205      1.1  christos 
    206      1.1  christos static int shake_kat_test(void)
    207      1.1  christos {
    208      1.1  christos     int ret = 0;
    209      1.1  christos     EVP_MD_CTX *ctx = NULL;
    210      1.1  christos     unsigned char out[sizeof(shake256_output)];
    211      1.1  christos 
    212      1.1  christos     if (!TEST_ptr(ctx = shake_setup("SHAKE256")))
    213      1.1  christos         return 0;
    214      1.1  christos     if (!TEST_true(EVP_DigestUpdate(ctx, shake256_input,
    215  1.1.1.2  christos             sizeof(shake256_input)))
    216      1.1  christos         || !TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out)))
    217      1.1  christos         || !TEST_mem_eq(out, sizeof(out),
    218  1.1.1.2  christos             shake256_output, sizeof(shake256_output))
    219      1.1  christos         /* Test that a second call to EVP_DigestFinalXOF fails */
    220      1.1  christos         || !TEST_false(EVP_DigestFinalXOF(ctx, out, sizeof(out)))
    221      1.1  christos         /* Test that a call to EVP_DigestSqueeze fails */
    222      1.1  christos         || !TEST_false(EVP_DigestSqueeze(ctx, out, sizeof(out))))
    223      1.1  christos         goto err;
    224      1.1  christos     ret = 1;
    225      1.1  christos err:
    226      1.1  christos     EVP_MD_CTX_free(ctx);
    227      1.1  christos     return ret;
    228      1.1  christos }
    229      1.1  christos 
    230      1.1  christos static int shake_kat_digestfinal_test(void)
    231      1.1  christos {
    232      1.1  christos     int ret = 0;
    233      1.1  christos     unsigned int digest_length = 0;
    234      1.1  christos     EVP_MD_CTX *ctx = NULL;
    235      1.1  christos     unsigned char out[sizeof(shake256_output)];
    236      1.1  christos 
    237      1.1  christos     /* Test that EVP_DigestFinal without setting XOFLEN fails */
    238      1.1  christos     if (!TEST_ptr(ctx = shake_setup("SHAKE256")))
    239      1.1  christos         return 0;
    240      1.1  christos     if (!TEST_true(EVP_DigestUpdate(ctx, shake256_input,
    241  1.1.1.2  christos             sizeof(shake256_input))))
    242      1.1  christos         return 0;
    243      1.1  christos     ERR_set_mark();
    244      1.1  christos     if (!TEST_false(EVP_DigestFinal(ctx, out, &digest_length))) {
    245      1.1  christos         ERR_clear_last_mark();
    246      1.1  christos         return 0;
    247      1.1  christos     }
    248      1.1  christos     ERR_pop_to_mark();
    249      1.1  christos     EVP_MD_CTX_free(ctx);
    250      1.1  christos 
    251      1.1  christos     /* However EVP_DigestFinalXOF must work */
    252      1.1  christos     if (!TEST_ptr(ctx = shake_setup("SHAKE256")))
    253      1.1  christos         return 0;
    254      1.1  christos     if (!TEST_true(EVP_DigestUpdate(ctx, shake256_input,
    255  1.1.1.2  christos             sizeof(shake256_input))))
    256      1.1  christos         return 0;
    257      1.1  christos     if (!TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out)))
    258      1.1  christos         || !TEST_mem_eq(out, sizeof(out),
    259  1.1.1.2  christos             shake256_output, sizeof(shake256_output))
    260      1.1  christos         || !TEST_false(EVP_DigestFinalXOF(ctx, out, sizeof(out))))
    261      1.1  christos         goto err;
    262      1.1  christos     ret = 1;
    263      1.1  christos err:
    264      1.1  christos     EVP_MD_CTX_free(ctx);
    265      1.1  christos     return ret;
    266      1.1  christos }
    267      1.1  christos 
    268      1.1  christos /*
    269      1.1  christos  * Test that EVP_DigestFinal() returns the output length
    270      1.1  christos  * set by the OSSL_DIGEST_PARAM_XOFLEN param.
    271      1.1  christos  */
    272      1.1  christos static int shake_kat_digestfinal_xoflen_test(void)
    273      1.1  christos {
    274      1.1  christos     int ret = 0;
    275      1.1  christos     unsigned int digest_length = 0;
    276      1.1  christos     EVP_MD_CTX *ctx = NULL;
    277      1.1  christos     const EVP_MD *md;
    278      1.1  christos     unsigned char out[sizeof(shake256_output)];
    279      1.1  christos     OSSL_PARAM params[2];
    280      1.1  christos     size_t sz = 12;
    281      1.1  christos 
    282      1.1  christos     if (!TEST_ptr(ctx = shake_setup("SHAKE256")))
    283      1.1  christos         return 0;
    284      1.1  christos     md = EVP_MD_CTX_get0_md(ctx);
    285      1.1  christos 
    286      1.1  christos     memset(out, 0, sizeof(out));
    287      1.1  christos     params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &sz);
    288      1.1  christos     params[1] = OSSL_PARAM_construct_end();
    289      1.1  christos 
    290      1.1  christos     if (!TEST_int_eq(EVP_MD_CTX_size(ctx), -1)
    291      1.1  christos         || !TEST_int_eq(EVP_MD_CTX_set_params(ctx, params), 1)
    292      1.1  christos         || !TEST_int_eq(EVP_MD_CTX_size(ctx), sz)
    293      1.1  christos         || !TEST_int_eq(EVP_MD_get_size(md), 0)
    294      1.1  christos         || !TEST_true(EVP_MD_xof(md))
    295      1.1  christos         || !TEST_true(EVP_DigestUpdate(ctx, shake256_input,
    296  1.1.1.2  christos             sizeof(shake256_input)))
    297      1.1  christos         || !TEST_true(EVP_DigestFinal(ctx, out, &digest_length))
    298      1.1  christos         || !TEST_uint_eq(digest_length, (unsigned int)sz)
    299      1.1  christos         || !TEST_mem_eq(out, digest_length,
    300  1.1.1.2  christos             shake256_output, digest_length)
    301      1.1  christos         || !TEST_uchar_eq(out[digest_length], 0))
    302      1.1  christos         goto err;
    303      1.1  christos     ret = 1;
    304      1.1  christos err:
    305      1.1  christos     EVP_MD_CTX_free(ctx);
    306      1.1  christos     return ret;
    307      1.1  christos }
    308      1.1  christos 
    309      1.1  christos /*
    310      1.1  christos  * Test that multiple absorb calls gives the expected result.
    311      1.1  christos  * This is a nested test that uses multiple strides for the input.
    312      1.1  christos  */
    313      1.1  christos static int shake_absorb_test(void)
    314      1.1  christos {
    315      1.1  christos     int ret = 0;
    316      1.1  christos     EVP_MD_CTX *ctx = NULL;
    317      1.1  christos     unsigned char out[sizeof(shake256_largemsg_output)];
    318      1.1  christos     size_t total = sizeof(shake256_largemsg_input);
    319      1.1  christos     size_t i, stride, sz;
    320      1.1  christos 
    321      1.1  christos     if (!TEST_ptr(ctx = shake_setup("SHAKE256")))
    322      1.1  christos         return 0;
    323      1.1  christos 
    324      1.1  christos     for (stride = 1; stride < total; ++stride) {
    325      1.1  christos         sz = 0;
    326      1.1  christos         for (i = 0; i < total; i += sz) {
    327      1.1  christos             sz += stride;
    328      1.1  christos             if ((i + sz) > total)
    329      1.1  christos                 sz = total - i;
    330      1.1  christos             if (!TEST_true(EVP_DigestUpdate(ctx, shake256_largemsg_input + i,
    331  1.1.1.2  christos                     sz)))
    332      1.1  christos                 goto err;
    333      1.1  christos         }
    334      1.1  christos         if (!TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out)))
    335      1.1  christos             || !TEST_mem_eq(out, sizeof(out),
    336  1.1.1.2  christos                 shake256_largemsg_output,
    337  1.1.1.2  christos                 sizeof(shake256_largemsg_output)))
    338      1.1  christos             goto err;
    339      1.1  christos         if (!TEST_true(EVP_DigestInit_ex2(ctx, NULL, NULL)))
    340      1.1  christos             goto err;
    341      1.1  christos     }
    342      1.1  christos     ret = 1;
    343      1.1  christos err:
    344      1.1  christos     EVP_MD_CTX_free(ctx);
    345      1.1  christos     return ret;
    346      1.1  christos }
    347      1.1  christos 
    348      1.1  christos /*
    349      1.1  christos  * Table containing the size of the output to squeeze for the
    350      1.1  christos  * initially call, followed by a size for each subsequent call.
    351      1.1  christos  */
    352      1.1  christos static const struct {
    353      1.1  christos     size_t startsz, incsz;
    354      1.1  christos } stride_tests[] = {
    355      1.1  christos     { 1, 1 },
    356      1.1  christos     { 1, 136 },
    357  1.1.1.2  christos     { 1, 136 / 2 },
    358  1.1.1.2  christos     { 1, 136 / 2 - 1 },
    359  1.1.1.2  christos     { 1, 136 / 2 + 1 },
    360  1.1.1.2  christos     { 1, 136 * 3 },
    361      1.1  christos     { 8, 8 },
    362      1.1  christos     { 9, 9 },
    363      1.1  christos     { 10, 10 },
    364  1.1.1.2  christos     { 136 / 2 - 1, 136 },
    365  1.1.1.2  christos     { 136 / 2 - 1, 136 - 1 },
    366  1.1.1.2  christos     { 136 / 2 - 1, 136 + 1 },
    367  1.1.1.2  christos     { 136 / 2, 136 },
    368  1.1.1.2  christos     { 136 / 2, 136 - 1 },
    369  1.1.1.2  christos     { 136 / 2, 136 + 1 },
    370  1.1.1.2  christos     { 136 / 2 + 1, 136 },
    371  1.1.1.2  christos     { 136 / 2 + 1, 136 - 1 },
    372  1.1.1.2  christos     { 136 / 2 + 1, 136 + 1 },
    373      1.1  christos     { 136, 2 },
    374      1.1  christos     { 136, 136 },
    375  1.1.1.2  christos     { 136 - 1, 136 },
    376  1.1.1.2  christos     { 136 - 1, 136 - 1 },
    377  1.1.1.2  christos     { 136 - 1, 136 + 1 },
    378  1.1.1.2  christos     { 136 + 1, 136 },
    379  1.1.1.2  christos     { 136 + 1, 136 - 1 },
    380  1.1.1.2  christos     { 136 + 1, 136 + 1 },
    381  1.1.1.2  christos     { 136 * 3, 136 },
    382  1.1.1.2  christos     { 136 * 3, 136 + 1 },
    383  1.1.1.2  christos     { 136 * 3, 136 - 1 },
    384  1.1.1.2  christos     { 136 * 3, 136 / 2 },
    385  1.1.1.2  christos     { 136 * 3, 136 / 2 + 1 },
    386  1.1.1.2  christos     { 136 * 3, 136 / 2 - 1 },
    387      1.1  christos };
    388      1.1  christos 
    389      1.1  christos /*
    390      1.1  christos  * Helper to do multiple squeezes of output data using SHAKE256.
    391      1.1  christos  * tst is an index into the stride_tests[] containing an initial starting
    392      1.1  christos  * output length, followed by a second output length to use for all remaining
    393      1.1  christos  * squeezes. expected_outlen contains the total number of bytes to squeeze.
    394      1.1  christos  * in and inlen represent the input to absorb. expected_out and expected_outlen
    395      1.1  christos  * represent the expected output.
    396      1.1  christos  */
    397      1.1  christos static int do_shake_squeeze_test(int tst,
    398  1.1.1.2  christos     const unsigned char *in, size_t inlen,
    399  1.1.1.2  christos     const unsigned char *expected_out,
    400  1.1.1.2  christos     size_t expected_outlen)
    401      1.1  christos {
    402      1.1  christos     int ret = 0;
    403      1.1  christos     EVP_MD_CTX *ctx = NULL;
    404      1.1  christos     unsigned char *out = NULL;
    405      1.1  christos     size_t i = 0, sz = stride_tests[tst].startsz;
    406      1.1  christos 
    407      1.1  christos     if (!TEST_ptr(ctx = shake_setup("SHAKE256")))
    408      1.1  christos         return 0;
    409      1.1  christos     if (!TEST_ptr(out = OPENSSL_malloc(expected_outlen)))
    410      1.1  christos         goto err;
    411      1.1  christos     if (!TEST_true(EVP_DigestUpdate(ctx, in, inlen)))
    412      1.1  christos         goto err;
    413      1.1  christos 
    414      1.1  christos     while (i < expected_outlen) {
    415      1.1  christos         if ((i + sz) > expected_outlen)
    416      1.1  christos             sz = expected_outlen - i;
    417      1.1  christos         if (!TEST_true(EVP_DigestSqueeze(ctx, out + i, sz)))
    418      1.1  christos             goto err;
    419      1.1  christos         i += sz;
    420      1.1  christos         sz = stride_tests[tst].incsz;
    421      1.1  christos     }
    422      1.1  christos     if (!TEST_mem_eq(out, expected_outlen, expected_out, expected_outlen))
    423      1.1  christos         goto err;
    424      1.1  christos     ret = 1;
    425      1.1  christos err:
    426      1.1  christos     OPENSSL_free(out);
    427      1.1  christos     EVP_MD_CTX_free(ctx);
    428      1.1  christos     return ret;
    429      1.1  christos }
    430      1.1  christos 
    431      1.1  christos static int shake_squeeze_kat_test(int tst)
    432      1.1  christos {
    433      1.1  christos     return do_shake_squeeze_test(tst, shake256_input, sizeof(shake256_input),
    434  1.1.1.2  christos         shake256_output, sizeof(shake256_output));
    435      1.1  christos }
    436      1.1  christos 
    437      1.1  christos /*
    438      1.1  christos  * Generate some random input to absorb, and then
    439      1.1  christos  * squeeze it out in one operation to get a expected
    440      1.1  christos  * output. Use this to test that multiple squeeze calls
    441      1.1  christos  * on the same input gives the same output.
    442      1.1  christos  */
    443      1.1  christos static int shake_squeeze_large_test(int tst)
    444      1.1  christos {
    445      1.1  christos     int ret = 0;
    446      1.1  christos     EVP_MD_CTX *ctx = NULL;
    447      1.1  christos     unsigned char msg[16];
    448      1.1  christos     unsigned char out[2000];
    449      1.1  christos 
    450      1.1  christos     if (!TEST_int_gt(RAND_bytes(msg, sizeof(msg)), 0)
    451      1.1  christos         || !TEST_ptr(ctx = shake_setup("SHAKE256"))
    452      1.1  christos         || !TEST_true(EVP_DigestUpdate(ctx, msg, sizeof(msg)))
    453      1.1  christos         || !TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out))))
    454      1.1  christos         goto err;
    455      1.1  christos 
    456      1.1  christos     ret = do_shake_squeeze_test(tst, msg, sizeof(msg), out, sizeof(out));
    457      1.1  christos err:
    458      1.1  christos     EVP_MD_CTX_free(ctx);
    459      1.1  christos     return ret;
    460      1.1  christos }
    461      1.1  christos 
    462      1.1  christos static const size_t dupoffset_tests[] = {
    463  1.1.1.2  christos     1, 135, 136, 137, 136 * 3 - 1, 136 * 3, 136 * 3 + 1
    464      1.1  christos };
    465      1.1  christos 
    466      1.1  christos /* Helper function to test that EVP_MD_CTX_dup() copies the internal state */
    467      1.1  christos static int do_shake_squeeze_dup_test(int tst, const char *alg,
    468  1.1.1.2  christos     const unsigned char *in, size_t inlen,
    469  1.1.1.2  christos     const unsigned char *expected_out,
    470  1.1.1.2  christos     size_t expected_outlen)
    471      1.1  christos {
    472      1.1  christos     int ret = 0;
    473      1.1  christos     EVP_MD_CTX *cur, *ctx = NULL, *dupctx = NULL;
    474      1.1  christos     unsigned char *out = NULL;
    475      1.1  christos     size_t i = 0, sz = 10;
    476      1.1  christos     size_t dupoffset = dupoffset_tests[tst];
    477      1.1  christos 
    478      1.1  christos     if (!TEST_ptr(ctx = shake_setup(alg)))
    479      1.1  christos         return 0;
    480      1.1  christos     cur = ctx;
    481      1.1  christos     if (!TEST_ptr(out = OPENSSL_malloc(expected_outlen)))
    482      1.1  christos         goto err;
    483      1.1  christos     if (!TEST_true(EVP_DigestUpdate(ctx, in, inlen)))
    484      1.1  christos         goto err;
    485      1.1  christos 
    486      1.1  christos     while (i < expected_outlen) {
    487      1.1  christos         if ((i + sz) > expected_outlen)
    488      1.1  christos             sz = expected_outlen - i;
    489      1.1  christos         if (!TEST_true(EVP_DigestSqueeze(cur, out + i, sz)))
    490      1.1  christos             goto err;
    491      1.1  christos         i += sz;
    492      1.1  christos         /* At a certain offset we swap to a new ctx that copies the state */
    493      1.1  christos         if (dupctx == NULL && i >= dupoffset) {
    494      1.1  christos             if (!TEST_ptr(dupctx = EVP_MD_CTX_dup(ctx)))
    495      1.1  christos                 goto err;
    496      1.1  christos             cur = dupctx;
    497      1.1  christos         }
    498      1.1  christos     }
    499      1.1  christos     if (!TEST_mem_eq(out, expected_outlen, expected_out, expected_outlen))
    500      1.1  christos         goto err;
    501      1.1  christos     ret = 1;
    502      1.1  christos err:
    503      1.1  christos     OPENSSL_free(out);
    504      1.1  christos     EVP_MD_CTX_free(ctx);
    505      1.1  christos     EVP_MD_CTX_free(dupctx);
    506      1.1  christos     return ret;
    507      1.1  christos }
    508      1.1  christos 
    509      1.1  christos /* Test that the internal state can be copied */
    510      1.1  christos static int shake_squeeze_dup_test(int tst)
    511      1.1  christos {
    512      1.1  christos     int ret = 0;
    513      1.1  christos     EVP_MD_CTX *ctx = NULL;
    514      1.1  christos     unsigned char msg[16];
    515      1.1  christos     unsigned char out[1000];
    516      1.1  christos     const char *alg = "SHAKE128";
    517      1.1  christos 
    518      1.1  christos     if (!TEST_int_gt(RAND_bytes(msg, sizeof(msg)), 0)
    519      1.1  christos         || !TEST_ptr(ctx = shake_setup(alg))
    520      1.1  christos         || !TEST_true(EVP_DigestUpdate(ctx, msg, sizeof(msg)))
    521      1.1  christos         || !TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out))))
    522      1.1  christos         goto err;
    523      1.1  christos 
    524      1.1  christos     ret = do_shake_squeeze_dup_test(tst, alg, msg, sizeof(msg),
    525  1.1.1.2  christos         out, sizeof(out));
    526      1.1  christos err:
    527      1.1  christos     EVP_MD_CTX_free(ctx);
    528      1.1  christos     return ret;
    529      1.1  christos }
    530      1.1  christos 
    531      1.1  christos /* Test that a squeeze without a preceding absorb works */
    532      1.1  christos static int shake_squeeze_no_absorb_test(void)
    533      1.1  christos {
    534      1.1  christos     int ret = 0;
    535      1.1  christos     EVP_MD_CTX *ctx = NULL;
    536      1.1  christos     unsigned char out[1000];
    537      1.1  christos     unsigned char out2[1000];
    538      1.1  christos     const char *alg = "SHAKE128";
    539      1.1  christos 
    540      1.1  christos     if (!TEST_ptr(ctx = shake_setup(alg))
    541      1.1  christos         || !TEST_true(EVP_DigestFinalXOF(ctx, out, sizeof(out))))
    542      1.1  christos         goto err;
    543      1.1  christos 
    544      1.1  christos     if (!TEST_true(EVP_DigestInit_ex2(ctx, NULL, NULL))
    545      1.1  christos         || !TEST_true(EVP_DigestSqueeze(ctx, out2, sizeof(out2) / 2))
    546      1.1  christos         || !TEST_true(EVP_DigestSqueeze(ctx, out2 + sizeof(out2) / 2,
    547  1.1.1.2  christos             sizeof(out2) / 2)))
    548      1.1  christos         goto err;
    549      1.1  christos 
    550      1.1  christos     if (!TEST_mem_eq(out2, sizeof(out2), out, sizeof(out)))
    551      1.1  christos         goto err;
    552      1.1  christos     ret = 1;
    553      1.1  christos 
    554      1.1  christos err:
    555      1.1  christos     EVP_MD_CTX_free(ctx);
    556      1.1  christos     return ret;
    557      1.1  christos }
    558      1.1  christos 
    559      1.1  christos static int xof_fail_test(void)
    560      1.1  christos {
    561      1.1  christos     int ret;
    562      1.1  christos     EVP_MD *md = NULL;
    563      1.1  christos 
    564      1.1  christos     ret = TEST_ptr(md = EVP_MD_fetch(NULL, "SHA256", NULL))
    565  1.1.1.2  christos         && TEST_false(EVP_MD_xof(md));
    566      1.1  christos     EVP_MD_free(md);
    567      1.1  christos     return ret;
    568      1.1  christos }
    569      1.1  christos 
    570      1.1  christos int setup_tests(void)
    571      1.1  christos {
    572      1.1  christos     ADD_TEST(shake_kat_test);
    573      1.1  christos     ADD_TEST(shake_kat_digestfinal_test);
    574      1.1  christos     ADD_TEST(shake_kat_digestfinal_xoflen_test);
    575      1.1  christos     ADD_TEST(shake_absorb_test);
    576      1.1  christos     ADD_ALL_TESTS(shake_squeeze_kat_test, OSSL_NELEM(stride_tests));
    577      1.1  christos     ADD_ALL_TESTS(shake_squeeze_large_test, OSSL_NELEM(stride_tests));
    578      1.1  christos     ADD_ALL_TESTS(shake_squeeze_dup_test, OSSL_NELEM(dupoffset_tests));
    579      1.1  christos     ADD_TEST(xof_fail_test);
    580      1.1  christos     ADD_TEST(shake_squeeze_no_absorb_test);
    581      1.1  christos     return 1;
    582      1.1  christos }
    583