1193645Ssimon#include "jpake.h" 2193645Ssimon 3193645Ssimon#include <openssl/crypto.h> 4193645Ssimon#include <openssl/sha.h> 5193645Ssimon#include <openssl/err.h> 6193645Ssimon#include <memory.h> 7193645Ssimon#include <assert.h> 8193645Ssimon 9193645Ssimon/* 10193645Ssimon * In the definition, (xa, xb, xc, xd) are Alice's (x1, x2, x3, x4) or 11193645Ssimon * Bob's (x3, x4, x1, x2). If you see what I mean. 12193645Ssimon */ 13193645Ssimon 14296465Sdelphijtypedef struct { 15296465Sdelphij char *name; /* Must be unique */ 16193645Ssimon char *peer_name; 17193645Ssimon BIGNUM *p; 18193645Ssimon BIGNUM *g; 19193645Ssimon BIGNUM *q; 20296465Sdelphij BIGNUM *gxc; /* Alice's g^{x3} or Bob's g^{x1} */ 21296465Sdelphij BIGNUM *gxd; /* Alice's g^{x4} or Bob's g^{x2} */ 22296465Sdelphij} JPAKE_CTX_PUBLIC; 23193645Ssimon 24296465Sdelphijstruct JPAKE_CTX { 25193645Ssimon JPAKE_CTX_PUBLIC p; 26296465Sdelphij BIGNUM *secret; /* The shared secret */ 27193645Ssimon BN_CTX *ctx; 28296465Sdelphij BIGNUM *xa; /* Alice's x1 or Bob's x3 */ 29296465Sdelphij BIGNUM *xb; /* Alice's x2 or Bob's x4 */ 30296465Sdelphij BIGNUM *key; /* The calculated (shared) key */ 31296465Sdelphij}; 32193645Ssimon 33193645Ssimonstatic void JPAKE_ZKP_init(JPAKE_ZKP *zkp) 34296465Sdelphij{ 35193645Ssimon zkp->gr = BN_new(); 36193645Ssimon zkp->b = BN_new(); 37296465Sdelphij} 38193645Ssimon 39193645Ssimonstatic void JPAKE_ZKP_release(JPAKE_ZKP *zkp) 40296465Sdelphij{ 41193645Ssimon BN_free(zkp->b); 42193645Ssimon BN_free(zkp->gr); 43296465Sdelphij} 44193645Ssimon 45193645Ssimon/* Two birds with one stone - make the global name as expected */ 46296465Sdelphij#define JPAKE_STEP_PART_init JPAKE_STEP2_init 47296465Sdelphij#define JPAKE_STEP_PART_release JPAKE_STEP2_release 48193645Ssimon 49193645Ssimonvoid JPAKE_STEP_PART_init(JPAKE_STEP_PART *p) 50296465Sdelphij{ 51193645Ssimon p->gx = BN_new(); 52193645Ssimon JPAKE_ZKP_init(&p->zkpx); 53296465Sdelphij} 54193645Ssimon 55193645Ssimonvoid JPAKE_STEP_PART_release(JPAKE_STEP_PART *p) 56296465Sdelphij{ 57193645Ssimon JPAKE_ZKP_release(&p->zkpx); 58193645Ssimon BN_free(p->gx); 59296465Sdelphij} 60193645Ssimon 61193645Ssimonvoid JPAKE_STEP1_init(JPAKE_STEP1 *s1) 62296465Sdelphij{ 63193645Ssimon JPAKE_STEP_PART_init(&s1->p1); 64193645Ssimon JPAKE_STEP_PART_init(&s1->p2); 65296465Sdelphij} 66193645Ssimon 67193645Ssimonvoid JPAKE_STEP1_release(JPAKE_STEP1 *s1) 68296465Sdelphij{ 69193645Ssimon JPAKE_STEP_PART_release(&s1->p2); 70193645Ssimon JPAKE_STEP_PART_release(&s1->p1); 71296465Sdelphij} 72193645Ssimon 73193645Ssimonstatic void JPAKE_CTX_init(JPAKE_CTX *ctx, const char *name, 74296465Sdelphij const char *peer_name, const BIGNUM *p, 75296465Sdelphij const BIGNUM *g, const BIGNUM *q, 76296465Sdelphij const BIGNUM *secret) 77296465Sdelphij{ 78193645Ssimon ctx->p.name = OPENSSL_strdup(name); 79193645Ssimon ctx->p.peer_name = OPENSSL_strdup(peer_name); 80193645Ssimon ctx->p.p = BN_dup(p); 81193645Ssimon ctx->p.g = BN_dup(g); 82193645Ssimon ctx->p.q = BN_dup(q); 83193645Ssimon ctx->secret = BN_dup(secret); 84193645Ssimon 85193645Ssimon ctx->p.gxc = BN_new(); 86193645Ssimon ctx->p.gxd = BN_new(); 87193645Ssimon 88193645Ssimon ctx->xa = BN_new(); 89193645Ssimon ctx->xb = BN_new(); 90193645Ssimon ctx->key = BN_new(); 91193645Ssimon ctx->ctx = BN_CTX_new(); 92296465Sdelphij} 93296465Sdelphij 94193645Ssimonstatic void JPAKE_CTX_release(JPAKE_CTX *ctx) 95296465Sdelphij{ 96193645Ssimon BN_CTX_free(ctx->ctx); 97193645Ssimon BN_clear_free(ctx->key); 98193645Ssimon BN_clear_free(ctx->xb); 99193645Ssimon BN_clear_free(ctx->xa); 100193645Ssimon 101193645Ssimon BN_free(ctx->p.gxd); 102193645Ssimon BN_free(ctx->p.gxc); 103193645Ssimon 104193645Ssimon BN_clear_free(ctx->secret); 105193645Ssimon BN_free(ctx->p.q); 106193645Ssimon BN_free(ctx->p.g); 107193645Ssimon BN_free(ctx->p.p); 108193645Ssimon OPENSSL_free(ctx->p.peer_name); 109193645Ssimon OPENSSL_free(ctx->p.name); 110193645Ssimon 111193645Ssimon memset(ctx, '\0', sizeof *ctx); 112296465Sdelphij} 113296465Sdelphij 114193645SsimonJPAKE_CTX *JPAKE_CTX_new(const char *name, const char *peer_name, 115296465Sdelphij const BIGNUM *p, const BIGNUM *g, const BIGNUM *q, 116296465Sdelphij const BIGNUM *secret) 117296465Sdelphij{ 118193645Ssimon JPAKE_CTX *ctx = OPENSSL_malloc(sizeof *ctx); 119193645Ssimon 120193645Ssimon JPAKE_CTX_init(ctx, name, peer_name, p, g, q, secret); 121193645Ssimon 122193645Ssimon return ctx; 123296465Sdelphij} 124193645Ssimon 125193645Ssimonvoid JPAKE_CTX_free(JPAKE_CTX *ctx) 126296465Sdelphij{ 127193645Ssimon JPAKE_CTX_release(ctx); 128193645Ssimon OPENSSL_free(ctx); 129296465Sdelphij} 130193645Ssimon 131193645Ssimonstatic void hashlength(SHA_CTX *sha, size_t l) 132296465Sdelphij{ 133193645Ssimon unsigned char b[2]; 134193645Ssimon 135193645Ssimon assert(l <= 0xffff); 136193645Ssimon b[0] = l >> 8; 137296465Sdelphij b[1] = l & 0xff; 138193645Ssimon SHA1_Update(sha, b, 2); 139296465Sdelphij} 140193645Ssimon 141193645Ssimonstatic void hashstring(SHA_CTX *sha, const char *string) 142296465Sdelphij{ 143193645Ssimon size_t l = strlen(string); 144193645Ssimon 145193645Ssimon hashlength(sha, l); 146193645Ssimon SHA1_Update(sha, string, l); 147296465Sdelphij} 148193645Ssimon 149193645Ssimonstatic void hashbn(SHA_CTX *sha, const BIGNUM *bn) 150296465Sdelphij{ 151193645Ssimon size_t l = BN_num_bytes(bn); 152193645Ssimon unsigned char *bin = OPENSSL_malloc(l); 153193645Ssimon 154193645Ssimon hashlength(sha, l); 155193645Ssimon BN_bn2bin(bn, bin); 156193645Ssimon SHA1_Update(sha, bin, l); 157193645Ssimon OPENSSL_free(bin); 158296465Sdelphij} 159193645Ssimon 160193645Ssimon/* h=hash(g, g^r, g^x, name) */ 161193645Ssimonstatic void zkp_hash(BIGNUM *h, const BIGNUM *zkpg, const JPAKE_STEP_PART *p, 162296465Sdelphij const char *proof_name) 163296465Sdelphij{ 164193645Ssimon unsigned char md[SHA_DIGEST_LENGTH]; 165193645Ssimon SHA_CTX sha; 166193645Ssimon 167296465Sdelphij /* 168296465Sdelphij * XXX: hash should not allow moving of the boundaries - Java code 169296465Sdelphij * is flawed in this respect. Length encoding seems simplest. 170296465Sdelphij */ 171193645Ssimon SHA1_Init(&sha); 172193645Ssimon hashbn(&sha, zkpg); 173193645Ssimon assert(!BN_is_zero(p->zkpx.gr)); 174193645Ssimon hashbn(&sha, p->zkpx.gr); 175193645Ssimon hashbn(&sha, p->gx); 176193645Ssimon hashstring(&sha, proof_name); 177193645Ssimon SHA1_Final(md, &sha); 178193645Ssimon BN_bin2bn(md, SHA_DIGEST_LENGTH, h); 179296465Sdelphij} 180193645Ssimon 181193645Ssimon/* 182193645Ssimon * Prove knowledge of x 183193645Ssimon * Note that p->gx has already been calculated 184193645Ssimon */ 185193645Ssimonstatic void generate_zkp(JPAKE_STEP_PART *p, const BIGNUM *x, 186296465Sdelphij const BIGNUM *zkpg, JPAKE_CTX *ctx) 187296465Sdelphij{ 188193645Ssimon BIGNUM *r = BN_new(); 189193645Ssimon BIGNUM *h = BN_new(); 190193645Ssimon BIGNUM *t = BN_new(); 191193645Ssimon 192296465Sdelphij /*- 193193645Ssimon * r in [0,q) 194193645Ssimon * XXX: Java chooses r in [0, 2^160) - i.e. distribution not uniform 195193645Ssimon */ 196193645Ssimon BN_rand_range(r, ctx->p.q); 197296465Sdelphij /* g^r */ 198193645Ssimon BN_mod_exp(p->zkpx.gr, zkpg, r, ctx->p.p, ctx->ctx); 199193645Ssimon 200296465Sdelphij /* h=hash... */ 201193645Ssimon zkp_hash(h, zkpg, p, ctx->p.name); 202193645Ssimon 203296465Sdelphij /* b = r - x*h */ 204193645Ssimon BN_mod_mul(t, x, h, ctx->p.q, ctx->ctx); 205193645Ssimon BN_mod_sub(p->zkpx.b, r, t, ctx->p.q, ctx->ctx); 206193645Ssimon 207296465Sdelphij /* cleanup */ 208193645Ssimon BN_free(t); 209193645Ssimon BN_free(h); 210193645Ssimon BN_free(r); 211296465Sdelphij} 212193645Ssimon 213193645Ssimonstatic int verify_zkp(const JPAKE_STEP_PART *p, const BIGNUM *zkpg, 214296465Sdelphij JPAKE_CTX *ctx) 215296465Sdelphij{ 216193645Ssimon BIGNUM *h = BN_new(); 217193645Ssimon BIGNUM *t1 = BN_new(); 218193645Ssimon BIGNUM *t2 = BN_new(); 219193645Ssimon BIGNUM *t3 = BN_new(); 220193645Ssimon int ret = 0; 221193645Ssimon 222193645Ssimon zkp_hash(h, zkpg, p, ctx->p.peer_name); 223193645Ssimon 224296465Sdelphij /* t1 = g^b */ 225193645Ssimon BN_mod_exp(t1, zkpg, p->zkpx.b, ctx->p.p, ctx->ctx); 226296465Sdelphij /* t2 = (g^x)^h = g^{hx} */ 227193645Ssimon BN_mod_exp(t2, p->gx, h, ctx->p.p, ctx->ctx); 228296465Sdelphij /* t3 = t1 * t2 = g^{hx} * g^b = g^{hx+b} = g^r (allegedly) */ 229193645Ssimon BN_mod_mul(t3, t1, t2, ctx->p.p, ctx->ctx); 230193645Ssimon 231296465Sdelphij /* verify t3 == g^r */ 232296465Sdelphij if (BN_cmp(t3, p->zkpx.gr) == 0) 233296465Sdelphij ret = 1; 234193645Ssimon else 235296465Sdelphij JPAKEerr(JPAKE_F_VERIFY_ZKP, JPAKE_R_ZKP_VERIFY_FAILED); 236193645Ssimon 237296465Sdelphij /* cleanup */ 238193645Ssimon BN_free(t3); 239193645Ssimon BN_free(t2); 240193645Ssimon BN_free(t1); 241193645Ssimon BN_free(h); 242193645Ssimon 243193645Ssimon return ret; 244296465Sdelphij} 245193645Ssimon 246193645Ssimonstatic void generate_step_part(JPAKE_STEP_PART *p, const BIGNUM *x, 247296465Sdelphij const BIGNUM *g, JPAKE_CTX *ctx) 248296465Sdelphij{ 249193645Ssimon BN_mod_exp(p->gx, g, x, ctx->p.p, ctx->ctx); 250193645Ssimon generate_zkp(p, x, g, ctx); 251296465Sdelphij} 252193645Ssimon 253193645Ssimon/* Generate each party's random numbers. xa is in [0, q), xb is in [1, q). */ 254193645Ssimonstatic void genrand(JPAKE_CTX *ctx) 255296465Sdelphij{ 256193645Ssimon BIGNUM *qm1; 257193645Ssimon 258296465Sdelphij /* xa in [0, q) */ 259193645Ssimon BN_rand_range(ctx->xa, ctx->p.q); 260193645Ssimon 261296465Sdelphij /* q-1 */ 262193645Ssimon qm1 = BN_new(); 263193645Ssimon BN_copy(qm1, ctx->p.q); 264193645Ssimon BN_sub_word(qm1, 1); 265193645Ssimon 266296465Sdelphij /* ... and xb in [0, q-1) */ 267193645Ssimon BN_rand_range(ctx->xb, qm1); 268296465Sdelphij /* [1, q) */ 269193645Ssimon BN_add_word(ctx->xb, 1); 270193645Ssimon 271296465Sdelphij /* cleanup */ 272193645Ssimon BN_free(qm1); 273296465Sdelphij} 274193645Ssimon 275193645Ssimonint JPAKE_STEP1_generate(JPAKE_STEP1 *send, JPAKE_CTX *ctx) 276296465Sdelphij{ 277193645Ssimon genrand(ctx); 278193645Ssimon generate_step_part(&send->p1, ctx->xa, ctx->p.g, ctx); 279193645Ssimon generate_step_part(&send->p2, ctx->xb, ctx->p.g, ctx); 280193645Ssimon 281193645Ssimon return 1; 282296465Sdelphij} 283193645Ssimon 284216166Ssimon/* g^x is a legal value */ 285216166Ssimonstatic int is_legal(const BIGNUM *gx, const JPAKE_CTX *ctx) 286296465Sdelphij{ 287216166Ssimon BIGNUM *t; 288216166Ssimon int res; 289216166Ssimon 290296465Sdelphij if (BN_is_negative(gx) || BN_is_zero(gx) || BN_cmp(gx, ctx->p.p) >= 0) 291296465Sdelphij return 0; 292296465Sdelphij 293216166Ssimon t = BN_new(); 294216166Ssimon BN_mod_exp(t, gx, ctx->p.q, ctx->p.p, ctx->ctx); 295216166Ssimon res = BN_is_one(t); 296216166Ssimon BN_free(t); 297216166Ssimon 298216166Ssimon return res; 299296465Sdelphij} 300216166Ssimon 301193645Ssimonint JPAKE_STEP1_process(JPAKE_CTX *ctx, const JPAKE_STEP1 *received) 302296465Sdelphij{ 303296465Sdelphij if (!is_legal(received->p1.gx, ctx)) { 304296465Sdelphij JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, 305296465Sdelphij JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL); 306296465Sdelphij return 0; 307296465Sdelphij } 308216166Ssimon 309296465Sdelphij if (!is_legal(received->p2.gx, ctx)) { 310296465Sdelphij JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, 311296465Sdelphij JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL); 312296465Sdelphij return 0; 313296465Sdelphij } 314216166Ssimon 315216166Ssimon /* verify their ZKP(xc) */ 316296465Sdelphij if (!verify_zkp(&received->p1, ctx->p.g, ctx)) { 317296465Sdelphij JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X3_FAILED); 318296465Sdelphij return 0; 319296465Sdelphij } 320193645Ssimon 321216166Ssimon /* verify their ZKP(xd) */ 322296465Sdelphij if (!verify_zkp(&received->p2, ctx->p.g, ctx)) { 323296465Sdelphij JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X4_FAILED); 324296465Sdelphij return 0; 325296465Sdelphij } 326193645Ssimon 327216166Ssimon /* g^xd != 1 */ 328296465Sdelphij if (BN_is_one(received->p2.gx)) { 329296465Sdelphij JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X4_IS_ONE); 330296465Sdelphij return 0; 331296465Sdelphij } 332193645Ssimon 333296465Sdelphij /* Save the bits we need for later */ 334193645Ssimon BN_copy(ctx->p.gxc, received->p1.gx); 335193645Ssimon BN_copy(ctx->p.gxd, received->p2.gx); 336193645Ssimon 337193645Ssimon return 1; 338296465Sdelphij} 339193645Ssimon 340193645Ssimonint JPAKE_STEP2_generate(JPAKE_STEP2 *send, JPAKE_CTX *ctx) 341296465Sdelphij{ 342193645Ssimon BIGNUM *t1 = BN_new(); 343193645Ssimon BIGNUM *t2 = BN_new(); 344193645Ssimon 345296465Sdelphij /*- 346193645Ssimon * X = g^{(xa + xc + xd) * xb * s} 347193645Ssimon * t1 = g^xa 348193645Ssimon */ 349193645Ssimon BN_mod_exp(t1, ctx->p.g, ctx->xa, ctx->p.p, ctx->ctx); 350296465Sdelphij /* t2 = t1 * g^{xc} = g^{xa} * g^{xc} = g^{xa + xc} */ 351193645Ssimon BN_mod_mul(t2, t1, ctx->p.gxc, ctx->p.p, ctx->ctx); 352296465Sdelphij /* t1 = t2 * g^{xd} = g^{xa + xc + xd} */ 353193645Ssimon BN_mod_mul(t1, t2, ctx->p.gxd, ctx->p.p, ctx->ctx); 354296465Sdelphij /* t2 = xb * s */ 355193645Ssimon BN_mod_mul(t2, ctx->xb, ctx->secret, ctx->p.q, ctx->ctx); 356193645Ssimon 357296465Sdelphij /*- 358193645Ssimon * ZKP(xb * s) 359193645Ssimon * XXX: this is kinda funky, because we're using 360193645Ssimon * 361193645Ssimon * g' = g^{xa + xc + xd} 362193645Ssimon * 363193645Ssimon * as the generator, which means X is g'^{xb * s} 364193645Ssimon * X = t1^{t2} = t1^{xb * s} = g^{(xa + xc + xd) * xb * s} 365193645Ssimon */ 366193645Ssimon generate_step_part(send, t2, t1, ctx); 367193645Ssimon 368296465Sdelphij /* cleanup */ 369193645Ssimon BN_free(t1); 370193645Ssimon BN_free(t2); 371193645Ssimon 372193645Ssimon return 1; 373296465Sdelphij} 374193645Ssimon 375193645Ssimon/* gx = g^{xc + xa + xb} * xd * s */ 376193645Ssimonstatic int compute_key(JPAKE_CTX *ctx, const BIGNUM *gx) 377296465Sdelphij{ 378193645Ssimon BIGNUM *t1 = BN_new(); 379193645Ssimon BIGNUM *t2 = BN_new(); 380193645Ssimon BIGNUM *t3 = BN_new(); 381193645Ssimon 382296465Sdelphij /*- 383193645Ssimon * K = (gx/g^{xb * xd * s})^{xb} 384193645Ssimon * = (g^{(xc + xa + xb) * xd * s - xb * xd *s})^{xb} 385193645Ssimon * = (g^{(xa + xc) * xd * s})^{xb} 386193645Ssimon * = g^{(xa + xc) * xb * xd * s} 387193645Ssimon * [which is the same regardless of who calculates it] 388193645Ssimon */ 389193645Ssimon 390296465Sdelphij /* t1 = (g^{xd})^{xb} = g^{xb * xd} */ 391193645Ssimon BN_mod_exp(t1, ctx->p.gxd, ctx->xb, ctx->p.p, ctx->ctx); 392296465Sdelphij /* t2 = -s = q-s */ 393193645Ssimon BN_sub(t2, ctx->p.q, ctx->secret); 394296465Sdelphij /* t3 = t1^t2 = g^{-xb * xd * s} */ 395193645Ssimon BN_mod_exp(t3, t1, t2, ctx->p.p, ctx->ctx); 396296465Sdelphij /* t1 = gx * t3 = X/g^{xb * xd * s} */ 397193645Ssimon BN_mod_mul(t1, gx, t3, ctx->p.p, ctx->ctx); 398296465Sdelphij /* K = t1^{xb} */ 399193645Ssimon BN_mod_exp(ctx->key, t1, ctx->xb, ctx->p.p, ctx->ctx); 400193645Ssimon 401296465Sdelphij /* cleanup */ 402193645Ssimon BN_free(t3); 403193645Ssimon BN_free(t2); 404193645Ssimon BN_free(t1); 405193645Ssimon 406193645Ssimon return 1; 407296465Sdelphij} 408193645Ssimon 409193645Ssimonint JPAKE_STEP2_process(JPAKE_CTX *ctx, const JPAKE_STEP2 *received) 410296465Sdelphij{ 411193645Ssimon BIGNUM *t1 = BN_new(); 412193645Ssimon BIGNUM *t2 = BN_new(); 413193645Ssimon int ret = 0; 414193645Ssimon 415296465Sdelphij /*- 416193645Ssimon * g' = g^{xc + xa + xb} [from our POV] 417193645Ssimon * t1 = xa + xb 418193645Ssimon */ 419193645Ssimon BN_mod_add(t1, ctx->xa, ctx->xb, ctx->p.q, ctx->ctx); 420296465Sdelphij /* t2 = g^{t1} = g^{xa+xb} */ 421193645Ssimon BN_mod_exp(t2, ctx->p.g, t1, ctx->p.p, ctx->ctx); 422296465Sdelphij /* t1 = g^{xc} * t2 = g^{xc + xa + xb} */ 423193645Ssimon BN_mod_mul(t1, ctx->p.gxc, t2, ctx->p.p, ctx->ctx); 424193645Ssimon 425296465Sdelphij if (verify_zkp(received, t1, ctx)) 426296465Sdelphij ret = 1; 427193645Ssimon else 428296465Sdelphij JPAKEerr(JPAKE_F_JPAKE_STEP2_PROCESS, JPAKE_R_VERIFY_B_FAILED); 429193645Ssimon 430193645Ssimon compute_key(ctx, received->gx); 431193645Ssimon 432296465Sdelphij /* cleanup */ 433193645Ssimon BN_free(t2); 434193645Ssimon BN_free(t1); 435193645Ssimon 436193645Ssimon return ret; 437296465Sdelphij} 438193645Ssimon 439193645Ssimonstatic void quickhashbn(unsigned char *md, const BIGNUM *bn) 440296465Sdelphij{ 441193645Ssimon SHA_CTX sha; 442193645Ssimon 443193645Ssimon SHA1_Init(&sha); 444193645Ssimon hashbn(&sha, bn); 445193645Ssimon SHA1_Final(md, &sha); 446296465Sdelphij} 447193645Ssimon 448193645Ssimonvoid JPAKE_STEP3A_init(JPAKE_STEP3A *s3a) 449296465Sdelphij{ 450296465Sdelphij} 451193645Ssimon 452193645Ssimonint JPAKE_STEP3A_generate(JPAKE_STEP3A *send, JPAKE_CTX *ctx) 453296465Sdelphij{ 454193645Ssimon quickhashbn(send->hhk, ctx->key); 455193645Ssimon SHA1(send->hhk, sizeof send->hhk, send->hhk); 456193645Ssimon 457193645Ssimon return 1; 458296465Sdelphij} 459193645Ssimon 460193645Ssimonint JPAKE_STEP3A_process(JPAKE_CTX *ctx, const JPAKE_STEP3A *received) 461296465Sdelphij{ 462193645Ssimon unsigned char hhk[SHA_DIGEST_LENGTH]; 463193645Ssimon 464193645Ssimon quickhashbn(hhk, ctx->key); 465193645Ssimon SHA1(hhk, sizeof hhk, hhk); 466296465Sdelphij if (memcmp(hhk, received->hhk, sizeof hhk)) { 467296465Sdelphij JPAKEerr(JPAKE_F_JPAKE_STEP3A_PROCESS, 468296465Sdelphij JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH); 469296465Sdelphij return 0; 470296465Sdelphij } 471193645Ssimon return 1; 472296465Sdelphij} 473193645Ssimon 474193645Ssimonvoid JPAKE_STEP3A_release(JPAKE_STEP3A *s3a) 475296465Sdelphij{ 476296465Sdelphij} 477193645Ssimon 478193645Ssimonvoid JPAKE_STEP3B_init(JPAKE_STEP3B *s3b) 479296465Sdelphij{ 480296465Sdelphij} 481193645Ssimon 482193645Ssimonint JPAKE_STEP3B_generate(JPAKE_STEP3B *send, JPAKE_CTX *ctx) 483296465Sdelphij{ 484193645Ssimon quickhashbn(send->hk, ctx->key); 485193645Ssimon 486193645Ssimon return 1; 487296465Sdelphij} 488193645Ssimon 489193645Ssimonint JPAKE_STEP3B_process(JPAKE_CTX *ctx, const JPAKE_STEP3B *received) 490296465Sdelphij{ 491193645Ssimon unsigned char hk[SHA_DIGEST_LENGTH]; 492193645Ssimon 493193645Ssimon quickhashbn(hk, ctx->key); 494296465Sdelphij if (memcmp(hk, received->hk, sizeof hk)) { 495296465Sdelphij JPAKEerr(JPAKE_F_JPAKE_STEP3B_PROCESS, JPAKE_R_HASH_OF_KEY_MISMATCH); 496296465Sdelphij return 0; 497296465Sdelphij } 498193645Ssimon return 1; 499296465Sdelphij} 500193645Ssimon 501193645Ssimonvoid JPAKE_STEP3B_release(JPAKE_STEP3B *s3b) 502296465Sdelphij{ 503296465Sdelphij} 504193645Ssimon 505193645Ssimonconst BIGNUM *JPAKE_get_shared_key(JPAKE_CTX *ctx) 506296465Sdelphij{ 507193645Ssimon return ctx->key; 508296465Sdelphij} 509