lkml.org 
[lkml]   [2022]   [Apr]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.16 0058/1017] KEYS: asymmetric: enforce that sig algo matches key algo
    Date
    From: Eric Biggers <ebiggers@google.com>

    commit 2abc9c246e0548e52985b10440c9ea3e9f65f793 upstream.

    Most callers of public_key_verify_signature(), including most indirect
    callers via verify_signature() as well as pkcs7_verify_sig_chain(),
    don't check that public_key_signature::pkey_algo matches
    public_key::pkey_algo. These should always match. However, a malicious
    signature could intentionally declare an unintended algorithm. It is
    essential that such signatures be rejected outright, or that the
    algorithm of the *key* be used -- not the algorithm of the signature as
    that would allow attackers to choose the algorithm used.

    Currently, public_key_verify_signature() correctly uses the key's
    algorithm when deciding which akcipher to allocate. That's good.
    However, it uses the signature's algorithm when deciding whether to do
    the first step of SM2, which is incorrect. Also, v4.19 and older
    kernels used the signature's algorithm for the entire process.

    Prevent such errors by making public_key_verify_signature() enforce that
    the signature's algorithm (if given) matches the key's algorithm.

    Also remove two checks of this done by callers, which are now redundant.

    Cc: stable@vger.kernel.org
    Tested-by: Stefan Berger <stefanb@linux.ibm.com>
    Tested-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
    Signed-off-by: Eric Biggers <ebiggers@google.com>
    Reviewed-by: Vitaly Chikunov <vt@altlinux.org>
    Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
    Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    crypto/asymmetric_keys/pkcs7_verify.c | 6 ------
    crypto/asymmetric_keys/public_key.c | 15 +++++++++++++++
    crypto/asymmetric_keys/x509_public_key.c | 6 ------
    3 files changed, 15 insertions(+), 12 deletions(-)

    --- a/crypto/asymmetric_keys/pkcs7_verify.c
    +++ b/crypto/asymmetric_keys/pkcs7_verify.c
    @@ -174,12 +174,6 @@ static int pkcs7_find_key(struct pkcs7_m
    pr_devel("Sig %u: Found cert serial match X.509[%u]\n",
    sinfo->index, certix);

    - if (strcmp(x509->pub->pkey_algo, sinfo->sig->pkey_algo) != 0) {
    - pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n",
    - sinfo->index);
    - continue;
    - }
    -
    sinfo->signer = x509;
    return 0;
    }
    --- a/crypto/asymmetric_keys/public_key.c
    +++ b/crypto/asymmetric_keys/public_key.c
    @@ -325,6 +325,21 @@ int public_key_verify_signature(const st
    BUG_ON(!sig);
    BUG_ON(!sig->s);

    + /*
    + * If the signature specifies a public key algorithm, it *must* match
    + * the key's actual public key algorithm.
    + *
    + * Small exception: ECDSA signatures don't specify the curve, but ECDSA
    + * keys do. So the strings can mismatch slightly in that case:
    + * "ecdsa-nist-*" for the key, but "ecdsa" for the signature.
    + */
    + if (sig->pkey_algo) {
    + if (strcmp(pkey->pkey_algo, sig->pkey_algo) != 0 &&
    + (strncmp(pkey->pkey_algo, "ecdsa-", 6) != 0 ||
    + strcmp(sig->pkey_algo, "ecdsa") != 0))
    + return -EKEYREJECTED;
    + }
    +
    ret = software_key_determine_akcipher(sig->encoding,
    sig->hash_algo,
    pkey, alg_name);
    --- a/crypto/asymmetric_keys/x509_public_key.c
    +++ b/crypto/asymmetric_keys/x509_public_key.c
    @@ -128,12 +128,6 @@ int x509_check_for_self_signed(struct x5
    goto out;
    }

    - ret = -EKEYREJECTED;
    - if (strcmp(cert->pub->pkey_algo, cert->sig->pkey_algo) != 0 &&
    - (strncmp(cert->pub->pkey_algo, "ecdsa-", 6) != 0 ||
    - strcmp(cert->sig->pkey_algo, "ecdsa") != 0))
    - goto out;
    -
    ret = public_key_verify_signature(cert->pub, cert->sig);
    if (ret < 0) {
    if (ret == -ENOPKG) {

    \
     
     \ /
      Last update: 2022-04-05 14:20    [W:5.008 / U:0.168 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site