if (secret) PORT_ZFree(secret, len);
KEA_Derive(SECItem *prime,            SECItem *public1,            SECItem *public2,            SECItem *private1,            SECItem *private2,           SECItem *derivedSecret){    mp_int p, Y, R, r, x, t, u, w;    mp_err err;    if (!prime || !public1 || !public2 || !private1 || !private2 ||        !derivedSecret) {	PORT_SetError(SEC_ERROR_INVALID_ARGS);	return SECFailure;    }    MP_DIGITS(&p) = 0;    MP_DIGITS(&Y) = 0;    MP_DIGITS(&R) = 0;    MP_DIGITS(&r) = 0;    MP_DIGITS(&x) = 0;    MP_DIGITS(&t) = 0;    MP_DIGITS(&u) = 0;    MP_DIGITS(&w) = 0;    CHECK_MPI_OK( mp_init(&p) );    CHECK_MPI_OK( mp_init(&Y) );    CHECK_MPI_OK( mp_init(&R) );    CHECK_MPI_OK( mp_init(&r) );    CHECK_MPI_OK( mp_init(&x) );    CHECK_MPI_OK( mp_init(&t) );    CHECK_MPI_OK( mp_init(&u) );    CHECK_MPI_OK( mp_init(&w) );    SECITEM_TO_MPINT(*prime,    &p);    SECITEM_TO_MPINT(*public1,  &Y);    SECITEM_TO_MPINT(*public2,  &R);    SECITEM_TO_MPINT(*private1, &r);    SECITEM_TO_MPINT(*private2, &x);    /* t = DH(Y, r, p) = Y ** r mod p */    CHECK_MPI_OK( mp_exptmod(&Y, &r, &p, &t) );    /* u = DH(R, x, p) = R ** x mod p */    CHECK_MPI_OK( mp_exptmod(&R, &x, &p, &u) );    /* w = (t + u) mod p */    CHECK_MPI_OK( mp_addmod(&t, &u, &p, &w) );    /* allocate output buffer and return */    SECITEM_AllocItem(NULL, derivedSecret, KEA_DERIVED_SECRET_LEN);    err = mp_to_fixlen_octets(&w, derivedSecret->data, KEA_DERIVED_SECRET_LEN);    if (err > 0) err = MP_OKAY;cleanup:    mp_clear(&p);    mp_clear(&Y);    mp_clear(&R);    mp_clear(&r);    mp_clear(&x);    mp_clear(&t);    mp_clear(&u);    mp_clear(&w);    if (err) {	MP_TO_SEC_ERROR(err);	return SECFailure;    }    return SECSuccess;}