]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/params.c
test: add a test RNG.
[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
P
619
620int OSSL_PARAM_get_BN(const OSSL_PARAM *p, BIGNUM **val)
621{
622 BIGNUM *b;
623
624 if (val == NULL
625 || p == NULL
626 || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
627 return 0;
628
629 b = BN_native2bn(p->data, (int)p->data_size, *val);
630 if (b != NULL) {
631 *val = b;
632 return 1;
633 }
634 return 0;
635}
636
4e7991b4 637int OSSL_PARAM_set_BN(OSSL_PARAM *p, const BIGNUM *val)
7ffbd7ca
P
638{
639 size_t bytes;
640
641 if (p == NULL)
642 return 0;
4e7991b4 643 p->return_size = 0;
7ffbd7ca
P
644 if (val == NULL || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
645 return 0;
646
6ce84e64
P
647 /* For the moment, only positive values are permitted */
648 if (BN_is_negative(val))
649 return 0;
650
7ffbd7ca 651 bytes = (size_t)BN_num_bytes(val);
4e7991b4 652 p->return_size = bytes;
8f3b8fd6
RL
653 if (p->data == NULL)
654 return 1;
0f73e719
RL
655 if (p->data_size >= bytes) {
656 p->return_size = p->data_size;
657 return BN_bn2nativepad(val, p->data, p->data_size) >= 0;
658 }
659 return 0;
7ffbd7ca
P
660}
661
662OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf,
4e7991b4 663 size_t bsize)
7ffbd7ca
P
664{
665 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER,
4e7991b4 666 buf, bsize);
7ffbd7ca
P
667}
668
669int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val)
670{
9830e7ea
P
671 int64_t i64;
672 uint64_t u64;
673
674 if (val == NULL || p == NULL)
7ffbd7ca
P
675 return 0;
676
9830e7ea
P
677 if (p->data_type == OSSL_PARAM_REAL) {
678 switch (p->data_size) {
679 case sizeof(double):
680 *val = *(const double *)p->data;
681 return 1;
682 }
683 } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
684 switch (p->data_size) {
685 case sizeof(uint32_t):
686 *val = *(const uint32_t *)p->data;
687 return 1;
688 case sizeof(uint64_t):
689 u64 = *(const uint64_t *)p->data;
690 if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
691 *val = (double)u64;
692 return 1;
693 }
694 break;
695 }
696 } else if (p->data_type == OSSL_PARAM_INTEGER) {
697 switch (p->data_size) {
698 case sizeof(int32_t):
699 *val = *(const int32_t *)p->data;
700 return 1;
701 case sizeof(int64_t):
702 i64 = *(const int64_t *)p->data;
703 u64 = i64 < 0 ? -i64 : i64;
704 if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
705 *val = 0.0 + i64;
706 return 1;
707 }
708 break;
709 }
7ffbd7ca
P
710 }
711 return 0;
712}
713
4e7991b4 714int OSSL_PARAM_set_double(OSSL_PARAM *p, double val)
7ffbd7ca
P
715{
716 if (p == NULL)
717 return 0;
4e7991b4 718 p->return_size = 0;
7ffbd7ca 719
9830e7ea 720 if (p->data_type == OSSL_PARAM_REAL) {
4e7991b4 721 p->return_size = sizeof(double);
8f3b8fd6
RL
722 if (p->data == NULL)
723 return 1;
9830e7ea
P
724 switch (p->data_size) {
725 case sizeof(double):
726 *(double *)p->data = val;
727 return 1;
728 }
729 } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER
c04a9916 730 && val == (ossl_uintmax_t)val) {
4e7991b4 731 p->return_size = sizeof(double);
8f3b8fd6
RL
732 if (p->data == NULL)
733 return 1;
9830e7ea
P
734 switch (p->data_size) {
735 case sizeof(uint32_t):
736 if (val >= 0 && val <= UINT32_MAX) {
4e7991b4 737 p->return_size = sizeof(uint32_t);
9830e7ea
P
738 *(uint32_t *)p->data = (uint32_t)val;
739 return 1;
740 }
741 break;
742 case sizeof(uint64_t):
743 if (val >= 0 && val <= UINT64_MAX) {
4e7991b4 744 p->return_size = sizeof(uint64_t);
9830e7ea
P
745 *(uint64_t *)p->data = (uint64_t)val;
746 return 1;
747 }
748 break; }
c04a9916 749 } else if (p->data_type == OSSL_PARAM_INTEGER && val == (ossl_intmax_t)val) {
4e7991b4 750 p->return_size = sizeof(double);
8f3b8fd6
RL
751 if (p->data == NULL)
752 return 1;
9830e7ea
P
753 switch (p->data_size) {
754 case sizeof(int32_t):
755 if (val >= INT32_MIN && val <= INT32_MAX) {
4e7991b4 756 p->return_size = sizeof(int32_t);
9830e7ea
P
757 *(int32_t *)p->data = (int32_t)val;
758 return 1;
759 }
760 break;
761 case sizeof(int64_t):
762 if (val >= INT64_MIN && val <= INT64_MAX) {
4e7991b4 763 p->return_size = sizeof(int64_t);
9830e7ea
P
764 *(int64_t *)p->data = (int64_t)val;
765 return 1;
766 }
767 break;
768 }
7ffbd7ca
P
769 }
770 return 0;
771}
772
4e7991b4 773OSSL_PARAM OSSL_PARAM_construct_double(const char *key, double *buf)
7ffbd7ca 774{
4e7991b4 775 return ossl_param_construct(key, OSSL_PARAM_REAL, buf, sizeof(double));
7ffbd7ca
P
776}
777
778static int get_string_internal(const OSSL_PARAM *p, void **val, size_t max_len,
779 size_t *used_len, unsigned int type)
780{
781 size_t sz;
782
b756626a 783 if ((val == NULL && used_len == NULL) || p == NULL || p->data_type != type)
7ffbd7ca
P
784 return 0;
785
786 sz = p->data_size;
787
788 if (used_len != NULL)
789 *used_len = sz;
790
86f32187
P
791 if (p->data == NULL)
792 return 0;
46ef075a 793
b756626a
MC
794 if (val == NULL)
795 return 1;
796
7ffbd7ca 797 if (*val == NULL) {
7c302f8a 798 char *const q = OPENSSL_malloc(sz > 0 ? sz : 1);
7ffbd7ca
P
799
800 if (q == NULL)
801 return 0;
802 *val = q;
7c302f8a
BK
803 if (sz != 0)
804 memcpy(q, p->data, sz);
7ffbd7ca
P
805 return 1;
806 }
807 if (max_len < sz)
808 return 0;
809 memcpy(*val, p->data, sz);
810 return 1;
811}
812
813int OSSL_PARAM_get_utf8_string(const OSSL_PARAM *p, char **val, size_t max_len)
814{
815 return get_string_internal(p, (void **)val, max_len, NULL,
816 OSSL_PARAM_UTF8_STRING);
817}
818
819int OSSL_PARAM_get_octet_string(const OSSL_PARAM *p, void **val, size_t max_len,
820 size_t *used_len)
821{
822 return get_string_internal(p, val, max_len, used_len,
823 OSSL_PARAM_OCTET_STRING);
824}
825
4e7991b4 826static int set_string_internal(OSSL_PARAM *p, const void *val, size_t len,
7ffbd7ca
P
827 unsigned int type)
828{
4e7991b4 829 p->return_size = len;
8f3b8fd6
RL
830 if (p->data == NULL)
831 return 1;
7ffbd7ca
P
832 if (p->data_type != type || p->data_size < len)
833 return 0;
834
835 memcpy(p->data, val, len);
836 return 1;
837}
838
4e7991b4 839int OSSL_PARAM_set_utf8_string(OSSL_PARAM *p, const char *val)
7ffbd7ca
P
840{
841 if (p == NULL)
842 return 0;
843
4e7991b4 844 p->return_size = 0;
7ffbd7ca
P
845 if (val == NULL)
846 return 0;
847 return set_string_internal(p, val, strlen(val) + 1, OSSL_PARAM_UTF8_STRING);
848}
849
4e7991b4 850int OSSL_PARAM_set_octet_string(OSSL_PARAM *p, const void *val,
7ffbd7ca
P
851 size_t len)
852{
853 if (p == NULL)
854 return 0;
855
4e7991b4 856 p->return_size = 0;
7ffbd7ca
P
857 if (val == NULL)
858 return 0;
859 return set_string_internal(p, val, len, OSSL_PARAM_OCTET_STRING);
860}
861
862OSSL_PARAM OSSL_PARAM_construct_utf8_string(const char *key, char *buf,
4e7991b4 863 size_t bsize)
7ffbd7ca 864{
7f588d20
P
865 if (buf != NULL && bsize == 0)
866 bsize = strlen(buf) + 1;
4e7991b4 867 return ossl_param_construct(key, OSSL_PARAM_UTF8_STRING, buf, bsize);
7ffbd7ca
P
868}
869
870OSSL_PARAM OSSL_PARAM_construct_octet_string(const char *key, void *buf,
4e7991b4 871 size_t bsize)
7ffbd7ca 872{
4e7991b4 873 return ossl_param_construct(key, OSSL_PARAM_OCTET_STRING, buf, bsize);
7ffbd7ca
P
874}
875
876static int get_ptr_internal(const OSSL_PARAM *p, const void **val,
877 size_t *used_len, unsigned int type)
878{
879 if (val == NULL || p == NULL || p->data_type != type)
880 return 0;
881 if (used_len != NULL)
882 *used_len = p->data_size;
883 *val = *(const void **)p->data;
884 return 1;
885}
886
887int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM *p, const char **val)
888{
889 return get_ptr_internal(p, (const void **)val, NULL, OSSL_PARAM_UTF8_PTR);
890}
891
892int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, const void **val,
893 size_t *used_len)
894{
895 return get_ptr_internal(p, val, used_len, OSSL_PARAM_OCTET_PTR);
896}
897
4e7991b4 898static int set_ptr_internal(OSSL_PARAM *p, const void *val,
7ffbd7ca
P
899 unsigned int type, size_t len)
900{
4e7991b4 901 p->return_size = len;
7ffbd7ca
P
902 if (p->data_type != type)
903 return 0;
8f3b8fd6
RL
904 if (p->data != NULL)
905 *(const void **)p->data = val;
7ffbd7ca
P
906 return 1;
907}
908
4e7991b4 909int OSSL_PARAM_set_utf8_ptr(OSSL_PARAM *p, const char *val)
7ffbd7ca
P
910{
911 if (p == NULL)
912 return 0;
4e7991b4 913 p->return_size = 0;
b3f3ba70
MC
914 return set_ptr_internal(p, val, OSSL_PARAM_UTF8_PTR,
915 val == NULL ? 0 : strlen(val) + 1);
7ffbd7ca
P
916}
917
4e7991b4 918int OSSL_PARAM_set_octet_ptr(OSSL_PARAM *p, const void *val,
7ffbd7ca
P
919 size_t used_len)
920{
921 if (p == NULL)
922 return 0;
4e7991b4 923 p->return_size = 0;
7ffbd7ca
P
924 return set_ptr_internal(p, val, OSSL_PARAM_OCTET_PTR, used_len);
925}
926
927OSSL_PARAM OSSL_PARAM_construct_utf8_ptr(const char *key, char **buf,
4e7991b4 928 size_t bsize)
7ffbd7ca 929{
4e7991b4 930 return ossl_param_construct(key, OSSL_PARAM_UTF8_PTR, buf, bsize);
7ffbd7ca
P
931}
932
933OSSL_PARAM OSSL_PARAM_construct_octet_ptr(const char *key, void **buf,
4e7991b4 934 size_t bsize)
7ffbd7ca 935{
4e7991b4 936 return ossl_param_construct(key, OSSL_PARAM_OCTET_PTR, buf, bsize);
7ffbd7ca 937}
195852fe
RL
938
939OSSL_PARAM OSSL_PARAM_construct_end(void)
940{
941 OSSL_PARAM end = OSSL_PARAM_END;
942
943 return end;
944}