mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 01:32:21 +02:00
integrity: Add support for sigv3 verification using ML-DSA keys
Add support for sigv3 signature verification using ML-DSA in pure mode. When a sigv3 signature is verified, first check whether the key to use for verification is an ML-DSA key and therefore uses a hashless signature verification scheme. The hashless signature verification method uses the ima_file_id structure directly for signature verification rather than its digest. Suggested-by: Eric Biggers <ebiggers@kernel.org> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> Tested-by: Kamlesh Kumar <kam@juniper.net> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
This commit is contained in:
parent
33aa0c8cf0
commit
489d7e2e7e
|
|
@ -204,20 +204,99 @@ static int calc_file_id_hash(enum evm_ima_xattr_type type,
|
|||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* asymmetric_verify_v3_hashless - Use hashless signature verification on sigv3
|
||||
* @key: The key to use for signature verification; caller must free it
|
||||
* @pk: The associated public key; must not be NULL
|
||||
* @encoding: The encoding the key type uses
|
||||
* @sig: The xattr signature
|
||||
* @siglen: The length of the xattr signature; must be at least
|
||||
* sizeof(struct signature_v2_hdr)
|
||||
* @algo: hash algorithm [enum hash_algo]; caller must ensure valid value
|
||||
* @digest: The file digest
|
||||
*
|
||||
* Create an ima_file_id structure and use it for signature verification
|
||||
* directly. This can be used for ML-DSA in pure mode for example.
|
||||
*/
|
||||
static int asymmetric_verify_v3_hashless(struct key *key,
|
||||
const struct public_key *pk,
|
||||
const char *encoding,
|
||||
const char *sig, int siglen,
|
||||
u8 algo,
|
||||
const u8 *digest)
|
||||
{
|
||||
struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
|
||||
struct ima_file_id file_id = {
|
||||
.hash_type = hdr->type,
|
||||
.hash_algorithm = algo,
|
||||
};
|
||||
size_t digest_size = hash_digest_size[algo];
|
||||
struct public_key_signature pks = {
|
||||
.m = (u8 *)&file_id,
|
||||
.m_size = sizeof(file_id) - (HASH_MAX_DIGESTSIZE - digest_size),
|
||||
.s = hdr->sig,
|
||||
.s_size = siglen - sizeof(*hdr),
|
||||
.pkey_algo = pk->pkey_algo,
|
||||
.hash_algo = "none",
|
||||
.encoding = encoding,
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (hdr->type != IMA_VERITY_DIGSIG &&
|
||||
hdr->type != EVM_IMA_XATTR_DIGSIG &&
|
||||
hdr->type != EVM_XATTR_PORTABLE_DIGSIG)
|
||||
return -EINVAL;
|
||||
|
||||
if (pks.s_size != be16_to_cpu(hdr->sig_size))
|
||||
return -EBADMSG;
|
||||
|
||||
memcpy(file_id.hash, digest, digest_size);
|
||||
|
||||
ret = verify_signature(key, &pks);
|
||||
pr_debug("%s() = %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int asymmetric_verify_v3(struct key *keyring, const char *sig, int siglen,
|
||||
const char *data, int datalen, u8 algo)
|
||||
{
|
||||
struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
|
||||
struct ima_max_digest_data hash;
|
||||
const struct public_key *pk;
|
||||
struct key *key;
|
||||
int rc;
|
||||
|
||||
if (algo >= HASH_ALGO__LAST)
|
||||
return -ENOPKG;
|
||||
|
||||
rc = calc_file_id_hash(hdr->type, algo, data, &hash);
|
||||
if (rc)
|
||||
return -EINVAL;
|
||||
if (siglen <= sizeof(*hdr))
|
||||
return -EBADMSG;
|
||||
|
||||
return asymmetric_verify(keyring, sig, siglen, hash.digest,
|
||||
hash.hdr.length);
|
||||
key = request_asymmetric_key(keyring, be32_to_cpu(hdr->keyid));
|
||||
if (IS_ERR(key))
|
||||
return PTR_ERR(key);
|
||||
|
||||
pk = asymmetric_key_public_key(key);
|
||||
if (!pk) {
|
||||
rc = -ENOKEY;
|
||||
goto out;
|
||||
}
|
||||
if (!strncmp(pk->pkey_algo, "mldsa", 5)) {
|
||||
rc = asymmetric_verify_v3_hashless(key, pk, "raw",
|
||||
sig, siglen, algo, data);
|
||||
} else {
|
||||
rc = calc_file_id_hash(hdr->type, algo, data, &hash);
|
||||
if (rc) {
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = asymmetric_verify_common(key, pk, sig, siglen, hash.digest,
|
||||
hash.hdr.length);
|
||||
}
|
||||
|
||||
out:
|
||||
key_put(key);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user