On Sun, Apr 23, 2023 at 4:24 AM <thomas@xxxxxxxx> wrote: > > On 2023-04-20 11:54:51-0500, Jorge Lopez wrote: > > .../x86/hp/hp-bioscfg/spmobj-attributes.c | 405 ++++++++++++++++++ > > 1 file changed, 405 insertions(+) > > create mode 100644 drivers/platform/x86/hp/hp-bioscfg/spmobj-attributes.c > > > > diff --git a/drivers/platform/x86/hp/hp-bioscfg/spmobj-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/spmobj-attributes.c > > new file mode 100644 > > index 000000000000..78228f44c39b > > --- /dev/null > > +++ b/drivers/platform/x86/hp/hp-bioscfg/spmobj-attributes.c > > @@ -0,0 +1,405 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Functions corresponding to secure platform management object type > > + * attributes under BIOS PASSWORD for use with hp-bioscfg driver > > + * > > + * Copyright (c) 2022 HP Development Company, L.P. > > + */ > > + > > +#include "bioscfg.h" > > + > > + > > +static const char * const spm_state_types[] = { > > + "not provisioned", > > + "provisioned", > > + "provisioning in progress" > > +}; > > + > > +static const char * const spm_mechanism_types[] = { > > + "not provision", > > "not provisioned" as above? Good catch. Done! > > > + "signing-key", > > + "endorsement-key" > > Trailing commas please. > Done! > > +}; > > + > > + > > +int check_spm_is_enabled(void) > > +{ > > + /* do we need to check the admin password is also configured */ > > + return bioscfg_drv.spm_data.is_enabled; > > +} > > + > > +/* > > + * calculate_security_buffer() - determines size of security buffer > > + * for authentication scheme > > + * > > + * @authentication: the authentication content > > + * > > + * Currently only supported type is Admin password > > + */ > > +size_t calculate_security_buffer(const char *authentication) > > +{ > > + int size; > > + > > + if (authentication != NULL && strlen(authentication) > 0) { > > + > > + size = (sizeof(u16) + (strlen(authentication) * sizeof(u16))); > > + if (strncmp(authentication, BEAM_PREFIX, strlen(BEAM_PREFIX)) != 0) > > strstarts() Done! > > > + size += (strlen(UTF_PREFIX) * sizeof(u16)); > > No need for braces. Done! > > > + > > + return size; > > + } > > + > > + size = sizeof(u16) * 2; > > + return size; > > +} > > + > > +/* > > + * populate_security_buffer() - builds a security buffer for > > + * authentication scheme > > + * > > + * @buffer: the buffer to populate > > + * @authentication: the authentication content > > + * > > + * Currently only supported type is PLAIN TEXT > > + */ > > +void populate_security_buffer(u16 *buffer, const char *authentication) > > +{ > > + u16 *auth = buffer; > > + char *strprefix = NULL; > > + > > + if (strncmp(authentication, BEAM_PREFIX, strlen(BEAM_PREFIX)) == 0) { > > strstarts() Done! > > > + /* > > + * BEAM_PREFIX is append to buffer when a signature > > + * is provided and Sure Admin is enabled in BIOS > > + */ > > + // BEAM_PREFIX found, convert part to unicode > > + auth = ascii_to_utf16_unicode(auth, authentication); > > + } else { > > + /* > > + * UTF-16 prefix is append to the * buffer when a BIOS > > + * admin password is configured in BIOS > > + */ > > + > > + // append UTF_PREFIX to part and then convert it to unicode > > + strprefix = kasprintf(GFP_KERNEL, "%s%s", UTF_PREFIX, > > + authentication); > > + if (!strprefix) > > + goto out_buffer; > > + > > + auth = ascii_to_utf16_unicode(auth, strprefix); > > + } > > +out_buffer: > > + > > + kfree(strprefix); > > +} > > + > > +ssize_t update_spm_state(void) > > +{ > > + int ret; > > + struct secureplatform_provisioning_data *data = NULL; > > This can be allocated on the stack. Done! > > > + > > + data = kmalloc(sizeof(struct secureplatform_provisioning_data), > > + GFP_KERNEL); > > + if (!data) { > > + ret = -ENOMEM; > > + goto state_exit; > > + } > > + > > + ret = hp_wmi_perform_query(HPWMI_SECUREPLATFORM_GET_STATE, > > + HPWMI_SECUREPLATFORM, data, 0, > > + sizeof(*data)); > > + if (ret < 0) > > + goto state_exit; > > + > > + bioscfg_drv.spm_data.mechanism = data->state; > > + if (bioscfg_drv.spm_data.mechanism) > > + bioscfg_drv.spm_data.is_enabled = 1; > > + > > +state_exit: > > + kfree(data); > > + > > + return ret; > > +} > > + > > +ssize_t statusbin(struct kobject *kobj, > > + struct kobj_attribute *attr, char *buf) > > This can be static. Done! > > If it is known that a struct secureplatform_provisioning_data is to be > passed, then the type can reflect that. Done! > > > +{ > > + int ret = hp_wmi_perform_query(HPWMI_SECUREPLATFORM_GET_STATE, > > + HPWMI_SECUREPLATFORM, buf, 0, > > + sizeof(struct secureplatform_provisioning_data)); > > + > > + return ret ? -ENODEV : sizeof(struct secureplatform_provisioning_data); > > Why not return "ret" on error? Good point. Done! > > > +} > > + > > +/* > > + * status_show - Reads SPM status > > + */ > > +ssize_t status_show(struct kobject *kobj, struct kobj_attribute > > + *attr, char *buf) > > +{ > > + int ret, i; > > + struct secureplatform_provisioning_data *data = NULL; > > Can also be on-stack. Done! > <snip> > > +static struct kobj_attribute password_spm_key_mechanism = __ATTR_RO(key_mechanism); > > + > > +static ssize_t sk_store(struct kobject *kobj, > > + struct kobj_attribute *attr, > > + const char *buf, size_t count) > > +{ > > + int ret; > > + int length; > > + > > + length = count; > > + if (buf[length-1] == '\n') > > + length--; > > + > > + /* allocate space and copy current signing key */ > > + bioscfg_drv.spm_data.signing_key = kmalloc(length, GFP_KERNEL); > > + if (!bioscfg_drv.spm_data.signing_key) { > > + ret = -ENOMEM; > > + goto exit_sk; > > + } > > + > > + memcpy(bioscfg_drv.spm_data.signing_key, buf, length); > > + bioscfg_drv.spm_data.signing_key[length] = '\0'; > > Is this supposed to handle zero-bytes in the input? > If yes: Did you test this with zero bytes, I don't think the normal > attribute APIs handle this. > If no: Why not use strscpy? > Done! <snip>