Coverage Report

Created: 2024-05-15 07:14

/src/openssl/crypto/params.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
3
 * Copyright (c) 2019, Oracle and/or its affiliates.  All rights reserved.
4
 *
5
 * Licensed under the Apache License 2.0 (the "License").  You may not use
6
 * this file except in compliance with the License.  You can obtain a copy
7
 * in the file LICENSE in the source distribution or at
8
 * https://www.openssl.org/source/license.html
9
 */
10
11
#include <string.h>
12
#include <openssl/params.h>
13
#include "internal/thread_once.h"
14
#include "internal/numbers.h"
15
16
OSSL_PARAM *OSSL_PARAM_locate(OSSL_PARAM *p, const char *key)
17
0
{
18
0
    if (p != NULL && key != NULL)
19
0
        for (; p->key != NULL; p++)
20
0
            if (strcmp(key, p->key) == 0)
21
0
                return p;
22
0
    return NULL;
23
0
}
24
25
const OSSL_PARAM *OSSL_PARAM_locate_const(const OSSL_PARAM *p, const char *key)
26
0
{
27
0
    return OSSL_PARAM_locate((OSSL_PARAM *)p, key);
28
0
}
29
30
static OSSL_PARAM ossl_param_construct(const char *key, unsigned int data_type,
31
                                       void *data, size_t data_size)
32
0
{
33
0
    OSSL_PARAM res;
34
35
0
    res.key = key;
36
0
    res.data_type = data_type;
37
0
    res.data = data;
38
0
    res.data_size = data_size;
39
0
    res.return_size = 0;
40
0
    return res;
41
0
}
42
43
int OSSL_PARAM_get_int(const OSSL_PARAM *p, int *val)
44
0
{
45
0
    switch (sizeof(int)) {
46
0
    case sizeof(int32_t):
47
0
        return OSSL_PARAM_get_int32(p, (int32_t *)val);
48
0
    case sizeof(int64_t):
49
0
        return OSSL_PARAM_get_int64(p, (int64_t *)val);
50
0
    }
51
0
    return 0;
52
0
}
53
54
int OSSL_PARAM_set_int(OSSL_PARAM *p, int val)
55
0
{
56
0
    switch (sizeof(int)) {
57
0
    case sizeof(int32_t):
58
0
        return OSSL_PARAM_set_int32(p, (int32_t)val);
59
0
    case sizeof(int64_t):
60
0
        return OSSL_PARAM_set_int64(p, (int64_t)val);
61
0
    }
62
0
    return 0;
63
0
}
64
65
OSSL_PARAM OSSL_PARAM_construct_int(const char *key, int *buf)
66
0
{
67
0
    return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int));
68
0
}
69
70
int OSSL_PARAM_get_uint(const OSSL_PARAM *p, unsigned int *val)
71
0
{
72
0
    switch (sizeof(unsigned int)) {
73
0
    case sizeof(uint32_t):
74
0
        return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
75
0
    case sizeof(uint64_t):
76
0
        return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
77
0
    }
78
0
    return 0;
79
0
}
80
81
int OSSL_PARAM_set_uint(OSSL_PARAM *p, unsigned int val)
82
0
{
83
0
    switch (sizeof(unsigned int)) {
84
0
    case sizeof(uint32_t):
85
0
        return OSSL_PARAM_set_uint32(p, (uint32_t)val);
86
0
    case sizeof(uint64_t):
87
0
        return OSSL_PARAM_set_uint64(p, (uint64_t)val);
88
0
    }
89
0
    return 0;
90
0
}
91
92
OSSL_PARAM OSSL_PARAM_construct_uint(const char *key, unsigned int *buf)
93
0
{
94
0
    return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
95
0
                                sizeof(unsigned int));
96
0
}
97
98
int OSSL_PARAM_get_long(const OSSL_PARAM *p, long int *val)
99
0
{
100
0
    switch (sizeof(long int)) {
101
0
    case sizeof(int32_t):
102
0
        return OSSL_PARAM_get_int32(p, (int32_t *)val);
103
0
    case sizeof(int64_t):
104
0
        return OSSL_PARAM_get_int64(p, (int64_t *)val);
105
0
    }
106
0
    return 0;
107
0
}
108
109
int OSSL_PARAM_set_long(OSSL_PARAM *p, long int val)
110
0
{
111
0
    switch (sizeof(long int)) {
112
0
    case sizeof(int32_t):
113
0
        return OSSL_PARAM_set_int32(p, (int32_t)val);
114
0
    case sizeof(int64_t):
115
0
        return OSSL_PARAM_set_int64(p, (int64_t)val);
116
0
    }
117
0
    return 0;
118
0
}
119
120
OSSL_PARAM OSSL_PARAM_construct_long(const char *key, long int *buf)
121
0
{
122
0
    return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(long int));
