1 #ifdef HAVE_CONFIG_H
2 #include <config.h>
3 #endif
4 
5 #include <stdbool.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <inttypes.h>
9 #include <openssl/evp.h>
10 #include <openssl/rsa.h>
11 #include <openssl/pem.h>
12 #include <openssl/err.h>
13 #include <string.h>
14 
15 #include "tss2_sys.h"
16 #include "tss2_mu.h"
17 
18 #define LOGMODULE test
19 #include "util/log.h"
20 #include "test-options.h"
21 #include "context-util.h"
22 
handleErrors(void)23 void handleErrors(void)
24 {
25     unsigned long errCode;
26 
27     printf("An error occurred\n");
28     while((errCode = ERR_get_error()))
29     {
30         char *err = ERR_error_string(errCode, NULL);
31         printf("%s\n", err);
32     }
33     abort();
34 }
35 
36 int
main(int argc,char * argv[])37 main (int argc, char *argv[])
38 {
39     TSS2_RC rc;
40     TSS2_SYS_CONTEXT *sapi_context;
41     TSS2L_SYS_AUTH_COMMAND auth_cmd = {
42         .auths = {{ .sessionHandle = TPM2_RS_PW }},
43         .count = 1
44     };
45     TPM2B_SENSITIVE_CREATE in_sensitive = { 0 };
46     TPM2B_PUBLIC in_public = {
47         .publicArea = {
48             .type = TPM2_ALG_ECC,
49             .nameAlg = TPM2_ALG_SHA256,
50             .objectAttributes = (
51                                  TPMA_OBJECT_FIXEDTPM |
52                                  TPMA_OBJECT_FIXEDPARENT |
53                                  TPMA_OBJECT_SENSITIVEDATAORIGIN |
54                                  TPMA_OBJECT_ADMINWITHPOLICY |
55                                  TPMA_OBJECT_RESTRICTED |
56                                  TPMA_OBJECT_DECRYPT
57                                  ),
58             .authPolicy = {
59                 .size = 32,
60                 .buffer = 0x83, 0x71, 0x97, 0x67, 0x44, 0x84,
61                 0xB3, 0xF8, 0x1A, 0x90, 0xCC, 0x8D,
62                 0x46, 0xA5, 0xD7, 0x24, 0xFD, 0x52,
63                 0xD7, 0x6E, 0x06, 0x52, 0x0B, 0x64,
64                 0xF2, 0xA1, 0xDA, 0x1B, 0x33, 0x14,
65                 0x69, 0xAA,
66             },
67             .parameters.eccDetail = {
68                 .symmetric = {
69                     .algorithm = TPM2_ALG_AES,
70                     .keyBits.aes = 128,
71                     .mode.aes = TPM2_ALG_CFB,
72                 },
73                 .scheme = {
74                     .scheme = TPM2_ALG_NULL,
75                     .details = { 0 }
76                 },
77                 .curveID = TPM2_ECC_NIST_P256,
78                 .kdf = {.scheme = TPM2_ALG_NULL,
79                         .details = { 0 }
80                 }
81             },
82             .unique.ecc = {
83                 .x = {.size = 32,.buffer = { 0 }},
84                 .y = {.size = 32,.buffer = { 0 }}
85             }
86         }
87     };
88     TPML_PCR_SELECTION creation_pcr = { 0 };
89     TPM2_HANDLE handle;
90     TPM2B_PUBLIC out_public = { 0 };
91     TSS2L_SYS_AUTH_RESPONSE auth_rsp = {
92         .count = 0
93     };
94 
95     test_opts_t opts = {
96         .tcti_type      = TCTI_DEFAULT,
97         .device_file    = DEVICE_PATH_DEFAULT,
98         .socket_address = HOSTNAME_DEFAULT,
99         .socket_port    = PORT_DEFAULT,
100     };
101 
102     get_test_opts_from_env (&opts);
103     if (sanity_check_test_opts (&opts) != 0)
104         exit (1);
105 
106     sapi_context = sapi_init_from_opts (&opts);
107     if (sapi_context == NULL)
108         exit (1);
109 
110     /* Generate the EK key */
111 
112     rc = Tss2_Sys_CreatePrimary(sapi_context, TPM2_RH_ENDORSEMENT, &auth_cmd,
113                                 &in_sensitive, &in_public, NULL, &creation_pcr,
114                                 &handle, &out_public, NULL, NULL, NULL, NULL, &auth_rsp);
115     if (rc != TSS2_RC_SUCCESS) {
116         LOG_ERROR("TPM CreatePrimary FAILED: 0x%"PRIx32, rc);
117         exit(1);
118     }
119 
120     rc = Tss2_Sys_FlushContext(sapi_context, handle);
121     if (rc != TSS2_RC_SUCCESS) {
122         LOG_ERROR("TPM FlushContext FAILED: 0x%"PRIx32, rc);
123         exit(1);
124     }
125 
126     sapi_teardown_full (sapi_context);
127 
128     /* Convert the key from out_public to PEM */
129 
130     EVP_PKEY *evp = EVP_PKEY_new();
131 
132     OpenSSL_add_all_algorithms();
133 
134     OpenSSL_add_all_algorithms();
135 
136     ERR_load_crypto_strings();
137 
138 
139     EC_KEY *ecc_key = EC_KEY_new();
140     BIGNUM *x = NULL, *y = NULL;
141     BIO *bio = BIO_new_fp(stdout, BIO_NOCLOSE);
142     int nid;
143 
144     nid = EC_curve_nist2nid("P-256");
145     EC_GROUP *ecgroup = EC_GROUP_new_by_curve_name(nid);
146 
147     if (!EC_KEY_set_group(ecc_key, ecgroup))
148         exit(1);
149 
150     EC_KEY_set_asn1_flag(ecc_key, OPENSSL_EC_NAMED_CURVE);
151     EC_GROUP_free(ecgroup);
152 
153     /* Set the ECC parameters in the OpenSSL key */
154     x = BN_bin2bn(out_public.publicArea.unique.ecc.x.buffer,
155                   out_public.publicArea.unique.ecc.x.size, NULL);
156 
157     y = BN_bin2bn(out_public.publicArea.unique.ecc.y.buffer,
158                   out_public.publicArea.unique.ecc.y.size, NULL);
159 
160     if (!x || !y) {
161         exit(1);
162     }
163 
164     if (!EC_KEY_set_public_key_affine_coordinates(ecc_key, x, y)) {
165         exit(1);
166     }
167 
168     if (!EVP_PKEY_assign_EC_KEY(evp, ecc_key)) {
169         handleErrors();
170         LOG_ERROR("PEM_write failed");
171         exit(1);
172     }
173 
174     if (!PEM_write_bio_PUBKEY(bio, evp)) {
175         handleErrors();
176         LOG_ERROR("PEM_write failed");
177         exit(1);
178     }
179 
180     BN_free(y);
181     BN_free(x);
182     EVP_PKEY_free(evp);
183     BIO_free(bio);
184 
185     return 0;
186 }
187