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 8193645Ssimon/* 9193645Ssimon * In the definition, (xa, xb, xc, xd) are Alice's (x1, x2, x3, x4) or 10193645Ssimon * Bob's (x3, x4, x1, x2). If you see what I mean. 11193645Ssimon */ 12193645Ssimon 13296341Sdelphijtypedef struct { 14296341Sdelphij char *name; /* Must be unique */ 15193645Ssimon char *peer_name; 16193645Ssimon BIGNUM *p; 17193645Ssimon BIGNUM *g; 18193645Ssimon BIGNUM *q; 19296341Sdelphij BIGNUM *gxc; /* Alice's g^{x3} or Bob's g^{x1} */ 20296341Sdelphij BIGNUM *gxd; /* Alice's g^{x4} or Bob's g^{x2} */ 21296341Sdelphij} JPAKE_CTX_PUBLIC; 22193645Ssimon 23296341Sdelphijstruct JPAKE_CTX { 24193645Ssimon JPAKE_CTX_PUBLIC p; 25296341Sdelphij BIGNUM *secret; /* The shared secret */ 26193645Ssimon BN_CTX *ctx; 27296341Sdelphij BIGNUM *xa; /* Alice's x1 or Bob's x3 */ 28296341Sdelphij BIGNUM *xb; /* Alice's x2 or Bob's x4 */ 29296341Sdelphij BIGNUM *key; /* The calculated (shared) key */ 30296341Sdelphij}; 31193645Ssimon 32193645Ssimonstatic void JPAKE_ZKP_init(JPAKE_ZKP *zkp) 33296341Sdelphij{ 34193645Ssimon zkp->gr = BN_new(); 35193645Ssimon zkp->b = BN_new(); 36296341Sdelphij} 37193645Ssimon 38193645Ssimonstatic void JPAKE_ZKP_release(JPAKE_ZKP *zkp) 39296341Sdelphij{ 40193645Ssimon BN_free(zkp->b); 41193645Ssimon BN_free(zkp->gr); 42296341Sdelphij} 43193645Ssimon 44193645Ssimon/* Two birds with one stone - make the global name as expected */ 45296341Sdelphij#define JPAKE_STEP_PART_init JPAKE_STEP2_init 46296341Sdelphij#define JPAKE_STEP_PART_release JPAKE_STEP2_release 47193645Ssimon 48193645Ssimonvoid JPAKE_STEP_PART_init(JPAKE_STEP_PART *p) 49296341Sdelphij{ 50193645Ssimon p->gx = BN_new(); 51193645Ssimon JPAKE_ZKP_init(&p->zkpx); 52296341Sdelphij} 53193645Ssimon 54193645Ssimonvoid JPAKE_STEP_PART_release(JPAKE_STEP_PART *p) 55296341Sdelphij{ 56193645Ssimon JPAKE_ZKP_release(&p->zkpx); 57193645Ssimon BN_free(p->gx); 58296341Sdelphij} 59193645Ssimon 60193645Ssimonvoid JPAKE_STEP1_init(JPAKE_STEP1 *s1) 61296341Sdelphij{ 62193645Ssimon JPAKE_STEP_PART_init(&s1->p1); 63193645Ssimon JPAKE_STEP_PART_init(&s1->p2); 64296341Sdelphij} 65193645Ssimon 66193645Ssimonvoid JPAKE_STEP1_release(JPAKE_STEP1 *s1) 67296341Sdelphij{ 68193645Ssimon JPAKE_STEP_PART_release(&s1->p2); 69193645Ssimon JPAKE_STEP_PART_release(&s1->p1); 70296341Sdelphij} 71193645Ssimon 72193645Ssimonstatic void JPAKE_CTX_init(JPAKE_CTX *ctx, const char *name, 73296341Sdelphij const char *peer_name, const BIGNUM *p, 74296341Sdelphij const BIGNUM *g, const BIGNUM *q, 75296341Sdelphij const BIGNUM *secret) 76296341Sdelphij{ 77193645Ssimon ctx->p.name = OPENSSL_strdup(name); 78193645Ssimon ctx->p.peer_name = OPENSSL_strdup(peer_name); 79193645Ssimon ctx->p.p = BN_dup(p); 80193645Ssimon ctx->p.g = BN_dup(g); 81193645Ssimon ctx->p.q = BN_dup(q); 82193645Ssimon ctx->secret = BN_dup(secret); 83193645Ssimon 84193645Ssimon ctx->p.gxc = BN_new(); 85193645Ssimon ctx->p.gxd = BN_new(); 86193645Ssimon 87193645Ssimon ctx->xa = BN_new(); 88193645Ssimon ctx->xb = BN_new(); 89193645Ssimon ctx->key = BN_new(); 90193645Ssimon ctx->ctx = BN_CTX_new(); 91296341Sdelphij} 92296341Sdelphij 93193645Ssimonstatic void JPAKE_CTX_release(JPAKE_CTX *ctx) 94296341Sdelphij{ 95193645Ssimon BN_CTX_free(ctx->ctx); 96193645Ssimon BN_clear_free(ctx->key); 97193645Ssimon BN_clear_free(ctx->xb); 98193645Ssimon BN_clear_free(ctx->xa); 99193645Ssimon 100193645Ssimon BN_free(ctx->p.gxd); 101193645Ssimon BN_free(ctx->p.gxc); 102193645Ssimon 103193645Ssimon BN_clear_free(ctx->secret); 104193645Ssimon BN_free(ctx->p.q); 105193645Ssimon BN_free(ctx->p.g); 106193645Ssimon BN_free(ctx->p.p); 107193645Ssimon OPENSSL_free(ctx->p.peer_name); 108193645Ssimon OPENSSL_free(ctx->p.name); 109193645Ssimon 110193645Ssimon memset(ctx, '\0', sizeof *ctx); 111296341Sdelphij} 112296341Sdelphij 113193645SsimonJPAKE_CTX *JPAKE_CTX_new(const char *name, const char *peer_name, 114296341Sdelphij const BIGNUM *p, const BIGNUM *g, const BIGNUM *q, 115296341Sdelphij const BIGNUM *secret) 116296341Sdelphij{ 117193645Ssimon JPAKE_CTX *ctx = OPENSSL_malloc(sizeof *ctx); 118193645Ssimon 119193645Ssimon JPAKE_CTX_init(ctx, name, peer_name, p, g, q, secret); 120193645Ssimon 121193645Ssimon return ctx; 122296341Sdelphij} 123193645Ssimon 124193645Ssimonvoid JPAKE_CTX_free(JPAKE_CTX *ctx) 125296341Sdelphij{ 126193645Ssimon JPAKE_CTX_release(ctx); 127193645Ssimon OPENSSL_free(ctx); 128296341Sdelphij} 129193645Ssimon 130193645Ssimonstatic void hashlength(SHA_CTX *sha, size_t l) 131296341Sdelphij{ 132193645Ssimon unsigned char b[2]; 133193645Ssimon 134238405Sjkim OPENSSL_assert(l <= 0xffff); 135193645Ssimon b[0] = l >> 8; 136296341Sdelphij b[1] = l & 0xff; 137193645Ssimon SHA1_Update(sha, b, 2); 138296341Sdelphij} 139193645Ssimon 140193645Ssimonstatic void hashstring(SHA_CTX *sha, const char *string) 141296341Sdelphij{ 142193645Ssimon size_t l = strlen(string); 143193645Ssimon 144193645Ssimon hashlength(sha, l); 145193645Ssimon SHA1_Update(sha, string, l); 146296341Sdelphij} 147193645Ssimon 148193645Ssimonstatic void hashbn(SHA_CTX *sha, const BIGNUM *bn) 149296341Sdelphij{ 150193645Ssimon size_t l = BN_num_bytes(bn); 151193645Ssimon unsigned char *bin = OPENSSL_malloc(l); 152193645Ssimon 153193645Ssimon hashlength(sha, l); 154193645Ssimon BN_bn2bin(bn, bin); 155193645Ssimon SHA1_Update(sha, bin, l); 156193645Ssimon OPENSSL_free(bin); 157296341Sdelphij} 158193645Ssimon 159193645Ssimon/* h=hash(g, g^r, g^x, name) */ 160193645Ssimonstatic void zkp_hash(BIGNUM *h, const BIGNUM *zkpg, const JPAKE_STEP_PART *p, 161296341Sdelphij const char *proof_name) 162296341Sdelphij{ 163193645Ssimon unsigned char md[SHA_DIGEST_LENGTH]; 164193645Ssimon SHA_CTX sha; 165193645Ssimon 166296341Sdelphij /* 167296341Sdelphij * XXX: hash should not allow moving of the boundaries - Java code 168296341Sdelphij * is flawed in this respect. Length encoding seems simplest. 169296341Sdelphij */ 170193645Ssimon SHA1_Init(&sha); 171193645Ssimon hashbn(&sha, zkpg); 172238405Sjkim OPENSSL_assert(!BN_is_zero(p->zkpx.gr)); 173193645Ssimon hashbn(&sha, p->zkpx.gr); 174193645Ssimon hashbn(&sha, p->gx); 175193645Ssimon hashstring(&sha, proof_name); 176193645Ssimon SHA1_Final(md, &sha); 177193645Ssimon BN_bin2bn(md, SHA_DIGEST_LENGTH, h); 178296341Sdelphij} 179193645Ssimon 180193645Ssimon/* 181193645Ssimon * Prove knowledge of x 182193645Ssimon * Note that p->gx has already been calculated 183193645Ssimon */ 184193645Ssimonstatic void generate_zkp(JPAKE_STEP_PART *p, const BIGNUM *x, 185296341Sdelphij const BIGNUM *zkpg, JPAKE_CTX *ctx) 186296341Sdelphij{ 187193645Ssimon BIGNUM *r = BN_new(); 188193645Ssimon BIGNUM *h = BN_new(); 189193645Ssimon BIGNUM *t = BN_new(); 190193645Ssimon 191296341Sdelphij /*- 192193645Ssimon * r in [0,q) 193193645Ssimon * XXX: Java chooses r in [0, 2^160) - i.e. distribution not uniform 194193645Ssimon */ 195193645Ssimon BN_rand_range(r, ctx->p.q); 196296341Sdelphij /* g^r */ 197193645Ssimon BN_mod_exp(p->zkpx.gr, zkpg, r, ctx->p.p, ctx->ctx); 198193645Ssimon 199296341Sdelphij /* h=hash... */ 200193645Ssimon zkp_hash(h, zkpg, p, ctx->p.name); 201193645Ssimon 202296341Sdelphij /* b = r - x*h */ 203193645Ssimon BN_mod_mul(t, x, h, ctx->p.q, ctx->ctx); 204193645Ssimon BN_mod_sub(p->zkpx.b, r, t, ctx->p.q, ctx->ctx); 205193645Ssimon 206296341Sdelphij /* cleanup */ 207193645Ssimon BN_free(t); 208193645Ssimon BN_free(h); 209193645Ssimon BN_free(r); 210296341Sdelphij} 211193645Ssimon 212193645Ssimonstatic int verify_zkp(const JPAKE_STEP_PART *p, const BIGNUM *zkpg, 213296341Sdelphij JPAKE_CTX *ctx) 214296341Sdelphij{ 215193645Ssimon BIGNUM *h = BN_new(); 216193645Ssimon BIGNUM *t1 = BN_new(); 217193645Ssimon BIGNUM *t2 = BN_new(); 218193645Ssimon BIGNUM *t3 = BN_new(); 219193645Ssimon int ret = 0; 220193645Ssimon 221193645Ssimon zkp_hash(h, zkpg, p, ctx->p.peer_name); 222193645Ssimon 223296341Sdelphij /* t1 = g^b */ 224193645Ssimon BN_mod_exp(t1, zkpg, p->zkpx.b, ctx->p.p, ctx->ctx); 225296341Sdelphij /* t2 = (g^x)^h = g^{hx} */ 226193645Ssimon BN_mod_exp(t2, p->gx, h, ctx->p.p, ctx->ctx); 227296341Sdelphij /* t3 = t1 * t2 = g^{hx} * g^b = g^{hx+b} = g^r (allegedly) */ 228193645Ssimon BN_mod_mul(t3, t1, t2, ctx->p.p, ctx->ctx); 229193645Ssimon 230296341Sdelphij /* verify t3 == g^r */ 231296341Sdelphij if (BN_cmp(t3, p->zkpx.gr) == 0) 232296341Sdelphij ret = 1; 233193645Ssimon else 234296341Sdelphij JPAKEerr(JPAKE_F_VERIFY_ZKP, JPAKE_R_ZKP_VERIFY_FAILED); 235193645Ssimon 236296341Sdelphij /* cleanup */ 237193645Ssimon BN_free(t3); 238193645Ssimon BN_free(t2); 239193645Ssimon BN_free(t1); 240193645Ssimon BN_free(h); 241193645Ssimon 242193645Ssimon return ret; 243296341Sdelphij} 244193645Ssimon 245193645Ssimonstatic void generate_step_part(JPAKE_STEP_PART *p, const BIGNUM *x, 246296341Sdelphij const BIGNUM *g, JPAKE_CTX *ctx) 247296341Sdelphij{ 248193645Ssimon BN_mod_exp(p->gx, g, x, ctx->p.p, ctx->ctx); 249193645Ssimon generate_zkp(p, x, g, ctx); 250296341Sdelphij} 251193645Ssimon 252193645Ssimon/* Generate each party's random numbers. xa is in [0, q), xb is in [1, q). */ 253193645Ssimonstatic void genrand(JPAKE_CTX *ctx) 254296341Sdelphij{ 255193645Ssimon BIGNUM *qm1; 256193645Ssimon 257296341Sdelphij /* xa in [0, q) */ 258193645Ssimon BN_rand_range(ctx->xa, ctx->p.q); 259193645Ssimon 260296341Sdelphij /* q-1 */ 261193645Ssimon qm1 = BN_new(); 262193645Ssimon BN_copy(qm1, ctx->p.q); 263193645Ssimon BN_sub_word(qm1, 1); 264193645Ssimon 265296341Sdelphij /* ... and xb in [0, q-1) */ 266193645Ssimon BN_rand_range(ctx->xb, qm1); 267296341Sdelphij /* [1, q) */ 268193645Ssimon BN_add_word(ctx->xb, 1); 269193645Ssimon 270296341Sdelphij /* cleanup */ 271193645Ssimon BN_free(qm1); 272296341Sdelphij} 273193645Ssimon 274193645Ssimonint JPAKE_STEP1_generate(JPAKE_STEP1 *send, JPAKE_CTX *ctx) 275296341Sdelphij{ 276193645Ssimon genrand(ctx); 277193645Ssimon generate_step_part(&send->p1, ctx->xa, ctx->p.g, ctx); 278193645Ssimon generate_step_part(&send->p2, ctx->xb, ctx->p.g, ctx); 279193645Ssimon 280193645Ssimon return 1; 281296341Sdelphij} 282193645Ssimon 283216166Ssimon/* g^x is a legal value */ 284216166Ssimonstatic int is_legal(const BIGNUM *gx, const JPAKE_CTX *ctx) 285296341Sdelphij{ 286216166Ssimon BIGNUM *t; 287216166Ssimon int res; 288216166Ssimon 289296341Sdelphij if (BN_is_negative(gx) || BN_is_zero(gx) || BN_cmp(gx, ctx->p.p) >= 0) 290296341Sdelphij return 0; 291296341Sdelphij 292216166Ssimon t = BN_new(); 293216166Ssimon BN_mod_exp(t, gx, ctx->p.q, ctx->p.p, ctx->ctx); 294216166Ssimon res = BN_is_one(t); 295216166Ssimon BN_free(t); 296216166Ssimon 297216166Ssimon return res; 298296341Sdelphij} 299216166Ssimon 300193645Ssimonint JPAKE_STEP1_process(JPAKE_CTX *ctx, const JPAKE_STEP1 *received) 301296341Sdelphij{ 302296341Sdelphij if (!is_legal(received->p1.gx, ctx)) { 303296341Sdelphij JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, 304296341Sdelphij JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL); 305296341Sdelphij return 0; 306296341Sdelphij } 307216166Ssimon 308296341Sdelphij if (!is_legal(received->p2.gx, ctx)) { 309296341Sdelphij JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, 310296341Sdelphij JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL); 311296341Sdelphij return 0; 312296341Sdelphij } 313216166Ssimon 314296341Sdelphij /* verify their ZKP(xc) */ 315296341Sdelphij if (!verify_zkp(&received->p1, ctx->p.g, ctx)) { 316296341Sdelphij JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X3_FAILED); 317296341Sdelphij return 0; 318296341Sdelphij } 319193645Ssimon 320296341Sdelphij /* verify their ZKP(xd) */ 321296341Sdelphij if (!verify_zkp(&received->p2, ctx->p.g, ctx)) { 322296341Sdelphij JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X4_FAILED); 323296341Sdelphij return 0; 324296341Sdelphij } 325193645Ssimon 326296341Sdelphij /* g^xd != 1 */ 327296341Sdelphij if (BN_is_one(received->p2.gx)) { 328296341Sdelphij JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X4_IS_ONE); 329296341Sdelphij return 0; 330296341Sdelphij } 331193645Ssimon 332296341Sdelphij /* Save the bits we need for later */ 333193645Ssimon BN_copy(ctx->p.gxc, received->p1.gx); 334193645Ssimon BN_copy(ctx->p.gxd, received->p2.gx); 335193645Ssimon 336193645Ssimon return 1; 337296341Sdelphij} 338193645Ssimon 339193645Ssimonint JPAKE_STEP2_generate(JPAKE_STEP2 *send, JPAKE_CTX *ctx) 340296341Sdelphij{ 341193645Ssimon BIGNUM *t1 = BN_new(); 342193645Ssimon BIGNUM *t2 = BN_new(); 343193645Ssimon 344296341Sdelphij /*- 345193645Ssimon * X = g^{(xa + xc + xd) * xb * s} 346193645Ssimon * t1 = g^xa 347193645Ssimon */ 348193645Ssimon BN_mod_exp(t1, ctx->p.g, ctx->xa, ctx->p.p, ctx->ctx); 349296341Sdelphij /* t2 = t1 * g^{xc} = g^{xa} * g^{xc} = g^{xa + xc} */ 350193645Ssimon BN_mod_mul(t2, t1, ctx->p.gxc, ctx->p.p, ctx->ctx); 351296341Sdelphij /* t1 = t2 * g^{xd} = g^{xa + xc + xd} */ 352193645Ssimon BN_mod_mul(t1, t2, ctx->p.gxd, ctx->p.p, ctx->ctx); 353296341Sdelphij /* t2 = xb * s */ 354193645Ssimon BN_mod_mul(t2, ctx->xb, ctx->secret, ctx->p.q, ctx->ctx); 355193645Ssimon 356296341Sdelphij /*- 357193645Ssimon * ZKP(xb * s) 358193645Ssimon * XXX: this is kinda funky, because we're using 359193645Ssimon * 360193645Ssimon * g' = g^{xa + xc + xd} 361193645Ssimon * 362193645Ssimon * as the generator, which means X is g'^{xb * s} 363193645Ssimon * X = t1^{t2} = t1^{xb * s} = g^{(xa + xc + xd) * xb * s} 364193645Ssimon */ 365193645Ssimon generate_step_part(send, t2, t1, ctx); 366193645Ssimon 367296341Sdelphij /* cleanup */ 368193645Ssimon BN_free(t1); 369193645Ssimon BN_free(t2); 370193645Ssimon 371193645Ssimon return 1; 372296341Sdelphij} 373193645Ssimon 374193645Ssimon/* gx = g^{xc + xa + xb} * xd * s */ 375193645Ssimonstatic int compute_key(JPAKE_CTX *ctx, const BIGNUM *gx) 376296341Sdelphij{ 377193645Ssimon BIGNUM *t1 = BN_new(); 378193645Ssimon BIGNUM *t2 = BN_new(); 379193645Ssimon BIGNUM *t3 = BN_new(); 380193645Ssimon 381296341Sdelphij /*- 382193645Ssimon * K = (gx/g^{xb * xd * s})^{xb} 383193645Ssimon * = (g^{(xc + xa + xb) * xd * s - xb * xd *s})^{xb} 384193645Ssimon * = (g^{(xa + xc) * xd * s})^{xb} 385193645Ssimon * = g^{(xa + xc) * xb * xd * s} 386193645Ssimon * [which is the same regardless of who calculates it] 387193645Ssimon */ 388193645Ssimon 389296341Sdelphij /* t1 = (g^{xd})^{xb} = g^{xb * xd} */ 390193645Ssimon BN_mod_exp(t1, ctx->p.gxd, ctx->xb, ctx->p.p, ctx->ctx); 391296341Sdelphij /* t2 = -s = q-s */ 392193645Ssimon BN_sub(t2, ctx->p.q, ctx->secret); 393296341Sdelphij /* t3 = t1^t2 = g^{-xb * xd * s} */ 394193645Ssimon BN_mod_exp(t3, t1, t2, ctx->p.p, ctx->ctx); 395296341Sdelphij /* t1 = gx * t3 = X/g^{xb * xd * s} */ 396193645Ssimon BN_mod_mul(t1, gx, t3, ctx->p.p, ctx->ctx); 397296341Sdelphij /* K = t1^{xb} */ 398193645Ssimon BN_mod_exp(ctx->key, t1, ctx->xb, ctx->p.p, ctx->ctx); 399193645Ssimon 400296341Sdelphij /* cleanup */ 401193645Ssimon BN_free(t3); 402193645Ssimon BN_free(t2); 403193645Ssimon BN_free(t1); 404193645Ssimon 405193645Ssimon return 1; 406296341Sdelphij} 407193645Ssimon 408193645Ssimonint JPAKE_STEP2_process(JPAKE_CTX *ctx, const JPAKE_STEP2 *received) 409296341Sdelphij{ 410193645Ssimon BIGNUM *t1 = BN_new(); 411193645Ssimon BIGNUM *t2 = BN_new(); 412193645Ssimon int ret = 0; 413193645Ssimon 414296341Sdelphij /*- 415193645Ssimon * g' = g^{xc + xa + xb} [from our POV] 416193645Ssimon * t1 = xa + xb 417193645Ssimon */ 418193645Ssimon BN_mod_add(t1, ctx->xa, ctx->xb, ctx->p.q, ctx->ctx); 419296341Sdelphij /* t2 = g^{t1} = g^{xa+xb} */ 420193645Ssimon BN_mod_exp(t2, ctx->p.g, t1, ctx->p.p, ctx->ctx); 421296341Sdelphij /* t1 = g^{xc} * t2 = g^{xc + xa + xb} */ 422193645Ssimon BN_mod_mul(t1, ctx->p.gxc, t2, ctx->p.p, ctx->ctx); 423193645Ssimon 424296341Sdelphij if (verify_zkp(received, t1, ctx)) 425296341Sdelphij ret = 1; 426193645Ssimon else 427296341Sdelphij JPAKEerr(JPAKE_F_JPAKE_STEP2_PROCESS, JPAKE_R_VERIFY_B_FAILED); 428193645Ssimon 429193645Ssimon compute_key(ctx, received->gx); 430193645Ssimon 431296341Sdelphij /* cleanup */ 432193645Ssimon BN_free(t2); 433193645Ssimon BN_free(t1); 434193645Ssimon 435193645Ssimon return ret; 436296341Sdelphij} 437193645Ssimon 438193645Ssimonstatic void quickhashbn(unsigned char *md, const BIGNUM *bn) 439296341Sdelphij{ 440193645Ssimon SHA_CTX sha; 441193645Ssimon 442193645Ssimon SHA1_Init(&sha); 443193645Ssimon hashbn(&sha, bn); 444193645Ssimon SHA1_Final(md, &sha); 445296341Sdelphij} 446193645Ssimon 447193645Ssimonvoid JPAKE_STEP3A_init(JPAKE_STEP3A *s3a) 448296341Sdelphij{ 449296341Sdelphij} 450193645Ssimon 451193645Ssimonint JPAKE_STEP3A_generate(JPAKE_STEP3A *send, JPAKE_CTX *ctx) 452296341Sdelphij{ 453193645Ssimon quickhashbn(send->hhk, ctx->key); 454193645Ssimon SHA1(send->hhk, sizeof send->hhk, send->hhk); 455193645Ssimon 456193645Ssimon return 1; 457296341Sdelphij} 458193645Ssimon 459193645Ssimonint JPAKE_STEP3A_process(JPAKE_CTX *ctx, const JPAKE_STEP3A *received) 460296341Sdelphij{ 461193645Ssimon unsigned char hhk[SHA_DIGEST_LENGTH]; 462193645Ssimon 463193645Ssimon quickhashbn(hhk, ctx->key); 464193645Ssimon SHA1(hhk, sizeof hhk, hhk); 465296341Sdelphij if (memcmp(hhk, received->hhk, sizeof hhk)) { 466296341Sdelphij JPAKEerr(JPAKE_F_JPAKE_STEP3A_PROCESS, 467296341Sdelphij JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH); 468296341Sdelphij return 0; 469296341Sdelphij } 470193645Ssimon return 1; 471296341Sdelphij} 472193645Ssimon 473193645Ssimonvoid JPAKE_STEP3A_release(JPAKE_STEP3A *s3a) 474296341Sdelphij{ 475296341Sdelphij} 476193645Ssimon 477193645Ssimonvoid JPAKE_STEP3B_init(JPAKE_STEP3B *s3b) 478296341Sdelphij{ 479296341Sdelphij} 480193645Ssimon 481193645Ssimonint JPAKE_STEP3B_generate(JPAKE_STEP3B *send, JPAKE_CTX *ctx) 482296341Sdelphij{ 483193645Ssimon quickhashbn(send->hk, ctx->key); 484193645Ssimon 485193645Ssimon return 1; 486296341Sdelphij} 487193645Ssimon 488193645Ssimonint JPAKE_STEP3B_process(JPAKE_CTX *ctx, const JPAKE_STEP3B *received) 489296341Sdelphij{ 490193645Ssimon unsigned char hk[SHA_DIGEST_LENGTH]; 491193645Ssimon 492193645Ssimon quickhashbn(hk, ctx->key); 493296341Sdelphij if (memcmp(hk, received->hk, sizeof hk)) { 494296341Sdelphij JPAKEerr(JPAKE_F_JPAKE_STEP3B_PROCESS, JPAKE_R_HASH_OF_KEY_MISMATCH); 495296341Sdelphij return 0; 496296341Sdelphij } 497193645Ssimon return 1; 498296341Sdelphij} 499193645Ssimon 500193645Ssimonvoid JPAKE_STEP3B_release(JPAKE_STEP3B *s3b) 501296341Sdelphij{ 502296341Sdelphij} 503193645Ssimon 504193645Ssimonconst BIGNUM *JPAKE_get_shared_key(JPAKE_CTX *ctx) 505296341Sdelphij{ 506193645Ssimon return ctx->key; 507296341Sdelphij} 508