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