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