2 * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
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
12 #include <openssl/err.h>
13 #include <openssl/cryptoerr.h>
14 #include <openssl/params.h>
15 #include <openssl/types.h>
16 #include <openssl/safestack.h>
17 #include "internal/cryptlib.h"
18 #include "openssl/param_build.h"
21 * Special internal param type to indicate the end of an allocate OSSL_PARAM
24 #define OSSL_PARAM_ALLOCATED_END 127
36 * These fields are never directly addressed, but their sizes are
37 * imporant so that all native types can be copied here without overrun.
45 DEFINE_STACK_OF(OSSL_PARAM_BLD_DEF
)
47 struct ossl_param_bld_st
{
50 STACK_OF(OSSL_PARAM_BLD_DEF
) *params
;
55 } OSSL_PARAM_BLD_BLOCK
;
57 #define ALIGN_SIZE sizeof(OSSL_PARAM_BLD_BLOCK)
59 static size_t bytes_to_blocks(size_t bytes
)
61 return (bytes
+ ALIGN_SIZE
- 1) / ALIGN_SIZE
;
64 static OSSL_PARAM_BLD_DEF
*param_push(OSSL_PARAM_BLD
*bld
, const char *key
,
65 int size
, size_t alloc
, int type
,
68 OSSL_PARAM_BLD_DEF
*pd
= OPENSSL_zalloc(sizeof(*pd
));
71 CRYPTOerr(CRYPTO_F_PARAM_PUSH
, ERR_R_MALLOC_FAILURE
);
77 pd
->alloc_blocks
= bytes_to_blocks(size
);
78 if ((pd
->secure
= secure
) != 0)
79 bld
->secure_blocks
+= pd
->alloc_blocks
;
81 bld
->total_blocks
+= pd
->alloc_blocks
;
82 if (sk_OSSL_PARAM_BLD_DEF_push(bld
->params
, pd
) <= 0) {
89 static int param_push_num(OSSL_PARAM_BLD
*bld
, const char *key
,
90 void *num
, size_t size
, int type
)
92 OSSL_PARAM_BLD_DEF
*pd
= param_push(bld
, key
, size
, size
, type
, 0);
96 if (size
> sizeof(pd
->num
)) {
97 CRYPTOerr(CRYPTO_F_PARAM_PUSH_NUM
, CRYPTO_R_TOO_MANY_BYTES
);
100 memcpy(&pd
->num
, num
, size
);
104 OSSL_PARAM_BLD
*OSSL_PARAM_BLD_new(void)
106 OSSL_PARAM_BLD
*r
= OPENSSL_zalloc(sizeof(OSSL_PARAM_BLD
));
109 r
->params
= sk_OSSL_PARAM_BLD_DEF_new_null();
110 if (r
->params
== NULL
) {
118 static void free_all_params(OSSL_PARAM_BLD
*bld
)
120 int i
, n
= sk_OSSL_PARAM_BLD_DEF_num(bld
->params
);
122 for (i
= 0; i
< n
; i
++)
123 OPENSSL_free(sk_OSSL_PARAM_BLD_DEF_pop(bld
->params
));
126 void OSSL_PARAM_BLD_free(OSSL_PARAM_BLD
*bld
)
128 free_all_params(bld
);
129 sk_OSSL_PARAM_BLD_DEF_free(bld
->params
);
133 int OSSL_PARAM_BLD_push_int(OSSL_PARAM_BLD
*bld
, const char *key
, int num
)
135 return param_push_num(bld
, key
, &num
, sizeof(num
), OSSL_PARAM_INTEGER
);
138 int OSSL_PARAM_BLD_push_uint(OSSL_PARAM_BLD
*bld
, const char *key
,
141 return param_push_num(bld
, key
, &num
, sizeof(num
),
142 OSSL_PARAM_UNSIGNED_INTEGER
);
145 int OSSL_PARAM_BLD_push_long(OSSL_PARAM_BLD
*bld
, const char *key
,
148 return param_push_num(bld
, key
, &num
, sizeof(num
), OSSL_PARAM_INTEGER
);
151 int OSSL_PARAM_BLD_push_ulong(OSSL_PARAM_BLD
*bld
, const char *key
,
152 unsigned long int num
)
154 return param_push_num(bld
, key
, &num
, sizeof(num
),
155 OSSL_PARAM_UNSIGNED_INTEGER
);
158 int OSSL_PARAM_BLD_push_int32(OSSL_PARAM_BLD
*bld
, const char *key
,
161 return param_push_num(bld
, key
, &num
, sizeof(num
), OSSL_PARAM_INTEGER
);
164 int OSSL_PARAM_BLD_push_uint32(OSSL_PARAM_BLD
*bld
, const char *key
,
167 return param_push_num(bld
, key
, &num
, sizeof(num
),
168 OSSL_PARAM_UNSIGNED_INTEGER
);
171 int OSSL_PARAM_BLD_push_int64(OSSL_PARAM_BLD
*bld
, const char *key
,
174 return param_push_num(bld
, key
, &num
, sizeof(num
), OSSL_PARAM_INTEGER
);
177 int OSSL_PARAM_BLD_push_uint64(OSSL_PARAM_BLD
*bld
, const char *key
,
180 return param_push_num(bld
, key
, &num
, sizeof(num
),
181 OSSL_PARAM_UNSIGNED_INTEGER
);
184 int OSSL_PARAM_BLD_push_size_t(OSSL_PARAM_BLD
*bld
, const char *key
,
187 return param_push_num(bld
, key
, &num
, sizeof(num
),
188 OSSL_PARAM_UNSIGNED_INTEGER
);
191 int OSSL_PARAM_BLD_push_double(OSSL_PARAM_BLD
*bld
, const char *key
,
194 return param_push_num(bld
, key
, &num
, sizeof(num
), OSSL_PARAM_REAL
);
197 int OSSL_PARAM_BLD_push_BN(OSSL_PARAM_BLD
*bld
, const char *key
,
200 return OSSL_PARAM_BLD_push_BN_pad(bld
, key
, bn
,
201 bn
== NULL
? 0 : BN_num_bytes(bn
));
204 int OSSL_PARAM_BLD_push_BN_pad(OSSL_PARAM_BLD
*bld
, const char *key
,
205 const BIGNUM
*bn
, size_t sz
)
208 OSSL_PARAM_BLD_DEF
*pd
;
211 n
= BN_num_bytes(bn
);
213 CRYPTOerr(0, CRYPTO_R_ZERO_LENGTH_NUMBER
);
216 if (sz
< (size_t)n
) {
217 CRYPTOerr(0, CRYPTO_R_TOO_SMALL_BUFFER
);
220 if (BN_get_flags(bn
, BN_FLG_SECURE
) == BN_FLG_SECURE
)
223 pd
= param_push(bld
, key
, sz
, sz
, OSSL_PARAM_UNSIGNED_INTEGER
, secure
);
230 int OSSL_PARAM_BLD_push_utf8_string(OSSL_PARAM_BLD
*bld
, const char *key
,
231 const char *buf
, size_t bsize
)
233 OSSL_PARAM_BLD_DEF
*pd
;
236 bsize
= strlen(buf
) + 1;
237 } else if (bsize
> INT_MAX
) {
238 CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_PUSH_UTF8_STRING
,
239 CRYPTO_R_STRING_TOO_LONG
);
242 pd
= param_push(bld
, key
, bsize
, bsize
, OSSL_PARAM_UTF8_STRING
, 0);
249 int OSSL_PARAM_BLD_push_utf8_ptr(OSSL_PARAM_BLD
*bld
, const char *key
,
250 char *buf
, size_t bsize
)
252 OSSL_PARAM_BLD_DEF
*pd
;
255 bsize
= strlen(buf
) + 1;
256 } else if (bsize
> INT_MAX
) {
257 CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_PUSH_UTF8_PTR
,
258 CRYPTO_R_STRING_TOO_LONG
);
261 pd
= param_push(bld
, key
, bsize
, sizeof(buf
), OSSL_PARAM_UTF8_PTR
, 0);
268 int OSSL_PARAM_BLD_push_octet_string(OSSL_PARAM_BLD
*bld
, const char *key
,
269 const void *buf
, size_t bsize
)
271 OSSL_PARAM_BLD_DEF
*pd
;
273 if (bsize
> INT_MAX
) {
274 CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_PUSH_OCTET_STRING
,
275 CRYPTO_R_STRING_TOO_LONG
);
278 pd
= param_push(bld
, key
, bsize
, bsize
, OSSL_PARAM_OCTET_STRING
, 0);
285 int OSSL_PARAM_BLD_push_octet_ptr(OSSL_PARAM_BLD
*bld
, const char *key
,
286 void *buf
, size_t bsize
)
288 OSSL_PARAM_BLD_DEF
*pd
;
290 if (bsize
> INT_MAX
) {
291 CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_PUSH_OCTET_PTR
,
292 CRYPTO_R_STRING_TOO_LONG
);
295 pd
= param_push(bld
, key
, bsize
, sizeof(buf
), OSSL_PARAM_OCTET_PTR
, 0);
302 static OSSL_PARAM
*param_bld_convert(OSSL_PARAM_BLD
*bld
, OSSL_PARAM
*param
,
303 OSSL_PARAM_BLD_BLOCK
*blk
,
304 OSSL_PARAM_BLD_BLOCK
*secure
)
306 int i
, num
= sk_OSSL_PARAM_BLD_DEF_num(bld
->params
);
307 OSSL_PARAM_BLD_DEF
*pd
;
310 for (i
= 0; i
< num
; i
++) {
311 pd
= sk_OSSL_PARAM_BLD_DEF_value(bld
->params
, i
);
312 param
[i
].key
= pd
->key
;
313 param
[i
].data_type
= pd
->type
;
314 param
[i
].data_size
= pd
->size
;
315 param
[i
].return_size
= 0;
319 secure
+= pd
->alloc_blocks
;
322 blk
+= pd
->alloc_blocks
;
325 if (pd
->bn
!= NULL
) {
327 BN_bn2nativepad(pd
->bn
, (unsigned char *)p
, pd
->size
);
328 } else if (pd
->type
== OSSL_PARAM_OCTET_PTR
329 || pd
->type
== OSSL_PARAM_UTF8_PTR
) {
331 *(const void **)p
= pd
->string
;
332 } else if (pd
->type
== OSSL_PARAM_OCTET_STRING
333 || pd
->type
== OSSL_PARAM_UTF8_STRING
) {
334 if (pd
->string
!= NULL
)
335 memcpy(p
, pd
->string
, pd
->size
);
337 memset(p
, 0, pd
->size
);
339 /* Number, but could also be a NULL BIGNUM */
340 if (pd
->size
> sizeof(pd
->num
))
341 memset(p
, 0, pd
->size
);
342 else if (pd
->size
> 0)
343 memcpy(p
, &pd
->num
, pd
->size
);
346 param
[i
] = OSSL_PARAM_construct_end();
350 OSSL_PARAM
*OSSL_PARAM_BLD_to_param(OSSL_PARAM_BLD
*bld
)
352 OSSL_PARAM_BLD_BLOCK
*blk
, *s
= NULL
;
353 OSSL_PARAM
*params
, *last
;
354 const int num
= sk_OSSL_PARAM_BLD_DEF_num(bld
->params
);
355 const size_t p_blks
= bytes_to_blocks((1 + num
) * sizeof(*params
));
356 const size_t total
= ALIGN_SIZE
* (p_blks
+ bld
->total_blocks
);
357 const size_t ss
= ALIGN_SIZE
* bld
->secure_blocks
;
360 s
= OPENSSL_secure_malloc(ss
);
362 CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM
,
363 CRYPTO_R_SECURE_MALLOC_FAILURE
);
368 params
= OPENSSL_malloc(total
);
369 if (params
== NULL
) {
370 CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM
, ERR_R_MALLOC_FAILURE
);
372 OPENSSL_secure_free(s
);
375 blk
= p_blks
+ (OSSL_PARAM_BLD_BLOCK
*)(params
);
376 last
= param_bld_convert(bld
, params
, blk
, s
);
377 last
->data_size
= ss
;
379 last
->data_type
= OSSL_PARAM_ALLOCATED_END
;
381 /* Reset builder for reuse */
382 bld
->total_blocks
= 0;
383 bld
->secure_blocks
= 0;
384 free_all_params(bld
);
388 void OSSL_PARAM_BLD_free_params(OSSL_PARAM
*params
)
390 if (params
!= NULL
) {
393 for (p
= params
; p
->key
!= NULL
; p
++)
395 if (p
->data_type
== OSSL_PARAM_ALLOCATED_END
)
396 OPENSSL_secure_clear_free(p
->data
, p
->data_size
);
397 OPENSSL_free(params
);