int JPAKE_STEP2_process(JPAKE_CTX *ctx, const JPAKE_STEP2 *received) { BIGNUM *t1 = BN_new(); BIGNUM *t2 = BN_new(); int ret = 0; /* * g' = g^{xc + xa + xb} [from our POV] * t1 = xa + xb */ BN_mod_add(t1, ctx->xa, ctx->xb, ctx->p.q, ctx->ctx); /* t2 = g^{t1} = g^{xa+xb} */ BN_mod_exp(t2, ctx->p.g, t1, ctx->p.p, ctx->ctx); /* t1 = g^{xc} * t2 = g^{xc + xa + xb} */ BN_mod_mul(t1, ctx->p.gxc, t2, ctx->p.p, ctx->ctx); if(verify_zkp(received, t1, ctx)) ret = 1; else JPAKEerr(JPAKE_F_JPAKE_STEP2_PROCESS, JPAKE_R_VERIFY_B_FAILED); compute_key(ctx, received->gx); /* cleanup */ BN_free(t2); BN_free(t1); return ret; }
static int verify_zkp(const JPAKE_STEP_PART *p, const BIGNUM *zkpg, JPAKE_CTX *ctx) { BIGNUM *h = BN_new(); BIGNUM *t1 = BN_new(); BIGNUM *t2 = BN_new(); BIGNUM *t3 = BN_new(); int ret = 0; zkp_hash(h, zkpg, p, ctx->p.peer_name); /* t1 = g^b */ BN_mod_exp(t1, zkpg, p->zkpx.b, ctx->p.p, ctx->ctx); /* t2 = (g^x)^h = g^{hx} */ BN_mod_exp(t2, p->gx, h, ctx->p.p, ctx->ctx); /* t3 = t1 * t2 = g^{hx} * g^b = g^{hx+b} = g^r (allegedly) */ BN_mod_mul(t3, t1, t2, ctx->p.p, ctx->ctx); /* verify t3 == g^r */ if(BN_cmp(t3, p->zkpx.gr) == 0) ret = 1; else JPAKEerr(JPAKE_F_VERIFY_ZKP, JPAKE_R_ZKP_VERIFY_FAILED); /* cleanup */ BN_free(t3); BN_free(t2); BN_free(t1); BN_free(h); return ret; }
int JPAKE_STEP3B_process(JPAKE_CTX *ctx, const JPAKE_STEP3B *received) { unsigned char hk[SHA_DIGEST_LENGTH]; quickhashbn(hk, ctx->key); if (memcmp(hk, received->hk, sizeof hk)) { JPAKEerr(JPAKE_F_JPAKE_STEP3B_PROCESS, JPAKE_R_HASH_OF_KEY_MISMATCH); return 0; } return 1; }
int JPAKE_STEP1_process(JPAKE_CTX *ctx, const JPAKE_STEP1 *received) { if(!is_legal(received->p1.gx, ctx)) { JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL); return 0; } if(!is_legal(received->p2.gx, ctx)) { JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL); return 0; } /* verify their ZKP(xc) */ if(!verify_zkp(&received->p1, ctx->p.g, ctx)) { JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X3_FAILED); return 0; } /* verify their ZKP(xd) */ if(!verify_zkp(&received->p2, ctx->p.g, ctx)) { JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X4_FAILED); return 0; } /* g^xd != 1 */ if(BN_is_one(received->p2.gx)) { JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X4_IS_ONE); return 0; } /* Save the bits we need for later */ BN_copy(ctx->p.gxc, received->p1.gx); BN_copy(ctx->p.gxd, received->p2.gx); return 1; }
int JPAKE_STEP3A_process(JPAKE_CTX *ctx, const JPAKE_STEP3A *received) { unsigned char hhk[SHA_DIGEST_LENGTH]; quickhashbn(hhk, ctx->key); SHA1(hhk, sizeof hhk, hhk); if(TINYCLR_SSL_MEMCMP(hhk, received->hhk, sizeof hhk)) { JPAKEerr(JPAKE_F_JPAKE_STEP3A_PROCESS, JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH); return 0; } return 1; }