Coverage Report

Created: 2026-03-06 06:32

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