1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci * Copyright (c) 2019, Oracle and/or its affiliates.  All rights reserved.
4e1051a39Sopenharmony_ci *
5e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
6e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
7e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
8e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
9e1051a39Sopenharmony_ci */
10e1051a39Sopenharmony_ci
11e1051a39Sopenharmony_ci#include <string.h>
12e1051a39Sopenharmony_ci#include <openssl/err.h>
13e1051a39Sopenharmony_ci#include <openssl/cryptoerr.h>
14e1051a39Sopenharmony_ci#include <openssl/params.h>
15e1051a39Sopenharmony_ci#include <openssl/types.h>
16e1051a39Sopenharmony_ci#include <openssl/safestack.h>
17e1051a39Sopenharmony_ci#include "internal/param_build_set.h"
18e1051a39Sopenharmony_ci
19e1051a39Sopenharmony_ci/*
20e1051a39Sopenharmony_ci * Special internal param type to indicate the end of an allocate OSSL_PARAM
21e1051a39Sopenharmony_ci * array.
22e1051a39Sopenharmony_ci */
23e1051a39Sopenharmony_ci
24e1051a39Sopenharmony_citypedef struct {
25e1051a39Sopenharmony_ci    const char *key;
26e1051a39Sopenharmony_ci    int type;
27e1051a39Sopenharmony_ci    int secure;
28e1051a39Sopenharmony_ci    size_t size;
29e1051a39Sopenharmony_ci    size_t alloc_blocks;
30e1051a39Sopenharmony_ci    const BIGNUM *bn;
31e1051a39Sopenharmony_ci    const void *string;
32e1051a39Sopenharmony_ci    union {
33e1051a39Sopenharmony_ci        /*
34e1051a39Sopenharmony_ci         * These fields are never directly addressed, but their sizes are
35e1051a39Sopenharmony_ci         * imporant so that all native types can be copied here without overrun.
36e1051a39Sopenharmony_ci         */
37e1051a39Sopenharmony_ci        ossl_intmax_t i;
38e1051a39Sopenharmony_ci        ossl_uintmax_t u;
39e1051a39Sopenharmony_ci        double d;
40e1051a39Sopenharmony_ci    } num;
41e1051a39Sopenharmony_ci} OSSL_PARAM_BLD_DEF;
42e1051a39Sopenharmony_ci
43e1051a39Sopenharmony_ciDEFINE_STACK_OF(OSSL_PARAM_BLD_DEF)
44e1051a39Sopenharmony_ci
45e1051a39Sopenharmony_cistruct ossl_param_bld_st {
46e1051a39Sopenharmony_ci    size_t total_blocks;
47e1051a39Sopenharmony_ci    size_t secure_blocks;
48e1051a39Sopenharmony_ci    STACK_OF(OSSL_PARAM_BLD_DEF) *params;
49e1051a39Sopenharmony_ci};
50e1051a39Sopenharmony_ci
51e1051a39Sopenharmony_cistatic OSSL_PARAM_BLD_DEF *param_push(OSSL_PARAM_BLD *bld, const char *key,
52e1051a39Sopenharmony_ci                                      int size, size_t alloc, int type,
53e1051a39Sopenharmony_ci                                      int secure)
54e1051a39Sopenharmony_ci{
55e1051a39Sopenharmony_ci    OSSL_PARAM_BLD_DEF *pd = OPENSSL_zalloc(sizeof(*pd));
56e1051a39Sopenharmony_ci
57e1051a39Sopenharmony_ci    if (pd == NULL) {
58e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
59e1051a39Sopenharmony_ci        return NULL;
60e1051a39Sopenharmony_ci    }
61e1051a39Sopenharmony_ci    pd->key = key;
62e1051a39Sopenharmony_ci    pd->type = type;
63e1051a39Sopenharmony_ci    pd->size = size;
64e1051a39Sopenharmony_ci    pd->alloc_blocks = ossl_param_bytes_to_blocks(alloc);
65e1051a39Sopenharmony_ci    if ((pd->secure = secure) != 0)
66e1051a39Sopenharmony_ci        bld->secure_blocks += pd->alloc_blocks;
67e1051a39Sopenharmony_ci    else
68e1051a39Sopenharmony_ci        bld->total_blocks += pd->alloc_blocks;
69e1051a39Sopenharmony_ci    if (sk_OSSL_PARAM_BLD_DEF_push(bld->params, pd) <= 0) {
70e1051a39Sopenharmony_ci        OPENSSL_free(pd);
71e1051a39Sopenharmony_ci        pd = NULL;
72e1051a39Sopenharmony_ci    }
73e1051a39Sopenharmony_ci    return pd;
74e1051a39Sopenharmony_ci}
75e1051a39Sopenharmony_ci
76e1051a39Sopenharmony_cistatic int param_push_num(OSSL_PARAM_BLD *bld, const char *key,
77e1051a39Sopenharmony_ci                          void *num, size_t size, int type)
78e1051a39Sopenharmony_ci{
79e1051a39Sopenharmony_ci    OSSL_PARAM_BLD_DEF *pd = param_push(bld, key, size, size, type, 0);
80e1051a39Sopenharmony_ci
81e1051a39Sopenharmony_ci    if (pd == NULL)
82e1051a39Sopenharmony_ci        return 0;
83e1051a39Sopenharmony_ci    if (size > sizeof(pd->num)) {
84e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_BYTES);
85e1051a39Sopenharmony_ci        return 0;
86e1051a39Sopenharmony_ci    }
87e1051a39Sopenharmony_ci    memcpy(&pd->num, num, size);
88e1051a39Sopenharmony_ci    return 1;
89e1051a39Sopenharmony_ci}
90e1051a39Sopenharmony_ci
91e1051a39Sopenharmony_ciOSSL_PARAM_BLD *OSSL_PARAM_BLD_new(void)
92e1051a39Sopenharmony_ci{
93e1051a39Sopenharmony_ci    OSSL_PARAM_BLD *r = OPENSSL_zalloc(sizeof(OSSL_PARAM_BLD));
94e1051a39Sopenharmony_ci
95e1051a39Sopenharmony_ci    if (r != NULL) {
96e1051a39Sopenharmony_ci        r->params = sk_OSSL_PARAM_BLD_DEF_new_null();
97e1051a39Sopenharmony_ci        if (r->params == NULL) {
98e1051a39Sopenharmony_ci            OPENSSL_free(r);
99e1051a39Sopenharmony_ci            r = NULL;
100e1051a39Sopenharmony_ci        }
101e1051a39Sopenharmony_ci    }
102e1051a39Sopenharmony_ci    return r;
103e1051a39Sopenharmony_ci}
104e1051a39Sopenharmony_ci
105e1051a39Sopenharmony_cistatic void free_all_params(OSSL_PARAM_BLD *bld)
106e1051a39Sopenharmony_ci{
107e1051a39Sopenharmony_ci    int i, n = sk_OSSL_PARAM_BLD_DEF_num(bld->params);
108e1051a39Sopenharmony_ci
109e1051a39Sopenharmony_ci    for (i = 0; i < n; i++)
110e1051a39Sopenharmony_ci        OPENSSL_free(sk_OSSL_PARAM_BLD_DEF_pop(bld->params));
111e1051a39Sopenharmony_ci}
112e1051a39Sopenharmony_ci
113e1051a39Sopenharmony_civoid OSSL_PARAM_BLD_free(OSSL_PARAM_BLD *bld)
114e1051a39Sopenharmony_ci{
115e1051a39Sopenharmony_ci    if (bld == NULL)
116e1051a39Sopenharmony_ci        return;
117e1051a39Sopenharmony_ci    free_all_params(bld);
118e1051a39Sopenharmony_ci    sk_OSSL_PARAM_BLD_DEF_free(bld->params);
119e1051a39Sopenharmony_ci    OPENSSL_free(bld);
120e1051a39Sopenharmony_ci}
121e1051a39Sopenharmony_ci
122e1051a39Sopenharmony_ciint OSSL_PARAM_BLD_push_int(OSSL_PARAM_BLD *bld, const char *key, int num)
123e1051a39Sopenharmony_ci{
124e1051a39Sopenharmony_ci    return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_INTEGER);
125e1051a39Sopenharmony_ci}
126e1051a39Sopenharmony_ci
127e1051a39Sopenharmony_ciint OSSL_PARAM_BLD_push_uint(OSSL_PARAM_BLD *bld, const char *key,
128e1051a39Sopenharmony_ci                             unsigned int num)
129e1051a39Sopenharmony_ci{
130e1051a39Sopenharmony_ci    return param_push_num(bld, key, &num, sizeof(num),
131e1051a39Sopenharmony_ci                          OSSL_PARAM_UNSIGNED_INTEGER);
132e1051a39Sopenharmony_ci}
133e1051a39Sopenharmony_ci
134e1051a39Sopenharmony_ciint OSSL_PARAM_BLD_push_long(OSSL_PARAM_BLD *bld, const char *key,
135e1051a39Sopenharmony_ci                             long int num)
136e1051a39Sopenharmony_ci{
137e1051a39Sopenharmony_ci    return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_INTEGER);
138e1051a39Sopenharmony_ci}
139e1051a39Sopenharmony_ci
140e1051a39Sopenharmony_ciint OSSL_PARAM_BLD_push_ulong(OSSL_PARAM_BLD *bld, const char *key,
141e1051a39Sopenharmony_ci                              unsigned long int num)
142e1051a39Sopenharmony_ci{
143e1051a39Sopenharmony_ci    return param_push_num(bld, key, &num, sizeof(num),
144e1051a39Sopenharmony_ci                          OSSL_PARAM_UNSIGNED_INTEGER);
145e1051a39Sopenharmony_ci}
146e1051a39Sopenharmony_ci
147e1051a39Sopenharmony_ciint OSSL_PARAM_BLD_push_int32(OSSL_PARAM_BLD *bld, const char *key,
148e1051a39Sopenharmony_ci                              int32_t num)
149e1051a39Sopenharmony_ci{
150e1051a39Sopenharmony_ci    return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_INTEGER);
151e1051a39Sopenharmony_ci}
152e1051a39Sopenharmony_ci
153e1051a39Sopenharmony_ciint OSSL_PARAM_BLD_push_uint32(OSSL_PARAM_BLD *bld, const char *key,
154e1051a39Sopenharmony_ci                               uint32_t num)
155e1051a39Sopenharmony_ci{
156e1051a39Sopenharmony_ci    return param_push_num(bld, key, &num, sizeof(num),
157e1051a39Sopenharmony_ci                          OSSL_PARAM_UNSIGNED_INTEGER);
158e1051a39Sopenharmony_ci}
159e1051a39Sopenharmony_ci
160e1051a39Sopenharmony_ciint OSSL_PARAM_BLD_push_int64(OSSL_PARAM_BLD *bld, const char *key,
161e1051a39Sopenharmony_ci                              int64_t num)
162e1051a39Sopenharmony_ci{
163e1051a39Sopenharmony_ci    return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_INTEGER);
164e1051a39Sopenharmony_ci}
165e1051a39Sopenharmony_ci
166e1051a39Sopenharmony_ciint OSSL_PARAM_BLD_push_uint64(OSSL_PARAM_BLD *bld, const char *key,
167e1051a39Sopenharmony_ci                               uint64_t num)
168e1051a39Sopenharmony_ci{
169e1051a39Sopenharmony_ci    return param_push_num(bld, key, &num, sizeof(num),
170e1051a39Sopenharmony_ci                          OSSL_PARAM_UNSIGNED_INTEGER);
171e1051a39Sopenharmony_ci}
172e1051a39Sopenharmony_ci
173e1051a39Sopenharmony_ciint OSSL_PARAM_BLD_push_size_t(OSSL_PARAM_BLD *bld, const char *key,
174e1051a39Sopenharmony_ci                               size_t num)
175e1051a39Sopenharmony_ci{
176e1051a39Sopenharmony_ci    return param_push_num(bld, key, &num, sizeof(num),
177e1051a39Sopenharmony_ci                          OSSL_PARAM_UNSIGNED_INTEGER);
178e1051a39Sopenharmony_ci}
179e1051a39Sopenharmony_ci
180e1051a39Sopenharmony_ciint OSSL_PARAM_BLD_push_time_t(OSSL_PARAM_BLD *bld, const char *key,
181e1051a39Sopenharmony_ci                               time_t num)
182e1051a39Sopenharmony_ci{
183e1051a39Sopenharmony_ci    return param_push_num(bld, key, &num, sizeof(num),
184e1051a39Sopenharmony_ci                          OSSL_PARAM_INTEGER);
185e1051a39Sopenharmony_ci}
186e1051a39Sopenharmony_ci
187e1051a39Sopenharmony_ciint OSSL_PARAM_BLD_push_double(OSSL_PARAM_BLD *bld, const char *key,
188e1051a39Sopenharmony_ci                               double num)
189e1051a39Sopenharmony_ci{
190e1051a39Sopenharmony_ci    return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_REAL);
191e1051a39Sopenharmony_ci}
192e1051a39Sopenharmony_ci
193e1051a39Sopenharmony_ciint OSSL_PARAM_BLD_push_BN(OSSL_PARAM_BLD *bld, const char *key,
194e1051a39Sopenharmony_ci                           const BIGNUM *bn)
195e1051a39Sopenharmony_ci{
196e1051a39Sopenharmony_ci    return OSSL_PARAM_BLD_push_BN_pad(bld, key, bn,
197e1051a39Sopenharmony_ci                                      bn == NULL ? 0 : BN_num_bytes(bn));
198e1051a39Sopenharmony_ci}
199e1051a39Sopenharmony_ci
200e1051a39Sopenharmony_ciint OSSL_PARAM_BLD_push_BN_pad(OSSL_PARAM_BLD *bld, const char *key,
201e1051a39Sopenharmony_ci                               const BIGNUM *bn, size_t sz)
202e1051a39Sopenharmony_ci{
203e1051a39Sopenharmony_ci    int n, secure = 0;
204e1051a39Sopenharmony_ci    OSSL_PARAM_BLD_DEF *pd;
205e1051a39Sopenharmony_ci
206e1051a39Sopenharmony_ci    if (bn != NULL) {
207e1051a39Sopenharmony_ci        if (BN_is_negative(bn)) {
208e1051a39Sopenharmony_ci            ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_UNSUPPORTED,
209e1051a39Sopenharmony_ci                           "Negative big numbers are unsupported for OSSL_PARAM");
210e1051a39Sopenharmony_ci            return 0;
211e1051a39Sopenharmony_ci        }
212e1051a39Sopenharmony_ci
213e1051a39Sopenharmony_ci        n = BN_num_bytes(bn);
214e1051a39Sopenharmony_ci        if (n < 0) {
215e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_ZERO_LENGTH_NUMBER);
216e1051a39Sopenharmony_ci            return 0;
217e1051a39Sopenharmony_ci        }
218e1051a39Sopenharmony_ci        if (sz < (size_t)n) {
219e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_SMALL_BUFFER);
220e1051a39Sopenharmony_ci            return 0;
221e1051a39Sopenharmony_ci        }
222e1051a39Sopenharmony_ci        if (BN_get_flags(bn, BN_FLG_SECURE) == BN_FLG_SECURE)
223e1051a39Sopenharmony_ci            secure = 1;
224e1051a39Sopenharmony_ci
225e1051a39Sopenharmony_ci        /* The BIGNUM is zero, we must transfer at least one byte */
226e1051a39Sopenharmony_ci        if (sz == 0)
227e1051a39Sopenharmony_ci            sz++;
228e1051a39Sopenharmony_ci    }
229e1051a39Sopenharmony_ci    pd = param_push(bld, key, sz, sz, OSSL_PARAM_UNSIGNED_INTEGER, secure);
230e1051a39Sopenharmony_ci    if (pd == NULL)
231e1051a39Sopenharmony_ci        return 0;
232e1051a39Sopenharmony_ci    pd->bn = bn;
233e1051a39Sopenharmony_ci    return 1;
234e1051a39Sopenharmony_ci}
235e1051a39Sopenharmony_ci
236e1051a39Sopenharmony_ciint OSSL_PARAM_BLD_push_utf8_string(OSSL_PARAM_BLD *bld, const char *key,
237e1051a39Sopenharmony_ci                                    const char *buf, size_t bsize)
238e1051a39Sopenharmony_ci{
239e1051a39Sopenharmony_ci    OSSL_PARAM_BLD_DEF *pd;
240e1051a39Sopenharmony_ci    int secure;
241e1051a39Sopenharmony_ci
242e1051a39Sopenharmony_ci    if (bsize == 0) {
243e1051a39Sopenharmony_ci        bsize = strlen(buf);
244e1051a39Sopenharmony_ci    } else if (bsize > INT_MAX) {
245e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_STRING_TOO_LONG);
246e1051a39Sopenharmony_ci        return 0;
247e1051a39Sopenharmony_ci    }
248e1051a39Sopenharmony_ci    secure = CRYPTO_secure_allocated(buf);
249e1051a39Sopenharmony_ci    pd = param_push(bld, key, bsize, bsize + 1, OSSL_PARAM_UTF8_STRING, secure);
250e1051a39Sopenharmony_ci    if (pd == NULL)
251e1051a39Sopenharmony_ci        return 0;
252e1051a39Sopenharmony_ci    pd->string = buf;
253e1051a39Sopenharmony_ci    return 1;
254e1051a39Sopenharmony_ci}
255e1051a39Sopenharmony_ci
256e1051a39Sopenharmony_ciint OSSL_PARAM_BLD_push_utf8_ptr(OSSL_PARAM_BLD *bld, const char *key,
257e1051a39Sopenharmony_ci                                 char *buf, size_t bsize)
258e1051a39Sopenharmony_ci{
259e1051a39Sopenharmony_ci    OSSL_PARAM_BLD_DEF *pd;
260e1051a39Sopenharmony_ci
261e1051a39Sopenharmony_ci    if (bsize == 0) {
262e1051a39Sopenharmony_ci        bsize = strlen(buf);
263e1051a39Sopenharmony_ci    } else if (bsize > INT_MAX) {
264e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_STRING_TOO_LONG);
265e1051a39Sopenharmony_ci        return 0;
266e1051a39Sopenharmony_ci    }
267e1051a39Sopenharmony_ci    pd = param_push(bld, key, bsize, sizeof(buf), OSSL_PARAM_UTF8_PTR, 0);
268e1051a39Sopenharmony_ci    if (pd == NULL)
269e1051a39Sopenharmony_ci        return 0;
270e1051a39Sopenharmony_ci    pd->string = buf;
271e1051a39Sopenharmony_ci    return 1;
272e1051a39Sopenharmony_ci}
273e1051a39Sopenharmony_ci
274e1051a39Sopenharmony_ciint OSSL_PARAM_BLD_push_octet_string(OSSL_PARAM_BLD *bld, const char *key,
275e1051a39Sopenharmony_ci                                     const void *buf, size_t bsize)
276e1051a39Sopenharmony_ci{
277e1051a39Sopenharmony_ci    OSSL_PARAM_BLD_DEF *pd;
278e1051a39Sopenharmony_ci    int secure;
279e1051a39Sopenharmony_ci
280e1051a39Sopenharmony_ci    if (bsize > INT_MAX) {
281e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_STRING_TOO_LONG);
282e1051a39Sopenharmony_ci        return 0;
283e1051a39Sopenharmony_ci    }
284e1051a39Sopenharmony_ci    secure = CRYPTO_secure_allocated(buf);
285e1051a39Sopenharmony_ci    pd = param_push(bld, key, bsize, bsize, OSSL_PARAM_OCTET_STRING, secure);
286e1051a39Sopenharmony_ci    if (pd == NULL)
287e1051a39Sopenharmony_ci        return 0;
288e1051a39Sopenharmony_ci    pd->string = buf;
289e1051a39Sopenharmony_ci    return 1;
290e1051a39Sopenharmony_ci}
291e1051a39Sopenharmony_ci
292e1051a39Sopenharmony_ciint OSSL_PARAM_BLD_push_octet_ptr(OSSL_PARAM_BLD *bld, const char *key,
293e1051a39Sopenharmony_ci                                  void *buf, size_t bsize)
294e1051a39Sopenharmony_ci{
295e1051a39Sopenharmony_ci    OSSL_PARAM_BLD_DEF *pd;
296e1051a39Sopenharmony_ci
297e1051a39Sopenharmony_ci    if (bsize > INT_MAX) {
298e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_STRING_TOO_LONG);
299e1051a39Sopenharmony_ci        return 0;
300e1051a39Sopenharmony_ci    }
301e1051a39Sopenharmony_ci    pd = param_push(bld, key, bsize, sizeof(buf), OSSL_PARAM_OCTET_PTR, 0);
302e1051a39Sopenharmony_ci    if (pd == NULL)
303e1051a39Sopenharmony_ci        return 0;
304e1051a39Sopenharmony_ci    pd->string = buf;
305e1051a39Sopenharmony_ci    return 1;
306e1051a39Sopenharmony_ci}
307e1051a39Sopenharmony_ci
308e1051a39Sopenharmony_cistatic OSSL_PARAM *param_bld_convert(OSSL_PARAM_BLD *bld, OSSL_PARAM *param,
309e1051a39Sopenharmony_ci                                     OSSL_PARAM_ALIGNED_BLOCK *blk,
310e1051a39Sopenharmony_ci                                     OSSL_PARAM_ALIGNED_BLOCK *secure)
311e1051a39Sopenharmony_ci{
312e1051a39Sopenharmony_ci    int i, num = sk_OSSL_PARAM_BLD_DEF_num(bld->params);
313e1051a39Sopenharmony_ci    OSSL_PARAM_BLD_DEF *pd;
314e1051a39Sopenharmony_ci    void *p;
315e1051a39Sopenharmony_ci
316e1051a39Sopenharmony_ci    for (i = 0; i < num; i++) {
317e1051a39Sopenharmony_ci        pd = sk_OSSL_PARAM_BLD_DEF_value(bld->params, i);
318e1051a39Sopenharmony_ci        param[i].key = pd->key;
319e1051a39Sopenharmony_ci        param[i].data_type = pd->type;
320e1051a39Sopenharmony_ci        param[i].data_size = pd->size;
321e1051a39Sopenharmony_ci        param[i].return_size = OSSL_PARAM_UNMODIFIED;
322e1051a39Sopenharmony_ci
323e1051a39Sopenharmony_ci        if (pd->secure) {
324e1051a39Sopenharmony_ci            p = secure;
325e1051a39Sopenharmony_ci            secure += pd->alloc_blocks;
326e1051a39Sopenharmony_ci        } else {
327e1051a39Sopenharmony_ci            p = blk;
328e1051a39Sopenharmony_ci            blk += pd->alloc_blocks;
329e1051a39Sopenharmony_ci        }
330e1051a39Sopenharmony_ci        param[i].data = p;
331e1051a39Sopenharmony_ci        if (pd->bn != NULL) {
332e1051a39Sopenharmony_ci            /* BIGNUM */
333e1051a39Sopenharmony_ci            BN_bn2nativepad(pd->bn, (unsigned char *)p, pd->size);
334e1051a39Sopenharmony_ci        } else if (pd->type == OSSL_PARAM_OCTET_PTR
335e1051a39Sopenharmony_ci                   || pd->type == OSSL_PARAM_UTF8_PTR) {
336e1051a39Sopenharmony_ci            /* PTR */
337e1051a39Sopenharmony_ci            *(const void **)p = pd->string;
338e1051a39Sopenharmony_ci        } else if (pd->type == OSSL_PARAM_OCTET_STRING
339e1051a39Sopenharmony_ci                   || pd->type == OSSL_PARAM_UTF8_STRING) {
340e1051a39Sopenharmony_ci            if (pd->string != NULL)
341e1051a39Sopenharmony_ci                memcpy(p, pd->string, pd->size);
342e1051a39Sopenharmony_ci            else
343e1051a39Sopenharmony_ci                memset(p, 0, pd->size);
344e1051a39Sopenharmony_ci            if (pd->type == OSSL_PARAM_UTF8_STRING)
345e1051a39Sopenharmony_ci                ((char *)p)[pd->size] = '\0';
346e1051a39Sopenharmony_ci        } else {
347e1051a39Sopenharmony_ci            /* Number, but could also be a NULL BIGNUM */
348e1051a39Sopenharmony_ci            if (pd->size > sizeof(pd->num))
349e1051a39Sopenharmony_ci                memset(p, 0, pd->size);
350e1051a39Sopenharmony_ci            else if (pd->size > 0)
351e1051a39Sopenharmony_ci                memcpy(p, &pd->num, pd->size);
352e1051a39Sopenharmony_ci        }
353e1051a39Sopenharmony_ci    }
354e1051a39Sopenharmony_ci    param[i] = OSSL_PARAM_construct_end();
355e1051a39Sopenharmony_ci    return param + i;
356e1051a39Sopenharmony_ci}
357e1051a39Sopenharmony_ci
358e1051a39Sopenharmony_ciOSSL_PARAM *OSSL_PARAM_BLD_to_param(OSSL_PARAM_BLD *bld)
359e1051a39Sopenharmony_ci{
360e1051a39Sopenharmony_ci    OSSL_PARAM_ALIGNED_BLOCK *blk, *s = NULL;
361e1051a39Sopenharmony_ci    OSSL_PARAM *params, *last;
362e1051a39Sopenharmony_ci    const int num = sk_OSSL_PARAM_BLD_DEF_num(bld->params);
363e1051a39Sopenharmony_ci    const size_t p_blks = ossl_param_bytes_to_blocks((1 + num) * sizeof(*params));
364e1051a39Sopenharmony_ci    const size_t total = OSSL_PARAM_ALIGN_SIZE * (p_blks + bld->total_blocks);
365e1051a39Sopenharmony_ci    const size_t ss = OSSL_PARAM_ALIGN_SIZE * bld->secure_blocks;
366e1051a39Sopenharmony_ci
367e1051a39Sopenharmony_ci    if (ss > 0) {
368e1051a39Sopenharmony_ci        s = OPENSSL_secure_malloc(ss);
369e1051a39Sopenharmony_ci        if (s == NULL) {
370e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_SECURE_MALLOC_FAILURE);
371e1051a39Sopenharmony_ci            return NULL;
372e1051a39Sopenharmony_ci        }
373e1051a39Sopenharmony_ci    }
374e1051a39Sopenharmony_ci    params = OPENSSL_malloc(total);
375e1051a39Sopenharmony_ci    if (params == NULL) {
376e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
377e1051a39Sopenharmony_ci        OPENSSL_secure_free(s);
378e1051a39Sopenharmony_ci        return NULL;
379e1051a39Sopenharmony_ci    }
380e1051a39Sopenharmony_ci    blk = p_blks + (OSSL_PARAM_ALIGNED_BLOCK *)(params);
381e1051a39Sopenharmony_ci    last = param_bld_convert(bld, params, blk, s);
382e1051a39Sopenharmony_ci    ossl_param_set_secure_block(last, s, ss);
383e1051a39Sopenharmony_ci
384e1051a39Sopenharmony_ci    /* Reset builder for reuse */
385e1051a39Sopenharmony_ci    bld->total_blocks = 0;
386e1051a39Sopenharmony_ci    bld->secure_blocks = 0;
387e1051a39Sopenharmony_ci    free_all_params(bld);
388e1051a39Sopenharmony_ci    return params;
389e1051a39Sopenharmony_ci}
390