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