integrity-v6.18

-----BEGIN PGP SIGNATURE-----
 
 iIoEABYKADIWIQQdXVVFGN5XqKr1Hj7LwZzRsCrn5QUCaOAhtRQcem9oYXJAbGlu
 dXguaWJtLmNvbQAKCRDLwZzRsCrn5bGkAP91Vptp6rJj3R0N0M338tzkVaeybA+V
 fjOHnuB8AvF+FwD/XGLF+lcIFiB8GizXGf/OoyXJwYwciNU7hEdONh5dzQ0=
 =euve
 -----END PGP SIGNATURE-----

Merge tag 'integrity-v6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity

Pull integrity updates from Mimi Zohar:
 "Just a couple of changes: crypto code cleanup and a IMA xattr bug fix"

* tag 'integrity-v6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity:
  ima: don't clear IMA_DIGSIG flag when setting or removing non-IMA xattr
  lib/digsig: Use SHA-1 library instead of crypto_shash
  integrity: Select CRYPTO from INTEGRITY_ASYMMETRIC_KEYS
pull/1354/merge
Linus Torvalds 2025-10-05 10:48:33 -07:00
commit 678074f1a8
4 changed files with 26 additions and 47 deletions

View File

@ -477,8 +477,7 @@ config MPILIB
config SIGNATURE config SIGNATURE
tristate tristate
depends on KEYS depends on KEYS
select CRYPTO select CRYPTO_LIB_SHA1
select CRYPTO_SHA1
select MPILIB select MPILIB
help help
Digital signature verification. Currently only RSA is supported. Digital signature verification. Currently only RSA is supported.

View File

