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