1 /*
2  * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef SMM_VARIABLE_CLIENT_H
8 #define SMM_VARIABLE_CLIENT_H
9 
10 #include <cstdint>
11 #include <protocols/common/efi/efi_status.h>
12 #include <protocols/service/smm_variable/smm_variable_proto.h>
13 #include <string>
14 #include <vector>
15 #include <uchar.h>
16 
17 #include "components/rpc/common/caller/rpc_caller_session.h"
18 
19 /*
20  * Provides a C++ client interface for accessing an instance of the smm-variable service.
21  * This client is intended for testing the UEFI variable store provided by the smm-variable
22  * service.
23  */
24 class smm_variable_client {
25 public:
26 	smm_variable_client();
27 	smm_variable_client(struct rpc_caller_session *session);
28 	~smm_variable_client();
29 
30 	void set_caller_session(struct rpc_caller_session *session);
31 	int err_rpc_status() const;
32 
33 	/* Set variable with C string name. */
34 	efi_status_t set_variable(const EFI_GUID &guid, const char16_t *name,
35 					       const std::string data, uint32_t attributes);
36 
37 	efi_status_t set_variable(const EFI_GUID &guid, const char16_t *name,
38 					       const unsigned char* data, size_t data_length,
39 					       uint32_t attributes);
40 
41 	/* Set character array variable */
42 	efi_status_t set_variable(const EFI_GUID &guid, const std::u16string &name,
43 				  const unsigned char *data, size_t data_length,
44 				  uint32_t attributes);
45 
46 	/* Set a string type variable */
47 	efi_status_t set_variable(const EFI_GUID &guid, const std::u16string &name,
48 				  const std::string &data, uint32_t attributes);
49 
50 	efi_status_t set_variable(const EFI_GUID &guid, const std::u16string &name,
51 				  const std::string &data, uint32_t attributes,
52 				  size_t override_name_size, size_t override_data_size);
53 
54 	/* Get a string type variable */
55 	efi_status_t get_variable(const EFI_GUID &guid, const char16_t *name, std::string &data);
56 	efi_status_t get_variable(const EFI_GUID &guid, const char16_t *name, std::string &data,
57 				  size_t override_name_size, size_t max_data_size);
58 
59 	efi_status_t get_variable(const EFI_GUID &guid, const std::u16string &name,
60 				  std::string &data);
61 
62 	efi_status_t get_variable(const EFI_GUID &guid, const std::u16string &name, std::string &data,
63 				  size_t override_name_size,
64 				  size_t max_data_size = MAX_VAR_DATA_SIZE);
65 
66 	/* Remove a variable */
67 	efi_status_t remove_variable(const EFI_GUID &guid, const char16_t *name);
68 	efi_status_t remove_variable(const EFI_GUID &guid, const std::u16string &name);
69 
70 	/* Query variable info */
71 	efi_status_t query_variable_info(uint32_t attributes, size_t *max_variable_storage_size,
72 					 size_t *remaining_variable_storage_size,
73 					 size_t *max_variable_size);
74 
75 	/* Get the next variable name - for enumerating store contents */
76 	efi_status_t get_next_variable_name(EFI_GUID &guid, std::u16string &name);
77 
78 	efi_status_t get_next_variable_name(EFI_GUID &guid, std::u16string &name,
79 					    size_t override_name_size);
80 
81 	/* Exit boot service */
82 	efi_status_t exit_boot_service();
83 
84 	/* Set variable check properties */
85 	efi_status_t set_var_check_property(const EFI_GUID &guid, const char16_t *name,
86 					    const VAR_CHECK_VARIABLE_PROPERTY &check_property);
87 
88 	efi_status_t set_var_check_property(const EFI_GUID &guid, const char16_t *name,
89 					    const VAR_CHECK_VARIABLE_PROPERTY &check_property,
90 					    size_t override_name_size);
91 
92 	efi_status_t set_var_check_property(const EFI_GUID &guid, const std::u16string &name,
93 					    const VAR_CHECK_VARIABLE_PROPERTY &check_property);
94 
95 	efi_status_t set_var_check_property(const EFI_GUID &guid, const std::u16string &name,
96 					    const VAR_CHECK_VARIABLE_PROPERTY &check_property,
97 					    size_t override_name_size);
98 
99 	/* Get variable check properties */
100 	efi_status_t get_var_check_property(const EFI_GUID &guid, const char16_t *name,
101 					    VAR_CHECK_VARIABLE_PROPERTY &check_property);
102 
103 	efi_status_t get_var_check_property(const EFI_GUID &guid, const char16_t *name,
104 					    VAR_CHECK_VARIABLE_PROPERTY &check_property,
105 					    size_t override_name_size);
106 
107 	efi_status_t get_var_check_property(const EFI_GUID &guid, const std::u16string &name,
108 					    VAR_CHECK_VARIABLE_PROPERTY &check_property);
109 
110 	efi_status_t get_var_check_property(const EFI_GUID &guid, const std::u16string &name,
111 					    VAR_CHECK_VARIABLE_PROPERTY &check_property,
112 					    size_t override_name_size);
113 
114 	/* Get maximum variable payload size */
115 	efi_status_t get_payload_size(size_t &payload_size);
116 
117 private:
118 	/* Datasize limit set by UEFI specification */
119 	static const size_t MAX_VAR_DATA_SIZE = 65536;
120 
121 	efi_status_t rpc_to_efi_status() const;
122 
123 	std::u16string to_variable_name(const char16_t *name) const;
124 	void from_variable_name(const int16_t *name, size_t name_size, std::u16string &result);
125 
126 	struct rpc_caller_session *session;
127 	int m_err_rpc_status;
128 };
129 
130 #endif /* SMM_VARIABLE_CLIENT_H */
131