Home | History | Annotate | Line # | Download | only in test
params_api_test.c revision 1.1
      1 /*
      2  * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.
      3  * Copyright (c) 2019, Oracle and/or its affiliates.  All rights reserved.
      4  *
      5  * Licensed under the Apache License 2.0 (the "License").  You may not use
      6  * this file except in compliance with the License.  You can obtain a copy
      7  * in the file LICENSE in the source distribution or at
      8  * https://www.openssl.org/source/license.html
      9  */
     10 
     11 #include <string.h>
     12 #include "testutil.h"
     13 #include "internal/nelem.h"
     14 #include "internal/endian.h"
     15 #include <openssl/params.h>
     16 #include <openssl/bn.h>
     17 
     18 /* The maximum size of the static buffers used to test most things */
     19 #define MAX_LEN 20
     20 
     21 static void swap_copy(unsigned char *out, const void *in, size_t len)
     22 {
     23     size_t j;
     24 
     25     for (j = 0; j < len; j++)
     26         out[j] = ((unsigned char *)in)[len - j - 1];
     27 }
     28 
     29 /*
     30  * A memory copy that converts the native byte ordering either to or from
     31  * little endian format.
     32  *
     33  * On a little endian machine copying either is just a memcpy(3), on a
     34  * big endian machine copying from native to or from little endian involves
     35  * byte reversal.
     36  */
     37 static void le_copy(unsigned char *out, size_t outlen,
     38                     const void *in, size_t inlen)
     39 {
     40     DECLARE_IS_ENDIAN;
     41 
     42     if (IS_LITTLE_ENDIAN) {
     43         memcpy(out, in, outlen);
     44     } else {
     45         if (outlen < inlen) {
     46             in = (const char *)in + inlen - outlen;
     47             inlen = outlen;
     48         }
     49         if (!ossl_assert(outlen <= inlen))
     50             return;
     51         swap_copy(out, in, inlen);
     52     }
     53 }
     54 
     55 static const struct {
     56     size_t len;
     57     unsigned char value[MAX_LEN];
     58 } raw_values[] = {
     59     { 1, { 0x47 } },
     60     { 1, { 0xd0 } },
     61     { 2, { 0x01, 0xe9 } },
     62     { 2, { 0xff, 0x53 } },
     63     { 3, { 0x16, 0xff, 0x7c } },
     64     { 3, { 0xa8, 0x9c, 0x0e } },
     65     { 4, { 0x38, 0x27, 0xbf, 0x3b } },
     66     { 4, { 0x9f, 0x26, 0x48, 0x22 } },
     67     { 5, { 0x30, 0x65, 0xfa, 0xe4, 0x81 } },
     68     { 5, { 0xd1, 0x76, 0x01, 0x1b, 0xcd } },
     69     { 8, { 0x59, 0xb2, 0x1a, 0xe9, 0x2a, 0xd8, 0x46, 0x40 } },
     70     { 8, { 0xb4, 0xae, 0xbd, 0xb4, 0xdd, 0x04, 0xb1, 0x4c } },
     71     { 16, { 0x61, 0xe8, 0x7e, 0x31, 0xe9, 0x33, 0x83, 0x3d,
     72             0x87, 0x99, 0xc7, 0xd8, 0x5d, 0xa9, 0x8b, 0x42 } },
     73     { 16, { 0xee, 0x6e, 0x8b, 0xc3, 0xec, 0xcf, 0x37, 0xcc,
     74             0x89, 0x67, 0xf2, 0x68, 0x33, 0xa0, 0x14, 0xb0 } },
     75 };
     76 
     77 static int test_param_type_null(OSSL_PARAM *param)
     78 {
     79     int rc = 0;
     80     uint64_t intval;
     81     double dval;
     82     BIGNUM *bn;
     83 
     84     switch(param->data_type) {
     85     case OSSL_PARAM_INTEGER:
     86         if (param->data_size == sizeof(int32_t))
     87             rc = OSSL_PARAM_get_int32(param, (int32_t *)&intval);
     88         else if (param->data_size == sizeof(uint64_t))
     89             rc = OSSL_PARAM_get_int64(param, (int64_t *)&intval);
     90         else
     91             return 1;
     92         break;
     93     case OSSL_PARAM_UNSIGNED_INTEGER:
     94         if (param->data_size == sizeof(uint32_t))
     95             rc = OSSL_PARAM_get_uint32(param, (uint32_t *)&intval);
     96         else if (param->data_size == sizeof(uint64_t))
     97             rc = OSSL_PARAM_get_uint64(param, &intval);
     98         else
     99             rc = OSSL_PARAM_get_BN(param, &bn);
    100         break;
    101     case OSSL_PARAM_REAL:
    102         rc = OSSL_PARAM_get_double(param, &dval);
    103         break;
    104     case OSSL_PARAM_UTF8_STRING:
    105     case OSSL_PARAM_OCTET_STRING:
    106     case OSSL_PARAM_UTF8_PTR:
    107     case OSSL_PARAM_OCTET_PTR:
    108         /* these are allowed to be null */
    109         return 1;
    110         break;
    111     }
    112 
    113     /*
    114      * we expect the various OSSL_PARAM_get functions above
    115      * to return failure when the data is set to NULL
    116      */
    117     return rc == 0;
    118 }
    119 
    120 static int test_param_type_extra(OSSL_PARAM *param, const unsigned char *cmp,
    121                                  size_t width)
    122 {
    123     int32_t i32;
    124     int64_t i64;
    125     size_t s, sz;
    126     unsigned char buf[MAX_LEN];
    127     const int bit32 = param->data_size <= sizeof(int32_t);
    128     const int sizet = param->data_size <= sizeof(size_t);
    129     const int signd = param->data_type == OSSL_PARAM_INTEGER;
    130 
    131     /*
    132      * Set the unmodified sentinel directly because there is no param array
    133      * for these tests.
    134      */
    135     param->return_size = OSSL_PARAM_UNMODIFIED;
    136     if (signd) {
    137         if ((bit32 && !TEST_true(OSSL_PARAM_get_int32(param, &i32)))
    138             || !TEST_true(OSSL_PARAM_get_int64(param, &i64)))
    139             return 0;
    140     } else {
    141         if ((bit32
    142              && !TEST_true(OSSL_PARAM_get_uint32(param, (uint32_t *)&i32)))
    143             || !TEST_true(OSSL_PARAM_get_uint64(param, (uint64_t *)&i64))
    144             || (sizet && !TEST_true(OSSL_PARAM_get_size_t(param, &s))))
    145             return 0;
    146     }
    147     if (!TEST_false(OSSL_PARAM_modified(param)))
    148         return 0;
    149 
    150     /* Check signed types */
    151     if (bit32) {
    152         le_copy(buf, sizeof(i32), &i32, sizeof(i32));
    153         sz = sizeof(i32) < width ? sizeof(i32) : width;
    154         if (!TEST_mem_eq(buf, sz, cmp, sz))
    155             return 0;
    156     }
    157     le_copy(buf, sizeof(i64), &i64, sizeof(i64));
    158     sz = sizeof(i64) < width ? sizeof(i64) : width;
    159     if (!TEST_mem_eq(buf, sz, cmp, sz))
    160         return 0;
    161     if (sizet && !signd) {
    162         le_copy(buf, sizeof(s), &s, sizeof(s));
    163         sz = sizeof(s) < width ? sizeof(s) : width;
    164         if (!TEST_mem_eq(buf, sz, cmp, sz))
    165             return 0;
    166     }
    167 
    168     /* Check a widening write if possible */
    169     if (sizeof(size_t) > width) {
    170         if (signd) {
    171             if (!TEST_true(OSSL_PARAM_set_int32(param, 12345))
    172                 || !TEST_true(OSSL_PARAM_get_int64(param, &i64))
    173                 || !TEST_size_t_eq((size_t)i64, 12345))
    174                 return 0;
    175         } else {
    176             if (!TEST_true(OSSL_PARAM_set_uint32(param, 12345))
    177                 || !TEST_true(OSSL_PARAM_get_uint64(param, (uint64_t *)&i64))
    178                 || !TEST_size_t_eq((size_t)i64, 12345))
    179                 return 0;
    180         }
    181         if (!TEST_true(OSSL_PARAM_modified(param)))
    182             return 0;
    183     }
    184     return 1;
    185 }
    186 
    187 /*
    188  * The test cases for each of the bastic integral types are similar.
    189  * For each type, a param of that type is set and an attempt to read it
    190  * get is made.  Finally, the above function is called to verify that
    191  * the params can be read as other types.
    192  *
    193  * All the real work is done via byte buffers which are converted to machine
    194  * byte order and to little endian for comparisons.  Narrower values are best
    195  * compared using little endian because their values and positions don't
    196  * change.
    197  */
    198 
    199 static int test_param_int(int n)
    200 {
    201     int in, out;
    202     unsigned char buf[MAX_LEN], cmp[sizeof(int)];
    203     const size_t len = raw_values[n].len >= sizeof(int) ?
    204                        sizeof(int) : raw_values[n].len;
    205     OSSL_PARAM param = OSSL_PARAM_int("a", NULL);
    206 
    207     if (!TEST_int_eq(test_param_type_null(&param), 1))
    208         return 0;
    209 
    210     memset(buf, 0, sizeof(buf));
    211     le_copy(buf, sizeof(in), raw_values[n].value, sizeof(in));
    212     memcpy(&in, buf, sizeof(in));
    213     param.data = &out;
    214     if (!TEST_true(OSSL_PARAM_set_int(&param, in)))
    215         return 0;
    216     le_copy(cmp, sizeof(out), &out, sizeof(out));
    217     if (!TEST_mem_eq(cmp, len, raw_values[n].value, len))
    218         return 0;
    219     in = 0;
    220     if (!TEST_true(OSSL_PARAM_get_int(&param, &in)))
    221         return 0;
    222     le_copy(cmp, sizeof(in), &in, sizeof(in));
    223     if (!TEST_mem_eq(cmp, sizeof(in), raw_values[n].value, sizeof(in)))
    224         return 0;
    225     param.data = &out;
    226     return test_param_type_extra(&param, raw_values[n].value, sizeof(int));
    227 }
    228 
    229 static int test_param_long(int n)
    230 {
    231     long int in, out;
    232     unsigned char buf[MAX_LEN], cmp[sizeof(long int)];
    233     const size_t len = raw_values[n].len >= sizeof(long int)
    234                        ? sizeof(long int) : raw_values[n].len;
    235     OSSL_PARAM param = OSSL_PARAM_long("a", NULL);
    236 
    237     if (!TEST_int_eq(test_param_type_null(&param), 1))
    238         return 0;
    239 
    240     memset(buf, 0, sizeof(buf));
    241     le_copy(buf, sizeof(in), raw_values[n].value, sizeof(in));
    242     memcpy(&in, buf, sizeof(in));
    243     param.data = &out;
    244     if (!TEST_true(OSSL_PARAM_set_long(&param, in)))
    245         return 0;
    246     le_copy(cmp, sizeof(out), &out, sizeof(out));
    247     if (!TEST_mem_eq(cmp, len, raw_values[n].value, len))
    248         return 0;
    249     in = 0;
    250     if (!TEST_true(OSSL_PARAM_get_long(&param, &in)))
    251         return 0;
    252     le_copy(cmp, sizeof(in), &in, sizeof(in));
    253     if (!TEST_mem_eq(cmp, sizeof(in), raw_values[n].value, sizeof(in)))
    254         return 0;
    255     param.data = &out;
    256     return test_param_type_extra(&param, raw_values[n].value, sizeof(long int));
    257 }
    258 
    259 static int test_param_uint(int n)
    260 {
    261     unsigned int in, out;
    262     unsigned char buf[MAX_LEN], cmp[sizeof(unsigned int)];
    263     const size_t len = raw_values[n].len >= sizeof(unsigned int) ? sizeof(unsigned int) : raw_values[n].len;
    264     OSSL_PARAM param = OSSL_PARAM_uint("a", NULL);
    265 
    266     if (!TEST_int_eq(test_param_type_null(&param), 1))
    267         return 0;
    268 
    269     memset(buf, 0, sizeof(buf));
    270     le_copy(buf, sizeof(in), raw_values[n].value, sizeof(in));
    271     memcpy(&in, buf, sizeof(in));
    272     param.data = &out;
    273     if (!TEST_true(OSSL_PARAM_set_uint(&param, in)))
    274         return 0;
    275     le_copy(cmp, sizeof(out), &out, sizeof(out));
    276     if (!TEST_mem_eq(cmp, len, raw_values[n].value, len))
    277         return 0;
    278     in = 0;
    279     if (!TEST_true(OSSL_PARAM_get_uint(&param, &in)))
    280         return 0;
    281     le_copy(cmp, sizeof(in), &in, sizeof(in));
    282     if (!TEST_mem_eq(cmp, sizeof(in), raw_values[n].value, sizeof(in)))
    283         return 0;
    284     param.data = &out;
    285     return test_param_type_extra(&param, raw_values[n].value, sizeof(unsigned int));
    286 }
    287 
    288 static int test_param_ulong(int n)
    289 {
    290     unsigned long int in, out;
    291     unsigned char buf[MAX_LEN], cmp[sizeof(unsigned long int)];
    292     const size_t len = raw_values[n].len >= sizeof(unsigned long int)
    293                        ? sizeof(unsigned long int) : raw_values[n].len;
    294     OSSL_PARAM param = OSSL_PARAM_ulong("a", NULL);
    295 
    296     if (!TEST_int_eq(test_param_type_null(&param), 1))
    297         return 0;
    298 
    299     memset(buf, 0, sizeof(buf));
    300     le_copy(buf, sizeof(in), raw_values[n].value, sizeof(in));
    301     memcpy(&in, buf, sizeof(in));
    302     param.data = &out;
    303     if (!TEST_true(OSSL_PARAM_set_ulong(&param, in)))
    304         return 0;
    305     le_copy(cmp, sizeof(out), &out, sizeof(out));
    306     if (!TEST_mem_eq(cmp, len, raw_values[n].value, len))
    307         return 0;
    308     in = 0;
    309     if (!TEST_true(OSSL_PARAM_get_ulong(&param, &in)))
    310         return 0;
    311     le_copy(cmp, sizeof(in), &in, sizeof(in));
    312     if (!TEST_mem_eq(cmp, sizeof(in), raw_values[n].value, sizeof(in)))
    313         return 0;
    314     param.data = &out;
    315     return test_param_type_extra(&param, raw_values[n].value, sizeof(unsigned long int));
    316 }
    317 
    318 static int test_param_int32(int n)
    319 {
    320     int32_t in, out;
    321     unsigned char buf[MAX_LEN], cmp[sizeof(int32_t)];
    322     const size_t len = raw_values[n].len >= sizeof(int32_t)
    323                        ? sizeof(int32_t) : raw_values[n].len;
    324     OSSL_PARAM param = OSSL_PARAM_int32("a", NULL);
    325 
    326     if (!TEST_int_eq(test_param_type_null(&param), 1))
    327         return 0;
    328 
    329     memset(buf, 0, sizeof(buf));
    330     le_copy(buf, sizeof(in), raw_values[n].value, sizeof(in));
    331     memcpy(&in, buf, sizeof(in));
    332     param.data = &out;
    333     if (!TEST_true(OSSL_PARAM_set_int32(&param, in)))
    334         return 0;
    335     le_copy(cmp, sizeof(out), &out, sizeof(out));
    336     if (!TEST_mem_eq(cmp, len, raw_values[n].value, len))
    337         return 0;
    338     in = 0;
    339     if (!TEST_true(OSSL_PARAM_get_int32(&param, &in)))
    340         return 0;
    341     le_copy(cmp, sizeof(in), &in, sizeof(in));
    342     if (!TEST_mem_eq(cmp, sizeof(in), raw_values[n].value, sizeof(in)))
    343         return 0;
    344     param.data = &out;
    345     return test_param_type_extra(&param, raw_values[n].value, sizeof(int32_t));
    346 }
    347 
    348 static int test_param_uint32(int n)
    349 {
    350     uint32_t in, out;
    351     unsigned char buf[MAX_LEN], cmp[sizeof(uint32_t)];
    352     const size_t len = raw_values[n].len >= sizeof(uint32_t)
    353                        ? sizeof(uint32_t) : raw_values[n].len;
    354     OSSL_PARAM param = OSSL_PARAM_uint32("a", NULL);
    355 
    356     if (!TEST_int_eq(test_param_type_null(&param), 1))
    357         return 0;
    358 
    359     memset(buf, 0, sizeof(buf));
    360     le_copy(buf, sizeof(in), raw_values[n].value, sizeof(in));
    361     memcpy(&in, buf, sizeof(in));
    362     param.data = &out;
    363     if (!TEST_true(OSSL_PARAM_set_uint32(&param, in)))
    364         return 0;
    365     le_copy(cmp, sizeof(out), &out, sizeof(out));
    366     if (!TEST_mem_eq(cmp, len, raw_values[n].value, len))
    367         return 0;
    368     in = 0;
    369     if (!TEST_true(OSSL_PARAM_get_uint32(&param, &in)))
    370         return 0;
    371     le_copy(cmp, sizeof(in), &in, sizeof(in));
    372     if (!TEST_mem_eq(cmp, sizeof(in), raw_values[n].value, sizeof(in)))
    373         return 0;
    374     param.data = &out;
    375     return test_param_type_extra(&param, raw_values[n].value, sizeof(uint32_t));
    376 }
    377 
    378 static int test_param_int64(int n)
    379 {
    380     int64_t in, out;
    381     unsigned char buf[MAX_LEN], cmp[sizeof(int64_t)];
    382     const size_t len = raw_values[n].len >= sizeof(int64_t)
    383                        ? sizeof(int64_t) : raw_values[n].len;
    384     OSSL_PARAM param = OSSL_PARAM_int64("a", NULL);
    385 
    386     if (!TEST_int_eq(test_param_type_null(&param), 1))
    387         return 0;
    388 
    389     memset(buf, 0, sizeof(buf));
    390     le_copy(buf, sizeof(in), raw_values[n].value, sizeof(in));
    391     memcpy(&in, buf, sizeof(in));
    392     param.data = &out;
    393     if (!TEST_true(OSSL_PARAM_set_int64(&param, in)))
    394         return 0;
    395     le_copy(cmp, sizeof(out), &out, sizeof(out));
    396     if (!TEST_mem_eq(cmp, len, raw_values[n].value, len))
    397         return 0;
    398     in = 0;
    399     if (!TEST_true(OSSL_PARAM_get_int64(&param, &in)))
    400         return 0;
    401     le_copy(cmp, sizeof(in), &in, sizeof(in));
    402     if (!TEST_mem_eq(cmp, sizeof(in), raw_values[n].value, sizeof(in)))
    403         return 0;
    404     param.data = &out;
    405     return test_param_type_extra(&param, raw_values[n].value, sizeof(int64_t));
    406 }
    407 
    408 static int test_param_uint64(int n)
    409 {
    410     uint64_t in, out;
    411     unsigned char buf[MAX_LEN], cmp[sizeof(uint64_t)];
    412     const size_t len = raw_values[n].len >= sizeof(uint64_t)
    413                        ? sizeof(uint64_t) : raw_values[n].len;
    414     OSSL_PARAM param = OSSL_PARAM_uint64("a", NULL);
    415 
    416     if (!TEST_int_eq(test_param_type_null(&param), 1))
    417         return 0;
    418 
    419     memset(buf, 0, sizeof(buf));
    420     le_copy(buf, sizeof(in), raw_values[n].value, sizeof(in));
    421     memcpy(&in, buf, sizeof(in));
    422     param.data = &out;
    423     if (!TEST_true(OSSL_PARAM_set_uint64(&param, in)))
    424         return 0;
    425     le_copy(cmp, sizeof(out), &out, sizeof(out));
    426     if (!TEST_mem_eq(cmp, len, raw_values[n].value, len))
    427         return 0;
    428     in = 0;
    429     if (!TEST_true(OSSL_PARAM_get_uint64(&param, &in)))
    430         return 0;
    431     le_copy(cmp, sizeof(in), &in, sizeof(in));
    432     if (!TEST_mem_eq(cmp, sizeof(in), raw_values[n].value, sizeof(in)))
    433         return 0;
    434     param.data = &out;
    435     return test_param_type_extra(&param, raw_values[n].value, sizeof(uint64_t));
    436 }
    437 
    438 static int test_param_size_t(int n)
    439 {
    440     size_t in, out;
    441     unsigned char buf[MAX_LEN], cmp[sizeof(size_t)];
    442     const size_t len = raw_values[n].len >= sizeof(size_t)
    443                        ? sizeof(size_t) : raw_values[n].len;
    444     OSSL_PARAM param = OSSL_PARAM_size_t("a", NULL);
    445 
    446     if (!TEST_int_eq(test_param_type_null(&param), 1))
    447         return 0;
    448 
    449     memset(buf, 0, sizeof(buf));
    450     le_copy(buf, sizeof(in), raw_values[n].value, sizeof(in));
    451     memcpy(&in, buf, sizeof(in));
    452     param.data = &out;
    453     if (!TEST_true(OSSL_PARAM_set_size_t(&param, in)))
    454         return 0;
    455     le_copy(cmp, sizeof(out), &out, sizeof(out));
    456     if (!TEST_mem_eq(cmp, len, raw_values[n].value, len))
    457         return 0;
    458     in = 0;
    459     if (!TEST_true(OSSL_PARAM_get_size_t(&param, &in)))
    460         return 0;
    461     le_copy(cmp, sizeof(in), &in, sizeof(in));
    462     if (!TEST_mem_eq(cmp, sizeof(in), raw_values[n].value, sizeof(in)))
    463         return 0;
    464     param.data = &out;
    465     return test_param_type_extra(&param, raw_values[n].value, sizeof(size_t));
    466 }
    467 
    468 static int test_param_time_t(int n)
    469 {
    470     time_t in, out;
    471     unsigned char buf[MAX_LEN], cmp[sizeof(time_t)];
    472     const size_t len = raw_values[n].len >= sizeof(time_t)
    473                        ? sizeof(time_t) : raw_values[n].len;
    474     OSSL_PARAM param = OSSL_PARAM_time_t("a", NULL);
    475 
    476     if (!TEST_int_eq(test_param_type_null(&param), 1))
    477         return 0;
    478 
    479     memset(buf, 0, sizeof(buf));
    480     le_copy(buf, sizeof(in), raw_values[n].value, sizeof(in));
    481     memcpy(&in, buf, sizeof(in));
    482     param.data = &out;
    483     if (!TEST_true(OSSL_PARAM_set_time_t(&param, in)))
    484         return 0;
    485     le_copy(cmp, sizeof(out), &out, sizeof(out));
    486     if (!TEST_mem_eq(cmp, len, raw_values[n].value, len))
    487         return 0;
    488     in = 0;
    489     if (!TEST_true(OSSL_PARAM_get_time_t(&param, &in)))
    490         return 0;
    491     le_copy(cmp, sizeof(in), &in, sizeof(in));
    492     if (!TEST_mem_eq(cmp, sizeof(in), raw_values[n].value, sizeof(in)))
    493         return 0;
    494     param.data = &out;
    495     return test_param_type_extra(&param, raw_values[n].value, sizeof(size_t));
    496 }
    497 
    498 static int test_param_bignum(int n)
    499 {
    500     unsigned char buf[MAX_LEN], bnbuf[MAX_LEN];
    501     const size_t len = raw_values[n].len;
    502     BIGNUM *b = NULL, *c = NULL;
    503     OSSL_PARAM param = OSSL_PARAM_DEFN("bn", OSSL_PARAM_UNSIGNED_INTEGER,
    504                                        NULL, 0);
    505     int ret = 0;
    506 
    507     if (!TEST_int_eq(test_param_type_null(&param), 1))
    508         return 0;
    509 
    510     param.data = bnbuf;
    511     param.data_size = sizeof(bnbuf);
    512 
    513     if (!TEST_ptr(b = BN_lebin2bn(raw_values[n].value, (int)len, NULL)))
    514         goto err;
    515 
    516     if (!TEST_true(OSSL_PARAM_set_BN(&param, b)))
    517         goto err;
    518     le_copy(buf, len, bnbuf, sizeof(bnbuf));
    519     if (!TEST_mem_eq(raw_values[n].value, len, buf, len))
    520         goto err;
    521     param.data_size = param.return_size;
    522     if (!TEST_true(OSSL_PARAM_get_BN(&param, &c))
    523         || !TEST_BN_eq(b, c))
    524         goto err;
    525 
    526     ret = 1;
    527 err:
    528     BN_free(b);
    529     BN_free(c);
    530     return ret;
    531 }
    532 
    533 static int test_param_signed_bignum(int n)
    534 {
    535     unsigned char buf[MAX_LEN], bnbuf[MAX_LEN];
    536     const size_t len = raw_values[n].len;
    537     BIGNUM *b = NULL, *c = NULL;
    538     OSSL_PARAM param = OSSL_PARAM_DEFN("bn", OSSL_PARAM_INTEGER, NULL, 0);
    539     int ret = 0;
    540 
    541     if (!TEST_int_eq(test_param_type_null(&param), 1))
    542         return 0;
    543 
    544     param.data = bnbuf;
    545     param.data_size = sizeof(bnbuf);
    546 
    547     if (!TEST_ptr(b = BN_signed_lebin2bn(raw_values[n].value, (int)len, NULL)))
    548         goto err;
    549 
    550     /* raw_values are little endian */
    551     if (!TEST_false(!!(raw_values[n].value[len - 1] & 0x80) ^ BN_is_negative(b)))
    552         goto err;
    553     if (!TEST_true(OSSL_PARAM_set_BN(&param, b)))
    554         goto err;
    555     le_copy(buf, len, bnbuf, sizeof(bnbuf));
    556     if (!TEST_mem_eq(raw_values[n].value, len, buf, len))
    557         goto err;
    558     param.data_size = param.return_size;
    559     if (!TEST_true(OSSL_PARAM_get_BN(&param, &c))
    560         || !TEST_BN_eq(b, c)) {
    561         BN_print_fp(stderr, c);
    562         goto err;
    563     }
    564 
    565     ret = 1;
    566 err:
    567     BN_free(b);
    568     BN_free(c);
    569     return ret;
    570 }
    571 
    572 static int test_param_real(void)
    573 {
    574     double p;
    575     OSSL_PARAM param = OSSL_PARAM_double("r", NULL);
    576 
    577     if (!TEST_int_eq(test_param_type_null(&param), 1))
    578         return 0;
    579 
    580     param.data = &p;
    581     return TEST_true(OSSL_PARAM_set_double(&param, 3.14159))
    582            && TEST_double_eq(p, 3.14159);
    583 }
    584 
    585 static int test_param_construct(int tstid)
    586 {
    587     static const char *int_names[] = {
    588         "int", "long", "int32", "int64"
    589     };
    590     static const char *uint_names[] = {
    591         "uint", "ulong", "uint32", "uint64", "size_t"
    592     };
    593     static const unsigned char bn_val[16] = {
    594         0xac, 0x75, 0x22, 0x7d, 0x81, 0x06, 0x7a, 0x23,
    595         0xa6, 0xed, 0x87, 0xc7, 0xab, 0xf4, 0x73, 0x22
    596     };
    597     OSSL_PARAM *p = NULL, *p1 = NULL;
    598     static const OSSL_PARAM params_empty[] = {
    599         OSSL_PARAM_END
    600     };
    601     OSSL_PARAM params[20];
    602     char buf[100], buf2[100], *bufp, *bufp2;
    603     unsigned char ubuf[100];
    604     void *vp, *vpn = NULL, *vp2;
    605     OSSL_PARAM *cp;
    606     int i, n = 0, ret = 0;
    607     unsigned int u;
    608     long int l;
    609     unsigned long int ul;
    610     int32_t i32;
    611     uint32_t u32;
    612     int64_t i64;
    613     uint64_t u64;
    614     size_t j, k, s;
    615     double d, d2;
    616     BIGNUM *bn = NULL, *bn2 = NULL;
    617 
    618     params[n++] = OSSL_PARAM_construct_int("int", &i);
    619     params[n++] = OSSL_PARAM_construct_uint("uint", &u);
    620     params[n++] = OSSL_PARAM_construct_long("long", &l);
    621     params[n++] = OSSL_PARAM_construct_ulong("ulong", &ul);
    622     params[n++] = OSSL_PARAM_construct_int32("int32", &i32);
    623     params[n++] = OSSL_PARAM_construct_int64("int64", &i64);
    624     params[n++] = OSSL_PARAM_construct_uint32("uint32", &u32);
    625     params[n++] = OSSL_PARAM_construct_uint64("uint64", &u64);
    626     params[n++] = OSSL_PARAM_construct_size_t("size_t", &s);
    627     params[n++] = OSSL_PARAM_construct_double("double", &d);
    628     params[n++] = OSSL_PARAM_construct_BN("bignum", ubuf, sizeof(ubuf));
    629     params[n++] = OSSL_PARAM_construct_utf8_string("utf8str", buf, sizeof(buf));
    630     params[n++] = OSSL_PARAM_construct_octet_string("octstr", buf, sizeof(buf));
    631     params[n++] = OSSL_PARAM_construct_utf8_ptr("utf8ptr", &bufp, 0);
    632     params[n++] = OSSL_PARAM_construct_octet_ptr("octptr", &vp, 0);
    633     params[n] = OSSL_PARAM_construct_end();
    634 
    635     switch (tstid) {
    636     case 0:
    637         p = params;
    638         break;
    639     case 1:
    640         p = OSSL_PARAM_merge(params, params_empty);
    641         break;
    642     case 2:
    643         p = OSSL_PARAM_dup(params);
    644         break;
    645     default:
    646         p1 = OSSL_PARAM_dup(params);
    647         p = OSSL_PARAM_merge(p1, params_empty);
    648         break;
    649     }
    650 
    651     /* Search failure */
    652     if (!TEST_ptr_null(OSSL_PARAM_locate(p, "fnord")))
    653         goto err;
    654 
    655     /* All signed integral types */
    656     for (j = 0; j < OSSL_NELEM(int_names); j++) {
    657         if (!TEST_ptr(cp = OSSL_PARAM_locate(p, int_names[j]))
    658             || !TEST_true(OSSL_PARAM_set_int32(cp, (int32_t)(3 + j)))
    659             || !TEST_true(OSSL_PARAM_get_int64(cp, &i64))
    660             || !TEST_size_t_eq(cp->data_size, cp->return_size)
    661             || !TEST_size_t_eq((size_t)i64, 3 + j)) {
    662             TEST_note("iteration %zu var %s", j + 1, int_names[j]);
    663             goto err;
    664         }
    665     }
    666     /* All unsigned integral types */
    667     for (j = 0; j < OSSL_NELEM(uint_names); j++) {
    668         if (!TEST_ptr(cp = OSSL_PARAM_locate(p, uint_names[j]))
    669             || !TEST_true(OSSL_PARAM_set_uint32(cp, (uint32_t)(3 + j)))
    670             || !TEST_true(OSSL_PARAM_get_uint64(cp, &u64))
    671             || !TEST_size_t_eq(cp->data_size, cp->return_size)
    672             || !TEST_size_t_eq((size_t)u64, 3 + j)) {
    673             TEST_note("iteration %zu var %s", j + 1, uint_names[j]);
    674             goto err;
    675         }
    676     }
    677     /* Real */
    678     if (!TEST_ptr(cp = OSSL_PARAM_locate(p, "double"))
    679         || !TEST_true(OSSL_PARAM_set_double(cp, 3.14))
    680         || !TEST_true(OSSL_PARAM_get_double(cp, &d2))
    681         || !TEST_size_t_eq(cp->return_size, sizeof(double))
    682         || !TEST_double_eq(d2, 3.14)
    683         || (tstid <= 1 && !TEST_double_eq(d, d2)))
    684         goto err;
    685     /* UTF8 string */
    686     bufp = NULL;
    687     if (!TEST_ptr(cp = OSSL_PARAM_locate(p, "utf8str"))
    688         || !TEST_true(OSSL_PARAM_set_utf8_string(cp, "abcdef"))
    689         || !TEST_size_t_eq(cp->return_size, sizeof("abcdef") - 1)
    690         || !TEST_true(OSSL_PARAM_get_utf8_string(cp, &bufp, 0))
    691         || !TEST_str_eq(bufp, "abcdef")) {
    692         OPENSSL_free(bufp);
    693         goto err;
    694     }
    695     OPENSSL_free(bufp);
    696     bufp = buf2;
    697     if (!TEST_true(OSSL_PARAM_get_utf8_string(cp, &bufp, sizeof(buf2)))
    698         || !TEST_str_eq(buf2, "abcdef"))
    699         goto err;
    700     /* UTF8 pointer */
    701     /* Note that the size of a UTF8 string does *NOT* include the NUL byte */
    702     bufp = buf;
    703     if (!TEST_ptr(cp = OSSL_PARAM_locate(p, "utf8ptr"))
    704         || !TEST_true(OSSL_PARAM_set_utf8_ptr(cp, "tuvwxyz"))
    705         || !TEST_size_t_eq(cp->return_size, sizeof("tuvwxyz") - 1)
    706         || !TEST_true(OSSL_PARAM_get_utf8_ptr(cp, (const char **)&bufp2))
    707         || !TEST_str_eq(bufp2, "tuvwxyz")
    708         || (tstid <= 1 && !TEST_ptr_eq(bufp2, bufp)))
    709         goto err;
    710     /* OCTET string */
    711     if (!TEST_ptr(cp = OSSL_PARAM_locate(p, "octstr"))
    712         || !TEST_true(OSSL_PARAM_set_octet_string(cp, "abcdefghi",
    713                                                   sizeof("abcdefghi")))
    714         || !TEST_size_t_eq(cp->return_size, sizeof("abcdefghi")))
    715         goto err;
    716     /* Match the return size to avoid trailing garbage bytes */
    717     cp->data_size = cp->return_size;
    718     if (!TEST_true(OSSL_PARAM_get_octet_string(cp, &vpn, 0, &s))
    719         || !TEST_size_t_eq(s, sizeof("abcdefghi"))
    720         || !TEST_mem_eq(vpn, sizeof("abcdefghi"),
    721                         "abcdefghi", sizeof("abcdefghi")))
    722         goto err;
    723     vp = buf2;
    724     if (!TEST_true(OSSL_PARAM_get_octet_string(cp, &vp, sizeof(buf2), &s))
    725         || !TEST_size_t_eq(s, sizeof("abcdefghi"))
    726         || !TEST_mem_eq(vp, sizeof("abcdefghi"),
    727                         "abcdefghi", sizeof("abcdefghi")))
    728         goto err;
    729     /* OCTET pointer */
    730     vp = &l;
    731     if (!TEST_ptr(cp = OSSL_PARAM_locate(p, "octptr"))
    732         || !TEST_true(OSSL_PARAM_set_octet_ptr(cp, &ul, sizeof(ul)))
    733         || !TEST_size_t_eq(cp->return_size, sizeof(ul))
    734         || (tstid <= 1 && !TEST_ptr_eq(vp, &ul)))
    735         goto err;
    736     /* Match the return size to avoid trailing garbage bytes */
    737     cp->data_size = cp->return_size;
    738     if (!TEST_true(OSSL_PARAM_get_octet_ptr(cp, (const void **)&vp2, &k))
    739         || !TEST_size_t_eq(k, sizeof(ul))
    740         || (tstid <= 1 && !TEST_ptr_eq(vp2, vp)))
    741         goto err;
    742     /* BIGNUM */
    743     if (!TEST_ptr(cp = OSSL_PARAM_locate(p, "bignum"))
    744         || !TEST_ptr(bn = BN_lebin2bn(bn_val, (int)sizeof(bn_val), NULL))
    745         || !TEST_true(OSSL_PARAM_set_BN(cp, bn))
    746         || !TEST_size_t_eq(cp->data_size, cp->return_size))
    747         goto err;
    748     /* Match the return size to avoid trailing garbage bytes */
    749     cp->data_size = cp->return_size;
    750     if (!TEST_true(OSSL_PARAM_get_BN(cp, &bn2))
    751         || !TEST_BN_eq(bn, bn2))
    752         goto err;
    753     ret = 1;
    754 err:
    755     if (p != params)
    756         OPENSSL_free(p);
    757     OPENSSL_free(p1);
    758     OPENSSL_free(vpn);
    759     BN_free(bn);
    760     BN_free(bn2);
    761     return ret;
    762 }
    763 
    764 static int test_param_modified(void)
    765 {
    766     OSSL_PARAM param[3] = { OSSL_PARAM_int("a", NULL),
    767                             OSSL_PARAM_int("b", NULL),
    768                             OSSL_PARAM_END };
    769     int a, b;
    770 
    771     param->data = &a;
    772     param[1].data = &b;
    773     if (!TEST_false(OSSL_PARAM_modified(param))
    774             && !TEST_true(OSSL_PARAM_set_int32(param, 1234))
    775             && !TEST_true(OSSL_PARAM_modified(param))
    776             && !TEST_false(OSSL_PARAM_modified(param + 1))
    777             && !TEST_true(OSSL_PARAM_set_int32(param + 1, 1))
    778             && !TEST_true(OSSL_PARAM_modified(param + 1)))
    779         return 0;
    780     OSSL_PARAM_set_all_unmodified(param);
    781     if (!TEST_false(OSSL_PARAM_modified(param))
    782             && !TEST_true(OSSL_PARAM_set_int32(param, 4321))
    783             && !TEST_true(OSSL_PARAM_modified(param))
    784             && !TEST_false(OSSL_PARAM_modified(param + 1))
    785             && !TEST_true(OSSL_PARAM_set_int32(param + 1, 2))
    786             && !TEST_true(OSSL_PARAM_modified(param + 1)))
    787         return 0;
    788     return 1;
    789 }
    790 
    791 static int test_param_copy_null(void)
    792 {
    793     int ret, val;
    794     int a = 1, b = 2, i = 0;
    795     OSSL_PARAM *cp1 = NULL, *cp2 = NULL, *p;
    796     OSSL_PARAM param[3];
    797 
    798     param[i++] = OSSL_PARAM_construct_int("a", &a);
    799     param[i++] = OSSL_PARAM_construct_int("b", &b);
    800     param[i] = OSSL_PARAM_construct_end();
    801 
    802     ret = TEST_ptr_null(OSSL_PARAM_dup(NULL))
    803           && TEST_ptr(cp1 = OSSL_PARAM_merge(NULL, param))
    804           && TEST_ptr(p = OSSL_PARAM_locate(cp1, "a"))
    805           && TEST_true(OSSL_PARAM_get_int(p, &val))
    806           && TEST_int_eq(val, 1)
    807           && TEST_ptr(p = OSSL_PARAM_locate(cp1, "b"))
    808           && TEST_true(OSSL_PARAM_get_int(p, &val))
    809           && TEST_int_eq(val, 2)
    810           && TEST_ptr(cp2 = OSSL_PARAM_merge(param, NULL))
    811           && TEST_ptr(p = OSSL_PARAM_locate(cp2, "a"))
    812           && TEST_true(OSSL_PARAM_get_int(p, &val))
    813           && TEST_int_eq(val, 1)
    814           && TEST_ptr(p = OSSL_PARAM_locate(cp2, "b"))
    815           && TEST_true(OSSL_PARAM_get_int(p, &val))
    816           && TEST_int_eq(val, 2)
    817           && TEST_ptr_null(OSSL_PARAM_merge(NULL, NULL));
    818     OSSL_PARAM_free(cp2);
    819     OSSL_PARAM_free(cp1);
    820     return ret;
    821 }
    822 static int test_param_merge(void)
    823 {
    824     int val, ret;
    825     int values[] = {1, 2, 3, 4};
    826     OSSL_PARAM *p = NULL, *cp = NULL;
    827     OSSL_PARAM param[3], param1[3];
    828 
    829     param[0] = OSSL_PARAM_construct_int("diff1", &values[0]);
    830     param[1] = OSSL_PARAM_construct_int("same", &values[1]);
    831     param[2] = OSSL_PARAM_construct_end();
    832     param1[0] = OSSL_PARAM_construct_int("diff2", &values[2]);
    833     param1[1] = OSSL_PARAM_construct_int("same", &values[3]);
    834     param1[2] = OSSL_PARAM_construct_end();
    835 
    836     ret = TEST_ptr(p = OSSL_PARAM_merge(param, param1))
    837         && TEST_ptr(cp = OSSL_PARAM_locate(p, "diff1"))
    838         && TEST_true(OSSL_PARAM_get_int(p, &val))
    839         && TEST_int_eq(val, values[0])
    840         && TEST_ptr(cp = OSSL_PARAM_locate(p, "diff2"))
    841         && TEST_true(OSSL_PARAM_get_int(cp, &val))
    842         && TEST_int_eq(val, values[2])
    843         && TEST_ptr(cp = OSSL_PARAM_locate(p, "same"))
    844         && TEST_true(OSSL_PARAM_get_int(cp, &val))
    845         && TEST_int_eq(val, values[3]);
    846     OSSL_PARAM_free(p);
    847     return ret;
    848 }
    849 
    850 int setup_tests(void)
    851 {
    852     ADD_ALL_TESTS(test_param_int, OSSL_NELEM(raw_values));
    853     ADD_ALL_TESTS(test_param_long, OSSL_NELEM(raw_values));
    854     ADD_ALL_TESTS(test_param_uint, OSSL_NELEM(raw_values));
    855     ADD_ALL_TESTS(test_param_ulong, OSSL_NELEM(raw_values));
    856     ADD_ALL_TESTS(test_param_int32, OSSL_NELEM(raw_values));
    857     ADD_ALL_TESTS(test_param_uint32, OSSL_NELEM(raw_values));
    858     ADD_ALL_TESTS(test_param_size_t, OSSL_NELEM(raw_values));
    859     ADD_ALL_TESTS(test_param_time_t, OSSL_NELEM(raw_values));
    860     ADD_ALL_TESTS(test_param_int64, OSSL_NELEM(raw_values));
    861     ADD_ALL_TESTS(test_param_uint64, OSSL_NELEM(raw_values));
    862     ADD_ALL_TESTS(test_param_bignum, OSSL_NELEM(raw_values));
    863     ADD_ALL_TESTS(test_param_signed_bignum, OSSL_NELEM(raw_values));
    864     ADD_TEST(test_param_real);
    865     ADD_ALL_TESTS(test_param_construct, 4);
    866     ADD_TEST(test_param_modified);
    867     ADD_TEST(test_param_copy_null);
    868     ADD_TEST(test_param_merge);
    869     return 1;
    870 }
    871