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