]>
Commit | Line | Data |
---|---|---|
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 | ||
19 | const 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 | ||
28 | static 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 | ||
42 | int 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 | ||
53 | int 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 | ||
64 | OSSL_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 | ||
70 | int 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 | ||
81 | int 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 | ||
92 | OSSL_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 | ||
99 | int 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 | ||
110 | int 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 | ||
121 | OSSL_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 | ||
128 | int 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 | ||
139 | int 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 | ||
150 | OSSL_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 | ||
157 | int OSSL_PARAM_get_int32(const OSSL_PARAM *p, int32_t *val) | |
158 | { | |
9830e7ea P |
159 | int64_t i64; |
160 | uint32_t u32; | |
161 | uint64_t u64; | |
162 | double d; | |
163 | ||
164 | if (val == NULL || p == NULL ) | |
7ffbd7ca P |
165 | return 0; |
166 | ||
9830e7ea P |
167 | if (p->data_type == OSSL_PARAM_INTEGER) { |
168 | switch (p->data_size) { | |
169 | case sizeof(int32_t): | |
170 | *val = *(const int32_t *)p->data; | |
171 | return 1; | |
172 | case sizeof(int64_t): | |
173 | i64 = *(const int64_t *)p->data; | |
174 | if (i64 >= INT32_MIN && i64 <= INT32_MAX) { | |
175 | *val = (int32_t)i64; | |
176 | return 1; | |
177 | } | |
178 | break; | |
179 | } | |
180 | } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { | |
181 | switch (p->data_size) { | |
182 | case sizeof(uint32_t): | |
183 | u32 = *(const uint32_t *)p->data; | |
184 | if (u32 <= INT32_MAX) { | |
185 | *val = (int32_t)u32; | |
186 | return 1; | |
187 | } | |
188 | break; | |
189 | case sizeof(uint64_t): | |
190 | u64 = *(const uint64_t *)p->data; | |
191 | if (u64 <= INT32_MAX) { | |
192 | *val = (int32_t)u64; | |
193 | return 1; | |
194 | } | |
195 | break; | |
196 | } | |
197 | } else if (p->data_type == OSSL_PARAM_REAL) { | |
198 | switch (p->data_size) { | |
199 | case sizeof(double): | |
200 | d = *(const double *)p->data; | |
201 | if (d >= INT32_MIN && d <= INT32_MAX && d == (int32_t)d) { | |
202 | *val = (int32_t)d; | |
203 | return 1; | |
204 | } | |
205 | break; | |
206 | } | |
7ffbd7ca P |
207 | } |
208 | return 0; | |
209 | } | |
210 | ||
211 | int OSSL_PARAM_set_int32(const OSSL_PARAM *p, int32_t val) | |
212 | { | |
213 | if (p == NULL) | |
214 | return 0; | |
215 | SET_RETURN_SIZE(p, 0); | |
9830e7ea P |
216 | if (p->data_type == OSSL_PARAM_INTEGER) { |
217 | SET_RETURN_SIZE(p, sizeof(int32_t)); /* Minimum expected size */ | |
218 | switch (p->data_size) { | |
219 | case sizeof(int32_t): | |
220 | *(int32_t *)p->data = val; | |
221 | return 1; | |
222 | case sizeof(int64_t): | |
223 | SET_RETURN_SIZE(p, sizeof(int64_t)); | |
224 | *(int64_t *)p->data = (int64_t)val; | |
225 | return 1; | |
226 | } | |
227 | } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) { | |
228 | SET_RETURN_SIZE(p, sizeof(uint32_t)); /* Minimum expected size */ | |
229 | switch (p->data_size) { | |
230 | case sizeof(uint32_t): | |
231 | *(uint32_t *)p->data = (uint32_t)val; | |
232 | return 1; | |
233 | case sizeof(uint64_t): | |
234 | SET_RETURN_SIZE(p, sizeof(uint64_t)); | |
235 | *(uint64_t *)p->data = (uint64_t)val; | |
236 | return 1; | |
237 | } | |
238 | } else if (p->data_type == OSSL_PARAM_REAL) { | |
239 | SET_RETURN_SIZE(p, sizeof(double)); | |
240 | switch (p->data_size) { | |
241 | case sizeof(double): | |
242 | *(double *)p->data = (double)val; | |
243 | return 1; | |
244 | } | |
7ffbd7ca P |
245 | } |
246 | return 0; | |
247 | } | |
248 | ||
249 | OSSL_PARAM OSSL_PARAM_construct_int32(const char *key, int32_t *buf, | |
250 | size_t *rsize) | |
251 | { | |
252 | return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, | |
253 | sizeof(int32_t), rsize); | |
254 | } | |
255 | ||
256 | int OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val) | |
257 | { | |
9830e7ea P |
258 | int32_t i32; |
259 | int64_t i64; | |
260 | uint64_t u64; | |
261 | double d; | |
262 | ||
263 | if (val == NULL || p == NULL) | |
7ffbd7ca P |
264 | return 0; |
265 | ||
9830e7ea P |
266 | if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { |
267 | switch (p->data_size) { | |
268 | case sizeof(uint32_t): | |
269 | *val = *(const uint32_t *)p->data; | |
270 | return 1; | |
271 | case sizeof(uint64_t): | |
272 | u64 = *(const uint64_t *)p->data; | |
273 | if (u64 <= UINT32_MAX) { | |
274 | *val = (uint32_t)u64; | |
275 | return 1; | |
276 | } | |
277 | break; | |
278 | } | |
279 | } else if (p->data_type == OSSL_PARAM_INTEGER) { | |
280 | switch (p->data_size) { | |
281 | case sizeof(int32_t): | |
282 | i32 = *(const int32_t *)p->data; | |
283 | if (i32 >= 0) { | |
284 | *val = i32; | |
285 | return 1; | |
286 | } | |
287 | break; | |
288 | case sizeof(int64_t): | |
289 | i64 = *(const int64_t *)p->data; | |
290 | if (i64 >= 0 && i64 <= UINT32_MAX) { | |
291 | *val = (uint32_t)i64; | |
292 | return 1; | |
293 | } | |
294 | break; | |
295 | } | |
296 | } else if (p->data_type == OSSL_PARAM_REAL) { | |
297 | switch (p->data_size) { | |
298 | case sizeof(double): | |
299 | d = *(const double *)p->data; | |
300 | if (d >= 0 && d <= UINT32_MAX && d == (uint32_t)d) { | |
301 | *val = (uint32_t)d; | |
302 | return 1; | |
303 | } | |
304 | break; | |
305 | } | |
7ffbd7ca P |
306 | } |
307 | return 0; | |
308 | } | |
309 | ||
310 | int OSSL_PARAM_set_uint32(const OSSL_PARAM *p, uint32_t val) | |
311 | { | |
9830e7ea | 312 | if (p == NULL) |
7ffbd7ca | 313 | return 0; |
9830e7ea | 314 | SET_RETURN_SIZE(p, 0); |
7ffbd7ca | 315 | |
9830e7ea P |
316 | if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { |
317 | SET_RETURN_SIZE(p, sizeof(uint32_t)); /* Minimum expected size */ | |
318 | switch (p->data_size) { | |
319 | case sizeof(uint32_t): | |
320 | *(uint32_t *)p->data = val; | |
321 | return 1; | |
322 | case sizeof(uint64_t): | |
323 | SET_RETURN_SIZE(p, sizeof(uint64_t)); | |
324 | *(uint64_t *)p->data = val; | |
325 | return 1; | |
326 | } | |
327 | } else if (p->data_type == OSSL_PARAM_INTEGER) { | |
328 | SET_RETURN_SIZE(p, sizeof(int32_t)); /* Minimum expected size */ | |
329 | switch (p->data_size) { | |
330 | case sizeof(int32_t): | |
331 | if (val <= INT32_MAX) { | |
332 | *(int32_t *)p->data = (int32_t)val; | |
333 | return 1; | |
334 | } | |
335 | break; | |
336 | case sizeof(int64_t): | |
337 | SET_RETURN_SIZE(p, sizeof(int64_t)); | |
338 | *(int64_t *)p->data = (int64_t)val; | |
339 | return 1; | |
340 | } | |
341 | } else if (p->data_type == OSSL_PARAM_REAL) { | |
342 | SET_RETURN_SIZE(p, sizeof(double)); | |
343 | switch (p->data_size) { | |
344 | case sizeof(double): | |
345 | *(double *)p->data = (double)val; | |
346 | return 1; | |
347 | } | |
7ffbd7ca P |
348 | } |
349 | return 0; | |
350 | } | |
351 | ||
352 | OSSL_PARAM OSSL_PARAM_construct_uint32(const char *key, uint32_t *buf, | |
353 | size_t *rsize) | |
354 | { | |
355 | return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf, | |
356 | sizeof(uint32_t), rsize); | |
357 | } | |
358 | ||
359 | int OSSL_PARAM_get_int64(const OSSL_PARAM *p, int64_t *val) | |
360 | { | |
9830e7ea P |
361 | uint64_t u64; |
362 | double d; | |
363 | ||
364 | if (val == NULL || p == NULL ) | |
7ffbd7ca P |
365 | return 0; |
366 | ||
9830e7ea P |
367 | if (p->data_type == OSSL_PARAM_INTEGER) { |
368 | switch (p->data_size) { | |
369 | case sizeof(int32_t): | |
370 | *val = *(const int32_t *)p->data; | |
371 | return 1; | |
372 | case sizeof(int64_t): | |
373 | *val = *(const int64_t *)p->data; | |
374 | return 1; | |
375 | } | |
376 | } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { | |
377 | switch (p->data_size) { | |
378 | case sizeof(uint32_t): | |
379 | *val = *(const uint32_t *)p->data; | |
380 | return 1; | |
381 | case sizeof(uint64_t): | |
382 | u64 = *(const uint64_t *)p->data; | |
383 | if (u64 <= INT64_MAX) { | |
384 | *val = (int64_t)u64; | |
385 | return 1; | |
386 | } | |
387 | break; | |
388 | } | |
389 | } else if (p->data_type == OSSL_PARAM_REAL) { | |
390 | switch (p->data_size) { | |
391 | case sizeof(double): | |
392 | d = *(const double *)p->data; | |
393 | if (d >= INT64_MIN && d <= INT64_MAX && d == (int64_t)d) { | |
394 | *val = (int64_t)d; | |
395 | return 1; | |
396 | } | |
397 | break; | |
398 | } | |
7ffbd7ca P |
399 | } |
400 | return 0; | |
401 | } | |
402 | ||
403 | int OSSL_PARAM_set_int64(const OSSL_PARAM *p, int64_t val) | |
404 | { | |
9830e7ea P |
405 | uint64_t u64; |
406 | ||
7ffbd7ca P |
407 | if (p == NULL) |
408 | return 0; | |
409 | SET_RETURN_SIZE(p, 0); | |
9830e7ea P |
410 | if (p->data_type == OSSL_PARAM_INTEGER) { |
411 | SET_RETURN_SIZE(p, sizeof(int64_t)); /* Expected size */ | |
412 | switch (p->data_size) { | |
413 | case sizeof(int32_t): | |
414 | if (val >= INT32_MIN && val <= INT32_MAX) { | |
415 | SET_RETURN_SIZE(p, sizeof(int32_t)); | |
416 | *(int32_t *)p->data = (int32_t)val; | |
417 | return 1; | |
418 | } | |
419 | break; | |
420 | case sizeof(int64_t): | |
421 | *(int64_t *)p->data = val; | |
422 | return 1; | |
423 | } | |
424 | } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) { | |
425 | SET_RETURN_SIZE(p, sizeof(uint64_t)); /* Expected size */ | |
426 | switch (p->data_size) { | |
427 | case sizeof(uint32_t): | |
428 | if (val <= UINT32_MAX) { | |
429 | SET_RETURN_SIZE(p, sizeof(uint32_t)); | |
430 | *(uint32_t *)p->data = (uint32_t)val; | |
431 | return 1; | |
432 | } | |
433 | break; | |
434 | case sizeof(uint64_t): | |
435 | *(uint64_t *)p->data = (uint64_t)val; | |
436 | return 1; | |
437 | } | |
438 | } else if (p->data_type == OSSL_PARAM_REAL) { | |
439 | SET_RETURN_SIZE(p, sizeof(double)); | |
440 | switch (p->data_size) { | |
441 | case sizeof(double): | |
442 | u64 = val < 0 ? -val : val; | |
443 | if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */ | |
444 | *(double *)p->data = (double)val; | |
445 | return 1; | |
446 | } | |
447 | break; | |
448 | } | |
7ffbd7ca P |
449 | } |
450 | return 0; | |
451 | } | |
452 | ||
453 | OSSL_PARAM OSSL_PARAM_construct_int64(const char *key, int64_t *buf, | |
454 | size_t *rsize) | |
455 | { | |
456 | return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int64_t), | |
457 | rsize); | |
458 | } | |
459 | ||
460 | int OSSL_PARAM_get_uint64(const OSSL_PARAM *p, uint64_t *val) | |
461 | { | |
9830e7ea P |
462 | int32_t i32; |
463 | int64_t i64; | |
464 | double d; | |
465 | ||
466 | if (val == NULL || p == NULL) | |
7ffbd7ca P |
467 | return 0; |
468 | ||
9830e7ea P |
469 | if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { |
470 | switch (p->data_size) { | |
471 | case sizeof(uint32_t): | |
472 | *val = *(const uint32_t *)p->data; | |
473 | return 1; | |
474 | case sizeof(uint64_t): | |
475 | *val = *(const uint64_t *)p->data; | |
476 | return 1; | |
477 | } | |
478 | } else if (p->data_type == OSSL_PARAM_INTEGER) { | |
479 | switch (p->data_size) { | |
480 | case sizeof(int32_t): | |
481 | i32 = *(const int32_t *)p->data; | |
482 | if (i32 >= 0) { | |
483 | *val = (uint64_t)i32; | |
484 | return 1; | |
485 | } | |
486 | break; | |
487 | case sizeof(int64_t): | |
488 | i64 = *(const int64_t *)p->data; | |
489 | if (i64 >= 0) { | |
490 | *val = (uint64_t)i64; | |
491 | return 1; | |
492 | } | |
493 | break; | |
494 | } | |
495 | } else if (p->data_type == OSSL_PARAM_REAL) { | |
496 | switch (p->data_size) { | |
497 | case sizeof(double): | |
498 | d = *(const double *)p->data; | |
499 | if (d >= 0 && d <= INT64_MAX && d == (uint64_t)d) { | |
500 | *val = (uint64_t)d; | |
501 | return 1; | |
502 | } | |
503 | break; | |
504 | } | |
7ffbd7ca P |
505 | } |
506 | return 0; | |
507 | } | |
508 | ||
509 | int OSSL_PARAM_set_uint64(const OSSL_PARAM *p, uint64_t val) | |
510 | { | |
511 | if (p == NULL) | |
512 | return 0; | |
513 | SET_RETURN_SIZE(p, 0); | |
7ffbd7ca | 514 | |
9830e7ea P |
515 | if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { |
516 | SET_RETURN_SIZE(p, sizeof(uint64_t)); /* Expected size */ | |
517 | switch (p->data_size) { | |
518 | case sizeof(uint32_t): | |
519 | if (val <= UINT32_MAX) { | |
520 | SET_RETURN_SIZE(p, sizeof(uint32_t)); | |
521 | *(uint32_t *)p->data = (uint32_t)val; | |
522 | return 1; | |
523 | } | |
524 | break; | |
525 | case sizeof(uint64_t): | |
526 | *(uint64_t *)p->data = val; | |
527 | return 1; | |
528 | } | |
529 | } else if (p->data_type == OSSL_PARAM_INTEGER) { | |
530 | SET_RETURN_SIZE(p, sizeof(int64_t)); /* Expected size */ | |
531 | switch (p->data_size) { | |
532 | case sizeof(int32_t): | |
533 | if (val <= INT32_MAX) { | |
534 | SET_RETURN_SIZE(p, sizeof(int32_t)); | |
535 | *(int32_t *)p->data = (int32_t)val; | |
536 | return 1; | |
537 | } | |
538 | break; | |
539 | case sizeof(int64_t): | |
540 | if (val <= INT64_MAX) { | |
541 | *(int64_t *)p->data = (int64_t)val; | |
542 | return 1; | |
543 | } | |
544 | break; | |
545 | } | |
546 | } else if (p->data_type == OSSL_PARAM_REAL) { | |
547 | SET_RETURN_SIZE(p, sizeof(double)); | |
548 | switch (p->data_size) { | |
549 | case sizeof(double): | |
550 | if ((val >> 53) == 0) { /* 53 significant bits in the mantissa */ | |
551 | *(double *)p->data = (double)val; | |
552 | return 1; | |
553 | } | |
554 | break; | |
555 | } | |
7ffbd7ca P |
556 | } |
557 | return 0; | |
558 | } | |
559 | ||
560 | OSSL_PARAM OSSL_PARAM_construct_uint64(const char *key, uint64_t *buf, | |
561 | size_t *rsize) { | |
562 | return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf, | |
563 | sizeof(uint64_t), rsize); | |
564 | } | |
565 | ||
566 | int OSSL_PARAM_get_size_t(const OSSL_PARAM *p, size_t *val) | |
567 | { | |
863360fb | 568 | switch (sizeof(size_t)) { |
7ffbd7ca | 569 | case sizeof(uint32_t): |
863360fb | 570 | return OSSL_PARAM_get_uint32(p, (uint32_t *)val); |
7ffbd7ca | 571 | case sizeof(uint64_t): |
863360fb | 572 | return OSSL_PARAM_get_uint64(p, (uint64_t *)val); |
7ffbd7ca P |
573 | } |
574 | return 0; | |
575 | } | |
576 | ||
577 | int OSSL_PARAM_set_size_t(const OSSL_PARAM *p, size_t val) | |
578 | { | |
863360fb | 579 | switch (sizeof(size_t)) { |
7ffbd7ca | 580 | case sizeof(uint32_t): |
863360fb | 581 | return OSSL_PARAM_set_uint32(p, (uint32_t)val); |
7ffbd7ca | 582 | case sizeof(uint64_t): |
863360fb | 583 | return OSSL_PARAM_set_uint64(p, (uint64_t)val); |
7ffbd7ca P |
584 | } |
585 | return 0; | |
586 | } | |
587 | ||
588 | OSSL_PARAM OSSL_PARAM_construct_size_t(const char *key, size_t *buf, | |
589 | size_t *rsize) | |
590 | { | |
591 | return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf, | |
592 | sizeof(size_t), rsize); } | |
593 | ||
9efa0ae0 MC |
594 | #ifndef FIPS_MODE |
595 | /* | |
596 | * TODO(3.0): Make this available in FIPS mode. | |
597 | * | |
598 | * Temporarily we don't include these functions in FIPS mode to avoid pulling | |
599 | * in the entire BN sub-library into the module at this point. | |
600 | */ | |
7ffbd7ca P |
601 | int OSSL_PARAM_get_BN(const OSSL_PARAM *p, BIGNUM **val) |
602 | { | |
603 | BIGNUM *b; | |
604 | ||
605 | if (val == NULL | |
606 | || p == NULL | |
607 | || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER) | |
608 | return 0; | |
609 | ||
610 | b = BN_native2bn(p->data, (int)p->data_size, *val); | |
611 | if (b != NULL) { | |
612 | *val = b; | |
613 | return 1; | |
614 | } | |
615 | return 0; | |
616 | } | |
617 | ||
618 | int OSSL_PARAM_set_BN(const OSSL_PARAM *p, const BIGNUM *val) | |
619 | { | |
620 | size_t bytes; | |
621 | ||
622 | if (p == NULL) | |
623 | return 0; | |
624 | SET_RETURN_SIZE(p, 0); | |
625 | if (val == NULL || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER) | |
626 | return 0; | |
627 | ||
6ce84e64 P |
628 | /* For the moment, only positive values are permitted */ |
629 | if (BN_is_negative(val)) | |
630 | return 0; | |
631 | ||
7ffbd7ca P |
632 | bytes = (size_t)BN_num_bytes(val); |
633 | SET_RETURN_SIZE(p, bytes); | |
634 | return p->data_size >= bytes | |
635 | && BN_bn2nativepad(val, p->data, bytes) >= 0; | |
636 | } | |
637 | ||
638 | OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf, | |
639 | size_t bsize, size_t *rsize) | |
640 | { | |
641 | return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, | |
642 | buf, bsize, rsize); | |
643 | } | |
9efa0ae0 | 644 | #endif |
7ffbd7ca P |
645 | |
646 | int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val) | |
647 | { | |
9830e7ea P |
648 | int64_t i64; |
649 | uint64_t u64; | |
650 | ||
651 | if (val == NULL || p == NULL) | |
7ffbd7ca P |
652 | return 0; |
653 | ||
9830e7ea P |
654 | if (p->data_type == OSSL_PARAM_REAL) { |
655 | switch (p->data_size) { | |
656 | case sizeof(double): | |
657 | *val = *(const double *)p->data; | |
658 | return 1; | |
659 | } | |
660 | } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { | |
661 | switch (p->data_size) { | |
662 | case sizeof(uint32_t): | |
663 | *val = *(const uint32_t *)p->data; | |
664 | return 1; | |
665 | case sizeof(uint64_t): | |
666 | u64 = *(const uint64_t *)p->data; | |
667 | if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */ | |
668 | *val = (double)u64; | |
669 | return 1; | |
670 | } | |
671 | break; | |
672 | } | |
673 | } else if (p->data_type == OSSL_PARAM_INTEGER) { | |
674 | switch (p->data_size) { | |
675 | case sizeof(int32_t): | |
676 | *val = *(const int32_t *)p->data; | |
677 | return 1; | |
678 | case sizeof(int64_t): | |
679 | i64 = *(const int64_t *)p->data; | |
680 | u64 = i64 < 0 ? -i64 : i64; | |
681 | if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */ | |
682 | *val = 0.0 + i64; | |
683 | return 1; | |
684 | } | |
685 | break; | |
686 | } | |
7ffbd7ca P |
687 | } |
688 | return 0; | |
689 | } | |
690 | ||
691 | int OSSL_PARAM_set_double(const OSSL_PARAM *p, double val) | |
692 | { | |
693 | if (p == NULL) | |
694 | return 0; | |
695 | SET_RETURN_SIZE(p, 0); | |
7ffbd7ca | 696 | |
9830e7ea | 697 | if (p->data_type == OSSL_PARAM_REAL) { |
7ffbd7ca | 698 | SET_RETURN_SIZE(p, sizeof(double)); |
9830e7ea P |
699 | switch (p->data_size) { |
700 | case sizeof(double): | |
701 | *(double *)p->data = val; | |
702 | return 1; | |
703 | } | |
704 | } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER | |
705 | && val == (uintmax_t)val) { | |
706 | SET_RETURN_SIZE(p, sizeof(double)); | |
707 | switch (p->data_size) { | |
708 | case sizeof(uint32_t): | |
709 | if (val >= 0 && val <= UINT32_MAX) { | |
710 | SET_RETURN_SIZE(p, sizeof(uint32_t)); | |
711 | *(uint32_t *)p->data = (uint32_t)val; | |
712 | return 1; | |
713 | } | |
714 | break; | |
715 | case sizeof(uint64_t): | |
716 | if (val >= 0 && val <= UINT64_MAX) { | |
717 | SET_RETURN_SIZE(p, sizeof(uint64_t)); | |
718 | *(uint64_t *)p->data = (uint64_t)val; | |
719 | return 1; | |
720 | } | |
721 | break; } | |
722 | } else if (p->data_type == OSSL_PARAM_INTEGER && val == (intmax_t)val) { | |
723 | SET_RETURN_SIZE(p, sizeof(double)); | |
724 | switch (p->data_size) { | |
725 | case sizeof(int32_t): | |
726 | if (val >= INT32_MIN && val <= INT32_MAX) { | |
727 | SET_RETURN_SIZE(p, sizeof(int32_t)); | |
728 | *(int32_t *)p->data = (int32_t)val; | |
729 | return 1; | |
730 | } | |
731 | break; | |
732 | case sizeof(int64_t): | |
733 | if (val >= INT64_MIN && val <= INT64_MAX) { | |
734 | SET_RETURN_SIZE(p, sizeof(int64_t)); | |
735 | *(int64_t *)p->data = (int64_t)val; | |
736 | return 1; | |
737 | } | |
738 | break; | |
739 | } | |
7ffbd7ca P |
740 | } |
741 | return 0; | |
742 | } | |
743 | ||
744 | OSSL_PARAM OSSL_PARAM_construct_double(const char *key, double *buf, | |
745 | size_t *rsize) | |
746 | { | |
747 | return ossl_param_construct(key, OSSL_PARAM_REAL, buf, sizeof(double), | |
748 | rsize); | |
749 | } | |
750 | ||
751 | static int get_string_internal(const OSSL_PARAM *p, void **val, size_t max_len, | |
752 | size_t *used_len, unsigned int type) | |
753 | { | |
754 | size_t sz; | |
755 | ||
756 | if (val == NULL || p == NULL || p->data_type != type) | |
757 | return 0; | |
758 | ||
759 | sz = p->data_size; | |
760 | ||
761 | if (used_len != NULL) | |
762 | *used_len = sz; | |
763 | ||
764 | if (*val == NULL) { | |
765 | char *const q = OPENSSL_malloc(sz); | |
766 | ||
767 | if (q == NULL) | |
768 | return 0; | |
769 | *val = q; | |
770 | memcpy(q, p->data, sz); | |
771 | return 1; | |
772 | } | |
773 | if (max_len < sz) | |
774 | return 0; | |
775 | memcpy(*val, p->data, sz); | |
776 | return 1; | |
777 | } | |
778 | ||
779 | int OSSL_PARAM_get_utf8_string(const OSSL_PARAM *p, char **val, size_t max_len) | |
780 | { | |
781 | return get_string_internal(p, (void **)val, max_len, NULL, | |
782 | OSSL_PARAM_UTF8_STRING); | |
783 | } | |
784 | ||
785 | int OSSL_PARAM_get_octet_string(const OSSL_PARAM *p, void **val, size_t max_len, | |
786 | size_t *used_len) | |
787 | { | |
788 | return get_string_internal(p, val, max_len, used_len, | |
789 | OSSL_PARAM_OCTET_STRING); | |
790 | } | |
791 | ||
792 | static int set_string_internal(const OSSL_PARAM *p, const void *val, size_t len, | |
793 | unsigned int type) | |
794 | { | |
795 | SET_RETURN_SIZE(p, len); | |
796 | if (p->data_type != type || p->data_size < len) | |
797 | return 0; | |
798 | ||
799 | memcpy(p->data, val, len); | |
800 | return 1; | |
801 | } | |
802 | ||
803 | int OSSL_PARAM_set_utf8_string(const OSSL_PARAM *p, const char *val) | |
804 | { | |
805 | if (p == NULL) | |
806 | return 0; | |
807 | ||
808 | SET_RETURN_SIZE(p, 0); | |
809 | if (val == NULL) | |
810 | return 0; | |
811 | return set_string_internal(p, val, strlen(val) + 1, OSSL_PARAM_UTF8_STRING); | |
812 | } | |
813 | ||
814 | int OSSL_PARAM_set_octet_string(const OSSL_PARAM *p, const void *val, | |
815 | size_t len) | |
816 | { | |
817 | if (p == NULL) | |
818 | return 0; | |
819 | ||
820 | SET_RETURN_SIZE(p, 0); | |
821 | if (val == NULL) | |
822 | return 0; | |
823 | return set_string_internal(p, val, len, OSSL_PARAM_OCTET_STRING); | |
824 | } | |
825 | ||
826 | OSSL_PARAM OSSL_PARAM_construct_utf8_string(const char *key, char *buf, | |
827 | size_t bsize, size_t *rsize) | |
828 | { | |
829 | return ossl_param_construct(key, OSSL_PARAM_UTF8_STRING, buf, bsize, | |
830 | rsize); | |
831 | } | |
832 | ||
833 | OSSL_PARAM OSSL_PARAM_construct_octet_string(const char *key, void *buf, | |
834 | size_t bsize, size_t *rsize) | |
835 | { | |
836 | return ossl_param_construct(key, OSSL_PARAM_OCTET_STRING, buf, bsize, | |
837 | rsize); | |
838 | } | |
839 | ||
840 | static int get_ptr_internal(const OSSL_PARAM *p, const void **val, | |
841 | size_t *used_len, unsigned int type) | |
842 | { | |
843 | if (val == NULL || p == NULL || p->data_type != type) | |
844 | return 0; | |
845 | if (used_len != NULL) | |
846 | *used_len = p->data_size; | |
847 | *val = *(const void **)p->data; | |
848 | return 1; | |
849 | } | |
850 | ||
851 | int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM *p, const char **val) | |
852 | { | |
853 | return get_ptr_internal(p, (const void **)val, NULL, OSSL_PARAM_UTF8_PTR); | |
854 | } | |
855 | ||
856 | int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, const void **val, | |
857 | size_t *used_len) | |
858 | { | |
859 | return get_ptr_internal(p, val, used_len, OSSL_PARAM_OCTET_PTR); | |
860 | } | |
861 | ||
862 | static int set_ptr_internal(const OSSL_PARAM *p, const void *val, | |
863 | unsigned int type, size_t len) | |
864 | { | |
865 | SET_RETURN_SIZE(p, len); | |
866 | if (p->data_type != type) | |
867 | return 0; | |
868 | *(const void **)p->data = val; | |
869 | return 1; | |
870 | } | |
871 | ||
872 | int OSSL_PARAM_set_utf8_ptr(const OSSL_PARAM *p, const char *val) | |
873 | { | |
874 | if (p == NULL) | |
875 | return 0; | |
876 | SET_RETURN_SIZE(p, 0); | |
877 | if (val == NULL) | |
878 | return 0; | |
879 | return set_ptr_internal(p, val, OSSL_PARAM_UTF8_PTR, strlen(val) + 1); | |
880 | } | |
881 | ||
882 | int OSSL_PARAM_set_octet_ptr(const OSSL_PARAM *p, const void *val, | |
883 | size_t used_len) | |
884 | { | |
885 | if (p == NULL) | |
886 | return 0; | |
887 | SET_RETURN_SIZE(p, 0); | |
888 | if (val == NULL) | |
889 | return 0; | |
890 | return set_ptr_internal(p, val, OSSL_PARAM_OCTET_PTR, used_len); | |
891 | } | |
892 | ||
893 | OSSL_PARAM OSSL_PARAM_construct_utf8_ptr(const char *key, char **buf, | |
f55ed701 | 894 | size_t bsize, size_t *rsize) |
7ffbd7ca | 895 | { |
f55ed701 | 896 | return ossl_param_construct(key, OSSL_PARAM_UTF8_PTR, buf, bsize, rsize); |
7ffbd7ca P |
897 | } |
898 | ||
899 | OSSL_PARAM OSSL_PARAM_construct_octet_ptr(const char *key, void **buf, | |
f55ed701 | 900 | size_t bsize, size_t *rsize) |
7ffbd7ca | 901 | { |
f55ed701 | 902 | return ossl_param_construct(key, OSSL_PARAM_OCTET_PTR, buf, bsize, rsize); |
7ffbd7ca | 903 | } |
195852fe RL |
904 | |
905 | OSSL_PARAM OSSL_PARAM_construct_end(void) | |
906 | { | |
907 | OSSL_PARAM end = OSSL_PARAM_END; | |
908 | ||
909 | return end; | |
910 | } |