2 * Copyright 2018 Intel Corporation
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 // main.c : Tool to import Openssl RSA key into TPM. Generates TPM duplication data
18 // Author: Arun Kumar Sekar
25 #include <openssl/pem.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"
36 char version[] = "0.1";
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"
48 static TPM2_RC convert_PEM_To_EVP(EVP_PKEY **evpPkey, /* freed by caller */
49 const char *pem_Filename,
53 FILE *fp_pemfile = NULL;
57 fp_pemfile = fopen(pem_Filename, "rb"); /* closed @2 */
58 if(fp_pemfile == NULL) {
65 *evpPkey = PEM_read_PrivateKey(fp_pemfile, NULL, NULL, (void *)pem_pwd);
68 printf("convert_PEM_To_EVP: Error reading key file %s\n", pem_Filename);
71 printf("PEM_read_PrivateKey success for file: %s \n", pem_Filename);
75 if (fp_pemfile != NULL)
83 static TPM2_RC convert_EVP_to_RSA(RSA **rsaKey, /* freed by caller */
90 *rsaKey = EVP_PKEY_get1_RSA(evpPkey);
93 printf("convert_EVP_to_RSA: EVP_PKEY_get1_RSA failed\n");
96 printf("convert_EVP_to_RSA success! \n");
103 int main(int argc, char* argv[])
108 char pem_Filename[256];
109 int pemfile_flag = 0;
110 const char *pem_pwd = ""; /* default empty password */
113 // SW Key Duplicate I/P variables
114 char parent_pub_Filename[256];
115 int parent_pub_flag = 0;
117 // SW Key Duplicate O/P variables
118 char dupPub_Filename[256];
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;
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;
134 TPM2B_PUBLIC parentKeyPublicPortion;
137 // RSA key structures
138 EVP_PKEY *evpPkey = NULL;
141 setbuf(stdout, NULL);
142 setvbuf (stdout, NULL, _IONBF, BUFSIZ);
145 printf("Arguments count does not match \n");
151 /* Get the argument values and evaluate it */
152 for( count = 1; count < argc; count++ )
154 if( 0 == strcmp( argv[count], "-pemfile" ) ) {
156 if( (1 != sscanf( argv[count], "%s", pem_Filename )) )
163 else if( 0 == strcmp( argv[count], "-pempwd" ) ) {
165 pem_pwd = argv[count];
168 else if( 0 == strcmp( argv[count], "-parentPub" ) ) {
170 if( (1 != sscanf( argv[count], "%s", parent_pub_Filename )) )
177 else if( 0 == strcmp( argv[count], "-dupPub" ) ) {
179 if( (1 != sscanf( argv[count], "%s", dupPub_Filename )) )
186 else if( 0 == strcmp( argv[count], "-dupPriv" ) ) {
188 if( (1 != sscanf( argv[count], "%s", dupPriv_Filename )) )
195 else if( 0 == strcmp( argv[count], "-dupSymSeed" ) ) {
197 if( (1 != sscanf( argv[count], "%s", dupSymSeed_Filename )) )
204 else if( 0 == strcmp( argv[count], "-dupEncKey" ) ) {
206 if( (1 != sscanf( argv[count], "%s", dupEncKey_Filename )) )
213 else if( 0 == strcmp( argv[count], "--help" ) ) {
224 // For Duplicate functionality, check all input params are present
225 if( (!pemfile_flag) ||
226 (!parent_pub_flag) ||
229 (!dupSymSeed_flag) ||
233 printf("Error: One or more Inputs for Duplicate are not passed as input \n");
237 printf("Input PEM file name: %s \n", pem_Filename);
240 rval = convert_PEM_To_EVP(&evpPkey, pem_Filename, pem_pwd);
243 rval = convert_EVP_to_RSA(&rsaKey, evpPkey);
247 file_size = sizeof(TPM2B_PUBLIC);
248 rval = loadDataFromFile(parent_pub_Filename, (UINT8 *) &parentKeyPublicPortion, &file_size);
251 /* SW key duplicate operation started */
253 rval = swKeyDuplicate(rsaKey, &parentKeyPublicPortion, policyDigest, digestSize,
254 &encryptionKey, &swKeyPublic, &swKeyPrivate, &encSymSeed);
256 printf("\nswKeyDuplicate failed: 0x%x ! \n", rval);
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");
270 if (rsaKey != NULL) {
273 if (evpPkey != NULL) {
274 EVP_PKEY_free(evpPkey);