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 <openssl/evp.h>
12 #include <openssl/aes.h>
13 #include <openssl/rsa.h>
14 #include <openssl/engine.h>
15 #include <openssl/pem.h>
16 #include <stdio.h>
17 #include <stddef.h>
18 #include <string.h>
19 #include <inttypes.h>
20
21 #include "tss2_fapi.h"
22
23 #define LOGMODULE test
24 #include "util/log.h"
25 #include "util/aux_util.h"
26
27 /** Test the FAPI functions use an external public key for signature and quote verify without TPM.
28 *
29 * Tested FAPI commands:
30 * - Fapi_Import()
31 * - Fapi_VerifySignature()
32 * - Fapi_SetCertificate()
33 * - Fapi_GetCertificate()
34 * - Fapi_List()
35 * - Fapi_VerifyQuote()
36 * - Fapi_Delete()
37 *
38 * @param[in,out] context The FAPI_CONTEXT.
39 * @retval EXIT_FAILURE
40 * @retval EXIT_SUCCESS
41 */
42 int
test_fapi_ext_public_key(FAPI_CONTEXT * context)43 test_fapi_ext_public_key(FAPI_CONTEXT *context)
44 {
45
46 TSS2_RC r;
47 BIO *bufio = NULL;
48
49 EVP_PKEY *evp_key = NULL;
50 RSA *rsa_key = NULL;
51
52 /* Key will be used for non TPM signature verfication. */
53 char *pubkey_pem =
54 "-----BEGIN PUBLIC KEY-----\n"
55 "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUymzBzI3LcxRpqJkiP0Ks7qp1UZH\n"
56 "93mYpmfUJBjK6anQawTyy8k87MteUdP5IPy47gzsO7sFcbWCoVZ8LvoQUw==\n"
57 "-----END PUBLIC KEY-----\n";
58
59 /* Quote info will be used for non TPM signature verfication. */
60 const char *quote_info =
61 "{\n"
62 " \"sig_scheme\":{\n"
63 " \"scheme\":\"ECDSA\",\n"
64 " \"details\":{\n"
65 " \"hashAlg\":\"SHA256\"\n"
66 " }\n"
67 " },\n"
68 " \"attest\":{\n"
69 " \"magic\":\"VALUE\",\n"
70 " \"type\":\"ATTEST_QUOTE\",\n"
71 " \"qualifiedSigner\":\"000b6f2f5ee244f7af20dbdfdf0a7dd21ef28afd9c3f377758f9ace6e29e64fc0ccf\",\n"
72 " \"extraData\":\"6768033e216468247bd031a0a2d9876d79818f8f\",\n"
73 " \"clockInfo\":{\n"
74 " \"clock\":4607,\n"
75 " \"resetCount\":2327013047,\n"
76 " \"restartCount\":1164757112,\n"
77 " \"safe\":\"YES\"\n"
78 " },\n"
79 " \"firmwareVersion\":[\n"
80 " 635916457,\n"
81 " 1185938286\n"
82 " ],\n"
83 " \"attested\":{\n"
84 " \"pcrSelect\":[\n"
85 " {\n"
86 " \"hash\":\"SHA256\",\n"
87 " \"pcrSelect\":[\n"
88 " 16\n"
89 " ]\n"
90 " }\n"
91 " ],\n"
92 " \"pcrDigest\":\"224eb2f4e5625ecb4a31cb7df43282ef6293c97a840a33415a3afe069535fa9b\"\n"
93 " }\n"
94 " }\n"
95 "}\n";
96
97 /* Test signature will be used for non TPM signature verfication. */
98 size_t test_signature_size = 71;
99 const uint8_t test_signature[71] = {
100 0x30, 0x45, 0x02, 0x21, 0x00, 0x8a, 0x00, 0x01,
101 0x6b, 0x79, 0xe2, 0x50, 0x84, 0x52, 0xc3, 0x40,
102 0xbb, 0x6c, 0xb4, 0xcb, 0x31, 0x42, 0xa2, 0xe5,
103 0x8b, 0x36, 0x35, 0x46, 0x8d, 0x8c, 0x3e, 0x59,
104 0xda, 0x0e, 0x83, 0x7e, 0x3b, 0x02, 0x20, 0x77,
105 0xb1, 0xe6, 0xa8, 0xab, 0x0e, 0x5f, 0x72, 0x28,
106 0x3e, 0x35, 0xe5, 0x91, 0x5b, 0x13, 0x35, 0xfe,
107 0x44, 0x54, 0xa4, 0x79, 0x63, 0x2a, 0x94, 0xd5,
108 0xaa, 0x07, 0xce, 0xba, 0xc6, 0x56, 0x85
109 };
110
111 /* Qualifying data will be used for non TPM signature verfication. */
112 uint8_t qualifying_data[20] = {
113 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
114 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f
115 };
116
117 const char *pub_pem =
118 "-----BEGIN PUBLIC KEY-----\n"
119 "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoGL6IrCSAznmIIzBessI\n"
120 "mW7tPOUy78uWTIaub32KnYHn78KXprrZ3ykp6WDrOQeMjv4AA+14mJbg77apVYXy\n"
121 "EnkFdOMa1hszSJnp6cJvx7ILngLvFUxzbVki/ehvgS3nRk67Njal+nMTe8hpe3UK\n"
122 "QeV/Ij+F0r6Yz91W+4LPmncAiUesRZLetI2BZsKwHYRMznmpIYpoua1NtS8QpEXR\n"
123 "MmsUue19eS/XRAPmmCfnb5BX2Tn06iCpk6wO+RfMo9etcX5cLSAuIYEQYCvV2/0X\n"
124 "TfEw607vttBN0Y54LrVOKno1vRXd5sxyRlfB0WL42F4VG5TfcJo5u1Xq7k9m9K57\n"
125 "8wIDAQAB\n"
126 "-----END PUBLIC KEY-----\n";
127
128 const char *priv_pem =
129 "-----BEGIN PRIVATE KEY-----\n"
130 "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCgYvoisJIDOeYg\n"
131 "jMF6ywiZbu085TLvy5ZMhq5vfYqdgefvwpemutnfKSnpYOs5B4yO/gAD7XiYluDv\n"
132 "tqlVhfISeQV04xrWGzNImenpwm/HsgueAu8VTHNtWSL96G+BLedGTrs2NqX6cxN7\n"
133 "yGl7dQpB5X8iP4XSvpjP3Vb7gs+adwCJR6xFkt60jYFmwrAdhEzOeakhimi5rU21\n"
134 "LxCkRdEyaxS57X15L9dEA+aYJ+dvkFfZOfTqIKmTrA75F8yj161xflwtIC4hgRBg\n"
135 "K9Xb/RdN8TDrTu+20E3RjngutU4qejW9Fd3mzHJGV8HRYvjYXhUblN9wmjm7Veru\n"
136 "T2b0rnvzAgMBAAECggEBAIwHvoJ5DRJ6A50Zp3dROxHTEphfOEi6xF/OGxBGWLbK\n"
137 "C7l+eS9d5gj8BJa5QsXI/IR/6X2EYQ1AdeV04oVD7CUKuqPiALU8jFrv3pV0aGm+\n"
138 "3nu37gv3crPe5jkvLeNoM4tkA/oCXom63SDuyoG6nxkHiSdatLlaJUse4em3vRAL\n"
139 "QivziZIMyswcleMe0xAoMi7LO+nUFFxBS8/xGya0vsU0dsMQEl1SRITv1VCXmPQD\n"
140 "T4dEI4+1cufv6Ax0EDbFKmnjyiGTjOeQKrGIqETUSQolbg5PgL1XZehaaxM822OY\n"
141 "Qpnp5T0XhUEmVrOb2Wrboj+dC/2tgAN/fWXjAAxnm2ECgYEA02UTZuZ+QnD6tqo3\n"
142 "/y3n5kaM9uA2mdOIqgECI9psGF1IBIC/iP2diKyuvmQL8hzymComb5YzZl3TOAga\n"
143 "WHQYbIeU3JhnYTG75/Dv5Zh32H4NjkIJHT2/8LUM25Ove9u6QAniVgIQpBZ47LjX\n"
144 "9jHjTYCW5n79qNSfu0egYJUvypECgYEAwjqWzzEINqnX/xIVCoB4XpuDuSdkM0JW\n"
145 "MZDIH9xHjZPp07/5XYEoITylk6Zwbh+djvWDNP4gzPtuK26VsqrNxoWMsFZeXn6U\n"
146 "xSOYL2UNCZiOgchdZCOr+6r8LRUuo8xHjbawVoJVK1+tZ2WsR3ilt3Gw34O8Z5ep\n"
147 "f4v7GOXw+EMCgYAUHjFrgJIRhqkFi0uK+HZyXtJ5iDsKBqyh6Tin6tiQtQfujcYs\n"
148 "pl5ArJZwvhq47vJTcud3hSbdHh7E3ViMhHfylDChkct833vPhgl+ozT8oHpvyG8P\n"
149 "nlnO8ZwIpZR0yCOAhrBImSe2RgE6HhlHb9X/ATbbNsizMZEGBLoJlwkWUQKBgQCy\n"
150 "4U7fh2LvJUF+82JZh7RUPZn1Pmg0JVZI0/TcEv37UEy77kR1b2xMIBTGhTVq1sc/\n"
151 "ULIEbkA7SR1P9sr7//8AZSMLjJ/hG2dcoMmabNCzE8O7l5MblRbh87nIs4d+57bG\n"
152 "t4h0RBi4l6eWYLdoI59L8fNaB3PPXIiIpZ0eczeZDQKBgQC2vuFYpUZqDb9CaJsn\n"
153 "Luee6P6n5v3ZBTAT4E+GG1kWS28BiebcCuLKNAY4ZtLo08ozaTWcMxooOTeka2ux\n"
154 "fQDE4M/LTNpam8QOJ2hqECF5a0uBYNcbmaGtfA9KwIgwCZZYuwb5IDq/DRPuR690\n"
155 "i8Kp6jR2wY0suObmZHKvbCB1Dw==\n"
156 "-----END PRIVATE KEY-----\n";
157
158 const char *cert =
159 "-----BEGIN CERTIFICATE-----\n"
160 "MIIDBjCCAe4CCQDcvXBOEVM0UTANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJE\n"
161 "RTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0\n"
162 "cyBQdHkgTHRkMB4XDTE5MDIyODEwNDkyM1oXDTM1MDgyNzEwNDkyM1owRTELMAkG\n"
163 "A1UEBhMCREUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0\n"
164 "IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n"
165 "AKBi+iKwkgM55iCMwXrLCJlu7TzlMu/LlkyGrm99ip2B5+/Cl6a62d8pKelg6zkH\n"
166 "jI7+AAPteJiW4O+2qVWF8hJ5BXTjGtYbM0iZ6enCb8eyC54C7xVMc21ZIv3ob4Et\n"
167 "50ZOuzY2pfpzE3vIaXt1CkHlfyI/hdK+mM/dVvuCz5p3AIlHrEWS3rSNgWbCsB2E\n"
168 "TM55qSGKaLmtTbUvEKRF0TJrFLntfXkv10QD5pgn52+QV9k59OogqZOsDvkXzKPX\n"
169 "rXF+XC0gLiGBEGAr1dv9F03xMOtO77bQTdGOeC61Tip6Nb0V3ebMckZXwdFi+Nhe\n"
170 "FRuU33CaObtV6u5PZvSue/MCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAcamUPe8I\n"
171 "nMOHcv9x5lVN1joihVRmKc0QqNLFc6XpJY8+U5rGkZvOcDe9Da8L97wDNXpKmU/q\n"
172 "pprj3rT8l3v0Z5xs8Vdr8lxS6T5NhqQV0UCsn1x14gZJcE48y9/LazYi6Zcar+BX\n"
173 "Am4vewAV3HmQ8X2EctsRhXe4wlAq4slIfEWaaofa8ai7BzO9KwpMLsGPWoNetkB9\n"
174 "19+SFt0lFFOj/6vDw5pCpSd1nQlo1ug69mJYSX/wcGkV4t4LfGhV8jRPDsGs6I5n\n"
175 "ETHSN5KV1XCPYJmRCjFY7sIt1x4zN7JJRO9DVw+YheIlduVfkBiF+GlQgLlFTjrJ\n"
176 "VrpSGMIFSu301A==\n"
177 "-----END CERTIFICATE-----\n";
178
179 char *cert2 = NULL;
180 char *path_list = NULL;
181
182 r = Fapi_Import(context, "myExtPubKey", pub_pem);
183 goto_if_error(r, "Error Fapi_Import", error);
184
185 bufio = BIO_new_mem_buf((void *)priv_pem, strlen(priv_pem));
186 evp_key = PEM_read_bio_PrivateKey(bufio, NULL, NULL, NULL);
187 rsa_key = EVP_PKEY_get1_RSA(evp_key);
188
189
190 if (!bufio || !evp_key || !rsa_key) {
191 LOG_ERROR("Generation of test key failed.");
192 goto error;
193 }
194
195 uint8_t digest[20] = {
196 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e,
197 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d
198 };
199 uint8_t signature[256];
200 unsigned int signatureLength = 256;
201
202 if (!RSA_sign(NID_sha1, digest, 20, signature, &signatureLength, rsa_key)) {
203 LOG_ERROR("Test RSA_sign failed.");
204 goto error;
205 }
206
207 r = Fapi_VerifySignature(context, "/ext/myExtPubKey", digest, 20,
208 signature, 256);
209 goto_if_error(r, "Error Fapi_VerifySignature", error);
210
211 r = Fapi_SetCertificate(context, "/ext/myExtPubKey", cert);
212 goto_if_error(r, "Error Fapi_SetCertificate", error);
213
214 r = Fapi_GetCertificate(context, "/ext/myExtPubKey", &cert2);
215 goto_if_error(r, "Error Fapi_SetCertificate", error);
216
217 if (strcmp(cert, cert2) != 0) {
218 goto_if_error(r, "Different certificates", error);
219 }
220
221 r = Fapi_List(context, "", &path_list);
222 goto_if_error(r, "Error Fapi_List", error);
223
224 /* Test VerfiyQuote in non TPM mode. */
225 r = Fapi_Import(context, "/ext/myExtPubKey", pubkey_pem);
226 goto_if_error(r, "Error Fapi_Import", error);
227
228 r = Fapi_VerifyQuote(context, "/ext/myExtPubKey",
229 qualifying_data, 20, quote_info,
230 test_signature, test_signature_size, NULL);
231 goto_if_error(r, "Error Fapi_Verfiy_Quote", error);
232
233 fprintf(stderr, "\nPathList:\n%s\n", path_list);
234
235 r = Fapi_Delete(context, "/ext");
236 goto_if_error(r, "Error Fapi_Delete", error);
237 if (bufio) {
238 BIO_free(bufio);
239 }
240 if (evp_key) {
241 EVP_PKEY_free(evp_key);
242 }
243 if (rsa_key) {
244 RSA_free(rsa_key);
245 }
246 SAFE_FREE(path_list);
247 SAFE_FREE(cert2);
248 return EXIT_SUCCESS;
249
250 error:
251 Fapi_Delete(context, "/");
252 if (bufio) {
253 BIO_free(bufio);
254 }
255 if (evp_key) {
256 EVP_PKEY_free(evp_key);
257 }
258 if (rsa_key) {
259 RSA_free(rsa_key);
260 }
261 SAFE_FREE(path_list);
262 SAFE_FREE(cert2);
263 return EXIT_FAILURE;
264 }
265
266 int
test_invoke_fapi(FAPI_CONTEXT * fapi_context)267 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
268 {
269 return test_fapi_ext_public_key(fapi_context);
270 }
271