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/params.h> 13e1051a39Sopenharmony_ci#include "internal/thread_once.h" 14e1051a39Sopenharmony_ci#include "internal/numbers.h" 15e1051a39Sopenharmony_ci#include "internal/endian.h" 16e1051a39Sopenharmony_ci 17e1051a39Sopenharmony_ci/* 18e1051a39Sopenharmony_ci * Return the number of bits in the mantissa of a double. This is used to 19e1051a39Sopenharmony_ci * shift a larger integral value to determine if it will exactly fit into a 20e1051a39Sopenharmony_ci * double. 21e1051a39Sopenharmony_ci */ 22e1051a39Sopenharmony_cistatic unsigned int real_shift(void) 23e1051a39Sopenharmony_ci{ 24e1051a39Sopenharmony_ci return sizeof(double) == 4 ? 24 : 53; 25e1051a39Sopenharmony_ci} 26e1051a39Sopenharmony_ci 27e1051a39Sopenharmony_ciOSSL_PARAM *OSSL_PARAM_locate(OSSL_PARAM *p, const char *key) 28e1051a39Sopenharmony_ci{ 29e1051a39Sopenharmony_ci if (p != NULL && key != NULL) 30e1051a39Sopenharmony_ci for (; p->key != NULL; p++) 31e1051a39Sopenharmony_ci if (strcmp(key, p->key) == 0) 32e1051a39Sopenharmony_ci return p; 33e1051a39Sopenharmony_ci return NULL; 34e1051a39Sopenharmony_ci} 35e1051a39Sopenharmony_ci 36e1051a39Sopenharmony_ciconst OSSL_PARAM *OSSL_PARAM_locate_const(const OSSL_PARAM *p, const char *key) 37e1051a39Sopenharmony_ci{ 38e1051a39Sopenharmony_ci return OSSL_PARAM_locate((OSSL_PARAM *)p, key); 39e1051a39Sopenharmony_ci} 40e1051a39Sopenharmony_ci 41e1051a39Sopenharmony_cistatic OSSL_PARAM ossl_param_construct(const char *key, unsigned int data_type, 42e1051a39Sopenharmony_ci void *data, size_t data_size) 43e1051a39Sopenharmony_ci{ 44e1051a39Sopenharmony_ci OSSL_PARAM res; 45e1051a39Sopenharmony_ci 46e1051a39Sopenharmony_ci res.key = key; 47e1051a39Sopenharmony_ci res.data_type = data_type; 48e1051a39Sopenharmony_ci res.data = data; 49e1051a39Sopenharmony_ci res.data_size = data_size; 50e1051a39Sopenharmony_ci res.return_size = OSSL_PARAM_UNMODIFIED; 51e1051a39Sopenharmony_ci return res; 52e1051a39Sopenharmony_ci} 53e1051a39Sopenharmony_ci 54e1051a39Sopenharmony_ciint OSSL_PARAM_modified(const OSSL_PARAM *p) 55e1051a39Sopenharmony_ci{ 56e1051a39Sopenharmony_ci return p != NULL && p->return_size != OSSL_PARAM_UNMODIFIED; 57e1051a39Sopenharmony_ci} 58e1051a39Sopenharmony_ci 59e1051a39Sopenharmony_civoid OSSL_PARAM_set_all_unmodified(OSSL_PARAM *p) 60e1051a39Sopenharmony_ci{ 61e1051a39Sopenharmony_ci if (p != NULL) 62e1051a39Sopenharmony_ci while (p->key != NULL) 63e1051a39Sopenharmony_ci p++->return_size = OSSL_PARAM_UNMODIFIED; 64e1051a39Sopenharmony_ci} 65e1051a39Sopenharmony_ci 66e1051a39Sopenharmony_ci/* Return non-zero if the signed number is negative */ 67e1051a39Sopenharmony_cistatic int is_negative(const void *number, size_t s) 68e1051a39Sopenharmony_ci{ 69e1051a39Sopenharmony_ci const unsigned char *n = number; 70e1051a39Sopenharmony_ci DECLARE_IS_ENDIAN; 71e1051a39Sopenharmony_ci 72e1051a39Sopenharmony_ci return 0x80 & (IS_BIG_ENDIAN ? n[0] : n[s - 1]); 73e1051a39Sopenharmony_ci} 74e1051a39Sopenharmony_ci 75e1051a39Sopenharmony_ci/* Check that all the bytes specified match the expected sign byte */ 76e1051a39Sopenharmony_cistatic int check_sign_bytes(const unsigned char *p, size_t n, unsigned char s) 77e1051a39Sopenharmony_ci{ 78e1051a39Sopenharmony_ci size_t i; 79e1051a39Sopenharmony_ci 80e1051a39Sopenharmony_ci for (i = 0; i < n; i++) 81e1051a39Sopenharmony_ci if (p[i] != s) 82e1051a39Sopenharmony_ci return 0; 83e1051a39Sopenharmony_ci return 1; 84e1051a39Sopenharmony_ci} 85e1051a39Sopenharmony_ci 86e1051a39Sopenharmony_ci/* 87e1051a39Sopenharmony_ci * Copy an integer to another integer. 88e1051a39Sopenharmony_ci * Handle different length integers and signed and unsigned integers. 89e1051a39Sopenharmony_ci * Both integers are in native byte ordering. 90e1051a39Sopenharmony_ci */ 91e1051a39Sopenharmony_cistatic int copy_integer(unsigned char *dest, size_t dest_len, 92e1051a39Sopenharmony_ci const unsigned char *src, size_t src_len, 93e1051a39Sopenharmony_ci unsigned char pad, int signed_int) 94e1051a39Sopenharmony_ci{ 95e1051a39Sopenharmony_ci size_t n; 96e1051a39Sopenharmony_ci DECLARE_IS_ENDIAN; 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_ci if (IS_BIG_ENDIAN) { 99e1051a39Sopenharmony_ci if (src_len < dest_len) { 100e1051a39Sopenharmony_ci n = dest_len - src_len; 101e1051a39Sopenharmony_ci memset(dest, pad, n); 102e1051a39Sopenharmony_ci memcpy(dest + n, src, src_len); 103e1051a39Sopenharmony_ci } else { 104e1051a39Sopenharmony_ci n = src_len - dest_len; 105e1051a39Sopenharmony_ci if (!check_sign_bytes(src, n, pad) 106e1051a39Sopenharmony_ci /* 107e1051a39Sopenharmony_ci * Shortening a signed value must retain the correct sign. 108e1051a39Sopenharmony_ci * Avoiding this kind of thing: -253 = 0xff03 -> 0x03 = 3 109e1051a39Sopenharmony_ci */ 110e1051a39Sopenharmony_ci || (signed_int && ((pad ^ src[n]) & 0x80) != 0)) 111e1051a39Sopenharmony_ci return 0; 112e1051a39Sopenharmony_ci memcpy(dest, src + n, dest_len); 113e1051a39Sopenharmony_ci } 114e1051a39Sopenharmony_ci } else /* IS_LITTLE_ENDIAN */ { 115e1051a39Sopenharmony_ci if (src_len < dest_len) { 116e1051a39Sopenharmony_ci n = dest_len - src_len; 117e1051a39Sopenharmony_ci memset(dest + src_len, pad, n); 118e1051a39Sopenharmony_ci memcpy(dest, src, src_len); 119e1051a39Sopenharmony_ci } else { 120e1051a39Sopenharmony_ci n = src_len - dest_len; 121e1051a39Sopenharmony_ci if (!check_sign_bytes(src + dest_len, n, pad) 122e1051a39Sopenharmony_ci /* 123e1051a39Sopenharmony_ci * Shortening a signed value must retain the correct sign. 124e1051a39Sopenharmony_ci * Avoiding this kind of thing: 130 = 0x0082 -> 0x82 = -126 125e1051a39Sopenharmony_ci */ 126e1051a39Sopenharmony_ci || (signed_int && ((pad ^ src[dest_len - 1]) & 0x80) != 0)) 127e1051a39Sopenharmony_ci return 0; 128e1051a39Sopenharmony_ci memcpy(dest, src, dest_len); 129e1051a39Sopenharmony_ci } 130e1051a39Sopenharmony_ci } 131e1051a39Sopenharmony_ci return 1; 132e1051a39Sopenharmony_ci} 133e1051a39Sopenharmony_ci 134e1051a39Sopenharmony_ci/* Copy a signed number to a signed number of possibly different length */ 135e1051a39Sopenharmony_cistatic int signed_from_signed(void *dest, size_t dest_len, 136e1051a39Sopenharmony_ci const void *src, size_t src_len) 137e1051a39Sopenharmony_ci{ 138e1051a39Sopenharmony_ci return copy_integer(dest, dest_len, src, src_len, 139e1051a39Sopenharmony_ci is_negative(src, src_len) ? 0xff : 0, 1); 140e1051a39Sopenharmony_ci} 141e1051a39Sopenharmony_ci 142e1051a39Sopenharmony_ci/* Copy an unsigned number to a signed number of possibly different length */ 143e1051a39Sopenharmony_cistatic int signed_from_unsigned(void *dest, size_t dest_len, 144e1051a39Sopenharmony_ci const void *src, size_t src_len) 145e1051a39Sopenharmony_ci{ 146e1051a39Sopenharmony_ci return copy_integer(dest, dest_len, src, src_len, 0, 1); 147e1051a39Sopenharmony_ci} 148e1051a39Sopenharmony_ci 149e1051a39Sopenharmony_ci/* Copy a signed number to an unsigned number of possibly different length */ 150e1051a39Sopenharmony_cistatic int unsigned_from_signed(void *dest, size_t dest_len, 151e1051a39Sopenharmony_ci const void *src, size_t src_len) 152e1051a39Sopenharmony_ci{ 153e1051a39Sopenharmony_ci if (is_negative(src, src_len)) 154e1051a39Sopenharmony_ci return 0; 155e1051a39Sopenharmony_ci return copy_integer(dest, dest_len, src, src_len, 0, 0); 156e1051a39Sopenharmony_ci} 157e1051a39Sopenharmony_ci 158e1051a39Sopenharmony_ci/* Copy an unsigned number to an unsigned number of possibly different length */ 159e1051a39Sopenharmony_cistatic int unsigned_from_unsigned(void *dest, size_t dest_len, 160e1051a39Sopenharmony_ci const void *src, size_t src_len) 161e1051a39Sopenharmony_ci{ 162e1051a39Sopenharmony_ci return copy_integer(dest, dest_len, src, src_len, 0, 0); 163e1051a39Sopenharmony_ci} 164e1051a39Sopenharmony_ci 165e1051a39Sopenharmony_ci/* General purpose get integer parameter call that handles odd sizes */ 166e1051a39Sopenharmony_cistatic int general_get_int(const OSSL_PARAM *p, void *val, size_t val_size) 167e1051a39Sopenharmony_ci{ 168e1051a39Sopenharmony_ci if (p->data_type == OSSL_PARAM_INTEGER) 169e1051a39Sopenharmony_ci return signed_from_signed(val, val_size, p->data, p->data_size); 170e1051a39Sopenharmony_ci if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) 171e1051a39Sopenharmony_ci return signed_from_unsigned(val, val_size, p->data, p->data_size); 172e1051a39Sopenharmony_ci return 0; 173e1051a39Sopenharmony_ci} 174e1051a39Sopenharmony_ci 175e1051a39Sopenharmony_ci/* General purpose set integer parameter call that handles odd sizes */ 176e1051a39Sopenharmony_cistatic int general_set_int(OSSL_PARAM *p, void *val, size_t val_size) 177e1051a39Sopenharmony_ci{ 178e1051a39Sopenharmony_ci int r = 0; 179e1051a39Sopenharmony_ci 180e1051a39Sopenharmony_ci p->return_size = val_size; /* Expected size */ 181e1051a39Sopenharmony_ci if (p->data == NULL) 182e1051a39Sopenharmony_ci return 1; 183e1051a39Sopenharmony_ci if (p->data_type == OSSL_PARAM_INTEGER) 184e1051a39Sopenharmony_ci r = signed_from_signed(p->data, p->data_size, val, val_size); 185e1051a39Sopenharmony_ci else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) 186e1051a39Sopenharmony_ci r = unsigned_from_signed(p->data, p->data_size, val, val_size); 187e1051a39Sopenharmony_ci p->return_size = r ? p->data_size : val_size; 188e1051a39Sopenharmony_ci return r; 189e1051a39Sopenharmony_ci} 190e1051a39Sopenharmony_ci 191e1051a39Sopenharmony_ci/* General purpose get unsigned integer parameter call that handles odd sizes */ 192e1051a39Sopenharmony_cistatic int general_get_uint(const OSSL_PARAM *p, void *val, size_t val_size) 193e1051a39Sopenharmony_ci{ 194e1051a39Sopenharmony_ci if (p->data_type == OSSL_PARAM_INTEGER) 195e1051a39Sopenharmony_ci return unsigned_from_signed(val, val_size, p->data, p->data_size); 196e1051a39Sopenharmony_ci if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) 197e1051a39Sopenharmony_ci return unsigned_from_unsigned(val, val_size, p->data, p->data_size); 198e1051a39Sopenharmony_ci return 0; 199e1051a39Sopenharmony_ci} 200e1051a39Sopenharmony_ci 201e1051a39Sopenharmony_ci/* General purpose set unsigned integer parameter call that handles odd sizes */ 202e1051a39Sopenharmony_cistatic int general_set_uint(OSSL_PARAM *p, void *val, size_t val_size) 203e1051a39Sopenharmony_ci{ 204e1051a39Sopenharmony_ci int r = 0; 205e1051a39Sopenharmony_ci 206e1051a39Sopenharmony_ci p->return_size = val_size; /* Expected size */ 207e1051a39Sopenharmony_ci if (p->data == NULL) 208e1051a39Sopenharmony_ci return 1; 209e1051a39Sopenharmony_ci if (p->data_type == OSSL_PARAM_INTEGER) 210e1051a39Sopenharmony_ci r = signed_from_unsigned(p->data, p->data_size, val, val_size); 211e1051a39Sopenharmony_ci else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) 212e1051a39Sopenharmony_ci r = unsigned_from_unsigned(p->data, p->data_size, val, val_size); 213e1051a39Sopenharmony_ci p->return_size = r ? p->data_size : val_size; 214e1051a39Sopenharmony_ci return r; 215e1051a39Sopenharmony_ci} 216e1051a39Sopenharmony_ci 217e1051a39Sopenharmony_ciint OSSL_PARAM_get_int(const OSSL_PARAM *p, int *val) 218e1051a39Sopenharmony_ci{ 219e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 220e1051a39Sopenharmony_ci switch (sizeof(int)) { 221e1051a39Sopenharmony_ci case sizeof(int32_t): 222e1051a39Sopenharmony_ci return OSSL_PARAM_get_int32(p, (int32_t *)val); 223e1051a39Sopenharmony_ci case sizeof(int64_t): 224e1051a39Sopenharmony_ci return OSSL_PARAM_get_int64(p, (int64_t *)val); 225e1051a39Sopenharmony_ci } 226e1051a39Sopenharmony_ci#endif 227e1051a39Sopenharmony_ci return general_get_int(p, val, sizeof(*val)); 228e1051a39Sopenharmony_ci} 229e1051a39Sopenharmony_ci 230e1051a39Sopenharmony_ciint OSSL_PARAM_set_int(OSSL_PARAM *p, int val) 231e1051a39Sopenharmony_ci{ 232e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 233e1051a39Sopenharmony_ci switch (sizeof(int)) { 234e1051a39Sopenharmony_ci case sizeof(int32_t): 235e1051a39Sopenharmony_ci return OSSL_PARAM_set_int32(p, (int32_t)val); 236e1051a39Sopenharmony_ci case sizeof(int64_t): 237e1051a39Sopenharmony_ci return OSSL_PARAM_set_int64(p, (int64_t)val); 238e1051a39Sopenharmony_ci } 239e1051a39Sopenharmony_ci#endif 240e1051a39Sopenharmony_ci return general_set_int(p, &val, sizeof(val)); 241e1051a39Sopenharmony_ci} 242e1051a39Sopenharmony_ci 243e1051a39Sopenharmony_ciOSSL_PARAM OSSL_PARAM_construct_int(const char *key, int *buf) 244e1051a39Sopenharmony_ci{ 245e1051a39Sopenharmony_ci return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int)); 246e1051a39Sopenharmony_ci} 247e1051a39Sopenharmony_ci 248e1051a39Sopenharmony_ciint OSSL_PARAM_get_uint(const OSSL_PARAM *p, unsigned int *val) 249e1051a39Sopenharmony_ci{ 250e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 251e1051a39Sopenharmony_ci switch (sizeof(unsigned int)) { 252e1051a39Sopenharmony_ci case sizeof(uint32_t): 253e1051a39Sopenharmony_ci return OSSL_PARAM_get_uint32(p, (uint32_t *)val); 254e1051a39Sopenharmony_ci case sizeof(uint64_t): 255e1051a39Sopenharmony_ci return OSSL_PARAM_get_uint64(p, (uint64_t *)val); 256e1051a39Sopenharmony_ci } 257e1051a39Sopenharmony_ci#endif 258e1051a39Sopenharmony_ci return general_get_uint(p, val, sizeof(*val)); 259e1051a39Sopenharmony_ci} 260e1051a39Sopenharmony_ci 261e1051a39Sopenharmony_ciint OSSL_PARAM_set_uint(OSSL_PARAM *p, unsigned int val) 262e1051a39Sopenharmony_ci{ 263e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 264e1051a39Sopenharmony_ci switch (sizeof(unsigned int)) { 265e1051a39Sopenharmony_ci case sizeof(uint32_t): 266e1051a39Sopenharmony_ci return OSSL_PARAM_set_uint32(p, (uint32_t)val); 267e1051a39Sopenharmony_ci case sizeof(uint64_t): 268e1051a39Sopenharmony_ci return OSSL_PARAM_set_uint64(p, (uint64_t)val); 269e1051a39Sopenharmony_ci } 270e1051a39Sopenharmony_ci#endif 271e1051a39Sopenharmony_ci return general_set_uint(p, &val, sizeof(val)); 272e1051a39Sopenharmony_ci} 273e1051a39Sopenharmony_ci 274e1051a39Sopenharmony_ciOSSL_PARAM OSSL_PARAM_construct_uint(const char *key, unsigned int *buf) 275e1051a39Sopenharmony_ci{ 276e1051a39Sopenharmony_ci return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf, 277e1051a39Sopenharmony_ci sizeof(unsigned int)); 278e1051a39Sopenharmony_ci} 279e1051a39Sopenharmony_ci 280e1051a39Sopenharmony_ciint OSSL_PARAM_get_long(const OSSL_PARAM *p, long int *val) 281e1051a39Sopenharmony_ci{ 282e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 283e1051a39Sopenharmony_ci switch (sizeof(long int)) { 284e1051a39Sopenharmony_ci case sizeof(int32_t): 285e1051a39Sopenharmony_ci return OSSL_PARAM_get_int32(p, (int32_t *)val); 286e1051a39Sopenharmony_ci case sizeof(int64_t): 287e1051a39Sopenharmony_ci return OSSL_PARAM_get_int64(p, (int64_t *)val); 288e1051a39Sopenharmony_ci } 289e1051a39Sopenharmony_ci#endif 290e1051a39Sopenharmony_ci return general_get_int(p, val, sizeof(*val)); 291e1051a39Sopenharmony_ci} 292e1051a39Sopenharmony_ci 293e1051a39Sopenharmony_ciint OSSL_PARAM_set_long(OSSL_PARAM *p, long int val) 294e1051a39Sopenharmony_ci{ 295e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 296e1051a39Sopenharmony_ci switch (sizeof(long int)) { 297e1051a39Sopenharmony_ci case sizeof(int32_t): 298e1051a39Sopenharmony_ci return OSSL_PARAM_set_int32(p, (int32_t)val); 299e1051a39Sopenharmony_ci case sizeof(int64_t): 300e1051a39Sopenharmony_ci return OSSL_PARAM_set_int64(p, (int64_t)val); 301e1051a39Sopenharmony_ci } 302e1051a39Sopenharmony_ci#endif 303e1051a39Sopenharmony_ci return general_set_int(p, &val, sizeof(val)); 304e1051a39Sopenharmony_ci} 305e1051a39Sopenharmony_ci 306e1051a39Sopenharmony_ciOSSL_PARAM OSSL_PARAM_construct_long(const char *key, long int *buf) 307e1051a39Sopenharmony_ci{ 308e1051a39Sopenharmony_ci return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(long int)); 309e1051a39Sopenharmony_ci} 310e1051a39Sopenharmony_ci 311e1051a39Sopenharmony_ciint OSSL_PARAM_get_ulong(const OSSL_PARAM *p, unsigned long int *val) 312e1051a39Sopenharmony_ci{ 313e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 314e1051a39Sopenharmony_ci switch (sizeof(unsigned long int)) { 315e1051a39Sopenharmony_ci case sizeof(uint32_t): 316e1051a39Sopenharmony_ci return OSSL_PARAM_get_uint32(p, (uint32_t *)val); 317e1051a39Sopenharmony_ci case sizeof(uint64_t): 318e1051a39Sopenharmony_ci return OSSL_PARAM_get_uint64(p, (uint64_t *)val); 319e1051a39Sopenharmony_ci } 320e1051a39Sopenharmony_ci#endif 321e1051a39Sopenharmony_ci return general_get_uint(p, val, sizeof(*val)); 322e1051a39Sopenharmony_ci} 323e1051a39Sopenharmony_ci 324e1051a39Sopenharmony_ciint OSSL_PARAM_set_ulong(OSSL_PARAM *p, unsigned long int val) 325e1051a39Sopenharmony_ci{ 326e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 327e1051a39Sopenharmony_ci switch (sizeof(unsigned long int)) { 328e1051a39Sopenharmony_ci case sizeof(uint32_t): 329e1051a39Sopenharmony_ci return OSSL_PARAM_set_uint32(p, (uint32_t)val); 330e1051a39Sopenharmony_ci case sizeof(uint64_t): 331e1051a39Sopenharmony_ci return OSSL_PARAM_set_uint64(p, (uint64_t)val); 332e1051a39Sopenharmony_ci } 333e1051a39Sopenharmony_ci#endif 334e1051a39Sopenharmony_ci return general_set_uint(p, &val, sizeof(val)); 335e1051a39Sopenharmony_ci} 336e1051a39Sopenharmony_ci 337e1051a39Sopenharmony_ciOSSL_PARAM OSSL_PARAM_construct_ulong(const char *key, unsigned long int *buf) 338e1051a39Sopenharmony_ci{ 339e1051a39Sopenharmony_ci return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf, 340e1051a39Sopenharmony_ci sizeof(unsigned long int)); 341e1051a39Sopenharmony_ci} 342e1051a39Sopenharmony_ci 343e1051a39Sopenharmony_ciint OSSL_PARAM_get_int32(const OSSL_PARAM *p, int32_t *val) 344e1051a39Sopenharmony_ci{ 345e1051a39Sopenharmony_ci double d; 346e1051a39Sopenharmony_ci 347e1051a39Sopenharmony_ci if (val == NULL || p == NULL ) 348e1051a39Sopenharmony_ci return 0; 349e1051a39Sopenharmony_ci 350e1051a39Sopenharmony_ci if (p->data_type == OSSL_PARAM_INTEGER) { 351e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 352e1051a39Sopenharmony_ci int64_t i64; 353e1051a39Sopenharmony_ci 354e1051a39Sopenharmony_ci switch (p->data_size) { 355e1051a39Sopenharmony_ci case sizeof(int32_t): 356e1051a39Sopenharmony_ci *val = *(const int32_t *)p->data; 357e1051a39Sopenharmony_ci return 1; 358e1051a39Sopenharmony_ci case sizeof(int64_t): 359e1051a39Sopenharmony_ci i64 = *(const int64_t *)p->data; 360e1051a39Sopenharmony_ci if (i64 >= INT32_MIN && i64 <= INT32_MAX) { 361e1051a39Sopenharmony_ci *val = (int32_t)i64; 362e1051a39Sopenharmony_ci return 1; 363e1051a39Sopenharmony_ci } 364e1051a39Sopenharmony_ci return 0; 365e1051a39Sopenharmony_ci } 366e1051a39Sopenharmony_ci#endif 367e1051a39Sopenharmony_ci return general_get_int(p, val, sizeof(*val)); 368e1051a39Sopenharmony_ci 369e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { 370e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 371e1051a39Sopenharmony_ci uint32_t u32; 372e1051a39Sopenharmony_ci uint64_t u64; 373e1051a39Sopenharmony_ci 374e1051a39Sopenharmony_ci switch (p->data_size) { 375e1051a39Sopenharmony_ci case sizeof(uint32_t): 376e1051a39Sopenharmony_ci u32 = *(const uint32_t *)p->data; 377e1051a39Sopenharmony_ci if (u32 <= INT32_MAX) { 378e1051a39Sopenharmony_ci *val = (int32_t)u32; 379e1051a39Sopenharmony_ci return 1; 380e1051a39Sopenharmony_ci } 381e1051a39Sopenharmony_ci return 0; 382e1051a39Sopenharmony_ci case sizeof(uint64_t): 383e1051a39Sopenharmony_ci u64 = *(const uint64_t *)p->data; 384e1051a39Sopenharmony_ci if (u64 <= INT32_MAX) { 385e1051a39Sopenharmony_ci *val = (int32_t)u64; 386e1051a39Sopenharmony_ci return 1; 387e1051a39Sopenharmony_ci } 388e1051a39Sopenharmony_ci return 0; 389e1051a39Sopenharmony_ci } 390e1051a39Sopenharmony_ci#endif 391e1051a39Sopenharmony_ci return general_get_int(p, val, sizeof(*val)); 392e1051a39Sopenharmony_ci 393e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_REAL) { 394e1051a39Sopenharmony_ci switch (p->data_size) { 395e1051a39Sopenharmony_ci case sizeof(double): 396e1051a39Sopenharmony_ci d = *(const double *)p->data; 397e1051a39Sopenharmony_ci if (d >= INT32_MIN && d <= INT32_MAX && d == (int32_t)d) { 398e1051a39Sopenharmony_ci *val = (int32_t)d; 399e1051a39Sopenharmony_ci return 1; 400e1051a39Sopenharmony_ci } 401e1051a39Sopenharmony_ci break; 402e1051a39Sopenharmony_ci } 403e1051a39Sopenharmony_ci } 404e1051a39Sopenharmony_ci return 0; 405e1051a39Sopenharmony_ci} 406e1051a39Sopenharmony_ci 407e1051a39Sopenharmony_ciint OSSL_PARAM_set_int32(OSSL_PARAM *p, int32_t val) 408e1051a39Sopenharmony_ci{ 409e1051a39Sopenharmony_ci if (p == NULL) 410e1051a39Sopenharmony_ci return 0; 411e1051a39Sopenharmony_ci p->return_size = 0; 412e1051a39Sopenharmony_ci if (p->data_type == OSSL_PARAM_INTEGER) { 413e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 414e1051a39Sopenharmony_ci p->return_size = sizeof(int32_t); /* Minimum expected size */ 415e1051a39Sopenharmony_ci if (p->data == NULL) 416e1051a39Sopenharmony_ci return 1; 417e1051a39Sopenharmony_ci switch (p->data_size) { 418e1051a39Sopenharmony_ci case sizeof(int32_t): 419e1051a39Sopenharmony_ci *(int32_t *)p->data = val; 420e1051a39Sopenharmony_ci return 1; 421e1051a39Sopenharmony_ci case sizeof(int64_t): 422e1051a39Sopenharmony_ci p->return_size = sizeof(int64_t); 423e1051a39Sopenharmony_ci *(int64_t *)p->data = (int64_t)val; 424e1051a39Sopenharmony_ci return 1; 425e1051a39Sopenharmony_ci } 426e1051a39Sopenharmony_ci#endif 427e1051a39Sopenharmony_ci return general_set_int(p, &val, sizeof(val)); 428e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) { 429e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 430e1051a39Sopenharmony_ci p->return_size = sizeof(uint32_t); /* Minimum expected size */ 431e1051a39Sopenharmony_ci if (p->data == NULL) 432e1051a39Sopenharmony_ci return 1; 433e1051a39Sopenharmony_ci switch (p->data_size) { 434e1051a39Sopenharmony_ci case sizeof(uint32_t): 435e1051a39Sopenharmony_ci *(uint32_t *)p->data = (uint32_t)val; 436e1051a39Sopenharmony_ci return 1; 437e1051a39Sopenharmony_ci case sizeof(uint64_t): 438e1051a39Sopenharmony_ci p->return_size = sizeof(uint64_t); 439e1051a39Sopenharmony_ci *(uint64_t *)p->data = (uint64_t)val; 440e1051a39Sopenharmony_ci return 1; 441e1051a39Sopenharmony_ci } 442e1051a39Sopenharmony_ci#endif 443e1051a39Sopenharmony_ci return general_set_int(p, &val, sizeof(val)); 444e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_REAL) { 445e1051a39Sopenharmony_ci p->return_size = sizeof(double); 446e1051a39Sopenharmony_ci if (p->data == NULL) 447e1051a39Sopenharmony_ci return 1; 448e1051a39Sopenharmony_ci switch (p->data_size) { 449e1051a39Sopenharmony_ci case sizeof(double): 450e1051a39Sopenharmony_ci *(double *)p->data = (double)val; 451e1051a39Sopenharmony_ci return 1; 452e1051a39Sopenharmony_ci } 453e1051a39Sopenharmony_ci } 454e1051a39Sopenharmony_ci return 0; 455e1051a39Sopenharmony_ci} 456e1051a39Sopenharmony_ci 457e1051a39Sopenharmony_ciOSSL_PARAM OSSL_PARAM_construct_int32(const char *key, int32_t *buf) 458e1051a39Sopenharmony_ci{ 459e1051a39Sopenharmony_ci return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, 460e1051a39Sopenharmony_ci sizeof(int32_t)); 461e1051a39Sopenharmony_ci} 462e1051a39Sopenharmony_ci 463e1051a39Sopenharmony_ciint OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val) 464e1051a39Sopenharmony_ci{ 465e1051a39Sopenharmony_ci double d; 466e1051a39Sopenharmony_ci 467e1051a39Sopenharmony_ci if (val == NULL || p == NULL) 468e1051a39Sopenharmony_ci return 0; 469e1051a39Sopenharmony_ci 470e1051a39Sopenharmony_ci if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { 471e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 472e1051a39Sopenharmony_ci uint64_t u64; 473e1051a39Sopenharmony_ci 474e1051a39Sopenharmony_ci switch (p->data_size) { 475e1051a39Sopenharmony_ci case sizeof(uint32_t): 476e1051a39Sopenharmony_ci *val = *(const uint32_t *)p->data; 477e1051a39Sopenharmony_ci return 1; 478e1051a39Sopenharmony_ci case sizeof(uint64_t): 479e1051a39Sopenharmony_ci u64 = *(const uint64_t *)p->data; 480e1051a39Sopenharmony_ci if (u64 <= UINT32_MAX) { 481e1051a39Sopenharmony_ci *val = (uint32_t)u64; 482e1051a39Sopenharmony_ci return 1; 483e1051a39Sopenharmony_ci } 484e1051a39Sopenharmony_ci return 0; 485e1051a39Sopenharmony_ci } 486e1051a39Sopenharmony_ci#endif 487e1051a39Sopenharmony_ci return general_get_uint(p, val, sizeof(*val)); 488e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_INTEGER) { 489e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 490e1051a39Sopenharmony_ci int32_t i32; 491e1051a39Sopenharmony_ci int64_t i64; 492e1051a39Sopenharmony_ci 493e1051a39Sopenharmony_ci switch (p->data_size) { 494e1051a39Sopenharmony_ci case sizeof(int32_t): 495e1051a39Sopenharmony_ci i32 = *(const int32_t *)p->data; 496e1051a39Sopenharmony_ci if (i32 >= 0) { 497e1051a39Sopenharmony_ci *val = i32; 498e1051a39Sopenharmony_ci return 1; 499e1051a39Sopenharmony_ci } 500e1051a39Sopenharmony_ci return 0; 501e1051a39Sopenharmony_ci case sizeof(int64_t): 502e1051a39Sopenharmony_ci i64 = *(const int64_t *)p->data; 503e1051a39Sopenharmony_ci if (i64 >= 0 && i64 <= UINT32_MAX) { 504e1051a39Sopenharmony_ci *val = (uint32_t)i64; 505e1051a39Sopenharmony_ci return 1; 506e1051a39Sopenharmony_ci } 507e1051a39Sopenharmony_ci return 0; 508e1051a39Sopenharmony_ci } 509e1051a39Sopenharmony_ci#endif 510e1051a39Sopenharmony_ci return general_get_uint(p, val, sizeof(*val)); 511e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_REAL) { 512e1051a39Sopenharmony_ci switch (p->data_size) { 513e1051a39Sopenharmony_ci case sizeof(double): 514e1051a39Sopenharmony_ci d = *(const double *)p->data; 515e1051a39Sopenharmony_ci if (d >= 0 && d <= UINT32_MAX && d == (uint32_t)d) { 516e1051a39Sopenharmony_ci *val = (uint32_t)d; 517e1051a39Sopenharmony_ci return 1; 518e1051a39Sopenharmony_ci } 519e1051a39Sopenharmony_ci break; 520e1051a39Sopenharmony_ci } 521e1051a39Sopenharmony_ci } 522e1051a39Sopenharmony_ci return 0; 523e1051a39Sopenharmony_ci} 524e1051a39Sopenharmony_ci 525e1051a39Sopenharmony_ciint OSSL_PARAM_set_uint32(OSSL_PARAM *p, uint32_t val) 526e1051a39Sopenharmony_ci{ 527e1051a39Sopenharmony_ci if (p == NULL) 528e1051a39Sopenharmony_ci return 0; 529e1051a39Sopenharmony_ci p->return_size = 0; 530e1051a39Sopenharmony_ci 531e1051a39Sopenharmony_ci if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { 532e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 533e1051a39Sopenharmony_ci p->return_size = sizeof(uint32_t); /* Minimum expected size */ 534e1051a39Sopenharmony_ci if (p->data == NULL) 535e1051a39Sopenharmony_ci return 1; 536e1051a39Sopenharmony_ci switch (p->data_size) { 537e1051a39Sopenharmony_ci case sizeof(uint32_t): 538e1051a39Sopenharmony_ci *(uint32_t *)p->data = val; 539e1051a39Sopenharmony_ci return 1; 540e1051a39Sopenharmony_ci case sizeof(uint64_t): 541e1051a39Sopenharmony_ci p->return_size = sizeof(uint64_t); 542e1051a39Sopenharmony_ci *(uint64_t *)p->data = val; 543e1051a39Sopenharmony_ci return 1; 544e1051a39Sopenharmony_ci } 545e1051a39Sopenharmony_ci#endif 546e1051a39Sopenharmony_ci return general_set_uint(p, &val, sizeof(val)); 547e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_INTEGER) { 548e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 549e1051a39Sopenharmony_ci p->return_size = sizeof(int32_t); /* Minimum expected size */ 550e1051a39Sopenharmony_ci if (p->data == NULL) 551e1051a39Sopenharmony_ci return 1; 552e1051a39Sopenharmony_ci switch (p->data_size) { 553e1051a39Sopenharmony_ci case sizeof(int32_t): 554e1051a39Sopenharmony_ci if (val <= INT32_MAX) { 555e1051a39Sopenharmony_ci *(int32_t *)p->data = (int32_t)val; 556e1051a39Sopenharmony_ci return 1; 557e1051a39Sopenharmony_ci } 558e1051a39Sopenharmony_ci return 0; 559e1051a39Sopenharmony_ci case sizeof(int64_t): 560e1051a39Sopenharmony_ci p->return_size = sizeof(int64_t); 561e1051a39Sopenharmony_ci *(int64_t *)p->data = (int64_t)val; 562e1051a39Sopenharmony_ci return 1; 563e1051a39Sopenharmony_ci } 564e1051a39Sopenharmony_ci#endif 565e1051a39Sopenharmony_ci return general_set_uint(p, &val, sizeof(val)); 566e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_REAL) { 567e1051a39Sopenharmony_ci p->return_size = sizeof(double); 568e1051a39Sopenharmony_ci if (p->data == NULL) 569e1051a39Sopenharmony_ci return 1; 570e1051a39Sopenharmony_ci switch (p->data_size) { 571e1051a39Sopenharmony_ci case sizeof(double): 572e1051a39Sopenharmony_ci *(double *)p->data = (double)val; 573e1051a39Sopenharmony_ci return 1; 574e1051a39Sopenharmony_ci } 575e1051a39Sopenharmony_ci } 576e1051a39Sopenharmony_ci return 0; 577e1051a39Sopenharmony_ci} 578e1051a39Sopenharmony_ci 579e1051a39Sopenharmony_ciOSSL_PARAM OSSL_PARAM_construct_uint32(const char *key, uint32_t *buf) 580e1051a39Sopenharmony_ci{ 581e1051a39Sopenharmony_ci return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf, 582e1051a39Sopenharmony_ci sizeof(uint32_t)); 583e1051a39Sopenharmony_ci} 584e1051a39Sopenharmony_ci 585e1051a39Sopenharmony_ciint OSSL_PARAM_get_int64(const OSSL_PARAM *p, int64_t *val) 586e1051a39Sopenharmony_ci{ 587e1051a39Sopenharmony_ci double d; 588e1051a39Sopenharmony_ci 589e1051a39Sopenharmony_ci if (val == NULL || p == NULL ) 590e1051a39Sopenharmony_ci return 0; 591e1051a39Sopenharmony_ci 592e1051a39Sopenharmony_ci if (p->data_type == OSSL_PARAM_INTEGER) { 593e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 594e1051a39Sopenharmony_ci switch (p->data_size) { 595e1051a39Sopenharmony_ci case sizeof(int32_t): 596e1051a39Sopenharmony_ci *val = *(const int32_t *)p->data; 597e1051a39Sopenharmony_ci return 1; 598e1051a39Sopenharmony_ci case sizeof(int64_t): 599e1051a39Sopenharmony_ci *val = *(const int64_t *)p->data; 600e1051a39Sopenharmony_ci return 1; 601e1051a39Sopenharmony_ci } 602e1051a39Sopenharmony_ci#endif 603e1051a39Sopenharmony_ci return general_get_int(p, val, sizeof(*val)); 604e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { 605e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 606e1051a39Sopenharmony_ci uint64_t u64; 607e1051a39Sopenharmony_ci 608e1051a39Sopenharmony_ci switch (p->data_size) { 609e1051a39Sopenharmony_ci case sizeof(uint32_t): 610e1051a39Sopenharmony_ci *val = *(const uint32_t *)p->data; 611e1051a39Sopenharmony_ci return 1; 612e1051a39Sopenharmony_ci case sizeof(uint64_t): 613e1051a39Sopenharmony_ci u64 = *(const uint64_t *)p->data; 614e1051a39Sopenharmony_ci if (u64 <= INT64_MAX) { 615e1051a39Sopenharmony_ci *val = (int64_t)u64; 616e1051a39Sopenharmony_ci return 1; 617e1051a39Sopenharmony_ci } 618e1051a39Sopenharmony_ci return 0; 619e1051a39Sopenharmony_ci } 620e1051a39Sopenharmony_ci#endif 621e1051a39Sopenharmony_ci return general_get_int(p, val, sizeof(*val)); 622e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_REAL) { 623e1051a39Sopenharmony_ci switch (p->data_size) { 624e1051a39Sopenharmony_ci case sizeof(double): 625e1051a39Sopenharmony_ci d = *(const double *)p->data; 626e1051a39Sopenharmony_ci if (d >= INT64_MIN 627e1051a39Sopenharmony_ci /* 628e1051a39Sopenharmony_ci * By subtracting 65535 (2^16-1) we cancel the low order 629e1051a39Sopenharmony_ci * 15 bits of INT64_MAX to avoid using imprecise floating 630e1051a39Sopenharmony_ci * point values. 631e1051a39Sopenharmony_ci */ 632e1051a39Sopenharmony_ci && d < (double)(INT64_MAX - 65535) + 65536.0 633e1051a39Sopenharmony_ci && d == (int64_t)d) { 634e1051a39Sopenharmony_ci *val = (int64_t)d; 635e1051a39Sopenharmony_ci return 1; 636e1051a39Sopenharmony_ci } 637e1051a39Sopenharmony_ci break; 638e1051a39Sopenharmony_ci } 639e1051a39Sopenharmony_ci } 640e1051a39Sopenharmony_ci return 0; 641e1051a39Sopenharmony_ci} 642e1051a39Sopenharmony_ci 643e1051a39Sopenharmony_ciint OSSL_PARAM_set_int64(OSSL_PARAM *p, int64_t val) 644e1051a39Sopenharmony_ci{ 645e1051a39Sopenharmony_ci uint64_t u64; 646e1051a39Sopenharmony_ci 647e1051a39Sopenharmony_ci if (p == NULL) 648e1051a39Sopenharmony_ci return 0; 649e1051a39Sopenharmony_ci p->return_size = 0; 650e1051a39Sopenharmony_ci if (p->data_type == OSSL_PARAM_INTEGER) { 651e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 652e1051a39Sopenharmony_ci p->return_size = sizeof(int64_t); /* Expected size */ 653e1051a39Sopenharmony_ci if (p->data == NULL) 654e1051a39Sopenharmony_ci return 1; 655e1051a39Sopenharmony_ci switch (p->data_size) { 656e1051a39Sopenharmony_ci case sizeof(int32_t): 657e1051a39Sopenharmony_ci if (val >= INT32_MIN && val <= INT32_MAX) { 658e1051a39Sopenharmony_ci p->return_size = sizeof(int32_t); 659e1051a39Sopenharmony_ci *(int32_t *)p->data = (int32_t)val; 660e1051a39Sopenharmony_ci return 1; 661e1051a39Sopenharmony_ci } 662e1051a39Sopenharmony_ci return 0; 663e1051a39Sopenharmony_ci case sizeof(int64_t): 664e1051a39Sopenharmony_ci *(int64_t *)p->data = val; 665e1051a39Sopenharmony_ci return 1; 666e1051a39Sopenharmony_ci } 667e1051a39Sopenharmony_ci#endif 668e1051a39Sopenharmony_ci return general_set_int(p, &val, sizeof(val)); 669e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) { 670e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 671e1051a39Sopenharmony_ci p->return_size = sizeof(uint64_t); /* Expected size */ 672e1051a39Sopenharmony_ci if (p->data == NULL) 673e1051a39Sopenharmony_ci return 1; 674e1051a39Sopenharmony_ci switch (p->data_size) { 675e1051a39Sopenharmony_ci case sizeof(uint32_t): 676e1051a39Sopenharmony_ci if (val <= UINT32_MAX) { 677e1051a39Sopenharmony_ci p->return_size = sizeof(uint32_t); 678e1051a39Sopenharmony_ci *(uint32_t *)p->data = (uint32_t)val; 679e1051a39Sopenharmony_ci return 1; 680e1051a39Sopenharmony_ci } 681e1051a39Sopenharmony_ci return 0; 682e1051a39Sopenharmony_ci case sizeof(uint64_t): 683e1051a39Sopenharmony_ci *(uint64_t *)p->data = (uint64_t)val; 684e1051a39Sopenharmony_ci return 1; 685e1051a39Sopenharmony_ci } 686e1051a39Sopenharmony_ci#endif 687e1051a39Sopenharmony_ci return general_set_int(p, &val, sizeof(val)); 688e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_REAL) { 689e1051a39Sopenharmony_ci p->return_size = sizeof(double); 690e1051a39Sopenharmony_ci if (p->data == NULL) 691e1051a39Sopenharmony_ci return 1; 692e1051a39Sopenharmony_ci switch (p->data_size) { 693e1051a39Sopenharmony_ci case sizeof(double): 694e1051a39Sopenharmony_ci u64 = val < 0 ? -val : val; 695e1051a39Sopenharmony_ci if ((u64 >> real_shift()) == 0) { 696e1051a39Sopenharmony_ci *(double *)p->data = (double)val; 697e1051a39Sopenharmony_ci return 1; 698e1051a39Sopenharmony_ci } 699e1051a39Sopenharmony_ci break; 700e1051a39Sopenharmony_ci } 701e1051a39Sopenharmony_ci } 702e1051a39Sopenharmony_ci return 0; 703e1051a39Sopenharmony_ci} 704e1051a39Sopenharmony_ci 705e1051a39Sopenharmony_ciOSSL_PARAM OSSL_PARAM_construct_int64(const char *key, int64_t *buf) 706e1051a39Sopenharmony_ci{ 707e1051a39Sopenharmony_ci return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int64_t)); 708e1051a39Sopenharmony_ci} 709e1051a39Sopenharmony_ci 710e1051a39Sopenharmony_ciint OSSL_PARAM_get_uint64(const OSSL_PARAM *p, uint64_t *val) 711e1051a39Sopenharmony_ci{ 712e1051a39Sopenharmony_ci double d; 713e1051a39Sopenharmony_ci 714e1051a39Sopenharmony_ci if (val == NULL || p == NULL) 715e1051a39Sopenharmony_ci return 0; 716e1051a39Sopenharmony_ci 717e1051a39Sopenharmony_ci if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { 718e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 719e1051a39Sopenharmony_ci switch (p->data_size) { 720e1051a39Sopenharmony_ci case sizeof(uint32_t): 721e1051a39Sopenharmony_ci *val = *(const uint32_t *)p->data; 722e1051a39Sopenharmony_ci return 1; 723e1051a39Sopenharmony_ci case sizeof(uint64_t): 724e1051a39Sopenharmony_ci *val = *(const uint64_t *)p->data; 725e1051a39Sopenharmony_ci return 1; 726e1051a39Sopenharmony_ci } 727e1051a39Sopenharmony_ci#endif 728e1051a39Sopenharmony_ci return general_get_uint(p, val, sizeof(*val)); 729e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_INTEGER) { 730e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 731e1051a39Sopenharmony_ci int32_t i32; 732e1051a39Sopenharmony_ci int64_t i64; 733e1051a39Sopenharmony_ci 734e1051a39Sopenharmony_ci switch (p->data_size) { 735e1051a39Sopenharmony_ci case sizeof(int32_t): 736e1051a39Sopenharmony_ci i32 = *(const int32_t *)p->data; 737e1051a39Sopenharmony_ci if (i32 >= 0) { 738e1051a39Sopenharmony_ci *val = (uint64_t)i32; 739e1051a39Sopenharmony_ci return 1; 740e1051a39Sopenharmony_ci } 741e1051a39Sopenharmony_ci return 0; 742e1051a39Sopenharmony_ci case sizeof(int64_t): 743e1051a39Sopenharmony_ci i64 = *(const int64_t *)p->data; 744e1051a39Sopenharmony_ci if (i64 >= 0) { 745e1051a39Sopenharmony_ci *val = (uint64_t)i64; 746e1051a39Sopenharmony_ci return 1; 747e1051a39Sopenharmony_ci } 748e1051a39Sopenharmony_ci return 0; 749e1051a39Sopenharmony_ci } 750e1051a39Sopenharmony_ci#endif 751e1051a39Sopenharmony_ci return general_get_uint(p, val, sizeof(*val)); 752e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_REAL) { 753e1051a39Sopenharmony_ci switch (p->data_size) { 754e1051a39Sopenharmony_ci case sizeof(double): 755e1051a39Sopenharmony_ci d = *(const double *)p->data; 756e1051a39Sopenharmony_ci if (d >= 0 757e1051a39Sopenharmony_ci /* 758e1051a39Sopenharmony_ci * By subtracting 65535 (2^16-1) we cancel the low order 759e1051a39Sopenharmony_ci * 15 bits of UINT64_MAX to avoid using imprecise floating 760e1051a39Sopenharmony_ci * point values. 761e1051a39Sopenharmony_ci */ 762e1051a39Sopenharmony_ci && d < (double)(UINT64_MAX - 65535) + 65536.0 763e1051a39Sopenharmony_ci && d == (uint64_t)d) { 764e1051a39Sopenharmony_ci *val = (uint64_t)d; 765e1051a39Sopenharmony_ci return 1; 766e1051a39Sopenharmony_ci } 767e1051a39Sopenharmony_ci break; 768e1051a39Sopenharmony_ci } 769e1051a39Sopenharmony_ci } 770e1051a39Sopenharmony_ci return 0; 771e1051a39Sopenharmony_ci} 772e1051a39Sopenharmony_ci 773e1051a39Sopenharmony_ciint OSSL_PARAM_set_uint64(OSSL_PARAM *p, uint64_t val) 774e1051a39Sopenharmony_ci{ 775e1051a39Sopenharmony_ci if (p == NULL) 776e1051a39Sopenharmony_ci return 0; 777e1051a39Sopenharmony_ci p->return_size = 0; 778e1051a39Sopenharmony_ci 779e1051a39Sopenharmony_ci if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { 780e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 781e1051a39Sopenharmony_ci p->return_size = sizeof(uint64_t); /* Expected size */ 782e1051a39Sopenharmony_ci if (p->data == NULL) 783e1051a39Sopenharmony_ci return 1; 784e1051a39Sopenharmony_ci switch (p->data_size) { 785e1051a39Sopenharmony_ci case sizeof(uint32_t): 786e1051a39Sopenharmony_ci if (val <= UINT32_MAX) { 787e1051a39Sopenharmony_ci p->return_size = sizeof(uint32_t); 788e1051a39Sopenharmony_ci *(uint32_t *)p->data = (uint32_t)val; 789e1051a39Sopenharmony_ci return 1; 790e1051a39Sopenharmony_ci } 791e1051a39Sopenharmony_ci return 0; 792e1051a39Sopenharmony_ci case sizeof(uint64_t): 793e1051a39Sopenharmony_ci *(uint64_t *)p->data = val; 794e1051a39Sopenharmony_ci return 1; 795e1051a39Sopenharmony_ci } 796e1051a39Sopenharmony_ci#endif 797e1051a39Sopenharmony_ci return general_set_uint(p, &val, sizeof(val)); 798e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_INTEGER) { 799e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 800e1051a39Sopenharmony_ci p->return_size = sizeof(int64_t); /* Expected size */ 801e1051a39Sopenharmony_ci if (p->data == NULL) 802e1051a39Sopenharmony_ci return 1; 803e1051a39Sopenharmony_ci switch (p->data_size) { 804e1051a39Sopenharmony_ci case sizeof(int32_t): 805e1051a39Sopenharmony_ci if (val <= INT32_MAX) { 806e1051a39Sopenharmony_ci p->return_size = sizeof(int32_t); 807e1051a39Sopenharmony_ci *(int32_t *)p->data = (int32_t)val; 808e1051a39Sopenharmony_ci return 1; 809e1051a39Sopenharmony_ci } 810e1051a39Sopenharmony_ci return 0; 811e1051a39Sopenharmony_ci case sizeof(int64_t): 812e1051a39Sopenharmony_ci if (val <= INT64_MAX) { 813e1051a39Sopenharmony_ci *(int64_t *)p->data = (int64_t)val; 814e1051a39Sopenharmony_ci return 1; 815e1051a39Sopenharmony_ci } 816e1051a39Sopenharmony_ci return 0; 817e1051a39Sopenharmony_ci } 818e1051a39Sopenharmony_ci#endif 819e1051a39Sopenharmony_ci return general_set_uint(p, &val, sizeof(val)); 820e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_REAL) { 821e1051a39Sopenharmony_ci p->return_size = sizeof(double); 822e1051a39Sopenharmony_ci switch (p->data_size) { 823e1051a39Sopenharmony_ci case sizeof(double): 824e1051a39Sopenharmony_ci if ((val >> real_shift()) == 0) { 825e1051a39Sopenharmony_ci *(double *)p->data = (double)val; 826e1051a39Sopenharmony_ci return 1; 827e1051a39Sopenharmony_ci } 828e1051a39Sopenharmony_ci break; 829e1051a39Sopenharmony_ci } 830e1051a39Sopenharmony_ci } 831e1051a39Sopenharmony_ci return 0; 832e1051a39Sopenharmony_ci} 833e1051a39Sopenharmony_ci 834e1051a39Sopenharmony_ciOSSL_PARAM OSSL_PARAM_construct_uint64(const char *key, uint64_t *buf) 835e1051a39Sopenharmony_ci{ 836e1051a39Sopenharmony_ci return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf, 837e1051a39Sopenharmony_ci sizeof(uint64_t)); 838e1051a39Sopenharmony_ci} 839e1051a39Sopenharmony_ci 840e1051a39Sopenharmony_ciint OSSL_PARAM_get_size_t(const OSSL_PARAM *p, size_t *val) 841e1051a39Sopenharmony_ci{ 842e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 843e1051a39Sopenharmony_ci switch (sizeof(size_t)) { 844e1051a39Sopenharmony_ci case sizeof(uint32_t): 845e1051a39Sopenharmony_ci return OSSL_PARAM_get_uint32(p, (uint32_t *)val); 846e1051a39Sopenharmony_ci case sizeof(uint64_t): 847e1051a39Sopenharmony_ci return OSSL_PARAM_get_uint64(p, (uint64_t *)val); 848e1051a39Sopenharmony_ci } 849e1051a39Sopenharmony_ci#endif 850e1051a39Sopenharmony_ci return general_get_uint(p, val, sizeof(*val)); 851e1051a39Sopenharmony_ci} 852e1051a39Sopenharmony_ci 853e1051a39Sopenharmony_ciint OSSL_PARAM_set_size_t(OSSL_PARAM *p, size_t val) 854e1051a39Sopenharmony_ci{ 855e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 856e1051a39Sopenharmony_ci switch (sizeof(size_t)) { 857e1051a39Sopenharmony_ci case sizeof(uint32_t): 858e1051a39Sopenharmony_ci return OSSL_PARAM_set_uint32(p, (uint32_t)val); 859e1051a39Sopenharmony_ci case sizeof(uint64_t): 860e1051a39Sopenharmony_ci return OSSL_PARAM_set_uint64(p, (uint64_t)val); 861e1051a39Sopenharmony_ci } 862e1051a39Sopenharmony_ci#endif 863e1051a39Sopenharmony_ci return general_set_uint(p, &val, sizeof(val)); 864e1051a39Sopenharmony_ci} 865e1051a39Sopenharmony_ci 866e1051a39Sopenharmony_ciOSSL_PARAM OSSL_PARAM_construct_size_t(const char *key, size_t *buf) 867e1051a39Sopenharmony_ci{ 868e1051a39Sopenharmony_ci return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf, 869e1051a39Sopenharmony_ci sizeof(size_t)); 870e1051a39Sopenharmony_ci} 871e1051a39Sopenharmony_ci 872e1051a39Sopenharmony_ciint OSSL_PARAM_get_time_t(const OSSL_PARAM *p, time_t *val) 873e1051a39Sopenharmony_ci{ 874e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 875e1051a39Sopenharmony_ci switch (sizeof(time_t)) { 876e1051a39Sopenharmony_ci case sizeof(int32_t): 877e1051a39Sopenharmony_ci return OSSL_PARAM_get_int32(p, (int32_t *)val); 878e1051a39Sopenharmony_ci case sizeof(int64_t): 879e1051a39Sopenharmony_ci return OSSL_PARAM_get_int64(p, (int64_t *)val); 880e1051a39Sopenharmony_ci } 881e1051a39Sopenharmony_ci#endif 882e1051a39Sopenharmony_ci return general_get_int(p, val, sizeof(*val)); 883e1051a39Sopenharmony_ci} 884e1051a39Sopenharmony_ci 885e1051a39Sopenharmony_ciint OSSL_PARAM_set_time_t(OSSL_PARAM *p, time_t val) 886e1051a39Sopenharmony_ci{ 887e1051a39Sopenharmony_ci#ifndef OPENSSL_SMALL_FOOTPRINT 888e1051a39Sopenharmony_ci switch (sizeof(time_t)) { 889e1051a39Sopenharmony_ci case sizeof(int32_t): 890e1051a39Sopenharmony_ci return OSSL_PARAM_set_int32(p, (int32_t)val); 891e1051a39Sopenharmony_ci case sizeof(int64_t): 892e1051a39Sopenharmony_ci return OSSL_PARAM_set_int64(p, (int64_t)val); 893e1051a39Sopenharmony_ci } 894e1051a39Sopenharmony_ci#endif 895e1051a39Sopenharmony_ci return general_set_int(p, &val, sizeof(val)); 896e1051a39Sopenharmony_ci} 897e1051a39Sopenharmony_ci 898e1051a39Sopenharmony_ciOSSL_PARAM OSSL_PARAM_construct_time_t(const char *key, time_t *buf) 899e1051a39Sopenharmony_ci{ 900e1051a39Sopenharmony_ci return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(time_t)); 901e1051a39Sopenharmony_ci} 902e1051a39Sopenharmony_ci 903e1051a39Sopenharmony_ciint OSSL_PARAM_get_BN(const OSSL_PARAM *p, BIGNUM **val) 904e1051a39Sopenharmony_ci{ 905e1051a39Sopenharmony_ci BIGNUM *b; 906e1051a39Sopenharmony_ci 907e1051a39Sopenharmony_ci if (val == NULL 908e1051a39Sopenharmony_ci || p == NULL 909e1051a39Sopenharmony_ci || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER) 910e1051a39Sopenharmony_ci return 0; 911e1051a39Sopenharmony_ci 912e1051a39Sopenharmony_ci b = BN_native2bn(p->data, (int)p->data_size, *val); 913e1051a39Sopenharmony_ci if (b != NULL) { 914e1051a39Sopenharmony_ci *val = b; 915e1051a39Sopenharmony_ci return 1; 916e1051a39Sopenharmony_ci } 917e1051a39Sopenharmony_ci return 0; 918e1051a39Sopenharmony_ci} 919e1051a39Sopenharmony_ci 920e1051a39Sopenharmony_ciint OSSL_PARAM_set_BN(OSSL_PARAM *p, const BIGNUM *val) 921e1051a39Sopenharmony_ci{ 922e1051a39Sopenharmony_ci size_t bytes; 923e1051a39Sopenharmony_ci 924e1051a39Sopenharmony_ci if (p == NULL) 925e1051a39Sopenharmony_ci return 0; 926e1051a39Sopenharmony_ci p->return_size = 0; 927e1051a39Sopenharmony_ci if (val == NULL || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER) 928e1051a39Sopenharmony_ci return 0; 929e1051a39Sopenharmony_ci 930e1051a39Sopenharmony_ci /* For the moment, only positive values are permitted */ 931e1051a39Sopenharmony_ci if (BN_is_negative(val)) 932e1051a39Sopenharmony_ci return 0; 933e1051a39Sopenharmony_ci 934e1051a39Sopenharmony_ci bytes = (size_t)BN_num_bytes(val); 935e1051a39Sopenharmony_ci /* We make sure that at least one byte is used, so zero is properly set */ 936e1051a39Sopenharmony_ci if (bytes == 0) 937e1051a39Sopenharmony_ci bytes++; 938e1051a39Sopenharmony_ci 939e1051a39Sopenharmony_ci p->return_size = bytes; 940e1051a39Sopenharmony_ci if (p->data == NULL) 941e1051a39Sopenharmony_ci return 1; 942e1051a39Sopenharmony_ci if (p->data_size >= bytes) { 943e1051a39Sopenharmony_ci p->return_size = p->data_size; 944e1051a39Sopenharmony_ci return BN_bn2nativepad(val, p->data, p->data_size) >= 0; 945e1051a39Sopenharmony_ci } 946e1051a39Sopenharmony_ci return 0; 947e1051a39Sopenharmony_ci} 948e1051a39Sopenharmony_ci 949e1051a39Sopenharmony_ciOSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf, 950e1051a39Sopenharmony_ci size_t bsize) 951e1051a39Sopenharmony_ci{ 952e1051a39Sopenharmony_ci return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, 953e1051a39Sopenharmony_ci buf, bsize); 954e1051a39Sopenharmony_ci} 955e1051a39Sopenharmony_ci 956e1051a39Sopenharmony_ciint OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val) 957e1051a39Sopenharmony_ci{ 958e1051a39Sopenharmony_ci int64_t i64; 959e1051a39Sopenharmony_ci uint64_t u64; 960e1051a39Sopenharmony_ci 961e1051a39Sopenharmony_ci if (val == NULL || p == NULL) 962e1051a39Sopenharmony_ci return 0; 963e1051a39Sopenharmony_ci 964e1051a39Sopenharmony_ci if (p->data_type == OSSL_PARAM_REAL) { 965e1051a39Sopenharmony_ci switch (p->data_size) { 966e1051a39Sopenharmony_ci case sizeof(double): 967e1051a39Sopenharmony_ci *val = *(const double *)p->data; 968e1051a39Sopenharmony_ci return 1; 969e1051a39Sopenharmony_ci } 970e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { 971e1051a39Sopenharmony_ci switch (p->data_size) { 972e1051a39Sopenharmony_ci case sizeof(uint32_t): 973e1051a39Sopenharmony_ci *val = *(const uint32_t *)p->data; 974e1051a39Sopenharmony_ci return 1; 975e1051a39Sopenharmony_ci case sizeof(uint64_t): 976e1051a39Sopenharmony_ci u64 = *(const uint64_t *)p->data; 977e1051a39Sopenharmony_ci if ((u64 >> real_shift()) == 0) { 978e1051a39Sopenharmony_ci *val = (double)u64; 979e1051a39Sopenharmony_ci return 1; 980e1051a39Sopenharmony_ci } 981e1051a39Sopenharmony_ci break; 982e1051a39Sopenharmony_ci } 983e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_INTEGER) { 984e1051a39Sopenharmony_ci switch (p->data_size) { 985e1051a39Sopenharmony_ci case sizeof(int32_t): 986e1051a39Sopenharmony_ci *val = *(const int32_t *)p->data; 987e1051a39Sopenharmony_ci return 1; 988e1051a39Sopenharmony_ci case sizeof(int64_t): 989e1051a39Sopenharmony_ci i64 = *(const int64_t *)p->data; 990e1051a39Sopenharmony_ci u64 = i64 < 0 ? -i64 : i64; 991e1051a39Sopenharmony_ci if ((u64 >> real_shift()) == 0) { 992e1051a39Sopenharmony_ci *val = 0.0 + i64; 993e1051a39Sopenharmony_ci return 1; 994e1051a39Sopenharmony_ci } 995e1051a39Sopenharmony_ci break; 996e1051a39Sopenharmony_ci } 997e1051a39Sopenharmony_ci } 998e1051a39Sopenharmony_ci return 0; 999e1051a39Sopenharmony_ci} 1000e1051a39Sopenharmony_ci 1001e1051a39Sopenharmony_ciint OSSL_PARAM_set_double(OSSL_PARAM *p, double val) 1002e1051a39Sopenharmony_ci{ 1003e1051a39Sopenharmony_ci if (p == NULL) 1004e1051a39Sopenharmony_ci return 0; 1005e1051a39Sopenharmony_ci p->return_size = 0; 1006e1051a39Sopenharmony_ci 1007e1051a39Sopenharmony_ci if (p->data_type == OSSL_PARAM_REAL) { 1008e1051a39Sopenharmony_ci p->return_size = sizeof(double); 1009e1051a39Sopenharmony_ci if (p->data == NULL) 1010e1051a39Sopenharmony_ci return 1; 1011e1051a39Sopenharmony_ci switch (p->data_size) { 1012e1051a39Sopenharmony_ci case sizeof(double): 1013e1051a39Sopenharmony_ci *(double *)p->data = val; 1014e1051a39Sopenharmony_ci return 1; 1015e1051a39Sopenharmony_ci } 1016e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER 1017e1051a39Sopenharmony_ci && val == (uint64_t)val) { 1018e1051a39Sopenharmony_ci p->return_size = sizeof(double); 1019e1051a39Sopenharmony_ci if (p->data == NULL) 1020e1051a39Sopenharmony_ci return 1; 1021e1051a39Sopenharmony_ci switch (p->data_size) { 1022e1051a39Sopenharmony_ci case sizeof(uint32_t): 1023e1051a39Sopenharmony_ci if (val >= 0 && val <= UINT32_MAX) { 1024e1051a39Sopenharmony_ci p->return_size = sizeof(uint32_t); 1025e1051a39Sopenharmony_ci *(uint32_t *)p->data = (uint32_t)val; 1026e1051a39Sopenharmony_ci return 1; 1027e1051a39Sopenharmony_ci } 1028e1051a39Sopenharmony_ci break; 1029e1051a39Sopenharmony_ci case sizeof(uint64_t): 1030e1051a39Sopenharmony_ci if (val >= 0 1031e1051a39Sopenharmony_ci /* 1032e1051a39Sopenharmony_ci * By subtracting 65535 (2^16-1) we cancel the low order 1033e1051a39Sopenharmony_ci * 15 bits of UINT64_MAX to avoid using imprecise floating 1034e1051a39Sopenharmony_ci * point values. 1035e1051a39Sopenharmony_ci */ 1036e1051a39Sopenharmony_ci && val < (double)(UINT64_MAX - 65535) + 65536.0) { 1037e1051a39Sopenharmony_ci p->return_size = sizeof(uint64_t); 1038e1051a39Sopenharmony_ci *(uint64_t *)p->data = (uint64_t)val; 1039e1051a39Sopenharmony_ci return 1; 1040e1051a39Sopenharmony_ci } 1041e1051a39Sopenharmony_ci break; } 1042e1051a39Sopenharmony_ci } else if (p->data_type == OSSL_PARAM_INTEGER && val == (int64_t)val) { 1043e1051a39Sopenharmony_ci p->return_size = sizeof(double); 1044e1051a39Sopenharmony_ci if (p->data == NULL) 1045e1051a39Sopenharmony_ci return 1; 1046e1051a39Sopenharmony_ci switch (p->data_size) { 1047e1051a39Sopenharmony_ci case sizeof(int32_t): 1048e1051a39Sopenharmony_ci if (val >= INT32_MIN && val <= INT32_MAX) { 1049e1051a39Sopenharmony_ci p->return_size = sizeof(int32_t); 1050e1051a39Sopenharmony_ci *(int32_t *)p->data = (int32_t)val; 1051e1051a39Sopenharmony_ci return 1; 1052e1051a39Sopenharmony_ci } 1053e1051a39Sopenharmony_ci break; 1054e1051a39Sopenharmony_ci case sizeof(int64_t): 1055e1051a39Sopenharmony_ci if (val >= INT64_MIN 1056e1051a39Sopenharmony_ci /* 1057e1051a39Sopenharmony_ci * By subtracting 65535 (2^16-1) we cancel the low order 1058e1051a39Sopenharmony_ci * 15 bits of INT64_MAX to avoid using imprecise floating 1059e1051a39Sopenharmony_ci * point values. 1060e1051a39Sopenharmony_ci */ 1061e1051a39Sopenharmony_ci && val < (double)(INT64_MAX - 65535) + 65536.0) { 1062e1051a39Sopenharmony_ci p->return_size = sizeof(int64_t); 1063e1051a39Sopenharmony_ci *(int64_t *)p->data = (int64_t)val; 1064e1051a39Sopenharmony_ci return 1; 1065e1051a39Sopenharmony_ci } 1066e1051a39Sopenharmony_ci break; 1067e1051a39Sopenharmony_ci } 1068e1051a39Sopenharmony_ci } 1069e1051a39Sopenharmony_ci return 0; 1070e1051a39Sopenharmony_ci} 1071e1051a39Sopenharmony_ci 1072e1051a39Sopenharmony_ciOSSL_PARAM OSSL_PARAM_construct_double(const char *key, double *buf) 1073e1051a39Sopenharmony_ci{ 1074e1051a39Sopenharmony_ci return ossl_param_construct(key, OSSL_PARAM_REAL, buf, sizeof(double)); 1075e1051a39Sopenharmony_ci} 1076e1051a39Sopenharmony_ci 1077e1051a39Sopenharmony_cistatic int get_string_internal(const OSSL_PARAM *p, void **val, 1078e1051a39Sopenharmony_ci size_t *max_len, size_t *used_len, 1079e1051a39Sopenharmony_ci unsigned int type) 1080e1051a39Sopenharmony_ci{ 1081e1051a39Sopenharmony_ci size_t sz, alloc_sz; 1082e1051a39Sopenharmony_ci 1083e1051a39Sopenharmony_ci if ((val == NULL && used_len == NULL) || p == NULL || p->data_type != type) 1084e1051a39Sopenharmony_ci return 0; 1085e1051a39Sopenharmony_ci 1086e1051a39Sopenharmony_ci sz = p->data_size; 1087e1051a39Sopenharmony_ci /* 1088e1051a39Sopenharmony_ci * If the input size is 0, or the input string needs NUL byte 1089e1051a39Sopenharmony_ci * termination, allocate an extra byte. 1090e1051a39Sopenharmony_ci */ 1091e1051a39Sopenharmony_ci alloc_sz = sz + (type == OSSL_PARAM_UTF8_STRING || sz == 0); 1092e1051a39Sopenharmony_ci 1093e1051a39Sopenharmony_ci if (used_len != NULL) 1094e1051a39Sopenharmony_ci *used_len = sz; 1095e1051a39Sopenharmony_ci 1096e1051a39Sopenharmony_ci if (p->data == NULL) 1097e1051a39Sopenharmony_ci return 0; 1098e1051a39Sopenharmony_ci 1099e1051a39Sopenharmony_ci if (val == NULL) 1100e1051a39Sopenharmony_ci return 1; 1101e1051a39Sopenharmony_ci 1102e1051a39Sopenharmony_ci if (*val == NULL) { 1103e1051a39Sopenharmony_ci char *const q = OPENSSL_malloc(alloc_sz); 1104e1051a39Sopenharmony_ci 1105e1051a39Sopenharmony_ci if (q == NULL) 1106e1051a39Sopenharmony_ci return 0; 1107e1051a39Sopenharmony_ci *val = q; 1108e1051a39Sopenharmony_ci *max_len = alloc_sz; 1109e1051a39Sopenharmony_ci } 1110e1051a39Sopenharmony_ci 1111e1051a39Sopenharmony_ci if (*max_len < sz) 1112e1051a39Sopenharmony_ci return 0; 1113e1051a39Sopenharmony_ci memcpy(*val, p->data, sz); 1114e1051a39Sopenharmony_ci return 1; 1115e1051a39Sopenharmony_ci} 1116e1051a39Sopenharmony_ci 1117e1051a39Sopenharmony_ciint OSSL_PARAM_get_utf8_string(const OSSL_PARAM *p, char **val, size_t max_len) 1118e1051a39Sopenharmony_ci{ 1119e1051a39Sopenharmony_ci int ret = get_string_internal(p, (void **)val, &max_len, NULL, 1120e1051a39Sopenharmony_ci OSSL_PARAM_UTF8_STRING); 1121e1051a39Sopenharmony_ci 1122e1051a39Sopenharmony_ci /* 1123e1051a39Sopenharmony_ci * We try to ensure that the copied string is terminated with a 1124e1051a39Sopenharmony_ci * NUL byte. That should be easy, just place a NUL byte at 1125e1051a39Sopenharmony_ci * |((char*)*val)[p->data_size]|. 1126e1051a39Sopenharmony_ci * Unfortunately, we have seen cases where |p->data_size| doesn't 1127e1051a39Sopenharmony_ci * correctly reflect the length of the string, and just happens 1128e1051a39Sopenharmony_ci * to be out of bounds according to |max_len|, so in that case, we 1129e1051a39Sopenharmony_ci * make the extra step of trying to find the true length of the 1130e1051a39Sopenharmony_ci * string that |p->data| points at, and use that as an index to 1131e1051a39Sopenharmony_ci * place the NUL byte in |*val|. 1132e1051a39Sopenharmony_ci */ 1133e1051a39Sopenharmony_ci size_t data_length = p->data_size; 1134e1051a39Sopenharmony_ci 1135e1051a39Sopenharmony_ci if (ret == 0) 1136e1051a39Sopenharmony_ci return 0; 1137e1051a39Sopenharmony_ci if (data_length >= max_len) 1138e1051a39Sopenharmony_ci data_length = OPENSSL_strnlen(p->data, data_length); 1139e1051a39Sopenharmony_ci if (data_length >= max_len) 1140e1051a39Sopenharmony_ci return 0; /* No space for a terminating NUL byte */ 1141e1051a39Sopenharmony_ci (*val)[data_length] = '\0'; 1142e1051a39Sopenharmony_ci 1143e1051a39Sopenharmony_ci return ret; 1144e1051a39Sopenharmony_ci} 1145e1051a39Sopenharmony_ci 1146e1051a39Sopenharmony_ciint OSSL_PARAM_get_octet_string(const OSSL_PARAM *p, void **val, size_t max_len, 1147e1051a39Sopenharmony_ci size_t *used_len) 1148e1051a39Sopenharmony_ci{ 1149e1051a39Sopenharmony_ci return get_string_internal(p, val, &max_len, used_len, 1150e1051a39Sopenharmony_ci OSSL_PARAM_OCTET_STRING); 1151e1051a39Sopenharmony_ci} 1152e1051a39Sopenharmony_ci 1153e1051a39Sopenharmony_cistatic int set_string_internal(OSSL_PARAM *p, const void *val, size_t len, 1154e1051a39Sopenharmony_ci unsigned int type) 1155e1051a39Sopenharmony_ci{ 1156e1051a39Sopenharmony_ci p->return_size = len; 1157e1051a39Sopenharmony_ci if (p->data == NULL) 1158e1051a39Sopenharmony_ci return 1; 1159e1051a39Sopenharmony_ci if (p->data_type != type || p->data_size < len) 1160e1051a39Sopenharmony_ci return 0; 1161e1051a39Sopenharmony_ci 1162e1051a39Sopenharmony_ci memcpy(p->data, val, len); 1163e1051a39Sopenharmony_ci /* If possible within the size of p->data, add a NUL terminator byte */ 1164e1051a39Sopenharmony_ci if (type == OSSL_PARAM_UTF8_STRING && p->data_size > len) 1165e1051a39Sopenharmony_ci ((char *)p->data)[len] = '\0'; 1166e1051a39Sopenharmony_ci return 1; 1167e1051a39Sopenharmony_ci} 1168e1051a39Sopenharmony_ci 1169e1051a39Sopenharmony_ciint OSSL_PARAM_set_utf8_string(OSSL_PARAM *p, const char *val) 1170e1051a39Sopenharmony_ci{ 1171e1051a39Sopenharmony_ci if (p == NULL) 1172e1051a39Sopenharmony_ci return 0; 1173e1051a39Sopenharmony_ci 1174e1051a39Sopenharmony_ci p->return_size = 0; 1175e1051a39Sopenharmony_ci if (val == NULL) 1176e1051a39Sopenharmony_ci return 0; 1177e1051a39Sopenharmony_ci return set_string_internal(p, val, strlen(val), OSSL_PARAM_UTF8_STRING); 1178e1051a39Sopenharmony_ci} 1179e1051a39Sopenharmony_ci 1180e1051a39Sopenharmony_ciint OSSL_PARAM_set_octet_string(OSSL_PARAM *p, const void *val, 1181e1051a39Sopenharmony_ci size_t len) 1182e1051a39Sopenharmony_ci{ 1183e1051a39Sopenharmony_ci if (p == NULL) 1184e1051a39Sopenharmony_ci return 0; 1185e1051a39Sopenharmony_ci 1186e1051a39Sopenharmony_ci p->return_size = 0; 1187e1051a39Sopenharmony_ci if (val == NULL) 1188e1051a39Sopenharmony_ci return 0; 1189e1051a39Sopenharmony_ci return set_string_internal(p, val, len, OSSL_PARAM_OCTET_STRING); 1190e1051a39Sopenharmony_ci} 1191e1051a39Sopenharmony_ci 1192e1051a39Sopenharmony_ciOSSL_PARAM OSSL_PARAM_construct_utf8_string(const char *key, char *buf, 1193e1051a39Sopenharmony_ci size_t bsize) 1194e1051a39Sopenharmony_ci{ 1195e1051a39Sopenharmony_ci if (buf != NULL && bsize == 0) 1196e1051a39Sopenharmony_ci bsize = strlen(buf); 1197e1051a39Sopenharmony_ci return ossl_param_construct(key, OSSL_PARAM_UTF8_STRING, buf, bsize); 1198e1051a39Sopenharmony_ci} 1199e1051a39Sopenharmony_ci 1200e1051a39Sopenharmony_ciOSSL_PARAM OSSL_PARAM_construct_octet_string(const char *key, void *buf, 1201e1051a39Sopenharmony_ci size_t bsize) 1202e1051a39Sopenharmony_ci{ 1203e1051a39Sopenharmony_ci return ossl_param_construct(key, OSSL_PARAM_OCTET_STRING, buf, bsize); 1204e1051a39Sopenharmony_ci} 1205e1051a39Sopenharmony_ci 1206e1051a39Sopenharmony_cistatic int get_ptr_internal(const OSSL_PARAM *p, const void **val, 1207e1051a39Sopenharmony_ci size_t *used_len, unsigned int type) 1208e1051a39Sopenharmony_ci{ 1209e1051a39Sopenharmony_ci if (val == NULL || p == NULL || p->data_type != type) 1210e1051a39Sopenharmony_ci return 0; 1211e1051a39Sopenharmony_ci if (used_len != NULL) 1212e1051a39Sopenharmony_ci *used_len = p->data_size; 1213e1051a39Sopenharmony_ci *val = *(const void **)p->data; 1214e1051a39Sopenharmony_ci return 1; 1215e1051a39Sopenharmony_ci} 1216e1051a39Sopenharmony_ci 1217e1051a39Sopenharmony_ciint OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM *p, const char **val) 1218e1051a39Sopenharmony_ci{ 1219e1051a39Sopenharmony_ci return get_ptr_internal(p, (const void **)val, NULL, OSSL_PARAM_UTF8_PTR); 1220e1051a39Sopenharmony_ci} 1221e1051a39Sopenharmony_ci 1222e1051a39Sopenharmony_ciint OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, const void **val, 1223e1051a39Sopenharmony_ci size_t *used_len) 1224e1051a39Sopenharmony_ci{ 1225e1051a39Sopenharmony_ci return get_ptr_internal(p, val, used_len, OSSL_PARAM_OCTET_PTR); 1226e1051a39Sopenharmony_ci} 1227e1051a39Sopenharmony_ci 1228e1051a39Sopenharmony_cistatic int set_ptr_internal(OSSL_PARAM *p, const void *val, 1229e1051a39Sopenharmony_ci unsigned int type, size_t len) 1230e1051a39Sopenharmony_ci{ 1231e1051a39Sopenharmony_ci p->return_size = len; 1232e1051a39Sopenharmony_ci if (p->data_type != type) 1233e1051a39Sopenharmony_ci return 0; 1234e1051a39Sopenharmony_ci if (p->data != NULL) 1235e1051a39Sopenharmony_ci *(const void **)p->data = val; 1236e1051a39Sopenharmony_ci return 1; 1237e1051a39Sopenharmony_ci} 1238e1051a39Sopenharmony_ci 1239e1051a39Sopenharmony_ciint OSSL_PARAM_set_utf8_ptr(OSSL_PARAM *p, const char *val) 1240e1051a39Sopenharmony_ci{ 1241e1051a39Sopenharmony_ci if (p == NULL) 1242e1051a39Sopenharmony_ci return 0; 1243e1051a39Sopenharmony_ci p->return_size = 0; 1244e1051a39Sopenharmony_ci return set_ptr_internal(p, val, OSSL_PARAM_UTF8_PTR, 1245e1051a39Sopenharmony_ci val == NULL ? 0 : strlen(val)); 1246e1051a39Sopenharmony_ci} 1247e1051a39Sopenharmony_ci 1248e1051a39Sopenharmony_ciint OSSL_PARAM_set_octet_ptr(OSSL_PARAM *p, const void *val, 1249e1051a39Sopenharmony_ci size_t used_len) 1250e1051a39Sopenharmony_ci{ 1251e1051a39Sopenharmony_ci if (p == NULL) 1252e1051a39Sopenharmony_ci return 0; 1253e1051a39Sopenharmony_ci p->return_size = 0; 1254e1051a39Sopenharmony_ci return set_ptr_internal(p, val, OSSL_PARAM_OCTET_PTR, used_len); 1255e1051a39Sopenharmony_ci} 1256e1051a39Sopenharmony_ci 1257e1051a39Sopenharmony_ciOSSL_PARAM OSSL_PARAM_construct_utf8_ptr(const char *key, char **buf, 1258e1051a39Sopenharmony_ci size_t bsize) 1259e1051a39Sopenharmony_ci{ 1260e1051a39Sopenharmony_ci return ossl_param_construct(key, OSSL_PARAM_UTF8_PTR, buf, bsize); 1261e1051a39Sopenharmony_ci} 1262e1051a39Sopenharmony_ci 1263e1051a39Sopenharmony_ciOSSL_PARAM OSSL_PARAM_construct_octet_ptr(const char *key, void **buf, 1264e1051a39Sopenharmony_ci size_t bsize) 1265e1051a39Sopenharmony_ci{ 1266e1051a39Sopenharmony_ci return ossl_param_construct(key, OSSL_PARAM_OCTET_PTR, buf, bsize); 1267e1051a39Sopenharmony_ci} 1268e1051a39Sopenharmony_ci 1269e1051a39Sopenharmony_ciOSSL_PARAM OSSL_PARAM_construct_end(void) 1270e1051a39Sopenharmony_ci{ 1271e1051a39Sopenharmony_ci OSSL_PARAM end = OSSL_PARAM_END; 1272e1051a39Sopenharmony_ci 1273e1051a39Sopenharmony_ci return end; 1274e1051a39Sopenharmony_ci} 1275e1051a39Sopenharmony_ci 1276e1051a39Sopenharmony_cistatic int get_string_ptr_internal(const OSSL_PARAM *p, const void **val, 1277e1051a39Sopenharmony_ci size_t *used_len, unsigned int type) 1278e1051a39Sopenharmony_ci{ 1279e1051a39Sopenharmony_ci if (val == NULL || p == NULL || p->data_type != type) 1280e1051a39Sopenharmony_ci return 0; 1281e1051a39Sopenharmony_ci if (used_len != NULL) 1282e1051a39Sopenharmony_ci *used_len = p->data_size; 1283e1051a39Sopenharmony_ci *val = p->data; 1284e1051a39Sopenharmony_ci return 1; 1285e1051a39Sopenharmony_ci} 1286e1051a39Sopenharmony_ci 1287e1051a39Sopenharmony_ciint OSSL_PARAM_get_utf8_string_ptr(const OSSL_PARAM *p, const char **val) 1288e1051a39Sopenharmony_ci{ 1289e1051a39Sopenharmony_ci return OSSL_PARAM_get_utf8_ptr(p, val) 1290e1051a39Sopenharmony_ci || get_string_ptr_internal(p, (const void **)val, NULL, 1291e1051a39Sopenharmony_ci OSSL_PARAM_UTF8_STRING); 1292e1051a39Sopenharmony_ci} 1293e1051a39Sopenharmony_ci 1294e1051a39Sopenharmony_ciint OSSL_PARAM_get_octet_string_ptr(const OSSL_PARAM *p, const void **val, 1295e1051a39Sopenharmony_ci size_t *used_len) 1296e1051a39Sopenharmony_ci{ 1297e1051a39Sopenharmony_ci return OSSL_PARAM_get_octet_ptr(p, val, used_len) 1298e1051a39Sopenharmony_ci || get_string_ptr_internal(p, val, used_len, OSSL_PARAM_OCTET_STRING); 1299e1051a39Sopenharmony_ci} 1300