spiped 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +7 -0
  2. data/ext/spiped/extconf.rb +3 -0
  3. data/ext/spiped/spiped-source/BUILDING +46 -0
  4. data/ext/spiped/spiped-source/CHANGELOG +44 -0
  5. data/ext/spiped/spiped-source/COPYRIGHT +33 -0
  6. data/ext/spiped/spiped-source/Makefile +47 -0
  7. data/ext/spiped/spiped-source/Makefile.POSIX +27 -0
  8. data/ext/spiped/spiped-source/Makefile.inc +20 -0
  9. data/ext/spiped/spiped-source/Makefile.prog +23 -0
  10. data/ext/spiped/spiped-source/POSIX/README +10 -0
  11. data/ext/spiped/spiped-source/POSIX/posix-cflags.sh +10 -0
  12. data/ext/spiped/spiped-source/POSIX/posix-clock_realtime.c +3 -0
  13. data/ext/spiped/spiped-source/POSIX/posix-l.c +1 -0
  14. data/ext/spiped/spiped-source/POSIX/posix-l.sh +14 -0
  15. data/ext/spiped/spiped-source/POSIX/posix-msg_nosignal.c +3 -0
  16. data/ext/spiped/spiped-source/README +198 -0
  17. data/ext/spiped/spiped-source/STYLE +151 -0
  18. data/ext/spiped/spiped-source/lib/dnsthread/dnsthread.c +464 -0
  19. data/ext/spiped/spiped-source/lib/dnsthread/dnsthread.h +45 -0
  20. data/ext/spiped/spiped-source/libcperciva/alg/sha256.c +442 -0
  21. data/ext/spiped/spiped-source/libcperciva/alg/sha256.h +95 -0
  22. data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport-X86-AESNI.c +13 -0
  23. data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport-X86-CPUID.c +8 -0
  24. data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport.sh +37 -0
  25. data/ext/spiped/spiped-source/libcperciva/cpusupport/cpusupport.h +63 -0
  26. data/ext/spiped/spiped-source/libcperciva/cpusupport/cpusupport_x86_aesni.c +30 -0
  27. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes.c +166 -0
  28. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes.h +31 -0
  29. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes_aesni.c +229 -0
  30. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes_aesni.h +31 -0
  31. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aesctr.c +124 -0
  32. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aesctr.h +41 -0
  33. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh.c +293 -0
  34. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh.h +43 -0
  35. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh_group14.c +46 -0
  36. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh_group14.h +9 -0
  37. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_entropy.c +215 -0
  38. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_entropy.h +14 -0
  39. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_verify_bytes.c +21 -0
  40. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_verify_bytes.h +14 -0
  41. data/ext/spiped/spiped-source/libcperciva/datastruct/elasticarray.c +276 -0
  42. data/ext/spiped/spiped-source/libcperciva/datastruct/elasticarray.h +167 -0
  43. data/ext/spiped/spiped-source/libcperciva/datastruct/mpool.h +85 -0
  44. data/ext/spiped/spiped-source/libcperciva/datastruct/ptrheap.c +334 -0
  45. data/ext/spiped/spiped-source/libcperciva/datastruct/ptrheap.h +89 -0
  46. data/ext/spiped/spiped-source/libcperciva/datastruct/timerqueue.c +241 -0
  47. data/ext/spiped/spiped-source/libcperciva/datastruct/timerqueue.h +60 -0
  48. data/ext/spiped/spiped-source/libcperciva/events/events.c +203 -0
  49. data/ext/spiped/spiped-source/libcperciva/events/events.h +106 -0
  50. data/ext/spiped/spiped-source/libcperciva/events/events_immediate.c +149 -0
  51. data/ext/spiped/spiped-source/libcperciva/events/events_internal.h +95 -0
  52. data/ext/spiped/spiped-source/libcperciva/events/events_network.c +347 -0
  53. data/ext/spiped/spiped-source/libcperciva/events/events_network_selectstats.c +106 -0
  54. data/ext/spiped/spiped-source/libcperciva/events/events_timer.c +273 -0
  55. data/ext/spiped/spiped-source/libcperciva/network/network.h +95 -0
  56. data/ext/spiped/spiped-source/libcperciva/network/network_accept.c +103 -0
  57. data/ext/spiped/spiped-source/libcperciva/network/network_connect.c +258 -0
  58. data/ext/spiped/spiped-source/libcperciva/network/network_read.c +155 -0
  59. data/ext/spiped/spiped-source/libcperciva/network/network_write.c +188 -0
  60. data/ext/spiped/spiped-source/libcperciva/util/asprintf.c +49 -0
  61. data/ext/spiped/spiped-source/libcperciva/util/asprintf.h +16 -0
  62. data/ext/spiped/spiped-source/libcperciva/util/daemonize.c +134 -0
  63. data/ext/spiped/spiped-source/libcperciva/util/daemonize.h +10 -0
  64. data/ext/spiped/spiped-source/libcperciva/util/entropy.c +76 -0
  65. data/ext/spiped/spiped-source/libcperciva/util/entropy.h +13 -0
  66. data/ext/spiped/spiped-source/libcperciva/util/imalloc.h +33 -0
  67. data/ext/spiped/spiped-source/libcperciva/util/insecure_memzero.c +19 -0
  68. data/ext/spiped/spiped-source/libcperciva/util/insecure_memzero.h +33 -0
  69. data/ext/spiped/spiped-source/libcperciva/util/monoclock.c +52 -0
  70. data/ext/spiped/spiped-source/libcperciva/util/monoclock.h +14 -0
  71. data/ext/spiped/spiped-source/libcperciva/util/noeintr.c +54 -0
  72. data/ext/spiped/spiped-source/libcperciva/util/noeintr.h +14 -0
  73. data/ext/spiped/spiped-source/libcperciva/util/sock.c +472 -0
  74. data/ext/spiped/spiped-source/libcperciva/util/sock.h +56 -0
  75. data/ext/spiped/spiped-source/libcperciva/util/sock_internal.h +14 -0
  76. data/ext/spiped/spiped-source/libcperciva/util/sock_util.c +271 -0
  77. data/ext/spiped/spiped-source/libcperciva/util/sock_util.h +51 -0
  78. data/ext/spiped/spiped-source/libcperciva/util/sysendian.h +146 -0
  79. data/ext/spiped/spiped-source/libcperciva/util/warnp.c +76 -0
  80. data/ext/spiped/spiped-source/libcperciva/util/warnp.h +59 -0
  81. data/ext/spiped/spiped-source/proto/proto_conn.c +362 -0
  82. data/ext/spiped/spiped-source/proto/proto_conn.h +25 -0
  83. data/ext/spiped/spiped-source/proto/proto_crypt.c +396 -0
  84. data/ext/spiped/spiped-source/proto/proto_crypt.h +102 -0
  85. data/ext/spiped/spiped-source/proto/proto_handshake.c +330 -0
  86. data/ext/spiped/spiped-source/proto/proto_handshake.h +30 -0
  87. data/ext/spiped/spiped-source/proto/proto_pipe.c +202 -0
  88. data/ext/spiped/spiped-source/proto/proto_pipe.h +23 -0
  89. data/ext/spiped/spiped-source/spipe/Makefile +90 -0
  90. data/ext/spiped/spiped-source/spipe/README +24 -0
  91. data/ext/spiped/spiped-source/spipe/main.c +178 -0
  92. data/ext/spiped/spiped-source/spipe/pushbits.c +101 -0
  93. data/ext/spiped/spiped-source/spipe/pushbits.h +10 -0
  94. data/ext/spiped/spiped-source/spipe/spipe.1 +60 -0
  95. data/ext/spiped/spiped-source/spiped/Makefile +98 -0
  96. data/ext/spiped/spiped-source/spiped/README +62 -0
  97. data/ext/spiped/spiped-source/spiped/dispatch.c +214 -0
  98. data/ext/spiped/spiped-source/spiped/dispatch.h +27 -0
  99. data/ext/spiped/spiped-source/spiped/main.c +267 -0
  100. data/ext/spiped/spiped-source/spiped/spiped.1 +112 -0
  101. data/lib/spiped.rb +3 -0
  102. metadata +143 -0
