Convert CONFIG_SYS_MAXARGS to Kconfig
[platform/kernel/u-boot.git] / cmd / tpm_test.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2015 Google, Inc
4  */
5
6 #include <common.h>
7 #include <command.h>
8 #include <cpu_func.h>
9 #include <log.h>
10 #include <tpm-v1.h>
11 #include "tpm-user-utils.h"
12 #include <tpm_api.h>
13
14 /* Prints error and returns on failure */
15 #define TPM_CHECK(tpm_command) do { \
16         uint32_t result; \
17         \
18         result = (tpm_command); \
19         if (result != TPM_SUCCESS) { \
20                 printf("TEST FAILED: line %d: " #tpm_command ": 0x%x\n", \
21                         __LINE__, result); \
22                 return result; \
23         } \
24 } while (0)
25
26 #define INDEX0                  0xda70
27 #define INDEX1                  0xda71
28 #define INDEX2                  0xda72
29 #define INDEX3                  0xda73
30 #define INDEX_INITIALISED       0xda80
31 #define PHYS_PRESENCE           4
32 #define PRESENCE                8
33
34 static uint32_t TlclStartupIfNeeded(struct udevice *dev)
35 {
36         uint32_t result = tpm_startup(dev, TPM_ST_CLEAR);
37
38         return result == TPM_INVALID_POSTINIT ? TPM_SUCCESS : result;
39 }
40
41 static int test_timer(struct udevice *dev)
42 {
43         printf("get_timer(0) = %lu\n", get_timer(0));
44         return 0;
45 }
46
47 static uint32_t tpm_get_flags(struct udevice *dev, uint8_t *disable,
48                               uint8_t *deactivated, uint8_t *nvlocked)
49 {
50         struct tpm_permanent_flags pflags;
51         uint32_t result;
52
53         result = tpm1_get_permanent_flags(dev, &pflags);
54         if (result)
55                 return result;
56         if (disable)
57                 *disable = pflags.disable;
58         if (deactivated)
59                 *deactivated = pflags.deactivated;
60         if (nvlocked)
61                 *nvlocked = pflags.nv_locked;
62         debug("TPM: Got flags disable=%d, deactivated=%d, nvlocked=%d\n",
63               pflags.disable, pflags.deactivated, pflags.nv_locked);
64
65         return 0;
66 }
67
68 static uint32_t tpm_nv_write_value_lock(struct udevice *dev, uint32_t index)
69 {
70         debug("TPM: Write lock 0x%x\n", index);
71
72         return tpm_nv_write_value(dev, index, NULL, 0);
73 }
74
75 static int tpm_is_owned(struct udevice *dev)
76 {
77         uint8_t response[TPM_PUBEK_SIZE];
78         uint32_t result;
79
80         result = tpm_read_pubek(dev, response, sizeof(response));
81
82         return result != TPM_SUCCESS;
83 }
84
85 static int test_early_extend(struct udevice *dev)
86 {
87         uint8_t value_in[20];
88         uint8_t value_out[20];
89
90         printf("Testing earlyextend ...");
91         tpm_init(dev);
92         TPM_CHECK(tpm_startup(dev, TPM_ST_CLEAR));
93         TPM_CHECK(tpm_continue_self_test(dev));
94         TPM_CHECK(tpm_pcr_extend(dev, 1, value_in, value_out));
95         printf("done\n");
96         return 0;
97 }
98
99 static int test_early_nvram(struct udevice *dev)
100 {
101         uint32_t x;
102
103         printf("Testing earlynvram ...");
104         tpm_init(dev);
105         TPM_CHECK(tpm_startup(dev, TPM_ST_CLEAR));
106         TPM_CHECK(tpm_continue_self_test(dev));
107         TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
108         TPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)));
109         printf("done\n");
110         return 0;
111 }
112
113 static int test_early_nvram2(struct udevice *dev)
114 {
115         uint32_t x;
116
117         printf("Testing earlynvram2 ...");
118         tpm_init(dev);
119         TPM_CHECK(tpm_startup(dev, TPM_ST_CLEAR));
120         TPM_CHECK(tpm_continue_self_test(dev));
121         TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
122         TPM_CHECK(tpm_nv_write_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)));
123         printf("done\n");
124         return 0;
125 }
126
127 static int test_enable(struct udevice *dev)
128 {
129         uint8_t disable = 0, deactivated = 0;
130
131         printf("Testing enable ...\n");
132         tpm_init(dev);
133         TPM_CHECK(TlclStartupIfNeeded(dev));
134         TPM_CHECK(tpm_self_test_full(dev));
135         TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
136         TPM_CHECK(tpm_get_flags(dev, &disable, &deactivated, NULL));
137         printf("\tdisable is %d, deactivated is %d\n", disable, deactivated);
138         TPM_CHECK(tpm_physical_enable(dev));
139         TPM_CHECK(tpm_physical_set_deactivated(dev, 0));
140         TPM_CHECK(tpm_get_flags(dev, &disable, &deactivated, NULL));
141         printf("\tdisable is %d, deactivated is %d\n", disable, deactivated);
142         if (disable == 1 || deactivated == 1)
143                 printf("\tfailed to enable or activate\n");
144         printf("\tdone\n");
145         return 0;
146 }
147
148 #define reboot() do { \
149         printf("\trebooting...\n"); \
150         reset_cpu(); \
151 } while (0)
152
153 static int test_fast_enable(struct udevice *dev)
154 {
155         uint8_t disable = 0, deactivated = 0;
156         int i;
157
158         printf("Testing fastenable ...\n");
159         tpm_init(dev);
160         TPM_CHECK(TlclStartupIfNeeded(dev));
161         TPM_CHECK(tpm_self_test_full(dev));
162         TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
163         TPM_CHECK(tpm_get_flags(dev, &disable, &deactivated, NULL));
164         printf("\tdisable is %d, deactivated is %d\n", disable, deactivated);
165         for (i = 0; i < 2; i++) {
166                 TPM_CHECK(tpm_force_clear(dev));
167                 TPM_CHECK(tpm_get_flags(dev, &disable, &deactivated, NULL));
168                 printf("\tdisable is %d, deactivated is %d\n", disable,
169                        deactivated);
170                 assert(disable == 1 && deactivated == 1);
171                 TPM_CHECK(tpm_physical_enable(dev));
172                 TPM_CHECK(tpm_physical_set_deactivated(dev, 0));
173                 TPM_CHECK(tpm_get_flags(dev, &disable, &deactivated, NULL));
174                 printf("\tdisable is %d, deactivated is %d\n", disable,
175                        deactivated);
176                 assert(disable == 0 && deactivated == 0);
177         }
178         printf("\tdone\n");
179         return 0;
180 }
181
182 static int test_global_lock(struct udevice *dev)
183 {
184         uint32_t zero = 0;
185         uint32_t result;
186         uint32_t x;
187
188         printf("Testing globallock ...\n");
189         tpm_init(dev);
190         TPM_CHECK(TlclStartupIfNeeded(dev));
191         TPM_CHECK(tpm_self_test_full(dev));
192         TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
193         TPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)));
194         TPM_CHECK(tpm_nv_write_value(dev, INDEX0, (uint8_t *)&zero,
195                                      sizeof(uint32_t)));
196         TPM_CHECK(tpm_nv_read_value(dev, INDEX1, (uint8_t *)&x, sizeof(x)));
197         TPM_CHECK(tpm_nv_write_value(dev, INDEX1, (uint8_t *)&zero,
198                                      sizeof(uint32_t)));
199         TPM_CHECK(tpm_set_global_lock(dev));
200         /* Verifies that write to index0 fails */
201         x = 1;
202         result = tpm_nv_write_value(dev, INDEX0, (uint8_t *)&x, sizeof(x));
203         assert(result == TPM_AREA_LOCKED);
204         TPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)));
205         assert(x == 0);
206         /* Verifies that write to index1 is still possible */
207         x = 2;
208         TPM_CHECK(tpm_nv_write_value(dev, INDEX1, (uint8_t *)&x, sizeof(x)));
209         TPM_CHECK(tpm_nv_read_value(dev, INDEX1, (uint8_t *)&x, sizeof(x)));
210         assert(x == 2);
211         /* Turns off PP */
212         tpm_tsc_physical_presence(dev, PHYS_PRESENCE);
213         /* Verifies that write to index1 fails */
214         x = 3;
215         result = tpm_nv_write_value(dev, INDEX1, (uint8_t *)&x, sizeof(x));
216         assert(result == TPM_BAD_PRESENCE);
217         TPM_CHECK(tpm_nv_read_value(dev, INDEX1, (uint8_t *)&x, sizeof(x)));
218         assert(x == 2);
219         printf("\tdone\n");
220         return 0;
221 }
222
223 static int test_lock(struct udevice *dev)
224 {
225         printf("Testing lock ...\n");
226         tpm_init(dev);
227         tpm_startup(dev, TPM_ST_CLEAR);
228         tpm_self_test_full(dev);
229         tpm_tsc_physical_presence(dev, PRESENCE);
230         tpm_nv_write_value_lock(dev, INDEX0);
231         printf("\tLocked 0x%x\n", INDEX0);
232         printf("\tdone\n");
233         return 0;
234 }
235
236 static void initialise_spaces(struct udevice *dev)
237 {
238         uint32_t zero = 0;
239         uint32_t perm = TPM_NV_PER_WRITE_STCLEAR | TPM_NV_PER_PPWRITE;
240
241         printf("\tInitialising spaces\n");
242         tpm1_nv_set_locked(dev);  /* useful only the first time */
243         tpm1_nv_define_space(dev, INDEX0, perm, 4);
244         tpm_nv_write_value(dev, INDEX0, (uint8_t *)&zero, 4);
245         tpm1_nv_define_space(dev, INDEX1, perm, 4);
246         tpm_nv_write_value(dev, INDEX1, (uint8_t *)&zero, 4);
247         tpm1_nv_define_space(dev, INDEX2, perm, 4);
248         tpm_nv_write_value(dev, INDEX2, (uint8_t *)&zero, 4);
249         tpm1_nv_define_space(dev, INDEX3, perm, 4);
250         tpm_nv_write_value(dev, INDEX3, (uint8_t *)&zero, 4);
251         perm = TPM_NV_PER_READ_STCLEAR | TPM_NV_PER_WRITE_STCLEAR |
252                 TPM_NV_PER_PPWRITE;
253         tpm1_nv_define_space(dev, INDEX_INITIALISED, perm, 1);
254 }
255
256 static int test_readonly(struct udevice *dev)
257 {
258         uint8_t c;
259         uint32_t index_0, index_1, index_2, index_3;
260         int read0, read1, read2, read3;
261
262         printf("Testing readonly ...\n");
263         tpm_init(dev);
264         tpm_startup(dev, TPM_ST_CLEAR);
265         tpm_self_test_full(dev);
266         tpm_tsc_physical_presence(dev, PRESENCE);
267         /*
268          * Checks if initialisation has completed by trying to read-lock a
269          * space that's created at the end of initialisation
270          */
271         if (tpm_nv_read_value(dev, INDEX_INITIALISED, &c, 0) == TPM_BADINDEX) {
272                 /* The initialisation did not complete */
273                 initialise_spaces(dev);
274         }
275
276         /* Checks if spaces are OK or messed up */
277         read0 = tpm_nv_read_value(dev, INDEX0, (uint8_t *)&index_0,
278                                   sizeof(index_0));
279         read1 = tpm_nv_read_value(dev, INDEX1, (uint8_t *)&index_1,
280                                   sizeof(index_1));
281         read2 = tpm_nv_read_value(dev, INDEX2, (uint8_t *)&index_2,
282                                   sizeof(index_2));
283         read3 = tpm_nv_read_value(dev, INDEX3, (uint8_t *)&index_3,
284                                   sizeof(index_3));
285         if (read0 || read1 || read2 || read3) {
286                 printf("Invalid contents\n");
287                 return 0;
288         }
289
290         /*
291          * Writes space, and locks it.  Then attempts to write again.
292          * I really wish I could use the imperative.
293          */
294         index_0 += 1;
295         if (tpm_nv_write_value(dev, INDEX0, (uint8_t *)&index_0,
296                                sizeof(index_0) !=
297                 TPM_SUCCESS)) {
298                 pr_err("\tcould not write index 0\n");
299         }
300         tpm_nv_write_value_lock(dev, INDEX0);
301         if (tpm_nv_write_value(dev, INDEX0, (uint8_t *)&index_0,
302                                sizeof(index_0)) ==
303                         TPM_SUCCESS)
304                 pr_err("\tindex 0 is not locked\n");
305
306         printf("\tdone\n");
307         return 0;
308 }
309
310 static int test_redefine_unowned(struct udevice *dev)
311 {
312         uint32_t perm;
313         uint32_t result;
314         uint32_t x;
315
316         printf("Testing redefine_unowned ...");
317         tpm_init(dev);
318         TPM_CHECK(TlclStartupIfNeeded(dev));
319         TPM_CHECK(tpm_self_test_full(dev));
320         TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
321         assert(!tpm_is_owned(dev));
322
323         /* Ensures spaces exist. */
324         TPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)));
325         TPM_CHECK(tpm_nv_read_value(dev, INDEX1, (uint8_t *)&x, sizeof(x)));
326
327         /* Redefines spaces a couple of times. */
328         perm = TPM_NV_PER_PPWRITE | TPM_NV_PER_GLOBALLOCK;
329         TPM_CHECK(tpm1_nv_define_space(dev, INDEX0, perm,
330                                        2 * sizeof(uint32_t)));
331         TPM_CHECK(tpm1_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t)));
332         perm = TPM_NV_PER_PPWRITE;
333         TPM_CHECK(tpm1_nv_define_space(dev, INDEX1, perm,
334                                        2 * sizeof(uint32_t)));
335         TPM_CHECK(tpm1_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t)));
336
337         /* Sets the global lock */
338         tpm_set_global_lock(dev);
339
340         /* Verifies that index0 cannot be redefined */
341         result = tpm1_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t));
342         assert(result == TPM_AREA_LOCKED);
343
344         /* Checks that index1 can */
345         TPM_CHECK(tpm1_nv_define_space(dev, INDEX1, perm,
346                                        2 * sizeof(uint32_t)));
347         TPM_CHECK(tpm1_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t)));
348
349         /* Turns off PP */
350         tpm_tsc_physical_presence(dev, PHYS_PRESENCE);
351
352         /* Verifies that neither index0 nor index1 can be redefined */
353         result = tpm1_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t));
354         assert(result == TPM_BAD_PRESENCE);
355         result = tpm1_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t));
356         assert(result == TPM_BAD_PRESENCE);
357
358         printf("done\n");
359         return 0;
360 }
361
362 #define PERMPPGL (TPM_NV_PER_PPWRITE | TPM_NV_PER_GLOBALLOCK)
363 #define PERMPP TPM_NV_PER_PPWRITE
364
365 static int test_space_perm(struct udevice *dev)
366 {
367         uint32_t perm;
368
369         printf("Testing spaceperm ...");
370         tpm_init(dev);
371         TPM_CHECK(TlclStartupIfNeeded(dev));
372         TPM_CHECK(tpm_continue_self_test(dev));
373         TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
374         TPM_CHECK(tpm_get_permissions(dev, INDEX0, &perm));
375         assert((perm & PERMPPGL) == PERMPPGL);
376         TPM_CHECK(tpm_get_permissions(dev, INDEX1, &perm));
377         assert((perm & PERMPP) == PERMPP);
378         printf("done\n");
379         return 0;
380 }
381
382 static int test_startup(struct udevice *dev)
383 {
384         uint32_t result;
385
386         printf("Testing startup ...\n");
387
388         tpm_init(dev);
389         result = tpm_startup(dev, TPM_ST_CLEAR);
390         if (result != 0 && result != TPM_INVALID_POSTINIT)
391                 printf("\ttpm startup failed with 0x%x\n", result);
392         result = tpm_get_flags(dev, NULL, NULL, NULL);
393         if (result != 0)
394                 printf("\ttpm getflags failed with 0x%x\n", result);
395         printf("\texecuting SelfTestFull\n");
396         tpm_self_test_full(dev);
397         result = tpm_get_flags(dev, NULL, NULL, NULL);
398         if (result != 0)
399                 printf("\ttpm getflags failed with 0x%x\n", result);
400         printf("\tdone\n");
401         return 0;
402 }
403
404 /*
405  * Runs [op] and ensures it returns success and doesn't run longer than
406  * [time_limit] in milliseconds.
407  */
408 #define TTPM_CHECK(op, time_limit) do { \
409         ulong start, time; \
410         uint32_t __result; \
411         \
412         start = get_timer(0); \
413         __result = op; \
414         if (__result != TPM_SUCCESS) { \
415                 printf("\t" #op ": error 0x%x\n", __result); \
416                 return -1; \
417         } \
418         time = get_timer(start); \
419         printf("\t" #op ": %lu ms\n", time); \
420         if (time > (ulong)time_limit) { \
421                 printf("\t" #op " exceeded " #time_limit " ms\n"); \
422         } \
423 } while (0)
424
425
426 static int test_timing(struct udevice *dev)
427 {
428         uint8_t in[20], out[20];
429         uint32_t x;
430
431         printf("Testing timing ...");
432         tpm_init(dev);
433         TTPM_CHECK(TlclStartupIfNeeded(dev), 50);
434         TTPM_CHECK(tpm_continue_self_test(dev), 100);
435         TTPM_CHECK(tpm_self_test_full(dev), 1000);
436         TTPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE), 100);
437         TTPM_CHECK(tpm_nv_write_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)),
438                    100);
439         TTPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)),
440                    100);
441         TTPM_CHECK(tpm_pcr_extend(dev, 0, in, out), 200);
442         TTPM_CHECK(tpm_set_global_lock(dev), 50);
443         TTPM_CHECK(tpm_tsc_physical_presence(dev, PHYS_PRESENCE), 100);
444         printf("done\n");
445         return 0;
446 }
447
448 #define TPM_MAX_NV_WRITES_NOOWNER 64
449
450 static int test_write_limit(struct udevice *dev)
451 {
452         uint32_t result;
453         int i;
454
455         printf("Testing writelimit ...\n");
456         tpm_init(dev);
457         TPM_CHECK(TlclStartupIfNeeded(dev));
458         TPM_CHECK(tpm_self_test_full(dev));
459         TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
460         TPM_CHECK(tpm_force_clear(dev));
461         TPM_CHECK(tpm_physical_enable(dev));
462         TPM_CHECK(tpm_physical_set_deactivated(dev, 0));
463
464         for (i = 0; i < TPM_MAX_NV_WRITES_NOOWNER + 2; i++) {
465                 printf("\twriting %d\n", i);
466                 result = tpm_nv_write_value(dev, INDEX0, (uint8_t *)&i,
467                                             sizeof(i));
468                 switch (result) {
469                 case TPM_SUCCESS:
470                         break;
471                 case TPM_MAXNVWRITES:
472                         assert(i >= TPM_MAX_NV_WRITES_NOOWNER);
473                 default:
474                         pr_err("\tunexpected error code %d (0x%x)\n",
475                               result, result);
476                 }
477         }
478
479         /* Reset write count */
480         TPM_CHECK(tpm_force_clear(dev));
481         TPM_CHECK(tpm_physical_enable(dev));
482         TPM_CHECK(tpm_physical_set_deactivated(dev, 0));
483
484         /* Try writing again. */
485         TPM_CHECK(tpm_nv_write_value(dev, INDEX0, (uint8_t *)&i, sizeof(i)));
486         printf("\tdone\n");
487         return 0;
488 }
489
490 #define VOIDTEST(XFUNC) \
491         int do_test_##XFUNC(struct cmd_tbl *cmd_tbl, int flag, int argc, \
492         char *const argv[]) \
493         { \
494                 struct udevice *dev; \
495                 int ret; \
496 \
497                 ret = get_tpm(&dev); \
498                 if (ret) \
499                         return ret; \
500                 return test_##XFUNC(dev); \
501         }
502
503 #define VOIDENT(XNAME) \
504         U_BOOT_CMD_MKENT(XNAME, 0, 1, do_test_##XNAME, "", ""),
505
506 VOIDTEST(early_extend)
507 VOIDTEST(early_nvram)
508 VOIDTEST(early_nvram2)
509 VOIDTEST(enable)
510 VOIDTEST(fast_enable)
511 VOIDTEST(global_lock)
512 VOIDTEST(lock)
513 VOIDTEST(readonly)
514 VOIDTEST(redefine_unowned)
515 VOIDTEST(space_perm)
516 VOIDTEST(startup)
517 VOIDTEST(timing)
518 VOIDTEST(write_limit)
519 VOIDTEST(timer)
520
521 static struct cmd_tbl cmd_cros_tpm_sub[] = {
522         VOIDENT(early_extend)
523         VOIDENT(early_nvram)
524         VOIDENT(early_nvram2)
525         VOIDENT(enable)
526         VOIDENT(fast_enable)
527         VOIDENT(global_lock)
528         VOIDENT(lock)
529         VOIDENT(readonly)
530         VOIDENT(redefine_unowned)
531         VOIDENT(space_perm)
532         VOIDENT(startup)
533         VOIDENT(timing)
534         VOIDENT(write_limit)
535         VOIDENT(timer)
536 };
537
538 static int do_tpmtest(struct cmd_tbl *cmdtp, int flag, int argc,
539                       char *const argv[])
540 {
541         struct cmd_tbl *c;
542         int i;
543
544         printf("argc = %d, argv = ", argc);
545
546         for (i = 0; i < argc; i++)
547                 printf(" %s", argv[i]);
548
549         printf("\n------\n");
550
551         argc--;
552         argv++;
553         c = find_cmd_tbl(argv[0], cmd_cros_tpm_sub,
554                          ARRAY_SIZE(cmd_cros_tpm_sub));
555         return c ? c->cmd(cmdtp, flag, argc, argv) : cmd_usage(cmdtp);
556 }
557
558 U_BOOT_CMD(tpmtest, 2, 1, do_tpmtest, "TPM tests",
559         "\n\tearly_extend\n"
560         "\tearly_nvram\n"
561         "\tearly_nvram2\n"
562         "\tenable\n"
563         "\tfast_enable\n"
564         "\tglobal_lock\n"
565         "\tlock\n"
566         "\treadonly\n"
567         "\tredefine_unowned\n"
568         "\tspace_perm\n"
569         "\tstartup\n"
570         "\ttiming\n"
571         "\twrite_limit\n");