Upgrade Duplicate utility to the latest tss
[aaf/sshsm.git] / tpm-util / duplicate / main.c
1 /*
2  * Copyright 2018 Intel Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *     Unless required by applicable law or agreed to in writing, software
11  *     distributed under the License is distributed on an "AS IS" BASIS,
12  *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *     See the License for the specific language governing permissions and
14  *     limitations under the License.
15  */
16 //
17 // main.c : Tool to import Openssl RSA key into TPM. Generates TPM duplication data
18 // Author: Arun Kumar Sekar
19 //
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <openssl/pem.h>
26 #include <pthread.h>
27 #include <tss2/tss2-tcti-tabrmd.h>
28 #include <tss2/tss2_common.h>
29 #include <tss2/tss2_tpm2_types.h>
30 #include <tss2/tpm2b.h>
31 #include "tpm_duplication_aux.h"
32 #include "util.h"
33
34
35 void PrintHelp();
36 char version[] = "0.1";
37
38 void PrintHelp()
39 {
40     printf(
41             "OSSL key to tpm import tool, Version %s\nUsage:"
42             "./ossl_tpm_duplicate [-pemfile InputPemFile] [-pempwd inputPemPwd (optional)] [-parentPub inputParentPubFile]"
43             "[-dupPub out_dupPubFile] [-dupPriv out_dupPrivFile] [-dupSymSeed out_dupSymSeedFile] [-dupEncKey out_dupEncKeyFile] \n"
44                         "\n"
45                          , version);
46 }
47
48 static TPM2_RC convert_PEM_To_EVP(EVP_PKEY **evpPkey,                /* freed by caller */
49                               const char *pem_Filename,
50                               const char *pem_pwd)
51 {
52     TPM2_RC      rc = 0;
53     FILE        *fp_pemfile = NULL;
54
55     if (rc == 0)
56     {
57         fp_pemfile = fopen(pem_Filename, "rb");  /* closed @2 */
58         if(fp_pemfile == NULL) {
59             rc = EXIT_FAILURE;
60         }
61     }
62
63     if (rc == 0)
64     {
65         *evpPkey = PEM_read_PrivateKey(fp_pemfile, NULL, NULL, (void *)pem_pwd);
66         if (*evpPkey == NULL)
67         {
68             printf("convert_PEM_To_EVP: Error reading key file %s\n", pem_Filename);
69             rc = EXIT_FAILURE;
70         }
71         printf("PEM_read_PrivateKey success for file: %s \n", pem_Filename);
72     }
73
74 end:
75    if (fp_pemfile != NULL)
76     {
77         fclose(fp_pemfile);
78     }
79
80     return rc;
81 }
82
83 static TPM2_RC convert_EVP_to_RSA(RSA **rsaKey,              /* freed by caller */
84                               EVP_PKEY *evpPkey)
85 {
86     TPM2_RC      rc = 0;
87
88     if (rc == 0)
89     {
90         *rsaKey = EVP_PKEY_get1_RSA(evpPkey);
91         if (*rsaKey == NULL)
92         {
93             printf("convert_EVP_to_RSA: EVP_PKEY_get1_RSA failed\n");
94             rc = EXIT_FAILURE;
95         }
96         printf("convert_EVP_to_RSA success! \n");
97     }
98
99     return rc;
100 }
101
102
103 int main(int argc, char* argv[])
104 {
105     TPM2_RC rval = 0;
106     int count=0;
107
108     char pem_Filename[256];
109     int pemfile_flag = 0;
110     const char *pem_pwd = "";   /* default empty password */
111     int pempwd_flag = 0;
112
113     // SW Key Duplicate I/P variables
114     char parent_pub_Filename[256];
115     int parent_pub_flag = 0;
116
117     // SW Key Duplicate O/P variables
118     char dupPub_Filename[256];
119     int dupPub_flag = 0;
120     char dupPriv_Filename[256];
121     int dupPriv_flag = 0;
122     char dupSymSeed_Filename[256];
123     int dupSymSeed_flag = 0;
124     char dupEncKey_Filename[256];
125     int dupEncKey_flag = 0;
126     TPM2B encryptionKey;
127     TPM2B_PUBLIC swKeyPublic;
128     TPM2B_PRIVATE swKeyPrivate;
129     TPM2B_ENCRYPTED_SECRET encSymSeed;
130     unsigned short file_size = 0;
131     UINT8 policyDigest[32] = {0};
132     UINT32 digestSize = 0;
133
134     TPM2B_PUBLIC parentKeyPublicPortion;
135     int pubKeysize = 0;
136
137     // RSA key structures
138     EVP_PKEY    *evpPkey = NULL;
139     RSA         *rsaKey = NULL;
140
141     setbuf(stdout, NULL);
142     setvbuf (stdout, NULL, _IONBF, BUFSIZ);
143     if( (argc < 2) )
144     {
145         printf("Arguments count does not match \n");
146         PrintHelp();
147         return 1;
148     }
149     else
150     {
151         /* Get the argument values and evaluate it */
152         for( count = 1; count < argc; count++ )
153         {
154             if( 0 == strcmp( argv[count], "-pemfile" ) ) {
155                 count++;
156                 if( (1 != sscanf( argv[count], "%s", pem_Filename )) )
157                 {
158                     PrintHelp();
159                     return 1;
160                 }
161                 pemfile_flag = 1;
162             }
163             else if( 0 == strcmp( argv[count], "-pempwd" ) ) {
164                 count++;
165                 pem_pwd = argv[count];
166                 pempwd_flag = 1;
167             }
168             else if( 0 == strcmp( argv[count], "-parentPub" ) ) {
169                 count++;
170                 if( (1 != sscanf( argv[count], "%s", parent_pub_Filename )) )
171                 {
172                     PrintHelp();
173                     return 1;
174                 }
175                 parent_pub_flag = 1;
176             }
177             else if( 0 == strcmp( argv[count], "-dupPub" ) ) {
178                 count++;
179                 if( (1 != sscanf( argv[count], "%s", dupPub_Filename )) )
180                 {
181                     PrintHelp();
182                     return 1;
183                 }
184                 dupPub_flag = 1;
185             }
186             else if( 0 == strcmp( argv[count], "-dupPriv" ) ) {
187                 count++;
188                 if( (1 != sscanf( argv[count], "%s", dupPriv_Filename )) )
189                 {
190                     PrintHelp();
191                     return 1;
192                 }
193                 dupPriv_flag = 1;
194             }
195             else if( 0 == strcmp( argv[count], "-dupSymSeed" ) ) {
196                 count++;
197                 if( (1 != sscanf( argv[count], "%s", dupSymSeed_Filename )) )
198                 {
199                     PrintHelp();
200                     return 1;
201                 }
202                 dupSymSeed_flag = 1;
203             }
204             else if( 0 == strcmp( argv[count], "-dupEncKey" ) ) {
205                 count++;
206                 if( (1 != sscanf( argv[count], "%s", dupEncKey_Filename )) )
207                 {
208                     PrintHelp();
209                     return 1;
210                 }
211                 dupEncKey_flag = 1;
212             }
213             else if( 0 == strcmp( argv[count], "--help" ) ) {
214                 PrintHelp();
215                 exit(1);
216             }
217             else {
218                 PrintHelp();
219                 exit(1);
220             }
221         }
222     }
223
224     // For Duplicate functionality, check all input params are present
225     if( (!pemfile_flag) ||
226                 (!parent_pub_flag) ||
227                 (!dupPub_flag) ||
228                 (!dupPriv_flag) ||
229                 (!dupSymSeed_flag) ||
230                 (!dupEncKey_flag)
231             )
232     {
233         printf("Error: One or more Inputs for Duplicate are not passed as input \n");
234         return -1;
235     }
236
237     printf("Input PEM file name: %s \n", pem_Filename);
238
239     if (rval == 0) {
240         rval = convert_PEM_To_EVP(&evpPkey, pem_Filename, pem_pwd);
241     }
242     if (rval == 0) {
243         rval = convert_EVP_to_RSA(&rsaKey, evpPkey);
244     }
245
246     if ( rval == 0 )  {
247         file_size = sizeof(TPM2B_PUBLIC);
248         rval = loadDataFromFile(parent_pub_Filename, (UINT8 *) &parentKeyPublicPortion, &file_size);
249     }
250
251     /* SW key duplicate operation started */
252     if ( rval == 0 )  {
253         rval = swKeyDuplicate(rsaKey, &parentKeyPublicPortion, policyDigest, digestSize,
254                 &encryptionKey, &swKeyPublic, &swKeyPrivate, &encSymSeed);
255         if(rval != 0) {
256             printf("\nswKeyDuplicate failed: 0x%x ! \n", rval);
257             goto end;
258         }
259         else {
260             printf("\nswKeyDuplicate success: 0x%x ! \n", rval);
261             rval = saveDataToFile(dupPub_Filename, (UINT8 *) &swKeyPublic, sizeof(TPM2B_PUBLIC));
262             rval = saveDataToFile(dupPriv_Filename, (UINT8 *) &swKeyPrivate, sizeof(TPM2B_PRIVATE));
263             rval = saveDataToFile(dupSymSeed_Filename, (UINT8 *) &encSymSeed, sizeof(TPM2B_ENCRYPTED_SECRET));
264             rval = saveDataToFile(dupEncKey_Filename, (UINT8 *) &encryptionKey, sizeof(TPM2B_DATA));
265             printf("\nOutput files are written successfully ! \n");
266         }
267     }
268
269 end:
270     if (rsaKey != NULL) {
271         RSA_free(rsaKey);
272     }
273     if (evpPkey != NULL) {
274         EVP_PKEY_free(evpPkey);
275     }
276
277     return rval;
278 }
279