123
0
}
124
125
int OSSL_PARAM_get_ulong(const OSSL_PARAM *p, unsigned long int *val)
126
0
{
127
0
    switch (sizeof(unsigned long int)) {
128
0
    case sizeof(uint32_t):
129
0
        return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
130
0
    case sizeof(uint64_t):
131
0
        return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
132
0
    }
133
0
    return 0;
134
0
}
135
136
int OSSL_PARAM_set_ulong(OSSL_PARAM *p, unsigned long int val)
137
0
{
138
0
    switch (sizeof(unsigned long int)) {
139
0
    case sizeof(uint32_t):
140
0
        return OSSL_PARAM_set_uint32(p, (uint32_t)val);
141
0
    case sizeof(uint64_t):
142
0
        return OSSL_PARAM_set_uint64(p, (uint64_t)val);
143
0
    }
144
0
    return 0;
145
0
}
146
147
OSSL_PARAM OSSL_PARAM_construct_ulong(const char *key, unsigned long int *buf)
148
0
{
149
0
    return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
150
0
                                sizeof(unsigned long int));
151
0
}
152
153
int OSSL_PARAM_get_int32(const OSSL_PARAM *p, int32_t *val)
154
0
{
155
0
    int64_t i64;
156
0
    uint32_t u32;
157
0
    uint64_t u64;
158
0
    double d;
159
160
0
    if (val == NULL || p == NULL )
161
0
        return 0;
162
163
0
    if (p->data_type == OSSL_PARAM_INTEGER) {
164
0
        switch (p->data_size) {
165
0
        case sizeof(int32_t):
166
0
            *val = *(const int32_t *)p->data;
167
0
            return 1;
168
0
        case sizeof(int64_t):
169
0
            i64 = *(const int64_t *)p->data;
170
0
            if (i64 >= INT32_MIN && i64 <= INT32_MAX) {
171
0
                *val = (int32_t)i64;
172
0
                return 1;
173
0
            }
174
0
            break;
175
0
        }
176
0
    } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
177
0
        switch (p->data_size) {
178
0
        case sizeof(uint32_t):
179
0
            u32 = *(const uint32_t *)p->data;
180
0
            if (u32 <= INT32_MAX) {
181
0
                *val = (int32_t)u32;
182
0
                return 1;
183
0
            }
184
0
            break;
185
0
        case sizeof(uint64_t):
186
0
            u64 = *(const uint64_t *)p->data;
187
0
            if (u64 <= INT32_MAX) {
188
0
                *val = (int32_t)u64;
189
0
                return 1;
190
0
            }
191
0
            break;
192
0
        }
193
0
    } else if (p->data_type == OSSL_PARAM_REAL) {
194
0
        switch (p->data_size) {
195
0
        case sizeof(double):
196
0
            d = *(const double *)p->data;
197
0
            if (d >= INT32_MIN && d <= INT32_MAX && d == (int32_t)d) {
198
0
                *val = (int32_t)d;
199
0
                return 1;
200
0
            }
201
0
            break;
202
0
        }
203
0
    }
204
0
    return 0;
