Coverage Report

Created: 2023-04-12 06:22

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