2 * Copyright 2019-2021 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"
15 #include "internal/endian.h"
18 * Return the number of bits in the mantissa of a double. This is used to
19 * shift a larger integral value to determine if it will exactly fit into a
22 static unsigned int real_shift(void)
24 return sizeof(double) == 4 ? 24 : 53;
27 OSSL_PARAM
*OSSL_PARAM_locate(OSSL_PARAM
*p
, const char *key
)
29 if (p
!= NULL
&& key
!= NULL
)
30 for (; p
->key
!= NULL
; p
++)
31 if (strcmp(key
, p
->key
) == 0)
36 const OSSL_PARAM
*OSSL_PARAM_locate_const(const OSSL_PARAM
*p
, const char *key
)
38 return OSSL_PARAM_locate((OSSL_PARAM
*)p
, key
);
41 static OSSL_PARAM
ossl_param_construct(const char *key
, unsigned int data_type
,
42 void *data
, size_t data_size
)
47 res
.data_type
= data_type
;
49 res
.data_size
= data_size
;
50 res
.return_size
= OSSL_PARAM_UNMODIFIED
;
54 int OSSL_PARAM_modified(const OSSL_PARAM
*p
)
56 return p
!= NULL
&& p
->return_size
!= OSSL_PARAM_UNMODIFIED
;
59 void OSSL_PARAM_set_all_unmodified(OSSL_PARAM
*p
)
62 while (p
->key
!= NULL
)
63 p
++->return_size
= OSSL_PARAM_UNMODIFIED
;
66 /* Return non-zero if the signed number is negative */
67 static int is_negative(const void *number
, size_t s
)
69 const unsigned char *n
= number
;
72 return 0x80 & (IS_BIG_ENDIAN
? n
[0] : n
[s
- 1]);
75 /* Check that all the bytes specified match the expected sign byte */
76 static int check_sign_bytes(const unsigned char *p
, size_t n
, unsigned char s
)
80 for (i
= 0; i
< n
; i
++)
87 * Copy an integer to another integer.
88 * Handle different length integers and signed and unsigned integers.
89 * Both integers are in native byte ordering.
91 static int copy_integer(unsigned char *dest
, size_t dest_len
,
92 const unsigned char *src
, size_t src_len
,
93 unsigned char pad
, int signed_int
)
99 if (src_len
< dest_len
) {
100 n
= dest_len
- src_len
;
101 memset(dest
, pad
, n
);
102 memcpy(dest
+ n
, src
, src_len
);
104 n
= src_len
- dest_len
;
105 if (!check_sign_bytes(src
, n
, pad
)
107 * Shortening a signed value must retain the correct sign.
108 * Avoiding this kind of thing: -253 = 0xff03 -> 0x03 = 3
110 || (signed_int
&& ((pad
^ src
[n
]) & 0x80) != 0))
112 memcpy(dest
, src
+ n
, dest_len
);
114 } else /* IS_LITTLE_ENDIAN */ {
115 if (src_len
< dest_len
) {
116 n
= dest_len
- src_len
;
117 memset(dest
+ src_len
, pad
, n
);
118 memcpy(dest
, src
, src_len
);
120 n
= src_len
- dest_len
;
121 if (!check_sign_bytes(src
+ dest_len
, n
, pad
)
123 * Shortening a signed value must retain the correct sign.
124 * Avoiding this kind of thing: 130 = 0x0082 -> 0x82 = -126
126 || (signed_int
&& ((pad
^ src
[dest_len
- 1]) & 0x80) != 0))
128 memcpy(dest
, src
, dest_len
);
134 /* Copy a signed number to a signed number of possibly different length */
135 static int signed_from_signed(void *dest
, size_t dest_len
,
136 const void *src
, size_t src_len
)
138 return copy_integer(dest
, dest_len
, src
, src_len
,
139 is_negative(src
, src_len
) ? 0xff : 0, 1);
142 /* Copy an unsigned number to a signed number of possibly different length */
143 static int signed_from_unsigned(void *dest
, size_t dest_len
,
144 const void *src
, size_t src_len
)
146 return copy_integer(dest
, dest_len
, src
, src_len
, 0, 1);
149 /* Copy a signed number to an unsigned number of possibly different length */
150 static int unsigned_from_signed(void *dest
, size_t dest_len
,
151 const void *src
, size_t src_len
)
153 if (is_negative(src
, src_len
))
155 return copy_integer(dest
, dest_len
, src
, src_len
, 0, 0);
158 /* Copy an unsigned number to an unsigned number of possibly different length */
159 static int unsigned_from_unsigned(void *dest
, size_t dest_len
,
160 const void *src
, size_t src_len
)
162 return copy_integer(dest
, dest_len
, src
, src_len
, 0, 0);
165 /* General purpose get integer parameter call that handles odd sizes */
166 static int general_get_int(const OSSL_PARAM
*p
, void *val
, size_t val_size
)
168 if (p
->data_type
== OSSL_PARAM_INTEGER
)
169 return signed_from_signed(val
, val_size
, p
->data
, p
->data_size
);
170 if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
)
171 return signed_from_unsigned(val
, val_size
, p
->data
, p
->data_size
);
175 /* General purpose set integer parameter call that handles odd sizes */
176 static int general_set_int(OSSL_PARAM
*p
, void *val
, size_t val_size
)
180 p
->return_size
= val_size
; /* Expected size */
183 if (p
->data_type
== OSSL_PARAM_INTEGER
)
184 r
= signed_from_signed(p
->data
, p
->data_size
, val
, val_size
);
185 else if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
)
186 r
= unsigned_from_signed(p
->data
, p
->data_size
, val
, val_size
);
187 p
->return_size
= r
? p
->data_size
: val_size
;
191 /* General purpose get unsigned integer parameter call that handles odd sizes */
192 static int general_get_uint(const OSSL_PARAM
*p
, void *val
, size_t val_size
)
194 if (p
->data_type
== OSSL_PARAM_INTEGER
)
195 return unsigned_from_signed(val
, val_size
, p
->data
, p
->data_size
);
196 if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
)
197 return unsigned_from_unsigned(val
, val_size
, p
->data
, p
->data_size
);
201 /* General purpose set unsigned integer parameter call that handles odd sizes */
202 static int general_set_uint(OSSL_PARAM
*p
, void *val
, size_t val_size
)
206 p
->return_size
= val_size
; /* Expected size */
209 if (p
->data_type
== OSSL_PARAM_INTEGER
)
210 r
= signed_from_unsigned(p
->data
, p
->data_size
, val
, val_size
);
211 else if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
)
212 r
= unsigned_from_unsigned(p
->data
, p
->data_size
, val
, val_size
);
213 p
->return_size
= r
? p
->data_size
: val_size
;
217 int OSSL_PARAM_get_int(const OSSL_PARAM
*p
, int *val
)
219 #ifndef OPENSSL_SMALL_FOOTPRINT
220 switch (sizeof(int)) {
221 case sizeof(int32_t):
222 return OSSL_PARAM_get_int32(p
, (int32_t *)val
);
223 case sizeof(int64_t):
224 return OSSL_PARAM_get_int64(p
, (int64_t *)val
);
227 return general_get_int(p
, val
, sizeof(*val
));
230 int OSSL_PARAM_set_int(OSSL_PARAM
*p
, int val
)
232 #ifndef OPENSSL_SMALL_FOOTPRINT
233 switch (sizeof(int)) {
234 case sizeof(int32_t):
235 return OSSL_PARAM_set_int32(p
, (int32_t)val
);
236 case sizeof(int64_t):
237 return OSSL_PARAM_set_int64(p
, (int64_t)val
);
240 return general_set_int(p
, &val
, sizeof(val
));
243 OSSL_PARAM
OSSL_PARAM_construct_int(const char *key
, int *buf
)
245 return ossl_param_construct(key
, OSSL_PARAM_INTEGER
, buf
, sizeof(int));
248 int OSSL_PARAM_get_uint(const OSSL_PARAM
*p
, unsigned int *val
)
250 #ifndef OPENSSL_SMALL_FOOTPRINT
251 switch (sizeof(unsigned int)) {
252 case sizeof(uint32_t):
253 return OSSL_PARAM_get_uint32(p
, (uint32_t *)val
);
254 case sizeof(uint64_t):
255 return OSSL_PARAM_get_uint64(p
, (uint64_t *)val
);
258 return general_get_uint(p
, val
, sizeof(*val
));
261 int OSSL_PARAM_set_uint(OSSL_PARAM
*p
, unsigned int val
)
263 #ifndef OPENSSL_SMALL_FOOTPRINT
264 switch (sizeof(unsigned int)) {
265 case sizeof(uint32_t):
266 return OSSL_PARAM_set_uint32(p
, (uint32_t)val
);
267 case sizeof(uint64_t):
268 return OSSL_PARAM_set_uint64(p
, (uint64_t)val
);
271 return general_set_uint(p
, &val
, sizeof(val
));
274 OSSL_PARAM
OSSL_PARAM_construct_uint(const char *key
, unsigned int *buf
)
276 return ossl_param_construct(key
, OSSL_PARAM_UNSIGNED_INTEGER
, buf
,
277 sizeof(unsigned int));
280 int OSSL_PARAM_get_long(const OSSL_PARAM
*p
, long int *val
)
282 #ifndef OPENSSL_SMALL_FOOTPRINT
283 switch (sizeof(long int)) {
284 case sizeof(int32_t):
285 return OSSL_PARAM_get_int32(p
, (int32_t *)val
);
286 case sizeof(int64_t):
287 return OSSL_PARAM_get_int64(p
, (int64_t *)val
);
290 return general_get_int(p
, val
, sizeof(*val
));
293 int OSSL_PARAM_set_long(OSSL_PARAM
*p
, long int val
)
295 #ifndef OPENSSL_SMALL_FOOTPRINT
296 switch (sizeof(long int)) {
297 case sizeof(int32_t):
298 return OSSL_PARAM_set_int32(p
, (int32_t)val
);
299 case sizeof(int64_t):
300 return OSSL_PARAM_set_int64(p
, (int64_t)val
);
303 return general_set_int(p
, &val
, sizeof(val
));
306 OSSL_PARAM
OSSL_PARAM_construct_long(const char *key
, long int *buf
)
308 return ossl_param_construct(key
, OSSL_PARAM_INTEGER
, buf
, sizeof(long int));
311 int OSSL_PARAM_get_ulong(const OSSL_PARAM
*p
, unsigned long int *val
)
313 #ifndef OPENSSL_SMALL_FOOTPRINT
314 switch (sizeof(unsigned long int)) {
315 case sizeof(uint32_t):
316 return OSSL_PARAM_get_uint32(p
, (uint32_t *)val
);
317 case sizeof(uint64_t):
318 return OSSL_PARAM_get_uint64(p
, (uint64_t *)val
);
321 return general_get_uint(p
, val
, sizeof(*val
));
324 int OSSL_PARAM_set_ulong(OSSL_PARAM
*p
, unsigned long int val
)
326 #ifndef OPENSSL_SMALL_FOOTPRINT
327 switch (sizeof(unsigned long int)) {
328 case sizeof(uint32_t):
329 return OSSL_PARAM_set_uint32(p
, (uint32_t)val
);
330 case sizeof(uint64_t):
331 return OSSL_PARAM_set_uint64(p
, (uint64_t)val
);
334 return general_set_uint(p
, &val
, sizeof(val
));
337 OSSL_PARAM
OSSL_PARAM_construct_ulong(const char *key
, unsigned long int *buf
)
339 return ossl_param_construct(key
, OSSL_PARAM_UNSIGNED_INTEGER
, buf
,
340 sizeof(unsigned long int));
343 int OSSL_PARAM_get_int32(const OSSL_PARAM
*p
, int32_t *val
)
347 if (val
== NULL
|| p
== NULL
)
350 if (p
->data_type
== OSSL_PARAM_INTEGER
) {
351 #ifndef OPENSSL_SMALL_FOOTPRINT
354 switch (p
->data_size
) {
355 case sizeof(int32_t):
356 *val
= *(const int32_t *)p
->data
;
358 case sizeof(int64_t):
359 i64
= *(const int64_t *)p
->data
;
360 if (i64
>= INT32_MIN
&& i64
<= INT32_MAX
) {
367 return general_get_int(p
, val
, sizeof(*val
));
369 } else if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
) {
370 #ifndef OPENSSL_SMALL_FOOTPRINT
374 switch (p
->data_size
) {
375 case sizeof(uint32_t):
376 u32
= *(const uint32_t *)p
->data
;
377 if (u32
<= INT32_MAX
) {
382 case sizeof(uint64_t):
383 u64
= *(const uint64_t *)p
->data
;
384 if (u64
<= INT32_MAX
) {
391 return general_get_int(p
, val
, sizeof(*val
));
393 } else if (p
->data_type
== OSSL_PARAM_REAL
) {
394 switch (p
->data_size
) {
396 d
= *(const double *)p
->data
;
397 if (d
>= INT32_MIN
&& d
<= INT32_MAX
&& d
== (int32_t)d
) {
407 int OSSL_PARAM_set_int32(OSSL_PARAM
*p
, int32_t val
)
412 if (p
->data_type
== OSSL_PARAM_INTEGER
) {
413 #ifndef OPENSSL_SMALL_FOOTPRINT
414 p
->return_size
= sizeof(int32_t); /* Minimum expected size */
417 switch (p
->data_size
) {
418 case sizeof(int32_t):
419 *(int32_t *)p
->data
= val
;
421 case sizeof(int64_t):
422 p
->return_size
= sizeof(int64_t);
423 *(int64_t *)p
->data
= (int64_t)val
;
427 return general_set_int(p
, &val
, sizeof(val
));
428 } else if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
&& val
>= 0) {
429 #ifndef OPENSSL_SMALL_FOOTPRINT
430 p
->return_size
= sizeof(uint32_t); /* Minimum expected size */
433 switch (p
->data_size
) {
434 case sizeof(uint32_t):
435 *(uint32_t *)p
->data
= (uint32_t)val
;
437 case sizeof(uint64_t):
438 p
->return_size
= sizeof(uint64_t);
439 *(uint64_t *)p
->data
= (uint64_t)val
;
443 return general_set_int(p
, &val
, sizeof(val
));
444 } else if (p
->data_type
== OSSL_PARAM_REAL
) {
445 p
->return_size
= sizeof(double);
448 switch (p
->data_size
) {
450 *(double *)p
->data
= (double)val
;
457 OSSL_PARAM
OSSL_PARAM_construct_int32(const char *key
, int32_t *buf
)
459 return ossl_param_construct(key
, OSSL_PARAM_INTEGER
, buf
,
463 int OSSL_PARAM_get_uint32(const OSSL_PARAM
*p
, uint32_t *val
)
467 if (val
== NULL
|| p
== NULL
)
470 if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
) {
471 #ifndef OPENSSL_SMALL_FOOTPRINT
474 switch (p
->data_size
) {
475 case sizeof(uint32_t):
476 *val
= *(const uint32_t *)p
->data
;
478 case sizeof(uint64_t):
479 u64
= *(const uint64_t *)p
->data
;
480 if (u64
<= UINT32_MAX
) {
481 *val
= (uint32_t)u64
;
487 return general_get_uint(p
, val
, sizeof(*val
));
488 } else if (p
->data_type
== OSSL_PARAM_INTEGER
) {
489 #ifndef OPENSSL_SMALL_FOOTPRINT
493 switch (p
->data_size
) {
494 case sizeof(int32_t):
495 i32
= *(const int32_t *)p
->data
;
501 case sizeof(int64_t):
502 i64
= *(const int64_t *)p
->data
;
503 if (i64
>= 0 && i64
<= UINT32_MAX
) {
504 *val
= (uint32_t)i64
;
510 return general_get_uint(p
, val
, sizeof(*val
));
511 } else if (p
->data_type
== OSSL_PARAM_REAL
) {
512 switch (p
->data_size
) {
514 d
= *(const double *)p
->data
;
515 if (d
>= 0 && d
<= UINT32_MAX
&& d
== (uint32_t)d
) {
525 int OSSL_PARAM_set_uint32(OSSL_PARAM
*p
, uint32_t val
)
531 if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
) {
532 #ifndef OPENSSL_SMALL_FOOTPRINT
533 p
->return_size
= sizeof(uint32_t); /* Minimum expected size */
536 switch (p
->data_size
) {
537 case sizeof(uint32_t):
538 *(uint32_t *)p
->data
= val
;
540 case sizeof(uint64_t):
541 p
->return_size
= sizeof(uint64_t);
542 *(uint64_t *)p
->data
= val
;
546 return general_set_uint(p
, &val
, sizeof(val
));
547 } else if (p
->data_type
== OSSL_PARAM_INTEGER
) {
548 #ifndef OPENSSL_SMALL_FOOTPRINT
549 p
->return_size
= sizeof(int32_t); /* Minimum expected size */
552 switch (p
->data_size
) {
553 case sizeof(int32_t):
554 if (val
<= INT32_MAX
) {
555 *(int32_t *)p
->data
= (int32_t)val
;
559 case sizeof(int64_t):
560 p
->return_size
= sizeof(int64_t);
561 *(int64_t *)p
->data
= (int64_t)val
;
565 return general_set_uint(p
, &val
, sizeof(val
));
566 } else if (p
->data_type
== OSSL_PARAM_REAL
) {
567 p
->return_size
= sizeof(double);
570 switch (p
->data_size
) {
572 *(double *)p
->data
= (double)val
;
579 OSSL_PARAM
OSSL_PARAM_construct_uint32(const char *key
, uint32_t *buf
)
581 return ossl_param_construct(key
, OSSL_PARAM_UNSIGNED_INTEGER
, buf
,
585 int OSSL_PARAM_get_int64(const OSSL_PARAM
*p
, int64_t *val
)
589 if (val
== NULL
|| p
== NULL
)
592 if (p
->data_type
== OSSL_PARAM_INTEGER
) {
593 #ifndef OPENSSL_SMALL_FOOTPRINT
594 switch (p
->data_size
) {
595 case sizeof(int32_t):
596 *val
= *(const int32_t *)p
->data
;
598 case sizeof(int64_t):
599 *val
= *(const int64_t *)p
->data
;
603 return general_get_int(p
, val
, sizeof(*val
));
604 } else if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
) {
605 #ifndef OPENSSL_SMALL_FOOTPRINT
608 switch (p
->data_size
) {
609 case sizeof(uint32_t):
610 *val
= *(const uint32_t *)p
->data
;
612 case sizeof(uint64_t):
613 u64
= *(const uint64_t *)p
->data
;
614 if (u64
<= INT64_MAX
) {
621 return general_get_int(p
, val
, sizeof(*val
));
622 } else if (p
->data_type
== OSSL_PARAM_REAL
) {
623 switch (p
->data_size
) {
625 d
= *(const double *)p
->data
;
628 * By subtracting 65535 (2^16-1) we cancel the low order
629 * 15 bits of INT64_MAX to avoid using imprecise floating
632 && d
< (double)(INT64_MAX
- 65535) + 65536.0
633 && d
== (int64_t)d
) {
643 int OSSL_PARAM_set_int64(OSSL_PARAM
*p
, int64_t val
)
650 if (p
->data_type
== OSSL_PARAM_INTEGER
) {
651 #ifndef OPENSSL_SMALL_FOOTPRINT
652 p
->return_size
= sizeof(int64_t); /* Expected size */
655 switch (p
->data_size
) {
656 case sizeof(int32_t):
657 if (val
>= INT32_MIN
&& val
<= INT32_MAX
) {
658 p
->return_size
= sizeof(int32_t);
659 *(int32_t *)p
->data
= (int32_t)val
;
663 case sizeof(int64_t):
664 *(int64_t *)p
->data
= val
;
668 return general_set_int(p
, &val
, sizeof(val
));
669 } else if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
&& val
>= 0) {
670 #ifndef OPENSSL_SMALL_FOOTPRINT
671 p
->return_size
= sizeof(uint64_t); /* Expected size */
674 switch (p
->data_size
) {
675 case sizeof(uint32_t):
676 if (val
<= UINT32_MAX
) {
677 p
->return_size
= sizeof(uint32_t);
678 *(uint32_t *)p
->data
= (uint32_t)val
;
682 case sizeof(uint64_t):
683 *(uint64_t *)p
->data
= (uint64_t)val
;
687 return general_set_int(p
, &val
, sizeof(val
));
688 } else if (p
->data_type
== OSSL_PARAM_REAL
) {
689 p
->return_size
= sizeof(double);
692 switch (p
->data_size
) {
694 u64
= val
< 0 ? -val
: val
;
695 if ((u64
>> real_shift()) == 0) {
696 *(double *)p
->data
= (double)val
;
705 OSSL_PARAM
OSSL_PARAM_construct_int64(const char *key
, int64_t *buf
)
707 return ossl_param_construct(key
, OSSL_PARAM_INTEGER
, buf
, sizeof(int64_t));
710 int OSSL_PARAM_get_uint64(const OSSL_PARAM
*p
, uint64_t *val
)
714 if (val
== NULL
|| p
== NULL
)
717 if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
) {
718 #ifndef OPENSSL_SMALL_FOOTPRINT
719 switch (p
->data_size
) {
720 case sizeof(uint32_t):
721 *val
= *(const uint32_t *)p
->data
;
723 case sizeof(uint64_t):
724 *val
= *(const uint64_t *)p
->data
;
728 return general_get_uint(p
, val
, sizeof(*val
));
729 } else if (p
->data_type
== OSSL_PARAM_INTEGER
) {
730 #ifndef OPENSSL_SMALL_FOOTPRINT
734 switch (p
->data_size
) {
735 case sizeof(int32_t):
736 i32
= *(const int32_t *)p
->data
;
738 *val
= (uint64_t)i32
;
742 case sizeof(int64_t):
743 i64
= *(const int64_t *)p
->data
;
745 *val
= (uint64_t)i64
;
751 return general_get_uint(p
, val
, sizeof(*val
));
752 } else if (p
->data_type
== OSSL_PARAM_REAL
) {
753 switch (p
->data_size
) {
755 d
= *(const double *)p
->data
;
758 * By subtracting 65535 (2^16-1) we cancel the low order
759 * 15 bits of UINT64_MAX to avoid using imprecise floating
762 && d
< (double)(UINT64_MAX
- 65535) + 65536.0
763 && d
== (uint64_t)d
) {
773 int OSSL_PARAM_set_uint64(OSSL_PARAM
*p
, uint64_t val
)
779 if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
) {
780 #ifndef OPENSSL_SMALL_FOOTPRINT
781 p
->return_size
= sizeof(uint64_t); /* Expected size */
784 switch (p
->data_size
) {
785 case sizeof(uint32_t):
786 if (val
<= UINT32_MAX
) {
787 p
->return_size
= sizeof(uint32_t);
788 *(uint32_t *)p
->data
= (uint32_t)val
;
792 case sizeof(uint64_t):
793 *(uint64_t *)p
->data
= val
;
797 return general_set_uint(p
, &val
, sizeof(val
));
798 } else if (p
->data_type
== OSSL_PARAM_INTEGER
) {
799 #ifndef OPENSSL_SMALL_FOOTPRINT
800 p
->return_size
= sizeof(int64_t); /* Expected size */
803 switch (p
->data_size
) {
804 case sizeof(int32_t):
805 if (val
<= INT32_MAX
) {
806 p
->return_size
= sizeof(int32_t);
807 *(int32_t *)p
->data
= (int32_t)val
;
811 case sizeof(int64_t):
812 if (val
<= INT64_MAX
) {
813 *(int64_t *)p
->data
= (int64_t)val
;
819 return general_set_uint(p
, &val
, sizeof(val
));
820 } else if (p
->data_type
== OSSL_PARAM_REAL
) {
821 p
->return_size
= sizeof(double);
822 switch (p
->data_size
) {
824 if ((val
>> real_shift()) == 0) {
825 *(double *)p
->data
= (double)val
;
834 OSSL_PARAM
OSSL_PARAM_construct_uint64(const char *key
, uint64_t *buf
)
836 return ossl_param_construct(key
, OSSL_PARAM_UNSIGNED_INTEGER
, buf
,
840 int OSSL_PARAM_get_size_t(const OSSL_PARAM
*p
, size_t *val
)
842 #ifndef OPENSSL_SMALL_FOOTPRINT
843 switch (sizeof(size_t)) {
844 case sizeof(uint32_t):
845 return OSSL_PARAM_get_uint32(p
, (uint32_t *)val
);
846 case sizeof(uint64_t):
847 return OSSL_PARAM_get_uint64(p
, (uint64_t *)val
);
850 return general_get_uint(p
, val
, sizeof(*val
));
853 int OSSL_PARAM_set_size_t(OSSL_PARAM
*p
, size_t val
)
855 #ifndef OPENSSL_SMALL_FOOTPRINT
856 switch (sizeof(size_t)) {
857 case sizeof(uint32_t):
858 return OSSL_PARAM_set_uint32(p
, (uint32_t)val
);
859 case sizeof(uint64_t):
860 return OSSL_PARAM_set_uint64(p
, (uint64_t)val
);
863 return general_set_uint(p
, &val
, sizeof(val
));
866 OSSL_PARAM
OSSL_PARAM_construct_size_t(const char *key
, size_t *buf
)
868 return ossl_param_construct(key
, OSSL_PARAM_UNSIGNED_INTEGER
, buf
,
872 int OSSL_PARAM_get_time_t(const OSSL_PARAM
*p
, time_t *val
)
874 #ifndef OPENSSL_SMALL_FOOTPRINT
875 switch (sizeof(time_t)) {
876 case sizeof(int32_t):
877 return OSSL_PARAM_get_int32(p
, (int32_t *)val
);
878 case sizeof(int64_t):
879 return OSSL_PARAM_get_int64(p
, (int64_t *)val
);
882 return general_get_int(p
, val
, sizeof(*val
));
885 int OSSL_PARAM_set_time_t(OSSL_PARAM
*p
, time_t val
)
887 #ifndef OPENSSL_SMALL_FOOTPRINT
888 switch (sizeof(time_t)) {
889 case sizeof(int32_t):
890 return OSSL_PARAM_set_int32(p
, (int32_t)val
);
891 case sizeof(int64_t):
892 return OSSL_PARAM_set_int64(p
, (int64_t)val
);
895 return general_set_int(p
, &val
, sizeof(val
));
898 OSSL_PARAM
OSSL_PARAM_construct_time_t(const char *key
, time_t *buf
)
900 return ossl_param_construct(key
, OSSL_PARAM_INTEGER
, buf
, sizeof(time_t));
903 int OSSL_PARAM_get_BN(const OSSL_PARAM
*p
, BIGNUM
**val
)
909 || p
->data_type
!= OSSL_PARAM_UNSIGNED_INTEGER
)
912 b
= BN_native2bn(p
->data
, (int)p
->data_size
, *val
);
920 int OSSL_PARAM_set_BN(OSSL_PARAM
*p
, const BIGNUM
*val
)
927 if (val
== NULL
|| p
->data_type
!= OSSL_PARAM_UNSIGNED_INTEGER
)
930 /* For the moment, only positive values are permitted */
931 if (BN_is_negative(val
))
934 bytes
= (size_t)BN_num_bytes(val
);
935 p
->return_size
= bytes
;
938 if (p
->data_size
>= bytes
) {
939 p
->return_size
= p
->data_size
;
940 return BN_bn2nativepad(val
, p
->data
, p
->data_size
) >= 0;
945 OSSL_PARAM
OSSL_PARAM_construct_BN(const char *key
, unsigned char *buf
,
948 return ossl_param_construct(key
, OSSL_PARAM_UNSIGNED_INTEGER
,
952 int OSSL_PARAM_get_double(const OSSL_PARAM
*p
, double *val
)
957 if (val
== NULL
|| p
== NULL
)
960 if (p
->data_type
== OSSL_PARAM_REAL
) {
961 switch (p
->data_size
) {
963 *val
= *(const double *)p
->data
;
966 } else if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
) {
967 switch (p
->data_size
) {
968 case sizeof(uint32_t):
969 *val
= *(const uint32_t *)p
->data
;
971 case sizeof(uint64_t):
972 u64
= *(const uint64_t *)p
->data
;
973 if ((u64
>> real_shift()) == 0) {
979 } else if (p
->data_type
== OSSL_PARAM_INTEGER
) {
980 switch (p
->data_size
) {
981 case sizeof(int32_t):
982 *val
= *(const int32_t *)p
->data
;
984 case sizeof(int64_t):
985 i64
= *(const int64_t *)p
->data
;
986 u64
= i64
< 0 ? -i64
: i64
;
987 if ((u64
>> real_shift()) == 0) {
997 int OSSL_PARAM_set_double(OSSL_PARAM
*p
, double val
)
1003 if (p
->data_type
== OSSL_PARAM_REAL
) {
1004 p
->return_size
= sizeof(double);
1005 if (p
->data
== NULL
)
1007 switch (p
->data_size
) {
1008 case sizeof(double):
1009 *(double *)p
->data
= val
;
1012 } else if (p
->data_type
== OSSL_PARAM_UNSIGNED_INTEGER
1013 && val
== (uint64_t)val
) {
1014 p
->return_size
= sizeof(double);
1015 if (p
->data
== NULL
)
1017 switch (p
->data_size
) {
1018 case sizeof(uint32_t):
1019 if (val
>= 0 && val
<= UINT32_MAX
) {
1020 p
->return_size
= sizeof(uint32_t);
1021 *(uint32_t *)p
->data
= (uint32_t)val
;
1025 case sizeof(uint64_t):
1028 * By subtracting 65535 (2^16-1) we cancel the low order
1029 * 15 bits of UINT64_MAX to avoid using imprecise floating
1032 && val
< (double)(UINT64_MAX
- 65535) + 65536.0) {
1033 p
->return_size
= sizeof(uint64_t);
1034 *(uint64_t *)p
->data
= (uint64_t)val
;
1038 } else if (p
->data_type
== OSSL_PARAM_INTEGER
&& val
== (int64_t)val
) {
1039 p
->return_size
= sizeof(double);
1040 if (p
->data
== NULL
)
1042 switch (p
->data_size
) {
1043 case sizeof(int32_t):
1044 if (val
>= INT32_MIN
&& val
<= INT32_MAX
) {
1045 p
->return_size
= sizeof(int32_t);
1046 *(int32_t *)p
->data
= (int32_t)val
;
1050 case sizeof(int64_t):
1051 if (val
>= INT64_MIN
1053 * By subtracting 65535 (2^16-1) we cancel the low order
1054 * 15 bits of INT64_MAX to avoid using imprecise floating
1057 && val
< (double)(INT64_MAX
- 65535) + 65536.0) {
1058 p
->return_size
= sizeof(int64_t);
1059 *(int64_t *)p
->data
= (int64_t)val
;
1068 OSSL_PARAM
OSSL_PARAM_construct_double(const char *key
, double *buf
)
1070 return ossl_param_construct(key
, OSSL_PARAM_REAL
, buf
, sizeof(double));
1073 static int get_string_internal(const OSSL_PARAM
*p
, void **val
,
1074 size_t *max_len
, size_t *used_len
,
1077 size_t sz
, alloc_sz
;
1079 if ((val
== NULL
&& used_len
== NULL
) || p
== NULL
|| p
->data_type
!= type
)
1084 * If the input size is 0, or the input string needs NUL byte
1085 * termination, allocate an extra byte.
1087 alloc_sz
= sz
+ (type
== OSSL_PARAM_UTF8_STRING
|| sz
== 0);
1089 if (used_len
!= NULL
)
1092 if (p
->data
== NULL
)
1099 char *const q
= OPENSSL_malloc(alloc_sz
);
1104 *max_len
= alloc_sz
;
1109 memcpy(*val
, p
->data
, sz
);
1113 int OSSL_PARAM_get_utf8_string(const OSSL_PARAM
*p
, char **val
, size_t max_len
)
1115 int ret
= get_string_internal(p
, (void **)val
, &max_len
, NULL
,
1116 OSSL_PARAM_UTF8_STRING
);
1119 * We try to ensure that the copied string is terminated with a
1120 * NUL byte. That should be easy, just place a NUL byte at
1121 * |((char*)*val)[p->data_size]|.
1122 * Unfortunately, we have seen cases where |p->data_size| doesn't
1123 * correctly reflect the length of the string, and just happens
1124 * to be out of bounds according to |max_len|, so in that case, we
1125 * make the extra step of trying to find the true length of the
1126 * string that |p->data| points at, and use that as an index to
1127 * place the NUL byte in |*val|.
1129 size_t data_length
= p
->data_size
;
1133 if (data_length
>= max_len
)
1134 data_length
= OPENSSL_strnlen(p
->data
, data_length
);
1135 if (data_length
>= max_len
)
1136 return 0; /* No space for a terminating NUL byte */
1137 (*val
)[data_length
] = '\0';
1142 int OSSL_PARAM_get_octet_string(const OSSL_PARAM
*p
, void **val
, size_t max_len
,
1145 return get_string_internal(p
, val
, &max_len
, used_len
,
1146 OSSL_PARAM_OCTET_STRING
);
1149 static int set_string_internal(OSSL_PARAM
*p
, const void *val
, size_t len
,
1152 p
->return_size
= len
;
1153 if (p
->data
== NULL
)
1155 if (p
->data_type
!= type
|| p
->data_size
< len
)
1158 memcpy(p
->data
, val
, len
);
1159 /* If possible within the size of p->data, add a NUL terminator byte */
1160 if (type
== OSSL_PARAM_UTF8_STRING
&& p
->data_size
> len
)
1161 ((char *)p
->data
)[len
] = '\0';
1165 int OSSL_PARAM_set_utf8_string(OSSL_PARAM
*p
, const char *val
)
1173 return set_string_internal(p
, val
, strlen(val
), OSSL_PARAM_UTF8_STRING
);
1176 int OSSL_PARAM_set_octet_string(OSSL_PARAM
*p
, const void *val
,
1185 return set_string_internal(p
, val
, len
, OSSL_PARAM_OCTET_STRING
);
1188 OSSL_PARAM
OSSL_PARAM_construct_utf8_string(const char *key
, char *buf
,
1191 if (buf
!= NULL
&& bsize
== 0)
1192 bsize
= strlen(buf
);
1193 return ossl_param_construct(key
, OSSL_PARAM_UTF8_STRING
, buf
, bsize
);
1196 OSSL_PARAM
OSSL_PARAM_construct_octet_string(const char *key
, void *buf
,
1199 return ossl_param_construct(key
, OSSL_PARAM_OCTET_STRING
, buf
, bsize
);
1202 static int get_ptr_internal(const OSSL_PARAM
*p
, const void **val
,
1203 size_t *used_len
, unsigned int type
)
1205 if (val
== NULL
|| p
== NULL
|| p
->data_type
!= type
)
1207 if (used_len
!= NULL
)
1208 *used_len
= p
->data_size
;
1209 *val
= *(const void **)p
->data
;
1213 int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM
*p
, const char **val
)
1215 return get_ptr_internal(p
, (const void **)val
, NULL
, OSSL_PARAM_UTF8_PTR
);
1218 int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM
*p
, const void **val
,
1221 return get_ptr_internal(p
, val
, used_len
, OSSL_PARAM_OCTET_PTR
);
1224 static int set_ptr_internal(OSSL_PARAM
*p
, const void *val
,
1225 unsigned int type
, size_t len
)
1227 p
->return_size
= len
;
1228 if (p
->data_type
!= type
)
1230 if (p
->data
!= NULL
)
1231 *(const void **)p
->data
= val
;
1235 int OSSL_PARAM_set_utf8_ptr(OSSL_PARAM
*p
, const char *val
)
1240 return set_ptr_internal(p
, val
, OSSL_PARAM_UTF8_PTR
,
1241 val
== NULL
? 0 : strlen(val
));
1244 int OSSL_PARAM_set_octet_ptr(OSSL_PARAM
*p
, const void *val
,
1250 return set_ptr_internal(p
, val
, OSSL_PARAM_OCTET_PTR
, used_len
);
1253 OSSL_PARAM
OSSL_PARAM_construct_utf8_ptr(const char *key
, char **buf
,
1256 return ossl_param_construct(key
, OSSL_PARAM_UTF8_PTR
, buf
, bsize
);
1259 OSSL_PARAM
OSSL_PARAM_construct_octet_ptr(const char *key
, void **buf
,
1262 return ossl_param_construct(key
, OSSL_PARAM_OCTET_PTR
, buf
, bsize
);
1265 OSSL_PARAM
OSSL_PARAM_construct_end(void)
1267 OSSL_PARAM end
= OSSL_PARAM_END
;
1272 static int get_string_ptr_internal(const OSSL_PARAM
*p
, const void **val
,
1273 size_t *used_len
, unsigned int type
)
1275 if (val
== NULL
|| p
== NULL
|| p
->data_type
!= type
)
1277 if (used_len
!= NULL
)
1278 *used_len
= p
->data_size
;
1283 int OSSL_PARAM_get_utf8_string_ptr(const OSSL_PARAM
*p
, const char **val
)
1285 return OSSL_PARAM_get_utf8_ptr(p
, val
)
1286 || get_string_ptr_internal(p
, (const void **)val
, NULL
,
1287 OSSL_PARAM_UTF8_STRING
);
1290 int OSSL_PARAM_get_octet_string_ptr(const OSSL_PARAM
*p
, const void **val
,
1293 return OSSL_PARAM_get_octet_ptr(p
, val
, used_len
)
1294 || get_string_ptr_internal(p
, val
, used_len
, OSSL_PARAM_OCTET_STRING
);