Coverage Report

Created: 2025-07-23 06:08

/src/openssl/crypto/params.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2019-2025 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 <openssl/err.h>
14
#include "internal/thread_once.h"
15
#include "internal/numbers.h"
16
#include "internal/endian.h"
17
#include "internal/params.h"
18
#include "internal/packet.h"
19
#include "internal/common.h"
20
21
/* Shortcuts for raising errors that are widely used */
22
#define err_unsigned_negative \
23
0
    ERR_raise(ERR_LIB_CRYPTO, \
24
0
              CRYPTO_R_PARAM_UNSIGNED_INTEGER_NEGATIVE_VALUE_UNSUPPORTED)
25
#define err_out_of_range      \
26
6
    ERR_raise(ERR_LIB_CRYPTO, \
27
0
              CRYPTO_R_PARAM_VALUE_TOO_LARGE_FOR_DESTINATION)
28
#define err_inexact           \
29
0
    ERR_raise(ERR_LIB_CRYPTO, \
30
0
              CRYPTO_R_PARAM_CANNOT_BE_REPRESENTED_EXACTLY)
31
#define err_not_integer       \
32
0
    ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_PARAM_NOT_INTEGER_TYPE)
33
#define err_too_small         \
34
0
    ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_SMALL_BUFFER)
35
#define err_bad_type          \
36
1.31k
    ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_PARAM_OF_INCOMPATIBLE_TYPE)
37
#define err_null_argument     \
38
0
    ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER)
39
#define err_unsupported_real  \
40
0
    ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_PARAM_UNSUPPORTED_FLOATING_POINT_FORMAT)
41
42
#ifndef OPENSSL_SYS_UEFI
43
/*
44
 * Return the number of bits in the mantissa of a double.  This is used to
45
 * shift a larger integral value to determine if it will exactly fit into a
46
 * double.
47
 */
48
static unsigned int real_shift(void)
49
0
{
50
0
    return sizeof(double) == 4 ? 24 : 53;
51
0
}
52
#endif
53
54
OSSL_PARAM *OSSL_PARAM_locate(OSSL_PARAM *p, const char *key)
55
140
{
56
140
    if (ossl_likely(p != NULL && key != NULL))
57
1.13k
        for (; p->key != NULL; p++)
58
995
            if (strcmp(key, p->key) == 0)
59
0
                return p;
60
140
    return NULL;
61
140
}
62
63
const OSSL_PARAM *OSSL_PARAM_locate_const(const OSSL_PARAM *p, const char *key)
64
130
{
65
130
    return OSSL_PARAM_locate((OSSL_PARAM *)p, key);
66
130
}
67
68
static OSSL_PARAM ossl_param_construct(const char *key, unsigned int data_type,
69
                                       void *data, size_t data_size)
70
1.30k
{
71
1.30k
    OSSL_PARAM res;
72
73
1.30k
    res.key = key;
74
1.30k
    res.data_type = data_type;
75
1.30k
    res.data = data;
76
1.30k
    res.data_size = data_size;
77
1.30k
    res.return_size = OSSL_PARAM_UNMODIFIED;
78
1.30k
    return res;
79
1.30k
}
80
81
int OSSL_PARAM_modified(const OSSL_PARAM *p)
82
3
{
83
3
    return p != NULL && p->return_size != OSSL_PARAM_UNMODIFIED;
84
3
}
85
86
void OSSL_PARAM_set_all_unmodified(OSSL_PARAM *p)
87
0
{
88
0
    if (p != NULL)
89
0
        while (p->key != NULL)
90
0
            p++->return_size = OSSL_PARAM_UNMODIFIED;
91
0
}
92
93
/* Return non-zero if the signed number is negative */
94
static int is_negative(const void *number, size_t s)
95
0
{
96
0
    const unsigned char *n = number;
97
0
    DECLARE_IS_ENDIAN;
98
99
0
    return 0x80 & (IS_BIG_ENDIAN ? n[0] : n[s - 1]);
100
0
}
101
102
/* Check that all the bytes specified match the expected sign byte */
103
static int check_sign_bytes(const unsigned char *p, size_t n, unsigned char s)
104
0
{
105
0
    size_t i;
106
107
0
    for (i = 0; i < n; i++)
108
0
        if (p[i] != s)
109
0
            return 0;
110
0
    return 1;
111
0
}
112
113
/*
114
 * Copy an integer to another integer.
115
 * Handle different length integers and signed and unsigned integers.
116
 * Both integers are in native byte ordering.
117
 */
118
static int copy_integer(unsigned char *dest, size_t dest_len,
119
                        const unsigned char *src, size_t src_len,
120
                        unsigned char pad, int signed_int)
121
0
{
122
0
    size_t n;
123
0
    DECLARE_IS_ENDIAN;
124
125
0
    if (IS_BIG_ENDIAN) {
126
0
        if (src_len < dest_len) {
127
0
            n = dest_len - src_len;
128
0
            memset(dest, pad, n);
129
0
            memcpy(dest + n, src, src_len);
130
0
        } else {
131
0
            n = src_len - dest_len;
132
0
            if (!check_sign_bytes(src, n, pad)
133
                    /*
134
                     * Shortening a signed value must retain the correct sign.
135
                     * Avoiding this kind of thing: -253 = 0xff03 -> 0x03 = 3
136
                     */
137
0
                    || (signed_int && ((pad ^ src[n]) & 0x80) != 0)) {
138
0
                err_out_of_range;
139
0
                return 0;
140
0
            }
141
0
            memcpy(dest, src + n, dest_len);
142
0
        }
143
0
    } else /* IS_LITTLE_ENDIAN */ {
144
0
        if (src_len < dest_len) {
145
0
            n = dest_len - src_len;
146
0
            memset(dest + src_len, pad, n);
147
0
            memcpy(dest, src, src_len);
148
0
        } else {
149
0
            n = src_len - dest_len;
150
0
            if (!check_sign_bytes(src + dest_len, n, pad)
151
                    /*
152
                     * Shortening a signed value must retain the correct sign.
153
                     * Avoiding this kind of thing: 130 = 0x0082 -> 0x82 = -126
154
                     */
155
0
                    || (signed_int && ((pad ^ src[dest_len - 1]) & 0x80) != 0)) {
156
0
                err_out_of_range;
157
0
                return 0;
158
0
            }
159
0
            memcpy(dest, src, dest_len);
160
0
        }
161
0
    }
162
0
    return 1;
163
0
}
164
165
/* Copy a signed number to a signed number of possibly different length */
166
static int signed_from_signed(void *dest, size_t dest_len,
167
                              const void *src, size_t src_len)
168
0
{
169
0
    return copy_integer(dest, dest_len, src, src_len,
170
0
                        is_negative(src, src_len) ? 0xff : 0, 1);
171
0
}
172
173
/* Copy an unsigned number to a signed number of possibly different length */
174
static int signed_from_unsigned(void *dest, size_t dest_len,
175
                                const void *src, size_t src_len)
176
0
{
177
0
    return copy_integer(dest, dest_len, src, src_len, 0, 1);
178
0
}
179
180
/* Copy a signed number to an unsigned number of possibly different length */
181
static int unsigned_from_signed(void *dest, size_t dest_len,
182
                                const void *src, size_t src_len)
183
0
{
184
0
    if (is_negative(src, src_len)) {
185
0
        err_unsigned_negative;
186
0
        return 0;
187
0
    }
188
0
    return copy_integer(dest, dest_len, src, src_len, 0, 0);
189
0
}
190
191
/* Copy an unsigned number to an unsigned number of possibly different length */
192
static int unsigned_from_unsigned(void *dest, size_t dest_len,
193
                                  const void *src, size_t src_len)
194
0
{
195
0
    return copy_integer(dest, dest_len, src, src_len, 0, 0);
196
0
}
197
198
/* General purpose get integer parameter call that handles odd sizes */
199
static int general_get_int(const OSSL_PARAM *p, void *val, size_t val_size)
200
0
{
201
0
    if (p->data == NULL) {
202
0
        err_null_argument;
203
0
        return 0;
204
0
    }
205
0
    if (p->data_type == OSSL_PARAM_INTEGER)
206
0
        return signed_from_signed(val, val_size, p->data, p->data_size);
207
0
    if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER)
208
0
        return signed_from_unsigned(val, val_size, p->data, p->data_size);
209
0
    err_not_integer;
210
0
    return 0;
