2baf3ac56534f22cb57504e436c1098ab3b481d8
[aaf/sshsm.git] / tpm-util / duplicate / tpm_duplication_aux.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 // Author: Arun Kumar Sekar
17
18
19 #include "tpm_duplication_aux.h"
20 #include "marshal.h"
21
22 #define AES_SIZE 16;
23
24 void print2b(char* msg, TPM2B * toprint){
25         print_buff(msg, toprint->size, toprint->buffer);
26 }
27
28 void 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
44 void 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
62 void 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 }
74 void 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
87 TPM2B_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
105 void 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
127 void 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
145 void 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
271 void 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
304 int 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
350 end:
351     return rc;
352 }
353
354
355 void 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
475 TSS2_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