2 * Copyright 2019-2020 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"
14 #include "internal/numbers.h"
16 OSSL_PARAM *OSSL_PARAM_locate(OSSL_PARAM *p, const char *key)
18 if (p != NULL && key != NULL)
19 for (; p->key != NULL; p++)
20 if (strcmp(key, p->key) == 0)
25 const OSSL_PARAM *OSSL_PARAM_locate_const(const OSSL_PARAM *p, const char *key)
27 return OSSL_PARAM_locate((OSSL_PARAM *)p, key);
30 static OSSL_PARAM ossl_param_construct(const char *key, unsigned int data_type,
31 void *data, size_t data_size)
36 res.data_type = data_type;
38 res.data_size = data_size;
39 res.return_size = OSSL_PARAM_UNMODIFIED;
43 int OSSL_PARAM_modified(const OSSL_PARAM *p)
45 return p != NULL && p->return_size != OSSL_PARAM_UNMODIFIED;
48 void OSSL_PARAM_set_all_unmodified(OSSL_PARAM *p)
51 while (p->key != NULL)
52 p++->return_size = OSSL_PARAM_UNMODIFIED;
55 int OSSL_PARAM_get_int(const OSSL_PARAM *p, int *val)
57 switch (sizeof(int)) {
59 return OSSL_PARAM_get_int32(p, (int32_t *)val);
61 return OSSL_PARAM_get_int64(p, (int64_t *)val);
66 int OSSL_PARAM_set_int(OSSL_PARAM *p, int val)
68 switch (sizeof(int)) {
70 return OSSL_PARAM_set_int32(p, (int32_t)val);
72 return OSSL_PARAM_set_int64(p, (int64_t)val);
77 OSSL_PARAM OSSL_PARAM_construct_int(const char *key, int *buf)
79 return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int));
82 int OSSL_PARAM_get_uint(const OSSL_PARAM *p, unsigned int *val)
84 switch (sizeof(unsigned int)) {
85 case sizeof(uint32_t):
86 return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
87 case sizeof(uint64_t):
88 return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
93 int OSSL_PARAM_set_uint(OSSL_PARAM *p, unsigned int val)
95 switch (sizeof(unsigned int)) {
96 case sizeof(uint32_t):
97 return OSSL_PARAM_set_uint32(p, (uint32_t)val);
98 case sizeof(uint64_t):
99 return OSSL_PARAM_set_uint64(p, (uint64_t)val);
104 OSSL_PARAM OSSL_PARAM_construct_uint(const char *key, unsigned int *buf)
106 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
107 sizeof(unsigned int));
110 int OSSL_PARAM_get_long(const OSSL_PARAM *p, long int *val)
112 switch (sizeof(long int)) {
113 case sizeof(int32_t):
114 return OSSL_PARAM_get_int32(p, (int32_t *)val);
115 case sizeof(int64_t):
116 return OSSL_PARAM_get_int64(p, (int64_t *)val);
121 int OSSL_PARAM_set_long(OSSL_PARAM *p, long int val)
123 switch (sizeof(long int)) {
124 case sizeof(int32_t):
125 return OSSL_PARAM_set_int32(p, (int32_t)val);
126 case sizeof(int64_t):
127 return OSSL_PARAM_set_int64(p, (int64_t)val);
132 OSSL_PARAM OSSL_PARAM_construct_long(const char *key, long int *buf)
134 return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(long int));
137 int OSSL_PARAM_get_ulong(const OSSL_PARAM *p, unsigned long int *val)
139 switch (sizeof(unsigned long int)) {
140 case sizeof(uint32_t):
141 return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
142 case sizeof(uint64_t):
143 return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
148 int OSSL_PARAM_set_ulong(OSSL_PARAM *p, unsigned long int val)
150 switch (sizeof(unsigned long int)) {
151 case sizeof(uint32_t):
152 return OSSL_PARAM_set_uint32(p, (uint32_t)val);
153 case sizeof(uint64_t):
154 return OSSL_PARAM_set_uint64(p, (uint64_t)val);
159 OSSL_PARAM OSSL_PARAM_construct_ulong(const char *key, unsigned long int *buf)
161 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
162 sizeof(unsigned long int));
165 int OSSL_PARAM_get_int32(const OSSL_PARAM *p, int32_t *val)
172 if (val == NULL || p == NULL )
175 if (p->data_type == OSSL_PARAM_INTEGER) {
176 switch (p->data_size) {
177 case sizeof(int32_t):
178 *val = *(const int32_t *)p->data;
180 case sizeof(int64_t):
181 i64 = *(const int64_t *)p->data;
182 if (i64 >= INT32_MIN && i64 <= INT32_MAX) {
188 } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
189 switch (p->data_size) {
190 case sizeof(uint32_t):
191 u32 = *(const uint32_t *)p->data;
192 if (u32 <= INT32_MAX) {
197 case sizeof(uint64_t):
198 u64 = *(const uint64_t *)p->data;
199 if (u64 <= INT32_MAX) {
205 } else if (p->data_type == OSSL_PARAM_REAL) {
206 switch (p->data_size) {
208 d = *(const double *)p->data;
209 if (d >= INT32_MIN && d <= INT32_MAX && d == (int32_t)d) {
219 int OSSL_PARAM_set_int32(OSSL_PARAM *p, int32_t val)
224 if (p->data_type == OSSL_PARAM_INTEGER) {
225 p->return_size = sizeof(int32_t); /* Minimum expected size */
228 switch (p->data_size) {
229 case sizeof(int32_t):
230 *(int32_t *)p->data = val;
232 case sizeof(int64_t):
233 p->return_size = sizeof(int64_t);
234 *(int64_t *)p->data = (int64_t)val;
237 } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) {
238 p->return_size = sizeof(uint32_t); /* Minimum expected size */
241 switch (p->data_size) {
242 case sizeof(uint32_t):
243 *(uint32_t *)p->data = (uint32_t)val;
245 case sizeof(uint64_t):
246 p->return_size = sizeof(uint64_t);
247 *(uint64_t *)p->data = (uint64_t)val;
250 } else if (p->data_type == OSSL_PARAM_REAL) {
251 p->return_size = sizeof(double);
254 switch (p->data_size) {
256 *(double *)p->data = (double)val;
263 OSSL_PARAM OSSL_PARAM_construct_int32(const char *key, int32_t *buf)
265 return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf,
269 int OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val)
276 if (val == NULL || p == NULL)
279 if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
280 switch (p->data_size) {
281 case sizeof(uint32_t):
282 *val = *(const uint32_t *)p->data;
284 case sizeof(uint64_t):
285 u64 = *(const uint64_t *)p->data;
286 if (u64 <= UINT32_MAX) {
287 *val = (uint32_t)u64;
292 } else if (p->data_type == OSSL_PARAM_INTEGER) {
293 switch (p->data_size) {
294 case sizeof(int32_t):
295 i32 = *(const int32_t *)p->data;
301 case sizeof(int64_t):
302 i64 = *(const int64_t *)p->data;
303 if (i64 >= 0 && i64 <= UINT32_MAX) {
304 *val = (uint32_t)i64;
309 } else if (p->data_type == OSSL_PARAM_REAL) {
310 switch (p->data_size) {
312 d = *(const double *)p->data;
313 if (d >= 0 && d <= UINT32_MAX && d == (uint32_t)d) {
323 int OSSL_PARAM_set_uint32(OSSL_PARAM *p, uint32_t val)
329 if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
330 p->return_size = sizeof(uint32_t); /* Minimum expected size */
333 switch (p->data_size) {
334 case sizeof(uint32_t):
335 *(uint32_t *)p->data = val;
337 case sizeof(uint64_t):
338 p->return_size = sizeof(uint64_t);
339 *(uint64_t *)p->data = val;
342 } else if (p->data_type == OSSL_PARAM_INTEGER) {
343 p->return_size = sizeof(int32_t); /* Minimum expected size */
346 switch (p->data_size) {
347 case sizeof(int32_t):
348 if (val <= INT32_MAX) {
349 *(int32_t *)p->data = (int32_t)val;
353 case sizeof(int64_t):
354 p->return_size = sizeof(int64_t);
355 *(int64_t *)p->data = (int64_t)val;
358 } else if (p->data_type == OSSL_PARAM_REAL) {
359 p->return_size = sizeof(double);
362 switch (p->data_size) {
364 *(double *)p->data = (double)val;
371 OSSL_PARAM OSSL_PARAM_construct_uint32(const char *key, uint32_t *buf)
373 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
377 int OSSL_PARAM_get_int64(const OSSL_PARAM *p, int64_t *val)
382 if (val == NULL || p == NULL )
385 if (p->data_type == OSSL_PARAM_INTEGER) {
386 switch (p->data_size) {
387 case sizeof(int32_t):
388 *val = *(const int32_t *)p->data;
390 case sizeof(int64_t):
391 *val = *(const int64_t *)p->data;
394 } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
395 switch (p->data_size) {
396 case sizeof(uint32_t):
397 *val = *(const uint32_t *)p->data;
399 case sizeof(uint64_t):
400 u64 = *(const uint64_t *)p->data;
401 if (u64 <= INT64_MAX) {
407 } else if (p->data_type == OSSL_PARAM_REAL) {
408 switch (p->data_size) {
410 d = *(const double *)p->data;
411 if (d >= INT64_MIN && d <= INT64_MAX && d == (int64_t)d) {
421 int OSSL_PARAM_set_int64(OSSL_PARAM *p, int64_t val)
428 if (p->data_type == OSSL_PARAM_INTEGER) {
429 p->return_size = sizeof(int64_t); /* Expected size */
432 switch (p->data_size) {
433 case sizeof(int32_t):
434 if (val >= INT32_MIN && val <= INT32_MAX) {
435 p->return_size = sizeof(int32_t);
436 *(int32_t *)p->data = (int32_t)val;
440 case sizeof(int64_t):
441 *(int64_t *)p->data = val;
444 } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) {
445 p->return_size = sizeof(uint64_t); /* Expected size */
448 switch (p->data_size) {
449 case sizeof(uint32_t):
450 if (val <= UINT32_MAX) {
451 p->return_size = sizeof(uint32_t);
452 *(uint32_t *)p->data = (uint32_t)val;
456 case sizeof(uint64_t):
457 *(uint64_t *)p->data = (uint64_t)val;
460 } else if (p->data_type == OSSL_PARAM_REAL) {
461 p->return_size = sizeof(double);
464 switch (p->data_size) {
466 u64 = val < 0 ? -val : val;
467 if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
468 *(double *)p->data = (double)val;
477 OSSL_PARAM OSSL_PARAM_construct_int64(const char *key, int64_t *buf)
479 return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int64_t));
482 int OSSL_PARAM_get_uint64(const OSSL_PARAM *p, uint64_t *val)
488 if (val == NULL || p == NULL)
491 if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
492 switch (p->data_size) {
493 case sizeof(uint32_t):
494 *val = *(const uint32_t *)p->data;
496 case sizeof(uint64_t):
497 *val = *(const uint64_t *)p->data;
500 } else if (p->data_type == OSSL_PARAM_INTEGER) {
501 switch (p->data_size) {
502 case sizeof(int32_t):
503 i32 = *(const int32_t *)p->data;
505 *val = (uint64_t)i32;
509 case sizeof(int64_t):
510 i64 = *(const int64_t *)p->data;
512 *val = (uint64_t)i64;
517 } else if (p->data_type == OSSL_PARAM_REAL) {
518 switch (p->data_size) {
520 d = *(const double *)p->data;
521 if (d >= 0 && d <= INT64_MAX && d == (uint64_t)d) {
531 int OSSL_PARAM_set_uint64(OSSL_PARAM *p, uint64_t val)
537 if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
538 p->return_size = sizeof(uint64_t); /* Expected size */
541 switch (p->data_size) {
542 case sizeof(uint32_t):
543 if (val <= UINT32_MAX) {
544 p->return_size = sizeof(uint32_t);
545 *(uint32_t *)p->data = (uint32_t)val;
549 case sizeof(uint64_t):
550 *(uint64_t *)p->data = val;
553 } else if (p->data_type == OSSL_PARAM_INTEGER) {
554 p->return_size = sizeof(int64_t); /* Expected size */
557 switch (p->data_size) {
558 case sizeof(int32_t):
559 if (val <= INT32_MAX) {
560 p->return_size = sizeof(int32_t);
561 *(int32_t *)p->data = (int32_t)val;
565 case sizeof(int64_t):
566 if (val <= INT64_MAX) {
567 *(int64_t *)p->data = (int64_t)val;
572 } else if (p->data_type == OSSL_PARAM_REAL) {
573 p->return_size = sizeof(double);
574 switch (p->data_size) {
576 if ((val >> 53) == 0) { /* 53 significant bits in the mantissa */
577 *(double *)p->data = (double)val;
586 OSSL_PARAM OSSL_PARAM_construct_uint64(const char *key, uint64_t *buf)
588 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
592 int OSSL_PARAM_get_size_t(const OSSL_PARAM *p, size_t *val)
594 switch (sizeof(size_t)) {
595 case sizeof(uint32_t):
596 return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
597 case sizeof(uint64_t):
598 return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
603 int OSSL_PARAM_set_size_t(OSSL_PARAM *p, size_t val)
605 switch (sizeof(size_t)) {
606 case sizeof(uint32_t):
607 return OSSL_PARAM_set_uint32(p, (uint32_t)val);
608 case sizeof(uint64_t):
609 return OSSL_PARAM_set_uint64(p, (uint64_t)val);
614 OSSL_PARAM OSSL_PARAM_construct_size_t(const char *key, size_t *buf)
616 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
620 int OSSL_PARAM_get_BN(const OSSL_PARAM *p, BIGNUM **val)
626 || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
629 b = BN_native2bn(p->data, (int)p->data_size, *val);
637 int OSSL_PARAM_set_BN(OSSL_PARAM *p, const BIGNUM *val)
644 if (val == NULL || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
647 /* For the moment, only positive values are permitted */
648 if (BN_is_negative(val))
651 bytes = (size_t)BN_num_bytes(val);
652 p->return_size = bytes;
655 if (p->data_size >= bytes) {
656 p->return_size = p->data_size;
657 return BN_bn2nativepad(val, p->data, p->data_size) >= 0;
662 OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf,
665 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER,
669 int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val)
674 if (val == NULL || p == NULL)
677 if (p->data_type == OSSL_PARAM_REAL) {
678 switch (p->data_size) {
680 *val = *(const double *)p->data;
683 } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
684 switch (p->data_size) {
685 case sizeof(uint32_t):
686 *val = *(const uint32_t *)p->data;
688 case sizeof(uint64_t):
689 u64 = *(const uint64_t *)p->data;
690 if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
696 } else if (p->data_type == OSSL_PARAM_INTEGER) {
697 switch (p->data_size) {
698 case sizeof(int32_t):
699 *val = *(const int32_t *)p->data;
701 case sizeof(int64_t):
702 i64 = *(const int64_t *)p->data;
703 u64 = i64 < 0 ? -i64 : i64;
704 if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
714 int OSSL_PARAM_set_double(OSSL_PARAM *p, double val)
720 if (p->data_type == OSSL_PARAM_REAL) {
721 p->return_size = sizeof(double);
724 switch (p->data_size) {
726 *(double *)p->data = val;
729 } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER
730 && val == (ossl_uintmax_t)val) {
731 p->return_size = sizeof(double);
734 switch (p->data_size) {
735 case sizeof(uint32_t):
736 if (val >= 0 && val <= UINT32_MAX) {
737 p->return_size = sizeof(uint32_t);
738 *(uint32_t *)p->data = (uint32_t)val;
742 case sizeof(uint64_t):
743 if (val >= 0 && val <= UINT64_MAX) {
744 p->return_size = sizeof(uint64_t);
745 *(uint64_t *)p->data = (uint64_t)val;
749 } else if (p->data_type == OSSL_PARAM_INTEGER && val == (ossl_intmax_t)val) {
750 p->return_size = sizeof(double);
753 switch (p->data_size) {
754 case sizeof(int32_t):
755 if (val >= INT32_MIN && val <= INT32_MAX) {
756 p->return_size = sizeof(int32_t);
757 *(int32_t *)p->data = (int32_t)val;
761 case sizeof(int64_t):
762 if (val >= INT64_MIN && val <= INT64_MAX) {
763 p->return_size = sizeof(int64_t);
764 *(int64_t *)p->data = (int64_t)val;
773 OSSL_PARAM OSSL_PARAM_construct_double(const char *key, double *buf)
775 return ossl_param_construct(key, OSSL_PARAM_REAL, buf, sizeof(double));
778 static int get_string_internal(const OSSL_PARAM *p, void **val, size_t max_len,
779 size_t *used_len, unsigned int type)
783 if (val == NULL || p == NULL || p->data_type != type)
788 if (used_len != NULL)
797 char *const q = OPENSSL_malloc(sz);
802 memcpy(q, p->data, sz);
807 memcpy(*val, p->data, sz);
811 int OSSL_PARAM_get_utf8_string(const OSSL_PARAM *p, char **val, size_t max_len)
813 return get_string_internal(p, (void **)val, max_len, NULL,
814 OSSL_PARAM_UTF8_STRING);
817 int OSSL_PARAM_get_octet_string(const OSSL_PARAM *p, void **val, size_t max_len,
820 return get_string_internal(p, val, max_len, used_len,
821 OSSL_PARAM_OCTET_STRING);
824 static int set_string_internal(OSSL_PARAM *p, const void *val, size_t len,
827 p->return_size = len;
830 if (p->data_type != type || p->data_size < len)
833 memcpy(p->data, val, len);
837 int OSSL_PARAM_set_utf8_string(OSSL_PARAM *p, const char *val)
845 return set_string_internal(p, val, strlen(val) + 1, OSSL_PARAM_UTF8_STRING);
848 int OSSL_PARAM_set_octet_string(OSSL_PARAM *p, const void *val,
857 return set_string_internal(p, val, len, OSSL_PARAM_OCTET_STRING);
860 OSSL_PARAM OSSL_PARAM_construct_utf8_string(const char *key, char *buf,
863 if (buf != NULL && bsize == 0)
864 bsize = strlen(buf) + 1;
865 return ossl_param_construct(key, OSSL_PARAM_UTF8_STRING, buf, bsize);
868 OSSL_PARAM OSSL_PARAM_construct_octet_string(const char *key, void *buf,
871 return ossl_param_construct(key, OSSL_PARAM_OCTET_STRING, buf, bsize);
874 static int get_ptr_internal(const OSSL_PARAM *p, const void **val,
875 size_t *used_len, unsigned int type)
877 if (val == NULL || p == NULL || p->data_type != type)
879 if (used_len != NULL)
880 *used_len = p->data_size;
881 *val = *(const void **)p->data;
885 int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM *p, const char **val)
887 return get_ptr_internal(p, (const void **)val, NULL, OSSL_PARAM_UTF8_PTR);
890 int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, const void **val,
893 return get_ptr_internal(p, val, used_len, OSSL_PARAM_OCTET_PTR);
896 static int set_ptr_internal(OSSL_PARAM *p, const void *val,
897 unsigned int type, size_t len)
899 p->return_size = len;
900 if (p->data_type != type)
903 *(const void **)p->data = val;
907 int OSSL_PARAM_set_utf8_ptr(OSSL_PARAM *p, const char *val)
912 return set_ptr_internal(p, val, OSSL_PARAM_UTF8_PTR,
913 val == NULL ? 0 : strlen(val) + 1);
916 int OSSL_PARAM_set_octet_ptr(OSSL_PARAM *p, const void *val,
922 return set_ptr_internal(p, val, OSSL_PARAM_OCTET_PTR, used_len);
925 OSSL_PARAM OSSL_PARAM_construct_utf8_ptr(const char *key, char **buf,
928 return ossl_param_construct(key, OSSL_PARAM_UTF8_PTR, buf, bsize);
931 OSSL_PARAM OSSL_PARAM_construct_octet_ptr(const char *key, void **buf,
934 return ossl_param_construct(key, OSSL_PARAM_OCTET_PTR, buf, bsize);
937 OSSL_PARAM OSSL_PARAM_construct_end(void)
939 OSSL_PARAM end = OSSL_PARAM_END;