Coverage Report

Created: 2023-09-25 06:41

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