]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/params.c
Params: add OSSL_PARAM_construct_end()
[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{
159 if (val == NULL || p == NULL || (p->data_type != OSSL_PARAM_INTEGER))
160 return 0;
161
162 if (p->data_size == sizeof(int32_t)) {
163 *val = *(const int32_t *)p->data;
164 return 1;
165 }
166 return 0;
167}
168
169int OSSL_PARAM_set_int32(const OSSL_PARAM *p, int32_t val)
170{
171 if (p == NULL)
172 return 0;
173 SET_RETURN_SIZE(p, 0);
174 if (p->data_type != OSSL_PARAM_INTEGER)
175 return 0;
176
177 SET_RETURN_SIZE(p, sizeof(int32_t)); /* Minimum expected size */
178 switch (p->data_size) {
179 case sizeof(int32_t):
180 SET_RETURN_SIZE(p, sizeof(int32_t));
181 *(int32_t *)p->data = val;
182 return 1;
183 case sizeof(int64_t):
184 SET_RETURN_SIZE(p, sizeof(int64_t));
185 *(int64_t *)p->data = (int64_t)val;
186 return 1;
187 }
188 return 0;
189}
190
191OSSL_PARAM OSSL_PARAM_construct_int32(const char *key, int32_t *buf,
192 size_t *rsize)
193{
194 return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf,
195 sizeof(int32_t), rsize);
196}
197
198int OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val)
199{
200 if (val == NULL
201 || p == NULL
202 || (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER))
203 return 0;
204
205 if (p->data_size == sizeof(uint32_t)) {
206 *val = *(const uint32_t *)p->data;
207 return 1;
208 }
209 return 0;
210}
211
212int OSSL_PARAM_set_uint32(const OSSL_PARAM *p, uint32_t val)
213{
214 if (p == NULL) return 0;
215 SET_RETURN_SIZE(p, 0);
216 if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
217 return 0;
218
219 SET_RETURN_SIZE(p, sizeof(uint32_t)); /* Minimum expected size */
220 switch (p->data_size) {
221 case sizeof(uint32_t):
222 SET_RETURN_SIZE(p, sizeof(uint32_t));
223 *(uint32_t *)p->data = val;
224 return 1;
225 case sizeof(uint64_t):
226 SET_RETURN_SIZE(p, sizeof(uint64_t));
227 *(uint64_t *)p->data = (uint64_t)val;
228 return 1;
229 }
230 return 0;
231}
232
233OSSL_PARAM OSSL_PARAM_construct_uint32(const char *key, uint32_t *buf,
234 size_t *rsize)
235{
236 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
237 sizeof(uint32_t), rsize);
238}
239
240int OSSL_PARAM_get_int64(const OSSL_PARAM *p, int64_t *val)
241{
242 if (val == NULL || p == NULL || (p->data_type != OSSL_PARAM_INTEGER))
243 return 0;
244
245 switch (p->data_size) {
246 case sizeof(int32_t):
247 *val = (int64_t)*(const int32_t *)p->data;
248 return 1;
249 case sizeof(int64_t):
250 *val = *(const int64_t *)p->data;
251 return 1;
252 }
253 return 0;
254}
255
256int OSSL_PARAM_set_int64(const OSSL_PARAM *p, int64_t val)
257{
258 if (p == NULL)
259 return 0;
260 SET_RETURN_SIZE(p, 0);
261 if (p->data_type != OSSL_PARAM_INTEGER)
262 return 0;
263
264 SET_RETURN_SIZE(p, sizeof(int64_t)); /* Minimum expected size */
265 switch (p->data_size) {
266 case sizeof(int64_t):
267 SET_RETURN_SIZE(p, sizeof(int64_t));
268 *(int64_t *)p->data = val;
269 return 1;
270 }
271 return 0;
272}
273
274OSSL_PARAM OSSL_PARAM_construct_int64(const char *key, int64_t *buf,
275 size_t *rsize)
276{
277 return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int64_t),
278 rsize);
279}
280
281int OSSL_PARAM_get_uint64(const OSSL_PARAM *p, uint64_t *val)
282{
283 if (val == NULL
284 || p == NULL
285 || (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER))
286 return 0;
287
288 switch (p->data_size) {
289 case sizeof(uint32_t):
290 *val = (uint64_t)*(const uint32_t *)p->data;
291 return 1;
292 case sizeof(uint64_t):
293 *val = *(const uint64_t *)p->data;
294 return 1;
295 }
296 return 0;
297}
298
299int OSSL_PARAM_set_uint64(const OSSL_PARAM *p, uint64_t val)
300{
301 if (p == NULL)
302 return 0;
303 SET_RETURN_SIZE(p, 0);
304 if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
305 return 0;
306
307 SET_RETURN_SIZE(p, sizeof(uint64_t)); /* Minimum expected size */
308 switch (p->data_size) {
309 case sizeof(uint64_t):
310 SET_RETURN_SIZE(p, sizeof(uint64_t));
311 *(uint64_t *)p->data = val;
312 return 1;
313 }
314 return 0;
315}
316
317OSSL_PARAM OSSL_PARAM_construct_uint64(const char *key, uint64_t *buf,
318 size_t *rsize) {
319 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
320 sizeof(uint64_t), rsize);
321}
322
323int OSSL_PARAM_get_size_t(const OSSL_PARAM *p, size_t *val)
324{
863360fb 325 switch (sizeof(size_t)) {
7ffbd7ca 326 case sizeof(uint32_t):
863360fb 327 return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
7ffbd7ca 328 case sizeof(uint64_t):
863360fb 329 return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
7ffbd7ca
P
330 }
331 return 0;
332}
333
334int OSSL_PARAM_set_size_t(const OSSL_PARAM *p, size_t val)
335{
863360fb 336 switch (sizeof(size_t)) {
7ffbd7ca 337 case sizeof(uint32_t):
863360fb 338 return OSSL_PARAM_set_uint32(p, (uint32_t)val);
7ffbd7ca 339 case sizeof(uint64_t):
863360fb 340 return OSSL_PARAM_set_uint64(p, (uint64_t)val);
7ffbd7ca
P
341 }
342 return 0;
343}
344
345OSSL_PARAM OSSL_PARAM_construct_size_t(const char *key, size_t *buf,
346 size_t *rsize)
347{
348 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
349 sizeof(size_t), rsize); }
350
9efa0ae0
MC
351#ifndef FIPS_MODE
352/*
353 * TODO(3.0): Make this available in FIPS mode.
354 *
355 * Temporarily we don't include these functions in FIPS mode to avoid pulling
356 * in the entire BN sub-library into the module at this point.
357 */
7ffbd7ca
P
358int OSSL_PARAM_get_BN(const OSSL_PARAM *p, BIGNUM **val)
359{
360 BIGNUM *b;
361
362 if (val == NULL
363 || p == NULL
364 || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
365 return 0;
366
367 b = BN_native2bn(p->data, (int)p->data_size, *val);
368 if (b != NULL) {
369 *val = b;
370 return 1;
371 }
372 return 0;
373}
374
375int OSSL_PARAM_set_BN(const OSSL_PARAM *p, const BIGNUM *val)
376{
377 size_t bytes;
378
379 if (p == NULL)
380 return 0;
381 SET_RETURN_SIZE(p, 0);
382 if (val == NULL || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
383 return 0;
384
6ce84e64
P
385 /* For the moment, only positive values are permitted */
386 if (BN_is_negative(val))
387 return 0;
388
7ffbd7ca
P
389 bytes = (size_t)BN_num_bytes(val);
390 SET_RETURN_SIZE(p, bytes);
391 return p->data_size >= bytes
392 && BN_bn2nativepad(val, p->data, bytes) >= 0;
393}
394
395OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf,
396 size_t bsize, size_t *rsize)
397{
398 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER,
399 buf, bsize, rsize);
400}
9efa0ae0 401#endif
7ffbd7ca
P
402
403int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val)
404{
405 if (val == NULL || p == NULL || p->data_type != OSSL_PARAM_REAL)
406 return 0;
407
408 switch (p->data_size) {
409 case sizeof(double):
410 *val = *(const double *)p->data;
411 return 1;
412 }
413 return 0;
414}
415
416int OSSL_PARAM_set_double(const OSSL_PARAM *p, double val)
417{
418 if (p == NULL)
419 return 0;
420 SET_RETURN_SIZE(p, 0);
421 if (p->data_type != OSSL_PARAM_REAL)
422 return 0;
423
424 switch (p->data_size) {
425 case sizeof(double):
426 SET_RETURN_SIZE(p, sizeof(double));
427 *(double *)p->data = val;
428 return 1;
429 }
430 return 0;
431}
432
433OSSL_PARAM OSSL_PARAM_construct_double(const char *key, double *buf,
434 size_t *rsize)
435{
436 return ossl_param_construct(key, OSSL_PARAM_REAL, buf, sizeof(double),
437 rsize);
438}
439
440static int get_string_internal(const OSSL_PARAM *p, void **val, size_t max_len,
441 size_t *used_len, unsigned int type)
442{
443 size_t sz;
444
445 if (val == NULL || p == NULL || p->data_type != type)
446 return 0;
447
448 sz = p->data_size;
449
450 if (used_len != NULL)
451 *used_len = sz;
452
453 if (*val == NULL) {
454 char *const q = OPENSSL_malloc(sz);
455
456 if (q == NULL)
457 return 0;
458 *val = q;
459 memcpy(q, p->data, sz);
460 return 1;
461 }
462 if (max_len < sz)
463 return 0;
464 memcpy(*val, p->data, sz);
465 return 1;
466}
467
468int OSSL_PARAM_get_utf8_string(const OSSL_PARAM *p, char **val, size_t max_len)
469{
470 return get_string_internal(p, (void **)val, max_len, NULL,
471 OSSL_PARAM_UTF8_STRING);
472}
473
474int OSSL_PARAM_get_octet_string(const OSSL_PARAM *p, void **val, size_t max_len,
475 size_t *used_len)
476{
477 return get_string_internal(p, val, max_len, used_len,
478 OSSL_PARAM_OCTET_STRING);
479}
480
481static int set_string_internal(const OSSL_PARAM *p, const void *val, size_t len,
482 unsigned int type)
483{
484 SET_RETURN_SIZE(p, len);
485 if (p->data_type != type || p->data_size < len)
486 return 0;
487
488 memcpy(p->data, val, len);
489 return 1;
490}
491
492int OSSL_PARAM_set_utf8_string(const OSSL_PARAM *p, const char *val)
493{
494 if (p == NULL)
495 return 0;
496
497 SET_RETURN_SIZE(p, 0);
498 if (val == NULL)
499 return 0;
500 return set_string_internal(p, val, strlen(val) + 1, OSSL_PARAM_UTF8_STRING);
501}
502
503int OSSL_PARAM_set_octet_string(const OSSL_PARAM *p, const void *val,
504 size_t len)
505{
506 if (p == NULL)
507 return 0;
508
509 SET_RETURN_SIZE(p, 0);
510 if (val == NULL)
511 return 0;
512 return set_string_internal(p, val, len, OSSL_PARAM_OCTET_STRING);
513}
514
515OSSL_PARAM OSSL_PARAM_construct_utf8_string(const char *key, char *buf,
516 size_t bsize, size_t *rsize)
517{
518 return ossl_param_construct(key, OSSL_PARAM_UTF8_STRING, buf, bsize,
519 rsize);
520}
521
522OSSL_PARAM OSSL_PARAM_construct_octet_string(const char *key, void *buf,
523 size_t bsize, size_t *rsize)
524{
525 return ossl_param_construct(key, OSSL_PARAM_OCTET_STRING, buf, bsize,
526 rsize);
527}
528
529static int get_ptr_internal(const OSSL_PARAM *p, const void **val,
530 size_t *used_len, unsigned int type)
531{
532 if (val == NULL || p == NULL || p->data_type != type)
533 return 0;
534 if (used_len != NULL)
535 *used_len = p->data_size;
536 *val = *(const void **)p->data;
537 return 1;
538}
539
540int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM *p, const char **val)
541{
542 return get_ptr_internal(p, (const void **)val, NULL, OSSL_PARAM_UTF8_PTR);
543}
544
545int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, const void **val,
546 size_t *used_len)
547{
548 return get_ptr_internal(p, val, used_len, OSSL_PARAM_OCTET_PTR);
549}
550
551static int set_ptr_internal(const OSSL_PARAM *p, const void *val,
552 unsigned int type, size_t len)
553{
554 SET_RETURN_SIZE(p, len);
555 if (p->data_type != type)
556 return 0;
557 *(const void **)p->data = val;
558 return 1;
559}
560
561int OSSL_PARAM_set_utf8_ptr(const OSSL_PARAM *p, const char *val)
562{
563 if (p == NULL)
564 return 0;
565 SET_RETURN_SIZE(p, 0);
566 if (val == NULL)
567 return 0;
568 return set_ptr_internal(p, val, OSSL_PARAM_UTF8_PTR, strlen(val) + 1);
569}
570
571int OSSL_PARAM_set_octet_ptr(const OSSL_PARAM *p, const void *val,
572 size_t used_len)
573{
574 if (p == NULL)
575 return 0;
576 SET_RETURN_SIZE(p, 0);
577 if (val == NULL)
578 return 0;
579 return set_ptr_internal(p, val, OSSL_PARAM_OCTET_PTR, used_len);
580}
581
582OSSL_PARAM OSSL_PARAM_construct_utf8_ptr(const char *key, char **buf,
583 size_t *rsize)
584{
585 return ossl_param_construct(key, OSSL_PARAM_UTF8_PTR, buf, 0, rsize);
586}
587
588OSSL_PARAM OSSL_PARAM_construct_octet_ptr(const char *key, void **buf,
589 size_t *rsize)
590{
591 return ossl_param_construct(key, OSSL_PARAM_OCTET_PTR, buf, 0, rsize);
592}
195852fe
RL
593
594OSSL_PARAM OSSL_PARAM_construct_end(void)
595{
596 OSSL_PARAM end = OSSL_PARAM_END;
597
598 return end;
599}