Unverified Commit eccf28ee authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!10942 add support for arm virtcca attestation

Merge Pull Request from: @chenzheng5555 
 
 
 
Link:https://gitee.com/openeuler/kernel/pulls/10942

 

Reviewed-by: default avatarZhang Jianhua <chris.zjh@huawei.com>
Signed-off-by: default avatarZhang Peng <zhangpeng362@huawei.com>
parents b7906ac1 721f4ea8
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@ extern bool is_virtcca_cvm_world(void);

extern void __init swiotlb_cvm_update_mem_attributes(void);

extern void virtcca_cvm_tsi_init(void);

#else

static inline int set_cvm_memory_encrypted(unsigned long addr, int numpages)
@@ -35,5 +37,7 @@ static inline bool is_virtcca_cvm_world(void)

static inline void __init swiotlb_cvm_update_mem_attributes(void) {}

static inline void virtcca_cvm_tsi_init(void) {}

#endif /* CONFIG_HISI_VIRTCCA_GUEST */
#endif /* __VIRTCCA_CVM_GUEST_H */
+168 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __ASM_VIRTCCA_CVM_SMC_H_
#define __ASM_VIRTCCA_CVM_SMC_H_

#ifdef CONFIG_HISI_VIRTCCA_GUEST

#include <linux/arm-smccc.h>
#include <asm/virtcca_cvm_tsi.h>
#include <linux/slab.h>

#define SMC_TSI_CALL_BASE           0xC4000000
#define TSI_ABI_VERSION_MAJOR       1
#define TSI_ABI_VERSION_MINOR       0
#define TSI_ABI_VERSION             ((TSI_ABI_VERSION_MAJOR << 16) | TSI_ABI_VERSION_MINOR)

#define TSI_ABI_VERSION_GET_MAJOR(_version) ((_version) >> 16)
#define TSI_ABI_VERSION_GET_MINOR(_version) ((_version) & 0xFFFF)

#define TSI_SUCCESS             0
#define TSI_ERROR_INPUT         1
#define TSI_ERROR_STATE         2
#define TSI_INCOMPLETE          3

#define SMC_TSI_FID(_x)                        (SMC_TSI_CALL_BASE + (_x))
#define SMC_TSI_ABI_VERSION                    SMC_TSI_FID(0x190)

/*
 * arg1: Index, which measurements slot to read
 * arg2: Measurement value
 * ret0: Status / error
 */
#define SMC_TSI_MEASUREMENT_READ            SMC_TSI_FID(0x192)

/*
 * arg1: Index, which measurements slot to extend
 * arg2: Size of realm measurement in bytes, max 64 bytes
 * arg3: Measurement value
 * ret0: Status / error
 */
#define SMC_TSI_MEASUREMENT_EXTEND          SMC_TSI_FID(0x193)

/*
 * arg1: Challenge value
 * ret0: Status / error
 * ret1: Upper bound on attestation token size in bytes
 */
#define SMC_TSI_ATTESTATION_TOKEN_INIT      SMC_TSI_FID(0x194)

/*
 * arg1: IPA of the Granule to which the token will be written
 * arg2: Offset within Granule to start of buffer in bytes
 * arg3: Size of buffer in bytes
 * ret0: Status / error
 * ret1: Number of bytes written to buffer
 */
#define SMC_TSI_ATTESTATION_TOKEN_CONTINUE  SMC_TSI_FID(0x195)

/*
 * arg1: struct cVM config addr
 * ret0: Status / error
 */
#define SMC_TSI_CVM_CONFIG				    SMC_TSI_FID(0x196)

/*
 * arg1: Device cert buffer
 * arg2: Size of buffer in bytes
 * ret0: Status / error
 */
#define SMC_TSI_DEVICE_CERT                 SMC_TSI_FID(0x19A)

static inline unsigned long tsi_get_version(void)
{
	struct arm_smccc_res res;

	arm_smccc_1_1_smc(SMC_TSI_ABI_VERSION, &res);

	return res.a0;
}

static inline unsigned long tsi_get_cvm_config(struct virtcca_cvm_config *cfg)
{
	struct arm_smccc_res res;

	arm_smccc_1_1_smc(SMC_TSI_CVM_CONFIG, &res);

	cfg->ipa_bits = res.a1;
	cfg->algorithm = res.a2;

	return res.a0;
}

static inline unsigned long tsi_measurement_extend(struct virtcca_cvm_measurement_extend *cvm_meas_ext)
{

	struct arm_smccc_res res;
	unsigned char *value;

	value = kmalloc(MAX_MEASUREMENT_SIZE, GFP_KERNEL);
	if (!value)
		return -ENOMEM;
	memcpy(value, cvm_meas_ext->value, MAX_MEASUREMENT_SIZE);

	arm_smccc_1_1_smc(SMC_TSI_MEASUREMENT_EXTEND, cvm_meas_ext->index,
		cvm_meas_ext->size, virt_to_phys(value), &res);
	kfree(value);

	return res.a0;
}

static inline unsigned long tsi_measurement_read(struct virtcca_cvm_measurement *cvm_meas)
{
	struct arm_smccc_res res;
	unsigned char *value;

	value = kmalloc(MAX_MEASUREMENT_SIZE, GFP_KERNEL);
	if (!value)
		return -ENOMEM;
	arm_smccc_1_1_smc(SMC_TSI_MEASUREMENT_READ, cvm_meas->index,
		virt_to_phys(value), &res);

	memcpy(cvm_meas->value, value, MAX_MEASUREMENT_SIZE);
	kfree(value);

	return res.a0;
}

