diff --git a/CHANGES b/CHANGES index 612da599..7a478521 100644 --- a/CHANGES +++ b/CHANGES @@ -8,6 +8,10 @@ release branch. Changes between 1.1.0h and 1.1.1 [xx XXX xxxx] + *) Enforce checking in the pkeyutl command line app to ensure that the input + length does not exceed the maximum supported digest length when performing + a sign, verify or verifyrecover operation. + [Matt Caswell] *) SSL_MODE_AUTO_RETRY is enabled by default. Applications that use blocking I/O in combination with something like select() or poll() will hang. This diff --git a/apps/pkeyutl.c b/apps/pkeyutl.c index 911cc576..2c4e524b 100644 --- a/apps/pkeyutl.c +++ b/apps/pkeyutl.c @@ -282,7 +282,7 @@ int pkeyutl_main(int argc, char **argv) buf_inlen = bio_to_mem(&buf_in, keysize * 10, in); if (buf_inlen < 0) { BIO_printf(bio_err, "Error reading input Data\n"); - exit(1); + goto end; } if (rev) { size_t i; @@ -296,6 +296,16 @@ int pkeyutl_main(int argc, char **argv) } } + /* Sanity check the input */ + if (buf_inlen > EVP_MAX_MD_SIZE + && (pkey_op == EVP_PKEY_OP_SIGN + || pkey_op == EVP_PKEY_OP_VERIFY + || pkey_op == EVP_PKEY_OP_VERIFYRECOVER)) { + BIO_printf(bio_err, + "Error: The input data looks too long to be a hash\n"); + goto end; + } + if (pkey_op == EVP_PKEY_OP_VERIFY) { rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen, buf_in, (size_t)buf_inlen); diff --git a/crypto/ec/ec2_smpl.c b/crypto/ec/ec2_smpl.c index b73805a2..5a83b056 100644 --- a/crypto/ec/ec2_smpl.c +++ b/crypto/ec/ec2_smpl.c @@ -311,6 +311,7 @@ int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src) if (!BN_copy(dest->Z, src->Z)) return 0; dest->Z_is_one = src->Z_is_one; + dest->curve_name = src->curve_name; return 1; } diff --git a/crypto/ec/ec_curve.c b/crypto/ec/ec_curve.c index 7d56d26b..618ec04c 100644 --- a/crypto/ec/ec_curve.c +++ b/crypto/ec/ec_curve.c @@ -3066,6 +3066,8 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve) } #endif + EC_GROUP_set_curve_name(group, curve.nid); + if ((P = EC_POINT_new(group)) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; @@ -3131,8 +3133,6 @@ EC_GROUP *EC_GROUP_new_by_curve_name(int nid) return NULL; } - EC_GROUP_set_curve_name(ret, nid); - return ret; } diff --git a/crypto/ec/ec_err.c b/crypto/ec/ec_err.c index 807427f9..94a72072 100644 --- a/crypto/ec/ec_err.c +++ b/crypto/ec/ec_err.c @@ -250,8 +250,6 @@ static const ERR_STRING_DATA EC_str_functs[] = { "pkey_ecd_digestsign25519"}, {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_DIGESTSIGN448, 0), "pkey_ecd_digestsign448"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_SIGN25519, 0), "pkey_ecd_sign25519"}, - {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_SIGN448, 0), "pkey_ecd_sign448"}, {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECX_DERIVE, 0), "pkey_ecx_derive"}, {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_CTRL, 0), "pkey_ec_ctrl"}, {ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_CTRL_STR, 0), "pkey_ec_ctrl_str"}, diff --git a/crypto/ec/ec_lcl.h b/crypto/ec/ec_lcl.h index 36c65c5f..5e14071a 100644 --- a/crypto/ec/ec_lcl.h +++ b/crypto/ec/ec_lcl.h @@ -276,6 +276,8 @@ struct ec_key_st { struct ec_point_st { const EC_METHOD *meth; + /* NID for the curve if known */ + int curve_name; /* * All members except 'meth' are handled by the method functions, even if * they appear generic @@ -288,6 +290,20 @@ struct ec_point_st { * special case */ }; + +static ossl_inline int ec_point_is_compat(const EC_POINT *point, + const EC_GROUP *group) +{ + if (group->meth != point->meth + || (group->curve_name != 0 + && point->curve_name != 0 + && group->curve_name != point->curve_name)) + return 0; + + return 1; +} + + NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *); NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *); NISTP521_PRE_COMP *EC_nistp521_pre_comp_dup(NISTP521_PRE_COMP *); diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index 10b0cb77..30b11f75 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -140,6 +140,8 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) if (dest == src) return 1; + dest->curve_name = src->curve_name; + /* Copy precomputed */ dest->pre_comp_type = src->pre_comp_type; switch (src->pre_comp_type) { @@ -207,7 +209,6 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) return 0; } - dest->curve_name = src->curve_name; dest->asn1_flag = src->asn1_flag; dest->asn1_form = src->asn1_form; @@ -572,6 +573,7 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group) } ret->meth = group->meth; + ret->curve_name = group->curve_name; if (!ret->meth->point_init(ret)) { OPENSSL_free(ret); @@ -609,7 +611,10 @@ int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if (dest->meth != src->meth) { + if (dest->meth != src->meth + || (dest->curve_name != src->curve_name + && dest->curve_name != 0 + && src->curve_name != 0)) { ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS); return 0; } @@ -666,7 +671,7 @@ int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if (group->meth != point->meth) { + if (!ec_point_is_compat(point, group)) { ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); return 0; @@ -685,7 +690,7 @@ int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if (group->meth != point->meth) { + if (!ec_point_is_compat(point, group)) { ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); return 0; @@ -703,7 +708,7 @@ int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if (group->meth != point->meth) { + if (!ec_point_is_compat(point, group)) { ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); return 0; @@ -729,7 +734,7 @@ int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if (group->meth != point->meth) { + if (!ec_point_is_compat(point, group)) { ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS); return 0; @@ -755,7 +760,7 @@ int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if (group->meth != point->meth) { + if (!ec_point_is_compat(point, group)) { ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); return 0; @@ -773,7 +778,7 @@ int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if (group->meth != point->meth) { + if (!ec_point_is_compat(point, group)) { ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS); return 0; @@ -789,8 +794,8 @@ int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if ((group->meth != r->meth) || (r->meth != a->meth) - || (a->meth != b->meth)) { + if (!ec_point_is_compat(r, group) || !ec_point_is_compat(a, group) + || !ec_point_is_compat(b, group)) { ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS); return 0; } @@ -804,7 +809,7 @@ int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if ((group->meth != r->meth) || (r->meth != a->meth)) { + if (!ec_point_is_compat(r, group) || !ec_point_is_compat(a, group)) { ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS); return 0; } @@ -817,7 +822,7 @@ int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if (group->meth != a->meth) { + if (!ec_point_is_compat(a, group)) { ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS); return 0; } @@ -831,7 +836,7 @@ int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if (group->meth != point->meth) { + if (!ec_point_is_compat(point, group)) { ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS); return 0; } @@ -852,7 +857,7 @@ int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if (group->meth != point->meth) { + if (!ec_point_is_compat(point, group)) { ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS); return 0; } @@ -866,7 +871,7 @@ int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return -1; } - if ((group->meth != a->meth) || (a->meth != b->meth)) { + if (!ec_point_is_compat(a, group) || !ec_point_is_compat(b, group)) { ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS); return -1; } @@ -879,7 +884,7 @@ int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if (group->meth != point->meth) { + if (!ec_point_is_compat(point, group)) { ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS); return 0; } @@ -896,7 +901,7 @@ int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, return 0; } for (i = 0; i < num; i++) { - if (group->meth != points[i]->meth) { + if (!ec_point_is_compat(points[i], group)) { ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS); return 0; } diff --git a/crypto/ec/ec_mult.c b/crypto/ec/ec_mult.c index 1f343291..05a3aca0 100644 --- a/crypto/ec/ec_mult.c +++ b/crypto/ec/ec_mult.c @@ -368,7 +368,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, * precomputation is not available */ int ret = 0; - if (group->meth != r->meth) { + if (!ec_point_is_compat(r, group)) { ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS); return 0; } @@ -404,7 +404,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, } for (i = 0; i < num; i++) { - if (group->meth != points[i]->meth) { + if (!ec_point_is_compat(points[i], group)) { ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS); return 0; } diff --git a/crypto/ec/ec_oct.c b/crypto/ec/ec_oct.c index a21906e7..c87d495a 100644 --- a/crypto/ec/ec_oct.c +++ b/crypto/ec/ec_oct.c @@ -25,7 +25,7 @@ int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if (group->meth != point->meth) { + if (!ec_point_is_compat(point, group)) { ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); return 0; @@ -61,7 +61,7 @@ int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if (group->meth != point->meth) { + if (!ec_point_is_compat(point, group)) { ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS); return 0; @@ -88,7 +88,7 @@ size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if (group->meth != point->meth) { + if (!ec_point_is_compat(point, group)) { ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS); return 0; } @@ -118,7 +118,7 @@ int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if (group->meth != point->meth) { + if (!ec_point_is_compat(point, group)) { ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS); return 0; } diff --git a/crypto/ec/ecp_nistz256.c b/crypto/ec/ecp_nistz256.c index 4580f70b..d3603fbb 100644 --- a/crypto/ec/ecp_nistz256.c +++ b/crypto/ec/ecp_nistz256.c @@ -1162,7 +1162,7 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group, return 0; } - if (group->meth != r->meth) { + if (!ec_point_is_compat(r, group)) { ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS); return 0; } @@ -1171,7 +1171,7 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group, return EC_POINT_set_to_infinity(group, r); for (j = 0; j < num; j++) { - if (group->meth != points[j]->meth) { + if (!ec_point_is_compat(points[j], group)) { ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS); return 0; } diff --git a/crypto/ec/ecp_smpl.c b/crypto/ec/ecp_smpl.c index 7ff5489c..8543b416 100644 --- a/crypto/ec/ecp_smpl.c +++ b/crypto/ec/ecp_smpl.c @@ -347,6 +347,7 @@ int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src) if (!BN_copy(dest->Z, src->Z)) return 0; dest->Z_is_one = src->Z_is_one; + dest->curve_name = src->curve_name; return 1; } diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c index ea56df0d..d2aa6dd8 100644 --- a/crypto/ec/ecx_meth.c +++ b/crypto/ec/ecx_meth.c @@ -675,18 +675,18 @@ const EVP_PKEY_METHOD ecx448_pkey_meth = { 0 }; -static int pkey_ecd_sign25519(EVP_PKEY_CTX *ctx, unsigned char *sig, - size_t *siglen, const unsigned char *tbs, - size_t tbslen) +static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig, + size_t *siglen, const unsigned char *tbs, + size_t tbslen) { - const ECX_KEY *edkey = ctx->pkey->pkey.ecx; + const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx; if (sig == NULL) { *siglen = ED25519_SIGSIZE; return 1; } if (*siglen < ED25519_SIGSIZE) { - ECerr(EC_F_PKEY_ECD_SIGN25519, EC_R_BUFFER_TOO_SMALL); + ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL); return 0; } @@ -696,26 +696,18 @@ static int pkey_ecd_sign25519(EVP_PKEY_CTX *ctx, unsigned char *sig, return 1; } -static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig, - size_t *siglen, const unsigned char *tbs, - size_t tbslen) +static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig, + size_t *siglen, const unsigned char *tbs, + size_t tbslen) { - return pkey_ecd_sign25519(EVP_MD_CTX_pkey_ctx(ctx), sig, siglen, tbs, - tbslen); -} - -static int pkey_ecd_sign448(EVP_PKEY_CTX *ctx, unsigned char *sig, - size_t *siglen, const unsigned char *tbs, - size_t tbslen) -{ - const ECX_KEY *edkey = ctx->pkey->pkey.ecx; + const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx; if (sig == NULL) { *siglen = ED448_SIGSIZE; return 1; } if (*siglen < ED448_SIGSIZE) { - ECerr(EC_F_PKEY_ECD_SIGN448, EC_R_BUFFER_TOO_SMALL); + ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL); return 0; } @@ -726,18 +718,11 @@ static int pkey_ecd_sign448(EVP_PKEY_CTX *ctx, unsigned char *sig, return 1; } -static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig, - size_t *siglen, const unsigned char *tbs, - size_t tbslen) +static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig, + size_t siglen, const unsigned char *tbs, + size_t tbslen) { - return pkey_ecd_sign448(EVP_MD_CTX_pkey_ctx(ctx), sig, siglen, tbs, tbslen); -} - -static int pkey_ecd_verify25519(EVP_PKEY_CTX *ctx, const unsigned char *sig, - size_t siglen, const unsigned char *tbs, - size_t tbslen) -{ - const ECX_KEY *edkey = ctx->pkey->pkey.ecx; + const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx; if (siglen != ED25519_SIGSIZE) return 0; @@ -745,19 +730,11 @@ static int pkey_ecd_verify25519(EVP_PKEY_CTX *ctx, const unsigned char *sig, return ED25519_verify(tbs, tbslen, sig, edkey->pubkey); } -static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig, - size_t siglen, const unsigned char *tbs, - size_t tbslen) +static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig, + size_t siglen, const unsigned char *tbs, + size_t tbslen) { - return pkey_ecd_verify25519(EVP_MD_CTX_pkey_ctx(ctx), sig, siglen, tbs, - tbslen); -} - -static int pkey_ecd_verify448(EVP_PKEY_CTX *ctx, const unsigned char *sig, - size_t siglen, const unsigned char *tbs, - size_t tbslen) -{ - const ECX_KEY *edkey = ctx->pkey->pkey.ecx; + const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx; if (siglen != ED448_SIGSIZE) return 0; @@ -765,14 +742,6 @@ static int pkey_ecd_verify448(EVP_PKEY_CTX *ctx, const unsigned char *sig, return ED448_verify(tbs, tbslen, sig, edkey->pubkey, NULL, 0); } -static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig, - size_t siglen, const unsigned char *tbs, - size_t tbslen) -{ - return pkey_ecd_verify448(EVP_MD_CTX_pkey_ctx(ctx), sig, siglen, tbs, - tbslen); -} - static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { switch (type) { @@ -793,11 +762,7 @@ const EVP_PKEY_METHOD ed25519_pkey_meth = { EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM, 0, 0, 0, 0, 0, 0, pkey_ecx_keygen, - 0, - pkey_ecd_sign25519, - 0, - pkey_ecd_verify25519, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pkey_ecd_ctrl, 0, pkey_ecd_digestsign25519, @@ -808,11 +773,7 @@ const EVP_PKEY_METHOD ed448_pkey_meth = { EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM, 0, 0, 0, 0, 0, 0, pkey_ecx_keygen, - 0, - pkey_ecd_sign448, - 0, - pkey_ecd_verify448, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pkey_ecd_ctrl, 0, pkey_ecd_digestsign448, diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 209bd0d3..89e5ceb1 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -647,8 +647,6 @@ EC_F_PKEY_ECD_CTRL:271:pkey_ecd_ctrl EC_F_PKEY_ECD_DIGESTSIGN:272:pkey_ecd_digestsign EC_F_PKEY_ECD_DIGESTSIGN25519:276:pkey_ecd_digestsign25519 EC_F_PKEY_ECD_DIGESTSIGN448:277:pkey_ecd_digestsign448 -EC_F_PKEY_ECD_SIGN25519:284:pkey_ecd_sign25519 -EC_F_PKEY_ECD_SIGN448:285:pkey_ecd_sign448 EC_F_PKEY_ECX_DERIVE:269:pkey_ecx_derive EC_F_PKEY_EC_CTRL:197:pkey_ec_ctrl EC_F_PKEY_EC_CTRL_STR:198:pkey_ec_ctrl_str diff --git a/doc/man1/pkeyutl.pod b/doc/man1/pkeyutl.pod index d485f612..664dbef3 100644 --- a/doc/man1/pkeyutl.pod +++ b/doc/man1/pkeyutl.pod @@ -38,8 +38,8 @@ B B =head1 DESCRIPTION -The B command can be used to perform public key operations using -any supported algorithm. +The B command can be used to perform low level public key operations +using any supported algorithm. =head1 OPTIONS @@ -99,17 +99,17 @@ Reverse the order of the input buffer. This is useful for some libraries =item B<-sign> -Sign the input data and output the signed result. This requires -a private key. +Sign the input data (which must be a hash) and output the signed result. This +requires a private key. =item B<-verify> -Verify the input data against the signature file and indicate if the -verification succeeded or failed. +Verify the input data (which must be a hash) against the signature file and +indicate if the verification succeeded or failed. =item B<-verifyrecover> -Verify the input data and output the recovered data. +Verify the input data (which must be a hash) and output the recovered data. =item B<-encrypt> @@ -184,20 +184,25 @@ and its implementation. The OpenSSL operations and options are indicated below. Unless otherwise mentioned all algorithms support the B option which specifies the digest in use for sign, verify and verifyrecover operations. The value B should represent a digest name as used in the -EVP_get_digestbyname() function for example B. -This value is used only for sanity-checking the lengths of data passed in to -the B and for creating the structures that make up the signature -(e.g. B in RSASSA PKCS#1 v1.5 signatures). -In case of RSA, ECDSA and DSA signatures, this utility -will not perform hashing on input data but rather use the data directly as -input of signature algorithm. Depending on key type, signature type and mode -of padding, the maximum acceptable lengths of input data differ. In general, -with RSA the signed data can't be longer than the key modulus, in case of ECDSA -and DSA the data shouldn't be longer than field size, otherwise it will be -silently truncated to field size. +EVP_get_digestbyname() function for example B. This value is not used to +hash the input data. It is used (by some algorithms) for sanity-checking the +lengths of data passed in to the B and for creating the structures that +make up the signature (e.g. B in RSASSA PKCS#1 v1.5 signatures). -In other words, if the value of digest is B the input should be 20 bytes -long binary encoding of SHA-1 hash function output. +This utility does not hash the input data but rather it will use the data +directly as input to the signature algorithm. Depending on the key type, +signature type, and mode of padding, the maximum acceptable lengths of input +data differ. The signed data can't be longer than the key modulus with RSA. In +case of ECDSA and DSA the data shouldn't be longer than the field +size, otherwise it will be silently truncated to the field size. In any event +the input size must not be larger than the largest supported digest size. + +In other words, if the value of digest is B the input should be the 20 +bytes long binary encoding of the SHA-1 hash function output. + +The Ed25519 and Ed448 signature algorithms are not supported by this utility. +They accept non-hashed input, but this utility can only be used to sign hashed +input. =head1 RSA ALGORITHM diff --git a/include/openssl/ecerr.h b/include/openssl/ecerr.h index 320c6518..fd5ce84c 100644 --- a/include/openssl/ecerr.h +++ b/include/openssl/ecerr.h @@ -173,8 +173,6 @@ int ERR_load_EC_strings(void); # define EC_F_PKEY_ECD_DIGESTSIGN 272 # define EC_F_PKEY_ECD_DIGESTSIGN25519 276 # define EC_F_PKEY_ECD_DIGESTSIGN448 277 -# define EC_F_PKEY_ECD_SIGN25519 284 -# define EC_F_PKEY_ECD_SIGN448 285 # define EC_F_PKEY_ECX_DERIVE 269 # define EC_F_PKEY_EC_CTRL 197 # define EC_F_PKEY_EC_CTRL_STR 198