211
0
}
212
213
/* General purpose set integer parameter call that handles odd sizes */
214
static int general_set_int(OSSL_PARAM *p, void *val, size_t val_size)
215
0
{
216
0
    int r = 0;
217
218
0
    if (p->data == NULL) {
219
0
        p->return_size = val_size; /* Expected size */
220
0
        return 1;
221
0
    }
222
0
    if (p->data_type == OSSL_PARAM_INTEGER)
223
0
        r = signed_from_signed(p->data, p->data_size, val, val_size);
224
0
    else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER)
225
0
        r = unsigned_from_signed(p->data, p->data_size, val, val_size);
226
0
    else
227
0
        err_not_integer;
228
0
    p->return_size = r ? p->data_size : val_size;
229
0
    return r;
230
0
}
231
232
/* General purpose get unsigned integer parameter call that handles odd sizes */
233
static int general_get_uint(const OSSL_PARAM *p, void *val, size_t val_size)
234
0
{
235
236
0
    if (p->data == NULL) {
237
0
        err_null_argument;
238
0
        return 0;
239
0
    }
240
0
    if (p->data_type == OSSL_PARAM_INTEGER)
241
0
        return unsigned_from_signed(val, val_size, p->data, p->data_size);
242
0
    if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER)
243
0
        return unsigned_from_unsigned(val, val_size, p->data, p->data_size);
244
0
    err_not_integer;
245
0
    return 0;
246
0
}
247
248
/* General purpose set unsigned integer parameter call that handles odd sizes */
249
static int general_set_uint(OSSL_PARAM *p, void *val, size_t val_size)
250
0
{
251
0
    int r = 0;
252
253
0
    if (p->data == NULL) {
254
0
        p->return_size = val_size; /* Expected size */
255
0
        return 1;
256
0
    }
257
0
    if (p->data_type == OSSL_PARAM_INTEGER)
258
0
        r = signed_from_unsigned(p->data, p->data_size, val, val_size);
259
0
    else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER)
260
0
        r = unsigned_from_unsigned(p->data, p->data_size, val, val_size);
261
0
    else
262
0
        err_not_integer;
263
0
    p->return_size = r ? p->data_size : val_size;
264
0
    return r;
265
0
}
266
267
int OSSL_PARAM_get_int(const OSSL_PARAM *p, int *val)
268
6
{
269
6
#ifndef OPENSSL_SMALL_FOOTPRINT
270
6
    switch (sizeof(int)) {
271
6
    case sizeof(int32_t):
272
6
        return OSSL_PARAM_get_int32(p, (int32_t *)val);
273
0
    case sizeof(int64_t):
274
0
        return OSSL_PARAM_get_int64(p, (int64_t *)val);
275
6
    }
276
0
#endif
277
0
    return general_get_int(p, val, sizeof(*val));
278
6
}
279
280
int OSSL_PARAM_set_int(OSSL_PARAM *p, int val)
281
780
{
282
780
#ifndef OPENSSL_SMALL_FOOTPRINT
283
780
    switch (sizeof(int)) {
284
780
    case sizeof(int32_t):
285
780
        return OSSL_PARAM_set_int32(p, (int32_t)val);
286
0
    case sizeof(int64_t):
287
0
        return OSSL_PARAM_set_int64(p, (int64_t)val);
288
780
    }
289
0
#endif
290
0
    return general_set_int(p, &val, sizeof(val));
291
780
}
292
293
OSSL_PARAM OSSL_PARAM_construct_int(const char *key, int *buf)
294
780
{
295
780
    return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int));
296
780
}
297
298
int OSSL_PARAM_get_uint(const OSSL_PARAM *p, unsigned int *val)
299
3
{
300
3
#ifndef OPENSSL_SMALL_FOOTPRINT
301
3
    switch (sizeof(unsigned int)) {
302
3
    case sizeof(uint32_t):
303
3
        return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
304
0
    case sizeof(uint64_t):
305
0
        return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
306
3
    }
307
0
#endif
308
0
    return general_get_uint(p, val, sizeof(*val));
309
3
}
310
311
int OSSL_PARAM_set_uint(OSSL_PARAM *p, unsigned int val)
312
130
{
313
130
#ifndef OPENSSL_SMALL_FOOTPRINT
314
130
    switch (sizeof(unsigned int)) {
315
130
    case sizeof(uint32_t):
316
130
        return OSSL_PARAM_set_uint32(p, (uint32_t)val);
317
0
    case sizeof(uint64_t):
318
0
        return OSSL_PARAM_set_uint64(p, (uint64_t)val);
319
130
    }
320
0
#endif
321
0
    return general_set_uint(p, &val, sizeof(val));
322
130
}
323
324
OSSL_PARAM OSSL_PARAM_construct_uint(const char *key, unsigned int *buf)
325
133
{
326
133
    return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
327
133
                                sizeof(unsigned int));
328
133
}
329
330
int OSSL_PARAM_get_long(const OSSL_PARAM *p, long int *val)
331
0
{
332
0
#ifndef OPENSSL_SMALL_FOOTPRINT
333
0
    switch (sizeof(long int)) {
334
0
    case sizeof(int32_t):
335
0
        return OSSL_PARAM_get_int32(p, (int32_t *)val);
336
0
    case sizeof(int64_t):
337
0
        return OSSL_PARAM_get_int64(p, (int64_t *)val);
338
0
    }
339
0
#endif
340
0
    return general_get_int(p, val, sizeof(*val));
341
0
}
342
343
int OSSL_PARAM_set_long(OSSL_PARAM *p, long int val)
344
0
{
345
0
#ifndef OPENSSL_SMALL_FOOTPRINT
346
0
    switch (sizeof(long int)) {
347
0
    case sizeof(int32_t):
348
0
        return OSSL_PARAM_set_int32(p, (int32_t)val);
349
0
    case sizeof(int64_t):
350
0
        return OSSL_PARAM_set_int64(p, (int64_t)val);
351
0
    }
352
0
#endif
353
0
    return general_set_int(p, &val, sizeof(val));
354
0
}
355
356
OSSL_PARAM OSSL_PARAM_construct_long(const char *key, long int *buf)
357
0
{
358
0
    return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(long int));
359
0
}
360
361
int OSSL_PARAM_get_ulong(const OSSL_PARAM *p, unsigned long int *val)
362
0
{
363
0
#ifndef OPENSSL_SMALL_FOOTPRINT
364
0
    switch (sizeof(unsigned long int)) {
365
0
    case sizeof(uint32_t):
366
0
        return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
367
0
    case sizeof(uint64_t):
368
0
        return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
369
0
    }
370
0
#endif
371
0
    return general_get_uint(p, val, sizeof(*val));
372
0
}
373
374
int OSSL_PARAM_set_ulong(OSSL_PARAM *p, unsigned long int val)
375
0
{
376
0
#ifndef OPENSSL_SMALL_FOOTPRINT
377
0
    switch (sizeof(unsigned long int)) {
378
0
    case sizeof(uint32_t):
379
0
        return OSSL_PARAM_set_uint32(p, (uint32_t)val);
380
0
    case sizeof(uint64_t):
381
0
        return OSSL_PARAM_set_uint64(p, (uint64_t)val);
382
0
    }
383
0
#endif
384
0
    return general_set_uint(p, &val, sizeof(val));
385
0
}
386
387
OSSL_PARAM OSSL_PARAM_construct_ulong(const char *key, unsigned long int *buf)
388
0
{
389
0
    return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
390
0
                                sizeof(unsigned long int));
