2020-11-13 00:01:31 +02:00
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2016-20 Intel Corporation. */
# include <stddef.h>
# include "defines.h"
2021-11-15 10:35:24 -08:00
/*
* Data buffer spanning two pages that will be placed first in . data
* segment . Even if not used internally the second page is needed by
* external test manipulating page permissions .
*/
2021-06-10 11:30:21 +03:00
static uint8_t encl_buffer [ 8192 ] = { 1 } ;
2022-05-10 11:08:58 -07:00
enum sgx_enclu_function {
EACCEPT = 0x5 ,
EMODPE = 0x6 ,
} ;
static void do_encl_emodpe ( void * _op )
{
struct sgx_secinfo secinfo __aligned ( sizeof ( struct sgx_secinfo ) ) = { 0 } ;
struct encl_op_emodpe * op = _op ;
secinfo . flags = op - > flags ;
asm volatile ( " .byte 0x0f, 0x01, 0xd7 "
:
: " a " ( EMODPE ) ,
" b " ( & secinfo ) ,
" c " ( op - > epc_addr ) ) ;
}
static void do_encl_eaccept ( void * _op )
{
struct sgx_secinfo secinfo __aligned ( sizeof ( struct sgx_secinfo ) ) = { 0 } ;
struct encl_op_eaccept * op = _op ;
int rax ;
secinfo . flags = op - > flags ;
asm volatile ( " .byte 0x0f, 0x01, 0xd7 "
: " =a " ( rax )
: " a " ( EACCEPT ) ,
" b " ( & secinfo ) ,
" c " ( op - > epc_addr ) ) ;
op - > ret = rax ;
}
2020-11-13 00:01:31 +02:00
static void * memcpy ( void * dest , const void * src , size_t n )
{
size_t i ;
for ( i = 0 ; i < n ; i + + )
( ( char * ) dest ) [ i ] = ( ( char * ) src ) [ i ] ;
return dest ;
}
2022-05-10 11:09:02 -07:00
static void * memset ( void * dest , int c , size_t n )
{
size_t i ;
for ( i = 0 ; i < n ; i + + )
( ( char * ) dest ) [ i ] = c ;
return dest ;
}
static void do_encl_init_tcs_page ( void * _op )
{
struct encl_op_init_tcs_page * op = _op ;
void * tcs = ( void * ) op - > tcs_page ;
uint32_t val_32 ;
memset ( tcs , 0 , 16 ) ; /* STATE and FLAGS */
memcpy ( tcs + 16 , & op - > ssa , 8 ) ; /* OSSA */
memset ( tcs + 24 , 0 , 4 ) ; /* CSSA */
val_32 = 1 ;
memcpy ( tcs + 28 , & val_32 , 4 ) ; /* NSSA */
memcpy ( tcs + 32 , & op - > entry , 8 ) ; /* OENTRY */
memset ( tcs + 40 , 0 , 24 ) ; /* AEP, OFSBASE, OGSBASE */
val_32 = 0xFFFFFFFF ;
memcpy ( tcs + 64 , & val_32 , 4 ) ; /* FSLIMIT */
memcpy ( tcs + 68 , & val_32 , 4 ) ; /* GSLIMIT */
memset ( tcs + 72 , 0 , 4024 ) ; /* Reserved */
}
2021-11-15 10:35:23 -08:00
static void do_encl_op_put_to_buf ( void * op )
2021-11-15 10:35:22 -08:00
{
2021-11-15 10:35:23 -08:00
struct encl_op_put_to_buf * op2 = op ;
2021-11-15 10:35:22 -08:00
memcpy ( & encl_buffer [ 0 ] , & op2 - > value , 8 ) ;
}
2021-11-15 10:35:23 -08:00
static void do_encl_op_get_from_buf ( void * op )
2020-11-13 00:01:31 +02:00
{
2021-11-15 10:35:23 -08:00
struct encl_op_get_from_buf * op2 = op ;
2021-06-10 11:30:21 +03:00
2021-11-15 10:35:22 -08:00
memcpy ( & op2 - > value , & encl_buffer [ 0 ] , 8 ) ;
}
2021-11-15 10:35:24 -08:00
static void do_encl_op_put_to_addr ( void * _op )
{
struct encl_op_put_to_addr * op = _op ;
memcpy ( ( void * ) op - > addr , & op - > value , 8 ) ;
}
static void do_encl_op_get_from_addr ( void * _op )
{
struct encl_op_get_from_addr * op = _op ;
memcpy ( & op - > value , ( void * ) op - > addr , 8 ) ;
}
2021-11-15 10:35:26 -08:00
static void do_encl_op_nop ( void * _op )
{
}
2021-11-15 10:35:22 -08:00
void encl_body ( void * rdi , void * rsi )
{
const void ( * encl_op_array [ ENCL_OP_MAX ] ) ( void * ) = {
2021-11-15 10:35:23 -08:00
do_encl_op_put_to_buf ,
do_encl_op_get_from_buf ,
2021-11-15 10:35:24 -08:00
do_encl_op_put_to_addr ,
do_encl_op_get_from_addr ,
2021-11-15 10:35:26 -08:00
do_encl_op_nop ,
2022-05-10 11:08:58 -07:00
do_encl_eaccept ,
do_encl_emodpe ,
2022-05-10 11:09:02 -07:00
do_encl_init_tcs_page ,
2021-11-15 10:35:22 -08:00
} ;
2021-06-10 11:30:21 +03:00
2021-11-15 10:35:22 -08:00
struct encl_op_header * op = ( struct encl_op_header * ) rdi ;
2021-06-10 11:30:21 +03:00
2021-11-15 10:35:22 -08:00
if ( op - > type < ENCL_OP_MAX )
( * encl_op_array [ op - > type ] ) ( op ) ;
2020-11-13 00:01:31 +02:00
}