1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2018 Bootlin
4  * Author: Miquel Raynal <miquel.raynal@bootlin.com>
5  */
6 
7 #include <command.h>
8 #include <dm.h>
9 #include <log.h>
10 #include <mapmem.h>
11 #include <tpm-common.h>
12 #include <tpm-v2.h>
13 #include "tpm-user-utils.h"
14 
do_tpm2_startup(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])15 static int do_tpm2_startup(struct cmd_tbl *cmdtp, int flag, int argc,
16 			   char *const argv[])
17 {
18 	enum tpm2_startup_types mode;
19 	struct udevice *dev;
20 	int ret;
21 	bool bon = true;
22 
23 	ret = get_tpm(&dev);
24 	if (ret)
25 		return ret;
26 
27 	/* argv[2] is optional to perform a TPM2_CC_SHUTDOWN */
28 	if (argc > 3 || (argc == 3 && strcasecmp("off", argv[2])))
29 		return CMD_RET_USAGE;
30 
31 	if (!strcasecmp("TPM2_SU_CLEAR", argv[1])) {
32 		mode = TPM2_SU_CLEAR;
33 	} else if (!strcasecmp("TPM2_SU_STATE", argv[1])) {
34 		mode = TPM2_SU_STATE;
35 	} else {
36 		printf("Couldn't recognize mode string: %s\n", argv[1]);
37 		return CMD_RET_FAILURE;
38 	}
39 
40 	if (argv[2])
41 		bon = false;
42 
43 	return report_return_code(tpm2_startup(dev, bon, mode));
44 }
45 
do_tpm2_self_test(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])46 static int do_tpm2_self_test(struct cmd_tbl *cmdtp, int flag, int argc,
47 			     char *const argv[])
48 {
49 	enum tpm2_yes_no full_test;
50 	struct udevice *dev;
51 	int ret;
52 
53 	ret = get_tpm(&dev);
54 	if (ret)
55 		return ret;
56 	if (argc != 2)
57 		return CMD_RET_USAGE;
58 
59 	if (!strcasecmp("full", argv[1])) {
60 		full_test = TPMI_YES;
61 	} else if (!strcasecmp("continue", argv[1])) {
62 		full_test = TPMI_NO;
63 	} else {
64 		printf("Couldn't recognize test mode: %s\n", argv[1]);
65 		return CMD_RET_FAILURE;
66 	}
67 
68 	return report_return_code(tpm2_self_test(dev, full_test));
69 }
70 
do_tpm2_clear(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])71 static int do_tpm2_clear(struct cmd_tbl *cmdtp, int flag, int argc,
72 			 char *const argv[])
73 {
74 	u32 handle = 0;
75 	const char *pw = (argc < 3) ? NULL : argv[2];
76 	const ssize_t pw_sz = pw ? strlen(pw) : 0;
77 	struct udevice *dev;
78 	int ret;
79 
80 	ret = get_tpm(&dev);
81 	if (ret)
82 		return ret;
83 
84 	if (argc < 2 || argc > 3)
85 		return CMD_RET_USAGE;
86 
87 	if (pw_sz > TPM2_DIGEST_LEN)
88 		return -EINVAL;
89 
90 	if (!strcasecmp("TPM2_RH_LOCKOUT", argv[1]))
91 		handle = TPM2_RH_LOCKOUT;
92 	else if (!strcasecmp("TPM2_RH_PLATFORM", argv[1]))
93 		handle = TPM2_RH_PLATFORM;
94 	else
95 		return CMD_RET_USAGE;
96 
97 	return report_return_code(tpm2_clear(dev, handle, pw, pw_sz));
98 }
99 
do_tpm2_pcr_extend(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])100 static int do_tpm2_pcr_extend(struct cmd_tbl *cmdtp, int flag, int argc,
101 			      char *const argv[])
102 {
103 	struct udevice *dev;
104 	struct tpm_chip_priv *priv;
105 	u32 index = simple_strtoul(argv[1], NULL, 0);
106 	void *digest = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0);
107 	int algo = TPM2_ALG_SHA256;
108 	int algo_len;
109 	int ret;
110 	u32 rc;
111 
112 	if (argc < 3 || argc > 4)
113 		return CMD_RET_USAGE;
114 	if (argc == 4) {
115 		algo = tpm2_name_to_algorithm(argv[3]);
116 		if (algo == TPM2_ALG_INVAL)
117 			return CMD_RET_FAILURE;
118 	}
119 	algo_len = tpm2_algorithm_to_len(algo);
120 
121 	ret = get_tpm(&dev);
122 	if (ret)
123 		return ret;
124 
125 	priv = dev_get_uclass_priv(dev);
126 	if (!priv)
127 		return -EINVAL;
128 
129 	if (index >= priv->pcr_count)
130 		return -EINVAL;
131 
132 	rc = tpm2_pcr_extend(dev, index, algo, digest, algo_len);
133 	if (!rc) {
134 		printf("PCR #%u extended with %d byte %s digest\n", index,
135 		       algo_len, tpm2_algorithm_name(algo));
136 		print_byte_string(digest, algo_len);
137 	}
138 
139 	unmap_sysmem(digest);
140 
141 	return report_return_code(rc);
142 }
143 
do_tpm_pcr_read(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])144 static int do_tpm_pcr_read(struct cmd_tbl *cmdtp, int flag, int argc,
145 			   char *const argv[])
146 {
147 	enum tpm2_algorithms algo = TPM2_ALG_SHA256;
148 	struct udevice *dev;
149 	struct tpm_chip_priv *priv;
150 	u32 index, rc;
151 	int algo_len;
152 	unsigned int updates;
153 	void *data;
154 	int ret;
155 
156 	if (argc < 3 || argc > 4)
157 		return CMD_RET_USAGE;
158 	if (argc == 4) {
159 		algo = tpm2_name_to_algorithm(argv[3]);
160 		if (algo == TPM2_ALG_INVAL)
161 			return CMD_RET_FAILURE;
162 	}
163 	algo_len = tpm2_algorithm_to_len(algo);
164 
165 	ret = get_tpm(&dev);
166 	if (ret)
167 		return ret;
168 
169 	priv = dev_get_uclass_priv(dev);
170 	if (!priv)
171 		return -EINVAL;
172 
173 	index = simple_strtoul(argv[1], NULL, 0);
174 	if (index >= priv->pcr_count)
175 		return -EINVAL;
176 
177 	data = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0);
178 
179 	rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, algo,
180 			   data, algo_len, &updates);
181 	if (!rc) {
182 		printf("PCR #%u %s %d byte content (%u known updates):\n", index,
183 		       tpm2_algorithm_name(algo), algo_len, updates);
184 		print_byte_string(data, algo_len);
185 	}
186 
187 	unmap_sysmem(data);
188 
189 	return report_return_code(rc);
190 }
191 
do_tpm_get_capability(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])192 static int do_tpm_get_capability(struct cmd_tbl *cmdtp, int flag, int argc,
193 				 char *const argv[])
194 {
195 	u32 capability, property, rc;
196 	u8 *data;
197 	size_t count;
198 	int i, j;
199 	struct udevice *dev;
200 	int ret;
201 
202 	ret = get_tpm(&dev);
203 	if (ret)
204 		return ret;
205 
206 	if (argc != 5)
207 		return CMD_RET_USAGE;
208 
209 	capability = simple_strtoul(argv[1], NULL, 0);
210 	property = simple_strtoul(argv[2], NULL, 0);
211 	data = map_sysmem(simple_strtoul(argv[3], NULL, 0), 0);
212 	count = simple_strtoul(argv[4], NULL, 0);
213 
214 	rc = tpm2_get_capability(dev, capability, property, data, count);
215 	if (rc)
216 		goto unmap_data;
217 
218 	printf("Capabilities read from TPM:\n");
219 	for (i = 0; i < count; i++) {
220 		printf("Property 0x");
221 		for (j = 0; j < 4; j++)
222 			printf("%02x", data[(i * 8) + j + sizeof(u32)]);
223 		printf(": 0x");
224 		for (j = 4; j < 8; j++)
225 			printf("%02x", data[(i * 8) + j + sizeof(u32)]);
226 		printf("\n");
227 	}
228 
229 unmap_data:
230 	unmap_sysmem(data);
231 
232 	return report_return_code(rc);
233 }
234 
select_mask(u32 mask,enum tpm2_algorithms algo,bool select)235 static u32 select_mask(u32 mask, enum tpm2_algorithms algo, bool select)
236 {
237 	size_t i;
238 
239 	for (i = 0; i < ARRAY_SIZE(hash_algo_list); i++) {
240 		if (hash_algo_list[i].hash_alg != algo)
241 			continue;
242 
243 		if (select)
244 			mask |= hash_algo_list[i].hash_mask;
245 		else
246 			mask &= ~hash_algo_list[i].hash_mask;
247 
248 		break;
249 	}
250 
251 	return mask;
252 }
253 
254 static bool
is_algo_in_pcrs(enum tpm2_algorithms algo,struct tpml_pcr_selection * pcrs)255 is_algo_in_pcrs(enum tpm2_algorithms algo, struct tpml_pcr_selection *pcrs)
256 {
257 	size_t i;
258 
259 	for (i = 0; i < pcrs->count; i++) {
260 		if (algo == pcrs->selection[i].hash)
261 			return true;
262 	}
263 
264 	return false;
265 }
266 
do_tpm2_pcrallocate(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])267 static int do_tpm2_pcrallocate(struct cmd_tbl *cmdtp, int flag, int argc,
268 			       char *const argv[])
269 {
270 	struct udevice *dev;
271 	int ret;
272 	enum tpm2_algorithms algo;
273 	const char *pw = (argc < 4) ? NULL : argv[3];
274 	const ssize_t pw_sz = pw ? strlen(pw) : 0;
275 	static struct tpml_pcr_selection pcr = { 0 };
276 	u32 pcr_len = 0;
277 	bool bon = false;
278 	static u32 mask;
279 	int i;
280 
281 	/* argv[1]: algorithm (bank), argv[2]: on/off */
282 	if (argc < 3 || argc > 4)
283 		return CMD_RET_USAGE;
284 
285 	if (!strcasecmp("on", argv[2]))
286 		bon = true;
287 	else if (strcasecmp("off", argv[2]))
288 		return CMD_RET_USAGE;
289 
290 	algo = tpm2_name_to_algorithm(argv[1]);
291 	if (algo == TPM2_ALG_INVAL)
292 		return CMD_RET_USAGE;
293 
294 	ret = get_tpm(&dev);
295 	if (ret)
296 		return ret;
297 
298 	if (!pcr.count) {
299 		/*
300 		 * Get current active algorithms (banks), PCRs and mask via the
301 		 * first call
302 		 */
303 		ret = tpm2_get_pcr_info(dev, &pcr);
304 		if (ret)
305 			return ret;
306 
307 		for (i = 0; i < pcr.count; i++) {
308 			struct tpms_pcr_selection *sel = &pcr.selection[i];
309 			const char *name;
310 
311 			if (!tpm2_is_active_bank(sel))
312 				continue;
313 
314 			mask = select_mask(mask, sel->hash, true);
315 			name = tpm2_algorithm_name(sel->hash);
316 			if (name)
317 				printf("Active bank[%d]: %s\n", i, name);
318 		}
319 	}
320 
321 	if (!is_algo_in_pcrs(algo, &pcr)) {
322 		printf("%s is not supported by the tpm device\n", argv[1]);
323 		return CMD_RET_USAGE;
324 	}
325 
326 	mask = select_mask(mask, algo, bon);
327 	ret = tpm2_pcr_config_algo(dev, mask, &pcr, &pcr_len);
328 	if (ret)
329 		return ret;
330 
331 	return report_return_code(tpm2_send_pcr_allocate(dev, pw, pw_sz, &pcr,
332 							 pcr_len));
333 }
334 
do_tpm_dam_reset(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])335 static int do_tpm_dam_reset(struct cmd_tbl *cmdtp, int flag, int argc,
336 			    char *const argv[])
337 {
338 	const char *pw = (argc < 2) ? NULL : argv[1];
339 	const ssize_t pw_sz = pw ? strlen(pw) : 0;
340 	struct udevice *dev;
341 	int ret;
342 
343 	ret = get_tpm(&dev);
344 	if (ret)
345 		return ret;
346 
347 	if (argc > 2)
348 		return CMD_RET_USAGE;
349 
350 	if (pw_sz > TPM2_DIGEST_LEN)
351 		return -EINVAL;
352 
353 	return report_return_code(tpm2_dam_reset(dev, pw, pw_sz));
354 }
355 
do_tpm_dam_parameters(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])356 static int do_tpm_dam_parameters(struct cmd_tbl *cmdtp, int flag, int argc,
357 				 char *const argv[])
358 {
359 	const char *pw = (argc < 5) ? NULL : argv[4];
360 	const ssize_t pw_sz = pw ? strlen(pw) : 0;
361 	/*
362 	 * No Dictionary Attack Mitigation (DAM) means:
363 	 * maxtries = 0xFFFFFFFF, recovery_time = 1, lockout_recovery = 0
364 	 */
365 	unsigned long int max_tries;
366 	unsigned long int recovery_time;
367 	unsigned long int lockout_recovery;
368 	struct udevice *dev;
369 	int ret;
370 
371 	ret = get_tpm(&dev);
372 	if (ret)
373 		return ret;
374 
375 	if (argc < 4 || argc > 5)
376 		return CMD_RET_USAGE;
377 
378 	if (pw_sz > TPM2_DIGEST_LEN)
379 		return -EINVAL;
380 
381 	if (strict_strtoul(argv[1], 0, &max_tries))
382 		return CMD_RET_USAGE;
383 
384 	if (strict_strtoul(argv[2], 0, &recovery_time))
385 		return CMD_RET_USAGE;
386 
387 	if (strict_strtoul(argv[3], 0, &lockout_recovery))
388 		return CMD_RET_USAGE;
389 
390 	log(LOGC_NONE, LOGL_INFO, "Changing dictionary attack parameters:\n");
391 	log(LOGC_NONE, LOGL_INFO, "- maxTries: %lu", max_tries);
392 	log(LOGC_NONE, LOGL_INFO, "- recoveryTime: %lu\n", recovery_time);
393 	log(LOGC_NONE, LOGL_INFO, "- lockoutRecovery: %lu\n", lockout_recovery);
394 
395 	return report_return_code(tpm2_dam_parameters(dev, pw, pw_sz, max_tries,
396 						      recovery_time,
397 						      lockout_recovery));
398 }
399 
do_tpm_change_auth(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])400 static int do_tpm_change_auth(struct cmd_tbl *cmdtp, int flag, int argc,
401 			      char *const argv[])
402 {
403 	u32 handle;
404 	const char *newpw = argv[2];
405 	const char *oldpw = (argc == 3) ? NULL : argv[3];
406 	const ssize_t newpw_sz = strlen(newpw);
407 	const ssize_t oldpw_sz = oldpw ? strlen(oldpw) : 0;
408 	struct udevice *dev;
409 	int ret;
410 
411 	ret = get_tpm(&dev);
412 	if (ret)
413 		return ret;
414 
415 	if (argc < 3 || argc > 4)
416 		return CMD_RET_USAGE;
417 
418 	if (newpw_sz > TPM2_DIGEST_LEN || oldpw_sz > TPM2_DIGEST_LEN)
419 		return -EINVAL;
420 
421 	if (!strcasecmp("TPM2_RH_LOCKOUT", argv[1]))
422 		handle = TPM2_RH_LOCKOUT;
423 	else if (!strcasecmp("TPM2_RH_ENDORSEMENT", argv[1]))
424 		handle = TPM2_RH_ENDORSEMENT;
425 	else if (!strcasecmp("TPM2_RH_OWNER", argv[1]))
426 		handle = TPM2_RH_OWNER;
427 	else if (!strcasecmp("TPM2_RH_PLATFORM", argv[1]))
428 		handle = TPM2_RH_PLATFORM;
429 	else
430 		return CMD_RET_USAGE;
431 
432 	return report_return_code(tpm2_change_auth(dev, handle, newpw, newpw_sz,
433 						   oldpw, oldpw_sz));
434 }
435 
do_tpm_pcr_setauthpolicy(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])436 static int do_tpm_pcr_setauthpolicy(struct cmd_tbl *cmdtp, int flag, int argc,
437 				    char *const argv[])
438 {
439 	u32 index = simple_strtoul(argv[1], NULL, 0);
440 	char *key = argv[2];
441 	const char *pw = (argc < 4) ? NULL : argv[3];
442 	const ssize_t pw_sz = pw ? strlen(pw) : 0;
443 	struct udevice *dev;
444 	int ret;
445 
446 	ret = get_tpm(&dev);
447 	if (ret)
448 		return ret;
449 
450 	if (strlen(key) != TPM2_DIGEST_LEN)
451 		return -EINVAL;
452 
453 	if (argc < 3 || argc > 4)
454 		return CMD_RET_USAGE;
455 
456 	return report_return_code(tpm2_pcr_setauthpolicy(dev, pw, pw_sz, index,
457 							 key));
458 }
459 
do_tpm_pcr_setauthvalue(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])460 static int do_tpm_pcr_setauthvalue(struct cmd_tbl *cmdtp, int flag,
461 				   int argc, char *const argv[])
462 {
463 	u32 index = simple_strtoul(argv[1], NULL, 0);
464 	char *key = argv[2];
465 	const ssize_t key_sz = strlen(key);
466 	const char *pw = (argc < 4) ? NULL : argv[3];
467 	const ssize_t pw_sz = pw ? strlen(pw) : 0;
468 	struct udevice *dev;
469 	int ret;
470 
471 	ret = get_tpm(&dev);
472 	if (ret)
473 		return ret;
474 
475 	if (strlen(key) != TPM2_DIGEST_LEN)
476 		return -EINVAL;
477 
478 	if (argc < 3 || argc > 4)
479 		return CMD_RET_USAGE;
480 
481 	return report_return_code(tpm2_pcr_setauthvalue(dev, pw, pw_sz, index,
482 							key, key_sz));
483 }
484 
485 static struct cmd_tbl tpm2_commands[] = {
486 	U_BOOT_CMD_MKENT(device, 0, 1, do_tpm_device, "", ""),
487 	U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""),
488 	U_BOOT_CMD_MKENT(state, 0, 1, do_tpm_report_state, "", ""),
489 	U_BOOT_CMD_MKENT(init, 0, 1, do_tpm_init, "", ""),
490 	U_BOOT_CMD_MKENT(startup, 0, 1, do_tpm2_startup, "", ""),
491 	U_BOOT_CMD_MKENT(self_test, 0, 1, do_tpm2_self_test, "", ""),
492 	U_BOOT_CMD_MKENT(clear, 0, 1, do_tpm2_clear, "", ""),
493 	U_BOOT_CMD_MKENT(pcr_extend, 0, 1, do_tpm2_pcr_extend, "", ""),
494 	U_BOOT_CMD_MKENT(pcr_read, 0, 1, do_tpm_pcr_read, "", ""),
495 	U_BOOT_CMD_MKENT(get_capability, 0, 1, do_tpm_get_capability, "", ""),
496 	U_BOOT_CMD_MKENT(dam_reset, 0, 1, do_tpm_dam_reset, "", ""),
497 	U_BOOT_CMD_MKENT(dam_parameters, 0, 1, do_tpm_dam_parameters, "", ""),
498 	U_BOOT_CMD_MKENT(change_auth, 0, 1, do_tpm_change_auth, "", ""),
499 	U_BOOT_CMD_MKENT(autostart, 0, 1, do_tpm_autostart, "", ""),
500 	U_BOOT_CMD_MKENT(pcr_setauthpolicy, 0, 1,
501 			 do_tpm_pcr_setauthpolicy, "", ""),
502 	U_BOOT_CMD_MKENT(pcr_setauthvalue, 0, 1,
503 			 do_tpm_pcr_setauthvalue, "", ""),
504 	U_BOOT_CMD_MKENT(pcr_allocate, 0, 1, do_tpm2_pcrallocate, "", ""),
505 };
506 
get_tpm2_commands(unsigned int * size)507 struct cmd_tbl *get_tpm2_commands(unsigned int *size)
508 {
509 	*size = ARRAY_SIZE(tpm2_commands);
510 
511 	return tpm2_commands;
512 }
513 
514 U_BOOT_CMD(tpm2, CONFIG_SYS_MAXARGS, 1, do_tpm, "Issue a TPMv2.x command",
515 "<command> [<arguments>]\n"
516 "\n"
517 "device [num device]\n"
518 "    Show all devices or set the specified device\n"
519 "info\n"
520 "    Show information about the TPM.\n"
521 "state\n"
522 "    Show internal state from the TPM (if available)\n"
523 "autostart\n"
524 "    Initalize the tpm, perform a Startup(clear) and run a full selftest\n"
525 "    sequence\n"
526 "init\n"
527 "    Initialize the software stack. Always the first command to issue.\n"
528 "    'tpm startup' is the only acceptable command after a 'tpm init' has been\n"
529 "    issued\n"
530 "startup <mode> [<op>]\n"
531 "    Issue a TPM2_Startup command.\n"
532 "    <mode> is one of:\n"
533 "        * TPM2_SU_CLEAR (reset state)\n"
534 "        * TPM2_SU_STATE (preserved state)\n"
535 "    <op>:\n"
536 "        * off - To shutdown the TPM\n"
537 "self_test <type>\n"
538 "    Test the TPM capabilities.\n"
539 "    <type> is one of:\n"
540 "        * full (perform all tests)\n"
541 "        * continue (only check untested tests)\n"
542 "clear <hierarchy>\n"
543 "    Issue a TPM2_Clear command.\n"
544 "    <hierarchy> is one of:\n"
545 "        * TPM2_RH_LOCKOUT\n"
546 "        * TPM2_RH_PLATFORM\n"
547 "pcr_extend <pcr> <digest_addr> [<digest_algo>]\n"
548 "    Extend PCR #<pcr> with digest at <digest_addr> with digest_algo.\n"
549 "    <pcr>: index of the PCR\n"
550 "    <digest_addr>: address of digest of digest_algo type (defaults to SHA256)\n"
551 "pcr_read <pcr> <digest_addr> [<digest_algo>]\n"
552 "    Read PCR #<pcr> to memory address <digest_addr> with <digest_algo>.\n"
553 "    <pcr>: index of the PCR\n"
554 "    <digest_addr>: address of digest of digest_algo type (defaults to SHA256)\n"
555 "get_capability <capability> <property> <addr> <count>\n"
556 "    Read and display <count> entries indexed by <capability>/<property>.\n"
557 "    Values are 4 bytes long and are written at <addr>.\n"
558 "    <capability>: capability\n"
559 "    <property>: property\n"
560 "    <addr>: address to store <count> entries of 4 bytes\n"
561 "    <count>: number of entries to retrieve\n"
562 "dam_reset [<password>]\n"
563 "    If the TPM is not in a LOCKOUT state, reset the internal error counter.\n"
564 "    <password>: optional password\n"
565 "dam_parameters <max_tries> <recovery_time> <lockout_recovery> [<password>]\n"
566 "    If the TPM is not in a LOCKOUT state, set the DAM parameters\n"
567 "    <maxTries>: maximum number of failures before lockout,\n"
568 "                0 means always locking\n"
569 "    <recoveryTime>: time before decrement of the error counter,\n"
570 "                    0 means no lockout\n"
571 "    <lockoutRecovery>: time of a lockout (before the next try),\n"
572 "                       0 means a reboot is needed\n"
573 "    <password>: optional password of the LOCKOUT hierarchy\n"
574 "change_auth <hierarchy> <new_pw> [<old_pw>]\n"
575 "    <hierarchy>: the hierarchy\n"
576 "    <new_pw>: new password for <hierarchy>\n"
577 "    <old_pw>: optional previous password of <hierarchy>\n"
578 "pcr_setauthpolicy|pcr_setauthvalue <pcr> <key> [<password>]\n"
579 "    Change the <key> to access PCR #<pcr>.\n"
580 "    hierarchy and may be empty.\n"
581 "    /!\\WARNING: untested function, use at your own risks !\n"
582 "    <pcr>: index of the PCR\n"
583 "    <key>: secret to protect the access of PCR #<pcr>\n"
584 "    <password>: optional password of the PLATFORM hierarchy\n"
585 "pcr_allocate <algorithm> <on/off> [<password>]\n"
586 "    Issue a TPM2_PCR_Allocate Command to reconfig PCR bank algorithm.\n"
587 "    <algorithm> is one of:\n"
588 "        * sha1\n"
589 "        * sha256\n"
590 "        * sha384\n"
591 "        * sha512\n"
592 "    <on|off> is one of:\n"
593 "        * on  - Select all available PCRs associated with the specified\n"
594 "                algorithm (bank)\n"
595 "        * off - Clear all available PCRs associated with the specified\n"
596 "                algorithm (bank)\n"
597 "    <password>: optional password\n"
598 );
599