2 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
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
12 #include <openssl/params.h>
13 #include "internal/thread_once.h"
15 #define SET_RETURN_SIZE(p, sz) \
16 if ((p)->return_size != NULL) \
17 *(p)->return_size = (sz)
19 const OSSL_PARAM
*OSSL_PARAM_locate(const OSSL_PARAM
*p
, const char *key
)
21 if (p
!= NULL
&& key
!= NULL
)
22 for (; p
->key
!= NULL
; p
++)
23 if (strcmp(key
, p
->key
) == 0)
28 static OSSL_PARAM
ossl_param_construct(const char *key
, unsigned int data_type
,
29 void *data
, size_t data_size
,
35 res
.data_type
= data_type
;
37 res
.data_size
= data_size
;
38 res
.return_size
= return_size
;
42 int OSSL_PARAM_get_int(const OSSL_PARAM
*p
, int *val
)
44 switch (sizeof(int)) {
46 return OSSL_PARAM_get_int32(p
, (int32_t *)val
);
48 return OSSL_PARAM_get_int64(p
, (int64_t *)val
);
53 int OSSL_PARAM_set_int(const OSSL_PARAM
*p
, int val
)
55 switch (sizeof(int)) {
57 return OSSL_PARAM_set_int32(p
, (int32_t)val
);
59 return OSSL_PARAM_set_int64(p
, (int64_t)val
);
64 OSSL_PARAM
OSSL_PARAM_construct_int(const char *key
, int *buf
, size_t *rsize
)
66 return ossl_param_construct(key
, OSSL_PARAM_INTEGER
, buf
, sizeof(int),
70 int OSSL_PARAM_get_uint(const OSSL_PARAM
*p
, unsigned int *val
)
72 switch (sizeof(unsigned int)) {
73 case sizeof(uint32_t):
74 return OSSL_PARAM_get_uint32(p
, (uint32_t *)val
);
75 case sizeof(uint64_t):
76 return OSSL_PARAM_get_uint64(p
, (uint64_t *)val
);
81 int OSSL_PARAM_set_uint(const OSSL_PARAM
*p
, unsigned int val
)
83 switch (sizeof(unsigned int)) {
84 case sizeof(uint32_t):
85 return OSSL_PARAM_set_uint32(p
, (uint32_t)val
);
86 case sizeof(uint64_t):
87 return OSSL_PARAM_set_uint64(p
, (uint64_t)val
);
92 OSSL_PARAM
OSSL_PARAM_construct_uint(const char *key
, unsigned int *buf
,
95 return ossl_param_construct(key
, OSSL_PARAM_UNSIGNED_INTEGER
, buf
,
96 sizeof(unsigned int), rsize
);
99 int OSSL_PARAM_get_long(const OSSL_PARAM
*p
, long int *val
)
101 switch (sizeof(long int)) {
102 case sizeof(int32_t):
103 return OSSL_PARAM_get_int32(p
, (int32_t *)val
);
104 case sizeof(int64_t):
105 return OSSL_PARAM_get_int64(p
, (int64_t *)val
);
110 int OSSL_PARAM_set_long(const OSSL_PARAM
*p
, long int val
)
112 switch (sizeof(long int)) {
113 case sizeof(int32_t):
114 return OSSL_PARAM_set_int32(p
, (int32_t)val
);
115 case sizeof(int64_t):
116 return OSSL_PARAM_set_int64(p
, (int64_t)val
);
121 OSSL_PARAM
OSSL_PARAM_construct_long(const char *key
, long int *buf
,
124 return ossl_param_construct(key
, OSSL_PARAM_INTEGER
, buf
, sizeof(long int),
128 int OSSL_PARAM_get_ulong(const OSSL_PARAM
*p
, unsigned long int *val
)
130 switch (sizeof(unsigned long int)) {
131 case sizeof(uint32_t):
132 return OSSL_PARAM_get_uint32(p
, (uint32_t *)val
);
133 case sizeof(uint64_t):
134 return OSSL_PARAM_get_uint64(p
, (uint64_t *)val
);
139 int OSSL_PARAM_set_ulong(const OSSL_PARAM
*p
, unsigned long int val
)
141 switch (sizeof(unsigned long int)) {
142 case sizeof(uint32_t):
143 return OSSL_PARAM_set_uint32(p
, (uint32_t)val
);
144 case sizeof(uint64_t):
145 return OSSL_PARAM_set_uint64(p
, (uint64_t)val
);
150 OSSL_PARAM
OSSL_PARAM_construct_ulong(const char *key
, unsigned long int *buf
,
153 return ossl_param_construct(key
, OSSL_PARAM_UNSIGNED_INTEGER
, buf
,
154 sizeof(unsigned long int), rsize
);
157 int OSSL_PARAM_get_int32(const OSSL_PARAM
*p
, int32_t *val
)
159 if (val
== NULL
|| p
== NULL
|| (p
->data_type
!= OSSL_PARAM_INTEGER
))
162 if (p
->data_size
== sizeof(int32_t)) {
163 *val
= *(const int32_t *)p
->data
;
169 int OSSL_PARAM_set_int32(const OSSL_PARAM
*p
, int32_t val
)
173 SET_RETURN_SIZE(p
, 0);
174 if (p
->data_type
!= OSSL_PARAM_INTEGER
)
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
;
183 case sizeof(int64_t):
184 SET_RETURN_SIZE(p
, sizeof(int64_t));
185 *(int64_t *)p
->data
= (int64_t)val
;
191 OSSL_PARAM
OSSL_PARAM_construct_int32(const char *key
, int32_t *buf
,
194 return ossl_param_construct(key
, OSSL_PARAM_INTEGER
, buf
,
195 sizeof(int32_t), rsize
);
198 int OSSL_PARAM_get_uint32(const OSSL_PARAM
*p
, uint32_t *val
)
202 || (p
->data_type
!= OSSL_PARAM_UNSIGNED_INTEGER
))
205 if (p
->data_size
== sizeof(uint32_t)) {
206 *val
= *(const uint32_t *)p
->data
;
212 int OSSL_PARAM_set_uint32(const OSSL_PARAM
*p
, uint32_t val
)
214 if (p
== NULL
) return 0;
215 SET_RETURN_SIZE(p
, 0);
216 if (p
->data_type
!= OSSL_PARAM_UNSIGNED_INTEGER
)
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
;
225 case sizeof(uint64_t):
226 SET_RETURN_SIZE(p
, sizeof(uint64_t));
227 *(uint64_t *)p
->data
= (uint64_t)val
;
233 OSSL_PARAM
OSSL_PARAM_construct_uint32(const char *key
, uint32_t *buf
,
236 return ossl_param_construct(key
, OSSL_PARAM_UNSIGNED_INTEGER
, buf
,
237 sizeof(uint32_t), rsize
);
240 int OSSL_PARAM_get_int64(const OSSL_PARAM
*p
, int64_t *val
)
242 if (val
== NULL
|| p
== NULL
|| (p
->data_type
!= OSSL_PARAM_INTEGER
))
245 switch (p
->data_size
) {
246 case sizeof(int32_t):
247 *val
= (int64_t)*(const int32_t *)p
->data
;
249 case sizeof(int64_t):
250 *val
= *(const int64_t *)p
->data
;
256 int OSSL_PARAM_set_int64(const OSSL_PARAM
*p
, int64_t val
)
260 SET_RETURN_SIZE(p
, 0);
261 if (p
->data_type
!= OSSL_PARAM_INTEGER
)
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
;
274 OSSL_PARAM
OSSL_PARAM_construct_int64(const char *key
, int64_t *buf
,
277 return ossl_param_construct(key
, OSSL_PARAM_INTEGER
, buf
, sizeof(int64_t),
281 int OSSL_PARAM_get_uint64(const OSSL_PARAM
*p
, uint64_t *val
)
285 || (p
->data_type
!= OSSL_PARAM_UNSIGNED_INTEGER
))
288 switch (p
->data_size
) {
289 case sizeof(uint32_t):
290 *val
= (uint64_t)*(const uint32_t *)p
->data
;
292 case sizeof(uint64_t):
293 *val
= *(const uint64_t *)p
->data
;
299 int OSSL_PARAM_set_uint64(const OSSL_PARAM
*p
, uint64_t val
)
303 SET_RETURN_SIZE(p
, 0);
304 if (p
->data_type
!= OSSL_PARAM_UNSIGNED_INTEGER
)
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
;
317 OSSL_PARAM
OSSL_PARAM_construct_uint64(const char *key
, uint64_t *buf
,
319 return ossl_param_construct(key
, OSSL_PARAM_UNSIGNED_INTEGER
, buf
,
320 sizeof(uint64_t), rsize
);
323 int OSSL_PARAM_get_size_t(const OSSL_PARAM
*p
, size_t *val
)
325 switch (sizeof(size_t)) {
326 case sizeof(uint32_t):
327 return OSSL_PARAM_get_uint32(p
, (uint32_t *)val
);
328 case sizeof(uint64_t):
329 return OSSL_PARAM_get_uint64(p
, (uint64_t *)val
);
334 int OSSL_PARAM_set_size_t(const OSSL_PARAM
*p
, size_t val
)
336 switch (sizeof(size_t)) {
337 case sizeof(uint32_t):
338 return OSSL_PARAM_set_uint32(p
, (uint32_t)val
);
339 case sizeof(uint64_t):
340 return OSSL_PARAM_set_uint64(p
, (uint64_t)val
);
345 OSSL_PARAM
OSSL_PARAM_construct_size_t(const char *key
, size_t *buf
,
348 return ossl_param_construct(key
, OSSL_PARAM_UNSIGNED_INTEGER
, buf
,
349 sizeof(size_t), rsize
); }
353 * TODO(3.0): Make this available in FIPS mode.
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.
358 int OSSL_PARAM_get_BN(const OSSL_PARAM
*p
, BIGNUM
**val
)
364 || p
->data_type
!= OSSL_PARAM_UNSIGNED_INTEGER
)
367 b
= BN_native2bn(p
->data
, (int)p
->data_size
, *val
);
375 int OSSL_PARAM_set_BN(const OSSL_PARAM
*p
, const BIGNUM
*val
)
381 SET_RETURN_SIZE(p
, 0);
382 if (val
== NULL
|| p
->data_type
!= OSSL_PARAM_UNSIGNED_INTEGER
)
385 /* For the moment, only positive values are permitted */
386 if (BN_is_negative(val
))
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;
395 OSSL_PARAM
OSSL_PARAM_construct_BN(const char *key
, unsigned char *buf
,
396 size_t bsize
, size_t *rsize
)
398 return ossl_param_construct(key
, OSSL_PARAM_UNSIGNED_INTEGER
,
403 int OSSL_PARAM_get_double(const OSSL_PARAM
*p
, double *val
)
405 if (val
== NULL
|| p
== NULL
|| p
->data_type
!= OSSL_PARAM_REAL
)
408 switch (p
->data_size
) {
410 *val
= *(const double *)p
->data
;
416 int OSSL_PARAM_set_double(const OSSL_PARAM
*p
, double val
)
420 SET_RETURN_SIZE(p
, 0);
421 if (p
->data_type
!= OSSL_PARAM_REAL
)
424 switch (p
->data_size
) {
426 SET_RETURN_SIZE(p
, sizeof(double));
427 *(double *)p
->data
= val
;
433 OSSL_PARAM
OSSL_PARAM_construct_double(const char *key
, double *buf
,
436 return ossl_param_construct(key
, OSSL_PARAM_REAL
, buf
, sizeof(double),
440 static int get_string_internal(const OSSL_PARAM
*p
, void **val
, size_t max_len
,
441 size_t *used_len
, unsigned int type
)
445 if (val
== NULL
|| p
== NULL
|| p
->data_type
!= type
)
450 if (used_len
!= NULL
)
454 char *const q
= OPENSSL_malloc(sz
);
459 memcpy(q
, p
->data
, sz
);
464 memcpy(*val
, p
->data
, sz
);
468 int OSSL_PARAM_get_utf8_string(const OSSL_PARAM
*p
, char **val
, size_t max_len
)
470 return get_string_internal(p
, (void **)val
, max_len
, NULL
,
471 OSSL_PARAM_UTF8_STRING
);
474 int OSSL_PARAM_get_octet_string(const OSSL_PARAM
*p
, void **val
, size_t max_len
,
477 return get_string_internal(p
, val
, max_len
, used_len
,
478 OSSL_PARAM_OCTET_STRING
);
481 static int set_string_internal(const OSSL_PARAM
*p
, const void *val
, size_t len
,
484 SET_RETURN_SIZE(p
, len
);
485 if (p
->data_type
!= type
|| p
->data_size
< len
)
488 memcpy(p
->data
, val
, len
);
492 int OSSL_PARAM_set_utf8_string(const OSSL_PARAM
*p
, const char *val
)
497 SET_RETURN_SIZE(p
, 0);
500 return set_string_internal(p
, val
, strlen(val
) + 1, OSSL_PARAM_UTF8_STRING
);
503 int OSSL_PARAM_set_octet_string(const OSSL_PARAM
*p
, const void *val
,
509 SET_RETURN_SIZE(p
, 0);
512 return set_string_internal(p
, val
, len
, OSSL_PARAM_OCTET_STRING
);
515 OSSL_PARAM
OSSL_PARAM_construct_utf8_string(const char *key
, char *buf
,
516 size_t bsize
, size_t *rsize
)
518 return ossl_param_construct(key
, OSSL_PARAM_UTF8_STRING
, buf
, bsize
,
522 OSSL_PARAM
OSSL_PARAM_construct_octet_string(const char *key
, void *buf
,
523 size_t bsize
, size_t *rsize
)
525 return ossl_param_construct(key
, OSSL_PARAM_OCTET_STRING
, buf
, bsize
,
529 static int get_ptr_internal(const OSSL_PARAM
*p
, const void **val
,
530 size_t *used_len
, unsigned int type
)
532 if (val
== NULL
|| p
== NULL
|| p
->data_type
!= type
)
534 if (used_len
!= NULL
)
535 *used_len
= p
->data_size
;
536 *val
= *(const void **)p
->data
;
540 int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM
*p
, const char **val
)
542 return get_ptr_internal(p
, (const void **)val
, NULL
, OSSL_PARAM_UTF8_PTR
);
545 int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM
*p
, const void **val
,
548 return get_ptr_internal(p
, val
, used_len
, OSSL_PARAM_OCTET_PTR
);
551 static int set_ptr_internal(const OSSL_PARAM
*p
, const void *val
,
552 unsigned int type
, size_t len
)
554 SET_RETURN_SIZE(p
, len
);
555 if (p
->data_type
!= type
)
557 *(const void **)p
->data
= val
;
561 int OSSL_PARAM_set_utf8_ptr(const OSSL_PARAM
*p
, const char *val
)
565 SET_RETURN_SIZE(p
, 0);
568 return set_ptr_internal(p
, val
, OSSL_PARAM_UTF8_PTR
, strlen(val
) + 1);
571 int OSSL_PARAM_set_octet_ptr(const OSSL_PARAM
*p
, const void *val
,
576 SET_RETURN_SIZE(p
, 0);
579 return set_ptr_internal(p
, val
, OSSL_PARAM_OCTET_PTR
, used_len
);
582 OSSL_PARAM
OSSL_PARAM_construct_utf8_ptr(const char *key
, char **buf
,
583 size_t bsize
, size_t *rsize
)
585 return ossl_param_construct(key
, OSSL_PARAM_UTF8_PTR
, buf
, bsize
, rsize
);
588 OSSL_PARAM
OSSL_PARAM_construct_octet_ptr(const char *key
, void **buf
,
589 size_t bsize
, size_t *rsize
)
591 return ossl_param_construct(key
, OSSL_PARAM_OCTET_PTR
, buf
, bsize
, rsize
);
594 OSSL_PARAM
OSSL_PARAM_construct_end(void)
596 OSSL_PARAM end
= OSSL_PARAM_END
;