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(¶m), 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(¶m, 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(¶m, &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(¶m, 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(¶m), 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(¶m, 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(¶m, &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(¶m, 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(¶m), 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(¶m, 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(¶m, &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(¶m, 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(¶m), 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(¶m, 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(¶m, &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(¶m, 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(¶m), 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(¶m, 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(¶m, &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(¶m, 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(¶m), 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(¶m, 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(¶m, &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(¶m, 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(¶m), 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(¶m, 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(¶m, &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(¶m, 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(¶m), 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(¶m, 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(¶m, &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(¶m, 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(¶m), 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(¶m, 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(¶m, &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(¶m, 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(¶m), 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(¶m, 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(¶m, &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(¶m, 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(¶m), 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(¶m, 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(¶m, &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(¶m), 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(¶m, 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(¶m, &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(¶m), 1)) 583 return 0; 584 585 param.data = &p; 586 return TEST_true(OSSL_PARAM_set_double(¶m, 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