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 /* 12 * Confirm that a^b mod c agrees when calculated cleverly vs naively, for 13 * random a, b and c. 14 */ 15 16 #include <stdio.h> 17 #include <openssl/bn.h> 18 #include <openssl/err.h> 19 #include "fuzzer.h" 20 21 22 int FuzzerInitialize(int *argc, char ***argv) 23 { 24 OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); 25 ERR_clear_error(); 26 27 return 1; 28 } 29 30 int FuzzerTestOneInput(const uint8_t *buf, size_t len) 31 { 32 int success = 0; 33 size_t l1 = 0, l2 = 0, l3 = 0; 34 int s1 = 0, s3 = 0; 35 BN_CTX *ctx; 36 BIGNUM *b1; 37 BIGNUM *b2; 38 BIGNUM *b3; 39 BIGNUM *b4; 40 BIGNUM *b5; 41 42 b1 = BN_new(); 43 b2 = BN_new(); 44 b3 = BN_new(); 45 b4 = BN_new(); 46 b5 = BN_new(); 47 ctx = BN_CTX_new(); 48 49 /* Divide the input into three parts, using the values of the first two 50 * bytes to choose lengths, which generate b1, b2 and b3. Use three bits 51 * of the third byte to choose signs for the three numbers. 52 */ 53 if (len > 2) { 54 len -= 3; 55 l1 = (buf[0] * len) / 255; 56 ++buf; 57 l2 = (buf[0] * (len - l1)) / 255; 58 ++buf; 59 l3 = len - l1 - l2; 60 61 s1 = buf[0] & 1; 62 s3 = buf[0] & 4; 63 ++buf; 64 } 65 OPENSSL_assert(BN_bin2bn(buf, l1, b1) == b1); 66 BN_set_negative(b1, s1); 67 OPENSSL_assert(BN_bin2bn(buf + l1, l2, b2) == b2); 68 OPENSSL_assert(BN_bin2bn(buf + l1 + l2, l3, b3) == b3); 69 BN_set_negative(b3, s3); 70 71 /* mod 0 is undefined */ 72 if (BN_is_zero(b3)) { 73 success = 1; 74 goto done; 75 } 76 77 OPENSSL_assert(BN_mod_exp(b4, b1, b2, b3, ctx)); 78 OPENSSL_assert(BN_mod_exp_simple(b5, b1, b2, b3, ctx)); 79 80 success = BN_cmp(b4, b5) == 0; 81 if (!success) { 82 BN_print_fp(stdout, b1); 83 putchar('\n'); 84 BN_print_fp(stdout, b2); 85 putchar('\n'); 86 BN_print_fp(stdout, b3); 87 putchar('\n'); 88 BN_print_fp(stdout, b4); 89 putchar('\n'); 90 BN_print_fp(stdout, b5); 91 putchar('\n'); 92 } 93 94 done: 95 OPENSSL_assert(success); 96 BN_free(b1); 97 BN_free(b2); 98 BN_free(b3); 99 BN_free(b4); 100 BN_free(b5); 101 BN_CTX_free(ctx); 102 ERR_clear_error(); 103 104 return 0; 105 } 106 107 void FuzzerCleanup(void) 108 { 109 } 110