22// Distributed under the MIT software license, see the accompanying
33// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44
5+ #include < crypto/chacha20.h>
6+ #include < test/fuzz/FuzzedDataProvider.h>
7+ #include < test/fuzz/fuzz.h>
8+ #include < test/fuzz/util.h>
9+
510#include < cstdint>
611#include < netdb.h>
712#include < netinet/in.h>
1217#include < unistd.h>
1318#include < vector>
1419
20+ #define SV_SOCK_PATH " /tmp/socket_test.s"
21+
1522// read size from a file descriptor
1623// return true if val is set, false for EOF
1724static bool read_uint32 (int read_fd, uint32_t & val)
@@ -128,4 +135,84 @@ void send_to_python(int sockfd, uint32_t num)
128135 iBuf += rc;
129136 }
130137 }
138+ }
139+
140+ FUZZ_TARGET (crypto_diff_fuzz_pychacha20)
141+ {
142+ /* ----------------------- socket initialisation -------------------------- */
143+ struct sockaddr_un addr;
144+
145+ // Create a new client socket with domain: AF_UNIX, type: SOCK_STREAM, protocol: 0
146+ int sockfd = socket (AF_UNIX, SOCK_STREAM, 0 );
147+
148+ // Make sure socket's file descriptor is legit.
149+ if (sockfd == -1 ) {
150+ std::cout << " socket creation failed...\n " ;
151+ exit (1 );
152+ }
153+
154+ // Construct server address, and make the connection.
155+ memset (&addr, 0 , sizeof (struct sockaddr_un ));
156+ addr.sun_family = AF_UNIX;
157+ strncpy (addr.sun_path , SV_SOCK_PATH, sizeof (addr.sun_path ) - 1 );
158+
159+ struct timeval tv;
160+ tv.tv_sec = 60 ;
161+ tv.tv_usec = 0 ;
162+ setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof tv);
163+
164+ // Connects the active socket(sockfd) to the listening socket whose address is addr.
165+ if (connect (sockfd, (struct sockaddr *)&addr, sizeof (struct sockaddr_un )) == -1 ) {
166+ std::cout << " connection with the server failed...\n " ;
167+ exit (1 );
168+ }
169+ /* ----------------------- initialisation over ----------------------- */
170+ /* ----------------------- fuzzing phase ------------------------------ */
171+ FuzzedDataProvider fuzzed_data_provider{buffer.data (), buffer.size ()};
172+ ChaCha20 chacha20;
173+
174+ const std::vector<unsigned char > key = ConsumeFixedLengthByteVector (fuzzed_data_provider, 32 );
175+ chacha20 = ChaCha20{key.data (), key.size ()};
176+ // send to python server [4][init][key.size][key.data]
177+ send_to_python (sockfd, " init" );
178+ send_to_python (sockfd, std::string (key.begin (), key.end ()));
179+ // check if response from python server is "ok"
180+ std::vector<unsigned char > response = read_from_python (sockfd);
181+ std::string s1 (response.begin (), response.end ());
182+ assert (s1 == " ok" );
183+
184+ LIMITED_WHILE (fuzzed_data_provider.ConsumeBool (), 3000 )
185+ {
186+ CallOneOf (
187+ fuzzed_data_provider,
188+ [&] {
189+ uint32_t integralInRange = fuzzed_data_provider.ConsumeIntegralInRange <size_t >(0 , 4096 );
190+ std::vector<uint8_t > cpp_keystream (integralInRange);
191+ chacha20.Keystream (cpp_keystream.data (), cpp_keystream.size ());
192+ // send to python server [6]["stream"][keystream_size]
193+ send_to_python (sockfd, " stream" );
194+ send_to_python (sockfd, integralInRange);
195+ // check if the cpp and python computations of the keystream match
196+ std::vector<unsigned char > py_keystream = read_from_python (sockfd);
197+ assert (cpp_keystream == py_keystream);
198+ },
199+ [&] {
200+ uint32_t integralInRange = fuzzed_data_provider.ConsumeIntegralInRange <size_t >(0 , 4096 );
201+ std::vector<uint8_t > cpp_ciphertext (integralInRange);
202+ const std::vector<uint8_t > plaintext = ConsumeFixedLengthByteVector (fuzzed_data_provider, integralInRange);
203+ chacha20.Crypt (plaintext.data (), cpp_ciphertext.data (), integralInRange);
204+ // send to python server [5]["crypt"][size][plaintext]
205+ send_to_python (sockfd, " crypt" );
206+ send_to_python (sockfd, std::string (plaintext.begin (), plaintext.end ()));
207+ // check if the cpp and python ciphertext match
208+ std::vector<unsigned char > py_ciphertext = read_from_python (sockfd);
209+ assert (cpp_ciphertext == py_ciphertext);
210+ });
211+ }
212+ send_to_python (sockfd, " exit" );
213+ response = read_from_python (sockfd);
214+ std::string s2 (response.begin (), response.end ());
215+ assert (s2 == " ok" );
216+ /* ----------------------- end fuzzing phase ----------------------- */
217+ close (sockfd);
131218}
0 commit comments