205
0
}
206
207
int OSSL_PARAM_set_int32(OSSL_PARAM *p, int32_t val)
208
0
{
209
0
    if (p == NULL)
210
0
        return 0;
211
0
    p->return_size = 0;
212
0
    if (p->data_type == OSSL_PARAM_INTEGER) {
213
0
        p->return_size = sizeof(int32_t); /* Minimum expected size */
214
0
        if (p->data == NULL)
215
0
            return 1;
216
0
        switch (p->data_size) {
217
0
        case sizeof(int32_t):
218
0
            *(int32_t *)p->data = val;
219
0
            return 1;
220
0
        case sizeof(int64_t):
221
0
            p->return_size = sizeof(int64_t);
222
0
            *(int64_t *)p->data = (int64_t)val;
223
0
            return 1;
224
0
        }
225
0
    } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) {
226
0
        p->return_size = sizeof(uint32_t); /* Minimum expected size */
227
0
        if (p->data == NULL)
228
0
            return 1;
229
0
        switch (p->data_size) {
230
0
        case sizeof(uint32_t):
231
0
            *(uint32_t *)p->data = (uint32_t)val;
232
0
            return 1;
233
0
        case sizeof(uint64_t):
234
0
            p->return_size = sizeof(uint64_t);
235
0
            *(uint64_t *)p->data = (uint64_t)val;
236
0
            return 1;
237
0
        }
238
0
    } else if (p->data_type == OSSL_PARAM_REAL) {
239
0
        p->return_size = sizeof(double);
240
0
        if (p->data == NULL)
241
0
            return 1;
242
0
        switch (p->data_size) {
243
0
        case sizeof(double):
244
0
            *(double *)p->data = (double)val;
245
0
            return 1;
246
0
        }
247
0
    }
248
0
    return 0;
249
0
}
250
251
OSSL_PARAM OSSL_PARAM_construct_int32(const char *key, int32_t *buf)
252
0
{
253
0
    return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf,
254
0
                                sizeof(int32_t));
255
0
}
256
257
int OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val)
258
0
{
259
0
    int32_t i32;
260
0
    int64_t i64;
261
0
    uint64_t u64;
262
0
    double d;
263
264
0
    if (val == NULL || p == NULL)
265
0
        return 0;
266
267
0
    if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
268
0
        switch (p->data_size) {
269
0
        case sizeof(uint32_t):
270
0
            *val = *(const uint32_t *)p->data;
271
0
            return 1;
272
0
        case sizeof(uint64_t):
273
0
            u64 = *(const uint64_t *)p->data;
274
0
            if (u64 <= UINT32_MAX) {
275
0
                *val = (uint32_t)u64;
276
0
                return 1;
277
0
            }
278
0
            break;
279
0
        }
280
0
    } else if (p->data_type == OSSL_PARAM_INTEGER) {
281
0
        switch (p->data_size) {
282
0
        case sizeof(int32_t):
283
0
            i32 = *(const int32_t *)p->data;
284
0
            if (i32 >= 0) {
285
0
                *val = i32;
286
0
                return 1;
287
0
            }
288
0
            break;
289
0
        case sizeof(int64_t):
290
0
            i64 = *(const int64_t *)p->data;
291
0
            if (i64 >= 0 && i64 <= UINT32_MAX) {
292
0
                *val = (uint32_t)i64;
293
0
                return 1;
294
0
            }
295
0
            break;
296
0
        }
297
0
    } else if (p->data_type == OSSL_PARAM_REAL) {
298
0
        switch (p->data_size) {
299
0
        case sizeof(double):
300
0
            d = *(const double *)p->data;
301
0
            if (d >= 0 && d <= UINT32_MAX && d == (uint32_t)d) {
302
0
                *val = (uint32_t)d;
303
0
                return 1;
304
0
            }
305
0
            break;
306
0
        }
307
0
    }
308
0
    return 0;
309
0
}
310
311
int OSSL_PARAM_set_uint32(OSSL_PARAM *p, uint32_t val)
312
0
{
313
0
    if (p == NULL)
314
0
        return 0;
315
0
    p->return_size = 0;
316
317
0
    if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
318
0
        p->return_size = sizeof(uint32_t); /* Minimum expected size */
319
0
        if (p->data == NULL)
320
0
            return 1;
321
0
        switch (p->data_size) {
322
0
        case sizeof(uint32_t):
323
0
            *(uint32_t *)p->data = val;
324
0
            return 1;
325
0
        case sizeof(uint64_t):
326
0
            p->return_size = sizeof(uint64_t);
327
0
            *(uint64_t *)p->data = val;
328
0
            return 1;
329
0
        }
330
0
    } else if (p->data_type == OSSL_PARAM_INTEGER) {
331
0
        p->return_size = sizeof(int32_t); /* Minimum expected size */
332
0
        if (p->data == NULL)
333
0
            return 1;
334
0
        switch (p->data_size) {
335
0
        case sizeof(int32_t):
336
0
            if (val <= INT32_MAX) {
337
0
                *(int32_t *)p->data = (int32_t)val;
338
0
                return 1;
339
0
            }
340
0
            break;
341
0
        case sizeof(int64_t):
342
0
            p->return_size = sizeof(int64_t);
343
0
            *(int64_t *)p->data = (int64_t)val;
344
0
            return 1;
345
0
        }
346
0
    } else if (p->data_type == OSSL_PARAM_REAL) {
347
0
        p->return_size = sizeof(double);
348
0
        if (p->data == NULL)
349
0
            return 1;
350
0
        switch (p->data_size) {
351
0
        case sizeof(double):
352
0
            *(double *)p->data = (double)val;
353
0
            return 1;
354
0
        }
355
0
    }
