1 /* 2 * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL licenses, (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 "fuzzer.h" 19 20 int FuzzerInitialize(int *argc, char ***argv) { 21 return 1; 22 } 23 24 int FuzzerTestOneInput(const uint8_t *buf, size_t len) { 25 static BN_CTX *ctx; 26 static BIGNUM *b1; 27 static BIGNUM *b2; 28 static BIGNUM *b3; 29 static BIGNUM *b4; 30 static BIGNUM *b5; 31 int success = 0; 32 size_t l1 = 0, l2 = 0, l3 = 0; 33 int s1 = 0, s2 = 0, s3 = 0; 34 35 if (ctx == NULL) { 36 b1 = BN_new(); 37 b2 = BN_new(); 38 b3 = BN_new(); 39 b4 = BN_new(); 40 b5 = BN_new(); 41 ctx = BN_CTX_new(); 42 } 43 /* Divide the input into three parts, using the values of the first two 44 * bytes to choose lengths, which generate b1, b2 and b3. Use three bits 45 * of the third byte to choose signs for the three numbers. 46 */ 47 if (len > 2) { 48 len -= 3; 49 l1 = (buf[0] * len) / 255; 50 ++buf; 51 l2 = (buf[0] * (len - l1)) / 255; 52 ++buf; 53 l3 = len - l1 - l2; 54 55 s1 = buf[0] & 1; 56 s2 = buf[0] & 2; 57 s3 = buf[0] & 4; 58 ++buf; 59 } 60 OPENSSL_assert(BN_bin2bn(buf, l1, b1) == b1); 61 BN_set_negative(b1, s1); 62 OPENSSL_assert(BN_bin2bn(buf + l1, l2, b2) == b2); 63 BN_set_negative(b2, s2); 64 OPENSSL_assert(BN_bin2bn(buf + l1 + l2, l3, b3) == b3); 65 BN_set_negative(b3, s3); 66 67 /* mod 0 is undefined */ 68 if (BN_is_zero(b3)) { 69 success = 1; 70 goto done; 71 } 72 73 OPENSSL_assert(BN_mod_exp(b4, b1, b2, b3, ctx)); 74 OPENSSL_assert(BN_mod_exp_simple(b5, b1, b2, b3, ctx)); 75 76 success = BN_cmp(b4, b5) == 0; 77 if (!success) { 78 BN_print_fp(stdout, b1); 79 putchar('\n'); 80 BN_print_fp(stdout, b2); 81 putchar('\n'); 82 BN_print_fp(stdout, b3); 83 putchar('\n'); 84 BN_print_fp(stdout, b4); 85 putchar('\n'); 86 BN_print_fp(stdout, b5); 87 putchar('\n'); 88 } 89 90 done: 91 OPENSSL_assert(success); 92 93 return 0; 94 } 95