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 if (d, r) = a / b, then b * d + r == a, and that sign(d) == 13 * sign(a), and 0 <= r <= b 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; 33 /* s1 and s2 will be the signs for b1 and b2. */ 34 int s1 = 0, s2 = 0; 35 36 if (ctx == NULL) { 37 b1 = BN_new(); 38 b2 = BN_new(); 39 b3 = BN_new(); 40 b4 = BN_new(); 41 b5 = BN_new(); 42 ctx = BN_CTX_new(); 43 } 44 /* We are going to split the buffer in two, sizes l1 and l2, giving b1 and 45 * b2. 46 */ 47 if (len > 0) { 48 --len; 49 /* Use first byte to divide the remaining buffer into 3Fths. I admit 50 * this disallows some number sizes. If it matters, better ideas are 51 * welcome (Ben). 52 */ 53 l1 = ((buf[0] & 0x3f) * len) / 0x3f; 54 s1 = buf[0] & 0x40; 55 s2 = buf[0] & 0x80; 56 ++buf; 57 l2 = len - l1; 58 } 59 OPENSSL_assert(BN_bin2bn(buf, l1, b1) == b1); 60 BN_set_negative(b1, s1); 61 OPENSSL_assert(BN_bin2bn(buf + l1, l2, b2) == b2); 62 BN_set_negative(b2, s2); 63 64 /* divide by 0 is an error */ 65 if (BN_is_zero(b2)) { 66 success = 1; 67 goto done; 68 } 69 70 OPENSSL_assert(BN_div(b3, b4, b1, b2, ctx)); 71 if (BN_is_zero(b1)) 72 success = BN_is_zero(b3) && BN_is_zero(b4); 73 else if (BN_is_negative(b1)) 74 success = (BN_is_negative(b3) != BN_is_negative(b2) || BN_is_zero(b3)) 75 && (BN_is_negative(b4) || BN_is_zero(b4)); 76 else 77 success = (BN_is_negative(b3) == BN_is_negative(b2) || BN_is_zero(b3)) 78 && (!BN_is_negative(b4) || BN_is_zero(b4)); 79 OPENSSL_assert(BN_mul(b5, b3, b2, ctx)); 80 OPENSSL_assert(BN_add(b5, b5, b4)); 81 82 success = success && BN_cmp(b5, b1) == 0; 83 if (!success) { 84 BN_print_fp(stdout, b1); 85 putchar('\n'); 86 BN_print_fp(stdout, b2); 87 putchar('\n'); 88 BN_print_fp(stdout, b3); 89 putchar('\n'); 90 BN_print_fp(stdout, b4); 91 putchar('\n'); 92 BN_print_fp(stdout, b5); 93 putchar('\n'); 94 printf("%d %d %d %d %d %d %d\n", BN_is_negative(b1), 95 BN_is_negative(b2), 96 BN_is_negative(b3), BN_is_negative(b4), BN_is_zero(b4), 97 BN_is_negative(b3) != BN_is_negative(b2) 98 && (BN_is_negative(b4) || BN_is_zero(b4)), 99 BN_cmp(b5, b1)); 100 puts("----\n"); 101 } 102 103 done: 104 OPENSSL_assert(success); 105 106 return 0; 107 } 108