2 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
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
12 #include <openssl/params.h>
13 #include "internal/thread_once.h"
15 OSSL_PARAM
*OSSL_PARAM_locate(OSSL_PARAM
*p
, const char *key
)
17 if (p
!= NULL
&& key
!= NULL
)
18 for (; p
->key
!= NULL
; p
++)
19 if (strcmp(key
, p
->key
) == 0)
24 const OSSL_PARAM
*OSSL_PARAM_locate_const(const OSSL_PARAM
*p
, const char *key
)
26 return OSSL_PARAM_locate((OSSL_PARAM
*)p
, key
);
29 static OSSL_PARAM
ossl_param_construct(const char *key
, unsigned int data_type
,
30 void *data
, size_t data_size
)
35 res
.data_type
= data_type
;
37 res
.data_size
= data_size
;
42 int OSSL_PARAM_get_int(const OSSL_PARAM
*p
, int *val
)
44 switch (sizeof(int)) {
46 return OSSL_PARAM_get_int32(p
, (int32_t *)val
);
48 return OSSL_PARAM_get_int64(p
, (int64_t *)val
);
53 int OSSL_PARAM_set_int(OSSL_PARAM
*p
, int val
)
55 switch (sizeof(int)) {
57 return OSSL_PARAM_set_int32(p
, (int32_t)val
);
59 return OSSL_PARAM_set_int64(p
, (int64_t)val
);
64 OSSL_PARAM
OSSL_PARAM_construct_int(const char *key
, int *buf
)
66 return ossl_param_construct(key
, OSSL_PARAM_INTEGER
, buf
, sizeof(int));
69 int OSSL_PARAM_get_uint(const OSSL_PARAM
*p
, unsigned int *val
)
71 switch (sizeof(unsigned int)) {
72 case sizeof(uint32_t):
73 return OSSL_PARAM_get_uint32(p
, (uint32_t *)val
);
74 case sizeof(uint64_t):
75 return OSSL_PARAM_get_uint64(p
, (uint64_t *)val
);
80 int OSSL_PARAM_set_uint(OSSL_PARAM
*p
, unsigned int val
)
82 switch (sizeof(unsigned int)) {
83 case sizeof(uint32_t):
84 return OSSL_PARAM_set_uint32(p
, (uint32_t)val
);
85 case sizeof(uint64_t):
86 return OSSL_PARAM_set_uint64(p
, (uint64_t)val
);
91 OSSL_PARAM
OSSL_PARAM_construct_uint(const char *key
, unsigned int *buf
)
93 return ossl_param_construct(key
, OSSL_PARAM_UNSIGNED_INTEGER
, buf
,
94 sizeof(unsigned int));
97 int OSSL_PARAM_get_long(const OSSL_PARAM
*p
, long int *val
)
99 switch (sizeof(long int)) {
100 case sizeof(int32_t):
101 return OSSL_PARAM_get_int32(p
, (int32_t *)val
);
102 case sizeof(int64_t):
103 return OSSL_PARAM_get_int64(p
, (int64_t *)val
);
108 int OSSL_PARAM_set_long(OSSL_PARAM
*p
, long int val
)
110 switch (sizeof(long int)) {
111 case sizeof(int32_t):
112 return OSSL_PARAM_set_int32(p
, (int32_t)val
);
113 case sizeof(int64_t):
114 return OSSL_PARAM_set_int64(p
, (int64_t)val
);
119 OSSL_PARAM
OSSL_PARAM_construct_long(const char *key
, long int *buf
)
121 return ossl_param_construct(key
, OSSL_PARAM_INTEGER
, buf
, sizeof(long int));
124 int OSSL_PARAM_get_ulong(const OSSL_PARAM
*p
, unsigned long int *val
)
126 switch (sizeof(unsigned long int)) {
127 case sizeof(uint32_t):
128 return OSSL_PARAM_get_uint32(p
, (uint32_t *)val
);
129 case sizeof(uint64_t):
130 return OSSL_PARAM_get_uint64(p
, (uint64_t *)val
);
135 int OSSL_PARAM_set_ulong(OSSL_PARAM
*p
, unsigned long int val
)
137 switch (sizeof(unsigned long int)) {
138 case sizeof(uint32_t):
139 return OSSL_PARAM_set_uint32(p
, (uint32_t)val
);
140 case sizeof(uint64_t):
141 return OSSL_PARAM_set_uint64(p
, (uint64_t)val
);
146 OSSL_PARAM
OSSL_PARAM_construct_ulong(const char *key
, unsigned long int *buf
)
148 return ossl_param_construct(key
, OSSL_PARAM_UNSIGNED_INTEGER
, buf
,
149 sizeof(unsigned long int));
152 int OSSL_PARAM_get_int32(const OSSL_PARAM
*p
, int32_t *val
)
159 if (val
== NULL
|| p
== NULL
)
162 if (p
->data_type
== OSSL_PARAM_INTEGER
) {
163 switch (p
->data_size
) {
164 case sizeof(int32_t):
165 *val
= *(const int32_t *)p
->data
;
167 case sizeof(int64_t):
168 i64
= *(const int64_t *)p
->data
;
169 if (i64
>= INT32_MIN
&& i64
<= INT32_MAX
) {
175 } else if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
) {
176 switch (p
->data_size
) {
177 case sizeof(uint32_t):
178 u32
= *(const uint32_t *)p
->data
;
179 if (u32
<= INT32_MAX
) {
184 case sizeof(uint64_t):
185 u64
= *(const uint64_t *)p
->data
;
186 if (u64
<= INT32_MAX
) {
192 } else if (p
->data_type
== OSSL_PARAM_REAL
) {
193 switch (p
->data_size
) {
195 d
= *(const double *)p
->data
;
196 if (d
>= INT32_MIN
&& d
<= INT32_MAX
&& d
== (int32_t)d
) {
206 int OSSL_PARAM_set_int32(OSSL_PARAM
*p
, int32_t val
)
211 if (p
->data_type
== OSSL_PARAM_INTEGER
) {
212 p
->return_size
= sizeof(int32_t); /* Minimum expected size */
213 switch (p
->data_size
) {
214 case sizeof(int32_t):
215 *(int32_t *)p
->data
= val
;
217 case sizeof(int64_t):
218 p
->return_size
= sizeof(int64_t);
219 *(int64_t *)p
->data
= (int64_t)val
;
222 } else if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
&& val
>= 0) {
223 p
->return_size
= sizeof(uint32_t); /* Minimum expected size */
224 switch (p
->data_size
) {
225 case sizeof(uint32_t):
226 *(uint32_t *)p
->data
= (uint32_t)val
;
228 case sizeof(uint64_t):
229 p
->return_size
= sizeof(uint64_t);
230 *(uint64_t *)p
->data
= (uint64_t)val
;
233 } else if (p
->data_type
== OSSL_PARAM_REAL
) {
234 p
->return_size
= sizeof(double);
235 switch (p
->data_size
) {
237 *(double *)p
->data
= (double)val
;
244 OSSL_PARAM
OSSL_PARAM_construct_int32(const char *key
, int32_t *buf
)
246 return ossl_param_construct(key
, OSSL_PARAM_INTEGER
, buf
,
250 int OSSL_PARAM_get_uint32(const OSSL_PARAM
*p
, uint32_t *val
)
257 if (val
== NULL
|| p
== NULL
)
260 if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
) {
261 switch (p
->data_size
) {
262 case sizeof(uint32_t):
263 *val
= *(const uint32_t *)p
->data
;
265 case sizeof(uint64_t):
266 u64
= *(const uint64_t *)p
->data
;
267 if (u64
<= UINT32_MAX
) {
268 *val
= (uint32_t)u64
;
273 } else if (p
->data_type
== OSSL_PARAM_INTEGER
) {
274 switch (p
->data_size
) {
275 case sizeof(int32_t):
276 i32
= *(const int32_t *)p
->data
;
282 case sizeof(int64_t):
283 i64
= *(const int64_t *)p
->data
;
284 if (i64
>= 0 && i64
<= UINT32_MAX
) {
285 *val
= (uint32_t)i64
;
290 } else if (p
->data_type
== OSSL_PARAM_REAL
) {
291 switch (p
->data_size
) {
293 d
= *(const double *)p
->data
;
294 if (d
>= 0 && d
<= UINT32_MAX
&& d
== (uint32_t)d
) {
304 int OSSL_PARAM_set_uint32(OSSL_PARAM
*p
, uint32_t val
)
310 if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
) {
311 p
->return_size
= sizeof(uint32_t); /* Minimum expected size */
312 switch (p
->data_size
) {
313 case sizeof(uint32_t):
314 *(uint32_t *)p
->data
= val
;
316 case sizeof(uint64_t):
317 p
->return_size
= sizeof(uint64_t);
318 *(uint64_t *)p
->data
= val
;
321 } else if (p
->data_type
== OSSL_PARAM_INTEGER
) {
322 p
->return_size
= sizeof(int32_t); /* Minimum expected size */
323 switch (p
->data_size
) {
324 case sizeof(int32_t):
325 if (val
<= INT32_MAX
) {
326 *(int32_t *)p
->data
= (int32_t)val
;
330 case sizeof(int64_t):
331 p
->return_size
= sizeof(int64_t);
332 *(int64_t *)p
->data
= (int64_t)val
;
335 } else if (p
->data_type
== OSSL_PARAM_REAL
) {
336 p
->return_size
= sizeof(double);
337 switch (p
->data_size
) {
339 *(double *)p
->data
= (double)val
;
346 OSSL_PARAM
OSSL_PARAM_construct_uint32(const char *key
, uint32_t *buf
)
348 return ossl_param_construct(key
, OSSL_PARAM_UNSIGNED_INTEGER
, buf
,
352 int OSSL_PARAM_get_int64(const OSSL_PARAM
*p
, int64_t *val
)
357 if (val
== NULL
|| p
== NULL
)
360 if (p
->data_type
== OSSL_PARAM_INTEGER
) {
361 switch (p
->data_size
) {
362 case sizeof(int32_t):
363 *val
= *(const int32_t *)p
->data
;
365 case sizeof(int64_t):
366 *val
= *(const int64_t *)p
->data
;
369 } else if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
) {
370 switch (p
->data_size
) {
371 case sizeof(uint32_t):
372 *val
= *(const uint32_t *)p
->data
;
374 case sizeof(uint64_t):
375 u64
= *(const uint64_t *)p
->data
;
376 if (u64
<= INT64_MAX
) {
382 } else if (p
->data_type
== OSSL_PARAM_REAL
) {
383 switch (p
->data_size
) {
385 d
= *(const double *)p
->data
;
386 if (d
>= INT64_MIN
&& d
<= INT64_MAX
&& d
== (int64_t)d
) {
396 int OSSL_PARAM_set_int64(OSSL_PARAM
*p
, int64_t val
)
403 if (p
->data_type
== OSSL_PARAM_INTEGER
) {
404 p
->return_size
= sizeof(int64_t); /* Expected size */
405 switch (p
->data_size
) {
406 case sizeof(int32_t):
407 if (val
>= INT32_MIN
&& val
<= INT32_MAX
) {
408 p
->return_size
= sizeof(int32_t);
409 *(int32_t *)p
->data
= (int32_t)val
;
413 case sizeof(int64_t):
414 *(int64_t *)p
->data
= val
;
417 } else if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
&& val
>= 0) {
418 p
->return_size
= sizeof(uint64_t); /* Expected size */
419 switch (p
->data_size
) {
420 case sizeof(uint32_t):
421 if (val
<= UINT32_MAX
) {
422 p
->return_size
= sizeof(uint32_t);
423 *(uint32_t *)p
->data
= (uint32_t)val
;
427 case sizeof(uint64_t):
428 *(uint64_t *)p
->data
= (uint64_t)val
;
431 } else if (p
->data_type
== OSSL_PARAM_REAL
) {
432 p
->return_size
= sizeof(double);
433 switch (p
->data_size
) {
435 u64
= val
< 0 ? -val
: val
;
436 if ((u64
>> 53) == 0) { /* 53 significant bits in the mantissa */
437 *(double *)p
->data
= (double)val
;
446 OSSL_PARAM
OSSL_PARAM_construct_int64(const char *key
, int64_t *buf
)
448 return ossl_param_construct(key
, OSSL_PARAM_INTEGER
, buf
, sizeof(int64_t));
451 int OSSL_PARAM_get_uint64(const OSSL_PARAM
*p
, uint64_t *val
)
457 if (val
== NULL
|| p
== NULL
)
460 if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
) {
461 switch (p
->data_size
) {
462 case sizeof(uint32_t):
463 *val
= *(const uint32_t *)p
->data
;
465 case sizeof(uint64_t):
466 *val
= *(const uint64_t *)p
->data
;
469 } else if (p
->data_type
== OSSL_PARAM_INTEGER
) {
470 switch (p
->data_size
) {
471 case sizeof(int32_t):
472 i32
= *(const int32_t *)p
->data
;
474 *val
= (uint64_t)i32
;
478 case sizeof(int64_t):
479 i64
= *(const int64_t *)p
->data
;
481 *val
= (uint64_t)i64
;
486 } else if (p
->data_type
== OSSL_PARAM_REAL
) {
487 switch (p
->data_size
) {
489 d
= *(const double *)p
->data
;
490 if (d
>= 0 && d
<= INT64_MAX
&& d
== (uint64_t)d
) {
500 int OSSL_PARAM_set_uint64(OSSL_PARAM
*p
, uint64_t val
)
506 if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
) {
507 p
->return_size
= sizeof(uint64_t); /* Expected size */
508 switch (p
->data_size
) {
509 case sizeof(uint32_t):
510 if (val
<= UINT32_MAX
) {
511 p
->return_size
= sizeof(uint32_t);
512 *(uint32_t *)p
->data
= (uint32_t)val
;
516 case sizeof(uint64_t):
517 *(uint64_t *)p
->data
= val
;
520 } else if (p
->data_type
== OSSL_PARAM_INTEGER
) {
521 p
->return_size
= sizeof(int64_t); /* Expected size */
522 switch (p
->data_size
) {
523 case sizeof(int32_t):
524 if (val
<= INT32_MAX
) {
525 p
->return_size
= sizeof(int32_t);
526 *(int32_t *)p
->data
= (int32_t)val
;
530 case sizeof(int64_t):
531 if (val
<= INT64_MAX
) {
532 *(int64_t *)p
->data
= (int64_t)val
;
537 } else if (p
->data_type
== OSSL_PARAM_REAL
) {
538 p
->return_size
= sizeof(double);
539 switch (p
->data_size
) {
541 if ((val
>> 53) == 0) { /* 53 significant bits in the mantissa */
542 *(double *)p
->data
= (double)val
;
551 OSSL_PARAM
OSSL_PARAM_construct_uint64(const char *key
, uint64_t *buf
)
553 return ossl_param_construct(key
, OSSL_PARAM_UNSIGNED_INTEGER
, buf
,
557 int OSSL_PARAM_get_size_t(const OSSL_PARAM
*p
, size_t *val
)
559 switch (sizeof(size_t)) {
560 case sizeof(uint32_t):
561 return OSSL_PARAM_get_uint32(p
, (uint32_t *)val
);
562 case sizeof(uint64_t):
563 return OSSL_PARAM_get_uint64(p
, (uint64_t *)val
);
568 int OSSL_PARAM_set_size_t(OSSL_PARAM
*p
, size_t val
)
570 switch (sizeof(size_t)) {
571 case sizeof(uint32_t):
572 return OSSL_PARAM_set_uint32(p
, (uint32_t)val
);
573 case sizeof(uint64_t):
574 return OSSL_PARAM_set_uint64(p
, (uint64_t)val
);
579 OSSL_PARAM
OSSL_PARAM_construct_size_t(const char *key
, size_t *buf
)
581 return ossl_param_construct(key
, OSSL_PARAM_UNSIGNED_INTEGER
, buf
,
585 int OSSL_PARAM_get_BN(const OSSL_PARAM
*p
, BIGNUM
**val
)
591 || p
->data_type
!= OSSL_PARAM_UNSIGNED_INTEGER
)
594 b
= BN_native2bn(p
->data
, (int)p
->data_size
, *val
);
602 int OSSL_PARAM_set_BN(OSSL_PARAM
*p
, const BIGNUM
*val
)
609 if (val
== NULL
|| p
->data_type
!= OSSL_PARAM_UNSIGNED_INTEGER
)
612 /* For the moment, only positive values are permitted */
613 if (BN_is_negative(val
))
616 bytes
= (size_t)BN_num_bytes(val
);
617 p
->return_size
= bytes
;
618 return p
->data_size
>= bytes
619 && BN_bn2nativepad(val
, p
->data
, bytes
) >= 0;
622 OSSL_PARAM
OSSL_PARAM_construct_BN(const char *key
, unsigned char *buf
,
625 return ossl_param_construct(key
, OSSL_PARAM_UNSIGNED_INTEGER
,
629 int OSSL_PARAM_get_double(const OSSL_PARAM
*p
, double *val
)
634 if (val
== NULL
|| p
== NULL
)
637 if (p
->data_type
== OSSL_PARAM_REAL
) {
638 switch (p
->data_size
) {
640 *val
= *(const double *)p
->data
;
643 } else if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
) {
644 switch (p
->data_size
) {
645 case sizeof(uint32_t):
646 *val
= *(const uint32_t *)p
->data
;
648 case sizeof(uint64_t):
649 u64
= *(const uint64_t *)p
->data
;
650 if ((u64
>> 53) == 0) { /* 53 significant bits in the mantissa */
656 } else if (p
->data_type
== OSSL_PARAM_INTEGER
) {
657 switch (p
->data_size
) {
658 case sizeof(int32_t):
659 *val
= *(const int32_t *)p
->data
;
661 case sizeof(int64_t):
662 i64
= *(const int64_t *)p
->data
;
663 u64
= i64
< 0 ? -i64
: i64
;
664 if ((u64
>> 53) == 0) { /* 53 significant bits in the mantissa */
674 int OSSL_PARAM_set_double(OSSL_PARAM
*p
, double val
)
680 if (p
->data_type
== OSSL_PARAM_REAL
) {
681 p
->return_size
= sizeof(double);
682 switch (p
->data_size
) {
684 *(double *)p
->data
= val
;
687 } else if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
688 && val
== (uintmax_t)val
) {
689 p
->return_size
= sizeof(double);
690 switch (p
->data_size
) {
691 case sizeof(uint32_t):
692 if (val
>= 0 && val
<= UINT32_MAX
) {
693 p
->return_size
= sizeof(uint32_t);
694 *(uint32_t *)p
->data
= (uint32_t)val
;
698 case sizeof(uint64_t):
699 if (val
>= 0 && val
<= UINT64_MAX
) {
700 p
->return_size
= sizeof(uint64_t);
701 *(uint64_t *)p
->data
= (uint64_t)val
;
705 } else if (p
->data_type
== OSSL_PARAM_INTEGER
&& val
== (intmax_t)val
) {
706 p
->return_size
= sizeof(double);
707 switch (p
->data_size
) {
708 case sizeof(int32_t):
709 if (val
>= INT32_MIN
&& val
<= INT32_MAX
) {
710 p
->return_size
= sizeof(int32_t);
711 *(int32_t *)p
->data
= (int32_t)val
;
715 case sizeof(int64_t):
716 if (val
>= INT64_MIN
&& val
<= INT64_MAX
) {
717 p
->return_size
= sizeof(int64_t);
718 *(int64_t *)p
->data
= (int64_t)val
;
727 OSSL_PARAM
OSSL_PARAM_construct_double(const char *key
, double *buf
)
729 return ossl_param_construct(key
, OSSL_PARAM_REAL
, buf
, sizeof(double));
732 static int get_string_internal(const OSSL_PARAM
*p
, void **val
, size_t max_len
,
733 size_t *used_len
, unsigned int type
)
737 if (val
== NULL
|| p
== NULL
|| p
->data_type
!= type
)
742 if (used_len
!= NULL
)
746 char *const q
= OPENSSL_malloc(sz
);
751 memcpy(q
, p
->data
, sz
);
756 memcpy(*val
, p
->data
, sz
);
760 int OSSL_PARAM_get_utf8_string(const OSSL_PARAM
*p
, char **val
, size_t max_len
)
762 return get_string_internal(p
, (void **)val
, max_len
, NULL
,
763 OSSL_PARAM_UTF8_STRING
);
766 int OSSL_PARAM_get_octet_string(const OSSL_PARAM
*p
, void **val
, size_t max_len
,
769 return get_string_internal(p
, val
, max_len
, used_len
,
770 OSSL_PARAM_OCTET_STRING
);
773 static int set_string_internal(OSSL_PARAM
*p
, const void *val
, size_t len
,
776 p
->return_size
= len
;
777 if (p
->data_type
!= type
|| p
->data_size
< len
)
780 memcpy(p
->data
, val
, len
);
784 int OSSL_PARAM_set_utf8_string(OSSL_PARAM
*p
, const char *val
)
792 return set_string_internal(p
, val
, strlen(val
) + 1, OSSL_PARAM_UTF8_STRING
);
795 int OSSL_PARAM_set_octet_string(OSSL_PARAM
*p
, const void *val
,
804 return set_string_internal(p
, val
, len
, OSSL_PARAM_OCTET_STRING
);
807 OSSL_PARAM
OSSL_PARAM_construct_utf8_string(const char *key
, char *buf
,
810 return ossl_param_construct(key
, OSSL_PARAM_UTF8_STRING
, buf
, bsize
);
813 OSSL_PARAM
OSSL_PARAM_construct_octet_string(const char *key
, void *buf
,
816 return ossl_param_construct(key
, OSSL_PARAM_OCTET_STRING
, buf
, bsize
);
819 static int get_ptr_internal(const OSSL_PARAM
*p
, const void **val
,
820 size_t *used_len
, unsigned int type
)
822 if (val
== NULL
|| p
== NULL
|| p
->data_type
!= type
)
824 if (used_len
!= NULL
)
825 *used_len
= p
->data_size
;
826 *val
= *(const void **)p
->data
;
830 int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM
*p
, const char **val
)
832 return get_ptr_internal(p
, (const void **)val
, NULL
, OSSL_PARAM_UTF8_PTR
);
835 int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM
*p
, const void **val
,
838 return get_ptr_internal(p
, val
, used_len
, OSSL_PARAM_OCTET_PTR
);
841 static int set_ptr_internal(OSSL_PARAM
*p
, const void *val
,
842 unsigned int type
, size_t len
)
844 p
->return_size
= len
;
845 if (p
->data_type
!= type
)
847 *(const void **)p
->data
= val
;
851 int OSSL_PARAM_set_utf8_ptr(OSSL_PARAM
*p
, const char *val
)
858 return set_ptr_internal(p
, val
, OSSL_PARAM_UTF8_PTR
, strlen(val
) + 1);
861 int OSSL_PARAM_set_octet_ptr(OSSL_PARAM
*p
, const void *val
,
869 return set_ptr_internal(p
, val
, OSSL_PARAM_OCTET_PTR
, used_len
);
872 OSSL_PARAM
OSSL_PARAM_construct_utf8_ptr(const char *key
, char **buf
,
875 return ossl_param_construct(key
, OSSL_PARAM_UTF8_PTR
, buf
, bsize
);
878 OSSL_PARAM
OSSL_PARAM_construct_octet_ptr(const char *key
, void **buf
,
881 return ossl_param_construct(key
, OSSL_PARAM_OCTET_PTR
, buf
, bsize
);
884 OSSL_PARAM
OSSL_PARAM_construct_end(void)
886 OSSL_PARAM end
= OSSL_PARAM_END
;