391
0
}
392
393
int OSSL_PARAM_get_int32(const OSSL_PARAM *p, int32_t *val)
394
6
{
395
6
    if (val == NULL || p == NULL) {
396
0
        err_null_argument;
397
0
        return 0;
398
0
    }
399
400
6
    if (p->data == NULL) {
401
0
        err_null_argument;
402
0
        return 0;
403
0
    }
404
405
6
    if (p->data_type == OSSL_PARAM_INTEGER) {
406
0
#ifndef OPENSSL_SMALL_FOOTPRINT
407
0
        int64_t i64;
408
409
0
        switch (p->data_size) {
410
0
        case sizeof(int32_t):
411
0
            *val = *(const int32_t *)p->data;
412
0
            return 1;
413
0
        case sizeof(int64_t):
414
0
            i64 = *(const int64_t *)p->data;
415
0
            if (i64 >= INT32_MIN && i64 <= INT32_MAX) {
416
0
                *val = (int32_t)i64;
417
0
                return 1;
418
0
            }
419
0
            err_out_of_range;
420
0
            return 0;
421
0
        }
422
0
#endif
423
0
        return general_get_int(p, val, sizeof(*val));
424
425
6
    } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
426
6
#ifndef OPENSSL_SMALL_FOOTPRINT
427
6
        uint32_t u32;
428
6
        uint64_t u64;
429
430
6
        switch (p->data_size) {
431
0
        case sizeof(uint32_t):
432
0
            u32 = *(const uint32_t *)p->data;
433
0
            if (u32 <= INT32_MAX) {
434
0
                *val = (int32_t)u32;
435
0
                return 1;
436
0
            }
437
0
            err_out_of_range;
438
0
            return 0;
439
6
        case sizeof(uint64_t):
440
6
            u64 = *(const uint64_t *)p->data;
441
6
            if (u64 <= INT32_MAX) {
442
6
                *val = (int32_t)u64;
443
6
                return 1;
444
6
            }
445
0
            err_out_of_range;
446
0
            return 0;
447
6
        }
448
0
#endif
449
0
        return general_get_int(p, val, sizeof(*val));
450
451
6
    } else if (p->data_type == OSSL_PARAM_REAL) {
452
0
#ifndef OPENSSL_SYS_UEFI
453
0
        double d;
454
455
0
        switch (p->data_size) {
456
0
        case sizeof(double):
457
0
            d = *(const double *)p->data;
458
0
            if (d >= INT32_MIN && d <= INT32_MAX && d == (int32_t)d) {
459
0
                *val = (int32_t)d;
460
0
                return 1;
461
0
            }
462
0
            err_out_of_range;
463
0
            return 0;
464
0
        }
465
0
        err_unsupported_real;
466
0
        return 0;
467
0
#endif
468
0
    }
469
0
    err_bad_type;
470
0
    return 0;
471
6
}
472
473
int OSSL_PARAM_set_int32(OSSL_PARAM *p, int32_t val)
474
780
{
475
780
    if (p == NULL) {
476
0
        err_null_argument;
477
0
        return 0;
478
0
    }
479
780
    p->return_size = 0;
480
780
    if (p->data_type == OSSL_PARAM_INTEGER) {
481
780
#ifndef OPENSSL_SMALL_FOOTPRINT
482
780
        p->return_size = sizeof(int32_t); /* Minimum expected size */
483
780
        if (p->data == NULL)
484
0
            return 1;
485
780
        switch (p->data_size) {
486
780
        case sizeof(int32_t):
487
780
            *(int32_t *)p->data = val;
488
780
            return 1;
489
0
        case sizeof(int64_t):
490
0
            p->return_size = sizeof(int64_t);
491
0
            *(int64_t *)p->data = (int64_t)val;
492
0
            return 1;
493
780
        }
494
0
#endif
495
0
        return general_set_int(p, &val, sizeof(val));
496
780
    } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) {
497
0
#ifndef OPENSSL_SMALL_FOOTPRINT
498
0
        p->return_size = sizeof(uint32_t); /* Minimum expected size */
499
0
        if (p->data == NULL)
500
0
            return 1;
501
0
        switch (p->data_size) {
502
0
        case sizeof(uint32_t):
503
0
            *(uint32_t *)p->data = (uint32_t)val;
504
0
            return 1;
505
0
        case sizeof(uint64_t):
506
0
            p->return_size = sizeof(uint64_t);
507
0
            *(uint64_t *)p->data = (uint64_t)val;
508
0
            return 1;
509
0
        }
510
0
#endif
511
0
        return general_set_int(p, &val, sizeof(val));
512
0
    } else if (p->data_type == OSSL_PARAM_REAL) {
513
0
#ifndef OPENSSL_SYS_UEFI
514
0
        uint32_t u32;
515
0
        unsigned int shift;
516
517
0
        p->return_size = sizeof(double);
518
0
        if (p->data == NULL)
519
0
            return 1;
520
0
        switch (p->data_size) {
521
0
        case sizeof(double):
522
0
            shift = real_shift();
523
0
            if (shift < 8 * sizeof(val) - 1) {
524
0
                u32 = val < 0 ? -val : val;
525
0
                if ((u32 >> shift) != 0) {
526
0
                    err_inexact;
527
0
                    return 0;
528
0
                }
529
0
            }
530
0
            *(double *)p->data = (double)val;
531
0
            return 1;
532
0
        }
533
0
        err_unsupported_real;
534
0
        return 0;
535
0
#endif
536
0
    }
537
0
    err_bad_type;
538
0
    return 0;
539
780
}
540
541
OSSL_PARAM OSSL_PARAM_construct_int32(const char *key, int32_t *buf)
542
0
{
543
0
    return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf,
544
0
                                sizeof(int32_t));
545
0
}
546
547
int OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val)
548
3
{
549
3
    if (val == NULL || p == NULL) {
550
0
        err_null_argument;
551
0
        return 0;
552
0
    }
553
554
3
    if (p->data == NULL) {
555
0
        err_null_argument;
556
0
        return 0;
557
0
    }
558
559
3
    if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
560
3
#ifndef OPENSSL_SMALL_FOOTPRINT
561
3
        uint64_t u64;
562
563
3
        switch (p->data_size) {
564
3
        case sizeof(uint32_t):
565
3
            *val = *(const uint32_t *)p->data;
566
3
            return 1;
567
0
        case sizeof(uint64_t):
568
0
            u64 = *(const uint64_t *)p->data;
569
0
            if (u64 <= UINT32_MAX) {
570
0
                *val = (uint32_t)u64;
571
0
                return 1;
572
0
            }
573
0
            err_out_of_range;
574
0
            return 0;
575
3
        }
576
0
#endif
577
0
        return general_get_uint(p, val, sizeof(*val));
578
3
    } else if (p->data_type == OSSL_PARAM_INTEGER) {
579
0
#ifndef OPENSSL_SMALL_FOOTPRINT
580
0
        int32_t i32;
581
0
        int64_t i64;
582
583
0
        switch (p->data_size) {
584
0
        case sizeof(int32_t):
585
0
            i32 = *(const int32_t *)p->data;
586
0
            if (i32 >= 0) {
587
0
                *val = i32;
588
0
                return 1;
589
0
            }
590
0
            err_unsigned_negative;
591
0
            return 0;
592
0
        case sizeof(int64_t):
593
0
            i64 = *(const int64_t *)p->data;
594
0
            if (i64 >= 0 && i64 <= UINT32_MAX) {
595
0
                *val = (uint32_t)i64;
596
0
                return 1;
597
0
            }
598
0
            if (i64 < 0)
599
0
                err_unsigned_negative;
600
0
            else
601
0
                err_out_of_range;
602
0
            return 0;
603
0
        }
604
0
#endif
605
0
        return general_get_uint(p, val, sizeof(*val));
606
0
    } else if (p->data_type == OSSL_PARAM_REAL) {
607
0
#ifndef OPENSSL_SYS_UEFI
608
0
        double d;
609
610
0
        switch (p->data_size) {
611
0
        case sizeof(double):
612
0
            d = *(const double *)p->data;
613
0
            if (d >= 0 && d <= UINT32_MAX && d == (uint32_t)d) {
614
0
                *val = (uint32_t)d;
615
0
                return 1;
616
0
            }
617
0
            err_inexact;
618
0
            return 0;
619
0
        }
620
0
        err_unsupported_real;
621
0
        return 0;
622
0
#endif
623
0
    }
624
0
    err_bad_type;
625
0
    return 0;
