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