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.
16 // Author: Arun Kumar Sekar
19 #include "tpm_duplication_aux.h"
24 void print2b(char* msg, TPM2B * toprint){
25 print_buff(msg, toprint->size, toprint->buffer);
28 void TPMT_PUBLIC_TO_TPM2B(TPMT_PUBLIC *source, TPM2B_PUBLIC *target)
34 UINT16 sizeField = TPMT_PUBLIC_Marshal(source, &runner, &size);
36 UINT16_Marshal(&sizeField, &runner, &size);
40 size = sizeof(TPM2B_PUBLIC);
41 TPM2B_PUBLIC_Unmarshal(target, &runner, &size, 1);
44 void TPMT_SENSITIVE_TO_TPM2B(TPMT_SENSITIVE *source, TPM2B_SENSITIVE *target)
50 UINT16 sizeField = TPMT_SENSITIVE_Marshal(source, &runner, &size);
52 UINT16_Marshal(&sizeField, &runner, &size);
56 size = sizeof(TPM2B_SENSITIVE);
57 TPM2B_SENSITIVE_Unmarshal(target, &runner, &size);
60 void TPM2B_SENSITIVE_TO_TPMT(TPM2B_SENSITIVE *source, TPMT_SENSITIVE *target)
62 BYTE buffer[1024], *runner = buffer;
64 TPMT_SENSITIVE_Marshal(&(source->sensitiveArea), &runner, &size);
67 size = sizeof(*target);
69 TPMT_SENSITIVE_Unmarshal(target, &runner, &size);
72 void TPM2B_PUBLIC_TO_TPMT(TPM2B_PUBLIC *source, TPMT_PUBLIC *target)
74 BYTE buffer[1024], *runner = buffer;
76 TPMT_PUBLIC_Marshal(&(source->publicArea), &runner, &size);
79 size = sizeof(*target);
81 TPMT_PUBLIC_Unmarshal(target, &runner, &size, 1);
85 TPM2B_NAME * GetName(TPMI_ALG_HASH hashAlg, TPM2B_PUBLIC *obj)
88 BYTE buff[1024] = {0};
91 UINT16 toHashSize = TPM2B_PUBLIC_Marshal(obj, &runner, &size_in) ;
93 size = TPM2_ALG_ID_Marshal(&hashAlg, &runner , &size_in) + 32;
95 SHA256(buff+2, toHashSize-2, runner);
99 void CreateDuplicationBlob2B(
101 TPM2B_PUBLIC_KEY_RSA *protector,
102 TPM2B_PUBLIC * public2B,
103 TPM2B_SENSITIVE *sens2B,
104 TPM2B *plainSymSeed, TPMI_YES_NO generateInSymSeed,
105 TPM2B encryptionKey, TPMI_YES_NO generateEncryptionKey,
108 TPM2B_PRIVATE *outDuplicate,
109 TPM2B_ENCRYPTED_SECRET *encSymSeed)
111 TPMT_PUBLIC publicPortion;
114 TPM2B_PUBLIC_TO_TPMT(public2B, &publicPortion);
115 TPM2B_SENSITIVE_TO_TPMT(sens2B, &sens);
117 CreateDuplicationBlob(protector, &publicPortion, &sens, plainSymSeed, generateInSymSeed, encryptionKey, generateEncryptionKey, outDuplicate, encSymSeed);
121 void CreateSwDataObject2B(
122 BYTE* auth, UINT16 authSize,
124 BYTE * policyDigest, UINT16 policyDigestSize,
125 TPM2B_PUBLIC * outPublic2B,
126 TPM2B_SENSITIVE *outSens2B)
129 TPMT_PUBLIC publicPortion;
132 CreateSwDataObject(auth, authSize, rsaKey, NULL, 0, policyDigest, policyDigestSize, &publicPortion, &sens);
135 TPMT_PUBLIC_TO_TPM2B(&publicPortion, outPublic2B);
136 TPMT_SENSITIVE_TO_TPM2B(&sens, outSens2B);
139 void CreateDuplicationBlob(
141 TPM2B_PUBLIC_KEY_RSA *protector,
142 TPMT_PUBLIC * publicPortion,
143 TPMT_SENSITIVE *sens,
144 TPM2B *plainSymSeed, TPMI_YES_NO generateInSymSeed,
145 TPM2B encryptionKey, TPMI_YES_NO generateEncryptionKey,
148 TPM2B_PRIVATE *outDuplicate,
149 TPM2B_ENCRYPTED_SECRET *encSymSeed)
151 memset((void*)outDuplicate, 0, sizeof(TPM2B_PRIVATE));
152 memset((void*)encSymSeed, 0, sizeof(TPM2B_ENCRYPTED_SECRET));
157 TPM2B_PUBLIC public2B = {0};
158 TPM2B_SENSITIVE sens2B = {0};
161 TPM2B encSensitive = {0};
163 if(generateInSymSeed)
165 RAND_bytes(plainSymSeed->buffer, 16);
166 plainSymSeed->size = 16;
168 if(generateEncryptionKey)
170 RAND_bytes(encryptionKey.buffer, 16);
171 encryptionKey.size = 16;
174 // Preparing marshaled publicPortion:
175 TPMT_PUBLIC_TO_TPM2B(publicPortion, &public2B);
178 GetName(TPM2_ALG_SHA256, &(public2B));
180 // preparing marshaled sensitive:
181 TPMT_SENSITIVE_TO_TPM2B(sens, &sens2B);
183 //preparing encSensitive
188 TPM2B innerData = {0};
189 BYTE innerIntegrity[34] = {0}, toHash[1024] = {0};
191 BYTE* runner = toHash;
194 UINT16_Marshal(&(sens2B.size), &runner, &size_in);
195 TPMT_SENSITIVE_Marshal(sens, &runner, &size_in);
197 memcpy(runner, swkName.buffer, swkName.size );
198 runner += swkName.size;
201 SHA256(toHash, runner - toHash, innerIntegrity+2);
202 runner = innerIntegrity;
204 UINT16_Marshal(&tempUint16, &runner, &size_in);
206 memcpy(innerData.buffer, innerIntegrity, 34);
207 runner = innerData.buffer + 34;
210 UINT16_Marshal(&(sens2B.size), &runner, &size_in);
211 TPMT_SENSITIVE_Marshal(sens, &runner, &size_in);
213 innerData.size = sens2B.size + 36;
215 AES_128_CFB_enc_dec(&(innerData), &(encSensitive), &(encryptionKey), &(IV), NULL, 1);
222 TPM2B_DIGEST hmacKey = {0};
223 TPM2B_DIGEST outerHmac = {0};
224 TPM2B dupSensitive = {0};
225 TPM2B_MAX_BUFFER dataToHmac = {0};
226 BYTE * runner = NULL;
230 KDFa(TPM2_ALG_SHA256, (plainSymSeed), "STORAGE", &(swkName), &NULL_2B, 128 , (TPM2B_MAX_BUFFER*) &outerWrapper);
232 AES_128_CFB_enc_dec(&(encSensitive), &(dupSensitive), &(outerWrapper), &(IV), NULL, 1);
234 KDFa(TPM2_ALG_SHA256, (plainSymSeed), "INTEGRITY", &NULL_2B, &NULL_2B, 32*8,(TPM2B_MAX_BUFFER*) &(hmacKey));
236 memcpy(dataToHmac.buffer, dupSensitive.buffer, dupSensitive.size);
237 memcpy(dataToHmac.buffer + dupSensitive.size, swkName.buffer, swkName.size);
238 dataToHmac.size = dupSensitive.size + swkName.size;
241 HMAC(EVP_sha256(), hmacKey.buffer, hmacKey.size, dataToHmac.buffer, dataToHmac.size,
242 outerHmac.buffer, (UINT32*) &size_in);
244 outerHmac.size = size_in;
246 runner = outDuplicate->buffer;
247 size_in = sizeof(*outDuplicate) - 2;
248 outDuplicate->size = TPM2B_DIGEST_Marshal(&outerHmac, &runner, &size_in);
250 memcpy(runner, dupSensitive.buffer, dupSensitive.size);
251 outDuplicate->size += dupSensitive.size;
255 // Encrypting seed with RSA pub:
256 TPM2B_DATA encodingParams = {0};
257 encodingParams.size = 10;
258 memcpy(encodingParams.buffer, "DUPLICATE", 10);
260 RSA_OAEP_Enc((TPM2B_PUBLIC_KEY_RSA*)plainSymSeed, (TPM2B_PUBLIC_KEY_RSA*)encSymSeed, protector, &encodingParams);
264 void rsaKeyTobn( const RSA* rsaKey,
272 #if OPENSSL_VERSION_NUMBER < 0x10100000
288 RSA_get0_key(rsaKey, n, e, d);
292 RSA_get0_factors(rsaKey, p, q);
297 int rsabnTobin( const BIGNUM** n,
300 uint8_t** n_bytes, int* n_size,
301 uint8_t** e_bytes, int* e_size,
302 uint8_t** p_bytes, int* p_size
309 *n_size = BN_num_bytes(*n);
312 if( (n_bytes != NULL) && (*n_size > 0) )
314 *n_bytes = (uint8_t*) malloc(*n_size);
315 BN_bn2bin(*n, *n_bytes);
321 *e_size = BN_num_bytes(*e);
324 if( (e_bytes != NULL) && (*e_size > 0) )
326 *e_bytes = (uint8_t*) malloc(*e_size);
327 BN_bn2bin(*e, *e_bytes);
333 *p_size = BN_num_bytes(*p);
336 if( (p_bytes != NULL) && (*p_size > 0) )
338 *p_bytes = (uint8_t*) malloc(*p_size);
339 BN_bn2bin(*p, *p_bytes);
348 void CreateSwDataObject(
349 BYTE* auth, UINT16 authSize,
351 BYTE * dataToSeal, UINT16 dataSize,
352 BYTE * policyDigest, UINT16 policyDigestSize,
353 TPMT_PUBLIC * outPublic,
354 TPMT_SENSITIVE *outSens)
356 TPM2B_MAX_BUFFER hash_buffer;
361 /* Asymmetric key (RSA) creation */
369 uint8_t* n_bytes; int n_size;
370 uint8_t* e_bytes; int e_size;
371 uint8_t* p_bytes; int p_size;
373 rsaKeyTobn(rsaKey, &n, &e, &d, &p, &q);
375 rsabnTobin( &n, &e, &p,
381 /* Fill TPM Sensitive data */
382 outSens->sensitiveType = TPM2_ALG_RSA;
384 outSens->authValue.size = authSize;
385 memcpy(outSens->authValue.buffer, auth, authSize);
387 outSens->seedValue.size = 32;
388 memcpy(outSens->seedValue.buffer, seed, 32);
390 outSens->sensitive.bits.size = p_size;
391 memcpy(outSens->sensitive.bits.buffer, p_bytes, p_size);
393 /* Fill TPM Public portion */
394 outPublic->type = TPM2_ALG_RSA;
395 outPublic->nameAlg = TPM2_ALG_SHA256;
396 outPublic->objectAttributes = 0;
397 //outPublic->objectAttributes.val |= TPMA_OBJECT_RESTRICTED;
398 outPublic->objectAttributes |= TPMA_OBJECT_USERWITHAUTH;
399 outPublic->objectAttributes |= TPMA_OBJECT_SIGN_ENCRYPT;
400 outPublic->authPolicy.size = 0;
402 /* Table 182 - Definition of TPMU_PUBLIC_PARMS Union <IN/OUT, S> */
403 outPublic->parameters.rsaDetail.symmetric.algorithm = TPM2_ALG_NULL;
404 outPublic->parameters.rsaDetail.scheme.scheme = TPM2_ALG_NULL;
405 //outPublic->parameters.rsaDetail.scheme.details.rsassa.hashAlg = TPM_ALG_SHA256;
406 outPublic->parameters.rsaDetail.keyBits = BYTES_TO_BITS(n_size);;
407 printf("outPublic->parameters.rsaDetail.keyBits: %d \n", outPublic->parameters.rsaDetail.keyBits);
409 unsigned long tmp_val = 0; // Need to use this temp variable?
410 memcpy(&tmp_val, e_bytes, e_size);
411 outPublic->parameters.rsaDetail.exponent = tmp_val;
412 printf("outPublic->parameters.rsaDetail.exponent: 0x%x \n", outPublic->parameters.rsaDetail.exponent);
414 outPublic->unique.rsa.size = n_size;
415 memcpy(outPublic->unique.rsa.buffer, n_bytes, n_size);
416 printf("outPublic->unique.rsa.size: %d \n", outPublic->unique.rsa.size);
418 if(( policyDigestSize > 0) && (policyDigest != NULL) )
420 memcpy(outPublic->authPolicy.buffer, policyDigest, policyDigestSize);
421 outPublic->authPolicy.size = policyDigestSize;
424 else if( (dataToSeal != NULL) && (dataSize > 0) )
426 /* Symmetric Key Creation */
428 outSens->authValue.size = authSize;
429 memcpy(outSens->authValue.buffer, auth, authSize);
431 outSens->seedValue.size = 32;
432 memcpy(outSens->seedValue.buffer, seed, 32);
434 outSens->sensitive.bits.size = dataSize;
435 memcpy(outSens->sensitive.bits.buffer, dataToSeal, dataSize);
437 outSens->sensitiveType = TPM2_ALG_KEYEDHASH;
439 outPublic->objectAttributes = 0;
440 outPublic->objectAttributes = 1;
441 outPublic->nameAlg = TPM2_ALG_SHA256;
442 memcpy(outPublic->unique.keyedHash.buffer, dataToSeal, dataSize);
443 outPublic->unique.keyedHash.size = dataSize;
445 if(( policyDigestSize > 0) && (policyDigest != NULL) )
447 memcpy(outPublic->authPolicy.buffer, policyDigest, policyDigestSize);
448 outPublic->authPolicy.size = policyDigestSize;
451 outPublic->type = TPM2_ALG_KEYEDHASH;
452 outPublic->nameAlg = TPM2_ALG_SHA256;
454 outPublic->parameters.keyedHashDetail.scheme.scheme = TPM2_ALG_NULL;
455 outPublic->parameters.keyedHashDetail.scheme.details.hmac.hashAlg = TPM2_ALG_NULL;
457 memcpy(hash_buffer.buffer, seed, 32);
458 memcpy(hash_buffer.buffer+32, dataToSeal, dataSize);
459 SHA256(hash_buffer.buffer, 32+dataSize, outPublic->unique.keyedHash.buffer);
460 outPublic->unique.keyedHash.size = 32;
466 TSS2_RC swKeyDuplicate(
468 RSA* rsaKey, TPM2B_PUBLIC* parentKeyPublicPortion, UINT8* policyDigest, int digestSize,
470 TPM2B* encryptionKey, TPM2B_PUBLIC *swKeyPublic, TPM2B_PRIVATE *swKeyPrivate, TPM2B_ENCRYPTED_SECRET *encSymSeed)
472 TPM2_RC rval = TPM2_RC_SUCCESS;
474 TPM2B_SENSITIVE swKeySens;
475 TPM2B plainSymSeed = {0};
476 TPM2B_PUBLIC_KEY_RSA protectorRsaPub = {0};
478 INIT_SIMPLE_TPM2B_SIZE(swKeySens);
479 INIT_SIMPLE_TPM2B_SIZE(*swKeyPublic);
481 // Fill the protector data
482 memcpy(protectorRsaPub.buffer, parentKeyPublicPortion->publicArea.unique.rsa.buffer, parentKeyPublicPortion->publicArea.unique.rsa.size);
483 protectorRsaPub.size = parentKeyPublicPortion->publicArea.unique.rsa.size;
485 // Fill Symmetric seed
486 plainSymSeed.size = encryptionKey->size = 16;
487 encSymSeed->size = 16;
489 // Create SW Data Object Public and Sensitive portions
490 CreateSwDataObject2B(auth, 0, rsaKey, policyDigest, digestSize, swKeyPublic, &swKeySens);
492 // Create Duplication blob needed for Import
493 CreateDuplicationBlob2B( &protectorRsaPub, swKeyPublic, &swKeySens, &plainSymSeed, 0, *encryptionKey, 1, swKeyPrivate, encSymSeed);