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,229 @@
1
+ #include "cpusupport.h"
2
+ #ifdef CPUSUPPORT_X86_AESNI
3
+
4
+ #include <stdint.h>
5
+ #include <stdlib.h>
6
+ #include <string.h>
7
+ #include <wmmintrin.h>
8
+
9
+ #include "insecure_memzero.h"
10
+ #include "warnp.h"
11
+
12
+ #include "crypto_aes_aesni.h"
13
+
14
+ /* Expanded-key structure. */
15
+ struct crypto_aes_key_aesni {
16
+ __m128i rkeys[15];
17
+ size_t nr;
18
+ };
19
+
20
+ /* Compute an AES-128 round key. */
21
+ #define MKRKEY128(rkeys, i, rcon) do { \
22
+ __m128i _s = rkeys[i - 1]; \
23
+ __m128i _t = rkeys[i - 1]; \
24
+ _s = _mm_xor_si128(_s, _mm_slli_si128(_s, 4)); \
25
+ _s = _mm_xor_si128(_s, _mm_slli_si128(_s, 8)); \
26
+ _t = _mm_aeskeygenassist_si128(_t, rcon); \
27
+ _t = _mm_shuffle_epi32(_t, 0xff); \
28
+ rkeys[i] = _mm_xor_si128(_s, _t); \
29
+ } while (0)
30
+
31
+ /**
32
+ * crypto_aes_key_expand_128_aesni(key, rkeys):
33
+ * Expand the 128-bit AES key ${key} into the 11 round keys ${rkeys}. This
34
+ * implementation uses x86 AESNI instructions, and should only be used if
35
+ * CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero.
36
+ */
37
+ static void
38
+ crypto_aes_key_expand_128_aesni(const uint8_t key[16], __m128i rkeys[11])
39
+ {
40
+
41
+ /* The first round key is just the key. */
42
+ /**
43
+ * XXX Compiler breakage:
44
+ * The intrinsic defined by Intel for _mm_loadu_si128 defines it as
45
+ * taking a (const __m128i *) parameter. This forces us to write a
46
+ * bug: The cast to (const __m128i *) is invalid since it increases
47
+ * the alignment requirement of the pointer. Alas, until compilers
48
+ * get fixed intrinsics, all we can do is code the bug and require
49
+ * that alignment-requirement-increasing compiler warnings get
50
+ * disabled.
51
+ */
52
+ rkeys[0] = _mm_loadu_si128((const __m128i *)&key[0]);
53
+
54
+ /*
55
+ * Each of the remaining round keys are computed from the preceding
56
+ * round key: rotword+subword+rcon (provided as aeskeygenassist) to
57
+ * compute the 'temp' value, then xor with 1, 2, 3, or all 4 of the
58
+ * 32-bit words from the preceding round key. Unfortunately, 'rcon'
59
+ * is encoded as an immediate value, so we need to write the loop out
60
+ * ourselves rather than allowing the compiler to expand it.
61
+ */
62
+ MKRKEY128(rkeys, 1, 0x01);
63
+ MKRKEY128(rkeys, 2, 0x02);
64
+ MKRKEY128(rkeys, 3, 0x04);
65
+ MKRKEY128(rkeys, 4, 0x08);
66
+ MKRKEY128(rkeys, 5, 0x10);
67
+ MKRKEY128(rkeys, 6, 0x20);
68
+ MKRKEY128(rkeys, 7, 0x40);
69
+ MKRKEY128(rkeys, 8, 0x80);
70
+ MKRKEY128(rkeys, 9, 0x1b);
71
+ MKRKEY128(rkeys, 10, 0x36);
72
+ }
73
+
74
+ /* Compute an AES-256 round key. */
75
+ #define MKRKEY256(rkeys, i, shuffle, rcon) do { \
76
+ __m128i _s = rkeys[i - 2]; \
77
+ __m128i _t = rkeys[i - 1]; \
78
+ _s = _mm_xor_si128(_s, _mm_slli_si128(_s, 4)); \
79
+ _s = _mm_xor_si128(_s, _mm_slli_si128(_s, 8)); \
80
+ _t = _mm_aeskeygenassist_si128(_t, rcon); \
81
+ _t = _mm_shuffle_epi32(_t, shuffle); \
82
+ rkeys[i] = _mm_xor_si128(_s, _t); \
83
+ } while (0)
84
+
85
+ /**
86
+ * crypto_aes_key_expand_256_aesni(key, rkeys):
87
+ * Expand the 256-bit AES key ${key} into the 15 round keys ${rkeys}. This
88
+ * implementation uses x86 AESNI instructions, and should only be used if
89
+ * CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero.
90
+ */
91
+ static void
92
+ crypto_aes_key_expand_256_aesni(const uint8_t key[32], __m128i rkeys[15])
93
+ {
94
+
95
+ /* The first two round keys are just the key. */
96
+ /**
97
+ * XXX Compiler breakage:
98
+ * The intrinsic defined by Intel for _mm_loadu_si128 defines it as
99
+ * taking a (const __m128i *) parameter. This forces us to write a
100
+ * bug: The cast to (const __m128i *) is invalid since it increases
101
+ * the alignment requirement of the pointer. Alas, until compilers
102
+ * get fixed intrinsics, all we can do is code the bug and require
103
+ * that alignment-requirement-increasing compiler warnings get
104
+ * disabled.
105
+ */
106
+ rkeys[0] = _mm_loadu_si128((const __m128i *)&key[0]);
107
+ rkeys[1] = _mm_loadu_si128((const __m128i *)&key[16]);
108
+
109
+ /*
110
+ * Each of the remaining round keys are computed from the preceding
111
+ * pair of keys. Even rounds use rotword+subword+rcon, while odd
112
+ * rounds just use subword; the aeskeygenassist instruction computes
113
+ * both, and we use 0xff or 0xaa to select the one we need. The rcon
114
+ * value used is irrelevant for odd rounds since we ignore the value
115
+ * which it feeds into. Unfortunately, the 'shuffle' and 'rcon'
116
+ * values are encoded into the instructions as immediates, so we need
117
+ * to write the loop out ourselves rather than allowing the compiler
118
+ * to expand it.
119
+ */
120
+ MKRKEY256(rkeys, 2, 0xff, 0x01);
121
+ MKRKEY256(rkeys, 3, 0xaa, 0x00);
122
+ MKRKEY256(rkeys, 4, 0xff, 0x02);
123
+ MKRKEY256(rkeys, 5, 0xaa, 0x00);
124
+ MKRKEY256(rkeys, 6, 0xff, 0x04);
125
+ MKRKEY256(rkeys, 7, 0xaa, 0x00);
126
+ MKRKEY256(rkeys, 8, 0xff, 0x08);
127
+ MKRKEY256(rkeys, 9, 0xaa, 0x00);
128
+ MKRKEY256(rkeys, 10, 0xff, 0x10);
129
+ MKRKEY256(rkeys, 11, 0xaa, 0x00);
130
+ MKRKEY256(rkeys, 12, 0xff, 0x20);
131
+ MKRKEY256(rkeys, 13, 0xaa, 0x00);
132
+ MKRKEY256(rkeys, 14, 0xff, 0x40);
133
+ }
134
+
135
+ /**
136
+ * crypto_aes_key_expand_aesni(key, len):
137
+ * Expand the ${len}-byte AES key ${key} into a structure which can be passed
138
+ * to crypto_aes_encrypt_block_aesni. The length must be 16 or 32. This
139
+ * implementation uses x86 AESNI instructions, and should only be used if
140
+ * CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero.
141
+ */
142
+ void *
143
+ crypto_aes_key_expand_aesni(const uint8_t * key, size_t len)
144
+ {
145
+ struct crypto_aes_key_aesni * kexp;
146
+
147
+ /* Allocate structure. */
148
+ if ((kexp = malloc(sizeof(struct crypto_aes_key_aesni))) == NULL)
149
+ goto err0;
150
+
151
+ /* Compute round keys. */
152
+ if (len == 16) {
153
+ kexp->nr = 10;
154
+ crypto_aes_key_expand_128_aesni(key, kexp->rkeys);
155
+ } else if (len == 32) {
156
+ kexp->nr = 14;
157
+ crypto_aes_key_expand_256_aesni(key, kexp->rkeys);
158
+ } else {
159
+ warn0("Unsupported AES key length: %zu bytes", len);
160
+ goto err1;
161
+ }
162
+
163
+ /* Success! */
164
+ return (kexp);
165
+
166
+ err1:
167
+ free(kexp);
168
+ err0:
169
+ /* Failure! */
170
+ return (NULL);
171
+ }
172
+
173
+ /**
174
+ * crypto_aes_encrypt_block_aesni(in, out, key):
175
+ * Using the expanded AES key ${key}, encrypt the block ${in} and write the
176
+ * resulting ciphertext to ${out}. This implementation uses x86 AESNI
177
+ * instructions, and should only be used if CPUSUPPORT_X86_AESNI is defined
178
+ * and cpusupport_x86_aesni() returns nonzero.
179
+ */
180
+ void
181
+ crypto_aes_encrypt_block_aesni(const uint8_t * in, uint8_t * out,
182
+ const void * key)
183
+ {
184
+ const struct crypto_aes_key_aesni * _key = key;
185
+ const __m128i * aes_key = _key->rkeys;
186
+ __m128i aes_state;
187
+ size_t nr = _key->nr;
188
+
189
+ aes_state = _mm_loadu_si128((const __m128i *)in);
190
+ aes_state = _mm_xor_si128(aes_state, aes_key[0]);
191
+ aes_state = _mm_aesenc_si128(aes_state, aes_key[1]);
192
+ aes_state = _mm_aesenc_si128(aes_state, aes_key[2]);
193
+ aes_state = _mm_aesenc_si128(aes_state, aes_key[3]);
194
+ aes_state = _mm_aesenc_si128(aes_state, aes_key[4]);
195
+ aes_state = _mm_aesenc_si128(aes_state, aes_key[5]);
196
+ aes_state = _mm_aesenc_si128(aes_state, aes_key[6]);
197
+ aes_state = _mm_aesenc_si128(aes_state, aes_key[7]);
198
+ aes_state = _mm_aesenc_si128(aes_state, aes_key[8]);
199
+ aes_state = _mm_aesenc_si128(aes_state, aes_key[9]);
200
+ if (nr > 10) {
201
+ aes_state = _mm_aesenc_si128(aes_state, aes_key[10]);
202
+ aes_state = _mm_aesenc_si128(aes_state, aes_key[11]);
203
+
204
+ if (nr > 12) {
205
+ aes_state = _mm_aesenc_si128(aes_state, aes_key[12]);
206
+ aes_state = _mm_aesenc_si128(aes_state, aes_key[13]);
207
+ }
208
+ }
209
+
210
+ aes_state = _mm_aesenclast_si128(aes_state, aes_key[nr]);
211
+ _mm_storeu_si128((__m128i *)out, aes_state);
212
+ }
213
+
214
+ /**
215
+ * crypto_aes_key_free_aesni(key):
216
+ * Free the expanded AES key ${key}.
217
+ */
218
+ void
219
+ crypto_aes_key_free_aesni(void * key)
220
+ {
221
+
222
+ /* Attempt to zero the expanded key. */
223
+ insecure_memzero(key, sizeof(struct crypto_aes_key_aesni));
224
+
225
+ /* Free the key. */
226
+ free(key);
227
+ }
228
+
229
+ #endif /* CPUSUPPORT_X86_AESNI */
@@ -0,0 +1,31 @@
1
+ #ifndef _CRYPTO_AES_AESNI_H_
2
+ #define _CRYPTO_AES_AESNI_H_
3
+
4
+ #include <stddef.h>
5
+ #include <stdint.h>
6
+
7
+ /**
8
+ * crypto_aes_key_expand_aesni(key, len):
9
+ * Expand the ${len}-byte AES key ${key} into a structure which can be passed
10
+ * to crypto_aes_encrypt_block_aesni. The length must be 16 or 32. This
11
+ * implementation uses x86 AESNI instructions, and should only be used if
12
+ * CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero.
13
+ */
14
+ void * crypto_aes_key_expand_aesni(const uint8_t *, size_t);
15
+
16
+ /**
17
+ * crypto_aes_encrypt_block_aesni(in, out, key):
18
+ * Using the expanded AES key ${key}, encrypt the block ${in} and write the
19
+ * resulting ciphertext to ${out}. This implementation uses x86 AESNI
20
+ * instructions, and should only be used if CPUSUPPORT_X86_AESNI is defined
21
+ * and cpusupport_x86_aesni() returns nonzero.
22
+ */
23
+ void crypto_aes_encrypt_block_aesni(const uint8_t *, uint8_t *, const void *);
24
+
25
+ /**
26
+ * crypto_aes_key_free_aesni(key):
27
+ * Free the expanded AES key ${key}.
28
+ */
29
+ void crypto_aes_key_free_aesni(void *);
30
+
31
+ #endif /* !_CRYPTO_AES_AESNI_H_ */
@@ -0,0 +1,124 @@
1
+ #include <stdint.h>
2
+ #include <stdlib.h>
3
+
4
+ #include "crypto_aes.h"
5
+ #include "sysendian.h"
6
+
7
+ #include "crypto_aesctr.h"
8
+
9
+ struct crypto_aesctr {
10
+ const struct crypto_aes_key * key;
11
+ uint64_t nonce;
12
+ uint64_t bytectr;
13
+ uint8_t buf[16];
14
+ };
15
+
16
+ /**
17
+ * crypto_aesctr_init(key, nonce):
18
+ * Prepare to encrypt/decrypt data with AES in CTR mode, using the provided
19
+ * expanded key and nonce. The key provided must remain valid for the
20
+ * lifetime of the stream.
21
+ */
22
+ struct crypto_aesctr *
23
+ crypto_aesctr_init(const struct crypto_aes_key * key, uint64_t nonce)
24
+ {
25
+ struct crypto_aesctr * stream;
26
+
27
+ /* Allocate memory. */
28
+ if ((stream = malloc(sizeof(struct crypto_aesctr))) == NULL)
29
+ goto err0;
30
+
31
+ /* Initialize values. */
32
+ stream->key = key;
33
+ stream->nonce = nonce;
34
+ stream->bytectr = 0;
35
+
36
+ /* Success! */
37
+ return (stream);
38
+
39
+ err0:
40
+ /* Failure! */
41
+ return (NULL);
42
+ }
43
+
44
+ /**
45
+ * crypto_aesctr_stream(stream, inbuf, outbuf, buflen):
46
+ * Generate the next ${buflen} bytes of the AES-CTR stream and xor them with
47
+ * bytes from ${inbuf}, writing the result into ${outbuf}. If the buffers
48
+ * ${inbuf} and ${outbuf} overlap, they must be identical.
49
+ */
50
+ void
51
+ crypto_aesctr_stream(struct crypto_aesctr * stream, const uint8_t * inbuf,
52
+ uint8_t * outbuf, size_t buflen)
53
+ {
54
+ uint8_t pblk[16];
55
+ size_t pos;
56
+ int bytemod;
57
+
58
+ for (pos = 0; pos < buflen; pos++) {
59
+ /* How far through the buffer are we? */
60
+ bytemod = stream->bytectr % 16;
61
+
62
+ /* Generate a block of cipherstream if needed. */
63
+ if (bytemod == 0) {
64
+ be64enc(pblk, stream->nonce);
65
+ be64enc(pblk + 8, stream->bytectr / 16);
66
+ crypto_aes_encrypt_block(pblk, stream->buf,
67
+ stream->key);
68
+ }
69
+
70
+ /* Encrypt a byte. */
71
+ outbuf[pos] = inbuf[pos] ^ stream->buf[bytemod];
72
+
73
+ /* Move to the next byte of cipherstream. */
74
+ stream->bytectr += 1;
75
+ }
76
+ }
77
+
78
+ /**
79
+ * crypto_aesctr_free(stream):
80
+ * Free the provided stream object.
81
+ */
82
+ void
83
+ crypto_aesctr_free(struct crypto_aesctr * stream)
84
+ {
85
+ int i;
86
+
87
+ /* Be compatible with free(NULL). */
88
+ if (stream == NULL)
89
+ return;
90
+
91
+ /* Zero potentially sensitive information. */
92
+ for (i = 0; i < 16; i++)
93
+ stream->buf[i] = 0;
94
+ stream->bytectr = stream->nonce = 0;
95
+
96
+ /* Free the stream. */
97
+ free(stream);
98
+ }
99
+
100
+ /**
101
+ * crypto_aesctr_buf(key, nonce, inbuf, outbuf, buflen):
102
+ * Equivalent to init(key, nonce); stream(inbuf, outbuf, buflen); free.
103
+ */
104
+ void
105
+ crypto_aesctr_buf(const struct crypto_aes_key * key, uint64_t nonce,
106
+ const uint8_t * inbuf, uint8_t * outbuf, size_t buflen)
107
+ {
108
+ struct crypto_aesctr stream_rec;
109
+ struct crypto_aesctr * stream = &stream_rec;
110
+ int i;
111
+
112
+ /* Initialize values. */
113
+ stream->key = key;
114
+ stream->nonce = nonce;
115
+ stream->bytectr = 0;
116
+
117
+ /* Perform the encryption. */
118
+ crypto_aesctr_stream(stream, inbuf, outbuf, buflen);
119
+
120
+ /* Zero potentially sensitive information. */
121
+ for (i = 0; i < 16; i++)
122
+ stream->buf[i] = 0;
123
+ stream->bytectr = stream->nonce = 0;
124
+ }
@@ -0,0 +1,41 @@
1
+ #ifndef _CRYPTO_AESCTR_H_
2
+ #define _CRYPTO_AESCTR_H_
3
+
4
+ #include <stddef.h>
5
+ #include <stdint.h>
6
+
7
+ /* Opaque type. */
8
+ struct crypto_aes_key;
9
+
10
+ /**
11
+ * crypto_aesctr_init(key, nonce):
12
+ * Prepare to encrypt/decrypt data with AES in CTR mode, using the provided
13
+ * expanded key and nonce. The key provided must remain valid for the
14
+ * lifetime of the stream.
15
+ */
16
+ struct crypto_aesctr * crypto_aesctr_init(const struct crypto_aes_key *,
17
+ uint64_t);
18
+
19
+ /**
20
+ * crypto_aesctr_stream(stream, inbuf, outbuf, buflen):
21
+ * Generate the next ${buflen} bytes of the AES-CTR stream and xor them with
22
+ * bytes from ${inbuf}, writing the result into ${outbuf}. If the buffers
23
+ * ${inbuf} and ${outbuf} overlap, they must be identical.
24
+ */
25
+ void crypto_aesctr_stream(struct crypto_aesctr *, const uint8_t *,
26
+ uint8_t *, size_t);
27
+
28
+ /**
29
+ * crypto_aesctr_free(stream):
30
+ * Free the provided stream object.
31
+ */
32
+ void crypto_aesctr_free(struct crypto_aesctr *);
33
+
34
+ /**
35
+ * crypto_aesctr_buf(key, nonce, inbuf, outbuf, buflen):
36
+ * Equivalent to init(key, nonce); stream(inbuf, outbuf, buflen); free.
37
+ */
38
+ void crypto_aesctr_buf(const struct crypto_aes_key *, uint64_t,
39
+ const uint8_t *, uint8_t *, size_t);
40
+
41
+ #endif /* !_CRYPTO_AESCTR_H_ */
@@ -0,0 +1,293 @@
1
+ #include <stdint.h>
2
+ #include <string.h>
3
+
4
+ #include <openssl/bn.h>
5
+ #include <openssl/err.h>
6
+
7
+ #include "warnp.h"
8
+
9
+ #include "crypto_entropy.h"
10
+ #include "crypto_dh_group14.h"
11
+
12
+ #include "crypto_dh.h"
13
+
14
+ static int blinded_modexp(uint8_t r[CRYPTO_DH_PUBLEN], BIGNUM * a,
15
+ const uint8_t priv[CRYPTO_DH_PRIVLEN]);
16
+
17
+ /* Big-endian representation of 2^256. */
18
+ static uint8_t two_exp_256[] = {
19
+ 0x01,
20
+ 0x00, 0x00, 0x00, 0x00,
21
+ 0x00, 0x00, 0x00, 0x00,
22
+ 0x00, 0x00, 0x00, 0x00,
23
+ 0x00, 0x00, 0x00, 0x00,
24
+ 0x00, 0x00, 0x00, 0x00,
25
+ 0x00, 0x00, 0x00, 0x00,
26
+ 0x00, 0x00, 0x00, 0x00,
27
+ 0x00, 0x00, 0x00, 0x00
28
+ };
29
+
30
+ /**
31
+ * blinded_modexp(r, a, priv):
32
+ * Compute ${r} = ${a}^(2^258 + ${priv}), where ${r} and ${priv} are treated
33
+ * as big-endian integers; and avoid leaking timing data in this process.
34
+ */
35
+ static int
36
+ blinded_modexp(uint8_t r[CRYPTO_DH_PUBLEN], BIGNUM * a,
37
+ const uint8_t priv[CRYPTO_DH_PRIVLEN])
38
+ {
39
+ BIGNUM * two_exp_256_bn;
40
+ BIGNUM * priv_bn;
41
+ uint8_t blinding[CRYPTO_DH_PRIVLEN];
42
+ BIGNUM * blinding_bn;
43
+ BIGNUM * priv_blinded;
44
+ BIGNUM * m_bn;
45
+ BN_CTX * ctx;
46
+ BIGNUM * r1;
47
+ BIGNUM * r2;
48
+ size_t rlen;
49
+
50
+ /* Construct 2^256 in BN representation. */
51
+ if ((two_exp_256_bn = BN_bin2bn(two_exp_256, 33, NULL)) == NULL) {
52
+ warn0("%s", ERR_error_string(ERR_get_error(), NULL));
53
+ goto err0;
54
+ }
55
+
56
+ /* Construct 2^258 + ${priv} in BN representation. */
57
+ if ((priv_bn = BN_bin2bn(priv, CRYPTO_DH_PRIVLEN, NULL)) == NULL) {
58
+ warn0("%s", ERR_error_string(ERR_get_error(), NULL));
59
+ goto err1;
60
+ }
61
+ if ((!BN_add(priv_bn, priv_bn, two_exp_256_bn)) ||
62
+ (!BN_add(priv_bn, priv_bn, two_exp_256_bn)) ||
63
+ (!BN_add(priv_bn, priv_bn, two_exp_256_bn)) ||
64
+ (!BN_add(priv_bn, priv_bn, two_exp_256_bn))) {
65
+ warn0("%s", ERR_error_string(ERR_get_error(), NULL));
66
+ goto err2;
67
+ }
68
+
69
+ /* Generate blinding exponent. */
70
+ if (crypto_entropy_read(blinding, CRYPTO_DH_PRIVLEN))
71
+ goto err2;
72
+ if ((blinding_bn = BN_bin2bn(blinding,
73
+ CRYPTO_DH_PRIVLEN, NULL)) == NULL) {
74
+ warn0("%s", ERR_error_string(ERR_get_error(), NULL));
75
+ goto err2;
76
+ }
77
+ if (!BN_add(blinding_bn, blinding_bn, two_exp_256_bn)) {
78
+ warn0("%s", ERR_error_string(ERR_get_error(), NULL));
79
+ goto err3;
80
+ }
81
+
82
+ /* Generate blinded exponent. */
83
+ if ((priv_blinded = BN_new()) == NULL) {
84
+ warn0("%s", ERR_error_string(ERR_get_error(), NULL));
85
+ goto err3;
86
+ }
87
+ if (!BN_sub(priv_blinded, priv_bn, blinding_bn)) {
88
+ warn0("%s", ERR_error_string(ERR_get_error(), NULL));
89
+ goto err4;
90
+ }
91
+
92
+ /* Construct group #14 modulus in BN representation. */
93
+ if ((m_bn = BN_bin2bn(crypto_dh_group14, 256, NULL)) == NULL) {
94
+ warn0("%s", ERR_error_string(ERR_get_error(), NULL));
95
+ goto err4;
96
+ }
97
+
98
+ /* Allocate BN context. */
99
+ if ((ctx = BN_CTX_new()) == NULL) {
100
+ warn0("%s", ERR_error_string(ERR_get_error(), NULL));
101
+ goto err5;
102
+ }
103
+
104
+ /* Allocate space for storing results of exponentiations. */
105
+ if ((r1 = BN_new()) == NULL) {
106
+ warn0("%s", ERR_error_string(ERR_get_error(), NULL));
107
+ goto err6;
108
+ }
109
+ if ((r2 = BN_new()) == NULL) {
110
+ warn0("%s", ERR_error_string(ERR_get_error(), NULL));
111
+ goto err7;
112
+ }
113
+
114
+ /* Perform modular exponentiations. */
115
+ if (!BN_mod_exp(r1, a, blinding_bn, m_bn, ctx)) {
116
+ warn0("%s", ERR_error_string(ERR_get_error(), NULL));
117
+ goto err8;
118
+ }
119
+ if (!BN_mod_exp(r2, a, priv_blinded, m_bn, ctx)) {
120
+ warn0("%s", ERR_error_string(ERR_get_error(), NULL));
121
+ goto err8;
122
+ }
123
+
124
+ /* Compute final result and export to big-endian integer format. */
125
+ if (!BN_mod_mul(r1, r1, r2, m_bn, ctx)) {
126
+ warn0("%s", ERR_error_string(ERR_get_error(), NULL));
127
+ goto err8;
128
+ }
129
+ rlen = BN_num_bytes(r1);
130
+ if (rlen > CRYPTO_DH_PUBLEN) {
131
+ warn0("Exponent result too large!");
132
+ goto err8;
133
+ }
134
+ memset(r, 0, CRYPTO_DH_PUBLEN - rlen);
135
+ BN_bn2bin(r1, r + CRYPTO_DH_PUBLEN - rlen);
136
+
137
+ /* Free space allocated by BN_new. */
138
+ BN_clear_free(r2);
139
+ BN_clear_free(r1);
140
+
141
+ /* Free context allocated by BN_CTX_new. */
142
+ BN_CTX_free(ctx);
143
+
144
+ /* Free space allocated by BN_bin2bn. */
145
+ BN_free(m_bn);
146
+
147
+ /* Free space allocated by BN_new. */
148
+ BN_clear_free(priv_blinded);
149
+
150
+ /* Free space allocated by BN_bin2bn. */
151
+ BN_clear_free(blinding_bn);
152
+ BN_clear_free(priv_bn);
153
+ BN_free(two_exp_256_bn);
154
+
155
+ /* Success! */
156
+ return (0);
157
+
158
+ err8:
159
+ BN_clear_free(r2);
160
+ err7:
161
+ BN_clear_free(r1);
162
+ err6:
163
+ BN_CTX_free(ctx);
164
+ err5:
165
+ BN_free(m_bn);
166
+ err4:
167
+ BN_clear_free(priv_blinded);
168
+ err3:
169
+ BN_clear_free(blinding_bn);
170
+ err2:
171
+ BN_clear_free(priv_bn);
172
+ err1:
173
+ BN_free(two_exp_256_bn);
174
+ err0:
175
+ /* Failure! */
176
+ return (-1);
177
+ }
178
+
179
+ /**
180
+ * crypto_dh_generate_pub(pub, priv):
181
+ * Compute ${pub} equal to 2^(2^258 + ${priv}) in Diffie-Hellman group #14.
182
+ */
183
+ int
184
+ crypto_dh_generate_pub(uint8_t pub[CRYPTO_DH_PUBLEN],
185
+ const uint8_t priv[CRYPTO_DH_PRIVLEN])
186
+ {
187
+ BIGNUM * two;
188
+
189
+ /* Generate BN representation for 2. */
190
+ if ((two = BN_new()) == NULL) {
191
+ warn0("%s", ERR_error_string(ERR_get_error(), NULL));
192
+ goto err0;
193
+ }
194
+ if (!BN_set_word(two, 2)) {
195
+ warn0("%s", ERR_error_string(ERR_get_error(), NULL));
196
+ goto err1;
197
+ }
198
+
199
+ /* Compute pub = two^(2^258 + priv). */
200
+ if (blinded_modexp(pub, two, priv))
201
+ goto err1;
202
+
203
+ /* Free storage allocated by BN_new. */
204
+ BN_free(two);
205
+
206
+ /* Success! */
207
+ return (0);
208
+
209
+ err1:
210
+ BN_free(two);
211
+ err0:
212
+ /* Failure! */
213
+ return (-1);
214
+ }
215
+
216
+ /**
217
+ * crypto_dh_generate(pub, priv):
218
+ * Generate a 256-bit private key ${priv}, and compute ${pub} equal to
219
+ * 2^(2^258 + ${priv}) mod p where p is the Diffie-Hellman group #14 modulus.
220
+ * Both values are stored as big-endian integers.
221
+ */
222
+ int
223
+ crypto_dh_generate(uint8_t pub[CRYPTO_DH_PUBLEN],
224
+ uint8_t priv[CRYPTO_DH_PRIVLEN])
225
+ {
226
+
227
+ /* Generate a random private key. */
228
+ if (crypto_entropy_read(priv, CRYPTO_DH_PRIVLEN))
229
+ goto err0;
230
+
231
+ /* Compute the public key. */
232
+ if (crypto_dh_generate_pub(pub, priv))
233
+ goto err0;
234
+
235
+ /* Success! */
236
+ return (0);
237
+
238
+ err0:
239
+ /* Failure! */
240
+ return (-1);
241
+ }
242
+
243
+ /**
244
+ * crypto_dh_compute(pub, priv, key):
245
+ * In the Diffie-Hellman group #14, compute ${pub}^(2^258 + ${priv}) and
246
+ * write the result into ${key}. All values are big-endian. Note that the
247
+ * value ${pub} is the public key produced by the call to crypto_dh_generate
248
+ * made by the *other* participant in the key exchange.
249
+ */
250
+ int
251
+ crypto_dh_compute(const uint8_t pub[CRYPTO_DH_PUBLEN],
252
+ const uint8_t priv[CRYPTO_DH_PRIVLEN], uint8_t key[CRYPTO_DH_KEYLEN])
253
+ {
254
+ BIGNUM * a;
255
+
256
+ /* Convert ${pub} into BN representation. */
257
+ if ((a = BN_bin2bn(pub, CRYPTO_DH_PUBLEN, NULL)) == NULL) {
258
+ warn0("%s", ERR_error_string(ERR_get_error(), NULL));
259
+ goto err0;
260
+ }
261
+
262
+ /* Compute key = pub^(2^258 + priv). */
263
+ if (blinded_modexp(key, a, priv))
264
+ goto err1;
265
+
266
+ /* Free storage allocated by BN_bin2bn. */
267
+ BN_free(a);
268
+
269
+ /* Success! */
270
+ return (0);
271
+
272
+ err1:
273
+ BN_free(a);
274
+ err0:
275
+ /* Failure! */
276
+ return (-1);
277
+ }
278
+
279
+ /**
280
+ * crypto_dh_sanitycheck(pub):
281
+ * Sanity-check the Diffie-Hellman public value ${pub} by checking that it
282
+ * is less than the group #14 modulus. Return 0 if sane, -1 if insane.
283
+ */
284
+ int
285
+ crypto_dh_sanitycheck(const uint8_t pub[CRYPTO_DH_PUBLEN])
286
+ {
287
+
288
+ if (memcmp(pub, crypto_dh_group14, 256) >= 0)
289
+ return (-1);
290
+
291
+ /* Value is sane. */
292
+ return (0);
293
+ }