1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*******************************************************************************
3 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
4 * All rights reserved.
5 *******************************************************************************/
6
7 #ifdef HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10
11 #include <stdlib.h>
12
13 #include "tss2_esys.h"
14
15 #include "esys_iutil.h"
16 #define LOGMODULE test
17 #include "util/log.h"
18 #include "util/aux_util.h"
19
20 /** This test is intended to test RSA encryption / decryption.
21 * with password
22 * authentication.
23 * We create a RSA primary key (Esys_CreatePrimary) for every crypto action
24 * This key will be used for encryption/decryption in with the schemes:
25 * TPM2_ALG_NULL, TPM2_ALG_RSAES, and TPM2_ALG_OAEP
26 *
27 * Tested ESAPI commands:
28 * - Esys_CreatePrimary() (M)
29 * - Esys_FlushContext() (M)
30 * - Esys_RSA_Decrypt() (M)
31 * - Esys_RSA_Encrypt() (M)
32 *
33 * @param[in,out] esys_context The ESYS_CONTEXT.
34 * @retval EXIT_FAILURE
35 * @retval EXIT_SUCCESS
36 */
37
38 int
test_esys_rsa_encrypt_decrypt(ESYS_CONTEXT * esys_context)39 test_esys_rsa_encrypt_decrypt(ESYS_CONTEXT * esys_context)
40 {
41 TSS2_RC r;
42 ESYS_TR primaryHandle = ESYS_TR_NONE;
43
44 TPM2B_PUBLIC *outPublic = NULL;
45 TPM2B_CREATION_DATA *creationData = NULL;
46 TPM2B_DIGEST *creationHash = NULL;
47 TPMT_TK_CREATION *creationTicket = NULL;
48 TPM2B_PUBLIC_KEY_RSA *cipher = NULL;
49 TPM2B_PUBLIC_KEY_RSA *plain2 = NULL;
50 TPM2B_DATA * null_data = NULL;
51
52 TPM2B_AUTH authValuePrimary = {
53 .size = 5,
54 .buffer = {1, 2, 3, 4, 5}
55 };
56
57 TPM2B_SENSITIVE_CREATE inSensitivePrimary = {
58 .size = 0,
59 .sensitive = {
60 .userAuth = {
61 .size = 0,
62 .buffer = {0},
63 },
64 .data = {
65 .size = 0,
66 .buffer = {0},
67 },
68 },
69 };
70
71 inSensitivePrimary.sensitive.userAuth = authValuePrimary;
72
73 TPM2B_PUBLIC inPublic = {
74 .size = 0,
75 .publicArea = {
76 .type = TPM2_ALG_RSA,
77 .nameAlg = TPM2_ALG_SHA1,
78 .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
79 TPMA_OBJECT_DECRYPT |
80 TPMA_OBJECT_FIXEDTPM |
81 TPMA_OBJECT_FIXEDPARENT |
82 TPMA_OBJECT_SENSITIVEDATAORIGIN),
83 .authPolicy = {
84 .size = 0,
85 },
86 .parameters.rsaDetail = {
87 .symmetric = {
88 .algorithm = TPM2_ALG_NULL},
89 .scheme = { .scheme = TPM2_ALG_RSAES },
90 .keyBits = 2048,
91 .exponent = 0,
92 },
93 .unique.rsa = {
94 .size = 0,
95 .buffer = {},
96 },
97 },
98 };
99
100 LOG_INFO("\nRSA key will be created.");
101
102 TPM2B_DATA outsideInfo = {
103 .size = 0,
104 .buffer = {},
105 };
106
107 TPML_PCR_SELECTION creationPCR = {
108 .count = 0,
109 };
110
111 TPM2B_AUTH authValue = {
112 .size = 0,
113 .buffer = {}
114 };
115
116 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
117 goto_if_error(r, "Error: TR_SetAuth", error);
118
119 RSRC_NODE_T *primaryHandle_node;
120
121 for (int mode = 0; mode <= 2; mode++) {
122
123 if (mode == 0) {
124 inPublic.publicArea.parameters.rsaDetail.scheme.scheme =
125 TPM2_ALG_NULL;
126 } else if (mode == 1) {
127 inPublic.publicArea.parameters.rsaDetail.scheme.scheme =
128 TPM2_ALG_RSAES;
129 } else if (mode == 2) {
130 inPublic.publicArea.parameters.rsaDetail.scheme.scheme =
131 TPM2_ALG_OAEP;
132 inPublic.publicArea.parameters.rsaDetail.scheme.details.oaep.
133 hashAlg = TPM2_ALG_SHA1;
134 }
135
136 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
137 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary,
138 &inPublic, &outsideInfo, &creationPCR,
139 &primaryHandle, &outPublic, &creationData,
140 &creationHash, &creationTicket);
141 goto_if_error(r, "Error esys create primary", error);
142 Esys_Free(outPublic);
143 Esys_Free(creationData);
144 Esys_Free(creationHash);
145 Esys_Free(creationTicket);
146
147 r = esys_GetResourceObject(esys_context, primaryHandle,
148 &primaryHandle_node);
149 goto_if_error(r, "Error Esys GetResourceObject", error);
150
151 LOG_INFO("Created Primary with handle 0x%08x...",
152 primaryHandle_node->rsrc.handle);
153
154 r = Esys_TR_SetAuth(esys_context, primaryHandle,
155 &authValuePrimary);
156 goto_if_error(r, "Error: TR_SetAuth", error);
157
158 size_t plain_size = 3;
159 TPM2B_PUBLIC_KEY_RSA plain = {.size = plain_size,.buffer = {1, 2, 3}
160 };
161 TPMT_RSA_DECRYPT scheme;
162
163 if (mode == 0) {
164 scheme.scheme = TPM2_ALG_NULL;
165 } else if (mode == 1) {
166 scheme.scheme = TPM2_ALG_RSAES;
167 } else if (mode == 2) {
168 scheme.scheme = TPM2_ALG_OAEP;
169 scheme.details.oaep.hashAlg = TPM2_ALG_SHA1;
170 }
171 r = Esys_RSA_Encrypt(esys_context, primaryHandle, ESYS_TR_NONE,
172 ESYS_TR_NONE, ESYS_TR_NONE, &plain, &scheme,
173 null_data, &cipher);
174 goto_if_error(r, "Error esys rsa encrypt", error);
175
176 Esys_Free(null_data);
177
178 r = Esys_RSA_Decrypt(esys_context, primaryHandle,
179 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
180 cipher, &scheme, null_data, &plain2);
181 goto_if_error(r, "Error esys rsa decrypt", error);
182
183 Esys_Free(null_data);
184 Esys_Free(cipher);
185
186 if (mode > 0 && memcmp(&plain.buffer[0], &plain2->buffer[0], plain_size)) {
187 LOG_ERROR("plain texts are not equal for mode %i", mode);
188 goto error;
189 }
190
191 r = Esys_FlushContext(esys_context, primaryHandle);
192 goto_if_error(r, "Error: FlushContext", error);
193 Esys_Free(plain2);
194 }
195
196 return EXIT_SUCCESS;
197
198 error:
199
200 if (primaryHandle != ESYS_TR_NONE) {
201 if (Esys_FlushContext(esys_context, primaryHandle) != TSS2_RC_SUCCESS) {
202 LOG_ERROR("Cleanup primaryHandle failed.");
203 }
204 }
205
206 Esys_Free(outPublic);
207 Esys_Free(creationData);
208 Esys_Free(creationHash);
209 Esys_Free(creationTicket);
210 Esys_Free(cipher);
211 Esys_Free(plain2);
212 Esys_Free(null_data);
213 return EXIT_FAILURE;
214 }
215
216 int
test_invoke_esapi(ESYS_CONTEXT * esys_context)217 test_invoke_esapi(ESYS_CONTEXT * esys_context) {
218 return test_esys_rsa_encrypt_decrypt(esys_context);
219 }
220