+static void output_Zhash(FILE *out, int exout,
+ DH *dh, BIGNUM *peerkey, const EVP_MD *md,
+ unsigned char *rhash, size_t rhashlen)
+ {
+ unsigned char *Z;
+ unsigned char chash[EVP_MAX_MD_SIZE];
+ int Zlen;
+ if (rhash == NULL)
+ {
+ rhashlen = M_EVP_MD_size(md);
+ if (!DH_generate_key(dh))
+ exit (1);
+ do_bn_print_name(out, "YephemIUT", dh->pub_key);
+ if (exout)
+ do_bn_print_name(out, "XephemIUT", dh->priv_key);
+ }
+ Z = OPENSSL_malloc(BN_num_bytes(dh->p));
+ if (!Z)
+ exit(1);
+ Zlen = DH_compute_key_padded(Z, peerkey, dh);
+ if (exout)
+ OutputValue("Z", Z, Zlen, out, 0);
+ FIPS_digest(Z, Zlen, chash, NULL, md);
+ OutputValue(rhash ? "IUTHashZZ" : "HashZZ", chash, rhashlen, out, 0);
+ if (rhash)
+ {
+ fprintf(out, "Result = %s\n",
+ memcmp(chash, rhash, rhashlen) ? "F" : "P");
+ }
+ else
+ {
+ BN_clear_free(dh->priv_key);
+ BN_clear_free(dh->pub_key);
+ dh->priv_key = NULL;
+ dh->pub_key = NULL;
+ }
+ OPENSSL_cleanse(Z, Zlen);
+ OPENSSL_free(Z);
+ }
+