Coverage Report

Created: 2025-06-13 06:58

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