626
3
}
627
628
int OSSL_PARAM_set_uint32(OSSL_PARAM *p, uint32_t val)
629
130
{
630
130
    if (p == NULL) {
631
0
        err_null_argument;
632
0
        return 0;
633
0
    }
634
130
    p->return_size = 0;
635
636
130
    if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
637
130
#ifndef OPENSSL_SMALL_FOOTPRINT
638
130
        p->return_size = sizeof(uint32_t); /* Minimum expected size */
639
130
        if (p->data == NULL)
640
0
            return 1;
641
130
        switch (p->data_size) {
642
130
        case sizeof(uint32_t):
643
130
            *(uint32_t *)p->data = val;
644
130
            return 1;
645
0
        case sizeof(uint64_t):
646
0
            p->return_size = sizeof(uint64_t);
647
0
            *(uint64_t *)p->data = val;
648
0
            return 1;
649
130
        }
650
0
#endif
651
0
        return general_set_uint(p, &val, sizeof(val));
652
130
    } else if (p->data_type == OSSL_PARAM_INTEGER) {
653
0
#ifndef OPENSSL_SMALL_FOOTPRINT
654
0
        p->return_size = sizeof(int32_t); /* Minimum expected size */
655
0
        if (p->data == NULL)
656
0
            return 1;
657
0
        switch (p->data_size) {
658
0
        case sizeof(int32_t):
659
0
            if (val <= INT32_MAX) {
660
0
                *(int32_t *)p->data = (int32_t)val;
661
0
                return 1;
662
0
            }
663
0
            err_out_of_range;
664
0
            return 0;
665
0
        case sizeof(int64_t):
666
0
            p->return_size = sizeof(int64_t);
667
0
            *(int64_t *)p->data = (int64_t)val;
668
0
            return 1;
669
0
        }
670
0
#endif
671
0
        return general_set_uint(p, &val, sizeof(val));
672
0
    } else if (p->data_type == OSSL_PARAM_REAL) {
673
0
#ifndef OPENSSL_SYS_UEFI
674
0
        unsigned int shift;
675
676
0
        if (p->data == NULL) {
677
0
            p->return_size = sizeof(double);
678
0
            return 1;
679
0
        }
680
0
        switch (p->data_size) {
681
0
        case sizeof(double):
682
0
            shift = real_shift();
683
0
            if (shift < 8 * sizeof(val) && (val >> shift) != 0) {
684
0
                err_inexact;
685
0
                return 0;
686
0
            }
687
0
            *(double *)p->data = (double)val;
688
0
            p->return_size = sizeof(double);
689
0
            return 1;
690
0
        }
691
0
        err_unsupported_real;
692
0
        return 0;
693
0
#endif
694
0
    }
695
0
    err_bad_type;
696
0
    return 0;
697
130
}
698
699
OSSL_PARAM OSSL_PARAM_construct_uint32(const char *key, uint32_t *buf)
700
0
{
701
0
    return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
702
0
                                sizeof(uint32_t));
703
0
}
704
705
int OSSL_PARAM_get_int64(const OSSL_PARAM *p, int64_t *val)
706
0
{
707
0
    if (val == NULL || p == NULL) {
708
0
        err_null_argument;
709
0
        return 0;
710
0
    }
711
712
0
    if (p->data == NULL) {
713
0
        err_null_argument;
714
0
        return 0;
715
0
    }
716
717
0
    if (p->data_type == OSSL_PARAM_INTEGER) {
718
0
#ifndef OPENSSL_SMALL_FOOTPRINT
719
0
        switch (p->data_size) {
720
0
        case sizeof(int32_t):
721
0
            *val = *(const int32_t *)p->data;
722
0
            return 1;
723
0
        case sizeof(int64_t):
724
0
            *val = *(const int64_t *)p->data;
725
0
            return 1;
726
0
        }
727
0
#endif
728
0
        return general_get_int(p, val, sizeof(*val));
729
0
    } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
730
0
#ifndef OPENSSL_SMALL_FOOTPRINT
731
0
        uint64_t u64;
732
733
0
        switch (p->data_size) {
734
0
        case sizeof(uint32_t):
735
0
            *val = *(const uint32_t *)p->data;
736
0
            return 1;
737
0
        case sizeof(uint64_t):
738
0
            u64 = *(const uint64_t *)p->data;
739
0
            if (u64 <= INT64_MAX) {
740
0
                *val = (int64_t)u64;
741
0
                return 1;
742
0
            }
743
0
            err_out_of_range;
744
0
            return 0;
745
0
        }
746
0
#endif
747
0
        return general_get_int(p, val, sizeof(*val));
748
0
    } else if (p->data_type == OSSL_PARAM_REAL) {
749
0
#ifndef OPENSSL_SYS_UEFI
750
0
        double d;
751
752
0
        switch (p->data_size) {
753
0
        case sizeof(double):
754
0
            d = *(const double *)p->data;
755
0
            if (d >= INT64_MIN
756
                    /*
757
                     * By subtracting 65535 (2^16-1) we cancel the low order
758
                     * 15 bits of INT64_MAX to avoid using imprecise floating
759
                     * point values.
760
                     */
761
0
                    && d < (double)(INT64_MAX - 65535) + 65536.0
762
0
                    && d == (int64_t)d) {
763
0
                *val = (int64_t)d;
764
0
                return 1;
765
0
            }
766
0
            err_inexact;
767
0
            return 0;
768
0
        }
769
0
        err_unsupported_real;
770
0
        return 0;
771
0
#endif
772
0
    }
773
0
    err_bad_type;
774
0
    return 0;
775
0
}
776
777
int OSSL_PARAM_set_int64(OSSL_PARAM *p, int64_t val)
778
0
{
779
0
    if (p == NULL) {
780
0
        err_null_argument;
781
0
        return 0;
782
0
    }
783
0
    p->return_size = 0;
784
0
    if (p->data_type == OSSL_PARAM_INTEGER) {
785
0
#ifndef OPENSSL_SMALL_FOOTPRINT
786
0
        if (p->data == NULL) {
787
0
            p->return_size = sizeof(int64_t); /* Expected size */
788
0
            return 1;
789
0
        }
790
0
        switch (p->data_size) {
791
0
        case sizeof(int32_t):
792
0
            if (val >= INT32_MIN && val <= INT32_MAX) {
793
0
                p->return_size = sizeof(int32_t);
794
0
                *(int32_t *)p->data = (int32_t)val;
795
0
                return 1;
796
0
            }
797
0
            err_out_of_range;
798
0
            return 0;
799
0
        case sizeof(int64_t):
800
0
            p->return_size = sizeof(int64_t);
801
0
            *(int64_t *)p->data = val;
802
0
            return 1;
803
0
        }
804
0
#endif
805
0
        return general_set_int(p, &val, sizeof(val));
806
0
    } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) {
807
0
#ifndef OPENSSL_SMALL_FOOTPRINT
808
0
        if (p->data == NULL) {
809
0
            p->return_size = sizeof(uint64_t); /* Expected size */
810
0
            return 1;
811
0
        }
812
0
        switch (p->data_size) {
813
0
        case sizeof(uint32_t):
814
0
            if (val <= UINT32_MAX) {
815
0
                p->return_size = sizeof(uint32_t);
816
0
                *(uint32_t *)p->data = (uint32_t)val;
817
0
                return 1;
818
0
            }
819
0
            err_out_of_range;
820
0
            return 0;
821
0
        case sizeof(uint64_t):
822
0
            p->return_size = sizeof(uint64_t);
823
0
            *(uint64_t *)p->data = (uint64_t)val;
824
0
            return 1;
825
0
        }
826
0
#endif
827
0
        return general_set_int(p, &val, sizeof(val));
828
0
    } else if (p->data_type == OSSL_PARAM_REAL) {
829
0
#ifndef OPENSSL_SYS_UEFI
830
0
        uint64_t u64;
831
832
0
        if (p->data == NULL) {
833
0
            p->return_size = sizeof(double);
834
0
            return 1;
835
0
        }
836
0
        switch (p->data_size) {
837
0
        case sizeof(double):
838
0
            u64 = val < 0 ? -val : val;
839
0
            if ((u64 >> real_shift()) == 0) {
840
0
                p->return_size = sizeof(double);
841
0
                *(double *)p->data = (double)val;
842
0
                return 1;
843
0
            }
844
0
            err_inexact;
845
0
            return 0;
846
0
        }
847
0
        err_unsupported_real;
848
0
        return 0;
849
0
#endif
850
0
    }
851
0
    err_bad_type;
852
0
    return 0;
853
0
}
854
855
OSSL_PARAM OSSL_PARAM_construct_int64(const char *key, int64_t *buf)
856
0
{
857
0
    return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int64_t));
