*
*/
+#define OPENSSL_FIPSAPI
#include <string.h>
#include <limits.h>
NULL, /* init */
NULL, /* finish */
#endif
- 0, /* flags */
+ ECDH_FLAG_FIPS_METHOD, /* flags */
NULL /* app_data */
};
BN_CTX *ctx;
EC_POINT *tmp=NULL;
BIGNUM *x=NULL, *y=NULL;
+ const BIGNUM *priv_key;
+ const EC_GROUP* group;
int ret= -1;
size_t buflen, len;
unsigned char *buf=NULL;
+#ifdef OPENSSL_FIPS
+ if(FIPS_selftest_failed())
+ {
+ FIPSerr(FIPS_F_ECDH_COMPUTE_KEY,FIPS_R_FIPS_SELFTEST_FAILED);
+ return -1;
+ }
+#endif
+
if (outlen > INT_MAX)
{
ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE); /* sort of, anyway */
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
- if (ecdh->priv_key == NULL)
+ priv_key = EC_KEY_get0_private_key(ecdh);
+ if (priv_key == NULL)
{
ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_NO_PRIVATE_VALUE);
goto err;
}
- if ((tmp=EC_POINT_new(ecdh->group)) == NULL)
+ group = EC_KEY_get0_group(ecdh);
+
+ if (EC_KEY_get_flags(ecdh) & EC_FLAG_COFACTOR_ECDH)
+ {
+ if (!EC_GROUP_get_cofactor(group, x, ctx) ||
+ !BN_mul(x, x, priv_key, ctx))
+ {
+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ priv_key = x;
+ }
+
+ if ((tmp=EC_POINT_new(group)) == NULL)
{
ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
goto err;
}
- if (!EC_POINT_mul(ecdh->group, tmp, NULL, pub_key, ecdh->priv_key, ctx))
+ if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx))
{
ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
goto err;
}
- if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecdh->group)) == NID_X9_62_prime_field)
+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
{
- if (!EC_POINT_get_affine_coordinates_GFp(ecdh->group, tmp, x, y, ctx))
+ if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx))
{
ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
goto err;
}
}
+#ifndef OPENSSL_NO_EC2M
else
{
- if (!EC_POINT_get_affine_coordinates_GF2m(ecdh->group, tmp, x, y, ctx))
+ if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx))
{
ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
goto err;
}
}
+#endif
- buflen = (EC_GROUP_get_degree(ecdh->group) + 7)/8;
+ buflen = (EC_GROUP_get_degree(group) + 7)/8;
len = BN_num_bytes(x);
if (len > buflen)
{
if (buf) OPENSSL_free(buf);
return(ret);
}
+
+#ifdef OPENSSL_FIPSCANISTER
+/* FIPS stanadlone version of ecdh_check: just return FIPS method */
+ECDH_DATA *fips_ecdh_check(EC_KEY *key)
+ {
+ static ECDH_DATA rv = {
+ 0,0,0,
+ &openssl_ecdh_meth
+ };
+ return &rv;
+ }
+#endif