mirror of
https://github.com/openharmony/kernel_linux_common_modules.git
synced 2026-08-26 17:16:37 -04:00
verify part data in file to support code signing
Change-Id: I06948b7bf8741449dfa1af1964d9170329d90b4b Signed-off-by: lihehe <lihehao@huawei.com>
This commit is contained in:
+5
-4
@@ -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
@@ -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 \
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user