git ssb

0+

cel / dill-skhs



Commit 04d62f69fe06f0083d79534e7b8a0e45e5042322

Init

cel committed on 5/15/2017, 3:09:57 AM

Files changed

.gitignoreadded
Makefileadded
skhs.cadded
skhs.hadded
skhs.test.cadded
.gitignoreView
@@ -1,0 +1,3 @@
1 +*.o
2 +*.test
3 +*.stamp
MakefileView
@@ -1,0 +1,15 @@
1 +LDLIBS = -ldill -lsodium
2 +CFLAGS = -g
3 +
4 +test: skhs.test.stamp
5 +
6 +skhs.test: skhs.c skhs.test.c
7 +
8 +%.stamp: %
9 + ./$^
10 + touch $@
11 +
12 +clean:
13 + @rm -vf $(wildcard *.o *.test *.stamp)
14 +
15 +.PHONY: test clean
skhs.cView
@@ -1,0 +1,346 @@
1 +#include <errno.h>
2 +#include <string.h>
3 +#include <arpa/inet.h>
4 +#include <libdillimpl.h>
5 +#include <sodium.h>
6 +
7 +#include "skhs.h"
8 +
9 +static const int _skhs_type, *skhs_type = &_skhs_type;
10 +
11 +static uint8_t zeros[24] = {0};
12 +
13 +static void *skhs_hquery(struct hvfs *hvfs, const void *type);
14 +static void skhs_hclose(struct hvfs *hvfs);
15 +static int skhs_hdone(struct hvfs *hvfs, int64_t deadline);
16 +
17 +struct skhs_obj {
18 + struct hvfs hvfs;
19 + int u;
20 + uint8_t public_key[32];
21 + uint8_t secret_key[64];
22 + uint8_t app_key[32];
23 + uint8_t kx_pk[32];
24 + uint8_t kx_sk[32];
25 + uint8_t remote_kx_pk[32];
26 + uint8_t remote_public_key[32];
27 + uint8_t hello[96];
28 + uint8_t shash[32];
29 + uint8_t secret3[32];
30 +};
31 +
32 +static int auth_keypair(unsigned char pk[32], unsigned char sk[32], unsigned char seed[32])
33 +{
34 + unsigned char pk_ed[32], sk_ed[32];
35 + int rc = crypto_sign_seed_keypair(pk_ed, sk_ed, seed);
36 + if (rc < 0) { errno = ENOKEY; return -1; }
37 + rc = crypto_sign_ed25519_pk_to_curve25519(pk, pk_ed);
38 + if (rc < 0) { errno = ENOKEY; return -1; }
39 + rc = crypto_sign_ed25519_sk_to_curve25519(sk, sk_ed);
40 + if (rc < 0) { errno = ENOKEY; return -1; }
41 + return 0;
42 +}
43 +
44 +static void *skhs_hquery(struct hvfs *hvfs, const void *type)
45 +{
46 + struct skhs_obj *self = (void *)hvfs;
47 + if(type == skhs_type) return self;
48 + errno = ENOTSUP;
49 + return NULL;
50 +}
51 +
52 +static void skhs_hclose(struct hvfs *hvfs)
53 +{
54 + struct skhs_obj *self = (void *)hvfs;
55 + if (self->u >= 0) {
56 + hclose(self->u);
57 + }
58 + free(self);
59 +}
60 +
61 +static int send_challenge(int s, const uint8_t kx_pk[32], const uint8_t appkey[32], int64_t deadline)
62 +{
63 + uint8_t buf[64];
64 + int rc = crypto_auth(buf, kx_pk, 32, appkey);
65 + if (rc < 0) { errno = ENOKEY; return -1; }
66 + memcpy(buf+32, kx_pk, 32);
67 + return bsend(s, buf, sizeof(buf), deadline);
68 +}
69 +
70 +static int recv_challenge(int s, uint8_t remote_kx_pk[32], const uint8_t appkey[32], int64_t deadline)
71 +{
72 + uint8_t buf[64];
73 + int rc = brecv(s, buf, sizeof(buf), deadline);
74 + if (rc < 0) return -1;
75 + memcpy(remote_kx_pk, buf+32, 32);
76 + rc = crypto_auth_verify(buf, remote_kx_pk, 32, appkey);
77 + if (rc < 0) { errno = EPROTO; return -1; }
78 + return 0;
79 +}
80 +
81 +int skhs_client(int s, const uint8_t pubkey[32], const uint8_t seckey[64], const uint8_t appkey[32], const uint8_t server_pubkey[32], uint8_t shared_secret[32], int64_t deadline)
82 +{
83 + int err;
84 + int u = hdup(s);
85 + if (u < 0) return -1;
86 + int rc = hclose(s);
87 + if (rc < 0) return -1;
88 +
89 + uint8_t kx_pk[32], kx_sk[32];
90 + uint8_t seed[32];
91 + randombytes_buf(seed, sizeof(seed));
92 + rc = auth_keypair(kx_pk, kx_sk, seed);
93 + if (rc < 0) return -1;
94 +
95 + rc = send_challenge(u, kx_pk, appkey, deadline);
96 + if (rc < 0) goto error;
97 +
98 + uint8_t remote_kx_pk[32];
99 + rc = recv_challenge(u, remote_kx_pk, appkey, deadline);
100 + if (rc < 0) goto error;
101 +
102 + // send auth
103 +
104 + uint8_t secret[32];
105 + rc = crypto_scalarmult(secret, kx_sk, remote_kx_pk);
106 + if (rc < 0) { err = ENOKEY; goto error; }
107 +
108 + uint8_t remote_pk_curve[32];
109 + rc = crypto_sign_ed25519_pk_to_curve25519(remote_pk_curve, server_pubkey);
110 + if (rc < 0) { err = ENOKEY; goto error; }
111 +
112 + uint8_t a_bob[32];
113 + rc = crypto_scalarmult(a_bob, kx_sk, remote_pk_curve);
114 + if (rc < 0) { err = ENOKEY; goto error; }
115 +
116 + uint8_t secret2a[96];
117 + memcpy(secret2a, appkey, 32);
118 + memcpy(secret2a+32, secret, 32);
119 + memcpy(secret2a+64, a_bob, 32);
120 +
121 + uint8_t secret2[32];
122 + rc = crypto_hash_sha256(secret2, secret2a, sizeof(secret2a));
123 + if (rc < 0) { err = ENOKEY; goto error; }
124 +
125 + uint8_t shash[32];
126 + rc = crypto_hash_sha256(shash, secret, sizeof(secret));
127 + if (rc < 0) { err = ENOKEY; goto error; }
128 +
129 + uint8_t signed1[96];
130 + memcpy(signed1, appkey, 32);
131 + memcpy(signed1+32, server_pubkey, 32);
132 + memcpy(signed1+64, shash, 32);
133 +
134 + uint8_t sig[64];
135 + rc = crypto_sign_detached(sig, NULL, signed1, sizeof(signed1), seckey);
136 + if (rc < 0) { err = ENOKEY; goto error; }
137 +
138 + uint8_t hello[96];
139 + memcpy(hello, sig, 64);
140 + memcpy(hello+64, pubkey, 32);
141 +
142 + uint8_t boxed_auth[112];
143 + rc = crypto_secretbox_easy(boxed_auth, hello, sizeof(hello), zeros, secret2);
144 + if (rc < 0) { err = ENOKEY; goto error; }
145 +
146 + rc = bsend(u, boxed_auth, sizeof(boxed_auth), deadline);
147 + if (rc < 0) goto error;
148 +
149 + // verify accept
150 +
151 + uint8_t boxed_okay[80];
152 + rc = brecv(u, boxed_okay, sizeof(boxed_okay), deadline);
153 + if (rc < 0) { err = ECONNRESET; goto error; }
154 +
155 + uint8_t local_sk_curve[32];
156 + rc = crypto_sign_ed25519_sk_to_curve25519(local_sk_curve, seckey);
157 + if (rc < 0) { err = ENOKEY; goto error; }
158 +
159 + uint8_t b_alice[32];
160 + rc = crypto_scalarmult(b_alice, local_sk_curve, remote_kx_pk);
161 + if (rc < 0) { err = ENOKEY; goto error; }
162 +
163 + uint8_t secret3a[128];
164 + memcpy(secret3a, appkey, 32);
165 + memcpy(secret3a+32, secret, 32);
166 + memcpy(secret3a+64, a_bob, 32);
167 + memcpy(secret3a+96, b_alice, 32);
168 +
169 + uint8_t secret3[32];
170 + rc = crypto_hash_sha256(secret3, secret3a, sizeof(secret3a));
171 + if (rc < 0) { err = ENOKEY; goto error; }
172 +
173 + rc = crypto_secretbox_open_easy(sig, boxed_okay, sizeof(boxed_okay), zeros, secret3);
174 + if (rc < 0) { err = EPROTO; goto error; }
175 +
176 + uint8_t signed2[160];
177 + memcpy(signed2, appkey, 32);
178 + memcpy(signed2+32, hello, 96);
179 + memcpy(signed2+128, shash, 32);
180 +
181 + rc = crypto_sign_verify_detached(sig, signed2, sizeof(signed2), server_pubkey);
182 + if (rc < 0) { err = EPROTO; goto error; }
183 +
184 + rc = crypto_hash_sha256(shared_secret, secret3, 32);
185 + if (rc < 0) { err = ENOKEY; goto error; }
186 +
187 + rc = crypto_hash_sha256(shared_secret, shared_secret, 32);
188 + if (rc < 0) { err = ENOKEY; goto error; }
189 +
190 + return u;
191 +
192 +error:
193 + hclose(u);
194 + errno = err;
195 + return -1;
196 +}
197 +
198 +int skhs_server_attach(int s, const uint8_t pubkey[32], const uint8_t seckey[64], const uint8_t appkey[32], uint8_t client_pubkey[32], int64_t deadline)
199 +{
200 + int err;
201 + int u = hdup(s);
202 + if (u < 0) return -1;
203 + int rc = hclose(s);
204 + if (rc < 0) return -1;
205 + struct skhs_obj *self = malloc(sizeof(struct skhs_obj));
206 + if (!self) goto error1;
207 + uint8_t seed[32];
208 + randombytes_buf(seed, 32);
209 + rc = auth_keypair(self->kx_pk, self->kx_sk, seed);
210 + if (rc < 0) goto error2;
211 + self->hvfs.query = skhs_hquery;
212 + self->hvfs.close = skhs_hclose;
213 + memcpy(self->public_key, pubkey, 32);
214 + memcpy(self->secret_key, seckey, 64);
215 + memcpy(self->app_key, appkey, 32);
216 + memset(self->remote_public_key, 0, 32);
217 + self->u = u;
218 +
219 + rc = recv_challenge(u, self->remote_kx_pk, appkey, deadline);
220 + if (rc < 0) goto error2;
221 +
222 + rc = send_challenge(u, self->kx_pk, appkey, deadline);
223 + if (rc < 0) goto error2;
224 +
225 + // recv auth
226 +
227 + uint8_t boxed_auth[112];
228 + rc = brecv(u, boxed_auth, sizeof(boxed_auth), deadline);
229 + if (rc < 0) goto error2;
230 +
231 + uint8_t secret[32];
232 + rc = crypto_scalarmult(secret, self->kx_sk, self->remote_kx_pk);
233 + if (rc < 0) { errno = ENOKEY; goto error2; }
234 +
235 + rc = crypto_hash_sha256(self->shash, secret, sizeof(secret));
236 + if (rc < 0) { errno = ENOKEY; goto error2; }
237 +
238 + uint8_t sk_curve[32];
239 + rc = crypto_sign_ed25519_sk_to_curve25519(sk_curve, seckey);
240 + if (rc < 0) { errno = ENOKEY; goto error2; }
241 +
242 + uint8_t a_bob[32];
243 + rc = crypto_scalarmult(a_bob, sk_curve, self->remote_kx_pk);
244 + if (rc < 0) { errno = ENOKEY; goto error2; }
245 +
246 + uint8_t secret2a[96];
247 + memcpy(secret2a, appkey, 32);
248 + memcpy(secret2a+32, secret, 32);
249 + memcpy(secret2a+64, a_bob, 32);
250 +
251 + uint8_t secret2[32];
252 + rc = crypto_hash_sha256(secret2, secret2a, sizeof(secret2a));
253 + if (rc < 0) { errno = ENOKEY; goto error2; }
254 +
255 + rc = crypto_secretbox_open_easy(self->hello, boxed_auth, sizeof(boxed_auth), zeros, secret2);
256 + if (rc < 0) { errno = ENOKEY; goto error2; }
257 +
258 + uint8_t sig[64];
259 + memcpy(sig, self->hello, 64);
260 + memcpy(client_pubkey, self->hello+64, 32);
261 +
262 + uint8_t signed1[96];
263 + memcpy(signed1, appkey, 32);
264 + memcpy(signed1+32, pubkey, 32);
265 + memcpy(signed1+64, self->shash, 32);
266 +
267 + rc = crypto_sign_verify_detached(sig, signed1, sizeof(signed1), client_pubkey);
268 + if (rc < 0) { errno = EPROTO; goto error2; }
269 +
270 + uint8_t remote_pk_curve[32];
271 + rc = crypto_sign_ed25519_pk_to_curve25519(remote_pk_curve, client_pubkey);
272 + if (rc < 0) { errno = ENOKEY; goto error2; }
273 +
274 + uint8_t b_alice[32];
275 + rc = crypto_scalarmult(b_alice, self->kx_sk, remote_pk_curve);
276 + if (rc < 0) { errno = ENOKEY; goto error2; }
277 +
278 + uint8_t secret3a[128];
279 + memcpy(secret3a, appkey, 32);
280 + memcpy(secret3a+32, secret, 32);
281 + memcpy(secret3a+64, a_bob, 32);
282 + memcpy(secret3a+96, b_alice, 32);
283 +
284 + rc = crypto_hash_sha256(self->secret3, secret3a, sizeof(secret3a));
285 + if (rc < 0) { errno = ENOKEY; goto error2; }
286 +
287 + int h = hmake(&self->hvfs);
288 + if (h < 0) goto error2;
289 + return h;
290 +
291 +error2:
292 + err = errno;
293 + free(self);
294 +error1:
295 + hclose(u);
296 + errno = err;
297 + return -1;
298 +}
299 +
300 +int skhs_server_detach(int s, int64_t deadline)
301 +{
302 + struct skhs_obj *self = hquery(s, skhs_type);
303 + if (!self) return -1;
304 + int u = self->u;
305 + free(self);
306 + return u;
307 +}
308 +
309 +int skhs_server_accept(int s, uint8_t shared_secret[32], int64_t deadline)
310 +{
311 + int err;
312 + struct skhs_obj *self = hquery(s, skhs_type);
313 + if (!self) return -1;
314 +
315 + int rc = crypto_hash_sha256(shared_secret, self->secret3, 32);
316 + if (rc < 0) { errno = ENOKEY; goto error; }
317 +
318 + rc = crypto_hash_sha256(shared_secret, shared_secret, 32);
319 + if (rc < 0) { errno = ENOKEY; goto error; }
320 +
321 + uint8_t signed2[160];
322 + memcpy(signed2, self->app_key, 32);
323 + memcpy(signed2+32, self->hello, 96);
324 + memcpy(signed2+128, self->shash, 32);
325 +
326 + uint8_t sig[64];
327 + rc = crypto_sign_detached(sig, NULL, signed2, sizeof(signed2), self->secret_key);
328 + if (rc < 0) { errno = EPROTO; goto error; }
329 +
330 + uint8_t boxed_okay[80];
331 + rc = crypto_secretbox_easy(boxed_okay, sig, sizeof(sig), zeros, self->secret3);
332 + if (rc < 0) { errno = ENOKEY; goto error; }
333 +
334 + int u = self->u;
335 + rc = bsend(u, boxed_okay, sizeof(boxed_okay), deadline);
336 + if (rc < 0) goto error;
337 +
338 + free(self);
339 + return u;
340 +
341 +error:
342 + err = errno;
343 + skhs_hclose(&self->hvfs);
344 + errno = err;
345 + return -1;
346 +}
skhs.hView
@@ -1,0 +1,8 @@
1 +#pragma once
2 +
3 +#include <stdint.h>
4 +
5 +int skhs_client(int s, const uint8_t pubkey[32], const uint8_t seckey[64], const uint8_t appkey[32], const uint8_t server_pubkey[32], uint8_t shared_secret[32], int64_t deadline);
6 +int skhs_server_attach(int s, const uint8_t pubkey[32], const uint8_t seckey[64], const uint8_t appkey[32], uint8_t client_pubkey[32], int64_t deadline);
7 +int skhs_server_detach(int s, int64_t deadline);
8 +int skhs_server_accept(int s, uint8_t shared_secret[32], int64_t deadline);
skhs.test.cView
@@ -1,0 +1,59 @@
1 +#include <assert.h>
2 +#include <string.h>
3 +#include <libdill.h>
4 +#include <sodium.h>
5 +#include "skhs.h"
6 +
7 +uint8_t appkey[32] = "fab5d99999158c9ebe45cc85e6c38b5c";
8 +
9 +coroutine void client(int s, uint8_t client_pk[32], uint8_t client_sk[32], uint8_t server_pk[32], int shared_secret_ch) {
10 + uint8_t shared_secret[32];
11 + s = skhs_client(s, client_pk, client_sk, appkey, server_pk, shared_secret, -1);
12 + assert(s >= 0);
13 + int rc = chsend(shared_secret_ch, shared_secret, 32, -1);
14 + assert(rc == 0);
15 + rc = hclose(s);
16 + assert(rc == 0);
17 +}
18 +
19 +int main() {
20 + int s[2], rc;
21 +
22 + uint8_t client_seed[32], server_seed[32];
23 + randombytes_buf(client_seed, 32);
24 + randombytes_buf(server_seed, 32);
25 +
26 + uint8_t client_pk[32], client_sk[32];
27 + uint8_t server_pk[32], server_sk[32];
28 + assert(rc == 0);
29 + rc = crypto_sign_seed_keypair(client_pk, client_sk, client_seed);
30 + assert(rc == 0);
31 + rc = crypto_sign_seed_keypair(server_pk, server_sk, server_seed);
32 + assert(rc == 0);
33 +
34 + rc = ipc_pair(s);
35 + assert(rc == 0);
36 +
37 + int ch = chmake(32);
38 + assert(ch >= 0);
39 + int cr = go(client(s[0], client_pk, client_sk, server_pk, ch));
40 + assert(cr >= 0);
41 +
42 + uint8_t client_authed_pk[32];
43 + int server = skhs_server_attach(s[1], server_pk, server_sk, appkey, client_authed_pk, -1);
44 + assert(server >= 0);
45 + assert(memcmp(client_pk, client_authed_pk, 32) == 0);
46 + uint8_t shared_secret[32];
47 + int u = skhs_server_accept(server, shared_secret, -1);
48 + assert(u >= 0);
49 + uint8_t client_shared_secret[32];
50 + rc = chrecv(ch, client_shared_secret, 32, -1);
51 + assert(rc == 0);
52 + assert(memcmp(shared_secret, client_shared_secret, 32) == 0);
53 + rc = chdone(ch);
54 + assert(rc == 0);
55 + rc = hclose(u);
56 + assert(rc == 0);
57 + rc = hclose(cr);
58 + assert(rc == 0);
59 +}

Built with git-ssb-web