@@ -59,7 +59,14 @@ static u32 get_policy(const char *name)
5959 return PLPKS_SIGNEDUPDATE ;
6060}
6161
62- static const char * const plpks_var_names [] = {
62+ static const char * const plpks_var_names_static [] = {
63+ "PK" ,
64+ "moduledb" ,
65+ "trustedcadb" ,
66+ NULL ,
67+ };
68+
69+ static const char * const plpks_var_names_dynamic [] = {
6370 "PK" ,
6471 "KEK" ,
6572 "db" ,
@@ -152,39 +159,55 @@ static int plpks_set_variable(const char *key, u64 key_len, u8 *data,
152159 return rc ;
153160}
154161
155- // PLPKS dynamic secure boot doesn't give us a format string in the same way OPAL does.
156- // Instead, report the format using the SB_VERSION variable in the keystore.
157- // The string is made up by us, and takes the form "ibm,plpks-sb-v<n>" (or "ibm,plpks-sb-unknown"
158- // if the SB_VERSION variable doesn't exist). Hypervisor defines the SB_VERSION variable as a
159- // "1 byte unsigned integer value".
160- static ssize_t plpks_secvar_format (char * buf , size_t bufsize )
162+ /*
163+ * Return the key management mode.
164+ *
165+ * SB_VERSION is defined as a "1 byte unsigned integer value", taking values
166+ * starting from 1. It is owned by the Partition Firmware and its presence
167+ * indicates that the key management mode is dynamic. Any failure in
168+ * reading SB_VERSION defaults the key management mode to static. The error
169+ * codes -ENOENT or -EPERM are expected in static key management mode. An
170+ * unexpected error code will have to be investigated. Only signed variables
171+ * have null bytes in their names, SB_VERSION does not.
172+ *
173+ * Return 0 to indicate that the key management mode is static. Otherwise
174+ * return the SB_VERSION value to indicate that the key management mode is
175+ * dynamic.
176+ */
177+ static u8 plpks_get_sb_keymgmt_mode (void )
161178{
162- struct plpks_var var = {0 };
163- ssize_t ret ;
164- u8 version ;
165-
166- var .component = NULL ;
167- // Only the signed variables have null bytes in their names, this one doesn't
168- var .name = "SB_VERSION" ;
169- var .namelen = strlen (var .name );
170- var .datalen = 1 ;
171- var .data = & version ;
172-
173- // Unlike the other vars, SB_VERSION is owned by firmware instead of the OS
174- ret = plpks_read_fw_var (& var );
175- if (ret ) {
176- if (ret == - ENOENT ) {
177- ret = snprintf (buf , bufsize , "ibm,plpks-sb-unknown" );
178- } else {
179- pr_err ("Error %ld reading SB_VERSION from firmware\n" , ret );
180- ret = - EIO ;
181- }
182- goto err ;
179+ u8 mode ;
180+ ssize_t rc ;
181+ struct plpks_var var = {
182+ .component = NULL ,
183+ .name = "SB_VERSION" ,
184+ .namelen = 10 ,
185+ .datalen = 1 ,
186+ .data = & mode ,
187+ };
188+
189+ rc = plpks_read_fw_var (& var );
190+ if (rc ) {
191+ if (rc != - ENOENT && rc != - EPERM )
192+ pr_info ("Error %ld reading SB_VERSION from firmware\n" , rc );
193+ mode = 0 ;
183194 }
195+ return mode ;
196+ }
184197
185- ret = snprintf (buf , bufsize , "ibm,plpks-sb-v%hhu" , version );
186- err :
187- return ret ;
198+ /*
199+ * PLPKS dynamic secure boot doesn't give us a format string in the same way
200+ * OPAL does. Instead, report the format using the SB_VERSION variable in the
201+ * keystore. The string, made up by us, takes the form of either
202+ * "ibm,plpks-sb-v<n>" or "ibm,plpks-sb-v0", based on the key management mode,
203+ * and return the length of the secvar format property.
204+ */
205+ static ssize_t plpks_secvar_format (char * buf , size_t bufsize )
206+ {
207+ u8 mode ;
208+
209+ mode = plpks_get_sb_keymgmt_mode ();
210+ return snprintf (buf , bufsize , "ibm,plpks-sb-v%hhu" , mode );
188211}
189212
190213static int plpks_max_size (u64 * max_size )
@@ -197,21 +220,34 @@ static int plpks_max_size(u64 *max_size)
197220 return 0 ;
198221}
199222
223+ static const struct secvar_operations plpks_secvar_ops_static = {
224+ .get = plpks_get_variable ,
225+ .set = plpks_set_variable ,
226+ .format = plpks_secvar_format ,
227+ .max_size = plpks_max_size ,
228+ .config_attrs = config_attrs ,
229+ .var_names = plpks_var_names_static ,
230+ };
200231
201- static const struct secvar_operations plpks_secvar_ops = {
232+ static const struct secvar_operations plpks_secvar_ops_dynamic = {
202233 .get = plpks_get_variable ,
203234 .set = plpks_set_variable ,
204235 .format = plpks_secvar_format ,
205236 .max_size = plpks_max_size ,
206237 .config_attrs = config_attrs ,
207- .var_names = plpks_var_names ,
238+ .var_names = plpks_var_names_dynamic ,
208239};
209240
210241static int plpks_secvar_init (void )
211242{
243+ u8 mode ;
244+
212245 if (!plpks_is_available ())
213246 return - ENODEV ;
214247
215- return set_secvar_ops (& plpks_secvar_ops );
248+ mode = plpks_get_sb_keymgmt_mode ();
249+ if (mode )
250+ return set_secvar_ops (& plpks_secvar_ops_dynamic );
251+ return set_secvar_ops (& plpks_secvar_ops_static );
216252}
217253machine_device_initcall (pseries , plpks_secvar_init );
0 commit comments