356
0
    return 0;
357
0
}
358
359
OSSL_PARAM OSSL_PARAM_construct_uint32(const char *key, uint32_t *buf)
360
0
{
361
0
    return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
362
0
                                sizeof(uint32_t));
363
0
}
364
365
int OSSL_PARAM_get_int64(const OSSL_PARAM *p, int64_t *val)
366
0
{
367
0
    uint64_t u64;
368
0
    double d;
369
370
0
    if (val == NULL || p == NULL )
371
0
        return 0;
372
373
0
    if (p->data_type == OSSL_PARAM_INTEGER) {
374
0
        switch (p->data_size) {
375
0
        case sizeof(int32_t):
376
0
            *val = *(const int32_t *)p->data;
377
0
            return 1;
378
0
        case sizeof(int64_t):
379
0
            *val = *(const int64_t *)p->data;
380
0
            return 1;
381
0
        }
382
0
    } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
383
0
        switch (p->data_size) {
384
0
        case sizeof(uint32_t):
385
0
            *val = *(const uint32_t *)p->data;
386
0
            return 1;
387
0
        case sizeof(uint64_t):
388
0
            u64 = *(const uint64_t *)p->data;
389
0
            if (u64 <= INT64_MAX) {
390
0
                *val = (int64_t)u64;
391
0
                return 1;
392
0
            }
393
0
            break;
394
0
        }
395
0
    } else if (p->data_type == OSSL_PARAM_REAL) {
396
0
        switch (p->data_size) {
397
0
        case sizeof(double):
398
0
            d = *(const double *)p->data;
399
0
            if (d >= INT64_MIN && d <= INT64_MAX && d == (int64_t)d) {
400
0
                *val = (int64_t)d;
401
0
                return 1;
402
0
            }
403
0
            break;
404
0
        }
405
0
    }
406
0
    return 0;
407
0
}
408
409
int OSSL_PARAM_set_int64(OSSL_PARAM *p, int64_t val)
410
0
{
411
0
    uint64_t u64;
412
413
0
    if (p == NULL)
414
0
        return 0;
415
0
    p->return_size = 0;
416
0
    if (p->data_type == OSSL_PARAM_INTEGER) {
417
0
        p->return_size = sizeof(int64_t); /* Expected size */
418
0
        if (p->data == NULL)
419
0
            return 1;
420
0
        switch (p->data_size) {
421
0
        case sizeof(int32_t):
422
0
            if (val >= INT32_MIN && val <= INT32_MAX) {
423
0
                p->return_size = sizeof(int32_t);
424
0
                *(int32_t *)p->data = (int32_t)val;
425
0
                return 1;
426
0
            }
427
0
            break;
428
0
        case sizeof(int64_t):
429
0
            *(int64_t *)p->data = val;
430
0
            return 1;
431
0
        }
432
0
    } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) {
433
0
        p->return_size = sizeof(uint64_t); /* Expected size */
434
0
        if (p->data == NULL)
435
0
            return 1;
436
0
        switch (p->data_size) {
437
0
        case sizeof(uint32_t):
438
0
            if (val <= UINT32_MAX) {
439
0
                p->return_size = sizeof(uint32_t);
440
0
                *(uint32_t *)p->data = (uint32_t)val;
441
0
                return 1;
442
0
            }
443
0
            break;
444
0
        case sizeof(uint64_t):
445
0
            *(uint64_t *)p->data = (uint64_t)val;
446
0
            return 1;
447
0
        }
448
0
    } else if (p->data_type == OSSL_PARAM_REAL) {
449
0
        p->return_size = sizeof(double);
450
0
        if (p->data == NULL)
451
0
            return 1;
452
0
        switch (p->data_size) {
453
0
        case sizeof(double):
454
0
            u64 = val < 0 ? -val : val;
455
0
            if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
456
0
                *(double *)p->data = (double)val;
457
0
                return 1;
458
0
            }
459
0
            break;
460
0
        }
