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
swap_copy(unsigned char * out,const void * in,size_t len)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 */
le_copy(unsigned char * out,size_t outlen,const void * in,size_t inlen)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
test_param_type_null(OSSL_PARAM * param)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
test_param_type_extra(OSSL_PARAM * param,const unsigned char * cmp,size_t width)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
test_param_int(int n)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
test_param_long(int n)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
test_param_uint(int n)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
test_param_ulong(int n)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
test_param_int32(int n)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
test_param_uint32(int n)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
test_param_int64(int n)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
test_param_uint64(int n)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
test_param_size_t(int n)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
test_param_time_t(int n)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
test_param_bignum(int n)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
test_param_signed_bignum(int n)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
test_param_real(void)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
test_param_construct(int tstid)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
test_param_modified(void)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
test_param_copy_null(void)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 }
test_param_merge(void)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
setup_tests(void)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