858
0
}
859
860
int OSSL_PARAM_get_uint64(const OSSL_PARAM *p, uint64_t *val)
861
0
{
862
0
    if (val == NULL || p == NULL) {
863
0
        err_null_argument;
864
0
        return 0;
865
0
    }
866
867
0
    if (p->data == NULL) {
868
0
        err_null_argument;
869
0
        return 0;
870
0
    }
871
872
0
    if (ossl_likely(p->data_type == OSSL_PARAM_UNSIGNED_INTEGER)) {
873
0
#ifndef OPENSSL_SMALL_FOOTPRINT
874
0
        switch (p->data_size) {
875
0
        case sizeof(uint32_t):
876
0
            *val = *(const uint32_t *)p->data;
877
0
            return 1;
878
0
        case sizeof(uint64_t):
879
0
            *val = *(const uint64_t *)p->data;
880
0
            return 1;
881
0
        }
882
0
#endif
883
0
        return general_get_uint(p, val, sizeof(*val));
884
0
    } else if (p->data_type == OSSL_PARAM_INTEGER) {
885
0
#ifndef OPENSSL_SMALL_FOOTPRINT
886
0
        int32_t i32;
887
0
        int64_t i64;
888
889
0
        switch (p->data_size) {
890
0
        case sizeof(int32_t):
891
0
            i32 = *(const int32_t *)p->data;
892
0
            if (i32 >= 0) {
893
0
                *val = (uint64_t)i32;
894
0
                return 1;
895
0
            }
896
0
            err_unsigned_negative;
897
0
            return 0;
898
0
        case sizeof(int64_t):
899
0
            i64 = *(const int64_t *)p->data;
900
0
            if (i64 >= 0) {
901
0
                *val = (uint64_t)i64;
902
0
                return 1;
903
0
            }
904
0
            err_unsigned_negative;
905
0
            return 0;
906
0
        }
907
0
#endif
908
0
        return general_get_uint(p, val, sizeof(*val));
909
0
    } else if (p->data_type == OSSL_PARAM_REAL) {
910
0
#ifndef OPENSSL_SYS_UEFI
911
0
        double d;
912
913
0
        switch (p->data_size) {
914
0
        case sizeof(double):
915
0
            d = *(const double *)p->data;
916
0
            if (d >= 0
917
                    /*
918
                     * By subtracting 65535 (2^16-1) we cancel the low order
919
                     * 15 bits of UINT64_MAX to avoid using imprecise floating
920
                     * point values.
921
                     */
922
0
                    && d < (double)(UINT64_MAX - 65535) + 65536.0
923
0
                    && d == (uint64_t)d) {
924
0
                *val = (uint64_t)d;
925
0
                return 1;
926
0
            }
927
0
            err_inexact;
928
0
            return 0;
929
0
        }
930
0
        err_unsupported_real;
931
0
        return 0;
932
0
#endif
933
0
    }
934
0
    err_bad_type;
935
0
    return 0;
936
0
}
937
938
int OSSL_PARAM_set_uint64(OSSL_PARAM *p, uint64_t val)
939
396
{
940
396
    if (p == NULL) {
941
0
        err_null_argument;
942
0
        return 0;
943
0
    }
944
396
    p->return_size = 0;
945
946
396
    if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
947
396
#ifndef OPENSSL_SMALL_FOOTPRINT
948
396
        if (p->data == NULL) {
949
0
            p->return_size = sizeof(uint64_t); /* Expected size */
950
0
            return 1;
951
0
        }
952
396
        switch (p->data_size) {
953
0
        case sizeof(uint32_t):
954
0
            if (val <= UINT32_MAX) {
955
0
                p->return_size = sizeof(uint32_t);
956
0
                *(uint32_t *)p->data = (uint32_t)val;
957
0
                return 1;
958
0
            }
959
0
            err_out_of_range;
960
0
            return 0;
961
396
        case sizeof(uint64_t):
962
396
            p->return_size = sizeof(uint64_t);
963
396
            *(uint64_t *)p->data = val;
964
396
            return 1;
965
396
        }
966
0
#endif
967
0
        return general_set_uint(p, &val, sizeof(val));
968
396
    } else if (p->data_type == OSSL_PARAM_INTEGER) {
969
0
#ifndef OPENSSL_SMALL_FOOTPRINT
970
0
        if (p->data == NULL) {
971
0
            p->return_size = sizeof(int64_t); /* Expected size */
972
0
            return 1;
973
0
        }
974
0
        switch (p->data_size) {
975
0
        case sizeof(int32_t):
976
0
            if (val <= INT32_MAX) {
977
0
                p->return_size = sizeof(int32_t);
978
0
                *(int32_t *)p->data = (int32_t)val;
979
0
                return 1;
980
0
            }
981
0
            err_out_of_range;
982
0
            return 0;
983
0
        case sizeof(int64_t):
984
0
            if (val <= INT64_MAX) {
985
0
                p->return_size = sizeof(int64_t);
986
0
                *(int64_t *)p->data = (int64_t)val;
987
0
                return 1;
988
0
            }
989
0
            err_out_of_range;
990
0
            return 0;
991
0
        }
992
0
#endif
993
0
        return general_set_uint(p, &val, sizeof(val));
994
0
    } else if (p->data_type == OSSL_PARAM_REAL) {
995
0
#ifndef OPENSSL_SYS_UEFI
996
0
        switch (p->data_size) {
997
0
        case sizeof(double):
998
0
            if ((val >> real_shift()) == 0) {
999
0
                p->return_size = sizeof(double);
1000
0
                *(double *)p->data = (double)val;
1001
0
                return 1;
1002
0
            }
1003
0
            err_inexact;
1004
0
            return 0;
1005
0
        }
1006
0
        err_unsupported_real;
1007
0
        return 0;
1008
0
#endif
1009
0
    }
1010
0
    err_bad_type;
1011
0
    return 0;
1012
396
}
1013
1014
OSSL_PARAM OSSL_PARAM_construct_uint64(const char *key, uint64_t *buf)
1015
0
{
1016
0
    return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
1017
0
                                sizeof(uint64_t));
1018
0
}
1019
1020
int OSSL_PARAM_get_size_t(const OSSL_PARAM *p, size_t *val)
1021
0
{
1022
0
#ifndef OPENSSL_SMALL_FOOTPRINT
1023
0
    switch (sizeof(size_t)) {
1024
0
    case sizeof(uint32_t):
1025
0
        return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
1026
0
    case sizeof(uint64_t):
1027
0
        return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
1028
0
    }
1029
0
#endif
1030
0
    return general_get_uint(p, val, sizeof(*val));
1031
0
}
1032
1033
int OSSL_PARAM_set_size_t(OSSL_PARAM *p, size_t val)
1034
396
{
1035
396
#ifndef OPENSSL_SMALL_FOOTPRINT
1036
396
    switch (sizeof(size_t)) {
1037
0
    case sizeof(uint32_t):
1038
0
        return OSSL_PARAM_set_uint32(p, (uint32_t)val);
1039
396
    case sizeof(uint64_t):
1040
396
        return OSSL_PARAM_set_uint64(p, (uint64_t)val);
1041
396
    }
1042
0
#endif
1043
0
    return general_set_uint(p, &val, sizeof(val));
1044
396
}
1045
1046
OSSL_PARAM OSSL_PARAM_construct_size_t(const char *key, size_t *buf)
1047
396
{
1048
396
    return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
1049
396
                                sizeof(size_t));
1050
396
}
1051
1052
int OSSL_PARAM_get_time_t(const OSSL_PARAM *p, time_t *val)
1053
0
{
1054
0
#ifndef OPENSSL_SMALL_FOOTPRINT
1055
0
    switch (sizeof(time_t)) {
1056
0
    case sizeof(int32_t):
1057
0
        return OSSL_PARAM_get_int32(p, (int32_t *)val);
1058
0
    case sizeof(int64_t):
1059
0
        return OSSL_PARAM_get_int64(p, (int64_t *)val);
1060
0
    }
1061
0
#endif
1062
0
    return general_get_int(p, val, sizeof(*val));
1063
0
}
1064
1065
int OSSL_PARAM_set_time_t(OSSL_PARAM *p, time_t val)
1066
0
{
1067
0
#ifndef OPENSSL_SMALL_FOOTPRINT
1068
0
    switch (sizeof(time_t)) {
1069
0
    case sizeof(int32_t):
1070
0
        return OSSL_PARAM_set_int32(p, (int32_t)val);
1071
0
    case sizeof(int64_t):
1072
0
        return OSSL_PARAM_set_int64(p, (int64_t)val);
1073
0
    }
1074
0
#endif
1075
0
    return general_set_int(p, &val, sizeof(val));
1076
0
}
1077
1078
OSSL_PARAM OSSL_PARAM_construct_time_t(const char *key, time_t *buf)
1079
0
{
1080
0
    return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(time_t));
