1616 */
1717
1818#include "api.h"
19+ #include "hex.h"
1920#include "libos_fs_encrypted.h"
2021#include "libos_fs_pseudo.h"
2122#include "pal.h"
@@ -84,6 +85,21 @@ static int user_report_data_save(struct libos_dentry* dent, const char* data, si
8485 return 0 ;
8586}
8687
88+ #ifdef DEBUG
89+ static int cpu_svn_save (struct libos_dentry * dent , const char * data , size_t size ) {
90+ log_debug ("cpu_svn_save: saving %zu bytes" , size );
91+ __UNUSED (dent );
92+ cpu_svn_t cpu_svn ;
93+ if (size != sizeof (cpu_svn )) {
94+ log_warning ("CPU SVN must be exactly %zu bytes, got %zu" , sizeof (cpu_svn ), size );
95+ return - EINVAL ;
96+ }
97+ memcpy (& cpu_svn , data , sizeof (cpu_svn ));
98+
99+ return set_cpu_svn (& cpu_svn );
100+ }
101+ #endif /* DEBUG */
102+
87103/*!
88104 * \brief Modify target info used in `report` pseudo-file.
89105 *
@@ -239,6 +255,32 @@ static int quote_load(struct libos_dentry* dent, char** out_data, size_t* out_si
239255 return 0 ;
240256}
241257
258+ /*!
259+ * \brief Get CPU SVN of the platform.
260+ */
261+ static int cpu_svn_load (struct libos_dentry * dent , char * * out_data , size_t * out_size ) {
262+ __UNUSED (dent );
263+
264+ cpu_svn_t cpu_svn ;
265+ size_t cpu_svn_size = sizeof (cpu_svn );
266+ int ret = PalGetCPUSVN (& cpu_svn , & cpu_svn_size );
267+ if (ret < 0 ) {
268+ log_warning ("PalGetCPUSVN failed: %s" , pal_strerror (ret ));
269+ return pal_to_unix_errno (ret );
270+ }
271+
272+ char * str = calloc (1 , cpu_svn_size );
273+
274+ if (!str )
275+ return - ENOMEM ;
276+
277+ memcpy (str , & cpu_svn , sizeof (cpu_svn ));
278+
279+ * out_data = str ;
280+ * out_size = cpu_svn_size ;
281+ return 0 ;
282+ }
283+
242284/*!
243285 * \brief Get remote attestation type used.
244286 *
@@ -264,6 +306,22 @@ static bool key_name_exists(struct libos_dentry* parent, const char* name) {
264306 return key != NULL ;
265307}
266308
309+ static bool key_name_exists_svn (struct libos_dentry * parent , const char * name ) {
310+ __UNUSED (parent );
311+ if (strlen (name ) != 2 * sizeof (cpu_svn_t )) {
312+ log_warning ("key_name_exists_svn: invalid key name length %zu of %s, expected %zu" ,
313+ strlen (name ), name , 2 * sizeof (cpu_svn_t ));
314+ return false;
315+ }
316+ cpu_svn_t cpu_svn ;
317+ if (!hex2bytes ((char * )name , strlen (name ), & cpu_svn , sizeof (cpu_svn_t ))) {
318+ log_warning ("key_name_exists_svn: invalid key name format" );
319+ return false;
320+ }
321+
322+ return true;
323+ }
324+
267325struct key_list_names_data {
268326 readdir_callback_t callback ;
269327 void * arg ;
@@ -284,6 +342,13 @@ static int key_list_names(struct libos_dentry* parent, readdir_callback_t callba
284342 return list_encrypted_files_keys (& key_list_names_callback , & data );
285343}
286344
345+ static int key_list_names_svn (struct libos_dentry * parent , readdir_callback_t callback , void * arg ) {
346+ __UNUSED (parent );
347+ __UNUSED (callback );
348+ __UNUSED (arg );
349+ return 0 ;
350+ }
351+
287352static int key_load (struct libos_dentry * dent , char * * out_data , size_t * out_size ) {
288353 struct libos_encrypted_files_key * key = get_encrypted_files_key (dent -> name );
289354 if (!key )
@@ -307,6 +372,58 @@ static int key_load(struct libos_dentry* dent, char** out_data, size_t* out_size
307372 return 0 ;
308373}
309374
375+ static int key_load_svn (struct libos_dentry * dent , char * * out_data , size_t * out_size ) {
376+ if (strlen (dent -> name ) != 2 * sizeof (cpu_svn_t )) {
377+ log_warning ("key_name_exists_svn: invalid key name length" );
378+ return false;
379+ }
380+ cpu_svn_t cpu_svn ;
381+
382+ if (!hex2bytes ((char * )dent -> name , strlen (dent -> name ), & cpu_svn , sizeof (cpu_svn_t ))) {
383+ log_warning ("key_name_exists_svn: invalid key name format" );
384+ return false;
385+ }
386+
387+ int ret ;
388+
389+ char * key_name = dent -> parent -> name ;
390+ struct libos_encrypted_files_key * key = NULL ;
391+ key = calloc (1 , sizeof (* key ));
392+ if (!key ) {
393+ log_error ("Cannot allocate memory for key" );
394+ ret = - ENOMEM ;
395+ goto out ;
396+ }
397+ ret = create_encrypted_files_key_for_svn (key_name , & cpu_svn , & key );
398+ if (ret < 0 ) {
399+ log_error ("Cannot create or get key for SVN" );
400+ goto out ;
401+ }
402+ pf_key_t pf_key ;
403+ bool is_set = read_encrypted_files_key (key , & pf_key );
404+
405+ if (is_set ) {
406+ char * buf = malloc (sizeof (pf_key ));
407+ if (!buf )
408+ return - ENOMEM ;
409+ memcpy (buf , & pf_key , sizeof (pf_key ));
410+
411+ * out_data = buf ;
412+ * out_size = sizeof (pf_key );
413+ } else {
414+ * out_data = NULL ;
415+ * out_size = 0 ;
416+ }
417+ ret = 0 ;
418+ out :
419+ if (key ) {
420+ if (key -> name )
421+ free (key -> name );
422+ free (key );
423+ }
424+ return ret ;
425+ }
426+
310427static int key_save (struct libos_dentry * dent , const char * data , size_t size ) {
311428 struct libos_encrypted_files_key * key = get_encrypted_files_key (dent -> name );
312429 if (!key )
@@ -338,6 +455,13 @@ static int init_sgx_attestation(struct pseudo_node* attestation, struct pseudo_n
338455 pseudo_add_str (attestation , "attestation_type" , attestation_type_load );
339456 pseudo_add_str (attestation , "my_target_info" , & my_target_info_load );
340457 pseudo_add_str (attestation , "report" , & report_load );
458+ struct pseudo_node * cpu_svn = pseudo_add_str (attestation , "cpu_svn" , & cpu_svn_load );
459+ #ifdef DEBUG
460+ cpu_svn -> perm = PSEUDO_PERM_FILE_RW ;
461+ cpu_svn -> str .save = & cpu_svn_save ;
462+ #else
463+ cpu_svn -> perm = PSEUDO_PERM_FILE_R ;
464+ #endif /* DEBUG */
341465
342466 struct pseudo_node * user_report_data = pseudo_add_str (attestation , "user_report_data" , NULL );
343467 user_report_data -> perm = PSEUDO_PERM_FILE_RW ;
@@ -362,6 +486,13 @@ static int init_sgx_attestation(struct pseudo_node* attestation, struct pseudo_n
362486 pseudo_add_str (keys , PAL_KEY_NAME_SGX_MRENCLAVE , & key_load );
363487 pseudo_add_str (keys , PAL_KEY_NAME_SGX_MRSIGNER , & key_load );
364488
489+ struct pseudo_node * keys_svn = pseudo_add_dir (keys , "svn" );
490+ struct pseudo_node * keys_svn_mrenclave_key =
491+ pseudo_add_dir (keys_svn , PAL_KEY_NAME_SGX_MRENCLAVE );
492+ struct pseudo_node * key_cpu_svn = pseudo_add_str (keys_svn_mrenclave_key , NULL , & key_load_svn );
493+ key_cpu_svn -> name_exists = & key_name_exists_svn ;
494+ key_cpu_svn -> list_names = & key_list_names_svn ;
495+
365496 if (!strcmp (g_pal_public_state -> attestation_type , "none" )) {
366497 log_debug ("host is Linux-SGX and remote attestation type is 'none', skipping "
367498 "/dev/attestation/quote file" );
0 commit comments