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(¶m), 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(¶m, 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(¶m, &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(¶m, 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(¶m), 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(¶m, 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(¶m, &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(¶m, 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(¶m), 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(¶m, 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(¶m, &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(¶m, 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(¶m), 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(¶m, 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(¶m, &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(¶m, 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(¶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) : raw_values[n].len; 354 OSSL_PARAM param = OSSL_PARAM_uint32("a", NULL); 355 356 if (!TEST_int_eq(test_param_type_null(¶m), 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(¶m, 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(¶m, &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(¶m, 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(¶m), 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(¶m, 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(¶m, &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(¶m, 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(¶m), 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(¶m, 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(¶m, &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(¶m, 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(¶m), 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(¶m, 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(¶m, &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(¶m, 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(¶m), 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(¶m, 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(¶m, &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(¶m, 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(¶m), 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(¶m, 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(¶m, &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(¶m), 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(¶m, 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(¶m, &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(¶m), 1)) 578 return 0; 579 580 param.data = &p; 581 return TEST_true(OSSL_PARAM_set_double(¶m, 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