2 * Copyright 2019 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 "internal/cryptlib.h"
16 #include "internal/param_build.h"
18 #define OSSL_PARAM_ALLOCATED_END 127
22 } OSSL_PARAM_BLD_BLOCK
;
24 #define ALIGN_SIZE sizeof(OSSL_PARAM_BLD_BLOCK)
26 static size_t bytes_to_blocks(size_t bytes
)
28 return (bytes
+ ALIGN_SIZE
- 1) / ALIGN_SIZE
;
31 static OSSL_PARAM_BLD_DEF
*param_push(OSSL_PARAM_BLD
*bld
, const char *key
,
32 int size
, size_t alloc
, int type
,
35 OSSL_PARAM_BLD_DEF
*pd
;
37 if (bld
->curr
>= OSSL_PARAM_BLD_MAX
) {
38 CRYPTOerr(CRYPTO_F_PARAM_PUSH
, CRYPTO_R_TOO_MANY_RECORDS
);
41 pd
= bld
->params
+ bld
->curr
++;
42 memset(pd
, 0, sizeof(*pd
));
46 pd
->alloc_blocks
= bytes_to_blocks(size
);
47 if ((pd
->secure
= secure
) != 0)
48 bld
->secure_blocks
+= pd
->alloc_blocks
;
50 bld
->total_blocks
+= pd
->alloc_blocks
;
54 static int param_push_num(OSSL_PARAM_BLD
*bld
, const char *key
,
55 void *num
, size_t size
, int type
)
57 OSSL_PARAM_BLD_DEF
*pd
= param_push(bld
, key
, size
, size
, type
, 0);
61 if (size
> sizeof(pd
->num
)) {
62 CRYPTOerr(CRYPTO_F_PARAM_PUSH_NUM
, CRYPTO_R_TOO_MANY_BYTES
);
65 memcpy(&pd
->num
, num
, size
);
69 void ossl_param_bld_init(OSSL_PARAM_BLD
*bld
)
71 memset(bld
, 0, sizeof(*bld
));
74 int ossl_param_bld_push_int(OSSL_PARAM_BLD
*bld
, const char *key
, int num
)
76 return param_push_num(bld
, key
, &num
, sizeof(num
), OSSL_PARAM_INTEGER
);
79 int ossl_param_bld_push_uint(OSSL_PARAM_BLD
*bld
, const char *key
,
82 return param_push_num(bld
, key
, &num
, sizeof(num
),
83 OSSL_PARAM_UNSIGNED_INTEGER
);
86 int ossl_param_bld_push_long(OSSL_PARAM_BLD
*bld
, const char *key
,
89 return param_push_num(bld
, key
, &num
, sizeof(num
), OSSL_PARAM_INTEGER
);
92 int ossl_param_bld_push_ulong(OSSL_PARAM_BLD
*bld
, const char *key
,
93 unsigned long int num
)
95 return param_push_num(bld
, key
, &num
, sizeof(num
),
96 OSSL_PARAM_UNSIGNED_INTEGER
);
99 int ossl_param_bld_push_int32(OSSL_PARAM_BLD
*bld
, const char *key
,
102 return param_push_num(bld
, key
, &num
, sizeof(num
), OSSL_PARAM_INTEGER
);
105 int ossl_param_bld_push_uint32(OSSL_PARAM_BLD
*bld
, const char *key
,
108 return param_push_num(bld
, key
, &num
, sizeof(num
),
109 OSSL_PARAM_UNSIGNED_INTEGER
);
112 int ossl_param_bld_push_int64(OSSL_PARAM_BLD
*bld
, const char *key
,
115 return param_push_num(bld
, key
, &num
, sizeof(num
), OSSL_PARAM_INTEGER
);
118 int ossl_param_bld_push_uint64(OSSL_PARAM_BLD
*bld
, const char *key
,
121 return param_push_num(bld
, key
, &num
, sizeof(num
),
122 OSSL_PARAM_UNSIGNED_INTEGER
);
125 int ossl_param_bld_push_size_t(OSSL_PARAM_BLD
*bld
, const char *key
,
128 return param_push_num(bld
, key
, &num
, sizeof(num
),
129 OSSL_PARAM_UNSIGNED_INTEGER
);
132 int ossl_param_bld_push_double(OSSL_PARAM_BLD
*bld
, const char *key
,
135 return param_push_num(bld
, key
, &num
, sizeof(num
), OSSL_PARAM_REAL
);
138 int ossl_param_bld_push_BN(OSSL_PARAM_BLD
*bld
, const char *key
,
141 return ossl_param_bld_push_BN_pad(bld
, key
, bn
,
142 bn
== NULL
? 0 : BN_num_bytes(bn
));
145 int ossl_param_bld_push_BN_pad(OSSL_PARAM_BLD
*bld
, const char *key
,
146 const BIGNUM
*bn
, size_t sz
)
149 OSSL_PARAM_BLD_DEF
*pd
;
152 n
= BN_num_bytes(bn
);
154 CRYPTOerr(0, CRYPTO_R_ZERO_LENGTH_NUMBER
);
157 if (sz
< (size_t)n
) {
158 CRYPTOerr(0, CRYPTO_R_TOO_SMALL_BUFFER
);
161 if (BN_get_flags(bn
, BN_FLG_SECURE
) == BN_FLG_SECURE
)
164 pd
= param_push(bld
, key
, sz
, sz
, OSSL_PARAM_UNSIGNED_INTEGER
, secure
);
171 int ossl_param_bld_push_utf8_string(OSSL_PARAM_BLD
*bld
, const char *key
,
172 const char *buf
, size_t bsize
)
174 OSSL_PARAM_BLD_DEF
*pd
;
177 bsize
= strlen(buf
) + 1;
178 } else if (bsize
> INT_MAX
) {
179 CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_PUSH_UTF8_STRING
,
180 CRYPTO_R_STRING_TOO_LONG
);
183 pd
= param_push(bld
, key
, bsize
, bsize
, OSSL_PARAM_UTF8_STRING
, 0);
190 int ossl_param_bld_push_utf8_ptr(OSSL_PARAM_BLD
*bld
, const char *key
,
191 char *buf
, size_t bsize
)
193 OSSL_PARAM_BLD_DEF
*pd
;
196 bsize
= strlen(buf
) + 1;
197 } else if (bsize
> INT_MAX
) {
198 CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_PUSH_UTF8_PTR
,
199 CRYPTO_R_STRING_TOO_LONG
);
202 pd
= param_push(bld
, key
, bsize
, sizeof(buf
), OSSL_PARAM_UTF8_PTR
, 0);
209 int ossl_param_bld_push_octet_string(OSSL_PARAM_BLD
*bld
, const char *key
,
210 const void *buf
, size_t bsize
)
212 OSSL_PARAM_BLD_DEF
*pd
;
214 if (bsize
> INT_MAX
) {
215 CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_PUSH_OCTET_STRING
,
216 CRYPTO_R_STRING_TOO_LONG
);
219 pd
= param_push(bld
, key
, bsize
, bsize
, OSSL_PARAM_OCTET_STRING
, 0);
226 int ossl_param_bld_push_octet_ptr(OSSL_PARAM_BLD
*bld
, const char *key
,
227 void *buf
, size_t bsize
)
229 OSSL_PARAM_BLD_DEF
*pd
;
231 if (bsize
> INT_MAX
) {
232 CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_PUSH_OCTET_PTR
,
233 CRYPTO_R_STRING_TOO_LONG
);
236 pd
= param_push(bld
, key
, bsize
, sizeof(buf
), OSSL_PARAM_OCTET_PTR
, 0);
243 static OSSL_PARAM
*param_bld_convert(OSSL_PARAM_BLD
*bld
, OSSL_PARAM
*param
,
244 OSSL_PARAM_BLD_BLOCK
*blk
,
245 OSSL_PARAM_BLD_BLOCK
*secure
)
248 OSSL_PARAM_BLD_DEF
*pd
;
251 for (i
= 0; i
< bld
->curr
; i
++) {
252 pd
= bld
->params
+ i
;
253 param
[i
].key
= pd
->key
;
254 param
[i
].data_type
= pd
->type
;
255 param
[i
].data_size
= pd
->size
;
256 param
[i
].return_size
= 0;
260 secure
+= pd
->alloc_blocks
;
263 blk
+= pd
->alloc_blocks
;
266 if (pd
->bn
!= NULL
) {
268 BN_bn2nativepad(pd
->bn
, (unsigned char *)p
, pd
->size
);
269 } else if (pd
->type
== OSSL_PARAM_OCTET_PTR
270 || pd
->type
== OSSL_PARAM_UTF8_PTR
) {
272 *(const void **)p
= pd
->string
;
273 } else if (pd
->type
== OSSL_PARAM_OCTET_STRING
274 || pd
->type
== OSSL_PARAM_UTF8_STRING
) {
275 if (pd
->string
!= NULL
)
276 memcpy(p
, pd
->string
, pd
->size
);
278 memset(p
, 0, pd
->size
);
280 /* Number, but could also be a NULL BIGNUM */
281 if (pd
->size
> sizeof(pd
->num
))
282 memset(p
, 0, pd
->size
);
283 else if (pd
->size
> 0)
284 memcpy(p
, &pd
->num
, pd
->size
);
287 param
[i
] = OSSL_PARAM_construct_end();
291 OSSL_PARAM
*ossl_param_bld_to_param(OSSL_PARAM_BLD
*bld
)
293 OSSL_PARAM_BLD_BLOCK
*blk
, *s
= NULL
;
294 OSSL_PARAM
*params
, *last
;
295 const size_t p_blks
= bytes_to_blocks((1 + bld
->curr
) * sizeof(*params
));
296 const size_t total
= ALIGN_SIZE
* (p_blks
+ bld
->total_blocks
);
297 const size_t ss
= ALIGN_SIZE
* bld
->secure_blocks
;
300 s
= OPENSSL_secure_malloc(ss
);
302 CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM
,
303 CRYPTO_R_SECURE_MALLOC_FAILURE
);
307 params
= OPENSSL_malloc(total
);
308 if (params
== NULL
) {
309 CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM
, ERR_R_MALLOC_FAILURE
);
310 OPENSSL_secure_free(s
);
313 blk
= p_blks
+ (OSSL_PARAM_BLD_BLOCK
*)(params
);
314 last
= param_bld_convert(bld
, params
, blk
, s
);
315 last
->data_size
= ss
;
317 last
->data_type
= OSSL_PARAM_ALLOCATED_END
;
321 void ossl_param_bld_free(OSSL_PARAM
*params
)
323 if (params
!= NULL
) {
326 for (p
= params
; p
->key
!= NULL
; p
++)
328 if (p
->data_type
== OSSL_PARAM_ALLOCATED_END
)
329 OPENSSL_secure_clear_free(p
->data
, p
->data_size
);
330 OPENSSL_free(params
);
334 OSSL_PARAM
*ossl_param_bld_to_param_ex(OSSL_PARAM_BLD
*bld
, OSSL_PARAM
*params
,
335 size_t param_n
, void *data
,
336 size_t data_n
, void *secure
,
339 if (params
== NULL
|| data
== NULL
) {
340 CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM_EX
,
341 CRYPTO_R_INVALID_NULL_ARGUMENT
);
344 if (param_n
< bld
->curr
+ 1) {
345 CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM_EX
,
346 CRYPTO_R_INSUFFICIENT_PARAM_SIZE
);
349 if (data_n
< ALIGN_SIZE
* bld
->total_blocks
) {
350 CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM_EX
,
351 CRYPTO_R_INSUFFICIENT_DATA_SPACE
);
354 if (bld
->secure_blocks
> 0 && secure_n
< ALIGN_SIZE
* bld
->secure_blocks
) {
355 CRYPTOerr(CRYPTO_F_OSSL_PARAM_BLD_TO_PARAM_EX
,
356 CRYPTO_R_INSUFFICIENT_SECURE_DATA_SPACE
);
359 param_bld_convert(bld
, params
, (OSSL_PARAM_BLD_BLOCK
*)data
,
360 (OSSL_PARAM_BLD_BLOCK
*)secure
);