mirror of
https://github.com/t2linux/kernel.git
synced 2026-04-30 13:48:59 -07:00
Merge branch 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity
Pull integrity updates from Mimi Zohar: "The major feature in this time is IMA support for measuring and appraising appended file signatures. In addition are a couple of bug fixes and code cleanup to use struct_size(). In addition to the PE/COFF and IMA xattr signatures, the kexec kernel image may be signed with an appended signature, using the same scripts/sign-file tool that is used to sign kernel modules. Similarly, the initramfs may contain an appended signature. This contained a lot of refactoring of the existing appended signature verification code, so that IMA could retain the existing framework of calculating the file hash once, storing it in the IMA measurement list and extending the TPM, verifying the file's integrity based on a file hash or signature (eg. xattrs), and adding an audit record containing the file hash, all based on policy. (The IMA support for appended signatures patch set was posted and reviewed 11 times.) The support for appended signature paves the way for adding other signature verification methods, such as fs-verity, based on a single system-wide policy. The file hash used for verifying the signature and the signature, itself, can be included in the IMA measurement list" * 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity: ima: ima_api: Use struct_size() in kzalloc() ima: use struct_size() in kzalloc() sefltest/ima: support appended signatures (modsig) ima: Fix use after free in ima_read_modsig() MODSIGN: make new include file self contained ima: fix freeing ongoing ahash_request ima: always return negative code for error ima: Store the measurement again when appraising a modsig ima: Define ima-modsig template ima: Collect modsig ima: Implement support for module-style appended signatures ima: Factor xattr_verify() out of ima_appraise_measurement() ima: Add modsig appraise_type option for module-style appended signatures integrity: Select CONFIG_KEYS instead of depending on it PKCS#7: Introduce pkcs7_get_digest() PKCS#7: Refactor verify_pkcs7_signature() MODSIGN: Export module signature definitions ima: initialize the "template" field with the default template
This commit is contained in:
@@ -37,7 +37,7 @@ Description:
|
||||
euid:= decimal value
|
||||
fowner:= decimal value
|
||||
lsm: are LSM specific
|
||||
option: appraise_type:= [imasig]
|
||||
option: appraise_type:= [imasig] [imasig|modsig]
|
||||
template:= name of a defined IMA template type
|
||||
(eg, ima-ng). Only valid when action is "measure".
|
||||
pcr:= decimal value
|
||||
@@ -105,3 +105,7 @@ Description:
|
||||
|
||||
measure func=KEXEC_KERNEL_CHECK pcr=4
|
||||
measure func=KEXEC_INITRAMFS_CHECK pcr=5
|
||||
|
||||
Example of appraise rule allowing modsig appended signatures:
|
||||
|
||||
appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig|modsig
|
||||
|
||||
@@ -68,8 +68,10 @@ descriptors by adding their identifier to the format string
|
||||
- 'd-ng': the digest of the event, calculated with an arbitrary hash
|
||||
algorithm (field format: [<hash algo>:]digest, where the digest
|
||||
prefix is shown only if the hash algorithm is not SHA1 or MD5);
|
||||
- 'd-modsig': the digest of the event without the appended modsig;
|
||||
- 'n-ng': the name of the event, without size limitations;
|
||||
- 'sig': the file signature;
|
||||
- 'modsig' the appended file signature;
|
||||
- 'buf': the buffer data that was used to generate the hash without size limitations;
|
||||
|
||||
|
||||
@@ -79,6 +81,7 @@ Below, there is the list of defined template descriptors:
|
||||
- "ima-ng" (default): its format is ``d-ng|n-ng``;
|
||||
- "ima-sig": its format is ``d-ng|n-ng|sig``;
|
||||
- "ima-buf": its format is ``d-ng|n-ng|buf``;
|
||||
- "ima-modsig": its format is ``d-ng|n-ng|sig|d-modsig|modsig``;
|
||||
|
||||
|
||||
Use
|
||||
|
||||
+1
-1
@@ -556,7 +556,7 @@ config ARCH_HAS_KEXEC_PURGATORY
|
||||
|
||||
config KEXEC_VERIFY_SIG
|
||||
bool "Verify kernel signature during kexec_file_load() syscall"
|
||||
depends on KEXEC_FILE && SYSTEM_DATA_VERIFICATION
|
||||
depends on KEXEC_FILE && MODULE_SIG_FORMAT
|
||||
help
|
||||
This option makes kernel signature verification mandatory for
|
||||
the kexec_file_load() syscall.
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <linux/elf.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/module_signature.h>
|
||||
#include <linux/verification.h>
|
||||
#include <asm/boot_data.h>
|
||||
#include <asm/ipl.h>
|
||||
@@ -23,28 +23,6 @@ const struct kexec_file_ops * const kexec_file_loaders[] = {
|
||||
};
|
||||
|
||||
#ifdef CONFIG_KEXEC_VERIFY_SIG
|
||||
/*
|
||||
* Module signature information block.
|
||||
*
|
||||
* The constituents of the signature section are, in order:
|
||||
*
|
||||
* - Signer's name
|
||||
* - Key identifier
|
||||
* - Signature data
|
||||
* - Information block
|
||||
*/
|
||||
struct module_signature {
|
||||
u8 algo; /* Public-key crypto algorithm [0] */
|
||||
u8 hash; /* Digest algorithm [0] */
|
||||
u8 id_type; /* Key identifier type [PKEY_ID_PKCS7] */
|
||||
u8 signer_len; /* Length of signer's name [0] */
|
||||
u8 key_id_len; /* Length of key identifier [0] */
|
||||
u8 __pad[3];
|
||||
__be32 sig_len; /* Length of signature data */
|
||||
};
|
||||
|
||||
#define PKEY_ID_PKCS7 2
|
||||
|
||||
int s390_verify_sig(const char *kernel, unsigned long kernel_len)
|
||||
{
|
||||
const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1;
|
||||
|
||||
+45
-16
@@ -190,33 +190,27 @@ late_initcall(load_system_certificate_list);
|
||||
#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
|
||||
|
||||
/**
|
||||
* verify_pkcs7_signature - Verify a PKCS#7-based signature on system data.
|
||||
* verify_pkcs7_message_sig - Verify a PKCS#7-based signature on system data.
|
||||
* @data: The data to be verified (NULL if expecting internal data).
|
||||
* @len: Size of @data.
|
||||
* @raw_pkcs7: The PKCS#7 message that is the signature.
|
||||
* @pkcs7_len: The size of @raw_pkcs7.
|
||||
* @pkcs7: The PKCS#7 message that is the signature.
|
||||
* @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only,
|
||||
* (void *)1UL for all trusted keys).
|
||||
* @usage: The use to which the key is being put.
|
||||
* @view_content: Callback to gain access to content.
|
||||
* @ctx: Context for callback.
|
||||
*/
|
||||
int verify_pkcs7_signature(const void *data, size_t len,
|
||||
const void *raw_pkcs7, size_t pkcs7_len,
|
||||
struct key *trusted_keys,
|
||||
enum key_being_used_for usage,
|
||||
int (*view_content)(void *ctx,
|
||||
const void *data, size_t len,
|
||||
size_t asn1hdrlen),
|
||||
void *ctx)
|
||||
int verify_pkcs7_message_sig(const void *data, size_t len,
|
||||
struct pkcs7_message *pkcs7,
|
||||
struct key *trusted_keys,
|
||||
enum key_being_used_for usage,
|
||||
int (*view_content)(void *ctx,
|
||||
const void *data, size_t len,
|
||||
size_t asn1hdrlen),
|
||||
void *ctx)
|
||||
{
|
||||
struct pkcs7_message *pkcs7;
|
||||
int ret;
|
||||
|
||||
pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len);
|
||||
if (IS_ERR(pkcs7))
|
||||
return PTR_ERR(pkcs7);
|
||||
|
||||
/* The data should be detached - so we need to supply it. */
|
||||
if (data && pkcs7_supply_detached_data(pkcs7, data, len) < 0) {
|
||||
pr_err("PKCS#7 signature with non-detached data\n");
|
||||
@@ -269,6 +263,41 @@ int verify_pkcs7_signature(const void *data, size_t len,
|
||||
}
|
||||
|
||||
error:
|
||||
pr_devel("<==%s() = %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* verify_pkcs7_signature - Verify a PKCS#7-based signature on system data.
|
||||
* @data: The data to be verified (NULL if expecting internal data).
|
||||
* @len: Size of @data.
|
||||
* @raw_pkcs7: The PKCS#7 message that is the signature.
|
||||
* @pkcs7_len: The size of @raw_pkcs7.
|
||||
* @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only,
|
||||
* (void *)1UL for all trusted keys).
|
||||
* @usage: The use to which the key is being put.
|
||||
* @view_content: Callback to gain access to content.
|
||||
* @ctx: Context for callback.
|
||||
*/
|
||||
int verify_pkcs7_signature(const void *data, size_t len,
|
||||
const void *raw_pkcs7, size_t pkcs7_len,
|
||||
struct key *trusted_keys,
|
||||
enum key_being_used_for usage,
|
||||
int (*view_content)(void *ctx,
|
||||
const void *data, size_t len,
|
||||
size_t asn1hdrlen),
|
||||
void *ctx)
|
||||
{
|
||||
struct pkcs7_message *pkcs7;
|
||||
int ret;
|
||||
|
||||
pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len);
|
||||
if (IS_ERR(pkcs7))
|
||||
return PTR_ERR(pkcs7);
|
||||
|
||||
ret = verify_pkcs7_message_sig(data, len, pkcs7, trusted_keys, usage,
|
||||
view_content, ctx);
|
||||
|
||||
pkcs7_free_message(pkcs7);
|
||||
pr_devel("<==%s() = %d\n", __func__, ret);
|
||||
return ret;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/asn1.h>
|
||||
#include <crypto/hash.h>
|
||||
#include <crypto/hash_info.h>
|
||||
#include <crypto/public_key.h>
|
||||
#include "pkcs7_parser.h"
|
||||
|
||||
@@ -29,6 +30,10 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
|
||||
|
||||
kenter(",%u,%s", sinfo->index, sinfo->sig->hash_algo);
|
||||
|
||||
/* The digest was calculated already. */
|
||||
if (sig->digest)
|
||||
return 0;
|
||||
|
||||
if (!sinfo->sig->hash_algo)
|
||||
return -ENOPKG;
|
||||
|
||||
@@ -117,6 +122,34 @@ error_no_desc:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int pkcs7_get_digest(struct pkcs7_message *pkcs7, const u8 **buf, u32 *len,
|
||||
enum hash_algo *hash_algo)
|
||||
{
|
||||
struct pkcs7_signed_info *sinfo = pkcs7->signed_infos;
|
||||
int i, ret;
|
||||
|
||||
/*
|
||||
* This function doesn't support messages with more than one signature.
|
||||
*/
|
||||
if (sinfo == NULL || sinfo->next != NULL)
|
||||
return -EBADMSG;
|
||||
|
||||
ret = pkcs7_digest(pkcs7, sinfo);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*buf = sinfo->sig->digest;
|
||||
*len = sinfo->sig->digest_size;
|
||||
|
||||
for (i = 0; i < HASH_ALGO__LAST; i++)
|
||||
if (!strcmp(hash_algo_name[i], sinfo->sig->hash_algo)) {
|
||||
*hash_algo = i;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the key (X.509 certificate) to use to verify a PKCS#7 message. PKCS#7
|
||||
* uses the issuer's name and the issuing certificate serial number for
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#define _CRYPTO_PKCS7_H
|
||||
|
||||
#include <linux/verification.h>
|
||||
#include <linux/hash_info.h>
|
||||
#include <crypto/public_key.h>
|
||||
|
||||
struct key;
|
||||
@@ -40,4 +41,7 @@ extern int pkcs7_verify(struct pkcs7_message *pkcs7,
|
||||
extern int pkcs7_supply_detached_data(struct pkcs7_message *pkcs7,
|
||||
const void *data, size_t datalen);
|
||||
|
||||
extern int pkcs7_get_digest(struct pkcs7_message *pkcs7, const u8 **buf,
|
||||
u32 *len, enum hash_algo *hash_algo);
|
||||
|
||||
#endif /* _CRYPTO_PKCS7_H */
|
||||
|
||||
@@ -26,9 +26,6 @@
|
||||
#include <linux/percpu.h>
|
||||
#include <asm/module.h>
|
||||
|
||||
/* In stripped ARM and x86-64 modules, ~ is surprisingly rare. */
|
||||
#define MODULE_SIG_STRING "~Module signature appended~\n"
|
||||
|
||||
/* Not Yet Implemented */
|
||||
#define MODULE_SUPPORTED_DEVICE(name)
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Module signature handling.
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_MODULE_SIGNATURE_H
|
||||
#define _LINUX_MODULE_SIGNATURE_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* In stripped ARM and x86-64 modules, ~ is surprisingly rare. */
|
||||
#define MODULE_SIG_STRING "~Module signature appended~\n"
|
||||
|
||||
enum pkey_id_type {
|
||||
PKEY_ID_PGP, /* OpenPGP generated key ID */
|
||||
PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */
|
||||
PKEY_ID_PKCS7, /* Signature in PKCS#7 message */
|
||||
};
|
||||
|
||||
/*
|
||||
* Module signature information block.
|
||||
*
|
||||
* The constituents of the signature section are, in order:
|
||||
*
|
||||
* - Signer's name
|
||||
* - Key identifier
|
||||
* - Signature data
|
||||
* - Information block
|
||||
*/
|
||||
struct module_signature {
|
||||
u8 algo; /* Public-key crypto algorithm [0] */
|
||||
u8 hash; /* Digest algorithm [0] */
|
||||
u8 id_type; /* Key identifier type [PKEY_ID_PKCS7] */
|
||||
u8 signer_len; /* Length of signer's name [0] */
|
||||
u8 key_id_len; /* Length of key identifier [0] */
|
||||
u8 __pad[3];
|
||||
__be32 sig_len; /* Length of signature data */
|
||||
};
|
||||
|
||||
int mod_check_sig(const struct module_signature *ms, size_t file_len,
|
||||
const char *name);
|
||||
|
||||
#endif /* _LINUX_MODULE_SIGNATURE_H */
|
||||
@@ -32,6 +32,7 @@ extern const char *const key_being_used_for[NR__KEY_BEING_USED_FOR];
|
||||
#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
|
||||
|
||||
struct key;
|
||||
struct pkcs7_message;
|
||||
|
||||
extern int verify_pkcs7_signature(const void *data, size_t len,
|
||||
const void *raw_pkcs7, size_t pkcs7_len,
|
||||
@@ -41,6 +42,15 @@ extern int verify_pkcs7_signature(const void *data, size_t len,
|
||||
const void *data, size_t len,
|
||||
size_t asn1hdrlen),
|
||||
void *ctx);
|
||||
extern int verify_pkcs7_message_sig(const void *data, size_t len,
|
||||
struct pkcs7_message *pkcs7,
|
||||
struct key *trusted_keys,
|
||||
enum key_being_used_for usage,
|
||||
int (*view_content)(void *ctx,
|
||||
const void *data,
|
||||
size_t len,
|
||||
size_t asn1hdrlen),
|
||||
void *ctx);
|
||||
|
||||
#ifdef CONFIG_SIGNED_PE_FILE_VERIFICATION
|
||||
extern int verify_pefile_signature(const void *pebuf, unsigned pelen,
|
||||
|
||||
+5
-1
@@ -1963,6 +1963,10 @@ config BASE_SMALL
|
||||
default 0 if BASE_FULL
|
||||
default 1 if !BASE_FULL
|
||||
|
||||
config MODULE_SIG_FORMAT
|
||||
def_bool n
|
||||
select SYSTEM_DATA_VERIFICATION
|
||||
|
||||
menuconfig MODULES
|
||||
bool "Enable loadable module support"
|
||||
option modules
|
||||
@@ -2047,7 +2051,7 @@ config MODULE_SRCVERSION_ALL
|
||||
|
||||
config MODULE_SIG
|
||||
bool "Module signature verification"
|
||||
select SYSTEM_DATA_VERIFICATION
|
||||
select MODULE_SIG_FORMAT
|
||||
help
|
||||
Check modules for valid signatures upon load: the signature
|
||||
is simply appended to the module. For more information see
|
||||
|
||||
@@ -58,6 +58,7 @@ endif
|
||||
obj-$(CONFIG_UID16) += uid16.o
|
||||
obj-$(CONFIG_MODULES) += module.o
|
||||
obj-$(CONFIG_MODULE_SIG) += module_signing.o
|
||||
obj-$(CONFIG_MODULE_SIG_FORMAT) += module_signature.o
|
||||
obj-$(CONFIG_KALLSYMS) += kallsyms.o
|
||||
obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
|
||||
obj-$(CONFIG_CRASH_CORE) += crash_core.o
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <linux/export.h>
|
||||
#include <linux/extable.h>
|
||||
#include <linux/moduleloader.h>
|
||||
#include <linux/module_signature.h>
|
||||
#include <linux/trace_events.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kallsyms.h>
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Module signature checker
|
||||
*
|
||||
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
*/
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/module_signature.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
/**
|
||||
* mod_check_sig - check that the given signature is sane
|
||||
*
|
||||
* @ms: Signature to check.
|
||||
* @file_len: Size of the file to which @ms is appended.
|
||||
* @name: What is being checked. Used for error messages.
|
||||
*/
|
||||
int mod_check_sig(const struct module_signature *ms, size_t file_len,
|
||||
const char *name)
|
||||
{
|
||||
if (be32_to_cpu(ms->sig_len) >= file_len - sizeof(*ms))
|
||||
return -EBADMSG;
|
||||
|
||||
if (ms->id_type != PKEY_ID_PKCS7) {
|
||||
pr_err("%s: Module is not signed with expected PKCS#7 message\n",
|
||||
name);
|
||||
return -ENOPKG;
|
||||
}
|
||||
|
||||
if (ms->algo != 0 ||
|
||||
ms->hash != 0 ||
|
||||
ms->signer_len != 0 ||
|
||||
ms->key_id_len != 0 ||
|
||||
ms->__pad[0] != 0 ||
|
||||
ms->__pad[1] != 0 ||
|
||||
ms->__pad[2] != 0) {
|
||||
pr_err("%s: PKCS#7 signature info has unexpected non-zero params\n",
|
||||
name);
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
+8
-48
@@ -7,37 +7,13 @@
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/module_signature.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/verification.h>
|
||||
#include <crypto/public_key.h>
|
||||
#include "module-internal.h"
|
||||
|
||||
enum pkey_id_type {
|
||||
PKEY_ID_PGP, /* OpenPGP generated key ID */
|
||||
PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */
|
||||
PKEY_ID_PKCS7, /* Signature in PKCS#7 message */
|
||||
};
|
||||
|
||||
/*
|
||||
* Module signature information block.
|
||||
*
|
||||
* The constituents of the signature section are, in order:
|
||||
*
|
||||
* - Signer's name
|
||||
* - Key identifier
|
||||
* - Signature data
|
||||
* - Information block
|
||||
*/
|
||||
struct module_signature {
|
||||
u8 algo; /* Public-key crypto algorithm [0] */
|
||||
u8 hash; /* Digest algorithm [0] */
|
||||
u8 id_type; /* Key identifier type [PKEY_ID_PKCS7] */
|
||||
u8 signer_len; /* Length of signer's name [0] */
|
||||
u8 key_id_len; /* Length of key identifier [0] */
|
||||
u8 __pad[3];
|
||||
__be32 sig_len; /* Length of signature data */
|
||||
};
|
||||
|
||||
/*
|
||||
* Verify the signature on a module.
|
||||
*/
|
||||
@@ -45,6 +21,7 @@ int mod_verify_sig(const void *mod, struct load_info *info)
|
||||
{
|
||||
struct module_signature ms;
|
||||
size_t sig_len, modlen = info->len;
|
||||
int ret;
|
||||
|
||||
pr_devel("==>%s(,%zu)\n", __func__, modlen);
|
||||
|
||||
@@ -52,32 +29,15 @@ int mod_verify_sig(const void *mod, struct load_info *info)
|
||||
return -EBADMSG;
|
||||
|
||||
memcpy(&ms, mod + (modlen - sizeof(ms)), sizeof(ms));
|
||||
modlen -= sizeof(ms);
|
||||
|
||||
ret = mod_check_sig(&ms, modlen, info->name);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
sig_len = be32_to_cpu(ms.sig_len);
|
||||
if (sig_len >= modlen)
|
||||
return -EBADMSG;
|
||||
modlen -= sig_len;
|
||||
modlen -= sig_len + sizeof(ms);
|
||||
info->len = modlen;
|
||||
|
||||
if (ms.id_type != PKEY_ID_PKCS7) {
|
||||
pr_err("%s: Module is not signed with expected PKCS#7 message\n",
|
||||
info->name);
|
||||
return -ENOPKG;
|
||||
}
|
||||
|
||||
if (ms.algo != 0 ||
|
||||
ms.hash != 0 ||
|
||||
ms.signer_len != 0 ||
|
||||
ms.key_id_len != 0 ||
|
||||
ms.__pad[0] != 0 ||
|
||||
ms.__pad[1] != 0 ||
|
||||
ms.__pad[2] != 0) {
|
||||
pr_err("%s: PKCS#7 signature info has unexpected non-zero params\n",
|
||||
info->name);
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
|
||||
VERIFY_USE_SECONDARY_KEYRING,
|
||||
VERIFYING_MODULE_SIGNATURE,
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ hostprogs-$(CONFIG_VT) += conmakehash
|
||||
hostprogs-$(BUILD_C_RECORDMCOUNT) += recordmcount
|
||||
hostprogs-$(CONFIG_BUILDTIME_EXTABLE_SORT) += sortextable
|
||||
hostprogs-$(CONFIG_ASN1) += asn1_compiler
|
||||
hostprogs-$(CONFIG_MODULE_SIG) += sign-file
|
||||
hostprogs-$(CONFIG_MODULE_SIG_FORMAT) += sign-file
|
||||
hostprogs-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert
|
||||
hostprogs-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ if INTEGRITY
|
||||
|
||||
config INTEGRITY_SIGNATURE
|
||||
bool "Digital signature verification using multiple keyrings"
|
||||
depends on KEYS
|
||||
default n
|
||||
select KEYS
|
||||
select SIGNATURE
|
||||
help
|
||||
This option enables digital signature verification support
|
||||
|
||||
@@ -39,11 +39,10 @@ static const char * const keyring_name[INTEGRITY_KEYRING_MAX] = {
|
||||
#define restrict_link_to_ima restrict_link_by_builtin_trusted
|
||||
#endif
|
||||
|
||||
int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
|
||||
const char *digest, int digestlen)
|
||||
static struct key *integrity_keyring_from_id(const unsigned int id)
|
||||
{
|
||||
if (id >= INTEGRITY_KEYRING_MAX || siglen < 2)
|
||||
return -EINVAL;
|
||||
if (id >= INTEGRITY_KEYRING_MAX)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (!keyring[id]) {
|
||||
keyring[id] =
|
||||
@@ -52,23 +51,49 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
|
||||
int err = PTR_ERR(keyring[id]);
|
||||
pr_err("no %s keyring: %d\n", keyring_name[id], err);
|
||||
keyring[id] = NULL;
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
}
|
||||
|
||||
return keyring[id];
|
||||
}
|
||||
|
||||
int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
|
||||
const char *digest, int digestlen)
|
||||
{
|
||||
struct key *keyring;
|
||||
|
||||
if (siglen < 2)
|
||||
return -EINVAL;
|
||||
|
||||
keyring = integrity_keyring_from_id(id);
|
||||
if (IS_ERR(keyring))
|
||||
return PTR_ERR(keyring);
|
||||
|
||||
switch (sig[1]) {
|
||||
case 1:
|
||||
/* v1 API expect signature without xattr type */
|
||||
return digsig_verify(keyring[id], sig + 1, siglen - 1,
|
||||
digest, digestlen);
|
||||
return digsig_verify(keyring, sig + 1, siglen - 1, digest,
|
||||
digestlen);
|
||||
case 2:
|
||||
return asymmetric_verify(keyring[id], sig, siglen,
|
||||
digest, digestlen);
|
||||
return asymmetric_verify(keyring, sig, siglen, digest,
|
||||
digestlen);
|
||||
}
|
||||
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int integrity_modsig_verify(const unsigned int id, const struct modsig *modsig)
|
||||
{
|
||||
struct key *keyring;
|
||||
|
||||
keyring = integrity_keyring_from_id(id);
|
||||
if (IS_ERR(keyring))
|
||||
return PTR_ERR(keyring);
|
||||
|
||||
return ima_modsig_verify(keyring, modsig);
|
||||
}
|
||||
|
||||
static int __init __integrity_init_keyring(const unsigned int id,
|
||||
key_perm_t perm,
|
||||
struct key_restriction *restriction)
|
||||
|
||||
@@ -233,6 +233,19 @@ config IMA_APPRAISE_BOOTPARAM
|
||||
This option enables the different "ima_appraise=" modes
|
||||
(eg. fix, log) from the boot command line.
|
||||
|
||||
config IMA_APPRAISE_MODSIG
|
||||
bool "Support module-style signatures for appraisal"
|
||||
depends on IMA_APPRAISE
|
||||
depends on INTEGRITY_ASYMMETRIC_KEYS
|
||||
select PKCS7_MESSAGE_PARSER
|
||||
select MODULE_SIG_FORMAT
|
||||
default n
|
||||
help
|
||||
Adds support for signatures appended to files. The format of the
|
||||
appended signature is the same used for signed kernel modules.
|
||||
The modsig keyword can be used in the IMA policy to allow a hook
|
||||
to accept such signatures.
|
||||
|
||||
config IMA_TRUSTED_KEYRING
|
||||
bool "Require all keys on the .ima keyring be signed (deprecated)"
|
||||
depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING
|
||||
|
||||
@@ -9,5 +9,6 @@ obj-$(CONFIG_IMA) += ima.o
|
||||
ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
|
||||
ima_policy.o ima_template.o ima_template_lib.o
|
||||
ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
|
||||
ima-$(CONFIG_IMA_APPRAISE_MODSIG) += ima_modsig.o
|
||||
ima-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o
|
||||
obj-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user