Coverage Report

Created: 2026-06-16 07:08

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