SHA1_Update(sha, string, l);
}
-static void hashbn(SHA_CTX *sha, const BIGNUM *bn)
+static int hashbn(SHA_CTX *sha, const BIGNUM *bn)
{
size_t l = BN_num_bytes(bn);
unsigned char *bin = OPENSSL_malloc(l);
+ if (bin == NULL)
+ return 0;
+
hashlength(sha, l);
BN_bn2bin(bn, bin);
SHA1_Update(sha, bin, l);
OPENSSL_free(bin);
+ return 1;
}
/* h=hash(g, g^r, g^x, name) */
-static void zkp_hash(BIGNUM *h, const BIGNUM *zkpg, const JPAKE_STEP_PART *p,
+static int zkp_hash(BIGNUM *h, const BIGNUM *zkpg, const JPAKE_STEP_PART *p,
const char *proof_name)
{
unsigned char md[SHA_DIGEST_LENGTH];
* is flawed in this respect. Length encoding seems simplest.
*/
SHA1_Init(&sha);
- hashbn(&sha, zkpg);
+ if (!hashbn(&sha, zkpg))
+ return 0;
OPENSSL_assert(!BN_is_zero(p->zkpx.gr));
- hashbn(&sha, p->zkpx.gr);
- hashbn(&sha, p->gx);
+ if (!hashbn(&sha, p->zkpx.gr))
+ return 0;
+ if (!hashbn(&sha, p->gx))
+ return 0;
hashstring(&sha, proof_name);
SHA1_Final(md, &sha);
BN_bin2bn(md, SHA_DIGEST_LENGTH, h);
+ return 1;
}
/*
* Prove knowledge of x
* Note that p->gx has already been calculated
*/
-static void generate_zkp(JPAKE_STEP_PART *p, const BIGNUM *x,
+static int generate_zkp(JPAKE_STEP_PART *p, const BIGNUM *x,
const BIGNUM *zkpg, JPAKE_CTX *ctx)
{
+ int res = 0;
BIGNUM *r = BN_new();
BIGNUM *h = BN_new();
BIGNUM *t = BN_new();
BN_mod_exp(p->zkpx.gr, zkpg, r, ctx->p.p, ctx->ctx);
/* h=hash... */
- zkp_hash(h, zkpg, p, ctx->p.name);
+ if (!zkp_hash(h, zkpg, p, ctx->p.name))
+ goto end;
/* b = r - x*h */
BN_mod_mul(t, x, h, ctx->p.q, ctx->ctx);
BN_mod_sub(p->zkpx.b, r, t, ctx->p.q, ctx->ctx);
+ res = 1;
+end:
/* cleanup */
BN_free(t);
BN_free(h);
BN_free(r);
+ return res;
}
static int verify_zkp(const JPAKE_STEP_PART *p, const BIGNUM *zkpg,
BIGNUM *t3 = BN_new();
int ret = 0;
- zkp_hash(h, zkpg, p, ctx->p.peer_name);
+ if (!zkp_hash(h, zkpg, p, ctx->p.peer_name))
+ goto end;
/* t1 = g^b */
BN_mod_exp(t1, zkpg, p->zkpx.b, ctx->p.p, ctx->ctx);
else
JPAKEerr(JPAKE_F_VERIFY_ZKP, JPAKE_R_ZKP_VERIFY_FAILED);
+end:
/* cleanup */
BN_free(t3);
BN_free(t2);
return ret;
}
-static void generate_step_part(JPAKE_STEP_PART *p, const BIGNUM *x,
+static int generate_step_part(JPAKE_STEP_PART *p, const BIGNUM *x,
const BIGNUM *g, JPAKE_CTX *ctx)
{
BN_mod_exp(p->gx, g, x, ctx->p.p, ctx->ctx);
- generate_zkp(p, x, g, ctx);
+ if (!generate_zkp(p, x, g, ctx))
+ return 0;
+ return 1;
}
/* Generate each party's random numbers. xa is in [0, q), xb is in [1, q). */
int JPAKE_STEP1_generate(JPAKE_STEP1 *send, JPAKE_CTX *ctx)
{
genrand(ctx);
- generate_step_part(&send->p1, ctx->xa, ctx->p.g, ctx);
- generate_step_part(&send->p2, ctx->xb, ctx->p.g, ctx);
+ if (!generate_step_part(&send->p1, ctx->xa, ctx->p.g, ctx))
+ return 0;
+ if (!generate_step_part(&send->p2, ctx->xb, ctx->p.g, ctx))
+ return 0;
return 1;
}
int JPAKE_STEP2_generate(JPAKE_STEP2 *send, JPAKE_CTX *ctx)
{
+ int ret;
+
BIGNUM *t1 = BN_new();
BIGNUM *t2 = BN_new();
* as the generator, which means X is g'^{xb * s}
* X = t1^{t2} = t1^{xb * s} = g^{(xa + xc + xd) * xb * s}
*/
- generate_step_part(send, t2, t1, ctx);
+ ret = generate_step_part(send, t2, t1, ctx);
/* cleanup */
BN_free(t1);
BN_free(t2);
- return 1;
+ return ret;
}
/* gx = g^{xc + xa + xb} * xd * s */
return ret;
}
-static void quickhashbn(unsigned char *md, const BIGNUM *bn)
+static int quickhashbn(unsigned char *md, const BIGNUM *bn)
{
SHA_CTX sha;
SHA1_Init(&sha);
- hashbn(&sha, bn);
+ if (!hashbn(&sha, bn))
+ return 0;
SHA1_Final(md, &sha);
+ return 1;
}
void JPAKE_STEP3A_init(JPAKE_STEP3A *s3a)
int JPAKE_STEP3A_generate(JPAKE_STEP3A *send, JPAKE_CTX *ctx)
{
- quickhashbn(send->hhk, ctx->key);
+ if (!quickhashbn(send->hhk, ctx->key))
+ return 0;
SHA1(send->hhk, sizeof send->hhk, send->hhk);
return 1;
{
unsigned char hhk[SHA_DIGEST_LENGTH];
- quickhashbn(hhk, ctx->key);
+ if (!quickhashbn(hhk, ctx->key))
+ return 0;
SHA1(hhk, sizeof hhk, hhk);
if(memcmp(hhk, received->hhk, sizeof hhk))
{
int JPAKE_STEP3B_generate(JPAKE_STEP3B *send, JPAKE_CTX *ctx)
{
- quickhashbn(send->hk, ctx->key);
-
+ if (!quickhashbn(send->hk, ctx->key))
+ return 0;
return 1;
}
{
unsigned char hk[SHA_DIGEST_LENGTH];
- quickhashbn(hk, ctx->key);
+ if (!quickhashbn(hk, ctx->key))
+ return 0;
if(memcmp(hk, received->hk, sizeof hk))
{
JPAKEerr(JPAKE_F_JPAKE_STEP3B_PROCESS, JPAKE_R_HASH_OF_KEY_MISMATCH);