sha512.c: Grammar Fixes and Spell Checks in Implementation Notes
[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 int OSSL_PARAM_get_BN(const OSSL_PARAM *p, BIGNUM **val)
586 {
587     BIGNUM *b;
588
589     if (val == NULL
590         || p == NULL
591         || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
592         return 0;
593
594     b = BN_native2bn(p->data, (int)p->data_size, *val);
595     if (b != NULL) {
596         *val = b;
597         return 1;
598     }
599     return 0;
600 }
601
602 int OSSL_PARAM_set_BN(OSSL_PARAM *p, const BIGNUM *val)
603 {
604     size_t bytes;
605
606     if (p == NULL)
607         return 0;
608     p->return_size = 0;
609     if (val == NULL || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
610         return 0;
611
612     /* For the moment, only positive values are permitted */
613     if (BN_is_negative(val))
614         return 0;
615
616     bytes = (size_t)BN_num_bytes(val);
617     p->return_size = bytes;
618     return p->data_size >= bytes
619         && BN_bn2nativepad(val, p->data, bytes) >= 0;
620 }
621
622 OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf,
623                                    size_t bsize)
624 {
625     return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER,
626                                 buf, bsize);
627 }
628
629 int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val)
630 {
631     int64_t i64;
632     uint64_t u64;
633
634     if (val == NULL || p == NULL)
635         return 0;
636
637     if (p->data_type == OSSL_PARAM_REAL) {
638         switch (p->data_size) {
639         case sizeof(double):
640             *val = *(const double *)p->data;
641             return 1;
642         }
643     } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
644         switch (p->data_size) {
645         case sizeof(uint32_t):
646             *val = *(const uint32_t *)p->data;
647             return 1;
648         case sizeof(uint64_t):
649             u64 = *(const uint64_t *)p->data;
650             if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
651                 *val = (double)u64;
652                 return 1;
653             }
654             break;
655         }
656     } else if (p->data_type == OSSL_PARAM_INTEGER) {
657         switch (p->data_size) {
658         case sizeof(int32_t):
659             *val = *(const int32_t *)p->data;
660             return 1;
661         case sizeof(int64_t):
662             i64 = *(const int64_t *)p->data;
663             u64 = i64 < 0 ? -i64 : i64;
664             if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
665                 *val = 0.0 + i64;
666                 return 1;
667             }
668             break;
669         }
670     }
671     return 0;
672 }
673
674 int OSSL_PARAM_set_double(OSSL_PARAM *p, double val)
675 {
676     if (p == NULL)
677         return 0;
678     p->return_size = 0;
679
680     if (p->data_type == OSSL_PARAM_REAL) {
681         p->return_size = sizeof(double);
682         switch (p->data_size) {
683         case sizeof(double):
684             *(double *)p->data = val;
685             return 1;
686         }
687     } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER
688                && val == (uintmax_t)val) {
689         p->return_size = sizeof(double);
690         switch (p->data_size) {
691         case sizeof(uint32_t):
692             if (val >= 0 && val <= UINT32_MAX) {
693                 p->return_size = sizeof(uint32_t);
694                 *(uint32_t *)p->data = (uint32_t)val;
695                 return 1;
696             }
697             break;
698         case sizeof(uint64_t):
699             if (val >= 0 && val <= UINT64_MAX) {
700                 p->return_size = sizeof(uint64_t);
701                 *(uint64_t *)p->data = (uint64_t)val;
702                 return 1;
703             }
704             break;            }
705     } else if (p->data_type == OSSL_PARAM_INTEGER && val == (intmax_t)val) {
706         p->return_size = sizeof(double);
707         switch (p->data_size) {
708         case sizeof(int32_t):
709             if (val >= INT32_MIN && val <= INT32_MAX) {
710                 p->return_size = sizeof(int32_t);
711                 *(int32_t *)p->data = (int32_t)val;
712                 return 1;
713             }
714             break;
715         case sizeof(int64_t):
716             if (val >= INT64_MIN && val <= INT64_MAX) {
717                 p->return_size = sizeof(int64_t);
718                 *(int64_t *)p->data = (int64_t)val;
719                 return 1;
720             }
721             break;
722         }
723     }
724     return 0;
725 }
726
727 OSSL_PARAM OSSL_PARAM_construct_double(const char *key, double *buf)
728 {
729     return ossl_param_construct(key, OSSL_PARAM_REAL, buf, sizeof(double));
730 }
731
732 static int get_string_internal(const OSSL_PARAM *p, void **val, size_t max_len,
733                                size_t *used_len, unsigned int type)
734 {
735     size_t sz;
736
737     if (val == NULL || p == NULL || p->data_type != type)
738         return 0;
739
740     sz = p->data_size;
741
742     if (used_len != NULL)
743         *used_len = sz;
744
745     if (*val == NULL) {
746         char *const q = OPENSSL_malloc(sz);
747
748         if (q == NULL)
749             return 0;
750         *val = q;
751         memcpy(q, p->data, sz);
752         return 1;
753     }
754     if (max_len < sz)
755         return 0;
756     memcpy(*val, p->data, sz);
757     return 1;
758 }
759
760 int OSSL_PARAM_get_utf8_string(const OSSL_PARAM *p, char **val, size_t max_len)
761 {
762     return get_string_internal(p, (void **)val, max_len, NULL,
763                                OSSL_PARAM_UTF8_STRING);
764 }
765
766 int OSSL_PARAM_get_octet_string(const OSSL_PARAM *p, void **val, size_t max_len,
767                                 size_t *used_len)
768 {
769     return get_string_internal(p, val, max_len, used_len,
770                                OSSL_PARAM_OCTET_STRING);
771 }
772
773 static int set_string_internal(OSSL_PARAM *p, const void *val, size_t len,
774                                unsigned int type)
775 {
776     p->return_size = len;
777     if (p->data_type != type || p->data_size < len)
778         return 0;
779
780     memcpy(p->data, val, len);
781     return 1;
782 }
783
784 int OSSL_PARAM_set_utf8_string(OSSL_PARAM *p, const char *val)
785 {
786     if (p == NULL)
787         return 0;
788
789     p->return_size = 0;
790     if (val == NULL)
791         return 0;
792     return set_string_internal(p, val, strlen(val) + 1, OSSL_PARAM_UTF8_STRING);
793 }
794
795 int OSSL_PARAM_set_octet_string(OSSL_PARAM *p, const void *val,
796                                 size_t len)
797 {
798     if (p == NULL)
799         return 0;
800
801     p->return_size = 0;
802     if (val == NULL)
803         return 0;
804     return set_string_internal(p, val, len, OSSL_PARAM_OCTET_STRING);
805 }
806
807 OSSL_PARAM OSSL_PARAM_construct_utf8_string(const char *key, char *buf,
808                                             size_t bsize)
809 {
810     return ossl_param_construct(key, OSSL_PARAM_UTF8_STRING, buf, bsize);
811 }
812
813 OSSL_PARAM OSSL_PARAM_construct_octet_string(const char *key, void *buf,
814                                              size_t bsize)
815 {
816     return ossl_param_construct(key, OSSL_PARAM_OCTET_STRING, buf, bsize);
817 }
818
819 static int get_ptr_internal(const OSSL_PARAM *p, const void **val,
820                             size_t *used_len, unsigned int type)
821 {
822     if (val == NULL || p == NULL || p->data_type != type)
823         return 0;
824     if (used_len != NULL)
825         *used_len = p->data_size;
826     *val = *(const void **)p->data;
827     return 1;
828 }
829
830 int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM *p, const char **val)
831 {
832     return get_ptr_internal(p, (const void **)val, NULL, OSSL_PARAM_UTF8_PTR);
833 }
834
835 int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, const void **val,
836                              size_t *used_len)
837 {
838     return get_ptr_internal(p, val, used_len, OSSL_PARAM_OCTET_PTR);
839 }
840
841 static int set_ptr_internal(OSSL_PARAM *p, const void *val,
842                             unsigned int type, size_t len)
843 {
844     p->return_size = len;
845     if (p->data_type != type)
846         return 0;
847     *(const void **)p->data = val;
848     return 1;
849 }
850
851 int OSSL_PARAM_set_utf8_ptr(OSSL_PARAM *p, const char *val)
852 {
853     if (p == NULL)
854         return 0;
855     p->return_size = 0;
856     if (val == NULL)
857         return 0;
858     return set_ptr_internal(p, val, OSSL_PARAM_UTF8_PTR, strlen(val) + 1);
859 }
860
861 int OSSL_PARAM_set_octet_ptr(OSSL_PARAM *p, const void *val,
862                              size_t used_len)
863 {
864     if (p == NULL)
865         return 0;
866     p->return_size = 0;
867     if (val == NULL)
868         return 0;
869     return set_ptr_internal(p, val, OSSL_PARAM_OCTET_PTR, used_len);
870 }
871
872 OSSL_PARAM OSSL_PARAM_construct_utf8_ptr(const char *key, char **buf,
873                                          size_t bsize)
874 {
875     return ossl_param_construct(key, OSSL_PARAM_UTF8_PTR, buf, bsize);
876 }
877
878 OSSL_PARAM OSSL_PARAM_construct_octet_ptr(const char *key, void **buf,
879                                           size_t bsize)
880 {
881     return ossl_param_construct(key, OSSL_PARAM_OCTET_PTR, buf, bsize);
882 }
883
884 OSSL_PARAM OSSL_PARAM_construct_end(void)
885 {
886     OSSL_PARAM end = OSSL_PARAM_END;
887
888     return end;
889 }