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