/src/botan/src/fuzzer/oaep.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * (C) 2018 Jack Lloyd |
3 | | * |
4 | | * Botan is released under the Simplified BSD License (see license.txt) |
5 | | */ |
6 | | #include "fuzzers.h" |
7 | | |
8 | | #include <botan/internal/oaep.h> |
9 | | #include <botan/hex.h> |
10 | | |
11 | | namespace { |
12 | | |
13 | | Botan::secure_vector<uint8_t> |
14 | | ref_oaep_unpad(uint8_t& valid_mask, |
15 | | const uint8_t in[], size_t len, |
16 | | const Botan::secure_vector<uint8_t>& Phash) |
17 | 189 | { |
18 | 189 | const size_t hlen = Phash.size(); |
19 | | |
20 | 189 | if(len < 2*hlen + 1) |
21 | 6 | { |
22 | 6 | return Botan::secure_vector<uint8_t>(); |
23 | 6 | } |
24 | | |
25 | 638 | for(size_t i = hlen; i != 2*hlen; ++i) |
26 | 530 | { |
27 | 530 | if(in[i] != Phash[i-hlen]) |
28 | 75 | { |
29 | 75 | return Botan::secure_vector<uint8_t>(); |
30 | 75 | } |
31 | 530 | } |
32 | | |
33 | 811 | for(size_t i = 2*hlen; i != len; ++i) |
34 | 801 | { |
35 | 801 | if(in[i] != 0x00 && in[i] != 0x01) |
36 | 31 | { |
37 | 31 | return Botan::secure_vector<uint8_t>(); |
38 | 31 | } |
39 | | |
40 | 770 | if(in[i] == 0x01) |
41 | 67 | { |
42 | 67 | valid_mask = 0xFF; |
43 | 67 | return Botan::secure_vector<uint8_t>(in + i + 1, in + len); |
44 | 67 | } |
45 | 770 | } |
46 | | |
47 | 10 | return Botan::secure_vector<uint8_t>(); |
48 | 108 | } |
49 | | |
50 | | inline bool all_zeros(const Botan::secure_vector<uint8_t>& v) |
51 | 244 | { |
52 | 244 | for(size_t i = 0; i != v.size(); ++i) |
53 | 0 | { |
54 | 0 | if(v[i] != 0) |
55 | 0 | return false; |
56 | 0 | } |
57 | 244 | return true; |
58 | 244 | } |
59 | | |
60 | | } |
61 | | |
62 | | void fuzz(const uint8_t in[], size_t len) |
63 | 189 | { |
64 | 189 | static const Botan::secure_vector<uint8_t> Phash = { 1, 2, 3, 4 }; |
65 | | |
66 | 189 | uint8_t lib_valid_mask = 0; |
67 | 189 | const Botan::secure_vector<uint8_t> lib_output = Botan::oaep_find_delim(lib_valid_mask, in, len, Phash); |
68 | 189 | FUZZER_ASSERT_TRUE(lib_valid_mask == 0 || lib_valid_mask == 0xFF); |
69 | | |
70 | 189 | uint8_t ref_valid_mask = 0; |
71 | 189 | const Botan::secure_vector<uint8_t> ref_output = ref_oaep_unpad(ref_valid_mask, in, len, Phash); |
72 | 189 | FUZZER_ASSERT_TRUE(ref_valid_mask == 0 || ref_valid_mask == 0xFF); |
73 | | |
74 | 189 | if(ref_valid_mask == 0xFF && lib_valid_mask == 0x00) |
75 | 0 | { |
76 | 0 | FUZZER_WRITE_AND_CRASH("Ref accepted but library rejected, output " << Botan::hex_encode(ref_output) << "\n"); |
77 | 0 | } |
78 | 189 | else if(ref_valid_mask == 0x00 && lib_valid_mask == 0xFF) |
79 | 0 | { |
80 | 0 | FUZZER_WRITE_AND_CRASH("Lib accepted but ref rejected, output = " << Botan::hex_encode(lib_output) << "\n"); |
81 | 0 | } |
82 | | |
83 | 189 | if(ref_valid_mask == 0x00) |
84 | 122 | { |
85 | 122 | FUZZER_ASSERT_TRUE(all_zeros(ref_output)); |
86 | 122 | } |
87 | | |
88 | 189 | if(lib_valid_mask == 0x00) |
89 | 122 | { |
90 | 122 | FUZZER_ASSERT_TRUE(all_zeros(lib_output)); |
91 | 122 | } |
92 | | |
93 | 189 | if(ref_valid_mask && lib_valid_mask) |
94 | 67 | { |
95 | 67 | if(ref_output != lib_output) |
96 | 0 | { |
97 | 0 | FUZZER_WRITE_AND_CRASH("Ref and lib both accepted but produced different output:" |
98 | 0 | << " ref = " << Botan::hex_encode(ref_output) |
99 | 0 | << " lib = " << Botan::hex_encode(lib_output)); |
100 | 0 | } |
101 | 67 | } |
102 | 189 | } |