1081
0
}
1082
1083
int OSSL_PARAM_get_BN(const OSSL_PARAM *p, BIGNUM **val)
1084
0
{
1085
0
    BIGNUM *b = NULL;
1086
1087
0
    if (val == NULL || p == NULL || p->data == NULL) {
1088
0
        err_null_argument;
1089
0
        return 0;
1090
0
    }
1091
1092
0
    switch (p->data_type) {
1093
0
    case OSSL_PARAM_UNSIGNED_INTEGER:
1094
0
        b = BN_native2bn(p->data, (int)p->data_size, *val);
1095
0
        break;
1096
0
    case OSSL_PARAM_INTEGER:
1097
0
        b = BN_signed_native2bn(p->data, (int)p->data_size, *val);
1098
0
        break;
1099
0
    default:
1100
0
        err_bad_type;
1101
0
        break;
1102
0
    }
1103
1104
0
    if (b == NULL) {
1105
0
        ERR_raise(ERR_LIB_CRYPTO, ERR_R_BN_LIB);
1106
0
        return 0;
1107
0
    }
1108
1109
0
    *val = b;
1110
0
    return 1;
1111
0
}
1112
1113
int OSSL_PARAM_set_BN(OSSL_PARAM *p, const BIGNUM *val)
1114
0
{
1115
0
    size_t bytes;
1116
1117
0
    if (p == NULL) {
1118
0
        err_null_argument;
1119
0
        return 0;
1120
0
    }
1121
0
    p->return_size = 0;
1122
0
    if (val == NULL) {
1123
0
        err_null_argument;
1124
0
        return 0;
1125
0
    }
1126
0
    if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && BN_is_negative(val)) {
1127
0
        err_bad_type;
1128
0
        return 0;
1129
0
    }
1130
1131
0
    bytes = (size_t)BN_num_bytes(val);
1132
    /* We add 1 byte for signed numbers, to make space for a sign extension */
1133
0
    if (p->data_type == OSSL_PARAM_INTEGER)
1134
0
        bytes++;
1135
    /* We make sure that at least one byte is used, so zero is properly set */
1136
0
    if (bytes == 0)
1137
0
        bytes++;
1138
1139
0
    if (p->data == NULL) {
1140
0
        p->return_size = bytes;
1141
0
        return 1;
1142
0
    }
1143
0
    if (p->data_size >= bytes) {
1144
1145
0
        switch (p->data_type) {
1146
0
        case OSSL_PARAM_UNSIGNED_INTEGER:
1147
0
            if (BN_bn2nativepad(val, p->data, (int)p->data_size) < 0) {
1148
0
                ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_INTEGER_OVERFLOW);
1149
0
                return 0;
1150
0
            }
1151
0
            break;
1152
0
        case OSSL_PARAM_INTEGER:
1153
0
            if (BN_signed_bn2native(val, p->data, (int)p->data_size) < 0) {
1154
0
                ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_INTEGER_OVERFLOW);
1155
0
                return 0;
1156
0
            }
1157
0
            break;
1158
0
        default:
1159
0
            err_bad_type;
1160
0
            return 0;
1161
0
        }
1162
0
        p->return_size = p->data_size;
1163
0
        return 1;
1164
0
    }
1165
0
    p->return_size = bytes;
1166
0
    err_too_small;
1167
0
    return 0;
1168
0
}
1169
1170
OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf,
1171
                                   size_t bsize)
1172
0
{
1173
0
    return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER,
1174
0
                                buf, bsize);
1175
0
}
1176
1177
#ifndef OPENSSL_SYS_UEFI
1178
int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val)
1179
0
{
1180
0
    int64_t i64;
1181
0
    uint64_t u64;
1182
1183
0
    if (val == NULL || p == NULL || p->data == NULL) {
1184
0
        err_null_argument;
1185
0
        return 0;
1186
0
    }
1187
1188
0
    if (p->data_type == OSSL_PARAM_REAL) {
1189
0
        switch (p->data_size) {
1190
0
        case sizeof(double):
1191
0
            *val = *(const double *)p->data;
1192
0
            return 1;
1193
0
        }
1194
0
        err_unsupported_real;
1195
0
        return 0;
1196
0
    } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
1197
0
        switch (p->data_size) {
1198
0
        case sizeof(uint32_t):
1199
0
            *val = *(const uint32_t *)p->data;
1200
0
            return 1;
1201
0
        case sizeof(uint64_t):
1202
0
            u64 = *(const uint64_t *)p->data;
1203
0
            if ((u64 >> real_shift()) == 0) {
1204
0
                *val = (double)u64;
1205
0
                return 1;
1206
0
            }
1207
0
            err_inexact;
1208
0
            return 0;
1209
0
        }
1210
0
    } else if (p->data_type == OSSL_PARAM_INTEGER) {
1211
0
        switch (p->data_size) {
1212
0
        case sizeof(int32_t):
1213
0
            *val = *(const int32_t *)p->data;
1214
0
            return 1;
1215
0
        case sizeof(int64_t):
1216
0
            i64 = *(const int64_t *)p->data;
1217
0
            u64 = i64 < 0 ? -i64 : i64;
1218
0
            if ((u64 >> real_shift()) == 0) {
1219
0
                *val = 0.0 + i64;
1220
0
                return 1;
1221
0
            }
1222
0
            err_inexact;
1223
0
            return 0;
1224
0
        }
1225
0
    }
1226
0
    err_bad_type;
1227
0
    return 0;
1228
0
}
1229
1230
int OSSL_PARAM_set_double(OSSL_PARAM *p, double val)
1231
0
{
1232
0
#   define D_POW_31 ((double) (((uint32_t) 1) << 31))
1233
0
    const double d_pow_31 = D_POW_31;
1234
0
    const double d_pow_32 = 2.0 * D_POW_31;
1235
0
    const double d_pow_63 = 2.0 * D_POW_31 * D_POW_31;
1236
0
    const double d_pow_64 = 4.0 * D_POW_31 * D_POW_31;
1237
1238
0
    if (p == NULL) {
1239
0
        err_null_argument;
1240
0
        return 0;
1241
0
    }
1242
0
    p->return_size = 0;
1243
1244
0
    if (p->data_type == OSSL_PARAM_REAL) {
1245
0
        if (p->data == NULL) {
1246
0
            p->return_size = sizeof(double);
1247
0
            return 1;
1248
0
        }
1249
0
        switch (p->data_size) {
1250
0
        case sizeof(double):
1251
0
            p->return_size = sizeof(double);
1252
0
            *(double *)p->data = val;
1253
0
            return 1;
1254
0
        }
1255
0
        err_unsupported_real;
1256
0
        return 0;
1257
0
    } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
1258
0
        if (p->data == NULL) {
1259
            /*
1260
             * Unclear how this is usable, the parameter's type is integral.
1261
             * Its size should be the size of some integral type.
1262
             */
1263
0
            p->return_size = sizeof(double);
1264
0
            return 1;
1265
0
        }
1266
0
        if (val != (uint64_t)val) {
1267
0
            err_inexact;
1268
0
            return 0;
1269
0
        }
1270
0
        switch (p->data_size) {
1271
0
        case sizeof(uint32_t):
1272
0
            if (val >= 0 && val < d_pow_32) {
1273
0
                p->return_size = sizeof(uint32_t);
1274
0
                *(uint32_t *)p->data = (uint32_t)val;
1275
0
                return 1;
1276
0
            }
1277
0
            err_out_of_range;
1278
0
            return 0;
1279
0
        case sizeof(uint64_t):
1280
0
            if (val >= 0 && val < d_pow_64) {
1281
0
                p->return_size = sizeof(uint64_t);
1282
0
                *(uint64_t *)p->data = (uint64_t)val;
1283
0
                return 1;
1284
0
            }
1285
0
            err_out_of_range;
1286
0
            return 0;
1287
0
        }
1288
0
    } else if (p->data_type == OSSL_PARAM_INTEGER) {
1289
0
        if (p->data == NULL) {
1290
            /*
1291
             * Unclear how this is usable, the parameter's type is integral.
1292
             * Its size should be the size of some integral type.
1293
             */
1294
0
            p->return_size = sizeof(double);
1295
0
            return 1;
1296
0
        }
1297
0
        if (val != (int64_t)val) {
1298
0
            err_inexact;
1299
0
            return 0;
1300
0
        }
1301
0
        switch (p->data_size) {
1302
0
        case sizeof(int32_t):
1303
0
            if (val >= -d_pow_31 && val < d_pow_31) {
1304
0
                p->return_size = sizeof(int32_t);
1305
0
                *(int32_t *)p->data = (int32_t)val;
1306
0
                return 1;
1307
0
            }
1308
0
            err_out_of_range;
1309
0
            return 0;
1310
0
        case sizeof(int64_t):
1311
0
            if (val >= -d_pow_63 && val < d_pow_63) {
1312
0
                p->return_size = sizeof(int64_t);
1313
0
                *(int64_t *)p->data = (int64_t)val;
1314
0
                return 1;
1315
0
            }
1316
0
            err_out_of_range;
1317
0
            return 0;
1318
0
        }
1319
0
    }
