Commit 75394189 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Add EVP_DigestSign and EVP_DigesVerify



Add "single part" digest sign and verify functions. These sign and verify
a message in one function. This simplifies some operations and it will later
be used as the API for algorithms which do not support the update/final
mechanism (e.g. PureEdDSA).

Reviewed-by: default avatarAndy Polyakov <appro@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3409)
parent 4f2a5695
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -205,8 +205,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it,
        goto err;
    }

    if (!EVP_DigestSignUpdate(ctx, buf_in, inl)
        || !EVP_DigestSignFinal(ctx, buf_out, &outl)) {
    if (!EVP_DigestSign(ctx, buf_out, &outl, buf_in, inl)) {
        outl = 0;
        ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
        goto err;
+6 −15
Original line number Diff line number Diff line
@@ -89,7 +89,7 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
{
    EVP_MD_CTX *ctx = NULL;
    unsigned char *buf_in = NULL;
    int ret = -1, inl;
    int ret = -1, inl = 0;

    int mdnid, pknid;

@@ -159,24 +159,15 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
        goto err;
    }

    ret = EVP_DigestVerifyUpdate(ctx, buf_in, inl);

    OPENSSL_clear_free(buf_in, (unsigned int)inl);

    if (!ret) {
        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
        goto err;
    }
    ret = -1;

    if (EVP_DigestVerifyFinal(ctx, signature->data,
                              (size_t)signature->length) <= 0) {
    ret = EVP_DigestVerify(ctx, signature->data, (size_t)signature->length,
                           buf_in, inl);
    if (ret <= 0) {
        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
        ret = 0;
        goto err;
    }
    ret = 1;
 err:
    OPENSSL_clear_free(buf_in, (unsigned int)inl);
    EVP_MD_CTX_free(ctx);
    return (ret);
    return ret;
}
+16 −0
Original line number Diff line number Diff line
@@ -135,6 +135,14 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
    return 1;
}

int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
                   const unsigned char *tbs, size_t tbslen)
{
    if (sigret != NULL && EVP_DigestSignUpdate(ctx, tbs, tbslen) <= 0)
        return 0;
    return EVP_DigestSignFinal(ctx, sigret, siglen);
}

int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
                          size_t siglen)
{
@@ -167,3 +175,11 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
        return r;
    return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen);
}

int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
                     size_t siglen, const unsigned char *tbs, size_t tbslen)
{
    if (EVP_DigestVerifyUpdate(ctx, tbs, tbslen) <= 0)
        return -1;
    return EVP_DigestVerifyFinal(ctx, sigret, siglen);
}
+18 −5
Original line number Diff line number Diff line
@@ -2,7 +2,8 @@

=head1 NAME

EVP_DigestSignInit, EVP_DigestSignUpdate, EVP_DigestSignFinal - EVP signing functions
EVP_DigestSignInit, EVP_DigestSignUpdate, EVP_DigestSignFinal,
EVP_DigestSign - EVP signing functions

=head1 SYNOPSIS

@@ -13,6 +14,10 @@ EVP_DigestSignInit, EVP_DigestSignUpdate, EVP_DigestSignFinal - EVP signing func
 int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt);
 int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen);

 int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret,
                    size_t *siglen, const unsigned char *tbs,
                    size_t tbslen);

=head1 DESCRIPTION

The EVP signature routines are a high level interface to digital signatures.
@@ -35,12 +40,16 @@ B<siglen> parameter should contain the length of the B<sig> buffer, if the
call is successful the signature is written to B<sig> and the amount of data
written to B<siglen>.

EVP_DigestSign() signs B<tbslen> bytes of data at B<tbs> and places the
signature in B<sig> and its length in B<siglen> in a simiilar way to
EVP_DigestSignFinal().

=head1 RETURN VALUES

EVP_DigestSignInit() EVP_DigestSignUpdate() and EVP_DigestSignaFinal() return
1 for success and 0 or a negative value for failure. In particular a return
value of -2 indicates the operation is not supported by the public key
algorithm.
EVP_DigestSignInit(), EVP_DigestSignUpdate(), EVP_DigestSignaFinal() and
EVP_DigestSign() return 1 for success and 0 or a negative value for failure. In
particular a return value of -2 indicates the operation is not supported by the
public key algorithm.

The error codes can be obtained from L<ERR_get_error(3)>.

@@ -50,6 +59,10 @@ The B<EVP> interface to digital signatures should almost always be used in
preference to the low level interfaces. This is because the code then becomes
transparent to the algorithm used and much more flexible.

EVP_DigestSign() is a single part operation which signs a single block of data
in one function. It is equivalent to calling EVP_DigestSignUpdate() and
EVP_DigestSignFinal().

In previous versions of OpenSSL there was a link between message digest types
and public key algorithms. This meant that "clone" digests such as EVP_dss1()
needed to be used to sign using SHA1 and DSA. This is no longer necessary and
+18 −7
Original line number Diff line number Diff line
@@ -2,7 +2,8 @@

=head1 NAME

EVP_DigestVerifyInit, EVP_DigestVerifyUpdate, EVP_DigestVerifyFinal - EVP signature verification functions
EVP_DigestVerifyInit, EVP_DigestVerifyUpdate, EVP_DigestVerifyFinal,
EVP_DigestVerify - EVP signature verification functions

=head1 SYNOPSIS

@@ -11,7 +12,10 @@ EVP_DigestVerifyInit, EVP_DigestVerifyUpdate, EVP_DigestVerifyFinal - EVP signat
 int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
                        const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
 int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt);
 int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, size_t siglen);
 int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
                           size_t siglen);
 int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
                      size_t siglen, const unsigned char *tbs, size_t tbslen);

=head1 DESCRIPTION

@@ -31,16 +35,19 @@ using a macro.
EVP_DigestVerifyFinal() verifies the data in B<ctx> against the signature in
B<sig> of length B<siglen>.

EVP_DogestVerify() verifies B<tbslen> bytes at B<tbs> against the signature
in B<sig> of length B<siglen>.

=head1 RETURN VALUES

EVP_DigestVerifyInit() and EVP_DigestVerifyUpdate() return 1 for success and 0
for failure.

EVP_DigestVerifyFinal() returns 1 for success; any other value indicates
failure.  A return value of zero indicates that the signature did not verify
successfully (that is, tbs did not match the original data or the signature had
an invalid form), while other values indicate a more serious error (and
sometimes also indicate an invalid signature form).
EVP_DigestVerifyFinal() and EVP_DigestVerify() return 1 for success; any other
value indicates failure.  A return value of zero indicates that the signature
did not verify successfully (that is, B<tbs> did not match the original data or
the signature had an invalid form), while other values indicate a more serious
error (and sometimes also indicate an invalid signature form).

The error codes can be obtained from L<ERR_get_error(3)>.

@@ -50,6 +57,10 @@ The B<EVP> interface to digital signatures should almost always be used in
preference to the low level interfaces. This is because the code then becomes
transparent to the algorithm used and much more flexible.

EVP_DigesVerify() is a single part operation which verifies a single block of
data in one function. It is equivalent to calling EVP_DigestVerifyUpdate() and
EVP_DigestVerifyFinal().

In previous versions of OpenSSL there was a link between message digest types
and public key algorithms. This meant that "clone" digests such as EVP_dss1()
needed to be used to sign using SHA1 and DSA. This is no longer necessary and
Loading