xref: /freebsd/crypto/openssl/crypto/params.c (revision aa795734)
1 /*
2  * Copyright 2019-2023 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 #include "internal/endian.h"
16 
17 #ifndef OPENSSL_SYS_UEFI
18 /*
19  * Return the number of bits in the mantissa of a double.  This is used to
20  * shift a larger integral value to determine if it will exactly fit into a
21  * double.
22  */
real_shift(void)23 static unsigned int real_shift(void)
24 {
25     return sizeof(double) == 4 ? 24 : 53;
26 }
27 #endif
28 
OSSL_PARAM_locate(OSSL_PARAM * p,const char * key)29 OSSL_PARAM *OSSL_PARAM_locate(OSSL_PARAM *p, const char *key)
30 {
31     if (p != NULL && key != NULL)
32         for (; p->key != NULL; p++)
33             if (strcmp(key, p->key) == 0)
34                 return p;
35     return NULL;
36 }
37 
OSSL_PARAM_locate_const(const OSSL_PARAM * p,const char * key)38 const OSSL_PARAM *OSSL_PARAM_locate_const(const OSSL_PARAM *p, const char *key)
39 {
40     return OSSL_PARAM_locate((OSSL_PARAM *)p, key);
41 }
42 
ossl_param_construct(const char * key,unsigned int data_type,void * data,size_t data_size)43 static OSSL_PARAM ossl_param_construct(const char *key, unsigned int data_type,
44                                        void *data, size_t data_size)
45 {
46     OSSL_PARAM res;
47 
48     res.key = key;
49     res.data_type = data_type;
50     res.data = data;
51     res.data_size = data_size;
52     res.return_size = OSSL_PARAM_UNMODIFIED;
53     return res;
54 }
55 
OSSL_PARAM_modified(const OSSL_PARAM * p)56 int OSSL_PARAM_modified(const OSSL_PARAM *p)
57 {
58     return p != NULL && p->return_size != OSSL_PARAM_UNMODIFIED;
59 }
60 
OSSL_PARAM_set_all_unmodified(OSSL_PARAM * p)61 void OSSL_PARAM_set_all_unmodified(OSSL_PARAM *p)
62 {
63     if (p != NULL)
64         while (p->key != NULL)
65             p++->return_size = OSSL_PARAM_UNMODIFIED;
66 }
67 
68 /* Return non-zero if the signed number is negative */
is_negative(const void * number,size_t s)69 static int is_negative(const void *number, size_t s)
70 {
71     const unsigned char *n = number;
72     DECLARE_IS_ENDIAN;
73 
74     return 0x80 & (IS_BIG_ENDIAN ? n[0] : n[s - 1]);
75 }
76 
77 /* Check that all the bytes specified match the expected sign byte */
check_sign_bytes(const unsigned char * p,size_t n,unsigned char s)78 static int check_sign_bytes(const unsigned char *p, size_t n, unsigned char s)
79 {
80     size_t i;
81 
82     for (i = 0; i < n; i++)
83         if (p[i] != s)
84             return 0;
85     return 1;
86 }
87 
88 /*
89  * Copy an integer to another integer.
90  * Handle different length integers and signed and unsigned integers.
91  * Both integers are in native byte ordering.
92  */
copy_integer(unsigned char * dest,size_t dest_len,const unsigned char * src,size_t src_len,unsigned char pad,int signed_int)93 static int copy_integer(unsigned char *dest, size_t dest_len,
94                         const unsigned char *src, size_t src_len,
95                         unsigned char pad, int signed_int)
96 {
97     size_t n;
98     DECLARE_IS_ENDIAN;
99 
100     if (IS_BIG_ENDIAN) {
101         if (src_len < dest_len) {
102             n = dest_len - src_len;
103             memset(dest, pad, n);
104             memcpy(dest + n, src, src_len);
105         } else {
106             n = src_len - dest_len;
107             if (!check_sign_bytes(src, n, pad)
108                     /*
109                      * Shortening a signed value must retain the correct sign.
110                      * Avoiding this kind of thing: -253 = 0xff03 -> 0x03 = 3
111                      */
112                     || (signed_int && ((pad ^ src[n]) & 0x80) != 0))
113                 return 0;
114             memcpy(dest, src + n, dest_len);
115         }
116     } else /* IS_LITTLE_ENDIAN */ {
117         if (src_len < dest_len) {
118             n = dest_len - src_len;
119             memset(dest + src_len, pad, n);
120             memcpy(dest, src, src_len);
121         } else {
122             n = src_len - dest_len;
123             if (!check_sign_bytes(src + dest_len, n, pad)
124                     /*
125                      * Shortening a signed value must retain the correct sign.
126                      * Avoiding this kind of thing: 130 = 0x0082 -> 0x82 = -126
127                      */
128                     || (signed_int && ((pad ^ src[dest_len - 1]) & 0x80) != 0))
129                 return 0;
130             memcpy(dest, src, dest_len);
131         }
132     }
133     return 1;
134 }
135 
136 /* Copy a signed number to a signed number of possibly different length */
signed_from_signed(void * dest,size_t dest_len,const void * src,size_t src_len)137 static int signed_from_signed(void *dest, size_t dest_len,
138                               const void *src, size_t src_len)
139 {
140     return copy_integer(dest, dest_len, src, src_len,
141                         is_negative(src, src_len) ? 0xff : 0, 1);
142 }
143 
144 /* Copy an unsigned number to a signed number of possibly different length */
signed_from_unsigned(void * dest,size_t dest_len,const void * src,size_t src_len)145 static int signed_from_unsigned(void *dest, size_t dest_len,
146                                 const void *src, size_t src_len)
147 {
148     return copy_integer(dest, dest_len, src, src_len, 0, 1);
149 }
150 
151 /* Copy a signed number to an unsigned number of possibly different length */
unsigned_from_signed(void * dest,size_t dest_len,const void * src,size_t src_len)152 static int unsigned_from_signed(void *dest, size_t dest_len,
153                                 const void *src, size_t src_len)
154 {
155     if (is_negative(src, src_len))
156         return 0;
157     return copy_integer(dest, dest_len, src, src_len, 0, 0);
158 }
159 
160 /* Copy an unsigned number to an unsigned number of possibly different length */
unsigned_from_unsigned(void * dest,size_t dest_len,const void * src,size_t src_len)161 static int unsigned_from_unsigned(void *dest, size_t dest_len,
162                                   const void *src, size_t src_len)
163 {
164     return copy_integer(dest, dest_len, src, src_len, 0, 0);
165 }
166 
167 /* General purpose get integer parameter call that handles odd sizes */
general_get_int(const OSSL_PARAM * p,void * val,size_t val_size)168 static int general_get_int(const OSSL_PARAM *p, void *val, size_t val_size)
169 {
170     if (p->data_type == OSSL_PARAM_INTEGER)
171         return signed_from_signed(val, val_size, p->data, p->data_size);
172     if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER)
173         return signed_from_unsigned(val, val_size, p->data, p->data_size);
174     return 0;
175 }
176 
177 /* General purpose set integer parameter call that handles odd sizes */
general_set_int(OSSL_PARAM * p,void * val,size_t val_size)178 static int general_set_int(OSSL_PARAM *p, void *val, size_t val_size)
179 {
180     int r = 0;
181 
182     p->return_size = val_size; /* Expected size */
183     if (p->data == NULL)
184         return 1;
185     if (p->data_type == OSSL_PARAM_INTEGER)
186         r = signed_from_signed(p->data, p->data_size, val, val_size);
187     else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER)
188         r = unsigned_from_signed(p->data, p->data_size, val, val_size);
189     p->return_size = r ? p->data_size : val_size;
190     return r;
191 }
192 
193 /* General purpose get unsigned integer parameter call that handles odd sizes */
general_get_uint(const OSSL_PARAM * p,void * val,size_t val_size)194 static int general_get_uint(const OSSL_PARAM *p, void *val, size_t val_size)
195 {
196     if (p->data_type == OSSL_PARAM_INTEGER)
197         return unsigned_from_signed(val, val_size, p->data, p->data_size);
198     if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER)
199         return unsigned_from_unsigned(val, val_size, p->data, p->data_size);
200     return 0;
201 }
202 
203 /* General purpose set unsigned integer parameter call that handles odd sizes */
general_set_uint(OSSL_PARAM * p,void * val,size_t val_size)204 static int general_set_uint(OSSL_PARAM *p, void *val, size_t val_size)
205 {
206     int r = 0;
207 
208     p->return_size = val_size; /* Expected size */
209     if (p->data == NULL)
210         return 1;
211     if (p->data_type == OSSL_PARAM_INTEGER)
212         r = signed_from_unsigned(p->data, p->data_size, val, val_size);
213     else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER)
214         r = unsigned_from_unsigned(p->data, p->data_size, val, val_size);
215     p->return_size = r ? p->data_size : val_size;
216     return r;
217 }
218 
OSSL_PARAM_get_int(const OSSL_PARAM * p,int * val)219 int OSSL_PARAM_get_int(const OSSL_PARAM *p, int *val)
220 {
221 #ifndef OPENSSL_SMALL_FOOTPRINT
222     switch (sizeof(int)) {
223     case sizeof(int32_t):
224         return OSSL_PARAM_get_int32(p, (int32_t *)val);
225     case sizeof(int64_t):
226         return OSSL_PARAM_get_int64(p, (int64_t *)val);
227     }
228 #endif
229     return general_get_int(p, val, sizeof(*val));
230 }
231 
OSSL_PARAM_set_int(OSSL_PARAM * p,int val)232 int OSSL_PARAM_set_int(OSSL_PARAM *p, int val)
233 {
234 #ifndef OPENSSL_SMALL_FOOTPRINT
235     switch (sizeof(int)) {
236     case sizeof(int32_t):
237         return OSSL_PARAM_set_int32(p, (int32_t)val);
238     case sizeof(int64_t):
239         return OSSL_PARAM_set_int64(p, (int64_t)val);
240     }
241 #endif
242     return general_set_int(p, &val, sizeof(val));
243 }
244 
OSSL_PARAM_construct_int(const char * key,int * buf)245 OSSL_PARAM OSSL_PARAM_construct_int(const char *key, int *buf)
246 {
247     return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int));
248 }
249 
OSSL_PARAM_get_uint(const OSSL_PARAM * p,unsigned int * val)250 int OSSL_PARAM_get_uint(const OSSL_PARAM *p, unsigned int *val)
251 {
252 #ifndef OPENSSL_SMALL_FOOTPRINT
253     switch (sizeof(unsigned int)) {
254     case sizeof(uint32_t):
255         return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
256     case sizeof(uint64_t):
257         return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
258     }
259 #endif
260     return general_get_uint(p, val, sizeof(*val));
261 }
262 
OSSL_PARAM_set_uint(OSSL_PARAM * p,unsigned int val)263 int OSSL_PARAM_set_uint(OSSL_PARAM *p, unsigned int val)
264 {
265 #ifndef OPENSSL_SMALL_FOOTPRINT
266     switch (sizeof(unsigned int)) {
267     case sizeof(uint32_t):
268         return OSSL_PARAM_set_uint32(p, (uint32_t)val);
269     case sizeof(uint64_t):
270         return OSSL_PARAM_set_uint64(p, (uint64_t)val);
271     }
272 #endif
273     return general_set_uint(p, &val, sizeof(val));
274 }
275 
OSSL_PARAM_construct_uint(const char * key,unsigned int * buf)276 OSSL_PARAM OSSL_PARAM_construct_uint(const char *key, unsigned int *buf)
277 {
278     return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
279                                 sizeof(unsigned int));
280 }
281 
OSSL_PARAM_get_long(const OSSL_PARAM * p,long int * val)282 int OSSL_PARAM_get_long(const OSSL_PARAM *p, long int *val)
283 {
284 #ifndef OPENSSL_SMALL_FOOTPRINT
285     switch (sizeof(long int)) {
286     case sizeof(int32_t):
287         return OSSL_PARAM_get_int32(p, (int32_t *)val);
288     case sizeof(int64_t):
289         return OSSL_PARAM_get_int64(p, (int64_t *)val);
290     }
291 #endif
292     return general_get_int(p, val, sizeof(*val));
293 }
294 
OSSL_PARAM_set_long(OSSL_PARAM * p,long int val)295 int OSSL_PARAM_set_long(OSSL_PARAM *p, long int val)
296 {
297 #ifndef OPENSSL_SMALL_FOOTPRINT
298     switch (sizeof(long int)) {
299     case sizeof(int32_t):
300         return OSSL_PARAM_set_int32(p, (int32_t)val);
301     case sizeof(int64_t):
302         return OSSL_PARAM_set_int64(p, (int64_t)val);
303     }
304 #endif
305     return general_set_int(p, &val, sizeof(val));
306 }
307 
OSSL_PARAM_construct_long(const char * key,long int * buf)308 OSSL_PARAM OSSL_PARAM_construct_long(const char *key, long int *buf)
309 {
310     return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(long int));
311 }
312 
OSSL_PARAM_get_ulong(const OSSL_PARAM * p,unsigned long int * val)313 int OSSL_PARAM_get_ulong(const OSSL_PARAM *p, unsigned long int *val)
314 {
315 #ifndef OPENSSL_SMALL_FOOTPRINT
316     switch (sizeof(unsigned long int)) {
317     case sizeof(uint32_t):
318         return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
319     case sizeof(uint64_t):
320         return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
321     }
322 #endif
323     return general_get_uint(p, val, sizeof(*val));
324 }
325 
OSSL_PARAM_set_ulong(OSSL_PARAM * p,unsigned long int val)326 int OSSL_PARAM_set_ulong(OSSL_PARAM *p, unsigned long int val)
327 {
328 #ifndef OPENSSL_SMALL_FOOTPRINT
329     switch (sizeof(unsigned long int)) {
330     case sizeof(uint32_t):
331         return OSSL_PARAM_set_uint32(p, (uint32_t)val);
332     case sizeof(uint64_t):
333         return OSSL_PARAM_set_uint64(p, (uint64_t)val);
334     }
335 #endif
336     return general_set_uint(p, &val, sizeof(val));
337 }
338 
OSSL_PARAM_construct_ulong(const char * key,unsigned long int * buf)339 OSSL_PARAM OSSL_PARAM_construct_ulong(const char *key, unsigned long int *buf)
340 {
341     return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
342                                 sizeof(unsigned long int));
343 }
344 
OSSL_PARAM_get_int32(const OSSL_PARAM * p,int32_t * val)345 int OSSL_PARAM_get_int32(const OSSL_PARAM *p, int32_t *val)
346 {
347     if (val == NULL || p == NULL )
348         return 0;
349 
350     if (p->data_type == OSSL_PARAM_INTEGER) {
351 #ifndef OPENSSL_SMALL_FOOTPRINT
352         int64_t i64;
353 
354         switch (p->data_size) {
355         case sizeof(int32_t):
356             *val = *(const int32_t *)p->data;
357             return 1;
358         case sizeof(int64_t):
359             i64 = *(const int64_t *)p->data;
360             if (i64 >= INT32_MIN && i64 <= INT32_MAX) {
361                 *val = (int32_t)i64;
362                 return 1;
363             }
364             return 0;
365         }
366 #endif
367         return general_get_int(p, val, sizeof(*val));
368 
369     } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
370 #ifndef OPENSSL_SMALL_FOOTPRINT
371         uint32_t u32;
372         uint64_t u64;
373 
374         switch (p->data_size) {
375         case sizeof(uint32_t):
376             u32 = *(const uint32_t *)p->data;
377             if (u32 <= INT32_MAX) {
378                 *val = (int32_t)u32;
379                 return 1;
380             }
381             return 0;
382         case sizeof(uint64_t):
383             u64 = *(const uint64_t *)p->data;
384             if (u64 <= INT32_MAX) {
385                 *val = (int32_t)u64;
386                 return 1;
387             }
388             return 0;
389         }
390 #endif
391         return general_get_int(p, val, sizeof(*val));
392 
393     } else if (p->data_type == OSSL_PARAM_REAL) {
394 #ifndef OPENSSL_SYS_UEFI
395         double d;
396 
397         switch (p->data_size) {
398         case sizeof(double):
399             d = *(const double *)p->data;
400             if (d >= INT32_MIN && d <= INT32_MAX && d == (int32_t)d) {
401                 *val = (int32_t)d;
402                 return 1;
403             }
404             break;
405         }
406 #endif
407     }
408     return 0;
409 }
410 
OSSL_PARAM_set_int32(OSSL_PARAM * p,int32_t val)411 int OSSL_PARAM_set_int32(OSSL_PARAM *p, int32_t val)
412 {
413     if (p == NULL)
414         return 0;
415     p->return_size = 0;
416     if (p->data_type == OSSL_PARAM_INTEGER) {
417 #ifndef OPENSSL_SMALL_FOOTPRINT
418         p->return_size = sizeof(int32_t); /* Minimum expected size */
419         if (p->data == NULL)
420             return 1;
421         switch (p->data_size) {
422         case sizeof(int32_t):
423             *(int32_t *)p->data = val;
424             return 1;
425         case sizeof(int64_t):
426             p->return_size = sizeof(int64_t);
427             *(int64_t *)p->data = (int64_t)val;
428             return 1;
429         }
430 #endif
431         return general_set_int(p, &val, sizeof(val));
432     } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) {
433 #ifndef OPENSSL_SMALL_FOOTPRINT
434         p->return_size = sizeof(uint32_t); /* Minimum expected size */
435         if (p->data == NULL)
436             return 1;
437         switch (p->data_size) {
438         case sizeof(uint32_t):
439             *(uint32_t *)p->data = (uint32_t)val;
440             return 1;
441         case sizeof(uint64_t):
442             p->return_size = sizeof(uint64_t);
443             *(uint64_t *)p->data = (uint64_t)val;
444             return 1;
445         }
446 #endif
447         return general_set_int(p, &val, sizeof(val));
448     } else if (p->data_type == OSSL_PARAM_REAL) {
449 #ifndef OPENSSL_SYS_UEFI
450         p->return_size = sizeof(double);
451         if (p->data == NULL)
452             return 1;
453         switch (p->data_size) {
454         case sizeof(double):
455             *(double *)p->data = (double)val;
456             return 1;
457         }
458 #endif
459     }
460     return 0;
461 }
462 
OSSL_PARAM_construct_int32(const char * key,int32_t * buf)463 OSSL_PARAM OSSL_PARAM_construct_int32(const char *key, int32_t *buf)
464 {
465     return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf,
466                                 sizeof(int32_t));
467 }
468 
OSSL_PARAM_get_uint32(const OSSL_PARAM * p,uint32_t * val)469 int OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val)
470 {
471     if (val == NULL || p == NULL)
472         return 0;
473 
474     if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
475 #ifndef OPENSSL_SMALL_FOOTPRINT
476         uint64_t u64;
477 
478         switch (p->data_size) {
479         case sizeof(uint32_t):
480             *val = *(const uint32_t *)p->data;
481             return 1;
482         case sizeof(uint64_t):
483             u64 = *(const uint64_t *)p->data;
484             if (u64 <= UINT32_MAX) {
485                 *val = (uint32_t)u64;
486                 return 1;
487             }
488             return 0;
489         }
490 #endif
491         return general_get_uint(p, val, sizeof(*val));
492     } else if (p->data_type == OSSL_PARAM_INTEGER) {
493 #ifndef OPENSSL_SMALL_FOOTPRINT
494         int32_t i32;
495         int64_t i64;
496 
497         switch (p->data_size) {
498         case sizeof(int32_t):
499             i32 = *(const int32_t *)p->data;
500             if (i32 >= 0) {
501                 *val = i32;
502                 return 1;
503             }
504             return 0;
505         case sizeof(int64_t):
506             i64 = *(const int64_t *)p->data;
507             if (i64 >= 0 && i64 <= UINT32_MAX) {
508                 *val = (uint32_t)i64;
509                 return 1;
510             }
511             return 0;
512         }
513 #endif
514         return general_get_uint(p, val, sizeof(*val));
515     } else if (p->data_type == OSSL_PARAM_REAL) {
516 #ifndef OPENSSL_SYS_UEFI
517         double d;
518 
519         switch (p->data_size) {
520         case sizeof(double):
521             d = *(const double *)p->data;
522             if (d >= 0 && d <= UINT32_MAX && d == (uint32_t)d) {
523                 *val = (uint32_t)d;
524                 return 1;
525             }
526             break;
527         }
528 #endif
529     }
530     return 0;
531 }
532 
OSSL_PARAM_set_uint32(OSSL_PARAM * p,uint32_t val)533 int OSSL_PARAM_set_uint32(OSSL_PARAM *p, uint32_t val)
534 {
535     if (p == NULL)
536         return 0;
537     p->return_size = 0;
538 
539     if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
540 #ifndef OPENSSL_SMALL_FOOTPRINT
541         p->return_size = sizeof(uint32_t); /* Minimum expected size */
542         if (p->data == NULL)
543             return 1;
544         switch (p->data_size) {
545         case sizeof(uint32_t):
546             *(uint32_t *)p->data = val;
547             return 1;
548         case sizeof(uint64_t):
549             p->return_size = sizeof(uint64_t);
550             *(uint64_t *)p->data = val;
551             return 1;
552         }
553 #endif
554         return general_set_uint(p, &val, sizeof(val));
555     } else if (p->data_type == OSSL_PARAM_INTEGER) {
556 #ifndef OPENSSL_SMALL_FOOTPRINT
557         p->return_size = sizeof(int32_t); /* Minimum expected size */
558         if (p->data == NULL)
559             return 1;
560         switch (p->data_size) {
561         case sizeof(int32_t):
562             if (val <= INT32_MAX) {
563                 *(int32_t *)p->data = (int32_t)val;
564                 return 1;
565             }
566             return 0;
567         case sizeof(int64_t):
568             p->return_size = sizeof(int64_t);
569             *(int64_t *)p->data = (int64_t)val;
570             return 1;
571         }
572 #endif
573         return general_set_uint(p, &val, sizeof(val));
574     } else if (p->data_type == OSSL_PARAM_REAL) {
575 #ifndef OPENSSL_SYS_UEFI
576         p->return_size = sizeof(double);
577         if (p->data == NULL)
578             return 1;
579         switch (p->data_size) {
580         case sizeof(double):
581             *(double *)p->data = (double)val;
582             return 1;
583         }
584 #endif
585     }
586     return 0;
587 }
588 
OSSL_PARAM_construct_uint32(const char * key,uint32_t * buf)589 OSSL_PARAM OSSL_PARAM_construct_uint32(const char *key, uint32_t *buf)
590 {
591     return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
592                                 sizeof(uint32_t));
593 }
594 
OSSL_PARAM_get_int64(const OSSL_PARAM * p,int64_t * val)595 int OSSL_PARAM_get_int64(const OSSL_PARAM *p, int64_t *val)
596 {
597     if (val == NULL || p == NULL )
598         return 0;
599 
600     if (p->data_type == OSSL_PARAM_INTEGER) {
601 #ifndef OPENSSL_SMALL_FOOTPRINT
602         switch (p->data_size) {
603         case sizeof(int32_t):
604             *val = *(const int32_t *)p->data;
605             return 1;
606         case sizeof(int64_t):
607             *val = *(const int64_t *)p->data;
608             return 1;
609         }
610 #endif
611         return general_get_int(p, val, sizeof(*val));
612     } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
613 #ifndef OPENSSL_SMALL_FOOTPRINT
614         uint64_t u64;
615 
616         switch (p->data_size) {
617         case sizeof(uint32_t):
618             *val = *(const uint32_t *)p->data;
619             return 1;
620         case sizeof(uint64_t):
621             u64 = *(const uint64_t *)p->data;
622             if (u64 <= INT64_MAX) {
623                 *val = (int64_t)u64;
624                 return 1;
625             }
626             return 0;
627         }
628 #endif
629         return general_get_int(p, val, sizeof(*val));
630     } else if (p->data_type == OSSL_PARAM_REAL) {
631 #ifndef OPENSSL_SYS_UEFI
632         double d;
633 
634         switch (p->data_size) {
635         case sizeof(double):
636             d = *(const double *)p->data;
637             if (d >= INT64_MIN
638                     /*
639                      * By subtracting 65535 (2^16-1) we cancel the low order
640                      * 15 bits of INT64_MAX to avoid using imprecise floating
641                      * point values.
642                      */
643                     && d < (double)(INT64_MAX - 65535) + 65536.0
644                     && d == (int64_t)d) {
645                 *val = (int64_t)d;
646                 return 1;
647             }
648             break;
649         }
650 #endif
651     }
652     return 0;
653 }
654 
OSSL_PARAM_set_int64(OSSL_PARAM * p,int64_t val)655 int OSSL_PARAM_set_int64(OSSL_PARAM *p, int64_t val)
656 {
657     if (p == NULL)
658         return 0;
659     p->return_size = 0;
660     if (p->data_type == OSSL_PARAM_INTEGER) {
661 #ifndef OPENSSL_SMALL_FOOTPRINT
662         p->return_size = sizeof(int64_t); /* Expected size */
663         if (p->data == NULL)
664             return 1;
665         switch (p->data_size) {
666         case sizeof(int32_t):
667             if (val >= INT32_MIN && val <= INT32_MAX) {
668                 p->return_size = sizeof(int32_t);
669                 *(int32_t *)p->data = (int32_t)val;
670                 return 1;
671             }
672             return 0;
673         case sizeof(int64_t):
674             *(int64_t *)p->data = val;
675             return 1;
676         }
677 #endif
678         return general_set_int(p, &val, sizeof(val));
679     } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) {
680 #ifndef OPENSSL_SMALL_FOOTPRINT
681         p->return_size = sizeof(uint64_t); /* Expected size */
682         if (p->data == NULL)
683             return 1;
684         switch (p->data_size) {
685         case sizeof(uint32_t):
686             if (val <= UINT32_MAX) {
687                 p->return_size = sizeof(uint32_t);
688                 *(uint32_t *)p->data = (uint32_t)val;
689                 return 1;
690             }
691             return 0;
692         case sizeof(uint64_t):
693             *(uint64_t *)p->data = (uint64_t)val;
694             return 1;
695         }
696 #endif
697         return general_set_int(p, &val, sizeof(val));
698     } else if (p->data_type == OSSL_PARAM_REAL) {
699 #ifndef OPENSSL_SYS_UEFI
700         uint64_t u64;
701 
702         p->return_size = sizeof(double);
703         if (p->data == NULL)
704             return 1;
705         switch (p->data_size) {
706         case sizeof(double):
707             u64 = val < 0 ? -val : val;
708             if ((u64 >> real_shift()) == 0) {
709                 *(double *)p->data = (double)val;
710                 return 1;
711             }
712             break;
713         }
714 #endif
715     }
716     return 0;
717 }
718 
OSSL_PARAM_construct_int64(const char * key,int64_t * buf)719 OSSL_PARAM OSSL_PARAM_construct_int64(const char *key, int64_t *buf)
720 {
721     return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int64_t));
722 }
723 
OSSL_PARAM_get_uint64(const OSSL_PARAM * p,uint64_t * val)724 int OSSL_PARAM_get_uint64(const OSSL_PARAM *p, uint64_t *val)
725 {
726     if (val == NULL || p == NULL)
727         return 0;
728 
729     if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
730 #ifndef OPENSSL_SMALL_FOOTPRINT
731         switch (p->data_size) {
732         case sizeof(uint32_t):
733             *val = *(const uint32_t *)p->data;
734             return 1;
735         case sizeof(uint64_t):
736             *val = *(const uint64_t *)p->data;
737             return 1;
738         }
739 #endif
740         return general_get_uint(p, val, sizeof(*val));
741     } else if (p->data_type == OSSL_PARAM_INTEGER) {
742 #ifndef OPENSSL_SMALL_FOOTPRINT
743         int32_t i32;
744         int64_t i64;
745 
746         switch (p->data_size) {
747         case sizeof(int32_t):
748             i32 = *(const int32_t *)p->data;
749             if (i32 >= 0) {
750                 *val = (uint64_t)i32;
751                 return 1;
752             }
753             return 0;
754         case sizeof(int64_t):
755             i64 = *(const int64_t *)p->data;
756             if (i64 >= 0) {
757                 *val = (uint64_t)i64;
758                 return 1;
759             }
760             return 0;
761         }
762 #endif
763         return general_get_uint(p, val, sizeof(*val));
764     } else if (p->data_type == OSSL_PARAM_REAL) {
765 #ifndef OPENSSL_SYS_UEFI
766         double d;
767 
768         switch (p->data_size) {
769         case sizeof(double):
770             d = *(const double *)p->data;
771             if (d >= 0
772                     /*
773                      * By subtracting 65535 (2^16-1) we cancel the low order
774                      * 15 bits of UINT64_MAX to avoid using imprecise floating
775                      * point values.
776                      */
777                     && d < (double)(UINT64_MAX - 65535) + 65536.0
778                     && d == (uint64_t)d) {
779                 *val = (uint64_t)d;
780                 return 1;
781             }
782             break;
783         }
784 #endif
785     }
786     return 0;
787 }
788 
OSSL_PARAM_set_uint64(OSSL_PARAM * p,uint64_t val)789 int OSSL_PARAM_set_uint64(OSSL_PARAM *p, uint64_t val)
790 {
791     if (p == NULL)
792         return 0;
793     p->return_size = 0;
794 
795     if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
796 #ifndef OPENSSL_SMALL_FOOTPRINT
797         p->return_size = sizeof(uint64_t); /* Expected size */
798         if (p->data == NULL)
799             return 1;
800         switch (p->data_size) {
801         case sizeof(uint32_t):
802             if (val <= UINT32_MAX) {
803                 p->return_size = sizeof(uint32_t);
804                 *(uint32_t *)p->data = (uint32_t)val;
805                 return 1;
806             }
807             return 0;
808         case sizeof(uint64_t):
809             *(uint64_t *)p->data = val;
810             return 1;
811         }
812 #endif
813         return general_set_uint(p, &val, sizeof(val));
814     } else if (p->data_type == OSSL_PARAM_INTEGER) {
815 #ifndef OPENSSL_SMALL_FOOTPRINT
816         p->return_size = sizeof(int64_t); /* Expected size */
817         if (p->data == NULL)
818             return 1;
819         switch (p->data_size) {
820         case sizeof(int32_t):
821             if (val <= INT32_MAX) {
822                 p->return_size = sizeof(int32_t);
823                 *(int32_t *)p->data = (int32_t)val;
824                 return 1;
825             }
826             return 0;
827         case sizeof(int64_t):
828             if (val <= INT64_MAX) {
829                 *(int64_t *)p->data = (int64_t)val;
830                 return 1;
831             }
832             return 0;
833         }
834 #endif
835         return general_set_uint(p, &val, sizeof(val));
836     } else if (p->data_type == OSSL_PARAM_REAL) {
837 #ifndef OPENSSL_SYS_UEFI
838         p->return_size = sizeof(double);
839         switch (p->data_size) {
840         case sizeof(double):
841             if ((val >> real_shift()) == 0) {
842                 *(double *)p->data = (double)val;
843                 return 1;
844             }
845             break;
846         }
847 #endif
848     }
849     return 0;
850 }
851 
OSSL_PARAM_construct_uint64(const char * key,uint64_t * buf)852 OSSL_PARAM OSSL_PARAM_construct_uint64(const char *key, uint64_t *buf)
853 {
854     return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
855                                 sizeof(uint64_t));
856 }
857 
OSSL_PARAM_get_size_t(const OSSL_PARAM * p,size_t * val)858 int OSSL_PARAM_get_size_t(const OSSL_PARAM *p, size_t *val)
859 {
860 #ifndef OPENSSL_SMALL_FOOTPRINT
861     switch (sizeof(size_t)) {
862     case sizeof(uint32_t):
863         return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
864     case sizeof(uint64_t):
865         return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
866     }
867 #endif
868     return general_get_uint(p, val, sizeof(*val));
869 }
870 
OSSL_PARAM_set_size_t(OSSL_PARAM * p,size_t val)871 int OSSL_PARAM_set_size_t(OSSL_PARAM *p, size_t val)
872 {
873 #ifndef OPENSSL_SMALL_FOOTPRINT
874     switch (sizeof(size_t)) {
875     case sizeof(uint32_t):
876         return OSSL_PARAM_set_uint32(p, (uint32_t)val);
877     case sizeof(uint64_t):
878         return OSSL_PARAM_set_uint64(p, (uint64_t)val);
879     }
880 #endif
881     return general_set_uint(p, &val, sizeof(val));
882 }
883 
OSSL_PARAM_construct_size_t(const char * key,size_t * buf)884 OSSL_PARAM OSSL_PARAM_construct_size_t(const char *key, size_t *buf)
885 {
886     return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
887                                 sizeof(size_t));
888 }
889 
OSSL_PARAM_get_time_t(const OSSL_PARAM * p,time_t * val)890 int OSSL_PARAM_get_time_t(const OSSL_PARAM *p, time_t *val)
891 {
892 #ifndef OPENSSL_SMALL_FOOTPRINT
893     switch (sizeof(time_t)) {
894     case sizeof(int32_t):
895         return OSSL_PARAM_get_int32(p, (int32_t *)val);
896     case sizeof(int64_t):
897         return OSSL_PARAM_get_int64(p, (int64_t *)val);
898     }
899 #endif
900     return general_get_int(p, val, sizeof(*val));
901 }
902 
OSSL_PARAM_set_time_t(OSSL_PARAM * p,time_t val)903 int OSSL_PARAM_set_time_t(OSSL_PARAM *p, time_t val)
904 {
905 #ifndef OPENSSL_SMALL_FOOTPRINT
906     switch (sizeof(time_t)) {
907     case sizeof(int32_t):
908         return OSSL_PARAM_set_int32(p, (int32_t)val);
909     case sizeof(int64_t):
910         return OSSL_PARAM_set_int64(p, (int64_t)val);
911     }
912 #endif
913     return general_set_int(p, &val, sizeof(val));
914 }
915 
OSSL_PARAM_construct_time_t(const char * key,time_t * buf)916 OSSL_PARAM OSSL_PARAM_construct_time_t(const char *key, time_t *buf)
917 {
918     return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(time_t));
919 }
920 
OSSL_PARAM_get_BN(const OSSL_PARAM * p,BIGNUM ** val)921 int OSSL_PARAM_get_BN(const OSSL_PARAM *p, BIGNUM **val)
922 {
923     BIGNUM *b;
924 
925     if (val == NULL
926         || p == NULL
927         || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
928         return 0;
929 
930     b = BN_native2bn(p->data, (int)p->data_size, *val);
931     if (b != NULL) {
932         *val = b;
933         return 1;
934     }
935     return 0;
936 }
937 
OSSL_PARAM_set_BN(OSSL_PARAM * p,const BIGNUM * val)938 int OSSL_PARAM_set_BN(OSSL_PARAM *p, const BIGNUM *val)
939 {
940     size_t bytes;
941 
942     if (p == NULL)
943         return 0;
944     p->return_size = 0;
945     if (val == NULL || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
946         return 0;
947 
948     /* For the moment, only positive values are permitted */
949     if (BN_is_negative(val))
950         return 0;
951 
952     bytes = (size_t)BN_num_bytes(val);
953     /* We make sure that at least one byte is used, so zero is properly set */
954     if (bytes == 0)
955         bytes++;
956 
957     p->return_size = bytes;
958     if (p->data == NULL)
959         return 1;
960     if (p->data_size >= bytes) {
961         p->return_size = p->data_size;
962         return BN_bn2nativepad(val, p->data, p->data_size) >= 0;
963     }
964     return 0;
965 }
966 
OSSL_PARAM_construct_BN(const char * key,unsigned char * buf,size_t bsize)967 OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf,
968                                    size_t bsize)
969 {
970     return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER,
971                                 buf, bsize);
972 }
973 
974 #ifndef OPENSSL_SYS_UEFI
OSSL_PARAM_get_double(const OSSL_PARAM * p,double * val)975 int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val)
976 {
977     int64_t i64;
978     uint64_t u64;
979 
980     if (val == NULL || p == NULL)
981         return 0;
982 
983     if (p->data_type == OSSL_PARAM_REAL) {
984         switch (p->data_size) {
985         case sizeof(double):
986             *val = *(const double *)p->data;
987             return 1;
988         }
989     } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
990         switch (p->data_size) {
991         case sizeof(uint32_t):
992             *val = *(const uint32_t *)p->data;
993             return 1;
994         case sizeof(uint64_t):
995             u64 = *(const uint64_t *)p->data;
996             if ((u64 >> real_shift()) == 0) {
997                 *val = (double)u64;
998                 return 1;
999             }
1000             break;
1001         }
1002     } else if (p->data_type == OSSL_PARAM_INTEGER) {
1003         switch (p->data_size) {
1004         case sizeof(int32_t):
1005             *val = *(const int32_t *)p->data;
1006             return 1;
1007         case sizeof(int64_t):
1008             i64 = *(const int64_t *)p->data;
1009             u64 = i64 < 0 ? -i64 : i64;
1010             if ((u64 >> real_shift()) == 0) {
1011                 *val = 0.0 + i64;
1012                 return 1;
1013             }
1014             break;
1015         }
1016     }
1017     return 0;
1018 }
1019 
OSSL_PARAM_set_double(OSSL_PARAM * p,double val)1020 int OSSL_PARAM_set_double(OSSL_PARAM *p, double val)
1021 {
1022     if (p == NULL)
1023         return 0;
1024     p->return_size = 0;
1025 
1026     if (p->data_type == OSSL_PARAM_REAL) {
1027         p->return_size = sizeof(double);
1028         if (p->data == NULL)
1029             return 1;
1030         switch (p->data_size) {
1031         case sizeof(double):
1032             *(double *)p->data = val;
1033             return 1;
1034         }
1035     } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER
1036                && val == (uint64_t)val) {
1037         p->return_size = sizeof(double);
1038         if (p->data == NULL)
1039             return 1;
1040         switch (p->data_size) {
1041         case sizeof(uint32_t):
1042             if (val >= 0 && val <= UINT32_MAX) {
1043                 p->return_size = sizeof(uint32_t);
1044                 *(uint32_t *)p->data = (uint32_t)val;
1045                 return 1;
1046             }
1047             break;
1048         case sizeof(uint64_t):
1049             if (val >= 0
1050                     /*
1051                      * By subtracting 65535 (2^16-1) we cancel the low order
1052                      * 15 bits of UINT64_MAX to avoid using imprecise floating
1053                      * point values.
1054                      */
1055                     && val < (double)(UINT64_MAX - 65535) + 65536.0) {
1056                 p->return_size = sizeof(uint64_t);
1057                 *(uint64_t *)p->data = (uint64_t)val;
1058                 return 1;
1059             }
1060             break;            }
1061     } else if (p->data_type == OSSL_PARAM_INTEGER && val == (int64_t)val) {
1062         p->return_size = sizeof(double);
1063         if (p->data == NULL)
1064             return 1;
1065         switch (p->data_size) {
1066         case sizeof(int32_t):
1067             if (val >= INT32_MIN && val <= INT32_MAX) {
1068                 p->return_size = sizeof(int32_t);
1069                 *(int32_t *)p->data = (int32_t)val;
1070                 return 1;
1071             }
1072             break;
1073         case sizeof(int64_t):
1074             if (val >= INT64_MIN
1075                     /*
1076                      * By subtracting 65535 (2^16-1) we cancel the low order
1077                      * 15 bits of INT64_MAX to avoid using imprecise floating
1078                      * point values.
1079                      */
1080                     && val < (double)(INT64_MAX - 65535) + 65536.0) {
1081                 p->return_size = sizeof(int64_t);
1082                 *(int64_t *)p->data = (int64_t)val;
1083                 return 1;
1084             }
1085             break;
1086         }
1087     }
1088     return 0;
1089 }
1090 
OSSL_PARAM_construct_double(const char * key,double * buf)1091 OSSL_PARAM OSSL_PARAM_construct_double(const char *key, double *buf)
1092 {
1093     return ossl_param_construct(key, OSSL_PARAM_REAL, buf, sizeof(double));
1094 }
1095 #endif
1096 
get_string_internal(const OSSL_PARAM * p,void ** val,size_t * max_len,size_t * used_len,unsigned int type)1097 static int get_string_internal(const OSSL_PARAM *p, void **val,
1098                                size_t *max_len, size_t *used_len,
1099                                unsigned int type)
1100 {
1101     size_t sz, alloc_sz;
1102 
1103     if ((val == NULL && used_len == NULL) || p == NULL || p->data_type != type)
1104         return 0;
1105 
1106     sz = p->data_size;
1107     /*
1108      * If the input size is 0, or the input string needs NUL byte
1109      * termination, allocate an extra byte.
1110      */
1111     alloc_sz = sz + (type == OSSL_PARAM_UTF8_STRING || sz == 0);
1112 
1113     if (used_len != NULL)
1114         *used_len = sz;
1115 
1116     if (p->data == NULL)
1117         return 0;
1118 
1119     if (val == NULL)
1120         return 1;
1121 
1122     if (*val == NULL) {
1123         char *const q = OPENSSL_malloc(alloc_sz);
1124 
1125         if (q == NULL)
1126             return 0;
1127         *val = q;
1128         *max_len = alloc_sz;
1129     }
1130 
1131     if (*max_len < sz)
1132         return 0;
1133     memcpy(*val, p->data, sz);
1134     return 1;
1135 }
1136 
OSSL_PARAM_get_utf8_string(const OSSL_PARAM * p,char ** val,size_t max_len)1137 int OSSL_PARAM_get_utf8_string(const OSSL_PARAM *p, char **val, size_t max_len)
1138 {
1139     int ret = get_string_internal(p, (void **)val, &max_len, NULL,
1140                                   OSSL_PARAM_UTF8_STRING);
1141 
1142     /*
1143      * We try to ensure that the copied string is terminated with a
1144      * NUL byte.  That should be easy, just place a NUL byte at
1145      * |((char*)*val)[p->data_size]|.
1146      * Unfortunately, we have seen cases where |p->data_size| doesn't
1147      * correctly reflect the length of the string, and just happens
1148      * to be out of bounds according to |max_len|, so in that case, we
1149      * make the extra step of trying to find the true length of the
1150      * string that |p->data| points at, and use that as an index to
1151      * place the NUL byte in |*val|.
1152      */
1153     size_t data_length = p->data_size;
1154 
1155     if (ret == 0)
1156         return 0;
1157     if (data_length >= max_len)
1158         data_length = OPENSSL_strnlen(p->data, data_length);
1159     if (data_length >= max_len)
1160         return 0;            /* No space for a terminating NUL byte */
1161     (*val)[data_length] = '\0';
1162 
1163     return ret;
1164 }
1165 
OSSL_PARAM_get_octet_string(const OSSL_PARAM * p,void ** val,size_t max_len,size_t * used_len)1166 int OSSL_PARAM_get_octet_string(const OSSL_PARAM *p, void **val, size_t max_len,
1167                                 size_t *used_len)
1168 {
1169     return get_string_internal(p, val, &max_len, used_len,
1170                                OSSL_PARAM_OCTET_STRING);
1171 }
1172 
set_string_internal(OSSL_PARAM * p,const void * val,size_t len,unsigned int type)1173 static int set_string_internal(OSSL_PARAM *p, const void *val, size_t len,
1174                                unsigned int type)
1175 {
1176     p->return_size = len;
1177     if (p->data == NULL)
1178         return 1;
1179     if (p->data_type != type || p->data_size < len)
1180         return 0;
1181 
1182     memcpy(p->data, val, len);
1183     /* If possible within the size of p->data, add a NUL terminator byte */
1184     if (type == OSSL_PARAM_UTF8_STRING && p->data_size > len)
1185         ((char *)p->data)[len] = '\0';
1186     return 1;
1187 }
1188 
OSSL_PARAM_set_utf8_string(OSSL_PARAM * p,const char * val)1189 int OSSL_PARAM_set_utf8_string(OSSL_PARAM *p, const char *val)
1190 {
1191     if (p == NULL)
1192         return 0;
1193 
1194     p->return_size = 0;
1195     if (val == NULL)
1196         return 0;
1197     return set_string_internal(p, val, strlen(val), OSSL_PARAM_UTF8_STRING);
1198 }
1199 
OSSL_PARAM_set_octet_string(OSSL_PARAM * p,const void * val,size_t len)1200 int OSSL_PARAM_set_octet_string(OSSL_PARAM *p, const void *val,
1201                                 size_t len)
1202 {
1203     if (p == NULL)
1204         return 0;
1205 
1206     p->return_size = 0;
1207     if (val == NULL)
1208         return 0;
1209     return set_string_internal(p, val, len, OSSL_PARAM_OCTET_STRING);
1210 }
1211 
OSSL_PARAM_construct_utf8_string(const char * key,char * buf,size_t bsize)1212 OSSL_PARAM OSSL_PARAM_construct_utf8_string(const char *key, char *buf,
1213                                             size_t bsize)
1214 {
1215     if (buf != NULL && bsize == 0)
1216         bsize = strlen(buf);
1217     return ossl_param_construct(key, OSSL_PARAM_UTF8_STRING, buf, bsize);
1218 }
1219 
OSSL_PARAM_construct_octet_string(const char * key,void * buf,size_t bsize)1220 OSSL_PARAM OSSL_PARAM_construct_octet_string(const char *key, void *buf,
1221                                              size_t bsize)
1222 {
1223     return ossl_param_construct(key, OSSL_PARAM_OCTET_STRING, buf, bsize);
1224 }
1225 
get_ptr_internal(const OSSL_PARAM * p,const void ** val,size_t * used_len,unsigned int type)1226 static int get_ptr_internal(const OSSL_PARAM *p, const void **val,
1227                             size_t *used_len, unsigned int type)
1228 {
1229     if (val == NULL || p == NULL || p->data_type != type)
1230         return 0;
1231     if (used_len != NULL)
1232         *used_len = p->data_size;
1233     *val = *(const void **)p->data;
1234     return 1;
1235 }
1236 
OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM * p,const char ** val)1237 int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM *p, const char **val)
1238 {
1239     return get_ptr_internal(p, (const void **)val, NULL, OSSL_PARAM_UTF8_PTR);
1240 }
1241 
OSSL_PARAM_get_octet_ptr(const OSSL_PARAM * p,const void ** val,size_t * used_len)1242 int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, const void **val,
1243                              size_t *used_len)
1244 {
1245     return get_ptr_internal(p, val, used_len, OSSL_PARAM_OCTET_PTR);
1246 }
1247 
set_ptr_internal(OSSL_PARAM * p,const void * val,unsigned int type,size_t len)1248 static int set_ptr_internal(OSSL_PARAM *p, const void *val,
1249                             unsigned int type, size_t len)
1250 {
1251     p->return_size = len;
1252     if (p->data_type != type)
1253         return 0;
1254     if (p->data != NULL)
1255         *(const void **)p->data = val;
1256     return 1;
1257 }
1258 
OSSL_PARAM_set_utf8_ptr(OSSL_PARAM * p,const char * val)1259 int OSSL_PARAM_set_utf8_ptr(OSSL_PARAM *p, const char *val)
1260 {
1261     if (p == NULL)
1262         return 0;
1263     p->return_size = 0;
1264     return set_ptr_internal(p, val, OSSL_PARAM_UTF8_PTR,
1265                             val == NULL ? 0 : strlen(val));
1266 }
1267 
OSSL_PARAM_set_octet_ptr(OSSL_PARAM * p,const void * val,size_t used_len)1268 int OSSL_PARAM_set_octet_ptr(OSSL_PARAM *p, const void *val,
1269                              size_t used_len)
1270 {
1271     if (p == NULL)
1272         return 0;
1273     p->return_size = 0;
1274     return set_ptr_internal(p, val, OSSL_PARAM_OCTET_PTR, used_len);
1275 }
1276 
OSSL_PARAM_construct_utf8_ptr(const char * key,char ** buf,size_t bsize)1277 OSSL_PARAM OSSL_PARAM_construct_utf8_ptr(const char *key, char **buf,
1278                                          size_t bsize)
1279 {
1280     return ossl_param_construct(key, OSSL_PARAM_UTF8_PTR, buf, bsize);
1281 }
1282 
OSSL_PARAM_construct_octet_ptr(const char * key,void ** buf,size_t bsize)1283 OSSL_PARAM OSSL_PARAM_construct_octet_ptr(const char *key, void **buf,
1284                                           size_t bsize)
1285 {
1286     return ossl_param_construct(key, OSSL_PARAM_OCTET_PTR, buf, bsize);
1287 }
1288 
OSSL_PARAM_construct_end(void)1289 OSSL_PARAM OSSL_PARAM_construct_end(void)
1290 {
1291     OSSL_PARAM end = OSSL_PARAM_END;
1292 
1293     return end;
1294 }
1295 
get_string_ptr_internal(const OSSL_PARAM * p,const void ** val,size_t * used_len,unsigned int type)1296 static int get_string_ptr_internal(const OSSL_PARAM *p, const void **val,
1297                                    size_t *used_len, unsigned int type)
1298 {
1299     if (val == NULL || p == NULL || p->data_type != type)
1300         return 0;
1301     if (used_len != NULL)
1302         *used_len = p->data_size;
1303     *val = p->data;
1304     return 1;
1305 }
1306 
OSSL_PARAM_get_utf8_string_ptr(const OSSL_PARAM * p,const char ** val)1307 int OSSL_PARAM_get_utf8_string_ptr(const OSSL_PARAM *p, const char **val)
1308 {
1309     return OSSL_PARAM_get_utf8_ptr(p, val)
1310         || get_string_ptr_internal(p, (const void **)val, NULL,
1311                                    OSSL_PARAM_UTF8_STRING);
1312 }
1313 
OSSL_PARAM_get_octet_string_ptr(const OSSL_PARAM * p,const void ** val,size_t * used_len)1314 int OSSL_PARAM_get_octet_string_ptr(const OSSL_PARAM *p, const void **val,
1315                                     size_t *used_len)
1316 {
1317     return OSSL_PARAM_get_octet_ptr(p, val, used_len)
1318         || get_string_ptr_internal(p, val, used_len, OSSL_PARAM_OCTET_STRING);
1319 }
1320