spiped 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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_ */