1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Functions corresponding to password object type attributes under
4 * BIOS PASSWORD for use with hp-bioscfg driver.
5 *
6 * Copyright (c) 2022 HP Development Company, L.P.
7 */
8
9#include "bioscfg.h"
10#include <asm-generic/posix_types.h>
11
12GET_INSTANCE_ID(password);
13/*
14 * Clear all passwords copied to memory for a particular
15 * authentication instance
16 */
17static int clear_passwords(const int instance)
18{
19	struct password_data *password_data = &bioscfg_drv.password_data[instance];
20
21	if (!password_data->is_enabled)
22		return 0;
23
24	memset(password_data->current_password,
25	       0, sizeof(password_data->current_password));
26	memset(password_data->new_password,
27	       0, sizeof(password_data->new_password));
28
29	return 0;
30}
31
32/*
33 * Clear all credentials copied to memory for both Power-ON and Setup
34 * BIOS instances
35 */
36int hp_clear_all_credentials(void)
37{
38	int count = bioscfg_drv.password_instances_count;
39	int instance;
40
41	/* clear all passwords */
42	for (instance = 0; instance < count; instance++)
43		clear_passwords(instance);
44
45	/* clear auth_token */
46	kfree(bioscfg_drv.spm_data.auth_token);
47	bioscfg_drv.spm_data.auth_token = NULL;
48
49	return 0;
50}
51
52int hp_get_password_instance_for_type(const char *name)
53{
54	int count = bioscfg_drv.password_instances_count;
55	int instance;
56
57	for (instance = 0; instance < count; instance++)
58		if (!strcmp(bioscfg_drv.password_data[instance].common.display_name, name))
59			return instance;
60
61	return -EINVAL;
62}
63
64static int validate_password_input(int instance_id, const char *buf)
65{
66	int length;
67	struct password_data *password_data = &bioscfg_drv.password_data[instance_id];
68
69	length = strlen(buf);
70	if (buf[length - 1] == '\n')
71		length--;
72
73	if (length > MAX_PASSWD_SIZE)
74		return INVALID_BIOS_AUTH;
75
76	if (password_data->min_password_length > length ||
77	    password_data->max_password_length < length)
78		return INVALID_BIOS_AUTH;
79	return SUCCESS;
80}
81
82ATTRIBUTE_N_PROPERTY_SHOW(is_enabled, password);
83static struct kobj_attribute password_is_password_set = __ATTR_RO(is_enabled);
84
85static int store_password_instance(struct kobject *kobj, const char *buf,
86				   size_t count, bool is_current)
87{
88	char *buf_cp;
89	int id, ret = 0;
90
91	buf_cp = kstrdup(buf, GFP_KERNEL);
92	if (!buf_cp)
93		return -ENOMEM;
94
95	ret = hp_enforce_single_line_input(buf_cp, count);
96	if (!ret) {
97		id = get_password_instance_id(kobj);
98
99		if (id >= 0)
100			ret = validate_password_input(id, buf_cp);
101	}
102
103	if (!ret) {
104		if (is_current)
105			strscpy(bioscfg_drv.password_data[id].current_password,
106				buf_cp,
107				sizeof(bioscfg_drv.password_data[id].current_password));
108		else
109			strscpy(bioscfg_drv.password_data[id].new_password,
110				buf_cp,
111				sizeof(bioscfg_drv.password_data[id].new_password));
112	}
113
114	kfree(buf_cp);
115	return ret < 0 ? ret : count;
116}
117
118static ssize_t current_password_store(struct kobject *kobj,
119				      struct kobj_attribute *attr,
120				      const char *buf, size_t count)
121{
122	return store_password_instance(kobj, buf, count, true);
123}
124
125static struct kobj_attribute password_current_password = __ATTR_WO(current_password);
126
127static ssize_t new_password_store(struct kobject *kobj,
128				  struct kobj_attribute *attr,
129				  const char *buf, size_t count)
130{
131	return store_password_instance(kobj, buf, count, true);
132}
133
134static struct kobj_attribute password_new_password = __ATTR_WO(new_password);
135
136ATTRIBUTE_N_PROPERTY_SHOW(min_password_length, password);
137static struct kobj_attribute password_min_password_length = __ATTR_RO(min_password_length);
138
139ATTRIBUTE_N_PROPERTY_SHOW(max_password_length, password);
140static struct kobj_attribute password_max_password_length = __ATTR_RO(max_password_length);
141
142static ssize_t role_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
143{
144	if (!strcmp(kobj->name, SETUP_PASSWD))
145		return sysfs_emit(buf, "%s\n", BIOS_ADMIN);
146
147	if (!strcmp(kobj->name, POWER_ON_PASSWD))
148		return sysfs_emit(buf, "%s\n", POWER_ON);
149
150	return -EIO;
151}
152
153static struct kobj_attribute password_role = __ATTR_RO(role);
154
155static ssize_t mechanism_show(struct kobject *kobj, struct kobj_attribute *attr,
156			      char *buf)
157{
158	int i = get_password_instance_id(kobj);
159
160	if (i < 0)
161		return i;
162
163	if (bioscfg_drv.password_data[i].mechanism != PASSWORD)
164		return -EINVAL;
165
166	return sysfs_emit(buf, "%s\n", PASSWD_MECHANISM_TYPES);
167}
168
169static struct kobj_attribute password_mechanism = __ATTR_RO(mechanism);
170
171ATTRIBUTE_VALUES_PROPERTY_SHOW(encodings, password, SEMICOLON_SEP);
172static struct kobj_attribute password_encodings_val = __ATTR_RO(encodings);
173
174static struct attribute *password_attrs[] = {
175	&password_is_password_set.attr,
176	&password_min_password_length.attr,
177	&password_max_password_length.attr,
178	&password_current_password.attr,
179	&password_new_password.attr,
180	&password_role.attr,
181	&password_mechanism.attr,
182	&password_encodings_val.attr,
183	NULL
184};
185
186static const struct attribute_group password_attr_group = {
187	.attrs = password_attrs
188};
189
190int hp_alloc_password_data(void)
191{
192	bioscfg_drv.password_instances_count = hp_get_instance_count(HP_WMI_BIOS_PASSWORD_GUID);
193	bioscfg_drv.password_data = kcalloc(bioscfg_drv.password_instances_count,
194					    sizeof(*bioscfg_drv.password_data), GFP_KERNEL);
195	if (!bioscfg_drv.password_data) {
196		bioscfg_drv.password_instances_count = 0;
197		return -ENOMEM;
198	}
199
200	return 0;
201}
202
203/* Expected Values types associated with each element */
204static const acpi_object_type expected_password_types[] = {
205	[NAME] = ACPI_TYPE_STRING,
206	[VALUE] = ACPI_TYPE_STRING,
207	[PATH] = ACPI_TYPE_STRING,
208	[IS_READONLY] = ACPI_TYPE_INTEGER,
209	[DISPLAY_IN_UI] = ACPI_TYPE_INTEGER,
210	[REQUIRES_PHYSICAL_PRESENCE] = ACPI_TYPE_INTEGER,
211	[SEQUENCE] = ACPI_TYPE_INTEGER,
212	[PREREQUISITES_SIZE] = ACPI_TYPE_INTEGER,
213	[PREREQUISITES] = ACPI_TYPE_STRING,
214	[SECURITY_LEVEL] = ACPI_TYPE_INTEGER,
215	[PSWD_MIN_LENGTH] = ACPI_TYPE_INTEGER,
216	[PSWD_MAX_LENGTH] = ACPI_TYPE_INTEGER,
217	[PSWD_SIZE] = ACPI_TYPE_INTEGER,
218	[PSWD_ENCODINGS] = ACPI_TYPE_STRING,
219	[PSWD_IS_SET] = ACPI_TYPE_INTEGER,
220};
221
222static int hp_populate_password_elements_from_package(union acpi_object *password_obj,
223						      int password_obj_count,
224						      int instance_id)
225{
226	char *str_value = NULL;
227	int value_len;
228	int ret;
229	u32 size;
230	u32 int_value = 0;
231	int elem;
232	int reqs;
233	int eloc;
234	int pos_values;
235	struct password_data *password_data = &bioscfg_drv.password_data[instance_id];
236
237	if (!password_obj)
238		return -EINVAL;
239
240	for (elem = 1, eloc = 1; elem < password_obj_count; elem++, eloc++) {
241		/* ONLY look at the first PASSWORD_ELEM_CNT elements */
242		if (eloc == PSWD_ELEM_CNT)
243			goto exit_package;
244
245		switch (password_obj[elem].type) {
246		case ACPI_TYPE_STRING:
247			if (PREREQUISITES != elem && PSWD_ENCODINGS != elem) {
248				ret = hp_convert_hexstr_to_str(password_obj[elem].string.pointer,
249							       password_obj[elem].string.length,
250							       &str_value, &value_len);
251				if (ret)
252					continue;
253			}
254			break;
255		case ACPI_TYPE_INTEGER:
256			int_value = (u32)password_obj[elem].integer.value;
257			break;
258		default:
259			pr_warn("Unsupported object type [%d]\n", password_obj[elem].type);
260			continue;
261		}
262
263		/* Check that both expected and read object type match */
264		if (expected_password_types[eloc] != password_obj[elem].type) {
265			pr_err("Error expected type %d for elem %d, but got type %d instead\n",
266			       expected_password_types[eloc], elem, password_obj[elem].type);
267			kfree(str_value);
268			return -EIO;
269		}
270
271		/* Assign appropriate element value to corresponding field*/
272		switch (eloc) {
273		case VALUE:
274			break;
275		case PATH:
276			strscpy(password_data->common.path, str_value,
277				sizeof(password_data->common.path));
278			break;
279		case IS_READONLY:
280			password_data->common.is_readonly = int_value;
281			break;
282		case DISPLAY_IN_UI:
283			password_data->common.display_in_ui = int_value;
284			break;
285		case REQUIRES_PHYSICAL_PRESENCE:
286			password_data->common.requires_physical_presence = int_value;
287			break;
288		case SEQUENCE:
289			password_data->common.sequence = int_value;
290			break;
291		case PREREQUISITES_SIZE:
292			if (int_value > MAX_PREREQUISITES_SIZE) {
293				pr_warn("Prerequisites size value exceeded the maximum number of elements supported or data may be malformed\n");
294				int_value = MAX_PREREQUISITES_SIZE;
295			}
296			password_data->common.prerequisites_size = int_value;
297
298			/* This step is needed to keep the expected
299			 * element list pointing to the right obj[elem].type
300			 * when the size is zero. PREREQUISITES
301			 * object is omitted by BIOS when the size is
302			 * zero.
303			 */
304			if (int_value == 0)
305				eloc++;
306			break;
307		case PREREQUISITES:
308			size = min_t(u32, password_data->common.prerequisites_size,
309				     MAX_PREREQUISITES_SIZE);
310
311			for (reqs = 0; reqs < size; reqs++) {
312				ret = hp_convert_hexstr_to_str(password_obj[elem + reqs].string.pointer,
313							       password_obj[elem + reqs].string.length,
314							       &str_value, &value_len);
315
316				if (ret)
317					break;
318
319				strscpy(password_data->common.prerequisites[reqs],
320					str_value,
321					sizeof(password_data->common.prerequisites[reqs]));
322
323				kfree(str_value);
324				str_value = NULL;
325
326			}
327			break;
328		case SECURITY_LEVEL:
329			password_data->common.security_level = int_value;
330			break;
331		case PSWD_MIN_LENGTH:
332			password_data->min_password_length = int_value;
333			break;
334		case PSWD_MAX_LENGTH:
335			password_data->max_password_length = int_value;
336			break;
337		case PSWD_SIZE:
338
339			if (int_value > MAX_ENCODINGS_SIZE) {
340				pr_warn("Password Encoding size value exceeded the maximum number of elements supported or data may be malformed\n");
341				int_value = MAX_ENCODINGS_SIZE;
342			}
343			password_data->encodings_size = int_value;
344
345			/* This step is needed to keep the expected
346			 * element list pointing to the right obj[elem].type
347			 * when the size is zero. PSWD_ENCODINGS
348			 * object is omitted by BIOS when the size is
349			 * zero.
350			 */
351			if (int_value == 0)
352				eloc++;
353			break;
354		case PSWD_ENCODINGS:
355			size = min_t(u32, password_data->encodings_size, MAX_ENCODINGS_SIZE);
356			for (pos_values = 0; pos_values < size; pos_values++) {
357				ret = hp_convert_hexstr_to_str(password_obj[elem + pos_values].string.pointer,
358							       password_obj[elem + pos_values].string.length,
359							       &str_value, &value_len);
360				if (ret)
361					break;
362
363				strscpy(password_data->encodings[pos_values],
364					str_value,
365					sizeof(password_data->encodings[pos_values]));
366				kfree(str_value);
367				str_value = NULL;
368
369			}
370			break;
371		case PSWD_IS_SET:
372			password_data->is_enabled = int_value;
373			break;
374		default:
375			pr_warn("Invalid element: %d found in Password attribute or data may be malformed\n", elem);
376			break;
377		}
378
379		kfree(str_value);
380		str_value = NULL;
381	}
382
383exit_package:
384	kfree(str_value);
385	return 0;
386}
387
388/**
389 * hp_populate_password_package_data()
390 *	Populate all properties for an instance under password attribute
391 *
392 * @password_obj: ACPI object with password data
393 * @instance_id: The instance to enumerate
394 * @attr_name_kobj: The parent kernel object
395 */
396int hp_populate_password_package_data(union acpi_object *password_obj, int instance_id,
397				      struct kobject *attr_name_kobj)
398{
399	struct password_data *password_data = &bioscfg_drv.password_data[instance_id];
400
401	password_data->attr_name_kobj = attr_name_kobj;
402
403	hp_populate_password_elements_from_package(password_obj,
404						   password_obj->package.count,
405						   instance_id);
406
407	hp_friendly_user_name_update(password_data->common.path,
408				     attr_name_kobj->name,
409				     password_data->common.display_name,
410				     sizeof(password_data->common.display_name));
411
412	if (!strcmp(attr_name_kobj->name, SETUP_PASSWD))
413		return sysfs_create_group(attr_name_kobj, &password_attr_group);
414
415	return sysfs_create_group(attr_name_kobj, &password_attr_group);
416}
417
418static int hp_populate_password_elements_from_buffer(u8 *buffer_ptr, u32 *buffer_size,
419						     int instance_id)
420{
421	int values;
422	int isreadonly;
423	struct password_data *password_data = &bioscfg_drv.password_data[instance_id];
424	int ret = 0;
425
426	/*
427	 * Only data relevant to this driver and its functionality is
428	 * read. BIOS defines the order in which each * element is
429	 * read. Element 0 data is not relevant to this
430	 * driver hence it is ignored. For clarity, all element names
431	 * (DISPLAY_IN_UI) which defines the order in which is read
432	 * and the name matches the variable where the data is stored.
433	 *
434	 * In earlier implementation, reported errors were ignored
435	 * causing the data to remain uninitialized. It is not
436	 * possible to determine if data read from BIOS is valid or
437	 * not. It is for this reason functions may return a error
438	 * without validating the data itself.
439	 */
440
441	// VALUE:
442	ret = hp_get_string_from_buffer(&buffer_ptr, buffer_size, password_data->current_password,
443					sizeof(password_data->current_password));
444	if (ret < 0)
445		goto buffer_exit;
446
447	// COMMON:
448	ret = hp_get_common_data_from_buffer(&buffer_ptr, buffer_size,
449					     &password_data->common);
450	if (ret < 0)
451		goto buffer_exit;
452
453	// PSWD_MIN_LENGTH:
454	ret = hp_get_integer_from_buffer(&buffer_ptr, buffer_size,
455					 &password_data->min_password_length);
456	if (ret < 0)
457		goto buffer_exit;
458
459	// PSWD_MAX_LENGTH:
460	ret = hp_get_integer_from_buffer(&buffer_ptr, buffer_size,
461					 &password_data->max_password_length);
462	if (ret < 0)
463		goto buffer_exit;
464
465	// PSWD_SIZE:
466	ret = hp_get_integer_from_buffer(&buffer_ptr, buffer_size,
467					 &password_data->encodings_size);
468	if (ret < 0)
469		goto buffer_exit;
470
471	if (password_data->encodings_size > MAX_ENCODINGS_SIZE) {
472		/* Report a message and limit possible values size to maximum value */
473		pr_warn("Password Encoding size value exceeded the maximum number of elements supported or data may be malformed\n");
474		password_data->encodings_size = MAX_ENCODINGS_SIZE;
475	}
476
477	// PSWD_ENCODINGS:
478	for (values = 0; values < password_data->encodings_size; values++) {
479		ret = hp_get_string_from_buffer(&buffer_ptr, buffer_size,
480						password_data->encodings[values],
481						sizeof(password_data->encodings[values]));
482		if (ret < 0)
483			break;
484	}
485
486	// PSWD_IS_SET:
487	ret = hp_get_integer_from_buffer(&buffer_ptr, buffer_size, &isreadonly);
488	if (ret < 0)
489		goto buffer_exit;
490
491	password_data->is_enabled = isreadonly ? true : false;
492
493buffer_exit:
494	return ret;
495}
496
497/**
498 * hp_populate_password_buffer_data()
499 * Populate all properties for an instance under password object attribute
500 *
501 * @buffer_ptr: Buffer pointer
502 * @buffer_size: Buffer size
503 * @instance_id: The instance to enumerate
504 * @attr_name_kobj: The parent kernel object
505 */
506int hp_populate_password_buffer_data(u8 *buffer_ptr, u32 *buffer_size, int instance_id,
507				     struct kobject *attr_name_kobj)
508{
509	struct password_data *password_data = &bioscfg_drv.password_data[instance_id];
510	int ret = 0;
511
512	password_data->attr_name_kobj = attr_name_kobj;
513
514	/* Populate Password attributes */
515	ret = hp_populate_password_elements_from_buffer(buffer_ptr, buffer_size,
516							instance_id);
517	if (ret < 0)
518		return ret;
519
520	hp_friendly_user_name_update(password_data->common.path,
521				     attr_name_kobj->name,
522				     password_data->common.display_name,
523				     sizeof(password_data->common.display_name));
524	if (!strcmp(attr_name_kobj->name, SETUP_PASSWD))
525		return sysfs_create_group(attr_name_kobj, &password_attr_group);
526
527	return sysfs_create_group(attr_name_kobj, &password_attr_group);
528}
529
530/**
531 * hp_exit_password_attributes() - Clear all attribute data
532 *
533 * Clears all data allocated for this group of attributes
534 */
535void hp_exit_password_attributes(void)
536{
537	int instance_id;
538
539	for (instance_id = 0; instance_id < bioscfg_drv.password_instances_count;
540	     instance_id++) {
541		struct kobject *attr_name_kobj =
542			bioscfg_drv.password_data[instance_id].attr_name_kobj;
543
544		if (attr_name_kobj) {
545			if (!strcmp(attr_name_kobj->name, SETUP_PASSWD))
546				sysfs_remove_group(attr_name_kobj,
547						   &password_attr_group);
548			else
549				sysfs_remove_group(attr_name_kobj,
550						   &password_attr_group);
551		}
552	}
553	bioscfg_drv.password_instances_count = 0;
554	kfree(bioscfg_drv.password_data);
555	bioscfg_drv.password_data = NULL;
556}
557