/*
 *
 *    Copyright (c) 2017 Google LLC.
 *    All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

#include "ecjpake.h"

#include <openssl/crypto.h>
#include <openssl/err.h>
#include <string.h>

#ifdef OPENSSL_IS_BORINGSSL
#include <assert.h>
#define OPENSSL_assert(TEST) (assert(TEST))
#endif

/*
 * In the definition, (xa, xb, xc, xd) are Alice's (x1, x2, x3, x4) or
 * Bob's (x3, x4, x1, x2).
 */

typedef struct {
    unsigned char *num;        /* Must be unique */
    size_t len;
} ECJPAKE_ID;

struct ECJPAKE_CTX {
    /* public values */
    ECJPAKE_ID local_id;
    ECJPAKE_ID peer_id;
    const EC_GROUP *group;     /* Elliptic Curve Group */
    EC_POINT *Gxc;             /* Alice's G*x3 or Bob's G*x1 */
    EC_POINT *Gxd;             /* Alice's G*x4 or Bob's G*x2 */
    /* secret values - should not be revealed publicly and
                       should be cleared when released */
    BIGNUM *secret;            /* The shared secret */
    BN_CTX *ctx;
    BIGNUM *xa;                /* Alice's x1 or Bob's x3 */
    BIGNUM *xb;                /* Alice's x2 or Bob's x4 */
    unsigned char key[SHA256_DIGEST_LENGTH]; /* The calculated (shared) key */
};

static int zkp_init(ECJPAKE_ZKP *zkp, const EC_GROUP *group)
{
    zkp->Gr = EC_POINT_new(group);
    if (zkp->Gr == NULL)
        return 0;
    zkp->b = BN_new();
    if (zkp->b == NULL)
        return 0;
    return 1;
}

static void zkp_release(ECJPAKE_ZKP *zkp)
{
    if (zkp->b != NULL)
        BN_free(zkp->b);
    if (zkp->Gr != NULL)
        EC_POINT_free(zkp->Gr);
}

#define step_part_init       ECJPAKE_STEP2_init
#define step_part_release    ECJPAKE_STEP2_release

int step_part_init(ECJPAKE_STEP_PART *p, const ECJPAKE_CTX *ctx)
{
    memset(p, 0, sizeof(*p));
    p->Gx = EC_POINT_new(ctx->group);
    if (p->Gx == NULL)
        goto err;
    if (!zkp_init(&p->zkpx, ctx->group))
        goto err;
    return 1;

err:
    ECJPAKEerr(ECJPAKE_F_STEP_PART_INIT, ERR_R_MALLOC_FAILURE);
    step_part_release(p);
    return 0;
}

void step_part_release(ECJPAKE_STEP_PART *p)
{
    zkp_release(&p->zkpx);
    if (p->Gx != NULL)
        EC_POINT_free(p->Gx);
}

int ECJPAKE_STEP1_init(ECJPAKE_STEP1 *s1, const ECJPAKE_CTX *ctx)
{
    if (!step_part_init(&s1->p1, ctx))
        return 0;
    if (!step_part_init(&s1->p2, ctx))
        return 0;
    return 1;
}

void ECJPAKE_STEP1_release(ECJPAKE_STEP1 *s1)
{
    step_part_release(&s1->p2);
    step_part_release(&s1->p1);
}

ECJPAKE_CTX *ECJPAKE_CTX_new(const EC_GROUP *group, const BIGNUM *secret,
                             const unsigned char *local_id_num,
                             const size_t local_id_len,
                             const unsigned char *peer_id_num,
                             const size_t peer_id_len)
{
    ECJPAKE_CTX *ctx = NULL;

    /* init ecjpake context */
    ctx = OPENSSL_malloc(sizeof(*ctx));
    if (ctx == NULL)
        goto err;
    memset(ctx, 0, sizeof(*ctx));

    /* init elliptic curve group */
    if (group == NULL)
        goto err;
    ctx->group = group;

    /* init local id */
    ctx->local_id.num = (unsigned char *)OPENSSL_malloc(local_id_len);
    if (ctx->local_id.num == NULL)
        goto err;
    memcpy(ctx->local_id.num, local_id_num, local_id_len);
    ctx->local_id.len = local_id_len;

    /* init peer id */
    ctx->peer_id.num = (unsigned char *)OPENSSL_malloc(peer_id_len);
    if (ctx->peer_id.num == NULL)
        goto err;
    memcpy(ctx->peer_id.num, peer_id_num, peer_id_len);
    ctx->peer_id.len = peer_id_len;

    /* init secret */
    ctx->secret = BN_dup(secret);
    if (ctx->secret == NULL)
        goto err;

    /* init remaining ecjpake context fields */
    ctx->Gxc = EC_POINT_new(ctx->group);
    if (ctx->Gxc == NULL)
        goto err;
    ctx->Gxd = EC_POINT_new(ctx->group);
    if (ctx->Gxd == NULL)
        goto err;
    ctx->xa = BN_new();
    if (ctx->xa == NULL)
        goto err;
    ctx->xb = BN_new();
    if (ctx->xb == NULL)
        goto err;
    ctx->ctx = BN_CTX_new();
    if (ctx->ctx == NULL)
        goto err;

    return ctx;

err:
    ECJPAKEerr(ECJPAKE_F_ECJPAKE_CTX_NEW, ERR_R_MALLOC_FAILURE);
    ECJPAKE_CTX_free(ctx);
    return NULL;
}

void ECJPAKE_CTX_free(ECJPAKE_CTX *ctx)
{
    if (ctx != NULL) {
        if (ctx->ctx != NULL)
            BN_CTX_free(ctx->ctx);
        if (ctx->xb != NULL)
            BN_clear_free(ctx->xb);
        if (ctx->xa != NULL)
            BN_clear_free(ctx->xa);
        if (ctx->Gxd != NULL)
            EC_POINT_free(ctx->Gxd);
        if (ctx->Gxc != NULL)
            EC_POINT_free(ctx->Gxc);
        if (ctx->secret != NULL)
            BN_clear_free(ctx->secret);
        if (ctx->peer_id.num != NULL)
            OPENSSL_free(ctx->peer_id.num);
        if (ctx->local_id.num != NULL)
            OPENSSL_free(ctx->local_id.num);
        OPENSSL_free(ctx);
    }
}

static void hashlength(SHA256_CTX *sha, size_t l)
{
    unsigned char b[2];

    OPENSSL_assert(l <= 0xffff);
    b[0] = l >> 8;
    b[1] = l & 0xff;
    SHA256_Update(sha, b, 2);
}

static int hashpoint_default(ECJPAKE_CTX *ctx, SHA256_CTX *sha,
                             const EC_POINT *point)
{
    size_t point_len;
    unsigned char *point_oct = NULL;
    int ret = 0;

    point_len = EC_POINT_point2oct(ctx->group, point,
                                   POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
    if (point_len == 0)
        goto err;

    point_oct = (unsigned char *)OPENSSL_malloc(point_len);
    if (point_oct == NULL)
        goto err;

    point_len = EC_POINT_point2oct(ctx->group, point,
                                   POINT_CONVERSION_UNCOMPRESSED, point_oct,
                                   point_len, ctx->ctx);
    if (point_len == 0)
        goto err;

    hashlength(sha, point_len);
    SHA256_Update(sha, point_oct, point_len);
    ret = 1;

err:
    if (point_oct != NULL)
        OPENSSL_free(point_oct);
    return ret;
}

static ECJPAKE_HASHPOINT_FUNC_PTR hashpoint = &hashpoint_default;

void ECJPAKE_Set_HashECPoint(ECJPAKE_HASHPOINT_FUNC_PTR hashpoint_custom)
{
    hashpoint = hashpoint_custom;
}

/* h = hash(G, G*r, G*x, ecjpake_id) */
static int zkp_hash(ECJPAKE_CTX *ctx, BIGNUM *h, const EC_POINT *zkpG,
                    const ECJPAKE_STEP_PART *p, const int use_local_id)
{
    unsigned char md[SHA256_DIGEST_LENGTH];
    SHA256_CTX sha;

    SHA256_Init(&sha);
    if (!hashpoint(ctx, &sha, zkpG))
        goto err;
    if (!hashpoint(ctx, &sha, p->zkpx.Gr))
        goto err;
    if (!hashpoint(ctx, &sha, p->Gx))
        goto err;
    if (use_local_id)
        SHA256_Update(&sha, ctx->local_id.num, ctx->local_id.len);
    else
        SHA256_Update(&sha, ctx->peer_id.num, ctx->peer_id.len);
    SHA256_Final(md, &sha);
    if (BN_bin2bn(md, SHA256_DIGEST_LENGTH, h) == NULL)
        goto err;
    return 1;

err:
    ECJPAKEerr(ECJPAKE_F_ZKP_HASH, ERR_R_MALLOC_FAILURE);
    return 0;
}

/* Generate random number in [1, n - 1] ( i.e. [1, n) ) */
static int genrand(BIGNUM *rnd, const BIGNUM *n)
{
    BIGNUM *nm1 = NULL;
    int ret = 0;

    nm1 = BN_new();
    if (nm1 == NULL)
        goto err;
    /* n - 1 */
    if (!BN_copy(nm1, n))
        goto err;
    if (!BN_sub_word(nm1, 1))
        goto err;
    /* random number in [0, n - 1) */
    if (!BN_rand_range(rnd, nm1))
        goto err;
    /* [1, n) */
    if (!BN_add_word(rnd, 1))
        goto err;
    ret = 1;

err:
    if (!ret)
        ECJPAKEerr(ECJPAKE_F_GENRAND, ERR_R_MALLOC_FAILURE);
    if (nm1 != NULL)
        BN_free(nm1);
    return ret;
}

/* Prove knowledge of x. (Note that p->Gx has already been calculated) */
static int generate_zkp(ECJPAKE_STEP_PART *p, const BIGNUM *x,
                        const EC_POINT *zkpG, ECJPAKE_CTX *ctx)
{
    BIGNUM *order = NULL;
    BIGNUM *r = NULL;
    BIGNUM *h = NULL;
    BIGNUM *t = NULL;
    int ret = 0;

    order = BN_new();
    if (order == NULL)
        goto err;
    if (!EC_GROUP_get_order(ctx->group, order, ctx->ctx))
        goto err;
    /* r in [1,n-1] */
    r = BN_new();
    if (r == NULL)
        goto err;
    if (!genrand(r, order))
        goto err;
    /* G * r */
    if (!EC_POINT_mul(ctx->group, p->zkpx.Gr, NULL, zkpG, r, ctx->ctx))
        goto err;
    /* h = hash(G, G * r, G * x, ecjpake_id) */
    h = BN_new();
    if (h == NULL)
        goto err;
    if (!zkp_hash(ctx, h, zkpG, p, 1))
        goto err;
    /* b = r - x*h */
    t = BN_new();
    if (t == NULL)
        goto err;
    if (!BN_mod_mul(t, x, h, order, ctx->ctx))
        goto err;
    if (!BN_mod_sub(p->zkpx.b, r, t, order, ctx->ctx))
        goto err;
    ret = 1;

err:
    if (!ret)
        ECJPAKEerr(ECJPAKE_F_GENERATE_ZKP, ERR_R_MALLOC_FAILURE);
    if (t != NULL)
        BN_free(t);
    if (h != NULL)
        BN_free(h);
    if (r != NULL)
        BN_free(r);
    if (order != NULL)
        BN_free(order);
    return ret;
}

static int verify_zkp(const ECJPAKE_STEP_PART *p, const EC_POINT *zkpG,
                      ECJPAKE_CTX *ctx)
{
    BIGNUM *h = NULL;
    EC_POINT *point1 = NULL;
    EC_POINT *point2 = NULL;
    int ret = 0;

    /* h = hash(G, G * r, G * x, ecjpake_id) */
    h = BN_new();
    if (h == NULL)
        goto err;
    if (!zkp_hash(ctx, h, zkpG, p, 0))
        goto err;
    /* point1 = G * b */
    point1 = EC_POINT_new(ctx->group);
    if (point1 == NULL)
        goto err;
    if (!EC_POINT_mul(ctx->group, point1, NULL, zkpG, p->zkpx.b, ctx->ctx))
        goto err;
    /* point2 = (G * x) * h = G * {h * x} */
    point2 = EC_POINT_new(ctx->group);
    if (point2 == NULL)
        goto err;
    if (!EC_POINT_mul(ctx->group, point2, NULL, p->Gx, h, ctx->ctx))
        goto err;
    /* point2 = point1 + point2 = G*{hx} + G*b = G*{hx+b} = G*r (allegedly) */
    if (!EC_POINT_add(ctx->group, point2, point1, point2, ctx->ctx))
        goto err;
    /* verify (point2 == G * r) */
    if (0 != EC_POINT_cmp(ctx->group, point2, p->zkpx.Gr, ctx->ctx))
    {
        ECJPAKEerr(ECJPAKE_F_VERIFY_ZKP, ECJPAKE_R_ZKP_VERIFY_FAILED);
        goto clean;
    }

    ret = 1;
    goto clean;

err:
    ECJPAKEerr(ECJPAKE_F_VERIFY_ZKP, ERR_R_MALLOC_FAILURE);
clean:
    if (point2 != NULL)
        EC_POINT_free(point2);
    if (point1 != NULL)
        EC_POINT_free(point1);
    if (h != NULL)
        BN_free(h);
    return ret;
}

static int step_part_generate(ECJPAKE_STEP_PART *p, const BIGNUM *x,
                              const EC_POINT *G, ECJPAKE_CTX *ctx)
{
    if (!EC_POINT_mul(ctx->group, p->Gx, NULL, G, x, ctx->ctx))
        goto err;
    if (!generate_zkp(p, x, G, ctx))
        goto err;
    return 1;

err:
    ECJPAKEerr(ECJPAKE_F_STEP_PART_GENERATE, ERR_R_MALLOC_FAILURE);
    return 0;
}

int ECJPAKE_STEP1_generate(ECJPAKE_STEP1 *send, ECJPAKE_CTX *ctx)
{
    BIGNUM *order = NULL;
    const EC_POINT *generator = NULL;
    int ret = 0;

    order = BN_new();
    if (order == NULL)
        goto err;
    if (!EC_GROUP_get_order(ctx->group, order, ctx->ctx))
        goto err;

    if (!genrand(ctx->xa, order))
        goto err;
    if (!genrand(ctx->xb, order))
        goto err;

    generator = EC_GROUP_get0_generator(ctx->group);
    if (!step_part_generate(&send->p1, ctx->xa, generator, ctx))
        goto err;
    if (!step_part_generate(&send->p2, ctx->xb, generator, ctx))
        goto err;

    ret = 1;

err:
    if (!ret)
        ECJPAKEerr(ECJPAKE_F_ECJPAKE_STEP1_GENERATE, ERR_R_MALLOC_FAILURE);
    if (order != NULL)
        BN_free(order);
    return ret;
}

/*-
 * Elliptic Curve Point Validity Check.
 */
static int EC_POINT_is_legal(const EC_POINT *point, const EC_GROUP *group)
{
    EC_KEY *eckey = NULL;
    int legal = 0;

    if (point == NULL || group == NULL)
    {
        ECJPAKEerr(ECJPAKE_F_EC_POINT_IS_LEGAL, ERR_R_PASSED_NULL_PARAMETER);
        goto err;
    }
    if ((eckey = EC_KEY_new()) == NULL)
    {
        ECJPAKEerr(ECJPAKE_F_EC_POINT_IS_LEGAL, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    if (!EC_KEY_set_group(eckey, group))
    {
        ECJPAKEerr(ECJPAKE_F_EC_POINT_IS_LEGAL, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    if (!EC_KEY_set_public_key(eckey, point))
    {
        ECJPAKEerr(ECJPAKE_F_EC_POINT_IS_LEGAL, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    if (!EC_KEY_check_key(eckey))
    {
        ECJPAKEerr(ECJPAKE_F_EC_POINT_IS_LEGAL, ECJPAKE_R_G_IS_NOT_LEGAL);
        goto err;
    }

    legal = 1;

err:
    EC_KEY_free(eckey);

    return legal;
}

int ECJPAKE_STEP1_process(ECJPAKE_CTX *ctx, const ECJPAKE_STEP1 *received)
{

    /* check Gxc is a legal point on Elliptic Curve */
    if (!EC_POINT_is_legal(received->p1.Gx, ctx->group))
    {
        ECJPAKEerr(ECJPAKE_F_ECJPAKE_STEP1_PROCESS,
                   ECJPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL);
        return 0;
    }

    /* check Gxd is a legal point on Elliptic Curve */
    if (!EC_POINT_is_legal(received->p2.Gx, ctx->group))
    {
        ECJPAKEerr(ECJPAKE_F_ECJPAKE_STEP1_PROCESS,
                   ECJPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL);
        return 0;
    }

    /* verify ZKP(xc) */
    if (!verify_zkp(&received->p1, EC_GROUP_get0_generator(ctx->group), ctx))
    {
        ECJPAKEerr(ECJPAKE_F_ECJPAKE_STEP1_PROCESS,
                   ECJPAKE_R_VERIFY_X3_FAILED);
        return 0;
    }

    /* verify ZKP(xd) */
    if (!verify_zkp(&received->p2, EC_GROUP_get0_generator(ctx->group), ctx))
    {
        ECJPAKEerr(ECJPAKE_F_ECJPAKE_STEP1_PROCESS,
                   ECJPAKE_R_VERIFY_X4_FAILED);
        return 0;
    }

    /* Save the points we need for later */
    if (!EC_POINT_copy(ctx->Gxc, received->p1.Gx) ||
        !EC_POINT_copy(ctx->Gxd, received->p2.Gx))
    {
        ECJPAKEerr(ECJPAKE_F_ECJPAKE_STEP1_PROCESS, ERR_R_MALLOC_FAILURE);
        return 0;
    }

    return 1;
}

int ECJPAKE_STEP2_generate(ECJPAKE_STEP2 *send, ECJPAKE_CTX *ctx)
{
    EC_POINT *point = NULL;
    BIGNUM *order = NULL;
    BIGNUM *xbs = NULL;
    int ret = 0;

    /*-
     * X = G * {(xa + xc + xd) * xb * s}
     */
    point = EC_POINT_new(ctx->group);
    if (point == NULL)
        goto err;
    /* point = G * xa */
    if (!EC_POINT_mul(ctx->group, point, NULL,
                      EC_GROUP_get0_generator(ctx->group), ctx->xa, ctx->ctx))
        goto err;
    /* point = G * xa + G * xc = G * {xa + xc} */
    if (!EC_POINT_add(ctx->group, point, point, ctx->Gxc, ctx->ctx))
        goto err;
    /* point = G * {xa + xc} + G * xd = G * {xa + xc + xd} */
    if (!EC_POINT_add(ctx->group, point, point, ctx->Gxd, ctx->ctx))
        goto err;
    /* xbs = xb * s */
    order = BN_new();
    if (order == NULL)
        goto err;
    xbs = BN_new();
    if (xbs == NULL)
        goto err;
    if (!EC_GROUP_get_order(ctx->group, order, ctx->ctx))
        goto err;
    if (!BN_mod_mul(xbs, ctx->xb, ctx->secret, order, ctx->ctx))
        goto err;

    /*-
     * ZKP(xb * s)
     * For STEP2 the generator is:
     *     G' = G * {xa + xc + xd}
     * which means X is G' * {xb * s}
     *     X  = G' * {xb * s} = G * {(xa + xc + xd) * xb * s}
     */
    if (!step_part_generate(send, xbs, point, ctx))
        goto err;
    ret = 1;

err:
    if (!ret)
        ECJPAKEerr(ECJPAKE_F_ECJPAKE_STEP2_GENERATE, ERR_R_MALLOC_FAILURE);
    if (xbs != NULL)
        BN_clear_free(xbs);
    if (order != NULL)
        BN_free(order);
    if (point != NULL)
        EC_POINT_free(point);
    return ret;
}

/* Gx = G * {(xc + xa + xb) * xd * secret} */
static int compute_key(ECJPAKE_CTX *ctx, const EC_POINT *Gx)
{
    EC_POINT *point = NULL;
    SHA256_CTX sha;
    int ret = 0;

    /*-
     * K = (Gx - G * {xb * xd * secret}) * xb
     *   = (G * {(xc + xa + xb) * xd * secret - xb * xd * secret}) * xb
     *   = (G * {(xc + xa) * xd * secret}) * xb
     *   =  G * {(xa + xc) * xb * xd * secret}
     * [which is the same regardless of who calculates it]
     */

    /* point = (G * xd) * xb = G * {xb * xd} */
    point = EC_POINT_new(ctx->group);
    if (point == NULL)
        goto err;
    if (!EC_POINT_mul(ctx->group, point, NULL, ctx->Gxd, ctx->xb, ctx->ctx))
        goto err;
    /* point = - G * {xb * xd} */
    if (!EC_POINT_invert(ctx->group, point, ctx->ctx))
        goto err;
    /* point = - G * {xb * xd * secret} */
    if (!EC_POINT_mul(ctx->group, point, NULL, point, ctx->secret, ctx->ctx))
        goto err;
    /* point = Gx - G * {xb * xd * secret} */
    if (!EC_POINT_add(ctx->group, point, Gx, point, ctx->ctx))
        goto err;
    /* point = point * xb */
    if (!EC_POINT_mul(ctx->group, point, NULL, point, ctx->xb, ctx->ctx))
        goto err;
    /* Hash point to generate shared secret key */
    SHA256_Init(&sha);
    if (!hashpoint(ctx, &sha, point))
        goto err;
    SHA256_Final(ctx->key, &sha);
    ret = 1;

err:
    if (!ret)
        ECJPAKEerr(ECJPAKE_F_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
    if (point != NULL)
        EC_POINT_clear_free(point);
    return ret;
}

int ECJPAKE_STEP2_process(ECJPAKE_CTX *ctx, const ECJPAKE_STEP2 *received)
{
    BIGNUM *order = NULL;
    BIGNUM *tmp = NULL;
    EC_POINT *point = NULL;
    int ret = 0;

    /* Get Order */
    order = BN_new();
    if (order == NULL)
        goto err;
    if (!EC_GROUP_get_order(ctx->group, order, ctx->ctx))
        goto err;
    /* G' = G * {xc + xa + xb} */
    /* tmp = xa + xb */
    tmp = BN_new();
    if (tmp == NULL)
        goto err;
    if (!BN_mod_add(tmp, ctx->xa, ctx->xb, order, ctx->ctx))
        goto err;
    /* point = G * {xa + xb} */
    point = EC_POINT_new(ctx->group);
    if (point == NULL)
        goto err;
    if (!EC_POINT_mul(ctx->group, point, NULL,
                      EC_GROUP_get0_generator(ctx->group), tmp, ctx->ctx))
        goto err;
    /* point = G * {xc + xa + xb} */
    if (!EC_POINT_add(ctx->group, point, ctx->Gxc, point, ctx->ctx))
        goto err;
    /* Verify ZKP */
    if (!verify_zkp(received, point, ctx))
    {
        ECJPAKEerr(ECJPAKE_F_ECJPAKE_STEP2_PROCESS, ECJPAKE_R_VERIFY_X4S_FAILED);
        goto clean;
    }
    /* calculate shared secret (key) */
    if (!compute_key(ctx, received->Gx))
        goto err;

    ret = 1;
    goto clean;

err:
    ECJPAKEerr(ECJPAKE_F_ECJPAKE_STEP2_PROCESS, ERR_R_MALLOC_FAILURE);
clean:
    if (point != NULL)
        EC_POINT_free(point);
    if (tmp != NULL)
        BN_free(tmp);
    if (order != NULL)
        BN_free(order);
    return ret;
}

void ECJPAKE_STEP3A_init(ECJPAKE_STEP3A *s3a)
{
}

int ECJPAKE_STEP3A_generate(ECJPAKE_STEP3A *send, ECJPAKE_CTX *ctx)
{
    SHA256(ctx->key, sizeof ctx->key, send->hhk);
    SHA256(send->hhk, sizeof send->hhk, send->hhk);

    return 1;
}

int ECJPAKE_STEP3A_process(ECJPAKE_CTX *ctx, const ECJPAKE_STEP3A *received)
{
    unsigned char hhk[SHA256_DIGEST_LENGTH];

    SHA256(ctx->key, sizeof ctx->key, hhk);
    SHA256(hhk, sizeof hhk, hhk);
    if (memcmp(hhk, received->hhk, sizeof hhk)) {
        ECJPAKEerr(ECJPAKE_F_ECJPAKE_STEP3A_PROCESS,
                   ECJPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH);
        return 0;
    }
    return 1;
}

void ECJPAKE_STEP3A_release(ECJPAKE_STEP3A *s3a)
{
}

void ECJPAKE_STEP3B_init(ECJPAKE_STEP3B *s3b)
{
}

int ECJPAKE_STEP3B_generate(ECJPAKE_STEP3B *send, ECJPAKE_CTX *ctx)
{
    SHA256(ctx->key, sizeof(ctx->key), send->hk);
    return 1;
}

int ECJPAKE_STEP3B_process(ECJPAKE_CTX *ctx, const ECJPAKE_STEP3B *received)
{
    unsigned char hk[SHA256_DIGEST_LENGTH];

    SHA256(ctx->key, sizeof(ctx->key), hk);
    if (memcmp(hk, received->hk, sizeof(hk))) {
        ECJPAKEerr(ECJPAKE_F_ECJPAKE_STEP3B_PROCESS,
                   ECJPAKE_R_HASH_OF_KEY_MISMATCH);
        return 0;
    }
    return 1;
}

void ECJPAKE_STEP3B_release(ECJPAKE_STEP3B *s3b)
{
}

const EC_GROUP *ECJPAKE_get_ecGroup(const ECJPAKE_CTX *ctx)
{
    return ctx->group;
}

const unsigned char *ECJPAKE_get_shared_key(const ECJPAKE_CTX *ctx)
{
    return ctx->key;
}
