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