From 3a2d7781005ebb25f87f6b71d6f2da7087d9d578 Mon Sep 17 00:00:00 2001 From: lihehe Date: Fri, 27 Oct 2023 22:23:42 +0800 Subject: [PATCH] verify part data in file to support code signing Change-Id: I06948b7bf8741449dfa1af1964d9170329d90b4b Signed-off-by: lihehe --- code_sign/Kconfig | 9 ++-- code_sign/Makefile | 3 +- code_sign/code_sign_ext.c | 84 ++++++++++++++++++++++++++++++++++++++ code_sign/code_sign_ext.h | 19 +++++++++ code_sign/code_sign_misc.c | 6 ++- 5 files changed, 115 insertions(+), 6 deletions(-) create mode 100644 code_sign/code_sign_ext.c create mode 100644 code_sign/code_sign_ext.h diff --git a/code_sign/Kconfig b/code_sign/Kconfig index 0c6a9aa..e042f87 100644 --- a/code_sign/Kconfig +++ b/code_sign/Kconfig @@ -2,12 +2,13 @@ # Copyright (c) 2023 Huawei Device Co., Ltd. # config SECURITY_CODE_SIGN - bool "Advanced code signing feature based on FS Verity" + bool "Advanced code signing features based on FS Verity" depends on FS_VERITY default n help - This option enables additional code signing verify features - based on fs-verity, including verify if a certificate's subject - and issuer can be trusted, etc. + This option enables additional code signing features based + on fs-verity, such as 1) protecting part of file to support + carried signature and Merkle tree, 2) verifying if a signing + certificate can be trusted, etc. If unsure, say N. diff --git a/code_sign/Makefile b/code_sign/Makefile index ab3b982..894ea26 100644 --- a/code_sign/Makefile +++ b/code_sign/Makefile @@ -4,7 +4,8 @@ obj-$(CONFIG_SECURITY_CODE_SIGN) += \ code_sign_misc.o \ verify_cert_chain.o \ - code_sign_ioctl.o + code_sign_ioctl.o \ + code_sign_ext.o ccflags-$(CONFIG_SECURITY_CODE_SIGN) += \ -I$(srctree)/fs/code_sign \ diff --git a/code_sign/code_sign_ext.c b/code_sign/code_sign_ext.c new file mode 100644 index 0000000..c5d2126 --- /dev/null +++ b/code_sign/code_sign_ext.c @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + */ + +#include +#include + +#include "code_sign_ext.h" +#include "code_sign_log.h" + +/** + * Validate code sign descriptor + * + * Return: 1 on code sign version, 0 on basic version, and -errno on failure + */ +static inline int check_code_sign_descriptor(const struct inode *inode, + const struct code_sign_descriptor *desc) +{ + u64 tree_offset = le64_to_cpu(desc->tree_offset); + + if (!desc->cs_version) + return 0; + + if (desc->__reserved1 || + memchr_inv(desc->__reserved2, 0, sizeof(desc->__reserved2))) + return -EINVAL; + + if (le64_to_cpu(desc->data_size) > inode->i_size) { + code_sign_log_error("Wrong data_size: %llu (desc) > %lld (inode)", + le64_to_cpu(desc->data_size), inode->i_size); + return -EINVAL; + } + + if (desc->salt_size > sizeof(desc->salt)) { + code_sign_log_error("Invalid salt_size: %u", desc->salt_size); + return -EINVAL; + } + + if (IS_INSIDE_TREE(desc)) { + if ((tree_offset > inode->i_size) || (tree_offset % PAGE_SIZE != 0)) { + code_sign_log_error( + "Wrong tree_offset: %llu (desc) > %lld (file size) or alignment is wrong", + tree_offset, inode->i_size); + return -EINVAL; + } + } else { + if (tree_offset != 0) { + code_sign_log_error( + "Wrong tree_offset without tree: %llu (desc) != 0", + tree_offset); + return -EINVAL; + } + } + return 1; +} + +void code_sign_check_descriptor(const struct inode *inode, const void *desc, int *ret) +{ + *ret = check_code_sign_descriptor(inode, CONST_CAST_CODE_SIGN_DESC(desc)); +} + +void code_sign_before_measurement(void *_desc, int *ret) +{ + struct code_sign_descriptor *desc = CAST_CODE_SIGN_DESC(_desc); + + if (desc->cs_version) { + // replace version with cs_version + desc->version = desc->cs_version; + desc->cs_version = 0; + *ret = desc->version; + } +} + +void code_sign_after_measurement(void *_desc, int version) +{ + struct code_sign_descriptor *desc = CAST_CODE_SIGN_DESC(_desc); + + if (version) { + // restore cs_version + desc->cs_version = desc->version; + desc->version = version; + } +} diff --git a/code_sign/code_sign_ext.h b/code_sign/code_sign_ext.h new file mode 100644 index 0000000..d424907 --- /dev/null +++ b/code_sign/code_sign_ext.h @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + */ + +#ifndef _CODE_SIGN_EXT_H +#define _CODE_SIGN_EXT_H + +/* + * code_sign_ext.c + */ +void code_sign_check_descriptor(const struct inode *inode, + const void *desc, int *ret); + +void code_sign_before_measurement(void *_desc, int *ret); + +void code_sign_after_measurement(void *_desc, int version); + +#endif /* _CODE_SIGN_H */ diff --git a/code_sign/code_sign_misc.c b/code_sign/code_sign_misc.c index c2237bd..0fe17ee 100644 --- a/code_sign/code_sign_misc.c +++ b/code_sign/code_sign_misc.c @@ -10,6 +10,7 @@ #include "code_sign_ioctl.h" #include "code_sign_log.h" +#include "code_sign_ext.h" static const struct file_operations code_sign_ops = { .owner = THIS_MODULE, @@ -28,6 +29,9 @@ static struct miscdevice code_sign_misc = { static void code_sign_register_hck_hooks(void) { REGISTER_HCK_LITE_HOOK(code_sign_verify_certchain_lhck, code_sign_verify_certchain); + REGISTER_HCK_LITE_HOOK(code_sign_check_descriptor_lhck, code_sign_check_descriptor); + REGISTER_HCK_LITE_HOOK(code_sign_before_measurement_lhck, code_sign_before_measurement); + REGISTER_HCK_LITE_HOOK(code_sign_after_measurement_lhck, code_sign_after_measurement); } static int __init code_sign_init(void) @@ -46,4 +50,4 @@ static void __exit code_sign_exit(void) module_init(code_sign_init); module_exit(code_sign_exit); -MODULE_LICENSE("GPL"); \ No newline at end of file +MODULE_LICENSE("GPL"); -- Gitee