|
From: Mikhail K. <vie...@vi...> - 2016-12-23 22:59:24
|
I am not sure, if portable EVM signature version is still in discussion or not, but, in case of someone interested in this feature too, I propose to discuss patch that I am using. This patch are used for custom kernels in order to provide initial EVM signed files in packages from package build server to desktop PCs. This patch add portable EVM signature version support (can be tested on files signed by evmctl util with "-i" flag). This patch based on previous Dmitry's patch (https://sourceforge.net/p/linux-ima/mailman/message/32987311/) cleaned and revised in order to provide only portable EVM signature version support and nothing more. Signed-off-by: Dmitry Kasatkin <d.k...@sa...> Signed-off-by: Mikhail Kurinnoi <vie...@vi...> --- a/security/integrity/digsig.c 2016-07-24 22:23:50.000000000 +0300 +++ b/security/integrity/digsig.c 2016-12-22 21:18:16.504929652 +0300 @@ -71,6 +71,7 @@ int integrity_digsig_verify(const unsign return digsig_verify(keyring[id], sig + 1, siglen - 1, digest, digestlen); case 2: + case 3: return asymmetric_verify(keyring[id], sig, siglen, digest, digestlen); } --- a/security/integrity/evm/evm.h 2016-07-24 22:23:50.000000000 +0300 +++ b/security/integrity/evm/evm.h 2016-12-22 21:19:02.225835301 +0300 @@ -48,7 +48,7 @@ int evm_calc_hmac(struct dentry *dentry, size_t req_xattr_value_len, char *digest); int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name, const char *req_xattr_value, - size_t req_xattr_value_len, char *digest); + size_t req_xattr_value_len, int version, char *digest); int evm_init_hmac(struct inode *inode, const struct xattr *xattr, char *hmac_val); int evm_init_secfs(void); --- a/security/integrity/evm/evm_crypto.c 2016-07-24 22:23:50.000000000 +0300 +++ b/security/integrity/evm/evm_crypto.c 2016-12-22 21:20:36.667704195 +0300 @@ -161,6 +161,23 @@ static void hmac_add_misc(struct shash_d crypto_shash_final(desc, digest); } +static void hmac_add_misc_digsig(struct shash_desc *desc, struct inode *inode, + char *digest) +{ + struct h_misc { + uid_t uid; + gid_t gid; + umode_t mode; + } hmac_misc; + + memset(&hmac_misc, 0, sizeof(hmac_misc)); + hmac_misc.uid = from_kuid(&init_user_ns, inode->i_uid); + hmac_misc.gid = from_kgid(&init_user_ns, inode->i_gid); + hmac_misc.mode = inode->i_mode; + crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof(hmac_misc)); + crypto_shash_final(desc, digest); +} + /* * Calculate the HMAC value across the set of protected security xattrs. * @@ -210,7 +227,10 @@ static int evm_calc_hmac_or_hash(struct xattr_size = size; crypto_shash_update(desc, (const u8 *)xattr_value, xattr_size); } - hmac_add_misc(desc, inode, digest); + if (type == EVM_IMA_XATTR_DIGSIG) + hmac_add_misc_digsig(desc, inode, digest); + else + hmac_add_misc(desc, inode, digest); out: kfree(xattr_value); @@ -228,10 +248,12 @@ int evm_calc_hmac(struct dentry *dentry, int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name, const char *req_xattr_value, size_t req_xattr_value_len, - char *digest) + int version, char *digest) { return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value, - req_xattr_value_len, IMA_XATTR_DIGEST, digest); + req_xattr_value_len, + version == 3 ? EVM_IMA_XATTR_DIGSIG : IMA_XATTR_DIGEST, + digest); } /* --- a/security/integrity/evm/evm_main.c 2016-12-22 21:16:15.159523000 +0300 +++ b/security/integrity/evm/evm_main.c 2016-12-22 21:21:42.445004576 +0300 @@ -120,7 +120,7 @@ static enum integrity_status evm_verify_ struct evm_ima_xattr_data *xattr_data = NULL; struct evm_ima_xattr_data calc; enum integrity_status evm_status = INTEGRITY_PASS; - int rc, xattr_len; + int rc, xattr_len, version; if (iint && iint->evm_status == INTEGRITY_PASS) return iint->evm_status; @@ -159,8 +159,9 @@ static enum integrity_status evm_verify_ rc = -EINVAL; break; case EVM_IMA_XATTR_DIGSIG: + version = ((const char *)xattr_data)[1]; rc = evm_calc_hash(dentry, xattr_name, xattr_value, - xattr_value_len, calc.digest); + xattr_value_len, version, calc.digest); if (rc) break; rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM, |