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