Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: testing/libfuzzer/fuzzers/libsrtp_fuzzer.cc

Issue 2123553002: Add a fuzzer for srtp_unprotect in libsrtp. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Code review Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « testing/libfuzzer/fuzzers/BUILD.gn ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <assert.h>
6 #include <stddef.h>
7 #include <stdint.h>
8
9 #include "third_party/libsrtp/srtp/include/rtp.h"
10 #include "third_party/libsrtp/srtp/include/rtp_priv.h"
11 #include "third_party/libsrtp/srtp/include/srtp.h"
12
13 // TODO(katrielc) Also test the authenticated path, which is what
14 // WebRTC uses. This is nontrivial because you need to bypass the MAC
15 // check. Two options: add a UNSAFE_FUZZER_MODE flag to libsrtp (or
16 // the chromium fork of it), or compute the HMAC of whatever gibberish
17 // the fuzzer produces and write it into the packet manually.
18
19 namespace LibSrtpFuzzer {
20 enum CryptoPolicy {
21 NONE,
22 LIKE_WEBRTC,
23 LIKE_WEBRTC_WITHOUT_AUTH,
24 AES_GCM,
25 NUMBER_OF_POLICIES,
26 };
27 }
28
29 void crypto_policy_set_null_cipher_null_auth(crypto_policy_t* p) {
30 p->cipher_type = NULL_CIPHER;
31 p->cipher_key_len = 0;
32 p->auth_type = NULL_AUTH;
33 p->auth_key_len = 0;
34 p->auth_tag_len = 0;
35 p->sec_serv = sec_serv_none;
36 };
37
38 // Environment holds some structs and buffers so that we don't need to
39 // reallocate them on every fuzzer iteration.
40 struct Environment {
41 srtp_t session;
42 srtp_policy_t policy;
43 unsigned char key[30] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
mmoroz 2016/07/05 16:06:21 Would be better to use SRTP_MASTER_KEY_LEN instead
katrielc 2016/07/05 16:26:02 Absolutely, yes :)
44 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
45 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
46 0x59, 0x5a, 0x31, 0x32, 0x33, 0x34};
47
48 srtp_policy_t GetCryptoPolicy(LibSrtpFuzzer::CryptoPolicy crypto_policy,
49 const unsigned char* replacement_key) {
50 // Update some values and return the resulting srtp_policy_t.
51
52 switch (crypto_policy) {
53 case LibSrtpFuzzer::NUMBER_OF_POLICIES:
54 case LibSrtpFuzzer::NONE:
55 crypto_policy_set_null_cipher_null_auth(&policy.rtp);
56 crypto_policy_set_null_cipher_null_auth(&policy.rtcp);
57 break;
58 case LibSrtpFuzzer::LIKE_WEBRTC:
59 crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
60 crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
61 case LibSrtpFuzzer::LIKE_WEBRTC_WITHOUT_AUTH:
62 crypto_policy_set_aes_cm_128_null_auth(&policy.rtp);
63 crypto_policy_set_aes_cm_128_null_auth(&policy.rtcp);
64 break;
65 case LibSrtpFuzzer::AES_GCM:
66 // There was a security bug in the GCM mode in libsrtp 1.5.2.
67 crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
68 crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
69 break;
70 }
71
72 memcpy(key, replacement_key, SRTP_MASTER_KEY_LEN);
73 return policy;
74 };
75
76 Environment() {
77 srtp_init();
78
79 memset(&policy, 0, sizeof(policy));
80 policy.ssrc.type = ssrc_any_inbound;
81 policy.ssrc.value = 0xdeadbeef;
82 policy.window_size = 1024;
83 policy.allow_repeat_tx = 1;
84 policy.ekt = nullptr;
85 policy.next = nullptr;
86
87 // Set some defaults in case we don't want to override them later.
88 policy.key = key;
89 crypto_policy_set_null_cipher_null_auth(&policy.rtp);
90 crypto_policy_set_null_cipher_null_auth(&policy.rtcp);
91 }
92 };
93
94 size_t ReadLength(const uint8_t* data, size_t size) {
95 // Read one byte of input and check that that many bytes remain.
96 if (size == 0)
97 return 0;
98 size_t n = static_cast<size_t>(data[0]);
99
100 if (n > size - 1)
101 return 0;
102 else
103 return n;
104 }
105
106 Environment* env = new Environment();
107
108 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
109 // Read one byte and use it to choose a crypto policy.
110 if (size <= 1)
111 return 0;
112 LibSrtpFuzzer::CryptoPolicy policy = static_cast<LibSrtpFuzzer::CryptoPolicy>(
113 data[0] % LibSrtpFuzzer::NUMBER_OF_POLICIES);
114 data += 1;
115 size -= 1;
116
117 // Read some more bytes to use as a key.
118 if (size <= SRTP_MASTER_KEY_LEN)
119 return 0;
120 srtp_policy_t srtp_policy = env->GetCryptoPolicy(policy, data);
121 data += SRTP_MASTER_KEY_LEN;
122 size -= SRTP_MASTER_KEY_LEN;
123
124 // Create a session with the above data.
125 srtp_t session;
126 err_status_t error = srtp_create(&session, &srtp_policy);
127 assert(error == err_status_ok);
128
129 // Read one byte as a packet length N, then feed the next N bytes
130 // into srtp_unprotect. Keep going until we run out of data.
131 size_t packet_size;
132 while ((packet_size = ReadLength(data, size)) > 0) {
133 size -= packet_size + 1;
134
135 int out_len = static_cast<int>(packet_size);
136 unsigned char raw_packet[packet_size];
mmoroz 2016/07/05 16:06:21 Looks like variable-length arrays are not allowed:
katrielc 2016/07/05 16:26:03 Haha, I should have read the style guide better! l
137 memcpy(raw_packet, data + 1, packet_size);
138 srtp_unprotect(session, &reinterpret_cast<rtp_msg_t*>(raw_packet)->header,
mmoroz 2016/07/05 16:06:21 I cannot understand: 1) we read some "random" size
katrielc 2016/07/05 16:26:03 rtp_msg_t is a C struct of a srtp_something_t and
mmoroz 2016/07/05 16:40:10 Hm, |out_len| is also used as an input length -- I
katrielc 2016/07/05 17:47:31 What do you think of this? I think it's important
139 &out_len);
140
141 data += packet_size + 1;
142 }
143
144 srtp_dealloc(session);
145 return 0;
146 }
OLDNEW
« no previous file with comments | « testing/libfuzzer/fuzzers/BUILD.gn ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698