1320
0
    err_bad_type;
1321
0
    return 0;
1322
0
}
1323
1324
OSSL_PARAM OSSL_PARAM_construct_double(const char *key, double *buf)
1325
0
{
1326
0
    return ossl_param_construct(key, OSSL_PARAM_REAL, buf, sizeof(double));
1327
0
}
1328
#endif
1329
1330
static int get_string_internal(const OSSL_PARAM *p, void **val,
1331
                               size_t *max_len, size_t *used_len,
1332
                               unsigned int type)
1333
0
{
1334
0
    size_t sz, alloc_sz;
1335
1336
0
    if ((val == NULL && used_len == NULL) || p == NULL) {
1337
0
        err_null_argument;
1338
0
        return 0;
1339
0
    }
1340
0
    if (p->data_type != type) {
1341
0
        err_bad_type;
1342
0
        return 0;
1343
0
    }
1344
1345
0
    sz = p->data_size;
1346
    /*
1347
     * If the input size is 0, or the input string needs NUL byte
1348
     * termination, allocate an extra byte.
1349
     */
1350
0
    alloc_sz = sz + (type == OSSL_PARAM_UTF8_STRING || sz == 0);
1351
1352
0
    if (used_len != NULL)
1353
0
        *used_len = sz;
1354
1355
0
    if (p->data == NULL) {
1356
0
        err_null_argument;
1357
0
        return 0;
1358
0
    }
1359
1360
0
    if (val == NULL)
1361
0
        return 1;
1362
1363
0
    if (*val == NULL) {
1364
0
        char *const q = OPENSSL_malloc(alloc_sz);
1365
1366
0
        if (q == NULL)
1367
0
            return 0;
1368
0
        *val = q;
1369
0
        *max_len = alloc_sz;
1370
0
    }
1371
1372
0
    if (*max_len < sz) {
1373
0
        err_too_small;
1374
0
        return 0;
1375
0
    }
1376
0
    memcpy(*val, p->data, sz);
1377
0
    return 1;
1378
0
}
1379
1380
int OSSL_PARAM_get_utf8_string(const OSSL_PARAM *p, char **val, size_t max_len)
1381
0
{
1382
0
    int ret = get_string_internal(p, (void **)val, &max_len, NULL,
1383
0
                                  OSSL_PARAM_UTF8_STRING);
1384
1385
    /*
1386
     * We try to ensure that the copied string is terminated with a
1387
     * NUL byte.  That should be easy, just place a NUL byte at
1388
     * |((char*)*val)[p->data_size]|.
1389
     * Unfortunately, we have seen cases where |p->data_size| doesn't
1390
     * correctly reflect the length of the string, and just happens
1391
     * to be out of bounds according to |max_len|, so in that case, we
1392
     * make the extra step of trying to find the true length of the
1393
     * string that |p->data| points at, and use that as an index to
1394
     * place the NUL byte in |*val|.
1395
     */
1396
0
    size_t data_length = p->data_size;
1397
1398
0
    if (ret == 0)
1399
0
        return 0;
1400
0
    if (data_length >= max_len)
1401
0
        data_length = OPENSSL_strnlen(p->data, data_length);
1402
0
    if (data_length >= max_len) {
1403
0
        ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_NO_SPACE_FOR_TERMINATING_NULL);
1404
0
        return 0;            /* No space for a terminating NUL byte */
1405
0
    }
1406
0
    (*val)[data_length] = '\0';
1407
1408
0
    return ret;
1409
0
}
1410
1411
int OSSL_PARAM_get_octet_string(const OSSL_PARAM *p, void **val, size_t max_len,
1412
                                size_t *used_len)
1413
0
{
1414
0
    return get_string_internal(p, val, &max_len, used_len,
1415
0
                               OSSL_PARAM_OCTET_STRING);
1416
0
}
1417
1418
static int set_string_internal(OSSL_PARAM *p, const void *val, size_t len,
1419
                               unsigned int type)
1420
0
{
1421
0
    if (p->data_type != type) {
1422
0
        err_bad_type;
1423
0
        return 0;
1424
0
    }
1425
0
    p->return_size = len;
1426
0
    if (p->data == NULL)
1427
0
        return 1;
1428
0
    if (p->data_size < len) {
1429
0
        err_too_small;
1430
0
        return 0;
1431
0
    }
1432
1433
0
    memcpy(p->data, val, len);
1434
    /* If possible within the size of p->data, add a NUL terminator byte */
1435
0
    if (type == OSSL_PARAM_UTF8_STRING && p->data_size > len)
1436
0
        ((char *)p->data)[len] = '\0';
1437
0
    return 1;
1438
0
}
1439
1440
int OSSL_PARAM_set_utf8_string(OSSL_PARAM *p, const char *val)
1441
0
{
1442
0
    if (p == NULL || val == NULL) {
1443
0
        err_null_argument;
1444
0
        return 0;
1445
0
    }
1446
0
    p->return_size = 0;
1447
0
    return set_string_internal(p, val, strlen(val), OSSL_PARAM_UTF8_STRING);
1448
0
}
1449
1450
int OSSL_PARAM_set_octet_string(OSSL_PARAM *p, const void *val,
1451
                                size_t len)
1452
0
{
1453
0
    if (p == NULL || val == NULL) {
1454
0
        err_null_argument;
1455
0
        return 0;
1456
0
    }
1457
0
    p->return_size = 0;
1458
0
    return set_string_internal(p, val, len, OSSL_PARAM_OCTET_STRING);
1459
0
}
1460
1461
OSSL_PARAM OSSL_PARAM_construct_utf8_string(const char *key, char *buf,
1462
                                            size_t bsize)
1463
0
{
1464
0
    if (buf != NULL && bsize == 0)
1465
0
        bsize = strlen(buf);
1466
0
    return ossl_param_construct(key, OSSL_PARAM_UTF8_STRING, buf, bsize);
1467
0
}
1468
1469
OSSL_PARAM OSSL_PARAM_construct_octet_string(const char *key, void *buf,
1470
                                             size_t bsize)
1471
0
{
1472
0
    return ossl_param_construct(key, OSSL_PARAM_OCTET_STRING, buf, bsize);
1473
0
}
1474
1475
static int get_ptr_internal_skip_checks(const OSSL_PARAM *p, const void **val,
1476
                                        size_t *used_len)
1477
0
{
1478
0
    if (used_len != NULL)
1479
0
        *used_len = p->data_size;
1480
0
    *val = *(const void **)p->data;
1481
0
    return 1;
1482
0
}
1483
1484
static int get_ptr_internal(const OSSL_PARAM *p, const void **val,
1485
                            size_t *used_len, unsigned int type)
1486
0
{
1487
0
    if (val == NULL || p == NULL) {
1488
0
        err_null_argument;
1489
0
        return 0;
1490
0
    }
1491
0
    if (p->data_type != type) {
1492
0
        err_bad_type;
1493
0
        return 0;
1494
0
    }
1495
0
    return get_ptr_internal_skip_checks(p, val, used_len);
1496
0
}
1497
1498
int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM *p, const char **val)
1499
0
{
1500
0
    return get_ptr_internal(p, (const void **)val, NULL, OSSL_PARAM_UTF8_PTR);
1501
0
}
1502
1503
int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, const void **val,
1504
                             size_t *used_len)
1505
0
{
1506
0
    return get_ptr_internal(p, val, used_len, OSSL_PARAM_OCTET_PTR);
1507
0
}
1508
1509
static int set_ptr_internal(OSSL_PARAM *p, const void *val,
1510
                            unsigned int type, size_t len)
