verify part data in file to support code signing

Change-Id: I06948b7bf8741449dfa1af1964d9170329d90b4b
Signed-off-by: lihehe <lihehao@huawei.com>
This commit is contained in:
lihehe
2023-10-27 22:23:42 +08:00
parent 5b546b92eb
commit ce31db2c6c
5 changed files with 115 additions and 6 deletions
+5 -4
View File
@@ -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.
+2 -1
View File
@@ -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 \
+84
View File
@@ -0,0 +1,84 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
*/
#include <linux/code_sign.h>
#include <linux/fsverity.h>
#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;
}
}
+19
View File
@@ -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 */
+5 -1
View File
@@ -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");
MODULE_LICENSE("GPL");