@@ -0,0 +1,25 @@
1
+ #ifndef _PROTO_CONN_H_
2
+ #define _PROTO_CONN_H_
3
+
4
+ /* Opaque structures. */
5
+ struct proto_secret;
6
+ struct sock_addr;
7
+
8
+ /**
9
+ * proto_conn_create(s, sas, decr, nofps, requirefps, nokeepalive, K, timeo,
10
+ * callback_dead, cookie):
11
+ * Create a connection with one end at ${s} and the other end connecting to
12
+ * the target addresses ${sas}. If ${decr} is 0, encrypt the outgoing data;
13
+ * if ${decr} is nonzero, decrypt the outgoing data. If ${nofps} is non-zero,
14
+ * don't use perfect forward secrecy. If ${requirefps} is non-zero, drop
15
+ * the connection if the other end tries to disable perfect forward secrecy.
16
+ * Enable transport layer keep-alives (if applicable) on both sockets if and
17
+ * only if ${nokeepalive} is zero. Drop the connection if the handshake or
18
+ * connecting to the target takes more than ${timeo} seconds. When the
19
+ * connection is dropped, invoke ${callback_dead}(${cookie}). Free ${sas}
20
+ * once it is no longer needed.
21
+ */
22
+ int proto_conn_create(int, struct sock_addr **, int, int, int, int,
23
+ const struct proto_secret *, double, int (*)(void *), void *);
24
+
25
+ #endif /* !_CONN_H_ */
@@ -0,0 +1,396 @@
1
+ #include <assert.h>
2
+ #include <stdint.h>
3
+ #include <stdio.h>
4
+ #include <stdlib.h>
5
+ #include <string.h>
6
+
7
+ #include "crypto_aes.h"
8
+ #include "crypto_aesctr.h"
9
+ #include "crypto_verify_bytes.h"
10
+ #include "sha256.h"
11
+ #include "sysendian.h"
12
+ #include "warnp.h"
13
+
14
+ #include "proto_crypt.h"
15
+
16
+ struct proto_secret {
17
+ uint8_t K[32];
18
+ };
19
+
20
+ struct proto_keys {
21
+ struct crypto_aes_key * k_aes;
22
+ uint8_t k_hmac[32];
23
+ uint64_t pnum;
24
+ };
25
+
26
+ /**
27
+ * mkkeypair(kbuf):
28
+ * Convert the 64 bytes of ${kbuf} into a protocol key structure.
29
+ */
30
+ static struct proto_keys *
31
+ mkkeypair(uint8_t kbuf[64])
32
+ {
33
+ struct proto_keys * k;
34
+
35
+ /* Allocate a structure. */
36
+ if ((k = malloc(sizeof(struct proto_keys))) == NULL)
37
+ goto err0;
38
+
39
+ /* Expand the AES key. */
40
+ if ((k->k_aes = crypto_aes_key_expand(&kbuf[0], 32)) == NULL)
41
+ goto err1;
42
+
43
+ /* Fill in HMAC key. */
44
+ memcpy(k->k_hmac, &kbuf[32], 32);
45
+
46
+ /* The first packet will be packet number zero. */
47
+ k->pnum = 0;
48
+
49
+ /* Success! */
50
+ return (k);
51
+
52
+ err1:
53
+ free(k);
54
+ err0:
55
+ /* Failure! */
56
+ return (NULL);
57
+ }
58
+
59
+ /**
60
+ * proto_crypt_secret(filename):
61
+ * Read the key file ${filename} and return a protocol secret structure.
62
+ */
63
+ struct proto_secret *
64
+ proto_crypt_secret(const char * filename)
65
+ {
66
+ SHA256_CTX ctx;
67
+ FILE * f;
68
+ struct proto_secret * K;
69
+ uint8_t buf[BUFSIZ];
70
+ size_t lenread;
71
+
72
+ /* Allocate a protocol secret structure. */
73
+ if ((K = malloc(sizeof(struct proto_secret))) == NULL)
74
+ goto err0;
75
+
76
+ /* Open the file. */
77
+ if ((f = fopen(filename, "r")) == NULL) {
78
+ warnp("Cannot open file: %s", filename);
79
+ goto err1;
80
+ }
81
+
82
+ /* Initialize the SHA256 hash context. */
83
+ SHA256_Init(&ctx);
84
+
85
+ /* Read the file until we hit EOF. */
86
+ while ((lenread = fread(buf, 1, BUFSIZ, f)) > 0)
87
+ SHA256_Update(&ctx, buf, lenread);
88
+
89
+ /* Did we hit EOF? */
90
+ if (!feof(f)) {
91
+ warnp("Error reading file: %s", filename);
92
+ goto err2;
93
+ }
94
+
95
+ /* Close the file. */
96
+ fclose(f);
97
+
98
+ /* Compute the final hash. */
99
+ SHA256_Final(K->K, &ctx);
100
+
101
+ /* Success! */
102
+ return (K);
103
+
104
+ err2:
105
+ fclose(f);
106
+ err1:
107
+ free(K);
108
+ err0:
109
+ /* Failure! */
110
+ return (NULL);
111
+ }
112
+
113
+ /**
114
+ * proto_crypt_dhmac(K, nonce_l, nonce_r, dhmac_l, dhmac_r, decr):
115
+ * Using the key file hash ${K}, and the local and remote nonces ${nonce_l}
116
+ * and ${nonce_r}, compute the local and remote diffie-hellman parameter MAC
117
+ * keys ${dhmac_l} and ${dhmac_r}. If ${decr} is non-zero, "local" == "S"
118
+ * and "remote" == "C"; otherwise the assignments are opposite.
119
+ */
120
+ void
121
+ proto_crypt_dhmac(const struct proto_secret * K,
122
+ const uint8_t nonce_l[PCRYPT_NONCE_LEN],
123
+ const uint8_t nonce_r[PCRYPT_NONCE_LEN],
124
+ uint8_t dhmac_l[PCRYPT_DHMAC_LEN], uint8_t dhmac_r[PCRYPT_DHMAC_LEN],
125
+ int decr)
126
+ {
127
+ uint8_t nonce_CS[PCRYPT_NONCE_LEN * 2];
128
+ uint8_t dk_1[PCRYPT_DHMAC_LEN * 2];
129
+ const uint8_t * nonce_c, * nonce_s;
130
+ uint8_t * dhmac_c, * dhmac_s;
131
+
132
+ /* Figure out how {c, s} maps to {l, r}. */
133
+ nonce_c = decr ? nonce_r : nonce_l;
134
+ dhmac_c = decr ? dhmac_r : dhmac_l;
135
+ nonce_s = decr ? nonce_l : nonce_r;
136
+ dhmac_s = decr ? dhmac_l : dhmac_r;
137
+
138
+ /* Copy in nonces (in the right order). */
139
+ memcpy(&nonce_CS[0], nonce_c, PCRYPT_NONCE_LEN);
140
+ memcpy(&nonce_CS[PCRYPT_NONCE_LEN], nonce_s, PCRYPT_NONCE_LEN);
141
+
142
+ /* Compute dk_1. */
143
+ PBKDF2_SHA256(K->K, 32, nonce_CS, PCRYPT_NONCE_LEN * 2, 1,
144
+ dk_1, PCRYPT_DHMAC_LEN * 2);
145
+
146
+ /* Copy out diffie-hellman parameter MAC keys (in the right order). */
147
+ memcpy(dhmac_c, &dk_1[0], PCRYPT_DHMAC_LEN);
148
+ memcpy(dhmac_s, &dk_1[PCRYPT_DHMAC_LEN], PCRYPT_DHMAC_LEN);
149
+ }
150
+
151
+ /**
152
+ * is_not_one(x, len):
153
+ * Returns non-zero if the big-endian value stored at (${x}, ${len}) is not
154
+ * equal to 1.
155
+ */
156
+ static int
157
+ is_not_one(const uint8_t * x, size_t len)
158
+ {
159
+ size_t i;
160
+ char y;
161
+
162
+ for (i = 0, y = 0; i < len - 1; i++) {
163
+ y |= x[i];
164
+ }
165
+
166
+ return (y | (x[len - 1] - 1));
167
+ }
168
+
169
+ /**
170
+ * proto_crypt_dh_validate(yh_r, dhmac_r, requirefps):
171
+ * Return non-zero if the value ${yh_r} received from the remote party is not
172
+ * correctly MACed using the diffie-hellman parameter MAC key ${dhmac_r}, or
173
+ * if the included y value is >= the diffie-hellman group modulus, or if
174
+ * ${requirefps} is non-zero and the included y value is 1.
175
+ */
176
+ int
177
+ proto_crypt_dh_validate(const uint8_t yh_r[PCRYPT_YH_LEN],
178
+ const uint8_t dhmac_r[PCRYPT_DHMAC_LEN], int requirefps)
179
+ {
180
+ uint8_t hbuf[32];
181
+
182
+ /* Compute HMAC. */
183
+ HMAC_SHA256_Buf(dhmac_r, PCRYPT_DHMAC_LEN, yh_r, CRYPTO_DH_PUBLEN,
184
+ hbuf);
185
+
186
+ /* Check that the MAC matches. */
187
+ if (crypto_verify_bytes(&yh_r[CRYPTO_DH_PUBLEN], hbuf, 32))
188
+ return (1);
189
+
190
+ /* Sanity-check the diffie-hellman value. */
191
+ if (crypto_dh_sanitycheck(&yh_r[0]))
192
+ return (1);
193
+
194
+ /* If necessary, enforce that the diffie-hellman value is != 1. */
195
+ if (requirefps) {
196
+ if (! is_not_one(&yh_r[0], CRYPTO_DH_PUBLEN))
197
+ return (1);
198
+ }
199
+
200
+ /* Everything is good. */
201
+ return (0);
202
+ }
203
+
204
+ /**
205
+ * proto_crypt_dh_generate(yh_l, x, dhmac_l, nofps):
206
+ * Using the MAC key ${dhmac_l}, generate the MACed diffie-hellman handshake
207
+ * parameter ${yh_l}. Store the diffie-hellman private value in ${x}. If
208
+ * ${nofps} is non-zero, skip diffie-hellman generation and use y = 1.
209
+ */
210
+ int
211
+ proto_crypt_dh_generate(uint8_t yh_l[PCRYPT_YH_LEN], uint8_t x[PCRYPT_X_LEN],
212
+ const uint8_t dhmac_l[PCRYPT_DHMAC_LEN], int nofps)
213
+ {
214
+
215
+ /* Are we skipping the diffie-hellman generation? */
216
+ if (nofps) {
217
+ /* Set y_l to a big-endian 1. */
218
+ memset(yh_l, 0, CRYPTO_DH_PUBLEN - 1);
219
+ yh_l[CRYPTO_DH_PUBLEN - 1] = 1;
220
+ } else {
221
+ /* Generate diffie-hellman parameters x and y. */
222
+ if (crypto_dh_generate(yh_l, x))
223
+ goto err0;
224
+ }
225
+
226
+ /* Append an HMAC. */
227
+ HMAC_SHA256_Buf(dhmac_l, PCRYPT_DHMAC_LEN, yh_l, CRYPTO_DH_PUBLEN,
228
+ &yh_l[CRYPTO_DH_PUBLEN]);
229
+
230
+ /* Success! */
231
+ return (0);
232
+
233
+ err0:
234
+ /* Failure! */
235
+ return (-1);
236
+ }
237
+
238
+ /**
239
+ * proto_crypt_mkkeys(K, nonce_l, nonce_r, yh_r, x, nofps, decr, eh_c, eh_s):
240
+ * Using the protocol secret ${K}, the local and remote nonces ${nonce_l} and
241
+ * ${nonce_r}, the remote MACed diffie-hellman handshake parameter ${yh_r},
242
+ * and the local diffie-hellman secret ${x}, generate the keys ${eh_c} and
243
+ * ${eh_s}. If ${nofps} is non-zero, we are performing weak handshaking and
244
+ * y_SC is set to 1 rather than being computed. If ${decr} is non-zero,
245
+ * "local" == "S" and "remote" == "C"; otherwise the assignments are opposite.
246
+ */
247
+ int
248
+ proto_crypt_mkkeys(const struct proto_secret * K,
249
+ const uint8_t nonce_l[PCRYPT_NONCE_LEN],
250
+ const uint8_t nonce_r[PCRYPT_NONCE_LEN],
251
+ const uint8_t yh_r[PCRYPT_YH_LEN], const uint8_t x[PCRYPT_X_LEN],
252
+ int nofps, int decr,
253
+ struct proto_keys ** eh_c, struct proto_keys ** eh_s)
254
+ {
255
+ uint8_t nonce_y[PCRYPT_NONCE_LEN * 2 + CRYPTO_DH_KEYLEN];
256
+ uint8_t dk_2[128];
257
+ const uint8_t * nonce_c, * nonce_s;
258
+
259
+ /* Copy in nonces (in the right order). */
260
+ nonce_c = decr ? nonce_r : nonce_l;
261
+ nonce_s = decr ? nonce_l : nonce_r;
262
+ memcpy(&nonce_y[0], nonce_c, PCRYPT_NONCE_LEN);
263
+ memcpy(&nonce_y[PCRYPT_NONCE_LEN], nonce_s, PCRYPT_NONCE_LEN);
264
+
265
+ /* Are we bypassing the diffie-hellman computation? */
266
+ if (nofps) {
267
+ /* We sent y_l = 1, so y_SC is also 1. */
268
+ memset(&nonce_y[PCRYPT_NONCE_LEN * 2], 0,
269
+ CRYPTO_DH_KEYLEN - 1);
270
+ nonce_y[PCRYPT_NONCE_LEN * 2 + CRYPTO_DH_KEYLEN - 1] = 1;
271
+ } else {
272
+ /* Perform the diffie-hellman computation. */
273
+ if (crypto_dh_compute(yh_r, x,
274
+ &nonce_y[PCRYPT_NONCE_LEN * 2]))
275
+ goto err0;
276
+ }
277
+
278
+ /* Compute dk_2. */
279
+ PBKDF2_SHA256(K->K, 32, nonce_y,
280
+ PCRYPT_NONCE_LEN * 2 + CRYPTO_DH_KEYLEN, 1, dk_2, 128);
281
+
282
+ /* Create key structures. */
283
+ if ((*eh_c = mkkeypair(&dk_2[0])) == NULL)
284
+ goto err0;
285
+ if ((*eh_s = mkkeypair(&dk_2[64])) == NULL)
286
+ goto err1;
287
+
288
+ /* Success! */
289
+ return (0);
290
+
291
+ err1:
292
+ proto_crypt_free(*eh_c);
293
+ err0:
294
+ /* Failure! */
295
+ return (-1);
296
+ }
297
+
298
+ /**
299
+ * proto_crypt_enc(ibuf, len, obuf, k):
300
+ * Encrypt ${len} bytes from ${ibuf} into PCRYPT_ESZ bytes using the keys in
301
+ * ${k}, and write the result into ${obuf}.
302
+ */
303
+ void
304
+ proto_crypt_enc(uint8_t * ibuf, size_t len, uint8_t obuf[PCRYPT_ESZ],
305
+ struct proto_keys * k)
306
+ {
307
+ HMAC_SHA256_CTX ctx;
308
+ uint8_t pnum_exp[8];
309
+
310
+ /* Sanity-check the length. */
311
+ assert(len <= PCRYPT_MAXDSZ);
312
+
313
+ /* Copy the decrypted data into the encrypted buffer. */
314
+ memcpy(obuf, ibuf, len);
315
+
316
+ /* Pad up to PCRYPT_MAXDSZ with zeroes. */
317
+ memset(&obuf[len], 0, PCRYPT_MAXDSZ - len);
318
+
319
+ /* Add the length. */
320
+ be32enc(&obuf[PCRYPT_MAXDSZ], len);
321
+
322
+ /* Encrypt the buffer in-place. */
323
+ crypto_aesctr_buf(k->k_aes, k->pnum, obuf, obuf, PCRYPT_MAXDSZ + 4);
324
+
325
+ /* Append an HMAC. */
326
+ be64enc(pnum_exp, k->pnum);
327
+ HMAC_SHA256_Init(&ctx, k->k_hmac, 32);
328
+ HMAC_SHA256_Update(&ctx, obuf, PCRYPT_MAXDSZ + 4);
329
+ HMAC_SHA256_Update(&ctx, pnum_exp, 8);
330
+ HMAC_SHA256_Final(&obuf[PCRYPT_MAXDSZ + 4], &ctx);
331
+
332
+ /* Increment packet number. */
333
+ k->pnum += 1;
334
+ }
335
+
336
+ /**
337
+ * proto_crypt_dec(ibuf, obuf, k):
338
+ * Decrypt PCRYPT_ESZ bytes from ${ibuf} using the keys in ${k}. If the data
339
+ * is valid, write it into ${obuf} and return the length; otherwise, return
340
+ * -1.
341
+ */
342
+ ssize_t proto_crypt_dec(uint8_t ibuf[PCRYPT_ESZ], uint8_t * obuf,
343
+ struct proto_keys * k)
344
+ {
345
+ HMAC_SHA256_CTX ctx;
346
+ uint8_t hbuf[32];
347
+ uint8_t pnum_exp[8];
348
+ size_t len;
349
+
350
+ /* Verify HMAC. */
351
+ be64enc(pnum_exp, k->pnum);
352
+ HMAC_SHA256_Init(&ctx, k->k_hmac, 32);
353
+ HMAC_SHA256_Update(&ctx, ibuf, PCRYPT_MAXDSZ + 4);
354
+ HMAC_SHA256_Update(&ctx, pnum_exp, 8);
355
+ HMAC_SHA256_Final(hbuf, &ctx);
356
+ if (crypto_verify_bytes(hbuf, &ibuf[PCRYPT_MAXDSZ + 4], 32))
357
+ return (-1);
358
+
359
+ /* Decrypt the buffer in-place. */
360
+ crypto_aesctr_buf(k->k_aes, k->pnum, ibuf, ibuf, PCRYPT_MAXDSZ + 4);
361
+
362
+ /* Increment packet number. */
363
+ k->pnum += 1;
364
+
365
+ /* Parse length. */
366
+ len = be32dec(&ibuf[PCRYPT_MAXDSZ]);
367
+
368
+ /* Make sure nobody is being evil here... */
369
+ if ((len == 0) || (len > PCRYPT_MAXDSZ))
370
+ return (-1);
371
+
372
+ /* Copy the bytes into the output buffer. */
373
+ memcpy(obuf, ibuf, len);
374
+
375
+ /* Return the decrypted length. */
376
+ return (len);
377
+ }
378
+
379
+ /**
380
+ * proto_crypt_free(k):
381
+ * Free the protocol key structure ${k}.
382
+ */
383
+ void
384
+ proto_crypt_free(struct proto_keys * k)
385
+ {
386
+
387
+ /* Be compatible with free(NULL). */
388
+ if (k == NULL)
389
+ return;
390
+
391
+ /* Free the AES key. */
392
+ crypto_aes_key_free(k->k_aes);
393
+
394
+ /* Free the key structure. */
395
+ free(k);
396
+ }
@@ -0,0 +1,102 @@
1
+ #ifndef _PCRYPT_H_
2
+ #define _PCRYPT_H_
3
+
4
+ #include <stdint.h>
5
+ #include <unistd.h>
6
+
7
+ #include "crypto_dh.h"
8
+
9
+ struct proto_keys;
10
+ struct proto_secret;
11
+
12
+ /* Size of nonce. */
13
+ #define PCRYPT_NONCE_LEN 32
14
+
15
+ /* Size of temporary MAC keys used for Diffie-Hellman parameters. */
16
+ #define PCRYPT_DHMAC_LEN 32
17
+
18
+ /* Size of private Diffie-Hellman value. */
19
+ #define PCRYPT_X_LEN CRYPTO_DH_PRIVLEN
20
+
21
+ /* Size of MACed Diffie-Hellman parameter. */
22
+ #define PCRYPT_YH_LEN (CRYPTO_DH_PUBLEN + 32)
23
+
24
+ /**
25
+ * proto_crypt_secret(filename):
26
+ * Read the key file ${filename} and return a protocol secret structure.
27
+ */
28
+ struct proto_secret * proto_crypt_secret(const char *);
29
+
30
+ /**
31
+ * proto_crypt_dhmac(K, nonce_l, nonce_r, dhmac_l, dhmac_r, decr):
32
+ * Using the protocol secret ${K}, and the local and remote nonces ${nonce_l}
33
+ * and ${nonce_r}, compute the local and remote diffie-hellman parameter MAC
34
+ * keys ${dhmac_l} and ${dhmac_r}. If ${decr} is non-zero, "local" == "S"
35
+ * and "remote" == "C"; otherwise the assignments are opposite.
36
+ */
37
+ void proto_crypt_dhmac(const struct proto_secret *,
38
+ const uint8_t[PCRYPT_NONCE_LEN], const uint8_t[PCRYPT_NONCE_LEN],
39
+ uint8_t[PCRYPT_DHMAC_LEN], uint8_t[PCRYPT_DHMAC_LEN], int);
40
+
41
+ /**
42
+ * proto_crypt_dh_validate(yh_r, dhmac_r, requirefps):
43
+ * Return non-zero if the value ${yh_r} received from the remote party is not
44
+ * correctly MACed using the diffie-hellman parameter MAC key ${dhmac_r}, or
45
+ * if the included y value is >= the diffie-hellman group modulus, or if
46
+ * ${requirefps} is non-zero and the included y value is 1.
47
+ */
48
+ int proto_crypt_dh_validate(const uint8_t[PCRYPT_YH_LEN],
49
+ const uint8_t[PCRYPT_DHMAC_LEN], int);
50
+
51
+ /**
52
+ * proto_crypt_dh_generate(yh_l, x, dhmac_l, nofps):
53
+ * Using the MAC key ${dhmac_l}, generate the MACed diffie-hellman handshake
54
+ * parameter ${yh_l}. Store the diffie-hellman private value in ${x}. If
55
+ * ${nofps} is non-zero, skip diffie-hellman generation and use y = 1.
56
+ */
57
+ int proto_crypt_dh_generate(uint8_t[PCRYPT_YH_LEN], uint8_t[PCRYPT_X_LEN],
58
+ const uint8_t[PCRYPT_DHMAC_LEN], int);
59
+
60
+ /**
61
+ * proto_crypt_mkkeys(K, nonce_l, nonce_r, yh_r, x, nofps, decr, eh_c, eh_s):
62
+ * Using the protocol secret ${K}, the local and remote nonces ${nonce_l} and
63
+ * ${nonce_r}, the remote MACed diffie-hellman handshake parameter ${yh_r},
64
+ * and the local diffie-hellman secret ${x}, generate the keys ${eh_c} and
65
+ * ${eh_s}. If ${nofps} is non-zero, we are performing weak handshaking and
66
+ * y_SC is set to 1 rather than being computed. If ${decr} is non-zero,
67
+ * "local" == "S" and "remote" == "C"; otherwise the assignments are opposite.
68
+ */
69
+ int proto_crypt_mkkeys(const struct proto_secret *,
70
+ const uint8_t[PCRYPT_NONCE_LEN], const uint8_t[PCRYPT_NONCE_LEN],
71
+ const uint8_t[PCRYPT_YH_LEN], const uint8_t[PCRYPT_X_LEN], int, int,
72
+ struct proto_keys **, struct proto_keys **);
73
+
74
+ /* Maximum size of an unencrypted packet. */
75
+ #define PCRYPT_MAXDSZ 1024
76
+
77
+ /* Size of an encrypted packet. */
78
+ #define PCRYPT_ESZ (PCRYPT_MAXDSZ + 4 /* len */ + 32 /* hmac */)
79
+
80
+ /**
81
+ * proto_crypt_enc(ibuf, len, obuf, k):
82
+ * Encrypt ${len} bytes from ${ibuf} into PCRYPT_ESZ bytes using the keys in
83
+ * ${k}, and write the result into ${obuf}.
84
+ */
85
+ void proto_crypt_enc(uint8_t *, size_t, uint8_t[PCRYPT_ESZ],
86
+ struct proto_keys *);
87
+
88
+ /**
89
+ * proto_crypt_dec(ibuf, obuf, k):
90
+ * Decrypt PCRYPT_ESZ bytes from ${ibuf} using the keys in ${k}. If the data
91
+ * is valid, write it into ${obuf} and return the length; otherwise, return
92
+ * -1.
93
+ */
94
+ ssize_t proto_crypt_dec(uint8_t[PCRYPT_ESZ], uint8_t *, struct proto_keys *);
95
+
96
+ /**
97
+ * proto_crypt_free(k):
98
+ * Free the protocol key structure ${k}.
99
+ */
100
+ void proto_crypt_free(struct proto_keys *);
101
+
102
+ #endif /* !_PCRYPT_H_ */