@ -18,15 +18,11 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/key.h> #include <linux/key.h>
#include <linux/crypto.h>
#include <crypto/hash.h>
#include <crypto/sha1.h> #include <crypto/sha1.h>
#include <keys/user-type.h> #include <keys/user-type.h>
#include <linux/mpi.h> #include <linux/mpi.h>
#include <linux/digsig.h> #include <linux/digsig.h>
static struct crypto_shash *shash;
static const char *pkcs_1_v1_5_decode_emsa(const unsigned char *msg, static const char *pkcs_1_v1_5_decode_emsa(const unsigned char *msg,
unsigned long msglen, unsigned long msglen,
unsigned long modulus_bitlen, unsigned long modulus_bitlen,
@ -198,12 +194,12 @@ err1:
int digsig_verify(struct key *keyring, const char *sig, int siglen, int digsig_verify(struct key *keyring, const char *sig, int siglen,
const char *data, int datalen) const char *data, int datalen)
{ {
int err = -ENOMEM;
struct signature_hdr *sh = (struct signature_hdr *)sig; struct signature_hdr *sh = (struct signature_hdr *)sig;
struct shash_desc *desc = NULL; struct sha1_ctx ctx;
unsigned char hash[SHA1_DIGEST_SIZE]; unsigned char hash[SHA1_DIGEST_SIZE];
struct key *key; struct key *key;
char name[20]; char name[20];
int err;
if (siglen < sizeof(*sh) + 2) if (siglen < sizeof(*sh) + 2)
return -EINVAL; return -EINVAL;
@ -230,49 +226,19 @@ int digsig_verify(struct key *keyring, const char *sig, int siglen,
return PTR_ERR(key); return PTR_ERR(key);
} }
desc = kzalloc(sizeof(*desc) + crypto_shash_descsize(shash), sha1_init(&ctx);
GFP_KERNEL); sha1_update(&ctx, data, datalen);
if (!desc) sha1_update(&ctx, sig, sizeof(*sh));
goto err; sha1_final(&ctx, hash);
desc->tfm = shash;
crypto_shash_init(desc);
crypto_shash_update(desc, data, datalen);
crypto_shash_update(desc, sig, sizeof(*sh));
crypto_shash_final(desc, hash);
kfree(desc);
/* pass signature mpis address */ /* pass signature mpis address */
err = digsig_verify_rsa(key, sig + sizeof(*sh), siglen - sizeof(*sh), err = digsig_verify_rsa(key, sig + sizeof(*sh), siglen - sizeof(*sh),
hash, sizeof(hash)); hash, sizeof(hash));
err:
key_put(key); key_put(key);
return err ? -EINVAL : 0; return err ? -EINVAL : 0;
} }
EXPORT_SYMBOL_GPL(digsig_verify); EXPORT_SYMBOL_GPL(digsig_verify);
static int __init digsig_init(void)
{
shash = crypto_alloc_shash("sha1", 0, 0);
if (IS_ERR(shash)) {
pr_err("shash allocation failed\n");
return PTR_ERR(shash);
}
return 0;
}
static void __exit digsig_cleanup(void)
{
crypto_free_shash(shash);
}
module_init(digsig_init);
module_exit(digsig_cleanup);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");

View File

@ -36,6 +36,7 @@ config INTEGRITY_ASYMMETRIC_KEYS
default n default n
select ASYMMETRIC_KEY_TYPE select ASYMMETRIC_KEY_TYPE
select ASYMMETRIC_PUBLIC_KEY_SUBTYPE select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
select CRYPTO
select CRYPTO_RSA select CRYPTO_RSA
select X509_CERTIFICATE_PARSER select X509_CERTIFICATE_PARSER
help help

View File

@ -694,6 +694,15 @@ static int ima_protect_xattr(struct dentry *dentry, const char *xattr_name,
return 0; return 0;
} }
/*
* ima_reset_appraise_flags - reset ima_iint_cache flags
*
* @digsig: whether to clear/set IMA_DIGSIG flag, tristate values
* 0: clear IMA_DIGSIG
* 1: set IMA_DIGSIG
* -1: don't change IMA_DIGSIG
*
*/
static void ima_reset_appraise_flags(struct inode *inode, int digsig) static void ima_reset_appraise_flags(struct inode *inode, int digsig)
{ {
struct ima_iint_cache *iint; struct ima_iint_cache *iint;
@ -706,9 +715,9 @@ static void ima_reset_appraise_flags(struct inode *inode, int digsig)
return; return;
iint->measured_pcrs = 0; iint->measured_pcrs = 0;
set_bit(IMA_CHANGE_XATTR, &iint->atomic_flags); set_bit(IMA_CHANGE_XATTR, &iint->atomic_flags);
if (digsig) if (digsig == 1)
set_bit(IMA_DIGSIG, &iint->atomic_flags); set_bit(IMA_DIGSIG, &iint->atomic_flags);
else else if (digsig == 0)
clear_bit(IMA_DIGSIG, &iint->atomic_flags); clear_bit(IMA_DIGSIG, &iint->atomic_flags);
} }
@ -794,6 +803,8 @@ static int ima_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
digsig = (xvalue->type == EVM_IMA_XATTR_DIGSIG); digsig = (xvalue->type == EVM_IMA_XATTR_DIGSIG);
} else if (!strcmp(xattr_name, XATTR_NAME_EVM) && xattr_value_len > 0) { } else if (!strcmp(xattr_name, XATTR_NAME_EVM) && xattr_value_len > 0) {
digsig = (xvalue->type == EVM_XATTR_PORTABLE_DIGSIG); digsig = (xvalue->type == EVM_XATTR_PORTABLE_DIGSIG);
} else {
digsig = -1;
} }
if (result == 1 || evm_revalidate_status(xattr_name)) { if (result == 1 || evm_revalidate_status(xattr_name)) {
ima_reset_appraise_flags(d_backing_inode(dentry), digsig); ima_reset_appraise_flags(d_backing_inode(dentry), digsig);
@ -807,7 +818,7 @@ static int ima_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
const char *acl_name, struct posix_acl *kacl) const char *acl_name, struct posix_acl *kacl)
{ {
if (evm_revalidate_status(acl_name)) if (evm_revalidate_status(acl_name))
ima_reset_appraise_flags(d_backing_inode(dentry), 0); ima_reset_appraise_flags(d_backing_inode(dentry), -1);
return 0; return 0;
} }
@ -815,11 +826,13 @@ static int ima_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
static int ima_inode_removexattr(struct mnt_idmap *idmap, struct dentry *dentry, static int ima_inode_removexattr(struct mnt_idmap *idmap, struct dentry *dentry,
const char *xattr_name) const char *xattr_name)
{ {
int result; int result, digsig = -1;
result = ima_protect_xattr(dentry, xattr_name, NULL, 0); result = ima_protect_xattr(dentry, xattr_name, NULL, 0);
if (result == 1 || evm_revalidate_status(xattr_name)) { if (result == 1 || evm_revalidate_status(xattr_name)) {
ima_reset_appraise_flags(d_backing_inode(dentry), 0); if (!strcmp(xattr_name, XATTR_NAME_IMA))
digsig = 0;
ima_reset_appraise_flags(d_backing_inode(dentry), digsig);
if (result == 1) if (result == 1)
result = 0; result = 0;
} }