/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 | 147 | { |
18 | 147 | const size_t hlen = Phash.size(); |
19 | | |
20 | 147 | if(len < 2*hlen + 1) |
21 | 0 | { |
22 | 0 | return Botan::secure_vector<uint8_t>(); |
23 | 0 | } |
24 | | |
25 | 18.4E | for(size_t i = hlen; i != 2*hlen; ++i) |
26 | 0 | { |
27 | 0 | if(in[i] != Phash[i-hlen]) |
28 | 62 | { |
29 | 62 | return Botan::secure_vector<uint8_t>(); |
30 | 62 | } |
31 | 0 | } |
32 | | |
33 | 18.4E | for(size_t i = 2*hlen; i != len; ++i) |
34 | 0 | { |
35 | 0 | if(in[i] != 0x00 && in[i] != 0x01) |
36 | 0 | { |
37 | 0 | return Botan::secure_vector<uint8_t>(); |
38 | 0 | } |
39 | | |
40 | 0 | if(in[i] == 0x01) |
41 | 62 | { |
42 | 62 | valid_mask = 0xFF; |
43 | 62 | return Botan::secure_vector<uint8_t>(in + i + 1, in + len); |
44 | 62 | } |
45 | 0 | } |
46 | | |
47 | 23 | return Botan::secure_vector<uint8_t>(); |
48 | 85 | } |
49 | | |
50 | | inline bool all_zeros(const Botan::secure_vector<uint8_t>& v) |
51 | 170 | { |
52 | 170 | for(size_t i = 0; i != v.size(); ++i) |
53 | 0 | { |
54 | 0 | if(v[i] != 0) |
55 | 0 | return false; |
56 | 0 | } |
57 | 170 | return true; |
58 | 170 | } |
59 | | |
60 | | } |
61 | | |
62 | | void fuzz(const uint8_t in[], size_t len) |
63 | 147 | { |
64 | 147 | static const Botan::secure_vector<uint8_t> Phash = { 1, 2, 3, 4 }; |
65 | | |
66 | 147 | uint8_t lib_valid_mask = 0; |
67 | 147 | const Botan::secure_vector<uint8_t> lib_output = Botan::oaep_find_delim(lib_valid_mask, in, len, Phash); |
68 | 147 | FUZZER_ASSERT_TRUE(lib_valid_mask == 0 || lib_valid_mask == 0xFF); |
69 | | |
70 | 147 | uint8_t ref_valid_mask = 0; |
71 | 147 | const Botan::secure_vector<uint8_t> ref_output = ref_oaep_unpad(ref_valid_mask, in, len, Phash); |
72 | 147 | FUZZER_ASSERT_TRUE(ref_valid_mask == 0 || ref_valid_mask == 0xFF); |
73 | | |
74 | 147 | 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 | 147 | 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 | 147 | if(ref_valid_mask == 0x00) |
84 | 85 | { |
85 | 85 | FUZZER_ASSERT_TRUE(all_zeros(ref_output)); |
86 | 85 | } |
87 | | |
88 | 147 | if(lib_valid_mask == 0x00) |
89 | 85 | { |
90 | 85 | FUZZER_ASSERT_TRUE(all_zeros(lib_output)); |
91 | 85 | } |
92 | | |
93 | 147 | if(ref_valid_mask && lib_valid_mask) |
94 | 62 | { |
95 | 62 | 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 | 62 | } |
102 | 147 | } |