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.
- checksums.yaml +7 -0
- data/ext/spiped/extconf.rb +3 -0
- data/ext/spiped/spiped-source/BUILDING +46 -0
- data/ext/spiped/spiped-source/CHANGELOG +44 -0
- data/ext/spiped/spiped-source/COPYRIGHT +33 -0
- data/ext/spiped/spiped-source/Makefile +47 -0
- data/ext/spiped/spiped-source/Makefile.POSIX +27 -0
- data/ext/spiped/spiped-source/Makefile.inc +20 -0
- data/ext/spiped/spiped-source/Makefile.prog +23 -0
- data/ext/spiped/spiped-source/POSIX/README +10 -0
- data/ext/spiped/spiped-source/POSIX/posix-cflags.sh +10 -0
- data/ext/spiped/spiped-source/POSIX/posix-clock_realtime.c +3 -0
- data/ext/spiped/spiped-source/POSIX/posix-l.c +1 -0
- data/ext/spiped/spiped-source/POSIX/posix-l.sh +14 -0
- data/ext/spiped/spiped-source/POSIX/posix-msg_nosignal.c +3 -0
- data/ext/spiped/spiped-source/README +198 -0
- data/ext/spiped/spiped-source/STYLE +151 -0
- data/ext/spiped/spiped-source/lib/dnsthread/dnsthread.c +464 -0
- data/ext/spiped/spiped-source/lib/dnsthread/dnsthread.h +45 -0
- data/ext/spiped/spiped-source/libcperciva/alg/sha256.c +442 -0
- data/ext/spiped/spiped-source/libcperciva/alg/sha256.h +95 -0
- data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport-X86-AESNI.c +13 -0
- data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport-X86-CPUID.c +8 -0
- data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport.sh +37 -0
- data/ext/spiped/spiped-source/libcperciva/cpusupport/cpusupport.h +63 -0
- data/ext/spiped/spiped-source/libcperciva/cpusupport/cpusupport_x86_aesni.c +30 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes.c +166 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes.h +31 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes_aesni.c +229 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes_aesni.h +31 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aesctr.c +124 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aesctr.h +41 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh.c +293 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh.h +43 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh_group14.c +46 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh_group14.h +9 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_entropy.c +215 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_entropy.h +14 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_verify_bytes.c +21 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_verify_bytes.h +14 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/elasticarray.c +276 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/elasticarray.h +167 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/mpool.h +85 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/ptrheap.c +334 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/ptrheap.h +89 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/timerqueue.c +241 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/timerqueue.h +60 -0
- data/ext/spiped/spiped-source/libcperciva/events/events.c +203 -0
- data/ext/spiped/spiped-source/libcperciva/events/events.h +106 -0
- data/ext/spiped/spiped-source/libcperciva/events/events_immediate.c +149 -0
- data/ext/spiped/spiped-source/libcperciva/events/events_internal.h +95 -0
- data/ext/spiped/spiped-source/libcperciva/events/events_network.c +347 -0
- data/ext/spiped/spiped-source/libcperciva/events/events_network_selectstats.c +106 -0
- data/ext/spiped/spiped-source/libcperciva/events/events_timer.c +273 -0
- data/ext/spiped/spiped-source/libcperciva/network/network.h +95 -0
- data/ext/spiped/spiped-source/libcperciva/network/network_accept.c +103 -0
- data/ext/spiped/spiped-source/libcperciva/network/network_connect.c +258 -0
- data/ext/spiped/spiped-source/libcperciva/network/network_read.c +155 -0
- data/ext/spiped/spiped-source/libcperciva/network/network_write.c +188 -0
- data/ext/spiped/spiped-source/libcperciva/util/asprintf.c +49 -0
- data/ext/spiped/spiped-source/libcperciva/util/asprintf.h +16 -0
- data/ext/spiped/spiped-source/libcperciva/util/daemonize.c +134 -0
- data/ext/spiped/spiped-source/libcperciva/util/daemonize.h +10 -0
- data/ext/spiped/spiped-source/libcperciva/util/entropy.c +76 -0
- data/ext/spiped/spiped-source/libcperciva/util/entropy.h +13 -0
- data/ext/spiped/spiped-source/libcperciva/util/imalloc.h +33 -0
- data/ext/spiped/spiped-source/libcperciva/util/insecure_memzero.c +19 -0
- data/ext/spiped/spiped-source/libcperciva/util/insecure_memzero.h +33 -0
- data/ext/spiped/spiped-source/libcperciva/util/monoclock.c +52 -0
- data/ext/spiped/spiped-source/libcperciva/util/monoclock.h +14 -0
- data/ext/spiped/spiped-source/libcperciva/util/noeintr.c +54 -0
- data/ext/spiped/spiped-source/libcperciva/util/noeintr.h +14 -0
- data/ext/spiped/spiped-source/libcperciva/util/sock.c +472 -0
- data/ext/spiped/spiped-source/libcperciva/util/sock.h +56 -0
- data/ext/spiped/spiped-source/libcperciva/util/sock_internal.h +14 -0
- data/ext/spiped/spiped-source/libcperciva/util/sock_util.c +271 -0
- data/ext/spiped/spiped-source/libcperciva/util/sock_util.h +51 -0
- data/ext/spiped/spiped-source/libcperciva/util/sysendian.h +146 -0
- data/ext/spiped/spiped-source/libcperciva/util/warnp.c +76 -0
- data/ext/spiped/spiped-source/libcperciva/util/warnp.h +59 -0
- data/ext/spiped/spiped-source/proto/proto_conn.c +362 -0
- data/ext/spiped/spiped-source/proto/proto_conn.h +25 -0
- data/ext/spiped/spiped-source/proto/proto_crypt.c +396 -0
- data/ext/spiped/spiped-source/proto/proto_crypt.h +102 -0
- data/ext/spiped/spiped-source/proto/proto_handshake.c +330 -0
- data/ext/spiped/spiped-source/proto/proto_handshake.h +30 -0
- data/ext/spiped/spiped-source/proto/proto_pipe.c +202 -0
- data/ext/spiped/spiped-source/proto/proto_pipe.h +23 -0
- data/ext/spiped/spiped-source/spipe/Makefile +90 -0
- data/ext/spiped/spiped-source/spipe/README +24 -0
- data/ext/spiped/spiped-source/spipe/main.c +178 -0
- data/ext/spiped/spiped-source/spipe/pushbits.c +101 -0
- data/ext/spiped/spiped-source/spipe/pushbits.h +10 -0
- data/ext/spiped/spiped-source/spipe/spipe.1 +60 -0
- data/ext/spiped/spiped-source/spiped/Makefile +98 -0
- data/ext/spiped/spiped-source/spiped/README +62 -0
- data/ext/spiped/spiped-source/spiped/dispatch.c +214 -0
- data/ext/spiped/spiped-source/spiped/dispatch.h +27 -0
- data/ext/spiped/spiped-source/spiped/main.c +267 -0
- data/ext/spiped/spiped-source/spiped/spiped.1 +112 -0
- data/lib/spiped.rb +3 -0
- 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
|
+
}
|