1 /* SPDX-License-Identifier: BSD-2-Clause */
2 #ifdef HAVE_CONFIG_H
3 #include <config.h>
4 #endif
5 
6 #include <stdlib.h>
7 
8 #include "tss2_esys.h"
9 
10 #include "esys_iutil.h"
11 #define LOGMODULE test
12 #include "util/log.h"
13 #include "util/aux_util.h"
14 
15 /** This tests the Esys_TR_ToTPMPublic function by
16  *  creating a Primary Object Key and then attempting to retrieve
17  *  the TPM2_HANDLE for it and validating that the handle is correct for the
18  *  expected object type.
19  *
20  * Tested ESYS commands:
21  *  - Esys_CreatePrimary() (M)
22  *  - Esys_EvictControl() (M)
23  *  - Esys_FlushContext() (M)
24  *  - Esys_TR_ToTPMPublic() (M)
25  *
26  * @param[in,out] ectx The ESYS_CONTEXT.
27  * @retval EXIT_FAILURE
28  * @retval EXIT_SUCCESS
29  */
30 
31 int
test_esys_tr_toTpmPublic_key(ESYS_CONTEXT * ectx)32 test_esys_tr_toTpmPublic_key(ESYS_CONTEXT * ectx)
33 {
34     int rc = EXIT_FAILURE;
35 
36     TSS2_RC r;
37     ESYS_TR primaryHandle = ESYS_TR_NONE;
38     ESYS_TR keyHandle = ESYS_TR_NONE;
39 
40     TPM2B_AUTH authValuePrimary = {
41         .size = 5,
42         .buffer = {1, 2, 3, 4, 5}
43     };
44 
45     TPM2B_SENSITIVE_CREATE inSensitivePrimary = {
46         .size = 0,
47         .sensitive = {
48             .userAuth = {
49                  .size = 0,
50                  .buffer = {0 },
51              },
52             .data = {
53                  .size = 0,
54                  .buffer = {0},
55              },
56         },
57     };
58 
59     inSensitivePrimary.sensitive.userAuth = authValuePrimary;
60 
61     TPM2B_PUBLIC inPublic = {
62         .size = 0,
63         .publicArea = {
64             .type = TPM2_ALG_RSA,
65             .nameAlg = TPM2_ALG_SHA256,
66             .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
67                                  TPMA_OBJECT_RESTRICTED |
68                                  TPMA_OBJECT_DECRYPT |
69                                  TPMA_OBJECT_FIXEDTPM |
70                                  TPMA_OBJECT_FIXEDPARENT |
71                                  TPMA_OBJECT_SENSITIVEDATAORIGIN),
72             .authPolicy = {
73                  .size = 0,
74              },
75             .parameters.rsaDetail = {
76                  .symmetric = {
77                      .algorithm = TPM2_ALG_AES,
78                      .keyBits.aes = 128,
79                      .mode.aes = TPM2_ALG_CFB},
80                  .scheme = {
81                       .scheme = TPM2_ALG_NULL
82                   },
83                  .keyBits = 2048,
84                  .exponent = 0,
85              },
86             .unique.rsa = {
87                  .size = 0,
88                  .buffer = {},
89              },
90         },
91     };
92     LOG_INFO("\nRSA key will be created.");
93 
94     TPM2B_DATA outsideInfo = {
95         .size = 0,
96         .buffer = {},
97     };
98 
99     TPML_PCR_SELECTION creationPCR = {
100         .count = 0,
101     };
102 
103     /* create a key */
104     r = Esys_CreatePrimary(ectx, ESYS_TR_RH_OWNER,
105                            ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
106                            &inSensitivePrimary, &inPublic, &outsideInfo,
107                            &creationPCR,
108                            &primaryHandle, NULL, NULL, NULL, NULL);
109     goto_if_error(r, "Create primary", out);
110 
111     /* the handle should be transient */
112     TPM2_HANDLE tpmHandle = ESYS_TR_NONE;
113     r = Esys_TR_GetTpmHandle(ectx, primaryHandle, &tpmHandle);
114     goto_if_error(r, "Esys_TR_ToTPMPublic", error);
115 
116     if (!(tpmHandle & TPM2_HR_TRANSIENT)) {
117         LOG_ERROR("Retrieved handle should be transient, got: 0x%x", tpmHandle);
118         goto error;
119     }
120 
121     /* make it persistent */
122     r = Esys_EvictControl(ectx, ESYS_TR_RH_OWNER, primaryHandle,
123                           ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
124                           TPM2_PERSISTENT_FIRST, &keyHandle);
125     goto_if_error(r, "EvictControl make persistent", error);
126 
127     /* handle should be persistent */
128     r = Esys_TR_GetTpmHandle(ectx, keyHandle, &tpmHandle);
129     goto_if_error(r, "Esys_TR_ToTPMPublic", error);
130 
131     if (!(tpmHandle & TPM2_HR_PERSISTENT)) {
132         LOG_ERROR("Retrieved handle should be transient, got: 0x%x", tpmHandle);
133         goto error;
134     }
135 
136     rc = EXIT_SUCCESS;
137 
138 error:
139     r = Esys_FlushContext(ectx, primaryHandle);
140     if (r != TSS2_RC_SUCCESS) {
141         rc = EXIT_FAILURE;
142         LOG_ERROR("TR close on key object");
143     }
144 
145     r = Esys_EvictControl(ectx, ESYS_TR_RH_OWNER, keyHandle,
146                           ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
147                           TPM2_PERSISTENT_FIRST, &keyHandle);
148     if (r != TSS2_RC_SUCCESS) {
149         rc = EXIT_FAILURE;
150         LOG_ERROR("Esys_EvictControl");
151     }
152 
153 out:
154     return rc;
155 }
156 
157 int
test_invoke_esys(ESYS_CONTEXT * esys_context)158 test_invoke_esys(ESYS_CONTEXT * esys_context) {
159     return test_esys_tr_toTpmPublic_key(esys_context);
160 }
161