]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/params.c
evp: convert existing code to use the new modified sentinel for params.
[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
48void OSSL_PARAM_set_unmodified(OSSL_PARAM *p)
49{
50 if (p != NULL)
51 p->return_size = OSSL_PARAM_UNMODIFIED;
52}
53
7ffbd7ca
P
54int 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 65int 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 76OSSL_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
81int 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 92int 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 103OSSL_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
109int 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 120int 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 131OSSL_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
136int 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 147int 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 158OSSL_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
164int 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 218int 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 262OSSL_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
268int 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 322int 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 370OSSL_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
376int 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 420int 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 476OSSL_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
481int 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 530int 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
585OSSL_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
591int 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 602int 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 613OSSL_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
619int 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 636int 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
661OSSL_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
668int 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 713int 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 772OSSL_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
777static 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
810int 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
816int 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 823static 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 836int 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 847int 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
859OSSL_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
867OSSL_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
873static 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
884int 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
889int 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 895static 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 906int 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 915int 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
924OSSL_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
930OSSL_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
936OSSL_PARAM OSSL_PARAM_construct_end(void)
937{
938 OSSL_PARAM end = OSSL_PARAM_END;
939
940 return end;
941}