Coverage Report

Created: 2025-06-13 07:05

/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
}