1511
0
{
1512
0
    if (p->data_type != type) {
1513
0
        err_bad_type;
1514
0
        return 0;
1515
0
    }
1516
0
    p->return_size = len;
1517
0
    if (p->data != NULL)
1518
0
        *(const void **)p->data = val;
1519
0
    return 1;
1520
0
}
1521
1522
int OSSL_PARAM_set_utf8_ptr(OSSL_PARAM *p, const char *val)
1523
0
{
1524
0
    if (p == NULL) {
1525
0
        err_null_argument;
1526
0
        return 0;
1527
0
    }
1528
0
    p->return_size = 0;
1529
0
    return set_ptr_internal(p, val, OSSL_PARAM_UTF8_PTR,
1530
0
                            val == NULL ? 0 : strlen(val));
1531
0
}
1532
1533
int OSSL_PARAM_set_octet_ptr(OSSL_PARAM *p, const void *val,
1534
                             size_t used_len)
1535
0
{
1536
0
    if (p == NULL) {
1537
0
        err_null_argument;
1538
0
        return 0;
1539
0
    }
1540
0
    p->return_size = 0;
1541
0
    return set_ptr_internal(p, val, OSSL_PARAM_OCTET_PTR, used_len);
1542
0
}
1543
1544
OSSL_PARAM OSSL_PARAM_construct_utf8_ptr(const char *key, char **buf,
1545
                                         size_t bsize)
1546
0
{
1547
0
    return ossl_param_construct(key, OSSL_PARAM_UTF8_PTR, buf, bsize);
1548
0
}
1549
1550
OSSL_PARAM OSSL_PARAM_construct_octet_ptr(const char *key, void **buf,
1551
                                          size_t bsize)
1552
0
{
1553
0
    return ossl_param_construct(key, OSSL_PARAM_OCTET_PTR, buf, bsize);
1554
0
}
1555
1556
/*
1557
 * Extract the parameter into an allocated buffer.
1558
 * Any existing allocation in *out is cleared and freed.
1559
 *
1560
 * Returns 1 on success, 0 on failure and -1 if there are no matching params.
1561
 *
1562
 * *out and *out_len are guaranteed to be untouched if this function
1563
 * doesn't return success.
1564
 */
1565
int ossl_param_get1_octet_string(const OSSL_PARAM *params, const char *name,
1566
                                 unsigned char **out, size_t *out_len)
1567
0
{
1568
0
    const OSSL_PARAM *p = OSSL_PARAM_locate_const(params, name);
1569
0
    void *buf = NULL;
1570
0
    size_t len = 0;
1571
1572
0
    if (p == NULL)
1573
0
        return -1;
1574
1575
0
    if (p->data != NULL
1576
0
            && p->data_size > 0
1577
0
            && !OSSL_PARAM_get_octet_string(p, &buf, 0, &len))
1578
0
        return 0;
1579
1580
0
    OPENSSL_clear_free(*out, *out_len);
1581
0
    *out = buf;
1582
0
    *out_len = len;
1583
0
    return 1;
1584
0
}
1585
1586
static int setbuf_fromparams(const OSSL_PARAM *p, const char *name,
1587
                             unsigned char *out, size_t *outlen)
1588
0
{
1589
0
    int ret = 0;
1590
0
    WPACKET pkt;
1591
1592
0
    if (out == NULL) {
1593
0
        if (!WPACKET_init_null(&pkt, 0))
1594
0
            return 0;
1595
0
    } else {
1596
0
        if (!WPACKET_init_static_len(&pkt, out, *outlen, 0))
1597
0
            return 0;
1598
0
    }
1599
1600
0
    for (; p != NULL; p = OSSL_PARAM_locate_const(p + 1, name)) {
1601
0
        if (p->data_type != OSSL_PARAM_OCTET_STRING)
1602
0
            goto err;
1603
0
        if (p->data != NULL
1604
0
                && p->data_size != 0
1605
0
                && !WPACKET_memcpy(&pkt, p->data, p->data_size))
1606
0
            goto err;
1607
0
    }
1608
0
    if (!WPACKET_get_total_written(&pkt, outlen)
1609
0
            || !WPACKET_finish(&pkt))
1610
0
        goto err;
1611
0
    ret = 1;
1612
0
err:
1613
0
    WPACKET_cleanup(&pkt);
1614
0
    return ret;
1615
0
}
1616
1617
int ossl_param_get1_concat_octet_string(const OSSL_PARAM *params, const char *name,
1618
                                        unsigned char **out,
1619
                                        size_t *out_len, size_t maxsize)
1620
0
{
1621
0
    const OSSL_PARAM *p = OSSL_PARAM_locate_const(params, name);
1622
0
    unsigned char *res;
1623
0
    size_t sz = 0;
1624
1625
0
    if (p == NULL)
1626
0
        return -1;
1627
1628
    /* Calculate the total size */
1629
0
    if (!setbuf_fromparams(p, name, NULL, &sz))
1630
0
        return 0;
1631
1632
    /* Check that it's not oversized */
1633
0
    if (maxsize > 0 && sz > maxsize)
1634
0
        return 0;
1635
1636
    /* Special case zero length */
1637
0
    if (sz == 0) {
1638
0
        if ((res = OPENSSL_zalloc(1)) == NULL)
1639
0
            return 0;
1640
0
        goto fin;
1641
0
    }
1642
1643
    /* Allocate the buffer */
1644
0
    res = OPENSSL_malloc(sz);
1645
0
    if (res == NULL)
1646
0
        return 0;
1647
1648
    /* Concat one or more OSSL_KDF_PARAM_INFO fields */
1649
0
    if (!setbuf_fromparams(p, name, res, &sz)) {
1650
0
        OPENSSL_clear_free(res, sz);
1651
0
        return 0;
1652
0
    }
1653
1654
0
 fin:
1655
0
    OPENSSL_clear_free(*out, *out_len);
1656
0
    *out = res;
1657
0
    *out_len = sz;
1658
0
    return 1;
1659
0
}
1660
1661
OSSL_PARAM OSSL_PARAM_construct_end(void)
1662
130
{
1663
130
    OSSL_PARAM end = OSSL_PARAM_END;
1664
1665
130
    return end;
1666
130
}
1667
1668
static int get_string_ptr_internal(const OSSL_PARAM *p, const void **val,
1669
                                   size_t *used_len, unsigned int ref_type,
1670
                                   unsigned int type)
1671
0
{
1672
0
    if (val == NULL || p == NULL) {
1673
0
        err_null_argument;
1674
0
        return 0;
1675
0
    }
1676
1677
0
    if (p->data_type == ref_type)
1678
0
        return get_ptr_internal_skip_checks(p, (const void **)val, used_len);
1679
1680
0
    if (p->data_type != type) {
1681
0
        err_bad_type;
1682
0
        return 0;
1683
0
    }
1684
0
    if (used_len != NULL)
1685
0
        *used_len = p->data_size;
1686
0
    *val = p->data;
1687
0
    return 1;
1688
0
}
1689
1690
int OSSL_PARAM_get_utf8_string_ptr(const OSSL_PARAM *p, const char **val)
1691
0
{
1692
0
    return get_string_ptr_internal(p, (const void **)val, NULL,
1693
0
                                   OSSL_PARAM_UTF8_PTR,
1694
0
                                   OSSL_PARAM_UTF8_STRING);
1695
0
}
1696
1697
int OSSL_PARAM_get_octet_string_ptr(const OSSL_PARAM *p, const void **val,
1698
                                    size_t *used_len)
1699
0
{
1700
0
    return get_string_ptr_internal(p, (const void **)val, used_len,
1701
0
                                   OSSL_PARAM_OCTET_PTR,
1702
0
                                   OSSL_PARAM_OCTET_STRING);
1703
0
}
1704
1705
int OSSL_PARAM_set_octet_string_or_ptr(OSSL_PARAM *p, const void *val,
1706
                                       size_t len)
1707
0
{
1708
0
    if (p == NULL) {
1709
0
        err_null_argument;
1710
0
        return 0;
1711
0
    }
1712
1713
0
    if (p->data_type == OSSL_PARAM_OCTET_STRING)
1714
0
        return OSSL_PARAM_set_octet_string(p, val, len);
1715
0
    else if (p->data_type == OSSL_PARAM_OCTET_PTR)
1716
0
        return OSSL_PARAM_set_octet_ptr(p, val, len);
1717
1718
0
    err_bad_type;
1719
0
    return 0;
1720
0
}