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