• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PowerDNS / pdns / 18458071895

13 Oct 2025 07:15AM UTC coverage: 64.051% (-0.09%) from 64.141%
18458071895

push

github

web-flow
Merge pull request #16123 from pieterlexis/dnsdist-ipcrypt-16110

dnsdist: Add IPCrypt2 PFX to Remote(Response)LogAction

42885 of 101718 branches covered (42.16%)

Branch coverage included in aggregate %.

288 of 733 new or added lines in 8 files covered. (39.29%)

30 existing lines in 9 files now uncovered.

130276 of 168629 relevant lines covered (77.26%)

5856345.63 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

10.0
/ext/ipcrypt2/include/ipcrypt2.h
1
#ifndef ipcrypt2_H
2
#define ipcrypt2_H
3

4
#ifdef __cplusplus
5
extern "C" {
6
#endif
7

8
#include <stddef.h>
9
#include <stdint.h>
10

11
/* System headers for socket structures */
12
#if defined(_WIN32)
13
#    include <winsock2.h>
14
#else
15
#    include <sys/types.h>
16
/* <sys/types.h> must be included before <sys/socket.h> */
17
#    include <sys/socket.h>
18
#endif
19

20
/** Size of the AES encryption key, in bytes (128 bits). */
NEW
21
#define IPCRYPT_KEYBYTES 16U
×
22

23
/** Size of the encryption tweak, in bytes (64 bits). */
NEW
24
#define IPCRYPT_TWEAKBYTES 8U
×
25

26
/** Maximum length of an IP address string, including the null terminator. */
NEW
27
#define IPCRYPT_MAX_IP_STR_BYTES 46U
×
28

29
/** Size of the binary output for non-deterministic encryption. */
NEW
30
#define IPCRYPT_NDIP_BYTES 24U
×
31

32
/** Size of the hexadecimal output for non-deterministic encryption, including null terminator. */
NEW
33
#define IPCRYPT_NDIP_STR_BYTES (48U + 1U)
×
34

35
/** Size of the NDX encryption key, in bytes (256 bits). */
NEW
36
#define IPCRYPT_NDX_KEYBYTES 32U
×
37

38
/** Size of the NDX cryption tweak, in bytes (128 bits). */
NEW
39
#define IPCRYPT_NDX_TWEAKBYTES 16U
×
40

41
/** Size of the binary output for NDX encryption. */
NEW
42
#define IPCRYPT_NDX_NDIP_BYTES 32U
×
43

44
/** Size of the hexadecimal output for NDX encryption, including null terminator. */
NEW
45
#define IPCRYPT_NDX_NDIP_STR_BYTES (64U + 1U)
×
46

47
/** Size of the PFX encryption key, in bytes (256 bits). */
48
#define IPCRYPT_PFX_KEYBYTES 32U
14✔
49

50
/* -------- Utility functions -------- */
51

52
/**
53
 * Convert an IP address string (IPv4 or IPv6) to a 16-byte binary representation.
54
 */
55
int ipcrypt_str_to_ip16(uint8_t ip16[16], const char *ip_str);
56

57
/**
58
 * Convert a 16-byte binary IP address into a string.
59
 *
60
 * Returns the length of the resulting string on success, or 0 on error.
61
 */
62
size_t ipcrypt_ip16_to_str(char ip_str[IPCRYPT_MAX_IP_STR_BYTES], const uint8_t ip16[16]);
63

64
/**
65
 * Convert a socket address structure to a 16-byte binary IP representation.
66
 *
67
 * Supports both IPv4 (AF_INET) and IPv6 (AF_INET6) socket addresses.
68
 * For IPv4 addresses, they are converted to IPv4-mapped IPv6 format.
69
 *
70
 * Returns 0 on success, or -1 if the address family is not supported.
71
 */
72
int ipcrypt_sockaddr_to_ip16(uint8_t ip16[16], const struct sockaddr *sa);
73

74
/**
75
 * Convert a 16-byte binary IP address to a socket address structure.
76
 *
77
 * The socket address structure is populated based on the IP format:
78
 * - For IPv4-mapped IPv6 addresses, an IPv4 socket address is created
79
 * - For other IPv6 addresses, an IPv6 socket address is created
80
 *
81
 * The provided sockaddr_storage structure is guaranteed to be large enough
82
 * to hold any socket address type.
83
 */
84
void ipcrypt_ip16_to_sockaddr(struct sockaddr_storage *sa, const uint8_t ip16[16]);
85

86
/**
87
 * Convert a hexadecimal string to a secret key.
88
 *
89
 * The input string must be exactly 32 or 64 characters long (IPCRYPT_KEYBYTES or
90
 * IPCRYPT_NDX_KEYBYTES bytes in hex). Returns 0 on success, or -1 if the input string is invalid or
91
 * conversion fails.
92
 */
93
int ipcrypt_key_from_hex(uint8_t *key, size_t key_len, const char *hex, size_t hex_len);
94

95
/**
96
 * Convert a hexadecimal string to an ipcrypt-nd ciphertext.
97
 *
98
 * The input string must be exactly 48 characters long (IPCRYPT_NDIP_BYTES bytes in hex).
99
 * Returns 0 on success, or -1 if the input string is invalid or conversion fails.
100
 */
101
int ipcrypt_ndip_from_hex(uint8_t ndip[IPCRYPT_NDIP_BYTES], const char *hex, size_t hex_len);
102

103
/**
104
 * Convert a hexadecimal string to an ipcrypt-ndx ciphertext.
105
 *
106
 * The input string must be exactly 64 characters long (IPCRYPT_NDX_NDIP_BYTES bytes in hex).
107
 * Returns 0 on success, or -1 if the input string is invalid or conversion fails.
108
 */
109
int ipcrypt_ndx_ndip_from_hex(uint8_t ndip[IPCRYPT_NDX_NDIP_BYTES], const char *hex,
110
                              size_t hex_len);
111

112
/* -------- IP encryption -------- */
113

114
/**
115
 * Encryption context structure.
116
 * Must be initialized with ipcrypt_init() before use.
117
 */
118
typedef struct IPCrypt {
119
    uint8_t opaque[16U * 11];
120
} IPCrypt;
121

122
/**
123
 * Initialize the IPCrypt context with a 16-byte secret key.
124
 *
125
 * The key must:
126
 * - Be exactly IPCRYPT_KEYBYTES bytes.
127
 * - Be secret and randomly generated.
128
 */
129
void ipcrypt_init(IPCrypt *ipcrypt, const uint8_t key[IPCRYPT_KEYBYTES]);
130

131
/**
132
 * Securely clear and deinitialize the IPCrypt context.
133
 *
134
 * Optional: No heap allocations are used, but this ensures secrets are wiped from memory.
135
 */
136
void ipcrypt_deinit(IPCrypt *ipcrypt);
137

138
/**
139
 * Encrypt a 16-byte IP address in-place (format-preserving).
140
 */
141
void ipcrypt_encrypt_ip16(const IPCrypt *ipcrypt, uint8_t ip16[16]);
142

143
/**
144
 * Decrypt a 16-byte IP address in-place (format-preserving).
145
 */
146
void ipcrypt_decrypt_ip16(const IPCrypt *ipcrypt, uint8_t ip16[16]);
147

148
/**
149
 * Encrypt an IP address string (IPv4 or IPv6).
150
 *
151
 * Output is a format-preserving string written to encrypted_ip_str.
152
 * Returns the output length on success, or 0 on error.
153
 */
154
size_t ipcrypt_encrypt_ip_str(const IPCrypt *ipcrypt,
155
                              char encrypted_ip_str[IPCRYPT_MAX_IP_STR_BYTES], const char *ip_str);
156

157
/**
158
 * Decrypt a previously encrypted IP address string.
159
 *
160
 * Output is written to ip_str. Returns the output length on success, or 0 on error.
161
 */
162
size_t ipcrypt_decrypt_ip_str(const IPCrypt *ipcrypt,
163
                              char           ip_str[IPCRYPT_MAX_IP_STR_BYTES],
164
                              const char    *encrypted_ip_str);
165

166
/**
167
 * Non-deterministically encrypt a 16-byte IP address using an 8-byte tweak.
168
 *
169
 * Output is written to ndip. `random` must be set to a secure 8-byte random value.
170
 */
171
void ipcrypt_nd_encrypt_ip16(const IPCrypt *ipcrypt, uint8_t ndip[IPCRYPT_NDIP_BYTES],
172
                             const uint8_t ip16[16], const uint8_t random[IPCRYPT_TWEAKBYTES]);
173

174
/**
175
 * Decrypt a non-deterministically encrypted 16-byte IP address.
176
 *
177
 * Input is ndip, and output is written to ip16.
178
 */
179
void ipcrypt_nd_decrypt_ip16(const IPCrypt *ipcrypt, uint8_t ip16[16],
180
                             const uint8_t ndip[IPCRYPT_NDIP_BYTES]);
181

182
/**
183
 * Encrypt an IP address string non-deterministically.
184
 *
185
 * Output is a hex-encoded zero-terminated string written to encrypted_ip_str.
186
 *`random` must be an 8-byte random value.
187
 *
188
 * Returns the output length, without the null terminator.
189
 */
190
size_t ipcrypt_nd_encrypt_ip_str(const IPCrypt *ipcrypt,
191
                                 char           encrypted_ip_str[IPCRYPT_NDIP_STR_BYTES],
192
                                 const char    *ip_str,
193
                                 const uint8_t  random[IPCRYPT_TWEAKBYTES]);
194

195
/**
196
 * Decrypt a hex-encoded IP address string from non-deterministic mode.
197
 *
198
 * Output is written to ip_str. Returns the output length on success, or 0 on error.
199
 */
200
size_t ipcrypt_nd_decrypt_ip_str(const IPCrypt *ipcrypt,
201
                                 char           ip_str[IPCRYPT_MAX_IP_STR_BYTES],
202
                                 const char    *encrypted_ip_str);
203

204
/* -------- Prefix-preserving IP encryption -------- */
205

206
/**
207
 * Encryption context structure for prefix-preserving IP encryption.
208
 * Must be initialized with ipcrypt_pfx_init() before use.
209
 */
210
typedef struct IPCryptPFX {
211
    uint8_t opaque[16U * 11 * 2];
212
} IPCryptPFX;
213

214
/**
215
 * Initialize the IPCryptPFX context with a 32-byte secret key.
216
 *
217
 * The key must:
218
 * - Be exactly IPCRYPT_PFX_KEYBYTES bytes.
219
 * - Be secret and randomly generated.
220
 *
221
 * Returns 0 on success.
222
 */
223
int ipcrypt_pfx_init(IPCryptPFX *ipcrypt, const uint8_t key[IPCRYPT_PFX_KEYBYTES]);
224

225
/**
226
 * Securely clear and deinitialize the IPCryptPFX context.
227
 *
228
 * Optional: No heap allocations are used, but this ensures secrets are wiped from memory.
229
 */
230
void ipcrypt_pfx_deinit(IPCryptPFX *ipcrypt);
231

232
/**
233
 * Encrypt a 16-byte IP address in-place with prefix preservation.
234
 *
235
 * IP addresses with the same prefix produce encrypted IP addresses with the same prefix.
236
 * The prefix can be of any length. For IPv4 addresses (stored as IPv4-mapped IPv6),
237
 * preserves the IPv4 prefix structure.
238
 */
239
void ipcrypt_pfx_encrypt_ip16(const IPCryptPFX *ipcrypt, uint8_t ip16[16]);
240

241
/**
242
 * Decrypt a 16-byte IP address in-place with prefix preservation.
243
 *
244
 * Reverses the encryption performed by ipcrypt_pfx_encrypt_ip16().
245
 */
246
void ipcrypt_pfx_decrypt_ip16(const IPCryptPFX *ipcrypt, uint8_t ip16[16]);
247

248
/**
249
 * Encrypt an IP address string (IPv4 or IPv6) with prefix preservation.
250
 *
251
 * Output is a format-preserving string written to encrypted_ip_str.
252
 * Returns the output length on success, or 0 on error.
253
 */
254
size_t ipcrypt_pfx_encrypt_ip_str(const IPCryptPFX *ipcrypt,
255
                                  char              encrypted_ip_str[IPCRYPT_MAX_IP_STR_BYTES],
256
                                  const char       *ip_str);
257

258
/**
259
 * Decrypt a previously encrypted IP address string with prefix preservation.
260
 *
261
 * Output is written to ip_str. Returns the output length on success, or 0 on error.
262
 */
263
size_t ipcrypt_pfx_decrypt_ip_str(const IPCryptPFX *ipcrypt,
264
                                  char              ip_str[IPCRYPT_MAX_IP_STR_BYTES],
265
                                  const char       *encrypted_ip_str);
266

267
/* -------- IP non-deterministic encryption with a 16-byte tweak -------- */
268

269
/**
270
 * Encryption context structure for NDX mode (non-deterministic encryption with 16 bytes of
271
 * tweak and a 32-byte secret key).
272
 *
273
 * Must be initialized with ipcrypt_ndx_init() before use.
274
 */
275
typedef struct IPCryptNDX {
276
    uint8_t opaque[16U * 11 * 2];
277
} IPCryptNDX;
278

279
/**
280
 * Initialize the IPCryptNDX context with a 32-byte secret key.
281
 *
282
 * The key must:
283
 * - Be exactly IPCRYPT_NDX_KEYBYTES bytes.
284
 * - Be secret and randomly generated.
285
 *
286
 * Returns 0 on success.
287
 */
288
int ipcrypt_ndx_init(IPCryptNDX *ipcrypt, const uint8_t key[IPCRYPT_NDX_KEYBYTES]);
289

290
/**
291
 * Securely clear and deinitialize the IPCryptNDX context.
292
 *
293
 * Optional: No heap allocations are used, but this ensures secrets are wiped from memory.
294
 */
295
void ipcrypt_ndx_deinit(IPCryptNDX *ipcrypt);
296

297
/**
298
 * Non-deterministically encrypt a 16-byte IP address using an 16-byte tweak.
299
 *
300
 * Output is written to ndip. `random` must be set to a secure 16-byte random value.
301
 */
302
void ipcrypt_ndx_encrypt_ip16(const IPCryptNDX *ipcrypt, uint8_t ndip[IPCRYPT_NDX_NDIP_BYTES],
303
                              const uint8_t ip16[16], const uint8_t random[IPCRYPT_NDX_TWEAKBYTES]);
304

305
/**
306
 * Decrypt a non-deterministically encrypted 16-byte IP address, previously encrypted with
307
 * `ipcrypt_ndx_encrypt_ip16`.
308
 *
309
 * Input is ndip, and output is written to ip16.
310
 */
311
void ipcrypt_ndx_decrypt_ip16(const IPCryptNDX *ipcrypt, uint8_t ip16[16],
312
                              const uint8_t ndip[IPCRYPT_NDX_NDIP_BYTES]);
313

314
/**
315
 * Encrypt an IP address string non-deterministically.
316
 *
317
 * Output is a hex-encoded zero-terminated string written to encrypted_ip_str.
318
 *`random` must be an 16-byte random value.
319
 *
320
 * Returns the output length, without the null terminator.
321
 */
322
size_t ipcrypt_ndx_encrypt_ip_str(const IPCryptNDX *ipcrypt,
323
                                  char              encrypted_ip_str[IPCRYPT_NDX_NDIP_STR_BYTES],
324
                                  const char *ip_str, const uint8_t random[IPCRYPT_NDX_TWEAKBYTES]);
325

326
/**
327
 * Decrypt a hex-encoded IP address string from non-deterministic mode.
328
 *
329
 * Output is written to ip_str. Returns the output length on success, or 0 on error.
330
 */
331
size_t ipcrypt_ndx_decrypt_ip_str(const IPCryptNDX *ipcrypt, char ip_str[IPCRYPT_MAX_IP_STR_BYTES],
332
                                  const char *encrypted_ip_str);
333

334
#ifdef __cplusplus
335
}
336
#endif
337

338
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc