1 /* Copyright 2021 Google LLC
2 Licensed under the Apache License, Version 2.0 (the "License");
3 you may not use this file except in compliance with the License.
4 You may obtain a copy of the License at
5 http://www.apache.org/licenses/LICENSE-2.0
6 Unless required by applicable law or agreed to in writing, software
7 distributed under the License is distributed on an "AS IS" BASIS,
8 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9 See the License for the specific language governing permissions and
10 limitations under the License.
11 */
12
13
14 #include "config.h"
15 #include "syshead.h"
16
17 #include <openssl/x509.h>
18 #include <openssl/x509v3.h>
19 #include <openssl/ssl.h>
20 #include <openssl/err.h>
21
22 #include "fuzz_verify_cert.h"
23 #include "misc.h"
24 #include "manage.h"
25 #include "otime.h"
26 #include "base64.h"
27 #include "ssl_verify.h"
28 #include "ssl_verify_backend.h"
29
30 #include "fuzz_randomizer.h"
31
key_ctx_update_implicit_iv(struct key_ctx * ctx,uint8_t * key,size_t key_len)32 static void key_ctx_update_implicit_iv(struct key_ctx *ctx, uint8_t *key,
33 size_t key_len) {
34 const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt(ctx->cipher);
35
36 /* Only use implicit IV in AEAD cipher mode, where HMAC key is not used */
37 if (cipher_kt_mode_aead(cipher_kt)) {
38 size_t impl_iv_len = 0;
39 ASSERT(cipher_kt_iv_size(cipher_kt) >= OPENVPN_AEAD_MIN_IV_LEN);
40 impl_iv_len = cipher_kt_iv_size(cipher_kt) - sizeof(packet_id_type);
41 ASSERT(impl_iv_len <= OPENVPN_MAX_IV_LENGTH);
42 ASSERT(impl_iv_len <= key_len);
43 memcpy(ctx->implicit_iv, key, impl_iv_len);
44 ctx->implicit_iv_len = impl_iv_len;
45 }
46 }
47
init_frame(struct frame * frame)48 static int init_frame(struct frame *frame) {
49 frame->link_mtu = fuzz_randomizer_get_int(100, 1000);
50 frame->extra_buffer = fuzz_randomizer_get_int(100, 1000);
51 frame->link_mtu_dynamic = fuzz_randomizer_get_int(100, 1000);
52 frame->extra_frame = fuzz_randomizer_get_int(100, 1000);
53 frame->extra_tun = fuzz_randomizer_get_int(100, 1000);
54 frame->extra_link = fuzz_randomizer_get_int(100, 1000);
55 frame->align_flags = 0;
56 frame->align_adjust = 0;
57 if (TUN_MTU_SIZE(frame) <= 0) {
58 return -1;
59 }
60 return 0;
61 }
62
LLVMFuzzerInitialize(int * argc,char *** argv)63 int LLVMFuzzerInitialize(int *argc, char ***argv) {
64 OPENSSL_malloc_init();
65 SSL_library_init();
66 ERR_load_crypto_strings();
67
68 OpenSSL_add_all_algorithms();
69 OpenSSL_add_ssl_algorithms();
70
71 SSL_load_error_strings();
72 return 0;
73 }
74
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)75 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
76 fuzz_random_init(data, size);
77 fuzz_success = 1;
78 bool key_ctx_dec_initialized = false;
79 bool key_ctx_enc_initialized = false;
80 struct key_ctx key_ctx_dec;
81 memset(&key_ctx_dec, 0, sizeof(struct key_ctx));
82 struct key_ctx key_ctx_enc;
83 memset(&key_ctx_enc, 0, sizeof(struct key_ctx));
84
85 struct gc_arena gc;
86 struct tls_session *session = NULL;
87 X509 *x509 = NULL;
88 gc = gc_new();
89
90 gb_init();
91
92 // Read key file
93 struct key2 key2;
94 char *keydata = gb_get_random_string();
95 read_key_file(&key2, keydata, RKF_INLINE);
96
97 // init key type
98 struct key_type kt;
99 memset(&kt, 0, sizeof(struct key_type));
100
101 char *ciphername = gb_get_random_string();
102 char *authname = gb_get_random_string();
103 bool key_type_initialized = false;
104
105 if (strcmp(ciphername, "AES-256-GCM") == 0 ||
106 strcmp(ciphername, "AES-128-GCM") == 0 ||
107 strcmp(ciphername, "AES-192-GCM") == 0 ||
108 strcmp(ciphername, "CAMELLIA-128-CFB128") == 0) {
109
110 int v = fuzz_randomizer_get_int(0, 1);
111 if (v == 0) {
112 init_key_type(&kt, ciphername, authname, true, 0);
113 } else {
114 init_key_type(&kt, ciphername, authname, false, 0);
115 }
116 key_type_initialized = true;
117 }
118
119 if (fuzz_success == 0) {
120 goto cleanup;
121 }
122
123 // Generate key.
124 // Identify which one we should do, read or generate a random key.
125 int c = fuzz_randomizer_get_int(0, 1);
126 const uint8_t d[1024];
127 int key_read = 0;
128 struct key key;
129 if (c == 0) {
130 if (fuzz_get_random_data(d, 1024) != 1024) {
131 struct buffer buf = alloc_buf(1024);
132 buf_write(&buf, d, 1024);
133 if (read_key(&key, &kt, &buf) == 1) {
134 key_read = 1;
135 }
136 free_buf(&buf);
137 }
138 }
139 else {
140 if (key_type_initialized == true) {
141 generate_key_random(&key, &kt);
142 }
143 }
144
145 if (fuzz_success == 0) {
146 goto cleanup;
147 }
148 key_read = 1;
149
150 // init decryption context
151 if (key_type_initialized && key_read) {
152 init_key_ctx(&key_ctx_dec, &key, &kt, OPENVPN_OP_DECRYPT, "x");
153 key_ctx_update_implicit_iv(&key_ctx_dec, &(key.hmac), MAX_HMAC_KEY_LENGTH);
154 key_ctx_dec_initialized = true;
155 }
156
157 // init encryption context
158 if (key_type_initialized && key_read) {
159 init_key_ctx(&key_ctx_enc, &key, &kt, OPENVPN_OP_DECRYPT, "x");
160 key_ctx_update_implicit_iv(&key_ctx_enc, &(key.hmac), MAX_HMAC_KEY_LENGTH);
161 key_ctx_enc_initialized = true;
162 }
163
164 // perform encryption
165 struct frame frame;
166 memset(&frame, 0, sizeof(struct frame));
167 if (key_ctx_enc_initialized == true && key_ctx_dec_initialized == true &&
168 init_frame(&frame) == 0) {
169 struct crypto_options opt;
170 memset(&opt, 0, sizeof(opt));
171 opt.pid_persist = NULL;
172 opt.key_ctx_bi.encrypt = key_ctx_enc;
173 opt.key_ctx_bi.decrypt = key_ctx_dec;
174 opt.key_ctx_bi.initialized = true;
175 opt.packet_id.rec.initialized = true;
176 opt.packet_id.rec.seq_list = NULL;
177 opt.packet_id.rec.name = NULL;
178
179 void *buf_p;
180
181 struct buffer encrypt_workspace = alloc_buf_gc(BUF_SIZE(&(frame)), &gc);
182 struct buffer work = alloc_buf_gc(BUF_SIZE(&(frame)), &gc);
183 struct buffer src = alloc_buf_gc(TUN_MTU_SIZE(&(frame)), &gc);
184 struct buffer buf = clear_buf();
185
186 int x = fuzz_randomizer_get_int(1, TUN_MTU_SIZE(&frame));
187
188 ASSERT(buf_init(&work, FRAME_HEADROOM(&(frame))));
189 ASSERT(buf_init(&src, 0));
190 src.len = x;
191 ASSERT(rand_bytes(BPTR(&src), BLEN(&src)));
192
193 buf = work;
194 buf_p = buf_write_alloc(&buf, BLEN(&src));
195 ASSERT(buf_p);
196 memcpy(buf_p, BPTR(&src), BLEN(&src));
197
198 ASSERT(buf_init(&encrypt_workspace, FRAME_HEADROOM(&(frame))));
199
200 openvpn_encrypt(&buf, encrypt_workspace, &opt);
201 }
202
203 // perform decryption
204 memset(&frame, 0, sizeof(struct frame));
205 if (key_ctx_dec_initialized == true && key_ctx_enc_initialized == true &&
206 init_frame(&frame) == 0) {
207 struct crypto_options opt;
208 memset(&opt, 0, sizeof(opt));
209 opt.pid_persist = NULL;
210 opt.key_ctx_bi.encrypt = key_ctx_enc;
211 opt.key_ctx_bi.decrypt = key_ctx_dec;
212 opt.key_ctx_bi.initialized = true;
213 opt.packet_id.rec.initialized = true;
214 opt.packet_id.rec.seq_list = NULL;
215 opt.packet_id.rec.name = NULL;
216
217 void *buf_p;
218
219 struct buffer decrypt_workspace = alloc_buf_gc(BUF_SIZE(&(frame)), &gc);
220 struct buffer work = alloc_buf_gc(BUF_SIZE(&(frame)), &gc);
221 struct buffer src = alloc_buf_gc(TUN_MTU_SIZE(&(frame)), &gc);
222 struct buffer buf = clear_buf();
223
224 int x = fuzz_randomizer_get_int(1, TUN_MTU_SIZE(&frame));
225
226 ASSERT(buf_init(&work, FRAME_HEADROOM(&(frame))));
227 ASSERT(buf_init(&src, 0));
228 src.len = x;
229 ASSERT(rand_bytes(BPTR(&src), BLEN(&src)));
230
231 buf = work;
232 buf_p = buf_write_alloc(&buf, BLEN(&src));
233 ASSERT(buf_p);
234 memcpy(buf_p, BPTR(&src), BLEN(&src));
235
236 ASSERT(buf_init(&decrypt_workspace, FRAME_HEADROOM(&(frame))));
237
238 openvpn_decrypt(&buf, decrypt_workspace, &opt, &frame, BPTR(&buf));
239 }
240
241 cleanup:
242 // cleanup
243 gc_free(&gc);
244
245 if (key_ctx_dec_initialized == true) {
246 free_key_ctx(&key_ctx_dec);
247 }
248
249 if (key_ctx_enc_initialized == true) {
250 free_key_ctx(&key_ctx_enc);
251 }
252 fuzz_random_destroy();
253
254 gb_cleanup();
255
256 return 0;
257 }
258