blob: 2baf3ac56534f22cb57504e436c1098ab3b481d8 [file] [log] [blame]
Arun kumar Sekar2ac56332018-03-30 11:20:30 -07001/*
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// Author: Arun Kumar Sekar
17
18
19#include "tpm_duplication_aux.h"
20#include "marshal.h"
21
22#define AES_SIZE 16;
23
24void print2b(char* msg, TPM2B * toprint){
25 print_buff(msg, toprint->size, toprint->buffer);
26}
27
28void TPMT_PUBLIC_TO_TPM2B(TPMT_PUBLIC *source, TPM2B_PUBLIC *target)
29{
30 BYTE buff[1024],
31 *runner = buff+2;
32 int size = 1024;
33
34 UINT16 sizeField = TPMT_PUBLIC_Marshal(source, &runner, &size);
35 runner = buff;
36 UINT16_Marshal(&sizeField, &runner, &size);
37
38
39 runner = buff;
40 size = sizeof(TPM2B_PUBLIC);
41 TPM2B_PUBLIC_Unmarshal(target, &runner, &size, 1);
42}
43
44void TPMT_SENSITIVE_TO_TPM2B(TPMT_SENSITIVE *source, TPM2B_SENSITIVE *target)
45{
46 BYTE buff[1024]={0},
47 *runner = buff+2;
48 INT32 size = 1024;
49
50 UINT16 sizeField = TPMT_SENSITIVE_Marshal(source, &runner, &size);
51 runner = buff;
52 UINT16_Marshal(&sizeField, &runner, &size);
53
54
55 runner = buff;
56 size = sizeof(TPM2B_SENSITIVE);
57 TPM2B_SENSITIVE_Unmarshal(target, &runner, &size);
58
59
60}
61
62void TPM2B_SENSITIVE_TO_TPMT(TPM2B_SENSITIVE *source, TPMT_SENSITIVE *target)
63{
64 BYTE buffer[1024], *runner = buffer;
65 int size = 1024;
66 TPMT_SENSITIVE_Marshal(&(source->t.sensitiveArea), &runner, &size);
67
68 runner = buffer;
69 size = sizeof(*target);
70
71 TPMT_SENSITIVE_Unmarshal(target, &runner, &size);
72
73}
74void TPM2B_PUBLIC_TO_TPMT(TPM2B_PUBLIC *source, TPMT_PUBLIC *target)
75{
76 BYTE buffer[1024], *runner = buffer;
77 int size = 1024;
78 TPMT_PUBLIC_Marshal(&(source->t.publicArea), &runner, &size);
79
80 runner = buffer;
81 size = sizeof(*target);
82
83 TPMT_PUBLIC_Unmarshal(target, &runner, &size, 1);
84}
85
86
87TPM2B_NAME * GetName(TPMI_ALG_HASH hashAlg, TPM2B_PUBLIC *obj, TPM2B_NAME *outName)
88{
89 int size_in =1024;
90 BYTE buff[1024] = {0};
91 BYTE* runner = buff;
92
93 UINT16 toHashSize = TPM2B_PUBLIC_Marshal(obj, &runner, &size_in) ;
94
95 runner = outName->b.buffer;
96 size_in = 2;
97 outName->b.size = TPM_ALG_ID_Marshal(&hashAlg, &runner , &size_in) + 32;
98
99 SHA256(buff+2, toHashSize-2, runner);
100
101 return outName;
102}
103
104
105void CreateDuplicationBlob2B(
106 //IN
107 TPM2B_PUBLIC_KEY_RSA *protector,
108 TPM2B_PUBLIC * public2B,
109 TPM2B_SENSITIVE *sens2B,
110 TPM2B_ENCRYPTED_SECRET *plainSymSeed, TPMI_YES_NO generateInSymSeed,
111 TPM2B_DATA *encryptionKey, TPMI_YES_NO generateEncryptionKey,
112
113 //OUT
114 TPM2B_PRIVATE *outDuplicate,
115 TPM2B_ENCRYPTED_SECRET *encSymSeed)
116{
117 TPMT_PUBLIC publicPortion;
118 TPMT_SENSITIVE sens;
119
120 TPM2B_PUBLIC_TO_TPMT(public2B, &publicPortion);
121 TPM2B_SENSITIVE_TO_TPMT(sens2B, &sens);
122
123 CreateDuplicationBlob(protector, &publicPortion, &sens, plainSymSeed, generateInSymSeed, encryptionKey, generateEncryptionKey, outDuplicate, encSymSeed);
124
125}
126
127void CreateSwDataObject2B(
128 BYTE* auth, UINT16 authSize,
129 RSA * rsaKey,
130 BYTE * policyDigest, UINT16 policyDigestSize,
131 TPM2B_PUBLIC * outPublic2B,
132 TPM2B_SENSITIVE *outSens2B)
133{
134
135 TPMT_PUBLIC publicPortion;
136 TPMT_SENSITIVE sens;
137
138 CreateSwDataObject(auth, authSize, rsaKey, NULL, 0, policyDigest, policyDigestSize, &publicPortion, &sens);
139
140
141 TPMT_PUBLIC_TO_TPM2B(&publicPortion, outPublic2B);
142 TPMT_SENSITIVE_TO_TPM2B(&sens, outSens2B);
143}
144
145void CreateDuplicationBlob(
146 //IN
147 TPM2B_PUBLIC_KEY_RSA *protector,
148 TPMT_PUBLIC * publicPortion,
149 TPMT_SENSITIVE *sens,
150 TPM2B_ENCRYPTED_SECRET *plainSymSeed, TPMI_YES_NO generateInSymSeed,
151 TPM2B_DATA *encryptionKey, TPMI_YES_NO generateEncryptionKey,
152
153 //OUT
154 TPM2B_PRIVATE *outDuplicate,
155 TPM2B_ENCRYPTED_SECRET *encSymSeed)
156{
157 memset((void*)outDuplicate, 0, sizeof(TPM2B_PRIVATE));
158 memset((void*)encSymSeed, 0, sizeof(TPM2B_ENCRYPTED_SECRET));
159 TPM2B_SYM_KEY outerWrapper;
160 TPM2B NULL_2B = {0};
161 TPM2B_NAME swkName = {{0}};
162
163
164 TPM2B_PUBLIC public2B = {{0}};
165 TPM2B_SENSITIVE sens2B = {{0}};
166 INT32 size_in = 0;
167
168 TPM2B_MAX_BUFFER encSensitive = {{0}};
169
170 if(generateInSymSeed)
171 {
172 RAND_bytes(plainSymSeed->b.buffer, 16);
173 plainSymSeed->b.size = 16;
174 }
175 if(generateEncryptionKey)
176 {
177 RAND_bytes(encryptionKey->b.buffer, 16);
178 encryptionKey->b.size = 16;
179 }
180
181 // Preparing marshaled publicPortion:
182 TPMT_PUBLIC_TO_TPM2B(publicPortion, &public2B);
183
184 // calculating name:
185 GetName(TPM_ALG_SHA256, &(public2B), &swkName);
186
187 // preparing marshaled sensitive:
188 TPMT_SENSITIVE_TO_TPM2B(sens, &sens2B);
189
190 //preparing encSensitive
191 {
192 UINT16 tempUint16;
193 TPM2B_SYM_KEY IV = {0};
194 IV.b.size = 16;
195 TPM2B_MAX_BUFFER innerData = {0};
196 BYTE innerIntegrity[34] = {0}, toHash[1024] = {0};
197 size_in = 1024;
198 BYTE* runner = toHash;
199
200
201 UINT16_Marshal(&(sens2B.b.size), &runner, &size_in);
202 TPMT_SENSITIVE_Marshal(sens, &runner, &size_in);
203
204 memcpy(runner, swkName.b.buffer, swkName.b.size );
205 runner += swkName.b.size;
206
207
208 SHA256(toHash, runner - toHash, innerIntegrity+2);
209 runner = innerIntegrity;
210 tempUint16 = 32;
211 UINT16_Marshal(&tempUint16, &runner, &size_in);
212
213 memcpy(innerData.b.buffer, innerIntegrity, 34);
214 runner = innerData.b.buffer + 34;
215 size_in = 1024;
216
217 UINT16_Marshal(&(sens2B.b.size), &runner, &size_in);
218 TPMT_SENSITIVE_Marshal(sens, &runner, &size_in);
219
220 innerData.b.size = sens2B.b.size + 36;
221
222 AES_128_CFB_enc_dec(&(innerData.b), &(encSensitive.b), &(encryptionKey->b), &(IV.b), NULL, 1);
223 }
224
225
226 // outer integrity
227 {
228 TPM2B_SYM_KEY IV = {{0}};
229 TPM2B_DIGEST hmacKey = {{0}};
230 TPM2B_DIGEST outerHmac = {{0}};
231 TPM2B_MAX_BUFFER dupSensitive = {{0}};
232 TPM2B_MAX_BUFFER dataToHmac = {{0}};
233 BYTE * runner = NULL;
234
235 IV.b.size = 16;
236
237 KDFa(TPM_ALG_SHA256, &(plainSymSeed->b), "STORAGE", &(swkName.b), &NULL_2B, 128 , (TPM2B_MAX_BUFFER*) &outerWrapper);
238
239 AES_128_CFB_enc_dec(&(encSensitive.b), &(dupSensitive.b), &(outerWrapper.b), &(IV.b), NULL, 1);
240
241 KDFa(TPM_ALG_SHA256, &(plainSymSeed->b), "INTEGRITY", &NULL_2B, &NULL_2B, 32*8,(TPM2B_MAX_BUFFER*) &(hmacKey.b));
242
243 memcpy(dataToHmac.b.buffer, dupSensitive.b.buffer, dupSensitive.b.size);
244 memcpy(dataToHmac.b.buffer + dupSensitive.b.size, swkName.b.buffer, swkName.b.size);
245 dataToHmac.b.size = dupSensitive.b.size + swkName.b.size;
246
247
248 HMAC(EVP_sha256(), hmacKey.b.buffer, hmacKey.b.size, dataToHmac.b.buffer, dataToHmac.b.size,
249 outerHmac.b.buffer, (UINT32*) &size_in);
250
251 outerHmac.b.size = size_in;
252
253 runner = outDuplicate->b.buffer;
254 size_in = sizeof(*outDuplicate) - 2;
255 outDuplicate->b.size = TPM2B_DIGEST_Marshal(&outerHmac, &runner, &size_in);
256
257 memcpy(runner, dupSensitive.b.buffer, dupSensitive.b.size);
258 outDuplicate->b.size += dupSensitive.b.size;
259
260 }
261
262 // Encrypting seed with RSA pub:
263 TPM2B_DATA encodingParams = {{0}};
264 encodingParams.b.size = 10;
265 memcpy(encodingParams.b.buffer, "DUPLICATE", 10);
266
267 RSA_OAEP_Enc((TPM2B_PUBLIC_KEY_RSA*)plainSymSeed, (TPM2B_PUBLIC_KEY_RSA*)encSymSeed, protector, &encodingParams);
268
269}
270
271void rsaKeyTobn( const RSA* rsaKey,
272 const BIGNUM** n,
273 const BIGNUM** e,
274 const BIGNUM** d,
275 const BIGNUM** p,
276 const BIGNUM** q
277 )
278{
279#if OPENSSL_VERSION_NUMBER < 0x10100000
280 if (n != NULL)
281 {
282 *n = rsaKey->n;
283 *e = rsaKey->e;
284 *d = rsaKey->d;
285 }
286 if (p != NULL)
287 {
288 *p = rsaKey->p;
289 *q = rsaKey->q;
290 }
291
292#else
293 if (n != NULL)
294 {
295 RSA_get0_key(rsaKey, n, e, d);
296 }
297 if (p != NULL)
298 {
299 RSA_get0_factors(rsaKey, p, q);
300 }
301#endif
302}
303
304int rsabnTobin( const BIGNUM** n,
305 const BIGNUM** e,
306 const BIGNUM** p,
307 uint8_t** n_bytes, int* n_size,
308 uint8_t** e_bytes, int* e_size,
309 uint8_t** p_bytes, int* p_size
310 )
311{
312 int rc=-1;
313
314 if(n_size != NULL)
315 {
316 *n_size = BN_num_bytes(*n);
317 }
318
319 if( (n_bytes != NULL) && (*n_size > 0) )
320 {
321 *n_bytes = (uint8_t*) malloc(*n_size);
322 BN_bn2bin(*n, *n_bytes);
323 rc = 0;
324 }
325
326 if(e_size != NULL)
327 {
328 *e_size = BN_num_bytes(*e);
329 }
330
331 if( (e_bytes != NULL) && (*e_size > 0) )
332 {
333 *e_bytes = (uint8_t*) malloc(*e_size);
334 BN_bn2bin(*e, *e_bytes);
335 rc = 0;
336 }
337
338 if(p_size != NULL)
339 {
340 *p_size = BN_num_bytes(*p);
341 }
342
343 if( (p_bytes != NULL) && (*p_size > 0) )
344 {
345 *p_bytes = (uint8_t*) malloc(*p_size);
346 BN_bn2bin(*p, *p_bytes);
347 rc = 0;
348 }
349
350end:
351 return rc;
352}
353
354
355void CreateSwDataObject(
356 BYTE* auth, UINT16 authSize,
357 RSA * rsaKey,
358 BYTE * dataToSeal, UINT16 dataSize,
359 BYTE * policyDigest, UINT16 policyDigestSize,
360 TPMT_PUBLIC * outPublic,
361 TPMT_SENSITIVE *outSens)
362{
363 TPM2B_MAX_BUFFER hash_buffer;
364 BYTE seed[32] = {0};
365
366 if(rsaKey != NULL)
367 {
368 /* Asymmetric key (RSA) creation */
369
370 const BIGNUM *n;
371 const BIGNUM *e;
372 const BIGNUM *d;
373 const BIGNUM *p;
374 const BIGNUM *q;
375
376 uint8_t* n_bytes; int n_size;
377 uint8_t* e_bytes; int e_size;
378 uint8_t* p_bytes; int p_size;
379
380 rsaKeyTobn(rsaKey, &n, &e, &d, &p, &q);
381
382 rsabnTobin( &n, &e, &p,
383 &n_bytes, &n_size,
384 &e_bytes, &e_size,
385 &p_bytes, &p_size
386 );
387
388 /* Fill TPM Sensitive data */
389 outSens->sensitiveType = TPM_ALG_RSA;
390
391 outSens->authValue.b.size = authSize;
392 memcpy(outSens->authValue.b.buffer, auth, authSize);
393
394 outSens->seedValue.b.size = 32;
395 memcpy(outSens->seedValue.b.buffer, seed, 32);
396
397 outSens->sensitive.bits.b.size = p_size;
398 memcpy(outSens->sensitive.bits.b.buffer, p_bytes, p_size);
399
400 /* Fill TPM Public portion */
401 outPublic->type = TPM_ALG_RSA;
402 outPublic->nameAlg = TPM_ALG_SHA256;
403 outPublic->objectAttributes.val = 0;
404 //outPublic->objectAttributes.val |= TPMA_OBJECT_RESTRICTED;
405 outPublic->objectAttributes.val |= TPMA_OBJECT_USERWITHAUTH;
406 outPublic->objectAttributes.val |= TPMA_OBJECT_SIGN;
407 outPublic->authPolicy.t.size = 0;
408
409 /* Table 182 - Definition of TPMU_PUBLIC_PARMS Union <IN/OUT, S> */
410 outPublic->parameters.rsaDetail.symmetric.algorithm = TPM_ALG_NULL;
411 outPublic->parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL;
412 //outPublic->parameters.rsaDetail.scheme.details.rsassa.hashAlg = TPM_ALG_SHA256;
413
414 outPublic->parameters.rsaDetail.keyBits = BYTES_TO_BITS(n_size);;
415 printf("outPublic->parameters.rsaDetail.keyBits: %d \n", outPublic->parameters.rsaDetail.keyBits);
416
417 unsigned long tmp_val = 0; // Need to use this temp variable?
418 memcpy(&tmp_val, e_bytes, e_size);
419 outPublic->parameters.rsaDetail.exponent = tmp_val;
420 printf("outPublic->parameters.rsaDetail.exponent: 0x%x \n", outPublic->parameters.rsaDetail.exponent);
421
422 outPublic->unique.rsa.t.size = n_size;
423 memcpy(outPublic->unique.rsa.t.buffer, n_bytes, n_size);
424 printf("outPublic->unique.rsa.t.size: %d \n", outPublic->unique.rsa.t.size);
425
426 if(( policyDigestSize > 0) && (policyDigest != NULL) )
427 {
428 memcpy(outPublic->authPolicy.b.buffer, policyDigest, policyDigestSize);
429 outPublic->authPolicy.b.size = policyDigestSize;
430 }
431 }
432
433 else if( (dataToSeal != NULL) && (dataSize > 0) )
434 {
435 /* Symmetric Key Creation */
436
437 outSens->authValue.b.size = authSize;
438 memcpy(outSens->authValue.b.buffer, auth, authSize);
439
440 outSens->seedValue.b.size = 32;
441 memcpy(outSens->seedValue.b.buffer, seed, 32);
442
443 outSens->sensitive.bits.b.size = dataSize;
444 memcpy(outSens->sensitive.bits.b.buffer, dataToSeal, dataSize);
445
446 outSens->sensitiveType = TPM_ALG_KEYEDHASH;
447
448 outPublic->objectAttributes.val = 0;
449 outPublic->objectAttributes.adminWithPolicy = 1;
450 outPublic->nameAlg = TPM_ALG_SHA256;
451 memcpy(outPublic->unique.keyedHash.b.buffer, dataToSeal, dataSize);
452 outPublic->unique.keyedHash.b.size = dataSize;
453
454 if(( policyDigestSize > 0) && (policyDigest != NULL) )
455 {
456 memcpy(outPublic->authPolicy.b.buffer, policyDigest, policyDigestSize);
457 outPublic->authPolicy.b.size = policyDigestSize;
458 }
459
460 outPublic->type = TPM_ALG_KEYEDHASH;
461 outPublic->nameAlg = TPM_ALG_SHA256;
462
463 outPublic->parameters.keyedHashDetail.scheme.scheme = TPM_ALG_NULL;
464 outPublic->parameters.keyedHashDetail.scheme.details.hmac.hashAlg = TPM_ALG_NULL;
465
466 memcpy(hash_buffer.b.buffer, seed, 32);
467 memcpy(hash_buffer.b.buffer+32, dataToSeal, dataSize);
468 SHA256(hash_buffer.b.buffer, 32+dataSize, outPublic->unique.keyedHash.b.buffer);
469 outPublic->unique.keyedHash.b.size = 32;
470 }
471
472}
473
474
475TSS2_RC swKeyDuplicate(
476 /* IN */
477 RSA* rsaKey, TPM2B_PUBLIC* parentKeyPublicPortion, UINT8* policyDigest, int digestSize,
478 /* OUT */
479 TPM2B_DATA* encryptionKey, TPM2B_PUBLIC *swKeyPublic, TPM2B_PRIVATE *swKeyPrivate, TPM2B_ENCRYPTED_SECRET *encSymSeed)
480{
481 TPM_RC rval = TPM_RC_SUCCESS;
482 UINT8 auth[0];
483 TPM2B_SENSITIVE swKeySens;
484 TPM2B_ENCRYPTED_SECRET plainSymSeed = {{0}};
485 TPM2B_PUBLIC_KEY_RSA protectorRsaPub = {{0}};
486
487 INIT_SIMPLE_TPM2B_SIZE(swKeySens);
488 INIT_SIMPLE_TPM2B_SIZE(*swKeyPublic);
489
490 // Fill the protector data
491 memcpy(protectorRsaPub.b.buffer, parentKeyPublicPortion->t.publicArea.unique.rsa.t.buffer, parentKeyPublicPortion->t.publicArea.unique.rsa.t.size);
492 protectorRsaPub.b.size = parentKeyPublicPortion->t.publicArea.unique.rsa.t.size;
493
494 // Fill Symmetric seed
495 plainSymSeed.b.size = encryptionKey->b.size = 16;
496 encSymSeed->b.size = 16;
497
498 // Create SW Data Object Public and Sensitive portions
499 CreateSwDataObject2B(auth, 0, rsaKey, policyDigest, digestSize, swKeyPublic, &swKeySens);
500
501 // Create Duplication blob needed for Import
502 CreateDuplicationBlob2B( &protectorRsaPub, swKeyPublic, &swKeySens, &plainSymSeed, 0, encryptionKey, 1, swKeyPrivate, encSymSeed);
503
504 return rval;
505}
506
507