Coverage Report

Created: 2024-01-13 07:07

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