461
0
    }
462
0
    return 0;
463
0
}
464
465
OSSL_PARAM OSSL_PARAM_construct_int64(const char *key, int64_t *buf)
466
0
{
467
0
    return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int64_t));
468
0
}
469
470
int OSSL_PARAM_get_uint64(const OSSL_PARAM *p, uint64_t *val)
471
0
{
472
0
    int32_t i32;
473
0
    int64_t i64;
474
0
    double d;
475
476
0
    if (val == NULL || p == NULL)
477
0
        return 0;
478
479
0
    if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
480
0
        switch (p->data_size) {
481
0
        case sizeof(uint32_t):
482
0
            *val = *(const uint32_t *)p->data;
483
0
            return 1;
484
0
        case sizeof(uint64_t):
485
0
            *val = *(const uint64_t *)p->data;
486
0
            return 1;
487
0
        }
488
0
    } else if (p->data_type == OSSL_PARAM_INTEGER) {
489
0
        switch (p->data_size) {
490
0
        case sizeof(int32_t):
491
0
            i32 = *(const int32_t *)p->data;
492
0
            if (i32 >= 0) {
493
0
                *val = (uint64_t)i32;
494
0
                return 1;
495
0
            }
496
0
            break;
497
0
        case sizeof(int64_t):
498
0
            i64 = *(const int64_t *)p->data;
499
0
            if (i64 >= 0) {
500
0
                *val = (uint64_t)i64;
501
0
                return 1;
502
0
            }
503
0
            break;
504
0
        }
505
0
    } else if (p->data_type == OSSL_PARAM_REAL) {
506
0
        switch (p->data_size) {
507
0
        case sizeof(double):
508
0
            d = *(const double *)p->data;
509
0
            if (d >= 0 && d <= INT64_MAX && d == (uint64_t)d) {
510
0
                *val = (uint64_t)d;
511
0
                return 1;
512
0
            }
513
0
            break;
514
0
        }
515
0
    }
516
0
    return 0;
517
0
}
518
519
int OSSL_PARAM_set_uint64(OSSL_PARAM *p, uint64_t val)
520
0
{
521
0
    if (p == NULL)
522
0
        return 0;
523
0
    p->return_size = 0;
524
525
0
    if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
526
0
        p->return_size = sizeof(uint64_t); /* Expected size */
527
0
        if (p->data == NULL)
528
0
            return 1;
529
0
        switch (p->data_size) {
530
0
        case sizeof(uint32_t):
531
0
            if (val <= UINT32_MAX) {
532
0
                p->return_size = sizeof(uint32_t);
533
0
                *(uint32_t *)p->data = (uint32_t)val;
534
0
                return 1;
535
0
            }
536
0
            break;
537
0
        case sizeof(uint64_t):
538
0
            *(uint64_t *)p->data = val;
539
0
            return 1;
540
0
        }
541
0
    } else if (p->data_type == OSSL_PARAM_INTEGER) {
542
0
        p->return_size = sizeof(int64_t); /* Expected size */
543
0
        if (p->data == NULL)
544
0
            return 1;
545
0
        switch (p->data_size) {
546
0
        case sizeof(int32_t):
547
0
            if (val <= INT32_MAX) {
548
0
                p->return_size = sizeof(int32_t);
549
0
                *(int32_t *)p->data = (int32_t)val;
550
0
                return 1;
551
0
            }
552
0
            break;
553
0
        case sizeof(int64_t):
554
0
            if (val <= INT64_MAX) {
555
0
                *(int64_t *)p->data = (int64_t)val;
556
0
                return 1;
557
0
            }
558
0
            break;
559
0
        }
560
0
    } else if (p->data_type == OSSL_PARAM_REAL) {
561
0
        p->return_size = sizeof(double);
562
0
        switch (p->data_size) {
563
0
        case sizeof(double):
564
0
            if ((val >> 53) == 0) { /* 53 significant bits in the mantissa */
565
0
                *(double *)p->data = (double)val;
566
0
                return 1;
567
0
            }
568
0
            break;
569
0
        }
570
0
    }
571
0
    return 0;
572
0
}
573
574
OSSL_PARAM OSSL_PARAM_construct_uint64(const char *key, uint64_t *buf)
575
0
{
576
0
    return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
577
0
                                sizeof(uint64_t));
