Upgrade Duplicate utility to the latest tss
[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 void TPM2B_SENSITIVE_TO_TPMT(TPM2B_SENSITIVE *source, TPMT_SENSITIVE *target)
61 {
62         BYTE buffer[1024], *runner = buffer;
63         int size = 1024;
64         TPMT_SENSITIVE_Marshal(&(source->sensitiveArea), &runner, &size);
65
66         runner = buffer;
67         size = sizeof(*target);
68
69         TPMT_SENSITIVE_Unmarshal(target, &runner, &size);
70
71 }
72 void TPM2B_PUBLIC_TO_TPMT(TPM2B_PUBLIC *source, TPMT_PUBLIC *target)
73 {
74         BYTE buffer[1024], *runner = buffer;
75         int size = 1024;
76         TPMT_PUBLIC_Marshal(&(source->publicArea), &runner, &size);
77
78         runner = buffer;
79         size = sizeof(*target);
80
81         TPMT_PUBLIC_Unmarshal(target, &runner, &size, 1);
82 }
83
84
85 TPM2B_NAME * GetName(TPMI_ALG_HASH hashAlg, TPM2B_PUBLIC *obj)
86 {
87         int size_in =1024;
88         BYTE buff[1024] = {0};
89         BYTE* runner = buff;
90
91         UINT16 toHashSize = TPM2B_PUBLIC_Marshal(obj, &runner, &size_in) ;
92         size_in = 2;
93         size =  TPM2_ALG_ID_Marshal(&hashAlg, &runner , &size_in) + 32;
94
95         SHA256(buff+2, toHashSize-2, runner);
96 }
97
98
99 void CreateDuplicationBlob2B(
100                 //IN
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,
106
107                 //OUT
108                 TPM2B_PRIVATE *outDuplicate,
109                 TPM2B_ENCRYPTED_SECRET *encSymSeed)
110 {
111         TPMT_PUBLIC publicPortion;
112         TPMT_SENSITIVE sens;
113
114         TPM2B_PUBLIC_TO_TPMT(public2B, &publicPortion);
115         TPM2B_SENSITIVE_TO_TPMT(sens2B, &sens);
116
117         CreateDuplicationBlob(protector, &publicPortion, &sens, plainSymSeed, generateInSymSeed, encryptionKey, generateEncryptionKey, outDuplicate, encSymSeed);
118
119 }
120
121 void CreateSwDataObject2B(
122                 BYTE* auth, UINT16 authSize,
123                 RSA * rsaKey,
124                 BYTE * policyDigest, UINT16 policyDigestSize,
125                 TPM2B_PUBLIC * outPublic2B, 
126         TPM2B_SENSITIVE *outSens2B)
127 {
128
129         TPMT_PUBLIC publicPortion;
130         TPMT_SENSITIVE sens;
131
132         CreateSwDataObject(auth, authSize, rsaKey, NULL, 0, policyDigest, policyDigestSize, &publicPortion, &sens);
133
134
135         TPMT_PUBLIC_TO_TPM2B(&publicPortion, outPublic2B);
136         TPMT_SENSITIVE_TO_TPM2B(&sens, outSens2B);
137 }
138
139 void CreateDuplicationBlob(
140                 //IN
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,
146
147                 //OUT
148                 TPM2B_PRIVATE *outDuplicate,
149                 TPM2B_ENCRYPTED_SECRET *encSymSeed)
150 {
151         memset((void*)outDuplicate, 0, sizeof(TPM2B_PRIVATE));
152         memset((void*)encSymSeed, 0, sizeof(TPM2B_ENCRYPTED_SECRET));
153         TPM2B outerWrapper;
154         TPM2B NULL_2B = {0};
155         TPM2B swkName = {0};
156
157         TPM2B_PUBLIC public2B = {0};
158         TPM2B_SENSITIVE sens2B = {0};
159         INT32 size_in = 0;
160
161         TPM2B encSensitive = {0};
162
163         if(generateInSymSeed)
164         {
165                 RAND_bytes(plainSymSeed->buffer, 16);
166                 plainSymSeed->size = 16;
167         }
168         if(generateEncryptionKey)
169         {
170                 RAND_bytes(encryptionKey.buffer, 16);
171                 encryptionKey.size = 16;
172         }
173
174         // Preparing marshaled publicPortion:
175         TPMT_PUBLIC_TO_TPM2B(publicPortion, &public2B);
176
177         // calculating name:
178         GetName(TPM2_ALG_SHA256, &(public2B));
179
180         // preparing marshaled sensitive:
181         TPMT_SENSITIVE_TO_TPM2B(sens, &sens2B);
182
183         //preparing encSensitive
184         {
185                 UINT16 tempUint16;
186                 TPM2B IV = {0};
187                 IV.size = 16;
188                 TPM2B innerData = {0};
189                 BYTE innerIntegrity[34] = {0}, toHash[1024] = {0};
190                 size_in = 1024;
191                 BYTE* runner = toHash;
192
193
194                 UINT16_Marshal(&(sens2B.size), &runner, &size_in);
195                 TPMT_SENSITIVE_Marshal(sens, &runner, &size_in);
196
197                 memcpy(runner, swkName.buffer, swkName.size );
198                 runner += swkName.size;
199
200
201                 SHA256(toHash, runner - toHash, innerIntegrity+2);
202                 runner = innerIntegrity;
203                 tempUint16 = 32;
204                 UINT16_Marshal(&tempUint16, &runner, &size_in);
205
206                 memcpy(innerData.buffer, innerIntegrity, 34);
207                 runner = innerData.buffer + 34;
208                 size_in = 1024;
209
210                 UINT16_Marshal(&(sens2B.size), &runner, &size_in);
211                 TPMT_SENSITIVE_Marshal(sens, &runner, &size_in);
212
213                 innerData.size = sens2B.size + 36;
214
215                 AES_128_CFB_enc_dec(&(innerData), &(encSensitive), &(encryptionKey), &(IV), NULL, 1);
216         }
217
218
219         // outer integrity
220         {
221                 const TPM2B IV;
222                 TPM2B_DIGEST hmacKey = {0};
223                 TPM2B_DIGEST outerHmac = {0};
224                 TPM2B dupSensitive = {0};
225                 TPM2B_MAX_BUFFER dataToHmac = {0};
226                 BYTE * runner = NULL;
227
228                 //IV.size = 16;
229
230                 KDFa(TPM2_ALG_SHA256, (plainSymSeed), "STORAGE", &(swkName), &NULL_2B, 128 , (TPM2B_MAX_BUFFER*) &outerWrapper);
231
232                 AES_128_CFB_enc_dec(&(encSensitive), &(dupSensitive), &(outerWrapper), &(IV), NULL, 1);
233
234                 KDFa(TPM2_ALG_SHA256,  (plainSymSeed), "INTEGRITY", &NULL_2B, &NULL_2B, 32*8,(TPM2B_MAX_BUFFER*) &(hmacKey));
235
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;
239
240
241                 HMAC(EVP_sha256(), hmacKey.buffer, hmacKey.size, dataToHmac.buffer, dataToHmac.size,
242                                 outerHmac.buffer, (UINT32*) &size_in);
243
244                 outerHmac.size = size_in;
245
246                 runner = outDuplicate->buffer;
247                 size_in = sizeof(*outDuplicate) - 2;
248                 outDuplicate->size = TPM2B_DIGEST_Marshal(&outerHmac, &runner, &size_in);
249
250                 memcpy(runner, dupSensitive.buffer, dupSensitive.size);
251                 outDuplicate->size += dupSensitive.size;
252
253         }
254
255         // Encrypting seed with RSA pub:
256         TPM2B_DATA encodingParams = {0};
257         encodingParams.size = 10;
258         memcpy(encodingParams.buffer, "DUPLICATE", 10);
259
260         RSA_OAEP_Enc((TPM2B_PUBLIC_KEY_RSA*)plainSymSeed, (TPM2B_PUBLIC_KEY_RSA*)encSymSeed, protector, &encodingParams);
261
262 }
263
264 void rsaKeyTobn( const RSA* rsaKey,
265                 const BIGNUM** n,
266                 const BIGNUM** e,
267                 const BIGNUM** d,
268                 const BIGNUM** p,
269                 const BIGNUM** q
270                 )
271 {
272 #if OPENSSL_VERSION_NUMBER < 0x10100000
273     if (n != NULL) 
274     {
275         *n = rsaKey->n;
276         *e = rsaKey->e;
277         *d = rsaKey->d;
278     }
279     if (p != NULL) 
280     {
281         *p = rsaKey->p;
282         *q = rsaKey->q;
283     }
284
285 #else
286     if (n != NULL) 
287     {
288         RSA_get0_key(rsaKey, n, e, d);
289     }
290     if (p != NULL) 
291     {
292         RSA_get0_factors(rsaKey, p, q);
293     }
294 #endif
295 }
296
297 int rsabnTobin( const BIGNUM** n,
298                 const BIGNUM** e,
299                 const BIGNUM** p,
300                 uint8_t** n_bytes, int* n_size,
301                 uint8_t** e_bytes, int* e_size,
302                 uint8_t** p_bytes, int* p_size
303                 )
304 {
305     int rc=-1;
306     
307     if(n_size != NULL)
308     {
309         *n_size = BN_num_bytes(*n);
310     }
311
312     if( (n_bytes != NULL) && (*n_size > 0) )
313     {
314         *n_bytes = (uint8_t*) malloc(*n_size);
315         BN_bn2bin(*n, *n_bytes); 
316         rc = 0;
317     }
318
319     if(e_size != NULL)
320     {
321         *e_size = BN_num_bytes(*e);
322     }
323
324     if( (e_bytes != NULL) && (*e_size > 0) )
325     {
326         *e_bytes = (uint8_t*) malloc(*e_size);
327         BN_bn2bin(*e, *e_bytes); 
328         rc = 0;
329     }
330
331     if(p_size != NULL)
332     {
333         *p_size = BN_num_bytes(*p);
334     }
335
336     if( (p_bytes != NULL) && (*p_size > 0) )
337     {
338         *p_bytes = (uint8_t*) malloc(*p_size);
339         BN_bn2bin(*p, *p_bytes); 
340         rc = 0;
341     }
342
343 end:
344     return rc;
345 }
346
347
348 void CreateSwDataObject(
349                 BYTE* auth, UINT16 authSize,
350                 RSA * rsaKey,
351                 BYTE * dataToSeal, UINT16 dataSize,
352                 BYTE * policyDigest, UINT16 policyDigestSize,
353                 TPMT_PUBLIC * outPublic, 
354         TPMT_SENSITIVE *outSens)
355 {
356         TPM2B_MAX_BUFFER hash_buffer;
357         BYTE seed[32] = {0};
358
359     if(rsaKey != NULL)
360     {
361     /* Asymmetric key (RSA) creation */
362
363         const BIGNUM    *n;
364         const BIGNUM    *e;
365         const BIGNUM    *d;
366         const BIGNUM    *p;
367         const BIGNUM    *q;
368
369         uint8_t* n_bytes; int n_size;
370         uint8_t* e_bytes; int e_size;
371         uint8_t* p_bytes; int p_size;
372
373         rsaKeyTobn(rsaKey, &n, &e, &d, &p, &q);
374
375         rsabnTobin( &n, &e, &p,
376                 &n_bytes, &n_size,
377                 &e_bytes, &e_size,
378                 &p_bytes, &p_size
379                 );
380
381         /* Fill TPM Sensitive data */
382         outSens->sensitiveType = TPM2_ALG_RSA;
383
384         outSens->authValue.size = authSize;
385         memcpy(outSens->authValue.buffer, auth, authSize);
386
387         outSens->seedValue.size = 32;
388         memcpy(outSens->seedValue.buffer, seed, 32);
389
390         outSens->sensitive.bits.size = p_size;
391         memcpy(outSens->sensitive.bits.buffer, p_bytes, p_size);
392
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;
401
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);
408
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);
413
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);
417
418         if(( policyDigestSize > 0) && (policyDigest != NULL) )
419         {
420             memcpy(outPublic->authPolicy.buffer, policyDigest, policyDigestSize);
421             outPublic->authPolicy.size = policyDigestSize;
422         }
423     }
424     else if( (dataToSeal != NULL) && (dataSize > 0) )
425     {
426     /* Symmetric Key Creation */
427
428         outSens->authValue.size = authSize;
429         memcpy(outSens->authValue.buffer, auth, authSize);
430
431         outSens->seedValue.size = 32;
432         memcpy(outSens->seedValue.buffer, seed, 32);
433
434         outSens->sensitive.bits.size = dataSize;
435         memcpy(outSens->sensitive.bits.buffer, dataToSeal, dataSize);
436
437         outSens->sensitiveType = TPM2_ALG_KEYEDHASH;
438
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;
444
445         if(( policyDigestSize > 0) && (policyDigest != NULL) )
446         {
447             memcpy(outPublic->authPolicy.buffer, policyDigest, policyDigestSize);
448             outPublic->authPolicy.size = policyDigestSize;
449         }
450
451         outPublic->type = TPM2_ALG_KEYEDHASH;
452         outPublic->nameAlg = TPM2_ALG_SHA256;
453
454         outPublic->parameters.keyedHashDetail.scheme.scheme = TPM2_ALG_NULL;
455         outPublic->parameters.keyedHashDetail.scheme.details.hmac.hashAlg = TPM2_ALG_NULL;
456
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;
461     }
462
463 }
464
465
466 TSS2_RC swKeyDuplicate(
467       /* IN */
468       RSA* rsaKey, TPM2B_PUBLIC* parentKeyPublicPortion, UINT8* policyDigest, int digestSize,
469       /* OUT */
470       TPM2B* encryptionKey, TPM2B_PUBLIC *swKeyPublic, TPM2B_PRIVATE *swKeyPrivate,  TPM2B_ENCRYPTED_SECRET *encSymSeed)
471 {
472     TPM2_RC rval = TPM2_RC_SUCCESS;
473     UINT8 auth[0];
474     TPM2B_SENSITIVE swKeySens;
475     TPM2B plainSymSeed = {0};
476     TPM2B_PUBLIC_KEY_RSA protectorRsaPub = {0};
477
478     INIT_SIMPLE_TPM2B_SIZE(swKeySens);
479     INIT_SIMPLE_TPM2B_SIZE(*swKeyPublic);
480
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;
484
485     // Fill Symmetric seed
486     plainSymSeed.size =  encryptionKey->size = 16;
487     encSymSeed->size = 16;
488
489     // Create SW Data Object Public and Sensitive portions
490     CreateSwDataObject2B(auth, 0, rsaKey, policyDigest, digestSize, swKeyPublic, &swKeySens);
491
492     // Create Duplication blob needed for Import
493     CreateDuplicationBlob2B( &protectorRsaPub, swKeyPublic, &swKeySens, &plainSymSeed, 0, *encryptionKey, 1, swKeyPrivate, encSymSeed);
494
495         return rval;
496 }
497
498