662b9847bc6cf018668b59873bec5339cdbb939d
[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
26 #include <openssl/pem.h>
27
28 #include <pthread.h>
29
30 #include <sapi/tpm20.h>
31 #include <tcti/tcti_socket.h>
32
33 #include "tpm_duplication_aux.h"
34 #include "util.h"
35
36
37 void PrintHelp();
38 char version[] = "0.1";
39
40 void PrintHelp()
41 {
42     printf(
43             "OSSL key to tpm import tool, Version %s\nUsage:" 
44             "./ossl_tpm_duplicate [-pemfile InputPemFile] [-pempwd inputPemPwd (optional)] [-parentPub inputParentPubFile]" 
45             "[-dupPub out_dupPubFile] [-dupPriv out_dupPrivFile] [-dupSymSeed out_dupSymSeedFile] [-dupEncKey out_dupEncKeyFile] \n" 
46                         "\n"
47                          , version);
48 }
49
50 static TPM_RC convert_PEM_To_EVP(EVP_PKEY **evpPkey,                /* freed by caller */
51                               const char *pem_Filename,
52                               const char *pem_pwd)
53 {
54     TPM_RC      rc = 0;
55     FILE        *fp_pemfile = NULL;
56
57     if (rc == 0) 
58     {
59         fp_pemfile = fopen(pem_Filename, "rb");  /* closed @2 */
60         if(fp_pemfile == NULL) {
61             rc = EXIT_FAILURE;
62         }
63     }
64
65     if (rc == 0) 
66     {
67         *evpPkey = PEM_read_PrivateKey(fp_pemfile, NULL, NULL, (void *)pem_pwd);
68         if (*evpPkey == NULL) 
69         {
70             printf("convert_PEM_To_EVP: Error reading key file %s\n", pem_Filename);
71             rc = EXIT_FAILURE;
72         }
73         printf("PEM_read_PrivateKey success for file: %s \n", pem_Filename);
74     }
75
76 end: 
77    if (fp_pemfile != NULL) 
78     {
79         fclose(fp_pemfile);
80     }
81
82     return rc;
83 }
84
85 static TPM_RC convert_EVP_to_RSA(RSA **rsaKey,              /* freed by caller */
86                               EVP_PKEY *evpPkey)
87 {
88     TPM_RC      rc = 0;
89
90     if (rc == 0) 
91     {
92         *rsaKey = EVP_PKEY_get1_RSA(evpPkey);
93         if (*rsaKey == NULL) 
94         {
95             printf("convert_EVP_to_RSA: EVP_PKEY_get1_RSA failed\n");
96             rc = EXIT_FAILURE;
97         }
98         printf("convert_EVP_to_RSA success! \n");
99     }
100
101     return rc;
102 }
103
104
105 int main(int argc, char* argv[])
106 {
107     TPM_RC rval = 0;
108     int count=0;
109
110     char pem_Filename[256];
111     int pemfile_flag = 0;
112     const char *pem_pwd = "";   /* default empty password */
113     int pempwd_flag = 0;
114
115     // SW Key Duplicate I/P variables
116     char parent_pub_Filename[256];
117     int parent_pub_flag = 0;
118
119     // SW Key Duplicate O/P variables
120     char dupPub_Filename[256];
121     int dupPub_flag = 0;
122     char dupPriv_Filename[256];
123     int dupPriv_flag = 0;
124     char dupSymSeed_Filename[256];
125     int dupSymSeed_flag = 0;
126     char dupEncKey_Filename[256];
127     int dupEncKey_flag = 0;
128     TPM2B_DATA encryptionKey; 
129     TPM2B_PUBLIC swKeyPublic; 
130     TPM2B_PRIVATE swKeyPrivate; 
131     TPM2B_ENCRYPTED_SECRET encSymSeed; 
132     unsigned short file_size = 0;
133     UINT8 policyDigest[32] = {0};
134     UINT32 digestSize = 0;
135
136     TPM2B_PUBLIC parentKeyPublicPortion;
137     int pubKeysize = 0;
138
139     // RSA key structures
140     EVP_PKEY    *evpPkey = NULL;
141     RSA         *rsaKey = NULL;
142
143     setbuf(stdout, NULL);
144     setvbuf (stdout, NULL, _IONBF, BUFSIZ);
145     if( (argc < 2) )
146     {
147         printf("Arguments count does not match \n");
148         PrintHelp();
149         return 1;
150     }
151     else
152     {
153         /* Get the argument values and evaluate it */
154         for( count = 1; count < argc; count++ )
155         {
156             if( 0 == strcmp( argv[count], "-pemfile" ) ) {
157                 count++;
158                 if( (1 != sscanf( argv[count], "%s", pem_Filename )) )
159                 {
160                     PrintHelp();
161                     return 1;
162                 }
163                 pemfile_flag = 1;
164             }
165             else if( 0 == strcmp( argv[count], "-pempwd" ) ) {
166                 count++;
167                 pem_pwd = argv[count];
168                 pempwd_flag = 1;
169             }
170             else if( 0 == strcmp( argv[count], "-parentPub" ) ) {
171                 count++;
172                 if( (1 != sscanf( argv[count], "%s", parent_pub_Filename )) )
173                 {
174                     PrintHelp();
175                     return 1;
176                 }
177                 parent_pub_flag = 1;
178             }
179             else if( 0 == strcmp( argv[count], "-dupPub" ) ) {
180                 count++;
181                 if( (1 != sscanf( argv[count], "%s", dupPub_Filename )) )
182                 {
183                     PrintHelp();
184                     return 1;
185                 }
186                 dupPub_flag = 1;
187             }
188             else if( 0 == strcmp( argv[count], "-dupPriv" ) ) {
189                 count++;
190                 if( (1 != sscanf( argv[count], "%s", dupPriv_Filename )) )
191                 {
192                     PrintHelp();
193                     return 1;
194                 }
195                 dupPriv_flag = 1;
196             }
197             else if( 0 == strcmp( argv[count], "-dupSymSeed" ) ) {
198                 count++;
199                 if( (1 != sscanf( argv[count], "%s", dupSymSeed_Filename )) )
200                 {
201                     PrintHelp();
202                     return 1;
203                 }
204                 dupSymSeed_flag = 1;
205             }
206             else if( 0 == strcmp( argv[count], "-dupEncKey" ) ) {
207                 count++;
208                 if( (1 != sscanf( argv[count], "%s", dupEncKey_Filename )) )
209                 {
210                     PrintHelp();
211                     return 1;
212                 }
213                 dupEncKey_flag = 1;
214             }
215             else if( 0 == strcmp( argv[count], "--help" ) ) {
216                 PrintHelp();
217                 exit(1);
218             }
219             else {
220                 PrintHelp();
221                 exit(1);
222             }
223         }
224     }
225
226     // For Duplicate functionality, check all input params are present
227     if( (!pemfile_flag) || 
228                 (!parent_pub_flag) ||
229                 (!dupPub_flag) ||
230                 (!dupPriv_flag) ||
231                 (!dupSymSeed_flag) ||
232                 (!dupEncKey_flag)
233             ) 
234     {
235         printf("Error: One or more Inputs for Duplicate are not passed as input \n");
236         return -1;
237     }
238
239     printf("Input PEM file name: %s \n", pem_Filename);
240
241     if (rval == 0) {
242         rval = convert_PEM_To_EVP(&evpPkey, pem_Filename, pem_pwd);
243     }
244     if (rval == 0) {
245         rval = convert_EVP_to_RSA(&rsaKey, evpPkey);
246     }
247
248     if ( rval == 0 )  {
249         file_size = sizeof(TPM2B_PUBLIC);
250         rval = loadDataFromFile(parent_pub_Filename, (UINT8 *) &parentKeyPublicPortion, &file_size);
251     }
252
253     /* SW key duplicate operation started */
254     if ( rval == 0 )  {
255         rval = swKeyDuplicate(rsaKey, &parentKeyPublicPortion, policyDigest, digestSize, 
256                 &encryptionKey, &swKeyPublic, &swKeyPrivate, &encSymSeed);
257         if(rval != 0) {
258             printf("\nswKeyDuplicate failed: 0x%x ! \n", rval);
259             goto end;
260         }
261         else {
262             printf("\nswKeyDuplicate success: 0x%x ! \n", rval);
263             rval = saveDataToFile(dupPub_Filename, (UINT8 *) &swKeyPublic, sizeof(TPM2B_PUBLIC));
264             rval = saveDataToFile(dupPriv_Filename, (UINT8 *) &swKeyPrivate, sizeof(TPM2B_PRIVATE));
265             rval = saveDataToFile(dupSymSeed_Filename, (UINT8 *) &encSymSeed, sizeof(TPM2B_ENCRYPTED_SECRET));
266             rval = saveDataToFile(dupEncKey_Filename, (UINT8 *) &encryptionKey, sizeof(TPM2B_DATA));
267             printf("\nOutput files are written successfully ! \n");
268         }
269     }
270
271 end:
272     if (rsaKey != NULL) {
273         RSA_free(rsaKey);
274     }
275     if (evpPkey != NULL) {
276         EVP_PKEY_free(evpPkey);
277     }
278
279     return rval;
280 }
281