Constify OSSL_PROVIDER getter input parameters
[openssl.git] / crypto / params.c
1 /*
2  * Copyright 2019 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 <openssl/params.h>
13 #include "internal/thread_once.h"
14
15 #define SET_RETURN_SIZE(p, sz) \
16     if ((p)->return_size != NULL) \
17         *(p)->return_size = (sz)
18
19 const OSSL_PARAM *OSSL_PARAM_locate(const OSSL_PARAM *p, const char *key)
20 {
21     if (p != NULL && key != NULL)
22         for (; p->key != NULL; p++)
23             if (strcmp(key, p->key) == 0)
24                 return p;
25     return NULL;
26 }
27
28 static OSSL_PARAM ossl_param_construct(const char *key, unsigned int data_type,
29                                        void *data, size_t data_size,
30                                        size_t *return_size)
31 {
32     OSSL_PARAM res;
33
34     res.key = key;
35     res.data_type = data_type;
36     res.data = data;
37     res.data_size = data_size;
38     res.return_size = return_size;
39     return res;
40 }
41
42 int OSSL_PARAM_get_int(const OSSL_PARAM *p, int *val)
43 {
44     switch (sizeof(int)) {
45     case sizeof(int32_t):
46         return OSSL_PARAM_get_int32(p, (int32_t *)val);
47     case sizeof(int64_t):
48         return OSSL_PARAM_get_int64(p, (int64_t *)val);
49     }
50     return 0;
51 }
52
53 int OSSL_PARAM_set_int(const OSSL_PARAM *p, int val)
54 {
55     switch (sizeof(int)) {
56     case sizeof(int32_t):
57         return OSSL_PARAM_set_int32(p, (int32_t)val);
58     case sizeof(int64_t):
59         return OSSL_PARAM_set_int64(p, (int64_t)val);
60     }
61     return 0;
62 }
63
64 OSSL_PARAM OSSL_PARAM_construct_int(const char *key, int *buf, size_t *rsize)
65 {
66     return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int),
67                                 rsize);
68 }
69
70 int OSSL_PARAM_get_uint(const OSSL_PARAM *p, unsigned int *val)
71 {
72     switch (sizeof(unsigned int)) {
73     case sizeof(uint32_t):
74         return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
75     case sizeof(uint64_t):
76         return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
77     }
78     return 0;
79 }
80
81 int OSSL_PARAM_set_uint(const OSSL_PARAM *p, unsigned int val)
82 {
83     switch (sizeof(unsigned int)) {
84     case sizeof(uint32_t):
85         return OSSL_PARAM_set_uint32(p, (uint32_t)val);
86     case sizeof(uint64_t):
87         return OSSL_PARAM_set_uint64(p, (uint64_t)val);
88     }
89     return 0;
90 }
91
92 OSSL_PARAM OSSL_PARAM_construct_uint(const char *key, unsigned int *buf,
93                                      size_t *rsize)
94 {
95     return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
96                                 sizeof(unsigned int), rsize);
97 }
98
99 int OSSL_PARAM_get_long(const OSSL_PARAM *p, long int *val)
100 {
101     switch (sizeof(long int)) {
102     case sizeof(int32_t):
103         return OSSL_PARAM_get_int32(p, (int32_t *)val);
104     case sizeof(int64_t):
105         return OSSL_PARAM_get_int64(p, (int64_t *)val);
106     }
107     return 0;
108 }
109
110 int OSSL_PARAM_set_long(const OSSL_PARAM *p, long int val)
111 {
112     switch (sizeof(long int)) {
113     case sizeof(int32_t):
114         return OSSL_PARAM_set_int32(p, (int32_t)val);
115     case sizeof(int64_t):
116         return OSSL_PARAM_set_int64(p, (int64_t)val);
117     }
118     return 0;
119 }
120
121 OSSL_PARAM OSSL_PARAM_construct_long(const char *key, long int *buf,
122                                      size_t *rsize)
123 {
124     return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(long int),
125                                 rsize);
126 }
127
128 int OSSL_PARAM_get_ulong(const OSSL_PARAM *p, unsigned long int *val)
129 {
130     switch (sizeof(unsigned long int)) {
131     case sizeof(uint32_t):
132         return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
133     case sizeof(uint64_t):
134         return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
135     }
136     return 0;
137 }
138
139 int OSSL_PARAM_set_ulong(const OSSL_PARAM *p, unsigned long int val)
140 {
141     switch (sizeof(unsigned long int)) {
142     case sizeof(uint32_t):
143         return OSSL_PARAM_set_uint32(p, (uint32_t)val);
144     case sizeof(uint64_t):
145         return OSSL_PARAM_set_uint64(p, (uint64_t)val);
146     }
147     return 0;
148 }
149
150 OSSL_PARAM OSSL_PARAM_construct_ulong(const char *key, unsigned long int *buf,
151                                       size_t *rsize)
152 {
153     return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
154                                 sizeof(unsigned long int), rsize);
155 }
156
157 int OSSL_PARAM_get_int32(const OSSL_PARAM *p, int32_t *val)
158 {
159     int64_t i64;
160     uint32_t u32;
161     uint64_t u64;
162     double d;
163
164     if (val == NULL || p == NULL )
165         return 0;
166
167     if (p->data_type == OSSL_PARAM_INTEGER) {
168         switch (p->data_size) {
169         case sizeof(int32_t):
170             *val = *(const int32_t *)p->data;
171             return 1;
172         case sizeof(int64_t):
173             i64 = *(const int64_t *)p->data;
174             if (i64 >= INT32_MIN && i64 <= INT32_MAX) {
175                 *val = (int32_t)i64;
176                 return 1;
177             }
178             break;
179         }
180     } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
181         switch (p->data_size) {
182         case sizeof(uint32_t):
183             u32 = *(const uint32_t *)p->data;
184             if (u32 <= INT32_MAX) {
185                 *val = (int32_t)u32;
186                 return 1;
187             }
188             break;
189         case sizeof(uint64_t):
190             u64 = *(const uint64_t *)p->data;
191             if (u64 <= INT32_MAX) {
192                 *val = (int32_t)u64;
193                 return 1;
194             }
195             break;
196         }
197     } else if (p->data_type == OSSL_PARAM_REAL) {
198         switch (p->data_size) {
199         case sizeof(double):
200             d = *(const double *)p->data;
201             if (d >= INT32_MIN && d <= INT32_MAX && d == (int32_t)d) {
202                 *val = (int32_t)d;
203                 return 1;
204             }
205             break;
206         }
207     }
208     return 0;
209 }
210
211 int OSSL_PARAM_set_int32(const OSSL_PARAM *p, int32_t val)
212 {
213     if (p == NULL)
214         return 0;
215     SET_RETURN_SIZE(p, 0);
216     if (p->data_type == OSSL_PARAM_INTEGER) {
217         SET_RETURN_SIZE(p, sizeof(int32_t)); /* Minimum expected size */
218         switch (p->data_size) {
219         case sizeof(int32_t):
220             *(int32_t *)p->data = val;
221             return 1;
222         case sizeof(int64_t):
223             SET_RETURN_SIZE(p, sizeof(int64_t));
224             *(int64_t *)p->data = (int64_t)val;
225             return 1;
226         }
227     } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) {
228         SET_RETURN_SIZE(p, sizeof(uint32_t)); /* Minimum expected size */
229         switch (p->data_size) {
230         case sizeof(uint32_t):
231             *(uint32_t *)p->data = (uint32_t)val;
232             return 1;
233         case sizeof(uint64_t):
234             SET_RETURN_SIZE(p, sizeof(uint64_t));
235             *(uint64_t *)p->data = (uint64_t)val;
236             return 1;
237         }
238     } else if (p->data_type == OSSL_PARAM_REAL) {
239         SET_RETURN_SIZE(p, sizeof(double));
240         switch (p->data_size) {
241         case sizeof(double):
242             *(double *)p->data = (double)val;
243             return 1;
244         }
245     }
246     return 0;
247 }
248
249 OSSL_PARAM OSSL_PARAM_construct_int32(const char *key, int32_t *buf,
250                                       size_t *rsize)
251 {
252     return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf,
253                                 sizeof(int32_t), rsize);
254 }
255
256 int OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val)
257 {
258     int32_t i32;
259     int64_t i64;
260     uint64_t u64;
261     double d;
262
263     if (val == NULL || p == NULL)
264         return 0;
265
266     if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
267         switch (p->data_size) {
268         case sizeof(uint32_t):
269             *val = *(const uint32_t *)p->data;
270             return 1;
271         case sizeof(uint64_t):
272             u64 = *(const uint64_t *)p->data;
273             if (u64 <= UINT32_MAX) {
274                 *val = (uint32_t)u64;
275                 return 1;
276             }
277             break;
278         }
279     } else if (p->data_type == OSSL_PARAM_INTEGER) {
280         switch (p->data_size) {
281         case sizeof(int32_t):
282             i32 = *(const int32_t *)p->data;
283             if (i32 >= 0) {
284                 *val = i32;
285                 return 1;
286             }
287             break;
288         case sizeof(int64_t):
289             i64 = *(const int64_t *)p->data;
290             if (i64 >= 0 && i64 <= UINT32_MAX) {
291                 *val = (uint32_t)i64;
292                 return 1;
293             }
294             break;
295         }
296     } else if (p->data_type == OSSL_PARAM_REAL) {
297         switch (p->data_size) {
298         case sizeof(double):
299             d = *(const double *)p->data;
300             if (d >= 0 && d <= UINT32_MAX && d == (uint32_t)d) {
301                 *val = (uint32_t)d;
302                 return 1;
303             }
304             break;
305         }
306     }
307     return 0;
308 }
309
310 int OSSL_PARAM_set_uint32(const OSSL_PARAM *p, uint32_t val)
311 {
312     if (p == NULL)
313         return 0;
314     SET_RETURN_SIZE(p, 0);
315
316     if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
317         SET_RETURN_SIZE(p, sizeof(uint32_t)); /* Minimum expected size */
318         switch (p->data_size) {
319         case sizeof(uint32_t):
320             *(uint32_t *)p->data = val;
321             return 1;
322         case sizeof(uint64_t):
323             SET_RETURN_SIZE(p, sizeof(uint64_t));
324             *(uint64_t *)p->data = val;
325             return 1;
326         }
327     } else if (p->data_type == OSSL_PARAM_INTEGER) {
328         SET_RETURN_SIZE(p, sizeof(int32_t)); /* Minimum expected size */
329         switch (p->data_size) {
330         case sizeof(int32_t):
331             if (val <= INT32_MAX) {
332                 *(int32_t *)p->data = (int32_t)val;
333                 return 1;
334             }
335             break;
336         case sizeof(int64_t):
337             SET_RETURN_SIZE(p, sizeof(int64_t));
338             *(int64_t *)p->data = (int64_t)val;
339             return 1;
340         }
341     } else if (p->data_type == OSSL_PARAM_REAL) {
342         SET_RETURN_SIZE(p, sizeof(double));
343         switch (p->data_size) {
344         case sizeof(double):
345             *(double *)p->data = (double)val;
346             return 1;
347         }
348     }
349     return 0;
350 }
351
352 OSSL_PARAM OSSL_PARAM_construct_uint32(const char *key, uint32_t *buf,
353                                        size_t *rsize)
354 {
355     return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
356                                 sizeof(uint32_t), rsize);
357 }
358
359 int OSSL_PARAM_get_int64(const OSSL_PARAM *p, int64_t *val)
360 {
361     uint64_t u64;
362     double d;
363
364     if (val == NULL || p == NULL )
365         return 0;
366
367     if (p->data_type == OSSL_PARAM_INTEGER) {
368         switch (p->data_size) {
369         case sizeof(int32_t):
370             *val = *(const int32_t *)p->data;
371             return 1;
372         case sizeof(int64_t):
373             *val = *(const int64_t *)p->data;
374             return 1;
375         }
376     } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
377         switch (p->data_size) {
378         case sizeof(uint32_t):
379             *val = *(const uint32_t *)p->data;
380             return 1;
381         case sizeof(uint64_t):
382             u64 = *(const uint64_t *)p->data;
383             if (u64 <= INT64_MAX) {
384                 *val = (int64_t)u64;
385                 return 1;
386             }
387             break;
388         }
389     } else if (p->data_type == OSSL_PARAM_REAL) {
390         switch (p->data_size) {
391         case sizeof(double):
392             d = *(const double *)p->data;
393             if (d >= INT64_MIN && d <= INT64_MAX && d == (int64_t)d) {
394                 *val = (int64_t)d;
395                 return 1;
396             }
397             break;
398         }
399     }
400     return 0;
401 }
402
403 int OSSL_PARAM_set_int64(const OSSL_PARAM *p, int64_t val)
404 {
405     uint64_t u64;
406
407     if (p == NULL)
408         return 0;
409     SET_RETURN_SIZE(p, 0);
410     if (p->data_type == OSSL_PARAM_INTEGER) {
411         SET_RETURN_SIZE(p, sizeof(int64_t)); /* Expected size */
412         switch (p->data_size) {
413         case sizeof(int32_t):
414             if (val >= INT32_MIN && val <= INT32_MAX) {
415                 SET_RETURN_SIZE(p, sizeof(int32_t));
416                 *(int32_t *)p->data = (int32_t)val;
417                 return 1;
418             }
419             break;
420         case sizeof(int64_t):
421             *(int64_t *)p->data = val;
422             return 1;
423         }
424     } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) {
425         SET_RETURN_SIZE(p, sizeof(uint64_t)); /* Expected size */
426         switch (p->data_size) {
427         case sizeof(uint32_t):
428             if (val <= UINT32_MAX) {
429                 SET_RETURN_SIZE(p, sizeof(uint32_t));
430                 *(uint32_t *)p->data = (uint32_t)val;
431                 return 1;
432             }
433             break;
434         case sizeof(uint64_t):
435             *(uint64_t *)p->data = (uint64_t)val;
436             return 1;
437         }
438     } else if (p->data_type == OSSL_PARAM_REAL) {
439         SET_RETURN_SIZE(p, sizeof(double));
440         switch (p->data_size) {
441         case sizeof(double):
442             u64 = val < 0 ? -val : val;
443             if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
444                 *(double *)p->data = (double)val;
445                 return 1;
446             }
447             break;
448         }
449     }
450     return 0;
451 }
452
453 OSSL_PARAM OSSL_PARAM_construct_int64(const char *key, int64_t *buf,
454                                       size_t *rsize)
455 {
456     return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int64_t),
457                                 rsize);
458 }
459
460 int OSSL_PARAM_get_uint64(const OSSL_PARAM *p, uint64_t *val)
461 {
462     int32_t i32;
463     int64_t i64;
464     double d;
465
466     if (val == NULL || p == NULL)
467         return 0;
468
469     if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
470         switch (p->data_size) {
471         case sizeof(uint32_t):
472             *val = *(const uint32_t *)p->data;
473             return 1;
474         case sizeof(uint64_t):
475             *val = *(const uint64_t *)p->data;
476             return 1;
477         }
478     } else if (p->data_type == OSSL_PARAM_INTEGER) {
479         switch (p->data_size) {
480         case sizeof(int32_t):
481             i32 = *(const int32_t *)p->data;
482             if (i32 >= 0) {
483                 *val = (uint64_t)i32;
484                 return 1;
485             }
486             break;
487         case sizeof(int64_t):
488             i64 = *(const int64_t *)p->data;
489             if (i64 >= 0) {
490                 *val = (uint64_t)i64;
491                 return 1;
492             }
493             break;
494         }
495     } else if (p->data_type == OSSL_PARAM_REAL) {
496         switch (p->data_size) {
497         case sizeof(double):
498             d = *(const double *)p->data;
499             if (d >= 0 && d <= INT64_MAX && d == (uint64_t)d) {
500                 *val = (uint64_t)d;
501                 return 1;
502             }
503             break;
504         }
505     }
506     return 0;
507 }
508
509 int OSSL_PARAM_set_uint64(const OSSL_PARAM *p, uint64_t val)
510 {
511     if (p == NULL)
512         return 0;
513     SET_RETURN_SIZE(p, 0);
514
515     if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
516         SET_RETURN_SIZE(p, sizeof(uint64_t)); /* Expected size */
517         switch (p->data_size) {
518         case sizeof(uint32_t):
519             if (val <= UINT32_MAX) {
520                 SET_RETURN_SIZE(p, sizeof(uint32_t));
521                 *(uint32_t *)p->data = (uint32_t)val;
522                 return 1;
523             }
524             break;
525         case sizeof(uint64_t):
526             *(uint64_t *)p->data = val;
527             return 1;
528         }
529     } else if (p->data_type == OSSL_PARAM_INTEGER) {
530         SET_RETURN_SIZE(p, sizeof(int64_t)); /* Expected size */
531         switch (p->data_size) {
532         case sizeof(int32_t):
533             if (val <= INT32_MAX) {
534                 SET_RETURN_SIZE(p, sizeof(int32_t));
535                 *(int32_t *)p->data = (int32_t)val;
536                 return 1;
537             }
538             break;
539         case sizeof(int64_t):
540             if (val <= INT64_MAX) {
541                 *(int64_t *)p->data = (int64_t)val;
542                 return 1;
543             }
544             break;
545         }
546     } else if (p->data_type == OSSL_PARAM_REAL) {
547         SET_RETURN_SIZE(p, sizeof(double));
548         switch (p->data_size) {
549         case sizeof(double):
550             if ((val >> 53) == 0) { /* 53 significant bits in the mantissa */
551                 *(double *)p->data = (double)val;
552                 return 1;
553             }
554             break;
555         }
556     }
557     return 0;
558 }
559
560 OSSL_PARAM OSSL_PARAM_construct_uint64(const char *key, uint64_t *buf,
561                                        size_t *rsize) {
562     return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
563                                 sizeof(uint64_t), rsize);
564 }
565
566 int OSSL_PARAM_get_size_t(const OSSL_PARAM *p, size_t *val)
567 {
568     switch (sizeof(size_t)) {
569     case sizeof(uint32_t):
570         return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
571     case sizeof(uint64_t):
572         return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
573     }
574     return 0;
575 }
576
577 int OSSL_PARAM_set_size_t(const OSSL_PARAM *p, size_t val)
578 {
579     switch (sizeof(size_t)) {
580     case sizeof(uint32_t):
581         return OSSL_PARAM_set_uint32(p, (uint32_t)val);
582     case sizeof(uint64_t):
583         return OSSL_PARAM_set_uint64(p, (uint64_t)val);
584     }
585     return 0;
586 }
587
588 OSSL_PARAM OSSL_PARAM_construct_size_t(const char *key, size_t *buf,
589                                        size_t *rsize)
590 {
591     return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
592                                 sizeof(size_t), rsize); }
593
594 #ifndef FIPS_MODE
595 /*
596  * TODO(3.0): Make this available in FIPS mode.
597  *
598  * Temporarily we don't include these functions in FIPS mode to avoid pulling
599  * in the entire BN sub-library into the module at this point.
600  */
601 int OSSL_PARAM_get_BN(const OSSL_PARAM *p, BIGNUM **val)
602 {
603     BIGNUM *b;
604
605     if (val == NULL
606         || p == NULL
607         || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
608         return 0;
609
610     b = BN_native2bn(p->data, (int)p->data_size, *val);
611     if (b != NULL) {
612         *val = b;
613         return 1;
614     }
615     return 0;
616 }
617
618 int OSSL_PARAM_set_BN(const OSSL_PARAM *p, const BIGNUM *val)
619 {
620     size_t bytes;
621
622     if (p == NULL)
623         return 0;
624     SET_RETURN_SIZE(p, 0);
625     if (val == NULL || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
626         return 0;
627
628     /* For the moment, only positive values are permitted */
629     if (BN_is_negative(val))
630         return 0;
631
632     bytes = (size_t)BN_num_bytes(val);
633     SET_RETURN_SIZE(p, bytes);
634     return p->data_size >= bytes
635         && BN_bn2nativepad(val, p->data, bytes) >= 0;
636 }
637
638 OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf,
639                                    size_t bsize, size_t *rsize)
640 {
641     return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER,
642                                 buf, bsize, rsize);
643 }
644 #endif
645
646 int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val)
647 {
648     int64_t i64;
649     uint64_t u64;
650
651     if (val == NULL || p == NULL)
652         return 0;
653
654     if (p->data_type == OSSL_PARAM_REAL) {
655         switch (p->data_size) {
656         case sizeof(double):
657             *val = *(const double *)p->data;
658             return 1;
659         }
660     } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
661         switch (p->data_size) {
662         case sizeof(uint32_t):
663             *val = *(const uint32_t *)p->data;
664             return 1;
665         case sizeof(uint64_t):
666             u64 = *(const uint64_t *)p->data;
667             if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
668                 *val = (double)u64;
669                 return 1;
670             }
671             break;
672         }
673     } else if (p->data_type == OSSL_PARAM_INTEGER) {
674         switch (p->data_size) {
675         case sizeof(int32_t):
676             *val = *(const int32_t *)p->data;
677             return 1;
678         case sizeof(int64_t):
679             i64 = *(const int64_t *)p->data;
680             u64 = i64 < 0 ? -i64 : i64;
681             if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
682                 *val = 0.0 + i64;
683                 return 1;
684             }
685             break;
686         }
687     }
688     return 0;
689 }
690
691 int OSSL_PARAM_set_double(const OSSL_PARAM *p, double val)
692 {
693     if (p == NULL)
694         return 0;
695     SET_RETURN_SIZE(p, 0);
696
697     if (p->data_type == OSSL_PARAM_REAL) {
698         SET_RETURN_SIZE(p, sizeof(double));
699         switch (p->data_size) {
700         case sizeof(double):
701             *(double *)p->data = val;
702             return 1;
703         }
704     } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER
705                && val == (uintmax_t)val) {
706         SET_RETURN_SIZE(p, sizeof(double));
707         switch (p->data_size) {
708         case sizeof(uint32_t):
709             if (val >= 0 && val <= UINT32_MAX) {
710                 SET_RETURN_SIZE(p, sizeof(uint32_t));
711                 *(uint32_t *)p->data = (uint32_t)val;
712                 return 1;
713             }
714             break;
715         case sizeof(uint64_t):
716             if (val >= 0 && val <= UINT64_MAX) {
717                 SET_RETURN_SIZE(p, sizeof(uint64_t));
718                 *(uint64_t *)p->data = (uint64_t)val;
719                 return 1;
720             }
721             break;            }
722     } else if (p->data_type == OSSL_PARAM_INTEGER && val == (intmax_t)val) {
723         SET_RETURN_SIZE(p, sizeof(double));
724         switch (p->data_size) {
725         case sizeof(int32_t):
726             if (val >= INT32_MIN && val <= INT32_MAX) {
727                 SET_RETURN_SIZE(p, sizeof(int32_t));
728                 *(int32_t *)p->data = (int32_t)val;
729                 return 1;
730             }
731             break;
732         case sizeof(int64_t):
733             if (val >= INT64_MIN && val <= INT64_MAX) {
734                 SET_RETURN_SIZE(p, sizeof(int64_t));
735                 *(int64_t *)p->data = (int64_t)val;
736                 return 1;
737             }
738             break;
739         }
740     }
741     return 0;
742 }
743
744 OSSL_PARAM OSSL_PARAM_construct_double(const char *key, double *buf,
745                                        size_t *rsize)
746 {
747     return ossl_param_construct(key, OSSL_PARAM_REAL, buf, sizeof(double),
748                                 rsize);
749 }
750
751 static int get_string_internal(const OSSL_PARAM *p, void **val, size_t max_len,
752                                size_t *used_len, unsigned int type)
753 {
754     size_t sz;
755
756     if (val == NULL || p == NULL || p->data_type != type)
757         return 0;
758
759     sz = p->data_size;
760
761     if (used_len != NULL)
762         *used_len = sz;
763
764     if (*val == NULL) {
765         char *const q = OPENSSL_malloc(sz);
766
767         if (q == NULL)
768             return 0;
769         *val = q;
770         memcpy(q, p->data, sz);
771         return 1;
772     }
773     if (max_len < sz)
774         return 0;
775     memcpy(*val, p->data, sz);
776     return 1;
777 }
778
779 int OSSL_PARAM_get_utf8_string(const OSSL_PARAM *p, char **val, size_t max_len)
780 {
781     return get_string_internal(p, (void **)val, max_len, NULL,
782                                OSSL_PARAM_UTF8_STRING);
783 }
784
785 int OSSL_PARAM_get_octet_string(const OSSL_PARAM *p, void **val, size_t max_len,
786                                 size_t *used_len)
787 {
788     return get_string_internal(p, val, max_len, used_len,
789                                OSSL_PARAM_OCTET_STRING);
790 }
791
792 static int set_string_internal(const OSSL_PARAM *p, const void *val, size_t len,
793                                unsigned int type)
794 {
795     SET_RETURN_SIZE(p, len);
796     if (p->data_type != type || p->data_size < len)
797         return 0;
798
799     memcpy(p->data, val, len);
800     return 1;
801 }
802
803 int OSSL_PARAM_set_utf8_string(const OSSL_PARAM *p, const char *val)
804 {
805     if (p == NULL)
806         return 0;
807
808     SET_RETURN_SIZE(p, 0);
809     if (val == NULL)
810         return 0;
811     return set_string_internal(p, val, strlen(val) + 1, OSSL_PARAM_UTF8_STRING);
812 }
813
814 int OSSL_PARAM_set_octet_string(const OSSL_PARAM *p, const void *val,
815                                 size_t len)
816 {
817     if (p == NULL)
818         return 0;
819
820     SET_RETURN_SIZE(p, 0);
821     if (val == NULL)
822         return 0;
823     return set_string_internal(p, val, len, OSSL_PARAM_OCTET_STRING);
824 }
825
826 OSSL_PARAM OSSL_PARAM_construct_utf8_string(const char *key, char *buf,
827                                             size_t bsize, size_t *rsize)
828 {
829     return ossl_param_construct(key, OSSL_PARAM_UTF8_STRING, buf, bsize,
830                                 rsize);
831 }
832
833 OSSL_PARAM OSSL_PARAM_construct_octet_string(const char *key, void *buf,
834                                              size_t bsize, size_t *rsize)
835 {
836     return ossl_param_construct(key, OSSL_PARAM_OCTET_STRING, buf, bsize,
837                                 rsize);
838 }
839
840 static int get_ptr_internal(const OSSL_PARAM *p, const void **val,
841                             size_t *used_len, unsigned int type)
842 {
843     if (val == NULL || p == NULL || p->data_type != type)
844         return 0;
845     if (used_len != NULL)
846         *used_len = p->data_size;
847     *val = *(const void **)p->data;
848     return 1;
849 }
850
851 int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM *p, const char **val)
852 {
853     return get_ptr_internal(p, (const void **)val, NULL, OSSL_PARAM_UTF8_PTR);
854 }
855
856 int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, const void **val,
857                              size_t *used_len)
858 {
859     return get_ptr_internal(p, val, used_len, OSSL_PARAM_OCTET_PTR);
860 }
861
862 static int set_ptr_internal(const OSSL_PARAM *p, const void *val,
863                             unsigned int type, size_t len)
864 {
865     SET_RETURN_SIZE(p, len);
866     if (p->data_type != type)
867         return 0;
868     *(const void **)p->data = val;
869     return 1;
870 }
871
872 int OSSL_PARAM_set_utf8_ptr(const OSSL_PARAM *p, const char *val)
873 {
874     if (p == NULL)
875         return 0;
876     SET_RETURN_SIZE(p, 0);
877     if (val == NULL)
878         return 0;
879     return set_ptr_internal(p, val, OSSL_PARAM_UTF8_PTR, strlen(val) + 1);
880 }
881
882 int OSSL_PARAM_set_octet_ptr(const OSSL_PARAM *p, const void *val,
883                              size_t used_len)
884 {
885     if (p == NULL)
886         return 0;
887     SET_RETURN_SIZE(p, 0);
888     if (val == NULL)
889         return 0;
890     return set_ptr_internal(p, val, OSSL_PARAM_OCTET_PTR, used_len);
891 }
892
893 OSSL_PARAM OSSL_PARAM_construct_utf8_ptr(const char *key, char **buf,
894                                          size_t bsize, size_t *rsize)
895 {
896     return ossl_param_construct(key, OSSL_PARAM_UTF8_PTR, buf, bsize, rsize);
897 }
898
899 OSSL_PARAM OSSL_PARAM_construct_octet_ptr(const char *key, void **buf,
900                                           size_t bsize, size_t *rsize)
901 {
902     return ossl_param_construct(key, OSSL_PARAM_OCTET_PTR, buf, bsize, rsize);
903 }
904
905 OSSL_PARAM OSSL_PARAM_construct_end(void)
906 {
907     OSSL_PARAM end = OSSL_PARAM_END;
908
909     return end;
910 }