578
0
}
579
580
int OSSL_PARAM_get_size_t(const OSSL_PARAM *p, size_t *val)
581
0
{
582
0
    switch (sizeof(size_t)) {
583
0
    case sizeof(uint32_t):
584
0
        return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
585
0
    case sizeof(uint64_t):
586
0
        return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
587
0
    }
588
0
    return 0;
589
0
}
590
591
int OSSL_PARAM_set_size_t(OSSL_PARAM *p, size_t val)
592
0
{
593
0
    switch (sizeof(size_t)) {
594
0
    case sizeof(uint32_t):
595
0
        return OSSL_PARAM_set_uint32(p, (uint32_t)val);
596
0
    case sizeof(uint64_t):
597
0
        return OSSL_PARAM_set_uint64(p, (uint64_t)val);
598
0
    }
599
0
    return 0;
600
0
}
601
602
OSSL_PARAM OSSL_PARAM_construct_size_t(const char *key, size_t *buf)
603
0
{
604
0
    return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
605
0
                                sizeof(size_t));
606
0
}
607
608
int OSSL_PARAM_get_BN(const OSSL_PARAM *p, BIGNUM **val)
609
0
{
610
0
    BIGNUM *b;
611
612
0
    if (val == NULL
613
0
        || p == NULL
614
0
        || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
615
0
        return 0;
616
617
0
    b = BN_native2bn(p->data, (int)p->data_size, *val);
618
0
    if (b != NULL) {
619
0
        *val = b;
620
0
        return 1;
621
0
    }
622
0
    return 0;
623
0
}
624
625
int OSSL_PARAM_set_BN(OSSL_PARAM *p, const BIGNUM *val)
626
0
{
627
0
    size_t bytes;
628
629
0
    if (p == NULL)
630
0
        return 0;
631
0
    p->return_size = 0;
632
0
    if (val == NULL || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
633
0
        return 0;
634
635
    /* For the moment, only positive values are permitted */
636
0
    if (BN_is_negative(val))
637
0
        return 0;
638
639
0
    bytes = (size_t)BN_num_bytes(val);
640
0
    p->return_size = bytes;
641
0
    if (p->data == NULL)
642
0
        return 1;
643
0
    if (p->data_size >= bytes) {
644
0
        p->return_size = p->data_size;
645
0
        return BN_bn2nativepad(val, p->data, p->data_size) >= 0;
646
0
    }
647
0
    return 0;
648
0
}
649
650
OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf,
651
                                   size_t bsize)
652
0
{
653
0
    return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER,
654
0
                                buf, bsize);
655
0
}
656
657
int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val)
658
0
{
659
0
    int64_t i64;
660
0
    uint64_t u64;
661
662
0
    if (val == NULL || p == NULL)
663
0
        return 0;
664
665
0
    if (p->data_type == OSSL_PARAM_REAL) {
666
0
        switch (p->data_size) {
667
0
        case sizeof(double):
668
0
            *val = *(const double *)p->data;
669
0
            return 1;
670
0
        }
671
0
    } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) {
672
0
        switch (p->data_size) {
673
0
        case sizeof(uint32_t):
674
0
            *val = *(const uint32_t *)p->data;
675
0
            return 1;
676
0
        case sizeof(uint64_t):
677
0
            u64 = *(const uint64_t *)p->data;
678
0
            if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
679
0
                *val = (double)u64;
680
0
                return 1;
681
0
            }
682
0
            break;
683
0
        }
684
0
    } else if (p->data_type == OSSL_PARAM_INTEGER) {
685
0
        switch (p->data_size) {
686
0
        case sizeof(int32_t):
687
0
            *val = *(const int32_t *)p->data;
688
0
            return 1;
689
0
        case sizeof(int64_t):
690
0
            i64 = *(const int64_t *)p->data;
691
0
            u64 = i64 < 0 ? -i64 : i64;
692
0
            if ((u64 >> 53) == 0) { /* 53 significant bits in the mantissa */
693
0
                *val = 0.0 + i64;
694
0
                return 1;
695
0
            }
696
0
            break;
697
0
        }
698
0
    }
699
0
    return 0;
