}
}
+int ossl_dh_is_named_safe_prime_group(const DH *dh)
+{
+ int id = DH_get_nid(dh);
+
+ /*
+ * Exclude RFC5114 groups (id = 1..3) since they do not have
+ * q = (p - 1) / 2
+ */
+ return (id > 3);
+}
+
int DH_get_nid(const DH *dh)
{
if (dh == NULL)
}
/*
- * ECC Key validation as specified in SP800-56A R3.
- * Section 5.6.2.3.3 ECC Full Public-Key Validation.
+ * ECC Partial Public-Key Validation as specified in SP800-56A R3
+ * Section 5.6.2.3.4 ECC Partial Public-Key Validation Routine.
*/
-int ec_key_public_check(const EC_KEY *eckey, BN_CTX *ctx)
+int ec_key_public_check_quick(const EC_KEY *eckey, BN_CTX *ctx)
{
- int ret = 0;
- EC_POINT *point = NULL;
- const BIGNUM *order = NULL;
-
if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
return 0;
}
- point = EC_POINT_new(eckey->group);
- if (point == NULL)
- return 0;
-
/* 5.6.2.3.3 (Step 2) Test if the public key is in range */
if (!ec_key_public_range_check(ctx, eckey)) {
ERR_raise(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE);
- goto err;
+ return 0;
}
/* 5.6.2.3.3 (Step 3) is the pub_key on the elliptic curve */
if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) {
ERR_raise(ERR_LIB_EC, EC_R_POINT_IS_NOT_ON_CURVE);
- goto err;
+ return 0;
}
+ return 1;
+}
+
+/*
+ * ECC Key validation as specified in SP800-56A R3.
+ * Section 5.6.2.3.3 ECC Full Public-Key Validation Routine.
+ */
+int ec_key_public_check(const EC_KEY *eckey, BN_CTX *ctx)
+{
+ int ret = 0;
+ EC_POINT *point = NULL;
+ const BIGNUM *order = NULL;
+
+ if (!ec_key_public_check_quick(eckey, ctx))
+ return 0;
+
+ point = EC_POINT_new(eckey->group);
+ if (point == NULL)
+ return 0;
order = eckey->group->order;
if (BN_is_zero(order)) {
return evp_keymgmt_validate(keymgmt, keydata, selection, checktype);
}
-int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx)
+static int evp_pkey_public_check_combined(EVP_PKEY_CTX *ctx, int checktype)
{
EVP_PKEY *pkey = ctx->pkey;
int ok;
}
if ((ok = try_provided_check(ctx, OSSL_KEYMGMT_SELECT_PUBLIC_KEY,
- OSSL_KEYMGMT_VALIDATE_FULL_CHECK)) != -1)
+ checktype)) != -1)
return ok;
if (pkey->type == EVP_PKEY_NONE)
return -2;
}
+int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx)
+{
+ return evp_pkey_public_check_combined(ctx, OSSL_KEYMGMT_VALIDATE_FULL_CHECK);
+}
+
+int EVP_PKEY_public_check_quick(EVP_PKEY_CTX *ctx)
+{
+ return evp_pkey_public_check_combined(ctx, OSSL_KEYMGMT_VALIDATE_QUICK_CHECK);
+}
+
static int evp_pkey_param_check_combined(EVP_PKEY_CTX *ctx, int checktype)
{
EVP_PKEY *pkey = ctx->pkey;
=head1 NAME
EVP_PKEY_check, EVP_PKEY_param_check, EVP_PKEY_param_check_quick,
-EVP_PKEY_public_check, EVP_PKEY_private_check, EVP_PKEY_pairwise_check
+EVP_PKEY_public_check, EVP_PKEY_public_check_quick, EVP_PKEY_private_check,
+EVP_PKEY_pairwise_check
- key and parameter validation functions
=head1 SYNOPSIS
int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx);
int EVP_PKEY_param_check_quick(EVP_PKEY_CTX *ctx);
int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx);
+ int EVP_PKEY_public_check_quick(EVP_PKEY_CTX *ctx);
int EVP_PKEY_private_check(EVP_PKEY_CTX *ctx);
int EVP_PKEY_pairwise_check(EVP_PKEY_CTX *ctx);
EVP_PKEY_public_check() validates the public component of the key given by B<ctx>.
+EVP_PKEY_public_check_quick() validates the public component of the key
+given by B<ctx> like EVP_PKEY_public_check() does. However some algorithm
+implementations may offer a quicker form of validation that omits some checks in
+order to perform a lightweight sanity check of the key. If a quicker form is not
+provided then this function call does the same thing as EVP_PKEY_public_check().
+
EVP_PKEY_private_check() validates the private component of the key given by B<ctx>.
EVP_PKEY_pairwise_check() validates that the public and private components have
EVP_PKEY_check(), EVP_PKEY_public_check() and EVP_PKEY_param_check() were added
in OpenSSL 1.1.1.
-EVP_PKEY_param_check_quick(), EVP_PKEY_private_check() and
-EVP_PKEY_pairwise_check() were added in OpenSSL 3.0.
+EVP_PKEY_param_check_quick(), EVP_PKEY_public_check_quick(),
+EVP_PKEY_private_check() and EVP_PKEY_pairwise_check() were added in OpenSSL 3.0.
=head1 COPYRIGHT
const char *dh_gen_type_id2name(int id);
int dh_gen_type_name2id(const char *name);
void dh_cache_named_group(DH *dh);
+int ossl_dh_is_named_safe_prime_group(const DH *dh);
FFC_PARAMS *dh_get0_params(DH *dh);
int dh_get0_nid(const DH *dh);
const EVP_MD *md, OSSL_LIB_CTX *libctx, const char *propq);
int ec_key_public_check(const EC_KEY *eckey, BN_CTX *ctx);
+int ec_key_public_check_quick(const EC_KEY *eckey, BN_CTX *ctx);
int ec_key_private_check(const EC_KEY *eckey);
int ec_key_pairwise_check(const EC_KEY *eckey, BN_CTX *ctx);
OSSL_LIB_CTX *ec_key_get_libctx(const EC_KEY *eckey);
int EVP_PKEY_gen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
int EVP_PKEY_check(EVP_PKEY_CTX *ctx);
int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_public_check_quick(EVP_PKEY_CTX *ctx);
int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx);
int EVP_PKEY_param_check_quick(EVP_PKEY_CTX *ctx);
int EVP_PKEY_private_check(EVP_PKEY_CTX *ctx);
return 1;
}
-static int dh_validate_public(const DH *dh)
+static int dh_validate_public(const DH *dh, int checktype)
{
const BIGNUM *pub_key = NULL;
+ int res = 0;
DH_get0_key(dh, &pub_key, NULL);
if (pub_key == NULL)
return 0;
- return DH_check_pub_key_ex(dh, pub_key);
+
+ /* The partial test is only valid for named group's with q = (p - 1) / 2 */
+ if (checktype == OSSL_KEYMGMT_VALIDATE_QUICK_CHECK
+ && ossl_dh_is_named_safe_prime_group(dh))
+ return dh_check_pub_key_partial(dh, pub_key, &res);
+
+ return DH_check_pub_key(dh, pub_key, &res);
}
static int dh_validate_private(const DH *dh)
}
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
- ok = ok && dh_validate_public(dh);
+ ok = ok && dh_validate_public(dh, checktype);
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
ok = ok && dh_validate_private(dh);
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
ok = ok && EC_GROUP_check(EC_KEY_get0_group(eck), ctx);
- if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
- ok = ok && ec_key_public_check(eck, ctx);
+ if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+ if (checktype == OSSL_KEYMGMT_VALIDATE_QUICK_CHECK)
+ ok = ok && ec_key_public_check_quick(eck, ctx);
+ else
+ ok = ok && ec_key_public_check(eck, ctx);
+ }
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
ok = ok && sm2_key_private_check(eck);
ok = ok && EC_GROUP_check(EC_KEY_get0_group(eck), ctx);
}
- if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
- ok = ok && ec_key_public_check(eck, ctx);
+ if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+ if (checktype == OSSL_KEYMGMT_VALIDATE_QUICK_CHECK)
+ ok = ok && ec_key_public_check_quick(eck, ctx);
+ else
+ ok = ok && ec_key_public_check(eck, ctx);
+ }
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
ok = ok && ec_key_private_check(eck);
EVP_PKEY_fromdata_init ? 3_0_0 EXIST::FUNCTION:
EVP_PKEY_fromdata_settable ? 3_0_0 EXIST::FUNCTION:
EVP_PKEY_param_check_quick ? 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_public_check_quick ? 3_0_0 EXIST::FUNCTION: