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