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