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;