bignum.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. * https://www.openssl.org/source/license.html
  8. * or in the file LICENSE in the source distribution.
  9. */
  10. /*
  11. * Confirm that a^b mod c agrees when calculated cleverly vs naively, for
  12. * random a, b and c.
  13. */
  14. #include <stdio.h>
  15. #include <openssl/bn.h>
  16. #include <openssl/err.h>
  17. #include "fuzzer.h"
  18. int FuzzerInitialize(int *argc, char ***argv)
  19. {
  20. OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
  21. ERR_clear_error();
  22. return 1;
  23. }
  24. int FuzzerTestOneInput(const uint8_t *buf, size_t len)
  25. {
  26. int success = 0;
  27. size_t l1 = 0, l2 = 0, l3 = 0;
  28. int s1 = 0, s3 = 0;
  29. BN_CTX *ctx;
  30. BIGNUM *b1;
  31. BIGNUM *b2;
  32. BIGNUM *b3;
  33. BIGNUM *b4;
  34. BIGNUM *b5;
  35. b1 = BN_new();
  36. b2 = BN_new();
  37. b3 = BN_new();
  38. b4 = BN_new();
  39. b5 = BN_new();
  40. ctx = BN_CTX_new();
  41. /* Divide the input into three parts, using the values of the first two
  42. * bytes to choose lengths, which generate b1, b2 and b3. Use three bits
  43. * of the third byte to choose signs for the three numbers.
  44. */
  45. if (len > 2) {
  46. len -= 3;
  47. /* limit l1, l2, and l3 to be no more than 512 bytes */
  48. l1 = ((buf[0] * len) / 255) % 512;
  49. ++buf;
  50. l2 = ((buf[0] * (len - l1)) / 255) % 512;
  51. ++buf;
  52. l3 = (len - l1 - l2) % 512;
  53. s1 = buf[0] & 1;
  54. s3 = buf[0] & 4;
  55. ++buf;
  56. }
  57. OPENSSL_assert(BN_bin2bn(buf, l1, b1) == b1);
  58. BN_set_negative(b1, s1);
  59. OPENSSL_assert(BN_bin2bn(buf + l1, l2, b2) == b2);
  60. OPENSSL_assert(BN_bin2bn(buf + l1 + l2, l3, b3) == b3);
  61. BN_set_negative(b3, s3);
  62. /* mod 0 is undefined */
  63. if (BN_is_zero(b3)) {
  64. success = 1;
  65. goto done;
  66. }
  67. OPENSSL_assert(BN_mod_exp(b4, b1, b2, b3, ctx));
  68. OPENSSL_assert(BN_mod_exp_simple(b5, b1, b2, b3, ctx));
  69. success = BN_cmp(b4, b5) == 0;
  70. if (!success) {
  71. BN_print_fp(stdout, b1);
  72. putchar('\n');
  73. BN_print_fp(stdout, b2);
  74. putchar('\n');
  75. BN_print_fp(stdout, b3);
  76. putchar('\n');
  77. BN_print_fp(stdout, b4);
  78. putchar('\n');
  79. BN_print_fp(stdout, b5);
  80. putchar('\n');
  81. }
  82. done:
  83. OPENSSL_assert(success);
  84. BN_free(b1);
  85. BN_free(b2);
  86. BN_free(b3);
  87. BN_free(b4);
  88. BN_free(b5);
  89. BN_CTX_free(ctx);
  90. ERR_clear_error();
  91. return 0;
  92. }
  93. void FuzzerCleanup(void)
  94. {
  95. }