700
0
}
701
702
int OSSL_PARAM_set_double(OSSL_PARAM *p, double val)
703
0
{
704
0
    if (p == NULL)
705
0
        return 0;
706
0
    p->return_size = 0;
707
708
0
    if (p->data_type == OSSL_PARAM_REAL) {
709
0
        p->return_size = sizeof(double);
710
0
        if (p->data == NULL)
711
0
            return 1;
712
0
        switch (p->data_size) {
713
0
        case sizeof(double):
714
0
            *(double *)p->data = val;
715
0
            return 1;
716
0
        }
717
0
    } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER
718
0
               && val == (ossl_uintmax_t)val) {
719
0
        p->return_size = sizeof(double);
720
0
        if (p->data == NULL)
721
0
            return 1;
722
0
        switch (p->data_size) {
723
0
        case sizeof(uint32_t):
724
0
            if (val >= 0 && val <= UINT32_MAX) {
725
0
                p->return_size = sizeof(uint32_t);
726
0
                *(uint32_t *)p->data = (uint32_t)val;
727
0
                return 1;
728
0
            }
729
0
            break;
730
0
        case sizeof(uint64_t):
731
0
            if (val >= 0 && val <= UINT64_MAX) {
732
0
                p->return_size = sizeof(uint64_t);
733
0
                *(uint64_t *)p->data = (uint64_t)val;
734
0
                return 1;
735
0
            }
736
0
            break;            }
737
0
    } else if (p->data_type == OSSL_PARAM_INTEGER && val == (ossl_intmax_t)val) {
738
0
        p->return_size = sizeof(double);
739
0
        if (p->data == NULL)
740
0
            return 1;
741
0
        switch (p->data_size) {
742
0
        case sizeof(int32_t):
743
0
            if (val >= INT32_MIN && val <= INT32_MAX) {
744
0
                p->return_size = sizeof(int32_t);
745
0
                *(int32_t *)p->data = (int32_t)val;
746
0
                return 1;
747
0
            }
748
0
            break;
749
0
        case sizeof(int64_t):
750
0
            if (val >= INT64_MIN && val <= INT64_MAX) {
751
0
                p->return_size = sizeof(int64_t);
752
0
                *(int64_t *)p->data = (int64_t)val;
753
0
                return 1;
754
0
            }
755
0
            break;
756
0
        }
757
0
    }
758
0
    return 0;
759
0
}
760
761
OSSL_PARAM OSSL_PARAM_construct_double(const char *key, double *buf)
762
0
{
763
0
    return ossl_param_construct(key, OSSL_PARAM_REAL, buf, sizeof(double));
764
0
}
765
766
static int get_string_internal(const OSSL_PARAM *p, void **val, size_t max_len,
767
                               size_t *used_len, unsigned int type)
768
0
{
769
0
    size_t sz;
770
771
0
    if (val == NULL || p == NULL || p->data_type != type)
772
0
        return 0;
773
774
0
    sz = p->data_size;
775
776
0
    if (used_len != NULL)
777
0
        *used_len = sz;
778
779
0
    if (sz == 0)
780
0
        return 1;
781
782
0
    if (*val == NULL) {
783
0
        char *const q = OPENSSL_malloc(sz);
784
785
0
        if (q == NULL)
786
0
            return 0;
787
0
        *val = q;
788
0
        memcpy(q, p->data, sz);
789
0
        return 1;
790
0
    }
791
0
    if (max_len < sz)
792
0
        return 0;
793
0
    memcpy(*val, p->data, sz);
794
0
    return 1;
795
0
}
796
797
int OSSL_PARAM_get_utf8_string(const OSSL_PARAM *p, char **val, size_t max_len)
798
0
{
799
0
    return get_string_internal(p, (void **)val, max_len, NULL,
800
0
                               OSSL_PARAM_UTF8_STRING);
801
0
}
802
803
int OSSL_PARAM_get_octet_string(const OSSL_PARAM *p, void **val, size_t max_len,
804
                                size_t *used_len)
805
0
{
806
0
    return get_string_internal(p, val, max_len, used_len,
807
0
                               OSSL_PARAM_OCTET_STRING);
808
0
}
809
810
static int set_string_internal(OSSL_PARAM *p, const void *val, size_t len,
811
                               unsigned int type)
