/src/ndpi/fuzz/fuzz_gcrypt_gcm.cpp
Line | Count | Source |
1 | | #include <stdlib.h> |
2 | | #include <stdint.h> |
3 | | #include <assert.h> |
4 | | #include "fuzzer/FuzzedDataProvider.h" |
5 | | |
6 | | #define MBEDTLS_CHECK_RETURN_TYPICAL |
7 | | #define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) do { } while( 0 ) |
8 | | #include "gcrypt/aes.h" |
9 | | #include "gcrypt/cipher.h" |
10 | | #include "gcrypt/gcm.h" |
11 | | |
12 | | extern int force_no_aesni; |
13 | | |
14 | 319 | extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
15 | 319 | FuzzedDataProvider fuzzed_data(data, size); |
16 | 319 | mbedtls_aes_context *aes_e_ctx, *aes_d_ctx; |
17 | 319 | mbedtls_gcm_context *gcm_e_ctx, *gcm_d_ctx; |
18 | 319 | int key_lens[] = { 128, 192, 256, 512 /* invalid */ }; |
19 | 319 | unsigned char *output, *decrypted; |
20 | 319 | int key_len, rc_e, rc_d; |
21 | 319 | mbedtls_cipher_id_t cipher; |
22 | 319 | unsigned char *tag; |
23 | 319 | int iv_len, tag_len, ad_len, input_length, force_auth_tag_error; |
24 | | |
25 | | /* No real memory allocations involved */ |
26 | | |
27 | 319 | if(fuzzed_data.remaining_bytes() < 1 + 4 + 512 / 8 + |
28 | 319 | 1 + 64 + /* iv */ |
29 | 319 | 1 + /* tag_len */ |
30 | 319 | 1 + 17 + /* ad */ |
31 | 319 | 1 + 64 + /* input */ |
32 | 319 | 1 + /* force_auth_tag_error */ |
33 | 319 | 1 /* useless data: to be able to add the check with assert */) |
34 | 15 | return -1; |
35 | | |
36 | 304 | gcm_e_ctx = (mbedtls_gcm_context *)malloc(sizeof(mbedtls_gcm_context)); |
37 | 304 | gcm_d_ctx = (mbedtls_gcm_context *)malloc(sizeof(mbedtls_gcm_context)); |
38 | 304 | aes_e_ctx = (mbedtls_aes_context *)malloc(sizeof(mbedtls_aes_context)); |
39 | 304 | aes_d_ctx = (mbedtls_aes_context *)malloc(sizeof(mbedtls_aes_context)); |
40 | | |
41 | 304 | force_no_aesni = 0; |
42 | 304 | if(fuzzed_data.ConsumeBool()) |
43 | 97 | force_no_aesni = 1; |
44 | | |
45 | 304 | key_len = fuzzed_data.PickValueInArray(key_lens); |
46 | 304 | std::vector<unsigned char>key = fuzzed_data.ConsumeBytes<u_int8_t>(key_len / 8); |
47 | | |
48 | 304 | iv_len = fuzzed_data.ConsumeIntegralInRange(0, 64); |
49 | 304 | std::vector<u_int8_t>iv = fuzzed_data.ConsumeBytes<uint8_t>(iv_len); |
50 | | |
51 | 304 | tag_len = fuzzed_data.ConsumeIntegralInRange(0, 17); |
52 | 304 | tag = (unsigned char *)malloc(tag_len); |
53 | | |
54 | 304 | ad_len = fuzzed_data.ConsumeIntegralInRange(0, 17); |
55 | 304 | std::vector<u_int8_t>ad = fuzzed_data.ConsumeBytes<uint8_t>(ad_len); |
56 | | |
57 | 304 | input_length = fuzzed_data.ConsumeIntegralInRange(16, 64); |
58 | 304 | std::vector<unsigned char>input = fuzzed_data.ConsumeBytes<u_int8_t>(input_length); |
59 | 304 | output = (unsigned char *)malloc(input_length); |
60 | 304 | decrypted = (unsigned char *)malloc(input_length); |
61 | | |
62 | 304 | force_auth_tag_error = fuzzed_data.ConsumeBool(); |
63 | | |
64 | 304 | cipher = static_cast<mbedtls_cipher_id_t>(fuzzed_data.ConsumeIntegralInRange(0, (int)MBEDTLS_CIPHER_ID_CHACHA20)); |
65 | | |
66 | 304 | assert(fuzzed_data.remaining_bytes() > 0); |
67 | | |
68 | 304 | mbedtls_gcm_init(gcm_e_ctx, aes_e_ctx); |
69 | 304 | mbedtls_gcm_init(gcm_d_ctx, aes_d_ctx); |
70 | | |
71 | 304 | rc_e = mbedtls_gcm_setkey(gcm_e_ctx, cipher, key.data(), key.size() * 8); |
72 | 304 | rc_d = mbedtls_gcm_setkey(gcm_d_ctx, cipher, key.data(), key.size() * 8); |
73 | | |
74 | 304 | if (rc_e == 0 && rc_d == 0) { |
75 | 102 | rc_e = mbedtls_gcm_crypt_and_tag(gcm_e_ctx, MBEDTLS_GCM_ENCRYPT, |
76 | 102 | input.size(), |
77 | 102 | iv.data(), iv.size(), |
78 | 102 | ad.data(), ad.size(), |
79 | 102 | input.data(), |
80 | 102 | output, |
81 | 102 | tag_len, tag); |
82 | 102 | if(rc_e == 0) { |
83 | 65 | if(force_auth_tag_error && tag_len > 0 && tag[0] != 0) { |
84 | 21 | tag[0] = 0; |
85 | 44 | } else { |
86 | 44 | force_auth_tag_error = 0; |
87 | 44 | } |
88 | | |
89 | 65 | rc_d = mbedtls_gcm_auth_decrypt(gcm_d_ctx, |
90 | 65 | input.size(), |
91 | 65 | iv.data(), iv.size(), |
92 | 65 | ad.data(), ad.size(), |
93 | 65 | tag, tag_len, |
94 | 65 | output, |
95 | 65 | decrypted); |
96 | 65 | if(rc_d == 0) |
97 | 44 | assert(memcmp(input.data(), decrypted, input.size()) == 0); |
98 | 65 | if(force_auth_tag_error) |
99 | 21 | assert(rc_d == MBEDTLS_ERR_GCM_AUTH_FAILED); |
100 | 65 | } |
101 | 102 | } |
102 | | |
103 | 304 | mbedtls_gcm_free(gcm_e_ctx); |
104 | 304 | mbedtls_gcm_free(gcm_d_ctx); |
105 | | |
106 | 304 | free(tag); |
107 | 304 | free(gcm_e_ctx); |
108 | 304 | free(gcm_d_ctx); |
109 | 304 | free(aes_e_ctx); |
110 | 304 | free(aes_d_ctx); |
111 | 304 | free(output); |
112 | 304 | free(decrypted); |
113 | | |
114 | 304 | return 0; |
115 | 304 | } |