static inline unsigned long tsi_attestation_token_init(unsigned char *challenge)
{
	struct arm_smccc_res res;
	unsigned char *buf;

	buf = kmalloc(CHALLENGE_SIZE, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;
	memcpy(buf, challenge, CHALLENGE_SIZE);

	arm_smccc_1_1_smc(SMC_TSI_ATTESTATION_TOKEN_INIT, virt_to_phys(buf), &res);
	kfree(buf);

	return res.a0;
}

static inline unsigned long tsi_attestation_token_continue(struct virtcca_cvm_token_granule *token_granule)
{
	struct arm_smccc_res res;

	arm_smccc_1_1_smc(SMC_TSI_ATTESTATION_TOKEN_CONTINUE, virt_to_phys(token_granule->ipa),
		token_granule->offset, token_granule->size, &res);

	token_granule->num_wr_bytes = res.a1;

	return res.a0;
}

static inline unsigned long tsi_get_device_cert(unsigned char *device_cert,
	unsigned long *device_cert_size)
{
	struct arm_smccc_res res;

	arm_smccc_1_1_smc(SMC_TSI_DEVICE_CERT, virt_to_phys(device_cert), *device_cert_size, &res);

	*device_cert_size = res.a1;

	return res.a0;
}

#endif /* CONFIG_HISI_VIRTCCA_GUEST */
#endif  /* __ASM_VIRTCCA_CVM_SMC_H_ */
+79 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef __ASM_VIRTCCA_CVM_TSI_H_
#define __ASM_VIRTCCA_CVM_TSI_H_

#include <linux/ioctl.h>

#define TSI_MAGIC 'T'

/* Measurement slot reserved for RIM */
#define RIM_MEASUREMENT_SLOT       (0U)

/* Maximum number of measurements */
#define MEASUREMENT_SLOT_NR        (5U)

/* Size in bytes of the SHA256 measurement */
#define SHA256_SIZE                (32U)

/* Size in bytes of the SHA512 measurement */
#define SHA512_SIZE                (64U)

/*
 * Size in bytes of the largest measurement type that can be supported.
 * This macro needs to be updated accordingly if new algorithms are supported.
 */
#define MAX_MEASUREMENT_SIZE       SHA512_SIZE
#define MAX_DEV_CERT_SIZE          (4096U)

#define GRANULE_SIZE               (4096U)
#define MAX_TOKEN_GRANULE_COUNT    (2U)
#define CHALLENGE_SIZE             (64U)

struct virtcca_cvm_measurement {
	int index;
	unsigned char value[MAX_MEASUREMENT_SIZE];
};

struct virtcca_cvm_tsi_version {
	int major;
	int minor;
};

struct virtcca_cvm_config {
	unsigned long ipa_bits; /* Width of IPA in bits */
	unsigned long algorithm;	/* Hash algorithm */
};

struct virtcca_cvm_measurement_extend {
	unsigned long index;
	unsigned long size;
	unsigned char value[MAX_MEASUREMENT_SIZE];
};

struct virtcca_cvm_attestation_cmd {
	unsigned char challenge[CHALLENGE_SIZE]; /* input: challenge value */
	unsigned char token[GRANULE_SIZE * MAX_TOKEN_GRANULE_COUNT];
	unsigned long token_size; /* return: token size */
};

struct virtcca_cvm_token_granule {
	void *head;
	void *ipa;  /* IPA of the Granule to which the token will be written */
	unsigned long count;
	unsigned long offset; /* Offset within Granule to start of buffer in bytes */
	unsigned long size;  /* Size of buffer in bytes */
	unsigned long num_wr_bytes; /* Number of bytes written to buffer */
};

struct virtcca_device_cert {
	unsigned long size;
	unsigned char value[MAX_DEV_CERT_SIZE];
};

#define TMM_GET_TSI_VERSION _IOR(TSI_MAGIC, 0, struct virtcca_cvm_tsi_version)

#define TMM_GET_ATTESTATION_TOKEN _IOWR(TSI_MAGIC, 1, struct virtcca_cvm_attestation_cmd)

#define TMM_GET_DEVICE_CERT _IOR(TSI_MAGIC, 2, struct virtcca_device_cert)

#endif  /* __ASM_VIRTCCA_CVM_TSI_H_ */
+1 −1
Original line number Diff line number Diff line
@@ -81,7 +81,7 @@ obj-$(CONFIG_COMPAT_VDSO) += vdso32-wrap.o
obj-$(CONFIG_ARM64_ILP32)		+= vdso-ilp32/
obj-$(CONFIG_UNWIND_PATCH_PAC_INTO_SCS)	+= patch-scs.o
obj-$(CONFIG_IPI_AS_NMI)		+= ipi_nmi.o
obj-$(CONFIG_HISI_VIRTCCA_GUEST)	+= virtcca_cvm_guest.o
obj-$(CONFIG_HISI_VIRTCCA_GUEST)	+= virtcca_cvm_guest.o virtcca_cvm_tsi.o
CFLAGS_patch-scs.o			+= -mbranch-protection=none

# Force dependency (vdso*-wrap.S includes vdso.so through incbin)
+4 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@
#include <asm/kasan.h>
#include <asm/numa.h>
#include <asm/scs.h>
#include <asm/virtcca_cvm_guest.h>
#include <asm/sections.h>
#include <asm/setup.h>
#include <asm/smp_plat.h>
@@ -362,6 +363,9 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
	jump_label_init();
	parse_early_param();

	/* Init TSI after jump_labels are active */
	virtcca_cvm_tsi_init();

	dynamic_scs_init();

	/*
Loading