812
0
{
813
0
    p->return_size = len;
814
0
    if (p->data == NULL)
815
0
        return 1;
816
0
    if (p->data_type != type || p->data_size < len)
817
0
        return 0;
818
819
0
    memcpy(p->data, val, len);
820
0
    return 1;
821
0
}
822
823
int OSSL_PARAM_set_utf8_string(OSSL_PARAM *p, const char *val)
824
0
{
825
0
    if (p == NULL)
826
0
        return 0;
827
828
0
    p->return_size = 0;
829
0
    if (val == NULL)
830
0
        return 0;
831
0
    return set_string_internal(p, val, strlen(val) + 1, OSSL_PARAM_UTF8_STRING);
832
0
}
833
834
int OSSL_PARAM_set_octet_string(OSSL_PARAM *p, const void *val,
835
                                size_t len)
836
0
{
837
0
    if (p == NULL)
838
0
        return 0;
839
840
0
    p->return_size = 0;
841
0
    if (val == NULL)
842
0
        return 0;
843
0
    return set_string_internal(p, val, len, OSSL_PARAM_OCTET_STRING);
844
0
}
845
846
OSSL_PARAM OSSL_PARAM_construct_utf8_string(const char *key, char *buf,
847
                                            size_t bsize)
848
0
{
849
0
    if (buf != NULL && bsize == 0)
850
0
        bsize = strlen(buf) + 1;
851
0
    return ossl_param_construct(key, OSSL_PARAM_UTF8_STRING, buf, bsize);
852
0
}
853
854
OSSL_PARAM OSSL_PARAM_construct_octet_string(const char *key, void *buf,
855
                                             size_t bsize)
856
0
{
857
0
    return ossl_param_construct(key, OSSL_PARAM_OCTET_STRING, buf, bsize);
858
0
}
859
860
static int get_ptr_internal(const OSSL_PARAM *p, const void **val,
861
                            size_t *used_len, unsigned int type)
862
0
{
863
0
    if (val == NULL || p == NULL || p->data_type != type)
864
0
        return 0;
865
0
    if (used_len != NULL)
866
0
        *used_len = p->data_size;
867
0
    *val = *(const void **)p->data;
868
0
    return 1;
869
0
}
870
871
int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM *p, const char **val)
872
0
{
873
0
    return get_ptr_internal(p, (const void **)val, NULL, OSSL_PARAM_UTF8_PTR);
874
0
}
875
876
int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, const void **val,
877
                             size_t *used_len)
878
0
{
879
0
    return get_ptr_internal(p, val, used_len, OSSL_PARAM_OCTET_PTR);
880
0
}
881
882
static int set_ptr_internal(OSSL_PARAM *p, const void *val,
883
                            unsigned int type, size_t len)
884
0
{
885
0
    p->return_size = len;
886
0
    if (p->data_type != type)
887
0
        return 0;
888
0
    if (p->data != NULL)
889
0
        *(const void **)p->data = val;
890
0
    return 1;
891
0
}
892
893
int OSSL_PARAM_set_utf8_ptr(OSSL_PARAM *p, const char *val)
894
0
{
895
0
    if (p == NULL)
896
0
        return 0;
897
0
    p->return_size = 0;
898
0
    return set_ptr_internal(p, val, OSSL_PARAM_UTF8_PTR,
899
0
                            val == NULL ? 0 : strlen(val) + 1);
900
0
}
901
902
int OSSL_PARAM_set_octet_ptr(OSSL_PARAM *p, const void *val,
903
                             size_t used_len)
904
0
{
905
0
    if (p == NULL)
906
0
        return 0;
907
0
    p->return_size = 0;
908
0
    return set_ptr_internal(p, val, OSSL_PARAM_OCTET_PTR, used_len);
909
0
}
910
911
OSSL_PARAM OSSL_PARAM_construct_utf8_ptr(const char *key, char **buf,
912
                                         size_t bsize)
913
0
{
914
0
    return ossl_param_construct(key, OSSL_PARAM_UTF8_PTR, buf, bsize);
915
0
}
916
917
OSSL_PARAM OSSL_PARAM_construct_octet_ptr(const char *key, void **buf,
918
                                          size_t bsize)
919
0
{
920
0
    return ossl_param_construct(key, OSSL_PARAM_OCTET_PTR, buf, bsize);
921
0
}
922
923
OSSL_PARAM OSSL_PARAM_construct_end(void)
924
0
{
925
0
    OSSL_PARAM end = OSSL_PARAM_END;
926
927
0
    return end;
928
0
}