xref: /linux/tools/testing/selftests/sgx/test_encl.c (revision 20404a808593a6812cb485bec16256e702ff94c3)
12adcba79SJarkko Sakkinen // SPDX-License-Identifier: GPL-2.0
22adcba79SJarkko Sakkinen /*  Copyright(c) 2016-20 Intel Corporation. */
32adcba79SJarkko Sakkinen 
42adcba79SJarkko Sakkinen #include <stddef.h>
52adcba79SJarkko Sakkinen #include "defines.h"
62adcba79SJarkko Sakkinen 
7abc5cec4SReinette Chatre /*
8abc5cec4SReinette Chatre  * Data buffer spanning two pages that will be placed first in .data
9abc5cec4SReinette Chatre  * segment. Even if not used internally the second page is needed by
10abc5cec4SReinette Chatre  * external test manipulating page permissions.
11abc5cec4SReinette Chatre  */
1222118ce1SJarkko Sakkinen static uint8_t encl_buffer[8192] = { 1 };
1322118ce1SJarkko Sakkinen 
14*20404a80SReinette Chatre enum sgx_enclu_function {
15*20404a80SReinette Chatre 	EACCEPT = 0x5,
16*20404a80SReinette Chatre 	EMODPE = 0x6,
17*20404a80SReinette Chatre };
18*20404a80SReinette Chatre 
19*20404a80SReinette Chatre static void do_encl_emodpe(void *_op)
20*20404a80SReinette Chatre {
21*20404a80SReinette Chatre 	struct sgx_secinfo secinfo __aligned(sizeof(struct sgx_secinfo)) = {0};
22*20404a80SReinette Chatre 	struct encl_op_emodpe *op = _op;
23*20404a80SReinette Chatre 
24*20404a80SReinette Chatre 	secinfo.flags = op->flags;
25*20404a80SReinette Chatre 
26*20404a80SReinette Chatre 	asm volatile(".byte 0x0f, 0x01, 0xd7"
27*20404a80SReinette Chatre 				:
28*20404a80SReinette Chatre 				: "a" (EMODPE),
29*20404a80SReinette Chatre 				  "b" (&secinfo),
30*20404a80SReinette Chatre 				  "c" (op->epc_addr));
31*20404a80SReinette Chatre }
32*20404a80SReinette Chatre 
33*20404a80SReinette Chatre static void do_encl_eaccept(void *_op)
34*20404a80SReinette Chatre {
35*20404a80SReinette Chatre 	struct sgx_secinfo secinfo __aligned(sizeof(struct sgx_secinfo)) = {0};
36*20404a80SReinette Chatre 	struct encl_op_eaccept *op = _op;
37*20404a80SReinette Chatre 	int rax;
38*20404a80SReinette Chatre 
39*20404a80SReinette Chatre 	secinfo.flags = op->flags;
40*20404a80SReinette Chatre 
41*20404a80SReinette Chatre 	asm volatile(".byte 0x0f, 0x01, 0xd7"
42*20404a80SReinette Chatre 				: "=a" (rax)
43*20404a80SReinette Chatre 				: "a" (EACCEPT),
44*20404a80SReinette Chatre 				  "b" (&secinfo),
45*20404a80SReinette Chatre 				  "c" (op->epc_addr));
46*20404a80SReinette Chatre 
47*20404a80SReinette Chatre 	op->ret = rax;
48*20404a80SReinette Chatre }
49*20404a80SReinette Chatre 
502adcba79SJarkko Sakkinen static void *memcpy(void *dest, const void *src, size_t n)
512adcba79SJarkko Sakkinen {
522adcba79SJarkko Sakkinen 	size_t i;
532adcba79SJarkko Sakkinen 
542adcba79SJarkko Sakkinen 	for (i = 0; i < n; i++)
552adcba79SJarkko Sakkinen 		((char *)dest)[i] = ((char *)src)[i];
562adcba79SJarkko Sakkinen 
572adcba79SJarkko Sakkinen 	return dest;
582adcba79SJarkko Sakkinen }
592adcba79SJarkko Sakkinen 
60c085dfc7SReinette Chatre static void do_encl_op_put_to_buf(void *op)
6141493a09SJarkko Sakkinen {
62c085dfc7SReinette Chatre 	struct encl_op_put_to_buf *op2 = op;
6341493a09SJarkko Sakkinen 
6441493a09SJarkko Sakkinen 	memcpy(&encl_buffer[0], &op2->value, 8);
6541493a09SJarkko Sakkinen }
6641493a09SJarkko Sakkinen 
67c085dfc7SReinette Chatre static void do_encl_op_get_from_buf(void *op)
6841493a09SJarkko Sakkinen {
69c085dfc7SReinette Chatre 	struct encl_op_get_from_buf *op2 = op;
7041493a09SJarkko Sakkinen 
7141493a09SJarkko Sakkinen 	memcpy(&op2->value, &encl_buffer[0], 8);
7241493a09SJarkko Sakkinen }
7341493a09SJarkko Sakkinen 
74abc5cec4SReinette Chatre static void do_encl_op_put_to_addr(void *_op)
75abc5cec4SReinette Chatre {
76abc5cec4SReinette Chatre 	struct encl_op_put_to_addr *op = _op;
77abc5cec4SReinette Chatre 
78abc5cec4SReinette Chatre 	memcpy((void *)op->addr, &op->value, 8);
79abc5cec4SReinette Chatre }
80abc5cec4SReinette Chatre 
81abc5cec4SReinette Chatre static void do_encl_op_get_from_addr(void *_op)
82abc5cec4SReinette Chatre {
83abc5cec4SReinette Chatre 	struct encl_op_get_from_addr *op = _op;
84abc5cec4SReinette Chatre 
85abc5cec4SReinette Chatre 	memcpy(&op->value, (void *)op->addr, 8);
86abc5cec4SReinette Chatre }
87abc5cec4SReinette Chatre 
88688542e2SReinette Chatre static void do_encl_op_nop(void *_op)
89688542e2SReinette Chatre {
90688542e2SReinette Chatre 
91688542e2SReinette Chatre }
92688542e2SReinette Chatre 
932adcba79SJarkko Sakkinen void encl_body(void *rdi,  void *rsi)
942adcba79SJarkko Sakkinen {
9541493a09SJarkko Sakkinen 	const void (*encl_op_array[ENCL_OP_MAX])(void *) = {
96c085dfc7SReinette Chatre 		do_encl_op_put_to_buf,
97c085dfc7SReinette Chatre 		do_encl_op_get_from_buf,
98abc5cec4SReinette Chatre 		do_encl_op_put_to_addr,
99abc5cec4SReinette Chatre 		do_encl_op_get_from_addr,
100688542e2SReinette Chatre 		do_encl_op_nop,
101*20404a80SReinette Chatre 		do_encl_eaccept,
102*20404a80SReinette Chatre 		do_encl_emodpe,
10341493a09SJarkko Sakkinen 	};
10422118ce1SJarkko Sakkinen 
10541493a09SJarkko Sakkinen 	struct encl_op_header *op = (struct encl_op_header *)rdi;
10622118ce1SJarkko Sakkinen 
10741493a09SJarkko Sakkinen 	if (op->type < ENCL_OP_MAX)
10841493a09SJarkko Sakkinen 		(*encl_op_array[op->type])(op);
1092adcba79SJarkko Sakkinen }
110