1 #ifdef HAVE_CONFIG_H
2 #include <config.h>
3 #endif
4 
5 #include <string.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <inttypes.h>
9 
10 #include "tss2_sys.h"
11 #include "tss2_mu.h"
12 
13 #define LOGMODULE test
14 #include "util/log.h"
15 #include "test-options.h"
16 #include "context-util.h"
17 
18 #define TAB_SIZE(x) (sizeof(x)/sizeof(x[0]))
19 
20 /* NOTE: CAP_PCRS and CAP_HANDLES->HR_PCR do not change until a reboot is
21   triggered. This should be improved if an approach is found. */
22 struct {
23     TPM2_CAP cap;
24     UINT32 prop;
25     UINT32 count;
26 } capabilities[] = {
27     { TPM2_CAP_PCRS, 0, 10 },
28     { TPM2_CAP_HANDLES, TPM2_HR_PCR, TPM2_MAX_CAP_HANDLES },
29     { TPM2_CAP_HANDLES, TPM2_HR_HMAC_SESSION, TPM2_MAX_CAP_HANDLES },
30     { TPM2_CAP_HANDLES, TPM2_HR_POLICY_SESSION, TPM2_MAX_CAP_HANDLES },
31     { TPM2_CAP_HANDLES, TPM2_HR_TRANSIENT, TPM2_MAX_CAP_HANDLES },
32     { TPM2_CAP_HANDLES, TPM2_HR_PERSISTENT, TPM2_MAX_CAP_HANDLES },
33     { TPM2_CAP_HANDLES, TPM2_HR_NV_INDEX, TPM2_MAX_CAP_HANDLES },
34 };
35 
36 int
main(int argc,char * argv[])37 main (int argc, char *argv[])
38 {
39     TSS2_RC rc;
40     TSS2_SYS_CONTEXT *sys_context;
41     TSS2L_SYS_AUTH_COMMAND auth_cmd = {
42         .auths = {{ .sessionHandle = TPM2_RS_PW }},
43         .count = 1
44     };
45     TPMI_RH_NV_INDEX nvIndex;
46 
47     if (argv[1])
48         nvIndex = strtol(argv[1], NULL, 16);
49     else
50         nvIndex = 0x01c00002;
51 
52     TPM2B_AUTH nv_auth = { 0 };
53     TPM2B_NV_PUBLIC public_info = {
54         .nvPublic = {
55             .nameAlg = TPM2_ALG_SHA1,
56             .attributes = TPMA_NV_PPWRITE | TPMA_NV_AUTHREAD | TPMA_NV_OWNERREAD |
57                 TPMA_NV_PLATFORMCREATE | TPMA_NV_NO_DA,
58             .dataSize = 0,
59             .nvIndex = nvIndex,
60         },
61     };
62 
63     TSS2L_SYS_AUTH_RESPONSE auth_rsp = {
64         .count = 0
65     };
66     TPM2B_MAX_NV_BUFFER buf1 = { 0 };
67     TPM2B_MAX_NV_BUFFER buf2 = { 0 };
68 
69     buf1.size += fread(&buf1.buffer[buf1.size], sizeof(buf1.buffer[0]),
70                        sizeof(buf1.buffer) - buf1.size, stdin);
71     if (buf1.size >= sizeof(buf1.buffer)) {
72         LOG_ERROR("input to large");
73         exit(1);
74     }
75 
76     test_opts_t opts = {
77         .tcti_type      = TCTI_DEFAULT,
78         .device_file    = DEVICE_PATH_DEFAULT,
79         .socket_address = HOSTNAME_DEFAULT,
80         .socket_port    = PORT_DEFAULT,
81     };
82 
83     get_test_opts_from_env (&opts);
84     if (sanity_check_test_opts (&opts) != 0)
85         exit (1);
86 
87     sys_context = sys_init_from_opts (&opts);
88     if (sys_context == NULL)
89         exit (1);
90 
91     /* First make sure that not EK certificate is currently loaded */
92     LOG_WARNING("Cert input size is %"PRIu16, buf1.size);
93     public_info.nvPublic.dataSize = buf1.size;
94 
95     LOG_WARNING("Define NV cert with nv index: %x", public_info.nvPublic.nvIndex);
96 
97     rc = Tss2_Sys_NV_DefineSpace(sys_context, TPM2_RH_PLATFORM, &auth_cmd,
98                                  &nv_auth, &public_info, &auth_rsp);
99     if (rc != TSS2_RC_SUCCESS) {
100         LOG_ERROR("TPM NV DefineSpace FAILED: 0x%"PRIx32, rc);
101         exit(1);
102     }
103 
104     /* Split the input buffer into 2 chunks */
105     buf2.size = buf1.size;
106     buf1.size /= 2;
107     buf2.size -= buf1.size;
108     memcpy(&buf2.buffer[0], &buf1.buffer[buf1.size], buf2.size);
109 
110     rc = Tss2_Sys_NV_Write(sys_context, TPM2_RH_PLATFORM, nvIndex, &auth_cmd,
111                            &buf1, 0, &auth_rsp);
112     if (rc != TSS2_RC_SUCCESS) {
113         LOG_ERROR("TPM NV Write FAILED: 0x%"PRIx32, rc);
114         exit(1);
115     }
116 
117     rc = Tss2_Sys_NV_Write(sys_context, TPM2_RH_PLATFORM, nvIndex, &auth_cmd,
118                            &buf2, buf1.size, &auth_rsp);
119     if (rc != TSS2_RC_SUCCESS) {
120         LOG_ERROR("TPM NV Write FAILED: 0x%"PRIx32, rc);
121         exit(1);
122     }
123 
124     sys_teardown_full (sys_context);
125 
126     return 0;
127 }
128