bignum.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * Copyright 2016 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. l1 = (buf[0] * len) / 255;
  48. ++buf;
  49. l2 = (buf[0] * (len - l1)) / 255;
  50. ++buf;
  51. l3 = len - l1 - l2;
  52. s1 = buf[0] & 1;
  53. s3 = buf[0] & 4;
  54. ++buf;
  55. }
  56. OPENSSL_assert(BN_bin2bn(buf, l1, b1) == b1);
  57. BN_set_negative(b1, s1);
  58. OPENSSL_assert(BN_bin2bn(buf + l1, l2, b2) == b2);
  59. OPENSSL_assert(BN_bin2bn(buf + l1 + l2, l3, b3) == b3);
  60. BN_set_negative(b3, s3);
  61. /* mod 0 is undefined */
  62. if (BN_is_zero(b3)) {
  63. success = 1;
  64. goto done;
  65. }
  66. OPENSSL_assert(BN_mod_exp(b4, b1, b2, b3, ctx));
  67. OPENSSL_assert(BN_mod_exp_simple(b5, b1, b2, b3, ctx));
  68. success = BN_cmp(b4, b5) == 0;
  69. if (!success) {
  70. BN_print_fp(stdout, b1);
  71. putchar('\n');
  72. BN_print_fp(stdout, b2);
  73. putchar('\n');
  74. BN_print_fp(stdout, b3);
  75. putchar('\n');
  76. BN_print_fp(stdout, b4);
  77. putchar('\n');
  78. BN_print_fp(stdout, b5);
  79. putchar('\n');
  80. }
  81. done:
  82. OPENSSL_assert(success);
  83. BN_free(b1);
  84. BN_free(b2);
  85. BN_free(b3);
  86. BN_free(b4);
  87. BN_free(b5);
  88. BN_CTX_free(ctx);
  89. ERR_clear_error();
  90. return 0;
  91. }
  92. void FuzzerCleanup(void)
  93. {
  94. }