1 /* 2 * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. 3 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 4 * 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 9 */ 10 11 #include <string.h> 12 #include <openssl/params.h> 13 #include <openssl/err.h> 14 #include "internal/thread_once.h" 15 #include "internal/numbers.h" 16 #include "internal/endian.h" 17 #include "internal/params.h" 18 #include "internal/packet.h" 19 20 /* Shortcuts for raising errors that are widely used */ 21 #define err_unsigned_negative \ 22 ERR_raise(ERR_LIB_CRYPTO, \ 23 CRYPTO_R_PARAM_UNSIGNED_INTEGER_NEGATIVE_VALUE_UNSUPPORTED) 24 #define err_out_of_range \ 25 ERR_raise(ERR_LIB_CRYPTO, \ 26 CRYPTO_R_PARAM_VALUE_TOO_LARGE_FOR_DESTINATION) 27 #define err_inexact \ 28 ERR_raise(ERR_LIB_CRYPTO, \ 29 CRYPTO_R_PARAM_CANNOT_BE_REPRESENTED_EXACTLY) 30 #define err_not_integer \ 31 ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_PARAM_NOT_INTEGER_TYPE) 32 #define err_too_small \ 33 ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_SMALL_BUFFER) 34 #define err_bad_type \ 35 ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_PARAM_OF_INCOMPATIBLE_TYPE) 36 #define err_null_argument \ 37 ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER) 38 #define err_unsupported_real \ 39 ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_PARAM_UNSUPPORTED_FLOATING_POINT_FORMAT) 40 41 #ifndef OPENSSL_SYS_UEFI 42 /* 43 * Return the number of bits in the mantissa of a double. This is used to 44 * shift a larger integral value to determine if it will exactly fit into a 45 * double. 46 */ 47 static unsigned int real_shift(void) 48 { 49 return sizeof(double) == 4 ? 24 : 53; 50 } 51 #endif 52 53 OSSL_PARAM *OSSL_PARAM_locate(OSSL_PARAM *p, const char *key) 54 { 55 if (p != NULL && key != NULL) 56 for (; p->key != NULL; p++) 57 if (strcmp(key, p->key) == 0) 58 return p; 59 return NULL; 60 } 61 62 const OSSL_PARAM *OSSL_PARAM_locate_const(const OSSL_PARAM *p, const char *key) 63 { 64 return OSSL_PARAM_locate((OSSL_PARAM *)p, key); 65 } 66 67 static OSSL_PARAM ossl_param_construct(const char *key, unsigned int data_type, 68 void *data, size_t data_size) 69 { 70 OSSL_PARAM res; 71 72 res.key = key; 73 res.data_type = data_type; 74 res.data = data; 75 res.data_size = data_size; 76 res.return_size = OSSL_PARAM_UNMODIFIED; 77 return res; 78 } 79 80 int OSSL_PARAM_modified(const OSSL_PARAM *p) 81 { 82 return p != NULL && p->return_size != OSSL_PARAM_UNMODIFIED; 83 } 84 85 void OSSL_PARAM_set_all_unmodified(OSSL_PARAM *p) 86 { 87 if (p != NULL) 88 while (p->key != NULL) 89 p++->return_size = OSSL_PARAM_UNMODIFIED; 90 } 91 92 /* Return non-zero if the signed number is negative */ 93 static int is_negative(const void *number, size_t s) 94 { 95 const unsigned char *n = number; 96 DECLARE_IS_ENDIAN; 97 98 return 0x80 & (IS_BIG_ENDIAN ? n[0] : n[s - 1]); 99 } 100 101 /* Check that all the bytes specified match the expected sign byte */ 102 static int check_sign_bytes(const unsigned char *p, size_t n, unsigned char s) 103 { 104 size_t i; 105 106 for (i = 0; i < n; i++) 107 if (p[i] != s) 108 return 0; 109 return 1; 110 } 111 112 /* 113 * Copy an integer to another integer. 114 * Handle different length integers and signed and unsigned integers. 115 * Both integers are in native byte ordering. 116 */ 117 static int copy_integer(unsigned char *dest, size_t dest_len, 118 const unsigned char *src, size_t src_len, 119 unsigned char pad, int signed_int) 120 { 121 size_t n; 122 DECLARE_IS_ENDIAN; 123 124 if (IS_BIG_ENDIAN) { 125 if (src_len < dest_len) { 126 n = dest_len - src_len; 127 memset(dest, pad, n); 128 memcpy(dest + n, src, src_len); 129 } else { 130 n = src_len - dest_len; 131 if (!check_sign_bytes(src, n, pad) 132 /* 133 * Shortening a signed value must retain the correct sign. 134 * Avoiding this kind of thing: -253 = 0xff03 -> 0x03 = 3 135 */ 136 || (signed_int && ((pad ^ src[n]) & 0x80) != 0)) { 137 err_out_of_range; 138 return 0; 139 } 140 memcpy(dest, src + n, dest_len); 141 } 142 } else /* IS_LITTLE_ENDIAN */ { 143 if (src_len < dest_len) { 144 n = dest_len - src_len; 145 memset(dest + src_len, pad, n); 146 memcpy(dest, src, src_len); 147 } else { 148 n = src_len - dest_len; 149 if (!check_sign_bytes(src + dest_len, n, pad) 150 /* 151 * Shortening a signed value must retain the correct sign. 152 * Avoiding this kind of thing: 130 = 0x0082 -> 0x82 = -126 153 */ 154 || (signed_int && ((pad ^ src[dest_len - 1]) & 0x80) != 0)) { 155 err_out_of_range; 156 return 0; 157 } 158 memcpy(dest, src, dest_len); 159 } 160 } 161 return 1; 162 } 163 164 /* Copy a signed number to a signed number of possibly different length */ 165 static int signed_from_signed(void *dest, size_t dest_len, 166 const void *src, size_t src_len) 167 { 168 return copy_integer(dest, dest_len, src, src_len, 169 is_negative(src, src_len) ? 0xff : 0, 1); 170 } 171 172 /* Copy an unsigned number to a signed number of possibly different length */ 173 static int signed_from_unsigned(void *dest, size_t dest_len, 174 const void *src, size_t src_len) 175 { 176 return copy_integer(dest, dest_len, src, src_len, 0, 1); 177 } 178 179 /* Copy a signed number to an unsigned number of possibly different length */ 180 static int unsigned_from_signed(void *dest, size_t dest_len, 181 const void *src, size_t src_len) 182 { 183 if (is_negative(src, src_len)) { 184 err_unsigned_negative; 185 return 0; 186 } 187 return copy_integer(dest, dest_len, src, src_len, 0, 0); 188 } 189 190 /* Copy an unsigned number to an unsigned number of possibly different length */ 191 static int unsigned_from_unsigned(void *dest, size_t dest_len, 192 const void *src, size_t src_len) 193 { 194 return copy_integer(dest, dest_len, src, src_len, 0, 0); 195 } 196 197 /* General purpose get integer parameter call that handles odd sizes */ 198 static int general_get_int(const OSSL_PARAM *p, void *val, size_t val_size) 199 { 200 if (p->data == NULL) { 201 err_null_argument; 202 return 0; 203 } 204 if (p->data_type == OSSL_PARAM_INTEGER) 205 return signed_from_signed(val, val_size, p->data, p->data_size); 206 if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) 207 return signed_from_unsigned(val, val_size, p->data, p->data_size); 208 err_not_integer; 209 return 0; 210 } 211 212 /* General purpose set integer parameter call that handles odd sizes */ 213 static int general_set_int(OSSL_PARAM *p, void *val, size_t val_size) 214 { 215 int r = 0; 216 217 if (p->data == NULL) { 218 p->return_size = val_size; /* Expected size */ 219 return 1; 220 } 221 if (p->data_type == OSSL_PARAM_INTEGER) 222 r = signed_from_signed(p->data, p->data_size, val, val_size); 223 else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) 224 r = unsigned_from_signed(p->data, p->data_size, val, val_size); 225 else 226 err_not_integer; 227 p->return_size = r ? p->data_size : val_size; 228 return r; 229 } 230 231 /* General purpose get unsigned integer parameter call that handles odd sizes */ 232 static int general_get_uint(const OSSL_PARAM *p, void *val, size_t val_size) 233 { 234 235 if (p->data == NULL) { 236 err_null_argument; 237 return 0; 238 } 239 if (p->data_type == OSSL_PARAM_INTEGER) 240 return unsigned_from_signed(val, val_size, p->data, p->data_size); 241 if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) 242 return unsigned_from_unsigned(val, val_size, p->data, p->data_size); 243 err_not_integer; 244 return 0; 245 } 246 247 /* General purpose set unsigned integer parameter call that handles odd sizes */ 248 static int general_set_uint(OSSL_PARAM *p, void *val, size_t val_size) 249 { 250 int r = 0; 251 252 if (p->data == NULL) { 253 p->return_size = val_size; /* Expected size */ 254 return 1; 255 } 256 if (p->data_type == OSSL_PARAM_INTEGER) 257 r = signed_from_unsigned(p->data, p->data_size, val, val_size); 258 else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) 259 r = unsigned_from_unsigned(p->data, p->data_size, val, val_size); 260 else 261 err_not_integer; 262 p->return_size = r ? p->data_size : val_size; 263 return r; 264 } 265 266 int OSSL_PARAM_get_int(const OSSL_PARAM *p, int *val) 267 { 268 #ifndef OPENSSL_SMALL_FOOTPRINT 269 switch (sizeof(int)) { 270 case sizeof(int32_t): 271 return OSSL_PARAM_get_int32(p, (int32_t *)val); 272 case sizeof(int64_t): 273 return OSSL_PARAM_get_int64(p, (int64_t *)val); 274 } 275 #endif 276 return general_get_int(p, val, sizeof(*val)); 277 } 278 279 int OSSL_PARAM_set_int(OSSL_PARAM *p, int val) 280 { 281 #ifndef OPENSSL_SMALL_FOOTPRINT 282 switch (sizeof(int)) { 283 case sizeof(int32_t): 284 return OSSL_PARAM_set_int32(p, (int32_t)val); 285 case sizeof(int64_t): 286 return OSSL_PARAM_set_int64(p, (int64_t)val); 287 } 288 #endif 289 return general_set_int(p, &val, sizeof(val)); 290 } 291 292 OSSL_PARAM OSSL_PARAM_construct_int(const char *key, int *buf) 293 { 294 return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int)); 295 } 296 297 int OSSL_PARAM_get_uint(const OSSL_PARAM *p, unsigned int *val) 298 { 299 #ifndef OPENSSL_SMALL_FOOTPRINT 300 switch (sizeof(unsigned int)) { 301 case sizeof(uint32_t): 302 return OSSL_PARAM_get_uint32(p, (uint32_t *)val); 303 case sizeof(uint64_t): 304 return OSSL_PARAM_get_uint64(p, (uint64_t *)val); 305 } 306 #endif 307 return general_get_uint(p, val, sizeof(*val)); 308 } 309 310 int OSSL_PARAM_set_uint(OSSL_PARAM *p, unsigned int val) 311 { 312 #ifndef OPENSSL_SMALL_FOOTPRINT 313 switch (sizeof(unsigned int)) { 314 case sizeof(uint32_t): 315 return OSSL_PARAM_set_uint32(p, (uint32_t)val); 316 case sizeof(uint64_t): 317 return OSSL_PARAM_set_uint64(p, (uint64_t)val); 318 } 319 #endif 320 return general_set_uint(p, &val, sizeof(val)); 321 } 322 323 OSSL_PARAM OSSL_PARAM_construct_uint(const char *key, unsigned int *buf) 324 { 325 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf, 326 sizeof(unsigned int)); 327 } 328 329 int OSSL_PARAM_get_long(const OSSL_PARAM *p, long int *val) 330 { 331 #ifndef OPENSSL_SMALL_FOOTPRINT 332 switch (sizeof(long int)) { 333 case sizeof(int32_t): 334 return OSSL_PARAM_get_int32(p, (int32_t *)val); 335 case sizeof(int64_t): 336 return OSSL_PARAM_get_int64(p, (int64_t *)val); 337 } 338 #endif 339 return general_get_int(p, val, sizeof(*val)); 340 } 341 342 int OSSL_PARAM_set_long(OSSL_PARAM *p, long int val) 343 { 344 #ifndef OPENSSL_SMALL_FOOTPRINT 345 switch (sizeof(long int)) { 346 case sizeof(int32_t): 347 return OSSL_PARAM_set_int32(p, (int32_t)val); 348 case sizeof(int64_t): 349 return OSSL_PARAM_set_int64(p, (int64_t)val); 350 } 351 #endif 352 return general_set_int(p, &val, sizeof(val)); 353 } 354 355 OSSL_PARAM OSSL_PARAM_construct_long(const char *key, long int *buf) 356 { 357 return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(long int)); 358 } 359 360 int OSSL_PARAM_get_ulong(const OSSL_PARAM *p, unsigned long int *val) 361 { 362 #ifndef OPENSSL_SMALL_FOOTPRINT 363 switch (sizeof(unsigned long int)) { 364 case sizeof(uint32_t): 365 return OSSL_PARAM_get_uint32(p, (uint32_t *)val); 366 case sizeof(uint64_t): 367 return OSSL_PARAM_get_uint64(p, (uint64_t *)val); 368 } 369 #endif 370 return general_get_uint(p, val, sizeof(*val)); 371 } 372 373 int OSSL_PARAM_set_ulong(OSSL_PARAM *p, unsigned long int val) 374 { 375 #ifndef OPENSSL_SMALL_FOOTPRINT 376 switch (sizeof(unsigned long int)) { 377 case sizeof(uint32_t): 378 return OSSL_PARAM_set_uint32(p, (uint32_t)val); 379 case sizeof(uint64_t): 380 return OSSL_PARAM_set_uint64(p, (uint64_t)val); 381 } 382 #endif 383 return general_set_uint(p, &val, sizeof(val)); 384 } 385 386 OSSL_PARAM OSSL_PARAM_construct_ulong(const char *key, unsigned long int *buf) 387 { 388 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf, 389 sizeof(unsigned long int)); 390 } 391 392 int OSSL_PARAM_get_int32(const OSSL_PARAM *p, int32_t *val) 393 { 394 if (val == NULL || p == NULL) { 395 err_null_argument; 396 return 0; 397 } 398 399 if (p->data == NULL) { 400 err_null_argument; 401 return 0; 402 } 403 404 if (p->data_type == OSSL_PARAM_INTEGER) { 405 #ifndef OPENSSL_SMALL_FOOTPRINT 406 int64_t i64; 407 408 switch (p->data_size) { 409 case sizeof(int32_t): 410 *val = *(const int32_t *)p->data; 411 return 1; 412 case sizeof(int64_t): 413 i64 = *(const int64_t *)p->data; 414 if (i64 >= INT32_MIN && i64 <= INT32_MAX) { 415 *val = (int32_t)i64; 416 return 1; 417 } 418 err_out_of_range; 419 return 0; 420 } 421 #endif 422 return general_get_int(p, val, sizeof(*val)); 423 424 } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { 425 #ifndef OPENSSL_SMALL_FOOTPRINT 426 uint32_t u32; 427 uint64_t u64; 428 429 switch (p->data_size) { 430 case sizeof(uint32_t): 431 u32 = *(const uint32_t *)p->data; 432 if (u32 <= INT32_MAX) { 433 *val = (int32_t)u32; 434 return 1; 435 } 436 err_out_of_range; 437 return 0; 438 case sizeof(uint64_t): 439 u64 = *(const uint64_t *)p->data; 440 if (u64 <= INT32_MAX) { 441 *val = (int32_t)u64; 442 return 1; 443 } 444 err_out_of_range; 445 return 0; 446 } 447 #endif 448 return general_get_int(p, val, sizeof(*val)); 449 450 } else if (p->data_type == OSSL_PARAM_REAL) { 451 #ifndef OPENSSL_SYS_UEFI 452 double d; 453 454 switch (p->data_size) { 455 case sizeof(double): 456 d = *(const double *)p->data; 457 if (d >= INT32_MIN && d <= INT32_MAX && d == (int32_t)d) { 458 *val = (int32_t)d; 459 return 1; 460 } 461 err_out_of_range; 462 return 0; 463 } 464 err_unsupported_real; 465 return 0; 466 #endif 467 } 468 err_bad_type; 469 return 0; 470 } 471 472 int OSSL_PARAM_set_int32(OSSL_PARAM *p, int32_t val) 473 { 474 if (p == NULL) { 475 err_null_argument; 476 return 0; 477 } 478 p->return_size = 0; 479 if (p->data_type == OSSL_PARAM_INTEGER) { 480 #ifndef OPENSSL_SMALL_FOOTPRINT 481 p->return_size = sizeof(int32_t); /* Minimum expected size */ 482 if (p->data == NULL) 483 return 1; 484 switch (p->data_size) { 485 case sizeof(int32_t): 486 *(int32_t *)p->data = val; 487 return 1; 488 case sizeof(int64_t): 489 p->return_size = sizeof(int64_t); 490 *(int64_t *)p->data = (int64_t)val; 491 return 1; 492 } 493 #endif 494 return general_set_int(p, &val, sizeof(val)); 495 } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) { 496 #ifndef OPENSSL_SMALL_FOOTPRINT 497 p->return_size = sizeof(uint32_t); /* Minimum expected size */ 498 if (p->data == NULL) 499 return 1; 500 switch (p->data_size) { 501 case sizeof(uint32_t): 502 *(uint32_t *)p->data = (uint32_t)val; 503 return 1; 504 case sizeof(uint64_t): 505 p->return_size = sizeof(uint64_t); 506 *(uint64_t *)p->data = (uint64_t)val; 507 return 1; 508 } 509 #endif 510 return general_set_int(p, &val, sizeof(val)); 511 } else if (p->data_type == OSSL_PARAM_REAL) { 512 #ifndef OPENSSL_SYS_UEFI 513 uint32_t u32; 514 unsigned int shift; 515 516 p->return_size = sizeof(double); 517 if (p->data == NULL) 518 return 1; 519 switch (p->data_size) { 520 case sizeof(double): 521 shift = real_shift(); 522 if (shift < 8 * sizeof(val) - 1) { 523 u32 = val < 0 ? -val : val; 524 if ((u32 >> shift) != 0) { 525 err_inexact; 526 return 0; 527 } 528 } 529 *(double *)p->data = (double)val; 530 return 1; 531 } 532 err_unsupported_real; 533 return 0; 534 #endif 535 } 536 err_bad_type; 537 return 0; 538 } 539 540 OSSL_PARAM OSSL_PARAM_construct_int32(const char *key, int32_t *buf) 541 { 542 return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, 543 sizeof(int32_t)); 544 } 545 546 int OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val) 547 { 548 if (val == NULL || p == NULL) { 549 err_null_argument; 550 return 0; 551 } 552 553 if (p->data == NULL) { 554 err_null_argument; 555 return 0; 556 } 557 558 if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { 559 #ifndef OPENSSL_SMALL_FOOTPRINT 560 uint64_t u64; 561 562 switch (p->data_size) { 563 case sizeof(uint32_t): 564 *val = *(const uint32_t *)p->data; 565 return 1; 566 case sizeof(uint64_t): 567 u64 = *(const uint64_t *)p->data; 568 if (u64 <= UINT32_MAX) { 569 *val = (uint32_t)u64; 570 return 1; 571 } 572 err_out_of_range; 573 return 0; 574 } 575 #endif 576 return general_get_uint(p, val, sizeof(*val)); 577 } else if (p->data_type == OSSL_PARAM_INTEGER) { 578 #ifndef OPENSSL_SMALL_FOOTPRINT 579 int32_t i32; 580 int64_t i64; 581 582 switch (p->data_size) { 583 case sizeof(int32_t): 584 i32 = *(const int32_t *)p->data; 585 if (i32 >= 0) { 586 *val = i32; 587 return 1; 588 } 589 err_unsigned_negative; 590 return 0; 591 case sizeof(int64_t): 592 i64 = *(const int64_t *)p->data; 593 if (i64 >= 0 && i64 <= UINT32_MAX) { 594 *val = (uint32_t)i64; 595 return 1; 596 } 597 if (i64 < 0) 598 err_unsigned_negative; 599 else 600 err_out_of_range; 601 return 0; 602 } 603 #endif 604 return general_get_uint(p, val, sizeof(*val)); 605 } else if (p->data_type == OSSL_PARAM_REAL) { 606 #ifndef OPENSSL_SYS_UEFI 607 double d; 608 609 switch (p->data_size) { 610 case sizeof(double): 611 d = *(const double *)p->data; 612 if (d >= 0 && d <= UINT32_MAX && d == (uint32_t)d) { 613 *val = (uint32_t)d; 614 return 1; 615 } 616 err_inexact; 617 return 0; 618 } 619 err_unsupported_real; 620 return 0; 621 #endif 622 } 623 err_bad_type; 624 return 0; 625 } 626 627 int OSSL_PARAM_set_uint32(OSSL_PARAM *p, uint32_t val) 628 { 629 if (p == NULL) { 630 err_null_argument; 631 return 0; 632 } 633 p->return_size = 0; 634 635 if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { 636 #ifndef OPENSSL_SMALL_FOOTPRINT 637 p->return_size = sizeof(uint32_t); /* Minimum expected size */ 638 if (p->data == NULL) 639 return 1; 640 switch (p->data_size) { 641 case sizeof(uint32_t): 642 *(uint32_t *)p->data = val; 643 return 1; 644 case sizeof(uint64_t): 645 p->return_size = sizeof(uint64_t); 646 *(uint64_t *)p->data = val; 647 return 1; 648 } 649 #endif 650 return general_set_uint(p, &val, sizeof(val)); 651 } else if (p->data_type == OSSL_PARAM_INTEGER) { 652 #ifndef OPENSSL_SMALL_FOOTPRINT 653 p->return_size = sizeof(int32_t); /* Minimum expected size */ 654 if (p->data == NULL) 655 return 1; 656 switch (p->data_size) { 657 case sizeof(int32_t): 658 if (val <= INT32_MAX) { 659 *(int32_t *)p->data = (int32_t)val; 660 return 1; 661 } 662 err_out_of_range; 663 return 0; 664 case sizeof(int64_t): 665 p->return_size = sizeof(int64_t); 666 *(int64_t *)p->data = (int64_t)val; 667 return 1; 668 } 669 #endif 670 return general_set_uint(p, &val, sizeof(val)); 671 } else if (p->data_type == OSSL_PARAM_REAL) { 672 #ifndef OPENSSL_SYS_UEFI 673 unsigned int shift; 674 675 if (p->data == NULL) { 676 p->return_size = sizeof(double); 677 return 1; 678 } 679 switch (p->data_size) { 680 case sizeof(double): 681 shift = real_shift(); 682 if (shift < 8 * sizeof(val) && (val >> shift) != 0) { 683 err_inexact; 684 return 0; 685 } 686 *(double *)p->data = (double)val; 687 p->return_size = sizeof(double); 688 return 1; 689 } 690 err_unsupported_real; 691 return 0; 692 #endif 693 } 694 err_bad_type; 695 return 0; 696 } 697 698 OSSL_PARAM OSSL_PARAM_construct_uint32(const char *key, uint32_t *buf) 699 { 700 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf, 701 sizeof(uint32_t)); 702 } 703 704 int OSSL_PARAM_get_int64(const OSSL_PARAM *p, int64_t *val) 705 { 706 if (val == NULL || p == NULL) { 707 err_null_argument; 708 return 0; 709 } 710 711 if (p->data == NULL) { 712 err_null_argument; 713 return 0; 714 } 715 716 if (p->data_type == OSSL_PARAM_INTEGER) { 717 #ifndef OPENSSL_SMALL_FOOTPRINT 718 switch (p->data_size) { 719 case sizeof(int32_t): 720 *val = *(const int32_t *)p->data; 721 return 1; 722 case sizeof(int64_t): 723 *val = *(const int64_t *)p->data; 724 return 1; 725 } 726 #endif 727 return general_get_int(p, val, sizeof(*val)); 728 } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { 729 #ifndef OPENSSL_SMALL_FOOTPRINT 730 uint64_t u64; 731 732 switch (p->data_size) { 733 case sizeof(uint32_t): 734 *val = *(const uint32_t *)p->data; 735 return 1; 736 case sizeof(uint64_t): 737 u64 = *(const uint64_t *)p->data; 738 if (u64 <= INT64_MAX) { 739 *val = (int64_t)u64; 740 return 1; 741 } 742 err_out_of_range; 743 return 0; 744 } 745 #endif 746 return general_get_int(p, val, sizeof(*val)); 747 } else if (p->data_type == OSSL_PARAM_REAL) { 748 #ifndef OPENSSL_SYS_UEFI 749 double d; 750 751 switch (p->data_size) { 752 case sizeof(double): 753 d = *(const double *)p->data; 754 if (d >= INT64_MIN 755 /* 756 * By subtracting 65535 (2^16-1) we cancel the low order 757 * 15 bits of INT64_MAX to avoid using imprecise floating 758 * point values. 759 */ 760 && d < (double)(INT64_MAX - 65535) + 65536.0 761 && d == (int64_t)d) { 762 *val = (int64_t)d; 763 return 1; 764 } 765 err_inexact; 766 return 0; 767 } 768 err_unsupported_real; 769 return 0; 770 #endif 771 } 772 err_bad_type; 773 return 0; 774 } 775 776 int OSSL_PARAM_set_int64(OSSL_PARAM *p, int64_t val) 777 { 778 if (p == NULL) { 779 err_null_argument; 780 return 0; 781 } 782 p->return_size = 0; 783 if (p->data_type == OSSL_PARAM_INTEGER) { 784 #ifndef OPENSSL_SMALL_FOOTPRINT 785 if (p->data == NULL) { 786 p->return_size = sizeof(int64_t); /* Expected size */ 787 return 1; 788 } 789 switch (p->data_size) { 790 case sizeof(int32_t): 791 if (val >= INT32_MIN && val <= INT32_MAX) { 792 p->return_size = sizeof(int32_t); 793 *(int32_t *)p->data = (int32_t)val; 794 return 1; 795 } 796 err_out_of_range; 797 return 0; 798 case sizeof(int64_t): 799 p->return_size = sizeof(int64_t); 800 *(int64_t *)p->data = val; 801 return 1; 802 } 803 #endif 804 return general_set_int(p, &val, sizeof(val)); 805 } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && val >= 0) { 806 #ifndef OPENSSL_SMALL_FOOTPRINT 807 if (p->data == NULL) { 808 p->return_size = sizeof(uint64_t); /* Expected size */ 809 return 1; 810 } 811 switch (p->data_size) { 812 case sizeof(uint32_t): 813 if (val <= UINT32_MAX) { 814 p->return_size = sizeof(uint32_t); 815 *(uint32_t *)p->data = (uint32_t)val; 816 return 1; 817 } 818 err_out_of_range; 819 return 0; 820 case sizeof(uint64_t): 821 p->return_size = sizeof(uint64_t); 822 *(uint64_t *)p->data = (uint64_t)val; 823 return 1; 824 } 825 #endif 826 return general_set_int(p, &val, sizeof(val)); 827 } else if (p->data_type == OSSL_PARAM_REAL) { 828 #ifndef OPENSSL_SYS_UEFI 829 uint64_t u64; 830 831 if (p->data == NULL) { 832 p->return_size = sizeof(double); 833 return 1; 834 } 835 switch (p->data_size) { 836 case sizeof(double): 837 u64 = val < 0 ? -val : val; 838 if ((u64 >> real_shift()) == 0) { 839 p->return_size = sizeof(double); 840 *(double *)p->data = (double)val; 841 return 1; 842 } 843 err_inexact; 844 return 0; 845 } 846 err_unsupported_real; 847 return 0; 848 #endif 849 } 850 err_bad_type; 851 return 0; 852 } 853 854 OSSL_PARAM OSSL_PARAM_construct_int64(const char *key, int64_t *buf) 855 { 856 return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int64_t)); 857 } 858 859 int OSSL_PARAM_get_uint64(const OSSL_PARAM *p, uint64_t *val) 860 { 861 if (val == NULL || p == NULL) { 862 err_null_argument; 863 return 0; 864 } 865 866 if (p->data == NULL) { 867 err_null_argument; 868 return 0; 869 } 870 871 if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { 872 #ifndef OPENSSL_SMALL_FOOTPRINT 873 switch (p->data_size) { 874 case sizeof(uint32_t): 875 *val = *(const uint32_t *)p->data; 876 return 1; 877 case sizeof(uint64_t): 878 *val = *(const uint64_t *)p->data; 879 return 1; 880 } 881 #endif 882 return general_get_uint(p, val, sizeof(*val)); 883 } else if (p->data_type == OSSL_PARAM_INTEGER) { 884 #ifndef OPENSSL_SMALL_FOOTPRINT 885 int32_t i32; 886 int64_t i64; 887 888 switch (p->data_size) { 889 case sizeof(int32_t): 890 i32 = *(const int32_t *)p->data; 891 if (i32 >= 0) { 892 *val = (uint64_t)i32; 893 return 1; 894 } 895 err_unsigned_negative; 896 return 0; 897 case sizeof(int64_t): 898 i64 = *(const int64_t *)p->data; 899 if (i64 >= 0) { 900 *val = (uint64_t)i64; 901 return 1; 902 } 903 err_unsigned_negative; 904 return 0; 905 } 906 #endif 907 return general_get_uint(p, val, sizeof(*val)); 908 } else if (p->data_type == OSSL_PARAM_REAL) { 909 #ifndef OPENSSL_SYS_UEFI 910 double d; 911 912 switch (p->data_size) { 913 case sizeof(double): 914 d = *(const double *)p->data; 915 if (d >= 0 916 /* 917 * By subtracting 65535 (2^16-1) we cancel the low order 918 * 15 bits of UINT64_MAX to avoid using imprecise floating 919 * point values. 920 */ 921 && d < (double)(UINT64_MAX - 65535) + 65536.0 922 && d == (uint64_t)d) { 923 *val = (uint64_t)d; 924 return 1; 925 } 926 err_inexact; 927 return 0; 928 } 929 err_unsupported_real; 930 return 0; 931 #endif 932 } 933 err_bad_type; 934 return 0; 935 } 936 937 int OSSL_PARAM_set_uint64(OSSL_PARAM *p, uint64_t val) 938 { 939 if (p == NULL) { 940 err_null_argument; 941 return 0; 942 } 943 p->return_size = 0; 944 945 if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { 946 #ifndef OPENSSL_SMALL_FOOTPRINT 947 if (p->data == NULL) { 948 p->return_size = sizeof(uint64_t); /* Expected size */ 949 return 1; 950 } 951 switch (p->data_size) { 952 case sizeof(uint32_t): 953 if (val <= UINT32_MAX) { 954 p->return_size = sizeof(uint32_t); 955 *(uint32_t *)p->data = (uint32_t)val; 956 return 1; 957 } 958 err_out_of_range; 959 return 0; 960 case sizeof(uint64_t): 961 p->return_size = sizeof(uint64_t); 962 *(uint64_t *)p->data = val; 963 return 1; 964 } 965 #endif 966 return general_set_uint(p, &val, sizeof(val)); 967 } else if (p->data_type == OSSL_PARAM_INTEGER) { 968 #ifndef OPENSSL_SMALL_FOOTPRINT 969 if (p->data == NULL) { 970 p->return_size = sizeof(int64_t); /* Expected size */ 971 return 1; 972 } 973 switch (p->data_size) { 974 case sizeof(int32_t): 975 if (val <= INT32_MAX) { 976 p->return_size = sizeof(int32_t); 977 *(int32_t *)p->data = (int32_t)val; 978 return 1; 979 } 980 err_out_of_range; 981 return 0; 982 case sizeof(int64_t): 983 if (val <= INT64_MAX) { 984 p->return_size = sizeof(int64_t); 985 *(int64_t *)p->data = (int64_t)val; 986 return 1; 987 } 988 err_out_of_range; 989 return 0; 990 } 991 #endif 992 return general_set_uint(p, &val, sizeof(val)); 993 } else if (p->data_type == OSSL_PARAM_REAL) { 994 #ifndef OPENSSL_SYS_UEFI 995 switch (p->data_size) { 996 case sizeof(double): 997 if ((val >> real_shift()) == 0) { 998 p->return_size = sizeof(double); 999 *(double *)p->data = (double)val; 1000 return 1; 1001 } 1002 err_inexact; 1003 return 0; 1004 } 1005 err_unsupported_real; 1006 return 0; 1007 #endif 1008 } 1009 err_bad_type; 1010 return 0; 1011 } 1012 1013 OSSL_PARAM OSSL_PARAM_construct_uint64(const char *key, uint64_t *buf) 1014 { 1015 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf, 1016 sizeof(uint64_t)); 1017 } 1018 1019 int OSSL_PARAM_get_size_t(const OSSL_PARAM *p, size_t *val) 1020 { 1021 #ifndef OPENSSL_SMALL_FOOTPRINT 1022 switch (sizeof(size_t)) { 1023 case sizeof(uint32_t): 1024 return OSSL_PARAM_get_uint32(p, (uint32_t *)val); 1025 case sizeof(uint64_t): 1026 return OSSL_PARAM_get_uint64(p, (uint64_t *)val); 1027 } 1028 #endif 1029 return general_get_uint(p, val, sizeof(*val)); 1030 } 1031 1032 int OSSL_PARAM_set_size_t(OSSL_PARAM *p, size_t val) 1033 { 1034 #ifndef OPENSSL_SMALL_FOOTPRINT 1035 switch (sizeof(size_t)) { 1036 case sizeof(uint32_t): 1037 return OSSL_PARAM_set_uint32(p, (uint32_t)val); 1038 case sizeof(uint64_t): 1039 return OSSL_PARAM_set_uint64(p, (uint64_t)val); 1040 } 1041 #endif 1042 return general_set_uint(p, &val, sizeof(val)); 1043 } 1044 1045 OSSL_PARAM OSSL_PARAM_construct_size_t(const char *key, size_t *buf) 1046 { 1047 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf, 1048 sizeof(size_t)); 1049 } 1050 1051 int OSSL_PARAM_get_time_t(const OSSL_PARAM *p, time_t *val) 1052 { 1053 #ifndef OPENSSL_SMALL_FOOTPRINT 1054 switch (sizeof(time_t)) { 1055 case sizeof(int32_t): 1056 return OSSL_PARAM_get_int32(p, (int32_t *)val); 1057 case sizeof(int64_t): 1058 return OSSL_PARAM_get_int64(p, (int64_t *)val); 1059 } 1060 #endif 1061 return general_get_int(p, val, sizeof(*val)); 1062 } 1063 1064 int OSSL_PARAM_set_time_t(OSSL_PARAM *p, time_t val) 1065 { 1066 #ifndef OPENSSL_SMALL_FOOTPRINT 1067 switch (sizeof(time_t)) { 1068 case sizeof(int32_t): 1069 return OSSL_PARAM_set_int32(p, (int32_t)val); 1070 case sizeof(int64_t): 1071 return OSSL_PARAM_set_int64(p, (int64_t)val); 1072 } 1073 #endif 1074 return general_set_int(p, &val, sizeof(val)); 1075 } 1076 1077 OSSL_PARAM OSSL_PARAM_construct_time_t(const char *key, time_t *buf) 1078 { 1079 return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(time_t)); 1080 } 1081 1082 int OSSL_PARAM_get_BN(const OSSL_PARAM *p, BIGNUM **val) 1083 { 1084 BIGNUM *b = NULL; 1085 1086 if (val == NULL || p == NULL || p->data == NULL) { 1087 err_null_argument; 1088 return 0; 1089 } 1090 1091 switch (p->data_type) { 1092 case OSSL_PARAM_UNSIGNED_INTEGER: 1093 b = BN_native2bn(p->data, (int)p->data_size, *val); 1094 break; 1095 case OSSL_PARAM_INTEGER: 1096 b = BN_signed_native2bn(p->data, (int)p->data_size, *val); 1097 break; 1098 default: 1099 err_bad_type; 1100 break; 1101 } 1102 1103 if (b == NULL) { 1104 ERR_raise(ERR_LIB_CRYPTO, ERR_R_BN_LIB); 1105 return 0; 1106 } 1107 1108 *val = b; 1109 return 1; 1110 } 1111 1112 int OSSL_PARAM_set_BN(OSSL_PARAM *p, const BIGNUM *val) 1113 { 1114 size_t bytes; 1115 1116 if (p == NULL) { 1117 err_null_argument; 1118 return 0; 1119 } 1120 p->return_size = 0; 1121 if (val == NULL) { 1122 err_null_argument; 1123 return 0; 1124 } 1125 if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && BN_is_negative(val)) { 1126 err_bad_type; 1127 return 0; 1128 } 1129 1130 bytes = (size_t)BN_num_bytes(val); 1131 /* We add 1 byte for signed numbers, to make space for a sign extension */ 1132 if (p->data_type == OSSL_PARAM_INTEGER) 1133 bytes++; 1134 /* We make sure that at least one byte is used, so zero is properly set */ 1135 if (bytes == 0) 1136 bytes++; 1137 1138 if (p->data == NULL) { 1139 p->return_size = bytes; 1140 return 1; 1141 } 1142 if (p->data_size >= bytes) { 1143 1144 switch (p->data_type) { 1145 case OSSL_PARAM_UNSIGNED_INTEGER: 1146 if (BN_bn2nativepad(val, p->data, p->data_size) < 0) { 1147 ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_INTEGER_OVERFLOW); 1148 return 0; 1149 } 1150 break; 1151 case OSSL_PARAM_INTEGER: 1152 if (BN_signed_bn2native(val, p->data, p->data_size) < 0) { 1153 ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_INTEGER_OVERFLOW); 1154 return 0; 1155 } 1156 break; 1157 default: 1158 err_bad_type; 1159 return 0; 1160 } 1161 p->return_size = p->data_size; 1162 return 1; 1163 } 1164 p->return_size = bytes; 1165 err_too_small; 1166 return 0; 1167 } 1168 1169 OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf, 1170 size_t bsize) 1171 { 1172 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, 1173 buf, bsize); 1174 } 1175 1176 #ifndef OPENSSL_SYS_UEFI 1177 int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val) 1178 { 1179 int64_t i64; 1180 uint64_t u64; 1181 1182 if (val == NULL || p == NULL || p->data == NULL) { 1183 err_null_argument; 1184 return 0; 1185 } 1186 1187 if (p->data_type == OSSL_PARAM_REAL) { 1188 switch (p->data_size) { 1189 case sizeof(double): 1190 *val = *(const double *)p->data; 1191 return 1; 1192 } 1193 err_unsupported_real; 1194 return 0; 1195 } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { 1196 switch (p->data_size) { 1197 case sizeof(uint32_t): 1198 *val = *(const uint32_t *)p->data; 1199 return 1; 1200 case sizeof(uint64_t): 1201 u64 = *(const uint64_t *)p->data; 1202 if ((u64 >> real_shift()) == 0) { 1203 *val = (double)u64; 1204 return 1; 1205 } 1206 err_inexact; 1207 return 0; 1208 } 1209 } else if (p->data_type == OSSL_PARAM_INTEGER) { 1210 switch (p->data_size) { 1211 case sizeof(int32_t): 1212 *val = *(const int32_t *)p->data; 1213 return 1; 1214 case sizeof(int64_t): 1215 i64 = *(const int64_t *)p->data; 1216 u64 = i64 < 0 ? -i64 : i64; 1217 if ((u64 >> real_shift()) == 0) { 1218 *val = 0.0 + i64; 1219 return 1; 1220 } 1221 err_inexact; 1222 return 0; 1223 } 1224 } 1225 err_bad_type; 1226 return 0; 1227 } 1228 1229 int OSSL_PARAM_set_double(OSSL_PARAM *p, double val) 1230 { 1231 #define D_POW_31 ((double)(((uint32_t)1) << 31)) 1232 const double d_pow_31 = D_POW_31; 1233 const double d_pow_32 = 2.0 * D_POW_31; 1234 const double d_pow_63 = 2.0 * D_POW_31 * D_POW_31; 1235 const double d_pow_64 = 4.0 * D_POW_31 * D_POW_31; 1236 1237 if (p == NULL) { 1238 err_null_argument; 1239 return 0; 1240 } 1241 p->return_size = 0; 1242 1243 if (p->data_type == OSSL_PARAM_REAL) { 1244 if (p->data == NULL) { 1245 p->return_size = sizeof(double); 1246 return 1; 1247 } 1248 switch (p->data_size) { 1249 case sizeof(double): 1250 p->return_size = sizeof(double); 1251 *(double *)p->data = val; 1252 return 1; 1253 } 1254 err_unsupported_real; 1255 return 0; 1256 } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { 1257 if (p->data == NULL) { 1258 /* 1259 * Unclear how this is usable, the parameter's type is integral. 1260 * Its size should be the size of some integral type. 1261 */ 1262 p->return_size = sizeof(double); 1263 return 1; 1264 } 1265 if (val != (uint64_t)val) { 1266 err_inexact; 1267 return 0; 1268 } 1269 switch (p->data_size) { 1270 case sizeof(uint32_t): 1271 if (val >= 0 && val < d_pow_32) { 1272 p->return_size = sizeof(uint32_t); 1273 *(uint32_t *)p->data = (uint32_t)val; 1274 return 1; 1275 } 1276 err_out_of_range; 1277 return 0; 1278 case sizeof(uint64_t): 1279 if (val >= 0 && val < d_pow_64) { 1280 p->return_size = sizeof(uint64_t); 1281 *(uint64_t *)p->data = (uint64_t)val; 1282 return 1; 1283 } 1284 err_out_of_range; 1285 return 0; 1286 } 1287 } else if (p->data_type == OSSL_PARAM_INTEGER) { 1288 if (p->data == NULL) { 1289 /* 1290 * Unclear how this is usable, the parameter's type is integral. 1291 * Its size should be the size of some integral type. 1292 */ 1293 p->return_size = sizeof(double); 1294 return 1; 1295 } 1296 if (val != (int64_t)val) { 1297 err_inexact; 1298 return 0; 1299 } 1300 switch (p->data_size) { 1301 case sizeof(int32_t): 1302 if (val >= -d_pow_31 && val < d_pow_31) { 1303 p->return_size = sizeof(int32_t); 1304 *(int32_t *)p->data = (int32_t)val; 1305 return 1; 1306 } 1307 err_out_of_range; 1308 return 0; 1309 case sizeof(int64_t): 1310 if (val >= -d_pow_63 && val < d_pow_63) { 1311 p->return_size = sizeof(int64_t); 1312 *(int64_t *)p->data = (int64_t)val; 1313 return 1; 1314 } 1315 err_out_of_range; 1316 return 0; 1317 } 1318 } 1319 err_bad_type; 1320 return 0; 1321 } 1322 1323 OSSL_PARAM OSSL_PARAM_construct_double(const char *key, double *buf) 1324 { 1325 return ossl_param_construct(key, OSSL_PARAM_REAL, buf, sizeof(double)); 1326 } 1327 #endif 1328 1329 static int get_string_internal(const OSSL_PARAM *p, void **val, 1330 size_t *max_len, size_t *used_len, 1331 unsigned int type) 1332 { 1333 size_t sz, alloc_sz; 1334 1335 if ((val == NULL && used_len == NULL) || p == NULL) { 1336 err_null_argument; 1337 return 0; 1338 } 1339 if (p->data_type != type) { 1340 err_bad_type; 1341 return 0; 1342 } 1343 1344 sz = p->data_size; 1345 /* 1346 * If the input size is 0, or the input string needs NUL byte 1347 * termination, allocate an extra byte. 1348 */ 1349 alloc_sz = sz + (type == OSSL_PARAM_UTF8_STRING || sz == 0); 1350 1351 if (used_len != NULL) 1352 *used_len = sz; 1353 1354 if (p->data == NULL) { 1355 err_null_argument; 1356 return 0; 1357 } 1358 1359 if (val == NULL) 1360 return 1; 1361 1362 if (*val == NULL) { 1363 char *const q = OPENSSL_malloc(alloc_sz); 1364 1365 if (q == NULL) 1366 return 0; 1367 *val = q; 1368 *max_len = alloc_sz; 1369 } 1370 1371 if (*max_len < sz) { 1372 err_too_small; 1373 return 0; 1374 } 1375 memcpy(*val, p->data, sz); 1376 return 1; 1377 } 1378 1379 int OSSL_PARAM_get_utf8_string(const OSSL_PARAM *p, char **val, size_t max_len) 1380 { 1381 int ret = get_string_internal(p, (void **)val, &max_len, NULL, 1382 OSSL_PARAM_UTF8_STRING); 1383 1384 /* 1385 * We try to ensure that the copied string is terminated with a 1386 * NUL byte. That should be easy, just place a NUL byte at 1387 * |((char*)*val)[p->data_size]|. 1388 * Unfortunately, we have seen cases where |p->data_size| doesn't 1389 * correctly reflect the length of the string, and just happens 1390 * to be out of bounds according to |max_len|, so in that case, we 1391 * make the extra step of trying to find the true length of the 1392 * string that |p->data| points at, and use that as an index to 1393 * place the NUL byte in |*val|. 1394 */ 1395 size_t data_length = p->data_size; 1396 1397 if (ret == 0) 1398 return 0; 1399 if (data_length >= max_len) 1400 data_length = OPENSSL_strnlen(p->data, data_length); 1401 if (data_length >= max_len) { 1402 ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_NO_SPACE_FOR_TERMINATING_NULL); 1403 return 0; /* No space for a terminating NUL byte */ 1404 } 1405 (*val)[data_length] = '\0'; 1406 1407 return ret; 1408 } 1409 1410 int OSSL_PARAM_get_octet_string(const OSSL_PARAM *p, void **val, size_t max_len, 1411 size_t *used_len) 1412 { 1413 return get_string_internal(p, val, &max_len, used_len, 1414 OSSL_PARAM_OCTET_STRING); 1415 } 1416 1417 static int set_string_internal(OSSL_PARAM *p, const void *val, size_t len, 1418 unsigned int type) 1419 { 1420 if (p->data_type != type) { 1421 err_bad_type; 1422 return 0; 1423 } 1424 p->return_size = len; 1425 if (p->data == NULL) 1426 return 1; 1427 if (p->data_size < len) { 1428 err_too_small; 1429 return 0; 1430 } 1431 1432 memcpy(p->data, val, len); 1433 /* If possible within the size of p->data, add a NUL terminator byte */ 1434 if (type == OSSL_PARAM_UTF8_STRING && p->data_size > len) 1435 ((char *)p->data)[len] = '\0'; 1436 return 1; 1437 } 1438 1439 int OSSL_PARAM_set_utf8_string(OSSL_PARAM *p, const char *val) 1440 { 1441 if (p == NULL || val == NULL) { 1442 err_null_argument; 1443 return 0; 1444 } 1445 p->return_size = 0; 1446 return set_string_internal(p, val, strlen(val), OSSL_PARAM_UTF8_STRING); 1447 } 1448 1449 int OSSL_PARAM_set_octet_string(OSSL_PARAM *p, const void *val, 1450 size_t len) 1451 { 1452 if (p == NULL || val == NULL) { 1453 err_null_argument; 1454 return 0; 1455 } 1456 p->return_size = 0; 1457 return set_string_internal(p, val, len, OSSL_PARAM_OCTET_STRING); 1458 } 1459 1460 OSSL_PARAM OSSL_PARAM_construct_utf8_string(const char *key, char *buf, 1461 size_t bsize) 1462 { 1463 if (buf != NULL && bsize == 0) 1464 bsize = strlen(buf); 1465 return ossl_param_construct(key, OSSL_PARAM_UTF8_STRING, buf, bsize); 1466 } 1467 1468 OSSL_PARAM OSSL_PARAM_construct_octet_string(const char *key, void *buf, 1469 size_t bsize) 1470 { 1471 return ossl_param_construct(key, OSSL_PARAM_OCTET_STRING, buf, bsize); 1472 } 1473 1474 static int get_ptr_internal(const OSSL_PARAM *p, const void **val, 1475 size_t *used_len, unsigned int type) 1476 { 1477 if (val == NULL || p == NULL) { 1478 err_null_argument; 1479 return 0; 1480 } 1481 if (p->data_type != type) { 1482 err_bad_type; 1483 return 0; 1484 } 1485 if (used_len != NULL) 1486 *used_len = p->data_size; 1487 *val = *(const void **)p->data; 1488 return 1; 1489 } 1490 1491 int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM *p, const char **val) 1492 { 1493 return get_ptr_internal(p, (const void **)val, NULL, OSSL_PARAM_UTF8_PTR); 1494 } 1495 1496 int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, const void **val, 1497 size_t *used_len) 1498 { 1499 return get_ptr_internal(p, val, used_len, OSSL_PARAM_OCTET_PTR); 1500 } 1501 1502 static int set_ptr_internal(OSSL_PARAM *p, const void *val, 1503 unsigned int type, size_t len) 1504 { 1505 if (p->data_type != type) { 1506 err_bad_type; 1507 return 0; 1508 } 1509 p->return_size = len; 1510 if (p->data != NULL) 1511 *(const void **)p->data = val; 1512 return 1; 1513 } 1514 1515 int OSSL_PARAM_set_utf8_ptr(OSSL_PARAM *p, const char *val) 1516 { 1517 if (p == NULL) { 1518 err_null_argument; 1519 return 0; 1520 } 1521 p->return_size = 0; 1522 return set_ptr_internal(p, val, OSSL_PARAM_UTF8_PTR, 1523 val == NULL ? 0 : strlen(val)); 1524 } 1525 1526 int OSSL_PARAM_set_octet_ptr(OSSL_PARAM *p, const void *val, 1527 size_t used_len) 1528 { 1529 if (p == NULL) { 1530 err_null_argument; 1531 return 0; 1532 } 1533 p->return_size = 0; 1534 return set_ptr_internal(p, val, OSSL_PARAM_OCTET_PTR, used_len); 1535 } 1536 1537 OSSL_PARAM OSSL_PARAM_construct_utf8_ptr(const char *key, char **buf, 1538 size_t bsize) 1539 { 1540 return ossl_param_construct(key, OSSL_PARAM_UTF8_PTR, buf, bsize); 1541 } 1542 1543 OSSL_PARAM OSSL_PARAM_construct_octet_ptr(const char *key, void **buf, 1544 size_t bsize) 1545 { 1546 return ossl_param_construct(key, OSSL_PARAM_OCTET_PTR, buf, bsize); 1547 } 1548 1549 /* 1550 * Extract the parameter into an allocated buffer. 1551 * Any existing allocation in *out is cleared and freed. 1552 * 1553 * Returns 1 on success, 0 on failure and -1 if there are no matching params. 1554 * 1555 * *out and *out_len are guaranteed to be untouched if this function 1556 * doesn't return success. 1557 */ 1558 int ossl_param_get1_octet_string(const OSSL_PARAM *params, const char *name, 1559 unsigned char **out, size_t *out_len) 1560 { 1561 const OSSL_PARAM *p = OSSL_PARAM_locate_const(params, name); 1562 void *buf = NULL; 1563 size_t len = 0; 1564 1565 if (p == NULL) 1566 return -1; 1567 1568 if (p->data != NULL 1569 && p->data_size > 0 1570 && !OSSL_PARAM_get_octet_string(p, &buf, 0, &len)) 1571 return 0; 1572 1573 OPENSSL_clear_free(*out, *out_len); 1574 *out = buf; 1575 *out_len = len; 1576 return 1; 1577 } 1578 1579 static int setbuf_fromparams(const OSSL_PARAM *p, const char *name, 1580 unsigned char *out, size_t *outlen) 1581 { 1582 int ret = 0; 1583 WPACKET pkt; 1584 1585 if (out == NULL) { 1586 if (!WPACKET_init_null(&pkt, 0)) 1587 return 0; 1588 } else { 1589 if (!WPACKET_init_static_len(&pkt, out, *outlen, 0)) 1590 return 0; 1591 } 1592 1593 for (; p != NULL; p = OSSL_PARAM_locate_const(p + 1, name)) { 1594 if (p->data_type != OSSL_PARAM_OCTET_STRING) 1595 goto err; 1596 if (p->data != NULL 1597 && p->data_size != 0 1598 && !WPACKET_memcpy(&pkt, p->data, p->data_size)) 1599 goto err; 1600 } 1601 if (!WPACKET_get_total_written(&pkt, outlen) 1602 || !WPACKET_finish(&pkt)) 1603 goto err; 1604 ret = 1; 1605 err: 1606 WPACKET_cleanup(&pkt); 1607 return ret; 1608 } 1609 1610 int ossl_param_get1_concat_octet_string(const OSSL_PARAM *params, const char *name, 1611 unsigned char **out, 1612 size_t *out_len, size_t maxsize) 1613 { 1614 const OSSL_PARAM *p = OSSL_PARAM_locate_const(params, name); 1615 unsigned char *res; 1616 size_t sz = 0; 1617 1618 if (p == NULL) 1619 return -1; 1620 1621 /* Calculate the total size */ 1622 if (!setbuf_fromparams(p, name, NULL, &sz)) 1623 return 0; 1624 1625 /* Check that it's not oversized */ 1626 if (maxsize > 0 && sz > maxsize) 1627 return 0; 1628 1629 /* Special case zero length */ 1630 if (sz == 0) { 1631 if ((res = OPENSSL_zalloc(1)) == NULL) 1632 return 0; 1633 goto fin; 1634 } 1635 1636 /* Allocate the buffer */ 1637 res = OPENSSL_malloc(sz); 1638 if (res == NULL) 1639 return 0; 1640 1641 /* Concat one or more OSSL_KDF_PARAM_INFO fields */ 1642 if (!setbuf_fromparams(p, name, res, &sz)) { 1643 OPENSSL_clear_free(res, sz); 1644 return 0; 1645 } 1646 1647 fin: 1648 OPENSSL_clear_free(*out, *out_len); 1649 *out = res; 1650 *out_len = sz; 1651 return 1; 1652 } 1653 1654 OSSL_PARAM OSSL_PARAM_construct_end(void) 1655 { 1656 OSSL_PARAM end = OSSL_PARAM_END; 1657 1658 return end; 1659 } 1660 1661 static int get_string_ptr_internal(const OSSL_PARAM *p, const void **val, 1662 size_t *used_len, unsigned int type) 1663 { 1664 if (val == NULL || p == NULL) { 1665 err_null_argument; 1666 return 0; 1667 } 1668 if (p->data_type != type) { 1669 err_bad_type; 1670 return 0; 1671 } 1672 if (used_len != NULL) 1673 *used_len = p->data_size; 1674 *val = p->data; 1675 return 1; 1676 } 1677 1678 int OSSL_PARAM_get_utf8_string_ptr(const OSSL_PARAM *p, const char **val) 1679 { 1680 int rv; 1681 1682 ERR_set_mark(); 1683 rv = OSSL_PARAM_get_utf8_ptr(p, val); 1684 ERR_pop_to_mark(); 1685 1686 return rv || get_string_ptr_internal(p, (const void **)val, NULL, OSSL_PARAM_UTF8_STRING); 1687 } 1688 1689 int OSSL_PARAM_get_octet_string_ptr(const OSSL_PARAM *p, const void **val, 1690 size_t *used_len) 1691 { 1692 int rv; 1693 1694 ERR_set_mark(); 1695 rv = OSSL_PARAM_get_octet_ptr(p, val, used_len); 1696 ERR_pop_to_mark(); 1697 1698 return rv || get_string_ptr_internal(p, val, used_len, OSSL_PARAM_OCTET_STRING); 1699 } 1700