From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7731430BB86 for ; Mon, 5 Jan 2026 15:22:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767626543; cv=none; b=SIVmok53/gYMDXLvqIxkOs/b4dqBOaA1be3V2wtyfJIWN+hV54nYDw+EiQR/Zj3sPxEq21vRIBZlkhPlPXCudiHKKlEJubSUYZRK7XD1Ddx3q4xz5DtVh7nDi9tOFwhnmDBTgtBn/LcFjW4vzSjSaA6I1eYifImyLky7XCe3MEM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767626543; c=relaxed/simple; bh=UJ0JNuAjO4bhNUyDJJTmWDirBsmcCcvUnyXrgyxFwC0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=svxuJ3i0J0TsxwhTJnuuyYxfukevtxx5p3zUgfYVhi6DZ9VVd11tF0UZZKsMe11JG+64Vg8FvwJKs/XYsn53DsEpp2ukIJt6Z96pj1CbB65GRgrqBJDJk/oV2YOvbDt6E/MdwTsFgsHyzMmnXPZbXJ40uAjr/7RTFQZxaWnn4Ac= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=MAUwUqsr; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="MAUwUqsr" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1767626540; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LPY+GhOJq5nNgZrUBrGTmZ1jrCpWP/ToTTWyLrp7aIg=; b=MAUwUqsrWVGLK4qaECwcTYDntou2aDA790f9hvOc5lGqXletnyMnsTDelSn/FIoec9q1ey 44h1/V+D8oVSHKwz2hjJ4yo8A/7XgX+NdA7ar+uZhDHAjBr/FozyhW0YcYJRwCC+IJgjy2 RlOEZQY6jgrvzTMAL9h1hNf3sC8Fsjc= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-186-RsrvT5hTMqeqYQgZCoJKBQ-1; Mon, 05 Jan 2026 10:22:15 -0500 X-MC-Unique: RsrvT5hTMqeqYQgZCoJKBQ-1 X-Mimecast-MFC-AGG-ID: RsrvT5hTMqeqYQgZCoJKBQ_1767626532 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A7B5718005AE; Mon, 5 Jan 2026 15:22:12 +0000 (UTC) Received: from warthog.procyon.org.uk.com (unknown [10.42.28.4]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 2657530001A7; Mon, 5 Jan 2026 15:22:05 +0000 (UTC) From: David Howells To: Lukas Wunner , Ignat Korchagin Cc: David Howells , Jarkko Sakkinen , Herbert Xu , Eric Biggers , Luis Chamberlain , Petr Pavlu , Daniel Gomez , Sami Tolvanen , "Jason A . Donenfeld" , Ard Biesheuvel , Stephan Mueller , linux-crypto@vger.kernel.org, keyrings@vger.kernel.org, linux-modules@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v11 2/8] pkcs7: Allow the signing algo to calculate the digest itself Date: Mon, 5 Jan 2026 15:21:27 +0000 Message-ID: <20260105152145.1801972-3-dhowells@redhat.com> In-Reply-To: <20260105152145.1801972-1-dhowells@redhat.com> References: <20260105152145.1801972-1-dhowells@redhat.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 The ML-DSA public key algorithm really wants to calculate the message digest itself, rather than having the digest precalculated and fed to it separately as RSA does[*]. The kernel's PKCS#7 parser, however, is designed around the latter approach. [*] ML-DSA does allow for an "external mu", but CMS doesn't yet have that standardised. Fix this by noting in the public_key_signature struct when the signing algorithm is going to want this and then, rather than doing the digest of the authenticatedAttributes ourselves and overwriting the sig->digest with that, replace sig->digest with a copy of the contents of the authenticatedAttributes section and adjust the digest length to match. This will then be fed to the public key algorithm as normal which can do what it wants with the data. Signed-off-by: David Howells cc: Lukas Wunner cc: Ignat Korchagin cc: Stephan Mueller cc: Eric Biggers cc: Herbert Xu cc: keyrings@vger.kernel.org cc: linux-crypto@vger.kernel.org --- crypto/asymmetric_keys/pkcs7_parser.c | 4 +-- crypto/asymmetric_keys/pkcs7_verify.c | 48 ++++++++++++++++++--------- include/crypto/public_key.h | 1 + 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c index 423d13c47545..3cdbab3b9f50 100644 --- a/crypto/asymmetric_keys/pkcs7_parser.c +++ b/crypto/asymmetric_keys/pkcs7_parser.c @@ -599,8 +599,8 @@ int pkcs7_sig_note_set_of_authattrs(void *context, size_t hdrlen, } /* We need to switch the 'CONT 0' to a 'SET OF' when we digest */ - sinfo->authattrs = value - (hdrlen - 1); - sinfo->authattrs_len = vlen + (hdrlen - 1); + sinfo->authattrs = value - hdrlen; + sinfo->authattrs_len = vlen + hdrlen; return 0; } diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c index 6d6475e3a9bf..0f9f515b784d 100644 --- a/crypto/asymmetric_keys/pkcs7_verify.c +++ b/crypto/asymmetric_keys/pkcs7_verify.c @@ -70,8 +70,6 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7, * digest we just calculated. */ if (sinfo->authattrs) { - u8 tag; - if (!sinfo->msgdigest) { pr_warn("Sig %u: No messageDigest\n", sinfo->index); ret = -EKEYREJECTED; @@ -97,20 +95,40 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7, * as the contents of the digest instead. Note that we need to * convert the attributes from a CONT.0 into a SET before we * hash it. + * + * However, for certain algorithms, such as ML-DSA, the digest + * is integrated into the signing algorithm. In such a case, + * we copy the authattrs, modifying the tag type, and set that + * as the digest. */ - memset(sig->digest, 0, sig->digest_size); - - ret = crypto_shash_init(desc); - if (ret < 0) - goto error; - tag = ASN1_CONS_BIT | ASN1_SET; - ret = crypto_shash_update(desc, &tag, 1); - if (ret < 0) - goto error; - ret = crypto_shash_finup(desc, sinfo->authattrs, - sinfo->authattrs_len, sig->digest); - if (ret < 0) - goto error; + if (sig->algo_does_hash) { + kfree(sig->digest); + + ret = -ENOMEM; + sig->digest = kmalloc(umax(sinfo->authattrs_len, sig->digest_size), + GFP_KERNEL); + if (!sig->digest) + goto error_no_desc; + + sig->digest_size = sinfo->authattrs_len; + memcpy(sig->digest, sinfo->authattrs, sinfo->authattrs_len); + ((u8 *)sig->digest)[0] = ASN1_CONS_BIT | ASN1_SET; + ret = 0; + } else { + u8 tag = ASN1_CONS_BIT | ASN1_SET; + + ret = crypto_shash_init(desc); + if (ret < 0) + goto error; + ret = crypto_shash_update(desc, &tag, 1); + if (ret < 0) + goto error; + ret = crypto_shash_finup(desc, sinfo->authattrs + 1, + sinfo->authattrs_len - 1, + sig->digest); + if (ret < 0) + goto error; + } pr_devel("AADigest = [%*ph]\n", 8, sig->digest); } diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h index 81098e00c08f..e4ec8003a3a4 100644 --- a/include/crypto/public_key.h +++ b/include/crypto/public_key.h @@ -46,6 +46,7 @@ struct public_key_signature { u8 *digest; u32 s_size; /* Number of bytes in signature */ u32 digest_size; /* Number of bytes in digest */ + bool algo_does_hash; /* Public key algo does its own hashing */ const char *pkey_algo; const char *hash_algo; const char *encoding;