1 #include "jpake.h"
2
3 #include <openssl/crypto.h>
4 #include <openssl/sha.h>
5 #include <openssl/err.h>
6 #include <memory.h>
7
8 /*
9 * In the definition, (xa, xb, xc, xd) are Alice's (x1, x2, x3, x4) or
10 * Bob's (x3, x4, x1, x2). If you see what I mean.
11 */
12
13 typedef struct {
14 char *name; /* Must be unique */
15 char *peer_name;
16 BIGNUM *p;
17 BIGNUM *g;
18 BIGNUM *q;
19 BIGNUM *gxc; /* Alice's g^{x3} or Bob's g^{x1} */
20 BIGNUM *gxd; /* Alice's g^{x4} or Bob's g^{x2} */
21 } JPAKE_CTX_PUBLIC;
22
23 struct JPAKE_CTX {
24 JPAKE_CTX_PUBLIC p;
25 BIGNUM *secret; /* The shared secret */
26 BN_CTX *ctx;
27 BIGNUM *xa; /* Alice's x1 or Bob's x3 */
28 BIGNUM *xb; /* Alice's x2 or Bob's x4 */
29 BIGNUM *key; /* The calculated (shared) key */
30 };
31
JPAKE_ZKP_init(JPAKE_ZKP * zkp)32 static void JPAKE_ZKP_init(JPAKE_ZKP *zkp)
33 {
34 zkp->gr = BN_new();
35 zkp->b = BN_new();
36 }
37
JPAKE_ZKP_release(JPAKE_ZKP * zkp)38 static void JPAKE_ZKP_release(JPAKE_ZKP *zkp)
39 {
40 BN_free(zkp->b);
41 BN_free(zkp->gr);
42 }
43
44 /* Two birds with one stone - make the global name as expected */
45 #define JPAKE_STEP_PART_init JPAKE_STEP2_init
46 #define JPAKE_STEP_PART_release JPAKE_STEP2_release
47
JPAKE_STEP_PART_init(JPAKE_STEP_PART * p)48 void JPAKE_STEP_PART_init(JPAKE_STEP_PART *p)
49 {
50 p->gx = BN_new();
51 JPAKE_ZKP_init(&p->zkpx);
52 }
53
JPAKE_STEP_PART_release(JPAKE_STEP_PART * p)54 void JPAKE_STEP_PART_release(JPAKE_STEP_PART *p)
55 {
56 JPAKE_ZKP_release(&p->zkpx);
57 BN_free(p->gx);
58 }
59
JPAKE_STEP1_init(JPAKE_STEP1 * s1)60 void JPAKE_STEP1_init(JPAKE_STEP1 *s1)
61 {
62 JPAKE_STEP_PART_init(&s1->p1);
63 JPAKE_STEP_PART_init(&s1->p2);
64 }
65
JPAKE_STEP1_release(JPAKE_STEP1 * s1)66 void JPAKE_STEP1_release(JPAKE_STEP1 *s1)
67 {
68 JPAKE_STEP_PART_release(&s1->p2);
69 JPAKE_STEP_PART_release(&s1->p1);
70 }
71
JPAKE_CTX_init(JPAKE_CTX * ctx,const char * name,const char * peer_name,const BIGNUM * p,const BIGNUM * g,const BIGNUM * q,const BIGNUM * secret)72 static void JPAKE_CTX_init(JPAKE_CTX *ctx, const char *name,
73 const char *peer_name, const BIGNUM *p,
74 const BIGNUM *g, const BIGNUM *q,
75 const BIGNUM *secret)
76 {
77 ctx->p.name = OPENSSL_strdup(name);
78 ctx->p.peer_name = OPENSSL_strdup(peer_name);
79 ctx->p.p = BN_dup(p);
80 ctx->p.g = BN_dup(g);
81 ctx->p.q = BN_dup(q);
82 ctx->secret = BN_dup(secret);
83
84 ctx->p.gxc = BN_new();
85 ctx->p.gxd = BN_new();
86
87 ctx->xa = BN_new();
88 ctx->xb = BN_new();
89 ctx->key = BN_new();
90 ctx->ctx = BN_CTX_new();
91 }
92
JPAKE_CTX_release(JPAKE_CTX * ctx)93 static void JPAKE_CTX_release(JPAKE_CTX *ctx)
94 {
95 BN_CTX_free(ctx->ctx);
96 BN_clear_free(ctx->key);
97 BN_clear_free(ctx->xb);
98 BN_clear_free(ctx->xa);
99
100 BN_free(ctx->p.gxd);
101 BN_free(ctx->p.gxc);
102
103 BN_clear_free(ctx->secret);
104 BN_free(ctx->p.q);
105 BN_free(ctx->p.g);
106 BN_free(ctx->p.p);
107 OPENSSL_free(ctx->p.peer_name);
108 OPENSSL_free(ctx->p.name);
109
110 memset(ctx, '\0', sizeof *ctx);
111 }
112
JPAKE_CTX_new(const char * name,const char * peer_name,const BIGNUM * p,const BIGNUM * g,const BIGNUM * q,const BIGNUM * secret)113 JPAKE_CTX *JPAKE_CTX_new(const char *name, const char *peer_name,
114 const BIGNUM *p, const BIGNUM *g, const BIGNUM *q,
115 const BIGNUM *secret)
116 {
117 JPAKE_CTX *ctx = OPENSSL_malloc(sizeof *ctx);
118
119 JPAKE_CTX_init(ctx, name, peer_name, p, g, q, secret);
120
121 return ctx;
122 }
123
JPAKE_CTX_free(JPAKE_CTX * ctx)124 void JPAKE_CTX_free(JPAKE_CTX *ctx)
125 {
126 JPAKE_CTX_release(ctx);
127 OPENSSL_free(ctx);
128 }
129
hashlength(SHA_CTX * sha,size_t l)130 static void hashlength(SHA_CTX *sha, size_t l)
131 {
132 unsigned char b[2];
133
134 OPENSSL_assert(l <= 0xffff);
135 b[0] = l >> 8;
136 b[1] = l & 0xff;
137 SHA1_Update(sha, b, 2);
138 }
139
hashstring(SHA_CTX * sha,const char * string)140 static void hashstring(SHA_CTX *sha, const char *string)
141 {
142 size_t l = strlen(string);
143
144 hashlength(sha, l);
145 SHA1_Update(sha, string, l);
146 }
147
hashbn(SHA_CTX * sha,const BIGNUM * bn)148 static void hashbn(SHA_CTX *sha, const BIGNUM *bn)
149 {
150 size_t l = BN_num_bytes(bn);
151 unsigned char *bin = OPENSSL_malloc(l);
152
153 hashlength(sha, l);
154 BN_bn2bin(bn, bin);
155 SHA1_Update(sha, bin, l);
156 OPENSSL_free(bin);
157 }
158
159 /* h=hash(g, g^r, g^x, name) */
zkp_hash(BIGNUM * h,const BIGNUM * zkpg,const JPAKE_STEP_PART * p,const char * proof_name)160 static void zkp_hash(BIGNUM *h, const BIGNUM *zkpg, const JPAKE_STEP_PART *p,
161 const char *proof_name)
162 {
163 unsigned char md[SHA_DIGEST_LENGTH];
164 SHA_CTX sha;
165
166 /*
167 * XXX: hash should not allow moving of the boundaries - Java code
168 * is flawed in this respect. Length encoding seems simplest.
169 */
170 SHA1_Init(&sha);
171 hashbn(&sha, zkpg);
172 OPENSSL_assert(!BN_is_zero(p->zkpx.gr));
173 hashbn(&sha, p->zkpx.gr);
174 hashbn(&sha, p->gx);
175 hashstring(&sha, proof_name);
176 SHA1_Final(md, &sha);
177 BN_bin2bn(md, SHA_DIGEST_LENGTH, h);
178 }
179
180 /*
181 * Prove knowledge of x
182 * Note that p->gx has already been calculated
183 */
generate_zkp(JPAKE_STEP_PART * p,const BIGNUM * x,const BIGNUM * zkpg,JPAKE_CTX * ctx)184 static void generate_zkp(JPAKE_STEP_PART *p, const BIGNUM *x,
185 const BIGNUM *zkpg, JPAKE_CTX *ctx)
186 {
187 BIGNUM *r = BN_new();
188 BIGNUM *h = BN_new();
189 BIGNUM *t = BN_new();
190
191 /*-
192 * r in [0,q)
193 * XXX: Java chooses r in [0, 2^160) - i.e. distribution not uniform
194 */
195 BN_rand_range(r, ctx->p.q);
196 /* g^r */
197 BN_mod_exp(p->zkpx.gr, zkpg, r, ctx->p.p, ctx->ctx);
198
199 /* h=hash... */
200 zkp_hash(h, zkpg, p, ctx->p.name);
201
202 /* b = r - x*h */
203 BN_mod_mul(t, x, h, ctx->p.q, ctx->ctx);
204 BN_mod_sub(p->zkpx.b, r, t, ctx->p.q, ctx->ctx);
205
206 /* cleanup */
207 BN_free(t);
208 BN_free(h);
209 BN_free(r);
210 }
211
verify_zkp(const JPAKE_STEP_PART * p,const BIGNUM * zkpg,JPAKE_CTX * ctx)212 static int verify_zkp(const JPAKE_STEP_PART *p, const BIGNUM *zkpg,
213 JPAKE_CTX *ctx)
214 {
215 BIGNUM *h = BN_new();
216 BIGNUM *t1 = BN_new();
217 BIGNUM *t2 = BN_new();
218 BIGNUM *t3 = BN_new();
219 int ret = 0;
220
221 zkp_hash(h, zkpg, p, ctx->p.peer_name);
222
223 /* t1 = g^b */
224 BN_mod_exp(t1, zkpg, p->zkpx.b, ctx->p.p, ctx->ctx);
225 /* t2 = (g^x)^h = g^{hx} */
226 BN_mod_exp(t2, p->gx, h, ctx->p.p, ctx->ctx);
227 /* t3 = t1 * t2 = g^{hx} * g^b = g^{hx+b} = g^r (allegedly) */
228 BN_mod_mul(t3, t1, t2, ctx->p.p, ctx->ctx);
229
230 /* verify t3 == g^r */
231 if (BN_cmp(t3, p->zkpx.gr) == 0)
232 ret = 1;
233 else
234 JPAKEerr(JPAKE_F_VERIFY_ZKP, JPAKE_R_ZKP_VERIFY_FAILED);
235
236 /* cleanup */
237 BN_free(t3);
238 BN_free(t2);
239 BN_free(t1);
240 BN_free(h);
241
242 return ret;
243 }
244
generate_step_part(JPAKE_STEP_PART * p,const BIGNUM * x,const BIGNUM * g,JPAKE_CTX * ctx)245 static void generate_step_part(JPAKE_STEP_PART *p, const BIGNUM *x,
246 const BIGNUM *g, JPAKE_CTX *ctx)
247 {
248 BN_mod_exp(p->gx, g, x, ctx->p.p, ctx->ctx);
249 generate_zkp(p, x, g, ctx);
250 }
251
252 /* Generate each party's random numbers. xa is in [0, q), xb is in [1, q). */
genrand(JPAKE_CTX * ctx)253 static void genrand(JPAKE_CTX *ctx)
254 {
255 BIGNUM *qm1;
256
257 /* xa in [0, q) */
258 BN_rand_range(ctx->xa, ctx->p.q);
259
260 /* q-1 */
261 qm1 = BN_new();
262 BN_copy(qm1, ctx->p.q);
263 BN_sub_word(qm1, 1);
264
265 /* ... and xb in [0, q-1) */
266 BN_rand_range(ctx->xb, qm1);
267 /* [1, q) */
268 BN_add_word(ctx->xb, 1);
269
270 /* cleanup */
271 BN_free(qm1);
272 }
273
JPAKE_STEP1_generate(JPAKE_STEP1 * send,JPAKE_CTX * ctx)274 int JPAKE_STEP1_generate(JPAKE_STEP1 *send, JPAKE_CTX *ctx)
275 {
276 genrand(ctx);
277 generate_step_part(&send->p1, ctx->xa, ctx->p.g, ctx);
278 generate_step_part(&send->p2, ctx->xb, ctx->p.g, ctx);
279
280 return 1;
281 }
282
283 /* g^x is a legal value */
is_legal(const BIGNUM * gx,const JPAKE_CTX * ctx)284 static int is_legal(const BIGNUM *gx, const JPAKE_CTX *ctx)
285 {
286 BIGNUM *t;
287 int res;
288
289 if (BN_is_negative(gx) || BN_is_zero(gx) || BN_cmp(gx, ctx->p.p) >= 0)
290 return 0;
291
292 t = BN_new();
293 BN_mod_exp(t, gx, ctx->p.q, ctx->p.p, ctx->ctx);
294 res = BN_is_one(t);
295 BN_free(t);
296
297 return res;
298 }
299
JPAKE_STEP1_process(JPAKE_CTX * ctx,const JPAKE_STEP1 * received)300 int JPAKE_STEP1_process(JPAKE_CTX *ctx, const JPAKE_STEP1 *received)
301 {
302 if (!is_legal(received->p1.gx, ctx)) {
303 JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS,
304 JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL);
305 return 0;
306 }
307
308 if (!is_legal(received->p2.gx, ctx)) {
309 JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS,
310 JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL);
311 return 0;
312 }
313
314 /* verify their ZKP(xc) */
315 if (!verify_zkp(&received->p1, ctx->p.g, ctx)) {
316 JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X3_FAILED);
317 return 0;
318 }
319
320 /* verify their ZKP(xd) */
321 if (!verify_zkp(&received->p2, ctx->p.g, ctx)) {
322 JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X4_FAILED);
323 return 0;
324 }
325
326 /* g^xd != 1 */
327 if (BN_is_one(received->p2.gx)) {
328 JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X4_IS_ONE);
329 return 0;
330 }
331
332 /* Save the bits we need for later */
333 BN_copy(ctx->p.gxc, received->p1.gx);
334 BN_copy(ctx->p.gxd, received->p2.gx);
335
336 return 1;
337 }
338
JPAKE_STEP2_generate(JPAKE_STEP2 * send,JPAKE_CTX * ctx)339 int JPAKE_STEP2_generate(JPAKE_STEP2 *send, JPAKE_CTX *ctx)
340 {
341 BIGNUM *t1 = BN_new();
342 BIGNUM *t2 = BN_new();
343
344 /*-
345 * X = g^{(xa + xc + xd) * xb * s}
346 * t1 = g^xa
347 */
348 BN_mod_exp(t1, ctx->p.g, ctx->xa, ctx->p.p, ctx->ctx);
349 /* t2 = t1 * g^{xc} = g^{xa} * g^{xc} = g^{xa + xc} */
350 BN_mod_mul(t2, t1, ctx->p.gxc, ctx->p.p, ctx->ctx);
351 /* t1 = t2 * g^{xd} = g^{xa + xc + xd} */
352 BN_mod_mul(t1, t2, ctx->p.gxd, ctx->p.p, ctx->ctx);
353 /* t2 = xb * s */
354 BN_mod_mul(t2, ctx->xb, ctx->secret, ctx->p.q, ctx->ctx);
355
356 /*-
357 * ZKP(xb * s)
358 * XXX: this is kinda funky, because we're using
359 *
360 * g' = g^{xa + xc + xd}
361 *
362 * as the generator, which means X is g'^{xb * s}
363 * X = t1^{t2} = t1^{xb * s} = g^{(xa + xc + xd) * xb * s}
364 */
365 generate_step_part(send, t2, t1, ctx);
366
367 /* cleanup */
368 BN_free(t1);
369 BN_free(t2);
370
371 return 1;
372 }
373
374 /* gx = g^{xc + xa + xb} * xd * s */
compute_key(JPAKE_CTX * ctx,const BIGNUM * gx)375 static int compute_key(JPAKE_CTX *ctx, const BIGNUM *gx)
376 {
377 BIGNUM *t1 = BN_new();
378 BIGNUM *t2 = BN_new();
379 BIGNUM *t3 = BN_new();
380
381 /*-
382 * K = (gx/g^{xb * xd * s})^{xb}
383 * = (g^{(xc + xa + xb) * xd * s - xb * xd *s})^{xb}
384 * = (g^{(xa + xc) * xd * s})^{xb}
385 * = g^{(xa + xc) * xb * xd * s}
386 * [which is the same regardless of who calculates it]
387 */
388
389 /* t1 = (g^{xd})^{xb} = g^{xb * xd} */
390 BN_mod_exp(t1, ctx->p.gxd, ctx->xb, ctx->p.p, ctx->ctx);
391 /* t2 = -s = q-s */
392 BN_sub(t2, ctx->p.q, ctx->secret);
393 /* t3 = t1^t2 = g^{-xb * xd * s} */
394 BN_mod_exp(t3, t1, t2, ctx->p.p, ctx->ctx);
395 /* t1 = gx * t3 = X/g^{xb * xd * s} */
396 BN_mod_mul(t1, gx, t3, ctx->p.p, ctx->ctx);
397 /* K = t1^{xb} */
398 BN_mod_exp(ctx->key, t1, ctx->xb, ctx->p.p, ctx->ctx);
399
400 /* cleanup */
401 BN_free(t3);
402 BN_free(t2);
403 BN_free(t1);
404
405 return 1;
406 }
407
JPAKE_STEP2_process(JPAKE_CTX * ctx,const JPAKE_STEP2 * received)408 int JPAKE_STEP2_process(JPAKE_CTX *ctx, const JPAKE_STEP2 *received)
409 {
410 BIGNUM *t1 = BN_new();
411 BIGNUM *t2 = BN_new();
412 int ret = 0;
413
414 /*-
415 * g' = g^{xc + xa + xb} [from our POV]
416 * t1 = xa + xb
417 */
418 BN_mod_add(t1, ctx->xa, ctx->xb, ctx->p.q, ctx->ctx);
419 /* t2 = g^{t1} = g^{xa+xb} */
420 BN_mod_exp(t2, ctx->p.g, t1, ctx->p.p, ctx->ctx);
421 /* t1 = g^{xc} * t2 = g^{xc + xa + xb} */
422 BN_mod_mul(t1, ctx->p.gxc, t2, ctx->p.p, ctx->ctx);
423
424 if (verify_zkp(received, t1, ctx))
425 ret = 1;
426 else
427 JPAKEerr(JPAKE_F_JPAKE_STEP2_PROCESS, JPAKE_R_VERIFY_B_FAILED);
428
429 compute_key(ctx, received->gx);
430
431 /* cleanup */
432 BN_free(t2);
433 BN_free(t1);
434
435 return ret;
436 }
437
quickhashbn(unsigned char * md,const BIGNUM * bn)438 static void quickhashbn(unsigned char *md, const BIGNUM *bn)
439 {
440 SHA_CTX sha;
441
442 SHA1_Init(&sha);
443 hashbn(&sha, bn);
444 SHA1_Final(md, &sha);
445 }
446
JPAKE_STEP3A_init(JPAKE_STEP3A * s3a)447 void JPAKE_STEP3A_init(JPAKE_STEP3A *s3a)
448 {
449 }
450
JPAKE_STEP3A_generate(JPAKE_STEP3A * send,JPAKE_CTX * ctx)451 int JPAKE_STEP3A_generate(JPAKE_STEP3A *send, JPAKE_CTX *ctx)
452 {
453 quickhashbn(send->hhk, ctx->key);
454 SHA1(send->hhk, sizeof send->hhk, send->hhk);
455
456 return 1;
457 }
458
JPAKE_STEP3A_process(JPAKE_CTX * ctx,const JPAKE_STEP3A * received)459 int JPAKE_STEP3A_process(JPAKE_CTX *ctx, const JPAKE_STEP3A *received)
460 {
461 unsigned char hhk[SHA_DIGEST_LENGTH];
462
463 quickhashbn(hhk, ctx->key);
464 SHA1(hhk, sizeof hhk, hhk);
465 if (memcmp(hhk, received->hhk, sizeof hhk)) {
466 JPAKEerr(JPAKE_F_JPAKE_STEP3A_PROCESS,
467 JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH);
468 return 0;
469 }
470 return 1;
471 }
472
JPAKE_STEP3A_release(JPAKE_STEP3A * s3a)473 void JPAKE_STEP3A_release(JPAKE_STEP3A *s3a)
474 {
475 }
476
JPAKE_STEP3B_init(JPAKE_STEP3B * s3b)477 void JPAKE_STEP3B_init(JPAKE_STEP3B *s3b)
478 {
479 }
480
JPAKE_STEP3B_generate(JPAKE_STEP3B * send,JPAKE_CTX * ctx)481 int JPAKE_STEP3B_generate(JPAKE_STEP3B *send, JPAKE_CTX *ctx)
482 {
483 quickhashbn(send->hk, ctx->key);
484
485 return 1;
486 }
487
JPAKE_STEP3B_process(JPAKE_CTX * ctx,const JPAKE_STEP3B * received)488 int JPAKE_STEP3B_process(JPAKE_CTX *ctx, const JPAKE_STEP3B *received)
489 {
490 unsigned char hk[SHA_DIGEST_LENGTH];
491
492 quickhashbn(hk, ctx->key);
493 if (memcmp(hk, received->hk, sizeof hk)) {
494 JPAKEerr(JPAKE_F_JPAKE_STEP3B_PROCESS, JPAKE_R_HASH_OF_KEY_MISMATCH);
495 return 0;
496 }
497 return 1;
498 }
499
JPAKE_STEP3B_release(JPAKE_STEP3B * s3b)500 void JPAKE_STEP3B_release(JPAKE_STEP3B *s3b)
501 {
502 }
503
JPAKE_get_shared_key(JPAKE_CTX * ctx)504 const BIGNUM *JPAKE_get_shared_key(JPAKE_CTX *ctx)
505 {
506 return ctx->key;
507 }
508