1 /* Software-based Trusted Platform Module (TPM) Emulator
2  * Copyright (C) 2004-2010 Mario Strasser <mast@gmx.net>
3  *
4  * This module is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published
6  * by the Free Software Foundation; either version 2 of the License,
7  * or (at your option) any later version.
8  *
9  * This module is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * $Id: tpm_migration.c 462 2011-06-04 14:14:33Z mast $
15  */
16 
17 #include "tpm_emulator.h"
18 #include "tpm_commands.h"
19 #include "tpm_handles.h"
20 #include "tpm_data.h"
21 #include "tpm_marshalling.h"
22 #include "crypto/sha1.h"
23 #include "crypto/hmac.h"
24 
25 /*
26  * Migration ([TPM_Part3], Section 11)
27  */
28 
tpm_compute_migration_digest(TPM_PUBKEY * migrationKey,TPM_MIGRATE_SCHEME migrationScheme,TPM_NONCE * tpmProof,TPM_DIGEST * digest)29 static int tpm_compute_migration_digest(TPM_PUBKEY *migrationKey,
30                                         TPM_MIGRATE_SCHEME migrationScheme,
31                                         TPM_NONCE *tpmProof, TPM_DIGEST *digest)
32 {
33   tpm_sha1_ctx_t sha1;
34   UINT32 len = sizeof_TPM_PUBKEY((*migrationKey));
35   BYTE *buf, *ptr, buf2[2];
36   buf = ptr = tpm_malloc(len);
37   if (buf == NULL
38       || tpm_marshal_TPM_PUBKEY(&ptr, &len, migrationKey)) {
39     tpm_free(buf);
40     return -1;
41   }
42   /* compute SHA1 hash */
43   tpm_sha1_init(&sha1);
44   tpm_sha1_update(&sha1, buf, sizeof_TPM_PUBKEY((*migrationKey)));
45   ptr = buf2; len = 2;
46   tpm_marshal_UINT16(&ptr, &len, migrationScheme);
47   tpm_sha1_update(&sha1, buf2, 2);
48   tpm_sha1_update(&sha1, tpmProof->nonce, sizeof(TPM_NONCE));
49   tpm_sha1_final(&sha1, digest->digest);
50   tpm_free(buf);
51   return 0;
52 }
53 
tpm_verify_migration_digest(TPM_MIGRATIONKEYAUTH * migrationKeyAuth,TPM_NONCE * tpmProof)54 static int tpm_verify_migration_digest(TPM_MIGRATIONKEYAUTH *migrationKeyAuth,
55                                        TPM_NONCE *tpmProof)
56 {
57   TPM_DIGEST digest;
58   if (tpm_compute_migration_digest(&migrationKeyAuth->migrationKey,
59       migrationKeyAuth->migrationScheme, tpmProof, &digest)) return -1;
60   return memcmp(digest.digest, migrationKeyAuth->digest.digest, sizeof(TPM_DIGEST));
61 }
62 
TPM_CreateMigrationBlob(TPM_KEY_HANDLE parentHandle,TPM_MIGRATE_SCHEME migrationType,TPM_MIGRATIONKEYAUTH * migrationKeyAuth,UINT32 encDataSize,BYTE * encData,TPM_AUTH * auth1,TPM_AUTH * auth2,UINT32 * randomSize,BYTE ** random,UINT32 * outDataSize,BYTE ** outData)63 TPM_RESULT TPM_CreateMigrationBlob(TPM_KEY_HANDLE parentHandle,
64                                    TPM_MIGRATE_SCHEME migrationType,
65                                    TPM_MIGRATIONKEYAUTH *migrationKeyAuth,
66                                    UINT32 encDataSize, BYTE *encData,
67                                    TPM_AUTH *auth1, TPM_AUTH *auth2,
68                                    UINT32 *randomSize, BYTE **random,
69                                    UINT32 *outDataSize, BYTE **outData)
70 {
71   TPM_RESULT res;
72   TPM_KEY_DATA *parent;
73   TPM_SESSION_DATA *session;
74   BYTE *key_buf;
75   UINT32 key_buf_size;
76   TPM_STORE_ASYMKEY store;
77   TPM_PUBKEY_DATA key;
78 
79   info("TPM_CreateMigrationBlob()");
80   /* get parent key */
81   parent = tpm_get_key(parentHandle);
82   if (parent == NULL) return TPM_INVALID_KEYHANDLE;
83   /* verify parent authorization */
84   res = tpm_verify_auth(auth1, parent->usageAuth, parentHandle);
85   if (res != TPM_SUCCESS) return res;
86   session = tpm_get_auth(auth2->authHandle);
87   if (session == NULL || session->type != TPM_ST_OIAP) return TPM_AUTHFAIL;
88   /* verify key properties */
89   if (parent->keyUsage != TPM_KEY_STORAGE) return TPM_INVALID_KEYUSAGE;
90   /* decrypt private key */
91   if (tpm_decrypt_private_key(parent, encData, encDataSize,
92                               &store, &key_buf, &key_buf_size) != 0) {
93     return TPM_DECRYPT_ERROR;
94   }
95   if (store.payload != TPM_PT_ASYM) {
96     tpm_free(key_buf);
97     return TPM_DECRYPT_ERROR;
98   }
99   debug("key size: %d / %d", store.privKey.keyLength, key_buf_size);
100   /* verify migration authorization */
101   res = tpm_verify_auth(auth2, store.migrationAuth, TPM_INVALID_HANDLE);
102   if (res != TPM_SUCCESS) {
103     tpm_free(key_buf);
104     return TPM_MIGRATEFAIL;
105   }
106   if (tpm_verify_migration_digest(migrationKeyAuth,
107       &tpmData.permanent.data.tpmProof)) {
108     debug("tpm_verify_migration_digest() failed");
109     tpm_free(key_buf);
110     return TPM_MIGRATEFAIL;
111   }
112   debug("migration authorization is valid.");
113   /* set public key */
114   if (tpm_setup_pubkey_data(&migrationKeyAuth->migrationKey, &key) != 0) {
115       debug("tpm_setup_pubkey() failed");
116       tpm_free(key_buf);
117       return TPM_FAIL;
118   }
119   /* perform migration */
120   if (migrationType == TPM_MS_REWRAP) {
121     /* re-encrypt raw key data */
122     debug("migrationType = TPM_MS_REWRAP");
123     *random = NULL;
124     *randomSize = 0;
125     *outDataSize = key.key.size >> 3;
126     *outData = tpm_malloc(*outDataSize);
127     if (*outData == NULL) {
128       free_TPM_PUBKEY_DATA(key);
129       tpm_free(*outData);
130       tpm_free(key_buf);
131       return TPM_FAIL;
132     }
133     if (tpm_encrypt_public(&key, key_buf, key_buf_size,
134                            *outData, outDataSize) != 0) {
135         free_TPM_PUBKEY_DATA(key);
136         tpm_free(*outData);
137         tpm_free(key_buf);
138         return TPM_ENCRYPT_ERROR;
139     }
140   } else if (migrationType == TPM_MS_MIGRATE) {
141     BYTE *ptr, *buf;
142     UINT32 len;
143     size_t buf_len;
144     /* generate an OAEP encoding of the TPM_MIGRATE_ASYMKEY structure:
145        K1|seed|0x00-pad|0x01|TPM_MIGRATE_ASYMKEY */
146     debug("migrationType = TPM_MS_MIGRATE");
147     len = buf_len = 198;
148     ptr = buf = tpm_malloc(buf_len);
149     *randomSize = buf_len;
150     *random = tpm_malloc(*randomSize);
151     *outDataSize = key.key.size >> 3;
152     *outData = tpm_malloc(*outDataSize);
153     if (buf == NULL || *random == NULL || *outData == NULL) {
154       free_TPM_PUBKEY_DATA(key);
155       tpm_free(buf);
156       tpm_free(*random);
157       tpm_free(*outData);
158       tpm_free(key_buf);
159       return TPM_NOSPACE;
160     }
161     memset(buf, 0, buf_len);
162     tpm_marshal_UINT32(&ptr, &len, store.privKey.keyLength);
163     memcpy(ptr, store.privKey.key, 16);
164     ptr += 16;
165     memcpy(ptr, store.migrationAuth, sizeof(TPM_SECRET));
166     len = 46 + store.privKey.keyLength - 16;
167     ptr = &buf[buf_len - len];
168     tpm_marshal_BYTE(&ptr, &len, 0x01);
169     tpm_marshal_TPM_PAYLOAD_TYPE(&ptr, &len, TPM_PT_MIGRATE);
170     tpm_marshal_TPM_SECRET(&ptr, &len, &store.usageAuth);
171     tpm_marshal_TPM_DIGEST(&ptr, &len, &store.pubDataDigest);
172     tpm_marshal_UINT32(&ptr, &len, store.privKey.keyLength - 16);
173     memcpy(ptr, &store.privKey.key[16], store.privKey.keyLength - 16);
174     tpm_rsa_mask_generation(buf, SHA1_DIGEST_LENGTH,
175       &buf[SHA1_DIGEST_LENGTH], buf_len - SHA1_DIGEST_LENGTH);
176     tpm_rsa_mask_generation(&buf[SHA1_DIGEST_LENGTH],
177       buf_len - SHA1_DIGEST_LENGTH, buf, SHA1_DIGEST_LENGTH);
178     /* XOR encrypt OAEP encoding */
179     tpm_get_random_bytes(*random, *randomSize);
180     for (len = 0; len < buf_len; len++) buf[len] ^= (*random)[len];
181     /* RSA encrypt OAEP encoding */
182     if (tpm_rsa_encrypt(&key.key, RSA_ES_OAEP_SHA1, buf, buf_len,
183                         *outData, &buf_len)) {
184       debug("tpm_rsa_encrypt() failed");
185       free_TPM_PUBKEY_DATA(key);
186       tpm_free(buf);
187       tpm_free(*random);
188       tpm_free(*outData);
189       tpm_free(key_buf);
190       return TPM_ENCRYPT_ERROR;
191     }
192     *outDataSize = buf_len;
193     tpm_free(buf);
194   } else {
195     debug("invalid migration type: %d", migrationType);
196     free_TPM_PUBKEY_DATA(key);
197     tpm_free(key_buf);
198     return TPM_BAD_PARAMETER;
199   }
200   free_TPM_PUBKEY_DATA(key);
201   tpm_free(key_buf);
202   return TPM_SUCCESS;
203 }
204 
TPM_ConvertMigrationBlob(TPM_KEY_HANDLE parentHandle,UINT32 inDataSize,BYTE * inData,UINT32 randomSize,BYTE * random,TPM_AUTH * auth1,UINT32 * outDataSize,BYTE ** outData)205 TPM_RESULT TPM_ConvertMigrationBlob(TPM_KEY_HANDLE parentHandle,
206                                     UINT32 inDataSize, BYTE *inData,
207                                     UINT32 randomSize, BYTE *random,
208                                     TPM_AUTH *auth1,
209                                     UINT32 *outDataSize,BYTE **outData)
210 {
211   TPM_RESULT res;
212   TPM_KEY_DATA *parent;
213   BYTE *ptr, *buf;
214   UINT32 len;
215   size_t buf_len;
216   TPM_STORE_ASYMKEY store;
217 
218   info("TPM_ConvertMigrationBlob()");
219   /* get parent key */
220   parent = tpm_get_key(parentHandle);
221   if (parent == NULL) return TPM_INVALID_KEYHANDLE;
222   /* verify parent authorization */
223   if (auth1->authHandle != TPM_INVALID_HANDLE
224       || parent->authDataUsage != TPM_AUTH_NEVER) {
225     res = tpm_verify_auth(auth1, parent->usageAuth, parentHandle);
226     if (res != TPM_SUCCESS) return res;
227   }
228   /* verify key properties */
229   if (parent->keyUsage != TPM_KEY_STORAGE) return TPM_INVALID_KEYUSAGE;
230   /* decrypt private key */
231   buf_len = parent->key.size >> 3;
232   buf = tpm_malloc(buf_len);
233   if (buf == NULL) return TPM_NOSPACE;
234   /* RSA decrypt OAEP encoding */
235   if (tpm_rsa_decrypt(&parent->key, RSA_ES_OAEP_SHA1,
236                       inData, inDataSize, buf, &buf_len)
237       || buf_len != randomSize || buf_len != 198) {
238     debug("tpm_rsa_decrypt() failed");
239     tpm_free(buf);
240     return TPM_DECRYPT_ERROR;
241   }
242   /* XOR decrypt OAEP encoding */
243   for (len = 0; len < buf_len; len++) buf[len] ^= random[len];
244   /* unmask OAEP encoding */
245   tpm_rsa_mask_generation(&buf[SHA1_DIGEST_LENGTH],
246     buf_len - SHA1_DIGEST_LENGTH, buf, SHA1_DIGEST_LENGTH);
247   tpm_rsa_mask_generation(buf, SHA1_DIGEST_LENGTH,
248     &buf[SHA1_DIGEST_LENGTH], buf_len - SHA1_DIGEST_LENGTH);
249   /* create a TPM_STORE_ASYMKEY structure */
250   memcpy(store.migrationAuth, &buf[20], sizeof(TPM_SECRET));
251   for (ptr = &buf[20 + sizeof(TPM_SECRET)]; *ptr == 0x00; ptr++);
252   if (ptr[0] != 0x01 || ptr[1] != TPM_PT_MIGRATE) {
253       debug("OAEP encoding is invalid");
254       tpm_free(buf);
255       return TPM_DECRYPT_ERROR;
256   }
257   ptr += 2;
258   len = buf_len - (ptr - buf);
259   store.payload = TPM_PT_ASYM;
260   tpm_unmarshal_TPM_SECRET(&ptr, &len, &store.usageAuth);
261   tpm_unmarshal_TPM_DIGEST(&ptr, &len, &store.pubDataDigest);
262   tpm_unmarshal_UINT32(&ptr, &len, &store.privKey.keyLength);
263   store.privKey.keyLength += 16;
264   if (store.privKey.keyLength != len + 16) {
265     error("invalid key length %d; expected %d",
266           store.privKey.keyLength, len + 16);
267     tpm_free(buf);
268     return TPM_DECRYPT_ERROR;
269   }
270   memmove(&buf[20], ptr, len);
271   store.privKey.key = &buf[4];
272   /* encrypt private key */
273   *outDataSize = parent->key.size >> 3;
274   *outData = tpm_malloc(*outDataSize);
275   if (*outData == NULL) {
276     tpm_free(buf);
277     return TPM_NOSPACE;
278   }
279   if (tpm_encrypt_private_key(parent, &store, *outData, outDataSize)) {
280     debug("tpm_encrypt_private_key() failed");
281     tpm_free(*outData);
282     tpm_free(buf);
283     return TPM_ENCRYPT_ERROR;
284   }
285   tpm_free(buf);
286   return TPM_SUCCESS;
287 }
288 
tpm_copy_pubkey(TPM_PUBKEY * in,TPM_PUBKEY * out)289 static int tpm_copy_pubkey(TPM_PUBKEY *in, TPM_PUBKEY *out)
290 {
291   memcpy(out, in, sizeof(TPM_PUBKEY));
292   out->pubKey.key = tpm_malloc(out->pubKey.keyLength);
293   if (out->pubKey.key == NULL) return -1;
294   memcpy(out->pubKey.key, in->pubKey.key, out->pubKey.keyLength);
295   out->algorithmParms.parms.rsa.exponent =
296     tpm_malloc(out->algorithmParms.parms.rsa.exponentSize);
297   if (out->algorithmParms.parms.rsa.exponent == NULL) {
298     tpm_free(out->pubKey.key);
299     return -1;
300   }
301   memcpy(out->algorithmParms.parms.rsa.exponent,
302     in->algorithmParms.parms.rsa.exponent,
303     out->algorithmParms.parms.rsa.exponentSize);
304   return 0;
305 }
306 
TPM_AuthorizeMigrationKey(TPM_MIGRATE_SCHEME migrateScheme,TPM_PUBKEY * migrationKey,TPM_AUTH * auth1,TPM_MIGRATIONKEYAUTH * outData)307 TPM_RESULT TPM_AuthorizeMigrationKey(TPM_MIGRATE_SCHEME migrateScheme,
308                                      TPM_PUBKEY *migrationKey, TPM_AUTH *auth1,
309                                      TPM_MIGRATIONKEYAUTH *outData)
310 {
311   TPM_RESULT res;
312 
313   info("TPM_AuthorizeMigrationKey()");
314   /* verify authorization */
315   res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
316   if (res != TPM_SUCCESS) return res;
317   /* verify the key size and encryption scheme */
318   if (migrationKey->algorithmParms.encScheme != TPM_ES_RSAESOAEP_SHA1_MGF1
319       || migrationKey->algorithmParms.algorithmID != TPM_ALG_RSA)
320     return TPM_INAPPROPRIATE_ENC;
321   if (migrationKey->algorithmParms.parms.rsa.keyLength  < 2048)
322     return TPM_BAD_KEY_PROPERTY;
323   /* create migration key authorization */
324   if (tpm_compute_migration_digest(migrationKey, migrateScheme,
325       &tpmData.permanent.data.tpmProof, &outData->digest) != 0) {
326       debug("tpm_compute_migration_digest() failed");
327       return TPM_FAIL;
328   }
329   outData->migrationScheme = migrateScheme;
330   if (tpm_copy_pubkey(migrationKey, &outData->migrationKey) != 0) {
331       debug("tpm_copy_pubkey() failed");
332       return TPM_FAIL;
333   }
334   return TPM_SUCCESS;
335 }
336 
TPM_MigrateKey(TPM_KEY_HANDLE maKeyHandle,TPM_PUBKEY * pubKey,UINT32 inDataSize,BYTE * inData,TPM_AUTH * auth1,UINT32 * outDataSize,BYTE ** outData)337 TPM_RESULT TPM_MigrateKey(TPM_KEY_HANDLE maKeyHandle, TPM_PUBKEY *pubKey,
338                           UINT32 inDataSize, BYTE *inData, TPM_AUTH *auth1,
339                           UINT32 *outDataSize, BYTE **outData)
340 {
341   TPM_RESULT res;
342   TPM_KEY_DATA *key;
343   TPM_PUBKEY_DATA key2;
344   UINT32 size;
345   BYTE *buf;
346   UINT32 buf_len;
347 
348   info("TPM_MigrateKey()");
349   key = tpm_get_key(maKeyHandle);
350   if (key == NULL) return TPM_INVALID_KEYHANDLE;
351   /* verify key authorization */
352   res = tpm_verify_auth(auth1, key->usageAuth, maKeyHandle);
353   if (res != TPM_SUCCESS) return res;
354   /* verify key usage */
355   if (key->keyUsage != TPM_KEY_MIGRATE) return TPM_BAD_KEY_PROPERTY;
356   if (key->encScheme != TPM_ES_RSAESOAEP_SHA1_MGF1) return TPM_INAPPROPRIATE_ENC;
357   /* verify public key  */
358   if (pubKey->algorithmParms.algorithmID != TPM_ALG_RSA
359       || pubKey->algorithmParms.parms.rsa.keyLength < (inDataSize << 3))
360     return TPM_BAD_KEY_PROPERTY;
361   if (tpm_setup_pubkey_data(pubKey, &key2) != 0) return TPM_FAIL;
362   /* decrypt inData and re-encrypt it with the public key */
363   *outDataSize = size = pubKey->algorithmParms.parms.rsa.keyLength >> 3;
364   *outData = tpm_malloc(*outDataSize);
365   buf_len = inDataSize;
366   buf = tpm_malloc(buf_len);
367   if (*outData == NULL || buf == NULL) {
368     free_TPM_PUBKEY_DATA(key2);
369     tpm_free(*outData);
370     tpm_free(buf);
371     return TPM_NOSPACE;
372   }
373   if (tpm_decrypt(key, inData, inDataSize, buf, &buf_len) != 0) {
374     free_TPM_PUBKEY_DATA(key2);
375     tpm_free(*outData);
376     tpm_free(buf);
377     return TPM_DECRYPT_ERROR;
378   }
379   if (tpm_encrypt_public(&key2, buf, buf_len, *outData, outDataSize) != 0) {
380     free_TPM_PUBKEY_DATA(key2);
381     tpm_free(*outData);
382     tpm_free(buf);
383     return TPM_ENCRYPT_ERROR;
384   }
385   free_TPM_PUBKEY_DATA(key2);
386   tpm_free(buf);
387   return TPM_SUCCESS;
388 }
389 
TPM_CMK_SetRestrictions(TPM_CMK_DELEGATE restriction,TPM_AUTH * auth1)390 TPM_RESULT TPM_CMK_SetRestrictions(TPM_CMK_DELEGATE restriction,
391                                    TPM_AUTH *auth1)
392 {
393   TPM_RESULT res;
394 
395   info("TPM_CMK_SetRestrictions()");
396   /* verify authorization */
397   res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
398   if (res != TPM_SUCCESS) return res;
399   /* update delegation restriction */
400   tpmData.permanent.data.restrictDelegate = restriction;
401   return TPM_SUCCESS;
402 }
403 
TPM_CMK_ApproveMA(TPM_DIGEST * migrationAuthorityDigest,TPM_AUTH * auth1,TPM_HMAC * outData)404 TPM_RESULT TPM_CMK_ApproveMA(TPM_DIGEST *migrationAuthorityDigest,
405                              TPM_AUTH *auth1, TPM_HMAC *outData)
406 {
407   TPM_RESULT res;
408   BYTE buf[2];
409   tpm_hmac_ctx_t ctx;
410 
411   info("TPM_CMK_ApproveMA()");
412   /* verify authorization */
413   res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
414   if (res != TPM_SUCCESS) return res;
415   /* create hmac of a TPM_CMK_MA_APPROVAL structure */
416   buf[0] = (TPM_TAG_CMK_MA_APPROVAL >> 8) & 0xff;
417   buf[1] = TPM_TAG_CMK_MA_APPROVAL & 0xff;
418   tpm_hmac_init(&ctx, tpmData.permanent.data.tpmProof.nonce, sizeof(TPM_NONCE));
419   tpm_hmac_update(&ctx, buf, 2);
420   tpm_hmac_update(&ctx, migrationAuthorityDigest->digest, sizeof(TPM_DIGEST));
421   tpm_hmac_final(&ctx, outData->digest);
422   return TPM_SUCCESS;
423 }
424 
TPM_CMK_CreateKey(TPM_KEY_HANDLE parentHandle,TPM_ENCAUTH * dataUsageAuth,TPM_KEY * keyInfo,TPM_HMAC * migrationAuthorityApproval,TPM_DIGEST * migrationAuthorityDigest,TPM_AUTH * auth1,TPM_AUTH * auth2,TPM_KEY * wrappedKey)425 TPM_RESULT TPM_CMK_CreateKey(TPM_KEY_HANDLE parentHandle,
426                              TPM_ENCAUTH *dataUsageAuth,
427                              TPM_KEY *keyInfo,
428                              TPM_HMAC *migrationAuthorityApproval,
429                              TPM_DIGEST *migrationAuthorityDigest,
430                              TPM_AUTH *auth1, TPM_AUTH *auth2,
431                              TPM_KEY *wrappedKey)
432 {
433   TPM_RESULT res;
434   TPM_KEY_DATA *parent;
435   TPM_SESSION_DATA *session;
436   tpm_hmac_ctx_t ctx;
437   BYTE buf[SHA1_DIGEST_LENGTH];
438   TPM_STORE_ASYMKEY store;
439   tpm_rsa_private_key_t rsa;
440   UINT32 key_length;
441   TPM_PUBKEY pubKey;
442   TPM_DIGEST keyDigest;
443 
444   info("TPM_CMK_CreateKey()");
445   /* get parent key */
446   parent = tpm_get_key(parentHandle);
447   if (parent == NULL) return TPM_INVALID_KEYHANDLE;
448   /* verify authorization */
449   res = tpm_verify_auth(auth1, parent->usageAuth, parentHandle);
450   if (res != TPM_SUCCESS) return res;
451   auth1->continueAuthSession = FALSE;
452   session = tpm_get_auth(auth1->authHandle);
453   if (session->type != TPM_ST_OSAP) return TPM_AUTHFAIL;
454   /* must be TPM_KEY12 */
455   if (keyInfo->tag != TPM_TAG_KEY12) return TPM_INVALID_STRUCTURE;
456   /* verify key parameters */
457   if (parent->keyUsage != TPM_KEY_STORAGE
458       || parent->encScheme == TPM_ES_NONE
459       || parent->keyFlags & TPM_KEY_FLAG_MIGRATABLE
460       || !(keyInfo->keyFlags & TPM_KEY_FLAG_MIGRATABLE)
461       || !(keyInfo->keyFlags & TPM_KEY_FLAG_AUTHORITY)
462       || keyInfo->keyUsage == TPM_KEY_IDENTITY
463       || keyInfo->keyUsage == TPM_KEY_AUTHCHANGE) return TPM_INVALID_KEYUSAGE;
464   if (keyInfo->algorithmParms.algorithmID != TPM_ALG_RSA
465       || keyInfo->algorithmParms.parmSize == 0
466       || keyInfo->algorithmParms.parms.rsa.keyLength < 512
467       || keyInfo->algorithmParms.parms.rsa.numPrimes != 2
468       || keyInfo->algorithmParms.parms.rsa.exponentSize != 0)
469     return TPM_BAD_KEY_PROPERTY;
470   if (tpmData.permanent.flags.FIPS
471       && (keyInfo->algorithmParms.parms.rsa.keyLength < 1024
472           || keyInfo->authDataUsage == TPM_AUTH_NEVER
473           || keyInfo->keyUsage == TPM_KEY_LEGACY)) return TPM_NOTFIPS;
474   if ((keyInfo->keyUsage == TPM_KEY_STORAGE
475        || keyInfo->keyUsage == TPM_KEY_MIGRATE)
476       && (keyInfo->algorithmParms.algorithmID != TPM_ALG_RSA
477           || keyInfo->algorithmParms.parms.rsa.keyLength != 2048
478           || keyInfo->algorithmParms.sigScheme != TPM_SS_NONE
479           || keyInfo->algorithmParms.encScheme != TPM_ES_RSAESOAEP_SHA1_MGF1))
480     return TPM_BAD_KEY_PROPERTY;
481   /* verify migration authority */
482   buf[0] = (TPM_TAG_CMK_MA_APPROVAL >> 8) & 0xff;
483   buf[1] = TPM_TAG_CMK_MA_APPROVAL & 0xff;
484   tpm_hmac_init(&ctx, tpmData.permanent.data.tpmProof.nonce, sizeof(TPM_NONCE));
485   tpm_hmac_update(&ctx, buf, 2);
486   tpm_hmac_update(&ctx, migrationAuthorityDigest->digest, sizeof(TPM_DIGEST));
487   tpm_hmac_final(&ctx, buf);
488   if (memcmp(migrationAuthorityApproval->digest, buf, sizeof(TPM_HMAC)) != 0)
489     return TPM_MA_AUTHORITY;
490   /* setup the wrapped key */
491   memcpy(wrappedKey, keyInfo, sizeof(TPM_KEY));
492   /* setup key store */
493   store.payload = TPM_PT_MIGRATE_RESTRICTED;
494   tpm_decrypt_auth_secret(*dataUsageAuth, session->sharedSecret,
495     &session->lastNonceEven, store.usageAuth);
496   /* compute PCR digest */
497   if (keyInfo->PCRInfoSize > 0) {
498     tpm_compute_pcr_digest(&keyInfo->PCRInfo.creationPCRSelection,
499       &keyInfo->PCRInfo.digestAtCreation, NULL);
500     keyInfo->PCRInfo.localityAtCreation =
501       tpmData.stany.flags.localityModifier;
502   }
503   /* generate key and store it */
504   key_length = keyInfo->algorithmParms.parms.rsa.keyLength;
505   if (tpm_rsa_generate_key(&rsa, key_length)) {
506     debug("TPM_CreateWrapKey(): tpm_rsa_generate_key() failed.");
507     return TPM_FAIL;
508   }
509   wrappedKey->pubKey.keyLength = key_length >> 3;
510   wrappedKey->pubKey.key = tpm_malloc(wrappedKey->pubKey.keyLength);
511   store.privKey.keyLength = key_length >> 4;
512   store.privKey.key = tpm_malloc(store.privKey.keyLength);
513   wrappedKey->encDataSize = parent->key.size >> 3;
514   wrappedKey->encData = tpm_malloc(wrappedKey->encDataSize);
515   if (wrappedKey->pubKey.key == NULL || store.privKey.key == NULL
516       || wrappedKey->encData == NULL) {
517     tpm_rsa_release_private_key(&rsa);
518     tpm_free(wrappedKey->pubKey.key);
519     tpm_free(store.privKey.key);
520     tpm_free(wrappedKey->encData);
521     return TPM_NOSPACE;
522   }
523   tpm_rsa_export_modulus(&rsa, wrappedKey->pubKey.key, NULL);
524   tpm_rsa_export_prime1(&rsa, store.privKey.key, NULL);
525   tpm_rsa_release_private_key(&rsa);
526   /* create hmac of TPM_CMK_MIGAUTH  */
527   buf[0] = (TPM_TAG_CMK_MIGAUTH >> 8) & 0xff;
528   buf[1] = TPM_TAG_CMK_MIGAUTH & 0xff;
529   memcpy(&pubKey.algorithmParms, &wrappedKey->algorithmParms,
530          sizeof(TPM_KEY_PARMS));
531   memcpy(&pubKey.pubKey, &wrappedKey->pubKey, sizeof(TPM_STORE_PUBKEY));
532   if (tpm_compute_pubkey_digest(&pubKey, &keyDigest) !=0 ) {
533     debug("tpm_compute_pubkey_digest() failed");
534     return TPM_FAIL;
535   }
536   tpm_hmac_init(&ctx, tpmData.permanent.data.tpmProof.nonce, sizeof(TPM_NONCE));
537   tpm_hmac_update(&ctx, buf, 2);
538   tpm_hmac_update(&ctx, migrationAuthorityDigest->digest, sizeof(TPM_DIGEST));
539   tpm_hmac_update(&ctx, keyDigest.digest, sizeof(TPM_DIGEST));
540   tpm_hmac_final(&ctx, store.migrationAuth);
541   /* compute the digest of the wrapped key (without encData) */
542   if (tpm_compute_key_digest(wrappedKey, &store.pubDataDigest)) {
543     debug("TPM_CreateWrapKey(): tpm_compute_key_digest() failed.");
544     return TPM_FAIL;
545   }
546   /* encrypt private key data */
547   if (tpm_encrypt_private_key(parent, &store, wrappedKey->encData,
548       &wrappedKey->encDataSize)) {
549     tpm_free(wrappedKey->pubKey.key);
550     tpm_free(store.privKey.key);
551     tpm_free(wrappedKey->encData);
552     return TPM_ENCRYPT_ERROR;
553   }
554   tpm_free(store.privKey.key);
555   return TPM_SUCCESS;
556 }
557 
TPM_CMK_CreateTicket(TPM_PUBKEY * verificationKey,TPM_DIGEST * signedData,UINT32 signatureValueSize,BYTE * signatureValue,TPM_AUTH * auth1,TPM_DIGEST * sigTicket)558 TPM_RESULT TPM_CMK_CreateTicket(TPM_PUBKEY *verificationKey,
559                                 TPM_DIGEST *signedData,
560                                 UINT32 signatureValueSize,
561                                 BYTE *signatureValue, TPM_AUTH *auth1,
562                                 TPM_DIGEST *sigTicket)
563 {
564   TPM_RESULT res;
565   TPM_PUBKEY_DATA key;
566   BYTE buf[2];
567   TPM_DIGEST keyDigest;
568   tpm_hmac_ctx_t ctx;
569 
570   info("TPM_CMK_CreateTicket()");
571   /* verify authorization */
572   res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
573   /* verify key type and algorithm */
574   if (verificationKey->algorithmParms.algorithmID != TPM_ALG_RSA
575       || verificationKey->algorithmParms.encScheme != TPM_ES_NONE)
576     return TPM_BAD_KEY_PROPERTY;
577   if (verificationKey->algorithmParms.sigScheme != TPM_SS_RSASSAPKCS1v15_SHA1
578       && verificationKey->algorithmParms.sigScheme != TPM_SS_RSASSAPKCS1v15_INFO)
579     return TPM_BAD_KEY_PROPERTY;
580   /* verify signature */
581   if (tpm_setup_pubkey_data(verificationKey, &key) != 0) return TPM_FAIL;
582   res = tpm_verify(&key, auth1, FALSE, signedData->digest, sizeof(TPM_DIGEST),
583                    signatureValue, signatureValueSize);
584   free_TPM_PUBKEY_DATA(key);
585   if (res != TPM_SUCCESS) return res;
586   /* create hmac on TPM_CMK_SIGTICKET */
587   buf[0] = (TPM_TAG_CMK_SIGTICKET >> 8) & 0xff;
588   buf[1] = TPM_TAG_CMK_SIGTICKET & 0xff;
589   if (tpm_compute_pubkey_digest(verificationKey, &keyDigest) !=0 ) {
590     debug("tpm_compute_pubkey_digest() failed");
591     return TPM_FAIL;
592   }
593   tpm_hmac_init(&ctx, tpmData.permanent.data.tpmProof.nonce, sizeof(TPM_NONCE));
594   tpm_hmac_update(&ctx, buf, 2);
595   tpm_hmac_update(&ctx, keyDigest.digest, sizeof(TPM_DIGEST));
596   tpm_hmac_update(&ctx, signedData->digest, sizeof(TPM_DIGEST));
597   tpm_hmac_final(&ctx, sigTicket->digest);
598   return TPM_SUCCESS;
599 }
600 
TPM_CMK_CreateBlob(TPM_KEY_HANDLE parentHandle,TPM_MIGRATE_SCHEME migrationType,TPM_MIGRATIONKEYAUTH * migrationKeyAuth,TPM_DIGEST * pubSourceKeyDigest,TPM_MSA_COMPOSITE * msaList,TPM_CMK_AUTH * restrictTicket,TPM_HMAC * sigTicket,UINT32 encDataSize,BYTE * encData,TPM_AUTH * auth1,UINT32 * randomSize,BYTE ** random,UINT32 * outDataSize,BYTE ** outData)601 TPM_RESULT TPM_CMK_CreateBlob(TPM_KEY_HANDLE parentHandle,
602                               TPM_MIGRATE_SCHEME migrationType,
603                               TPM_MIGRATIONKEYAUTH *migrationKeyAuth,
604                               TPM_DIGEST *pubSourceKeyDigest,
605                               TPM_MSA_COMPOSITE *msaList,
606                               TPM_CMK_AUTH *restrictTicket,
607                               TPM_HMAC *sigTicket,
608                               UINT32 encDataSize, BYTE *encData,
609                               TPM_AUTH *auth1,
610                               UINT32 *randomSize, BYTE **random,
611                               UINT32 *outDataSize, BYTE **outData)
612 {
613   TPM_RESULT res;
614   TPM_KEY_DATA *parent;
615   TPM_STORE_ASYMKEY store;
616   BYTE *key_buf;
617   UINT32 key_buf_size;
618   tpm_hmac_ctx_t hmac_ctx;
619   tpm_sha1_ctx_t sha1_ctx;
620   BYTE tag[2], hmac[SHA1_DIGEST_LENGTH];
621   BYTE *ptr, *buf;
622   UINT32 i, len;
623   size_t buf_len;
624   TPM_DIGEST migKeyDigest;
625   TPM_DIGEST msaListDigest;
626   TPM_DIGEST ticketDigest;
627   TPM_PUBKEY_DATA key;
628 
629   info("TPM_CMK_CreateBlob()");
630   /* get parent key */
631   parent = tpm_get_key(parentHandle);
632   if (parent == NULL) return TPM_INVALID_KEYHANDLE;
633   /* verify authorization */
634   res = tpm_verify_auth(auth1, parent->usageAuth, parentHandle);
635   if (res != TPM_SUCCESS) return res;
636   /* migrationType must match */
637   if (migrationType != migrationKeyAuth->migrationScheme) return TPM_BAD_MODE;
638   if (parent->keyFlags & TPM_KEY_FLAG_MIGRATABLE) return TPM_BAD_KEY_PROPERTY;
639   /* decrypt private key */
640   if (tpm_decrypt_private_key(parent, encData, encDataSize,
641                               &store, &key_buf, &key_buf_size) != 0) {
642     return TPM_DECRYPT_ERROR;
643   }
644   if (store.payload != TPM_PT_MIGRATE_RESTRICTED
645       && store.payload != TPM_PT_MIGRATE_EXTERNAL) {
646     tpm_free(key_buf);
647     return TPM_DECRYPT_ERROR;
648   }
649   if (tpm_verify_migration_digest(migrationKeyAuth,
650       &tpmData.permanent.data.tpmProof)) {
651     debug("tpm_verify_migration_digest() failed");
652     tpm_free(key_buf);
653     return TPM_MIGRATEFAIL;
654   }
655   /* verify the migration authority list */
656   len = sizeof_TPM_MSA_COMPOSITE((*msaList));
657   ptr = buf = tpm_malloc(len);
658   if (buf == NULL || tpm_marshal_TPM_MSA_COMPOSITE(&ptr, &len, msaList)) {
659     debug("tpm_marshal_TPM_MSA_COMPOSITE() failed");
660     tpm_free(buf);
661     tpm_free(key_buf);
662     return TPM_FAIL;
663   }
664   tpm_sha1_init(&sha1_ctx);
665   tpm_sha1_update(&sha1_ctx, buf, sizeof_TPM_MSA_COMPOSITE((*msaList)));
666   tpm_sha1_final(&sha1_ctx, msaListDigest.digest);
667   tpm_free(buf);
668   tag[0] = (TPM_TAG_CMK_MIGAUTH >> 8) & 0xff;
669   tag[1] = TPM_TAG_CMK_MIGAUTH & 0xff;
670   tpm_hmac_init(&hmac_ctx, tpmData.permanent.data.tpmProof.nonce, sizeof(TPM_NONCE));
671   tpm_hmac_update(&hmac_ctx, tag, 2);
672   tpm_hmac_update(&hmac_ctx, msaListDigest.digest, sizeof(TPM_DIGEST));
673   tpm_hmac_update(&hmac_ctx, pubSourceKeyDigest->digest, sizeof(TPM_DIGEST));
674   tpm_hmac_final(&hmac_ctx, hmac);
675   if (memcmp(hmac, store.migrationAuth, sizeof(TPM_SECRET)) != 0) {
676     tpm_free(key_buf);
677     return TPM_MA_AUTHORITY;
678   }
679   if (tpm_compute_pubkey_digest(&migrationKeyAuth->migrationKey, &migKeyDigest) !=0 ) {
680     debug("tpm_compute_pubkey_digest() failed");
681     tpm_free(key_buf);
682     return TPM_FAIL;
683   }
684   len = sizeof_TPM_CMK_AUTH((*restrictTicket));
685   ptr = buf = tpm_malloc(len);
686   if (buf == NULL || tpm_marshal_TPM_CMK_AUTH(&ptr, &len, restrictTicket)) {
687     debug("tpm_marshal_TPM_CMK_AUTH() failed");
688     tpm_free(buf);
689     tpm_free(key_buf);
690     return TPM_FAIL;
691   }
692   tpm_sha1_init(&sha1_ctx);
693   tpm_sha1_update(&sha1_ctx, buf, sizeof_TPM_CMK_AUTH((*restrictTicket)));
694   tpm_sha1_final(&sha1_ctx, ticketDigest.digest);
695   tpm_free(buf);
696   /* verify the migration destination */
697   if (migrationKeyAuth->migrationScheme == TPM_MS_RESTRICT_MIGRATE) {
698     for (i = 0; i < msaList->MSAlist; i++) {
699         if (memcmp(msaList->migAuthDigest[i].digest, migKeyDigest.digest,
700                    sizeof(TPM_DIGEST)) == 0) break;
701     }
702     if (i >= msaList->MSAlist) {
703       tpm_free(key_buf);
704       return TPM_MA_AUTHORITY;
705     }
706     /* verify the key type and algorithm */
707     if (migrationKeyAuth->migrationKey.algorithmParms.algorithmID != TPM_ALG_RSA
708         || migrationKeyAuth->migrationKey.algorithmParms.encScheme != TPM_ES_RSAESOAEP_SHA1_MGF1
709         || migrationKeyAuth->migrationKey.algorithmParms.sigScheme != TPM_SS_NONE) {
710       tpm_free(key_buf);
711       return TPM_BAD_KEY_PROPERTY;
712     }
713   } else if (migrationKeyAuth->migrationScheme == TPM_MS_RESTRICT_APPROVE) {
714     if (restrictTicket == NULL || sigTicket == NULL) {
715       tpm_free(key_buf);
716       return TPM_BAD_PARAMETER;
717     }
718     for (i = 0; i < msaList->MSAlist; i++) {
719       /* create hmac of TPM_CMK_SIGTICKET */
720       tag[0] = (TPM_TAG_CMK_SIGTICKET >> 8) & 0xff;
721       tag[1] = TPM_TAG_CMK_SIGTICKET & 0xff;
722       tpm_hmac_init(&hmac_ctx, tpmData.permanent.data.tpmProof.nonce,
723                     sizeof(TPM_NONCE));
724       tpm_hmac_update(&hmac_ctx, tag, 2);
725       tpm_hmac_update(&hmac_ctx, msaList->migAuthDigest[i].digest,
726                       sizeof(TPM_DIGEST));
727       tpm_hmac_update(&hmac_ctx, ticketDigest.digest, sizeof(TPM_DIGEST));
728       tpm_hmac_final(&hmac_ctx, hmac);
729       if (memcmp(hmac, sigTicket->digest, sizeof(TPM_DIGEST)) == 0) break;
730     }
731     if (i >= msaList->MSAlist) {
732       tpm_free(key_buf);
733       return TPM_MA_AUTHORITY;
734     }
735     if (memcmp(&restrictTicket->destinationKeyDigest, &migKeyDigest,
736                sizeof(TPM_DIGEST)) != 0) {
737       tpm_free(key_buf);
738       return TPM_MA_DESTINATION;
739     }
740     if (memcmp(&restrictTicket->sourceKeyDigest, pubSourceKeyDigest,
741                sizeof(TPM_DIGEST)) != 0) {
742       tpm_free(key_buf);
743       return TPM_MA_SOURCE;
744     }
745   } else {
746     tpm_free(key_buf);
747     return TPM_BAD_PARAMETER;
748   }
749   /* set public key */
750   if (tpm_setup_pubkey_data(&migrationKeyAuth->migrationKey, &key) != 0) {
751     debug("tpm_setup_pubkey() failed");
752     tpm_free(key_buf);
753     return TPM_FAIL;
754   }
755   /* generate an OAEP encoding of the TPM_MIGRATE_ASYMKEY structure:
756      0x00|seed|K1|0x00-pad|0x01|TPM_MIGRATE_ASYMKEY */
757   len = buf_len = 198;
758   ptr = buf = tpm_malloc(buf_len);
759   *randomSize = buf_len;
760   *random = tpm_malloc(*randomSize);
761   *outDataSize = key.key.size >> 3;
762   *outData = tpm_malloc(*outDataSize);
763   if (buf == NULL || *random == NULL || *outData == NULL) {
764     free_TPM_PUBKEY_DATA(key);
765     tpm_free(buf);
766     tpm_free(*random);
767     tpm_free(*outData);
768     tpm_free(key_buf);
769     return TPM_NOSPACE;
770   }
771   memset(buf, 0, buf_len);
772   tpm_marshal_UINT32(&ptr, &len, store.privKey.keyLength);
773   memcpy(ptr, store.privKey.key, 16);
774   ptr += 16;
775   tpm_sha1_init(&sha1_ctx);
776   tpm_sha1_update(&sha1_ctx, msaListDigest.digest, sizeof(TPM_DIGEST));
777   tpm_sha1_update(&sha1_ctx, pubSourceKeyDigest->digest, sizeof(TPM_DIGEST));
778   tpm_sha1_final(&sha1_ctx, ptr);
779   len = 46 + store.privKey.keyLength - 16;
780   ptr = &buf[buf_len - len];
781   tpm_marshal_BYTE(&ptr, &len, 0x01);
782   tpm_marshal_TPM_PAYLOAD_TYPE(&ptr, &len, TPM_PT_CMK_MIGRATE);
783   tpm_marshal_TPM_SECRET(&ptr, &len, &store.usageAuth);
784   tpm_marshal_TPM_DIGEST(&ptr, &len, &store.pubDataDigest);
785   tpm_marshal_UINT32(&ptr, &len, store.privKey.keyLength - 16);
786   memcpy(ptr, &store.privKey.key[16], store.privKey.keyLength - 16);
787   tpm_rsa_mask_generation(buf, SHA1_DIGEST_LENGTH,
788     &buf[SHA1_DIGEST_LENGTH], buf_len - SHA1_DIGEST_LENGTH);
789   tpm_rsa_mask_generation(&buf[SHA1_DIGEST_LENGTH],
790     buf_len - SHA1_DIGEST_LENGTH, buf, SHA1_DIGEST_LENGTH);
791   /* XOR encrypt OAEP encoding */
792   tpm_get_random_bytes(*random, *randomSize);
793   for (len = 0; len < buf_len; len++) buf[len] ^= (*random)[len];
794   /* RSA encrypt OAEP encoding */
795   if (tpm_rsa_encrypt(&key.key, RSA_ES_OAEP_SHA1, buf, buf_len,
796                       *outData, &buf_len)) {
797     debug("tpm_rsa_encrypt() failed");
798     free_TPM_PUBKEY_DATA(key);
799     tpm_free(buf);
800     tpm_free(*random);
801     tpm_free(*outData);
802     tpm_free(key_buf);
803     return TPM_ENCRYPT_ERROR;
804   }
805   *outDataSize = buf_len;
806   free_TPM_PUBKEY_DATA(key);
807   tpm_free(key_buf);
808   tpm_free(buf);
809   return TPM_SUCCESS;
810 }
811 
TPM_CMK_ConvertMigration(TPM_KEY_HANDLE parentHandle,TPM_CMK_AUTH * restrictTicket,TPM_HMAC * sigTicket,TPM_KEY * migratedKey,TPM_MSA_COMPOSITE * msaList,UINT32 randomSize,BYTE * random,TPM_AUTH * auth1,UINT32 * outDataSize,BYTE ** outData)812 TPM_RESULT TPM_CMK_ConvertMigration(TPM_KEY_HANDLE parentHandle,
813                                     TPM_CMK_AUTH *restrictTicket,
814                                     TPM_HMAC *sigTicket, TPM_KEY *migratedKey,
815                                     TPM_MSA_COMPOSITE *msaList,
816                                     UINT32 randomSize, BYTE *random,
817                                     TPM_AUTH *auth1,
818                                     UINT32 *outDataSize, BYTE **outData)
819 {
820   TPM_RESULT res;
821   TPM_KEY_DATA *parent;
822   BYTE *ptr, *buf, *buf2;
823   UINT32 i, len;
824   size_t buf_len;
825   BYTE tag[2], hmac[SHA1_DIGEST_LENGTH];
826   TPM_STORE_ASYMKEY store;
827   tpm_sha1_ctx_t sha1_ctx;
828   tpm_hmac_ctx_t hmac_ctx;
829   TPM_PUBKEY migratedPubKey;
830   TPM_PUBKEY parentPubKey;
831   TPM_DIGEST migKeyDigest;
832   TPM_DIGEST msaListDigest;
833   TPM_DIGEST ticketDigest;
834   TPM_DIGEST parentDigest;
835 
836   info("TPM_CMK_ConvertMigration()");
837   /* get parent key */
838   parent = tpm_get_key(parentHandle);
839   if (parent == NULL) return TPM_INVALID_KEYHANDLE;
840   /* verify authorization */
841   if (auth1->authHandle != TPM_INVALID_HANDLE
842       || parent->authDataUsage != TPM_AUTH_NEVER) {
843     res = tpm_verify_auth(auth1, parent->usageAuth, parentHandle);
844     if (res != TPM_SUCCESS) return res;
845   }
846   /* verify key properties */
847   if (parent->keyUsage != TPM_KEY_STORAGE
848       || parent->keyFlags & TPM_KEY_FLAG_MIGRATABLE) return TPM_INVALID_KEYUSAGE;
849   if (!(migratedKey->keyFlags & TPM_KEY_FLAG_MIGRATABLE)
850       && (!(migratedKey->keyFlags & TPM_KEY_FLAG_AUTHORITY))) return TPM_INVALID_KEYUSAGE;
851   /* decrypt private key */
852   buf_len = parent->key.size >> 3;
853   buf = tpm_malloc(buf_len);
854   if (buf == NULL) return TPM_NOSPACE;
855   /* RSA decrypt OAEP encoding */
856   if (tpm_rsa_decrypt(&parent->key, RSA_ES_OAEP_SHA1, migratedKey->encData,
857                       migratedKey->encDataSize, buf, &buf_len)
858       || buf_len != randomSize || buf_len != 198) {
859     debug("tpm_rsa_decrypt() failed");
860     tpm_free(buf);
861     return TPM_DECRYPT_ERROR;
862   }
863   /* XOR decrypt OAEP encoding */
864   for (len = 0; len < buf_len; len++) buf[len] ^= random[len];
865   /* unmask OAEP encoding */
866   tpm_rsa_mask_generation(&buf[SHA1_DIGEST_LENGTH],
867     buf_len - SHA1_DIGEST_LENGTH , buf, SHA1_DIGEST_LENGTH);
868   tpm_rsa_mask_generation(buf, SHA1_DIGEST_LENGTH,
869     &buf[SHA1_DIGEST_LENGTH], buf_len - SHA1_DIGEST_LENGTH);
870   /* compute digest of migrated public key */
871   memcpy(&migratedPubKey.algorithmParms, &migratedKey->algorithmParms,
872          sizeof(TPM_KEY_PARMS));
873   memcpy(&migratedPubKey.pubKey, &migratedKey->pubKey, sizeof(TPM_STORE_PUBKEY));
874   if (tpm_compute_pubkey_digest(&migratedPubKey, &migKeyDigest) != 0) {
875     debug("tpm_compute_pubkey_digest() failed");
876     tpm_free(buf);
877     return TPM_FAIL;
878   }
879   /* compute digest of parent key */
880   parentPubKey.pubKey.keyLength = parent->key.size >> 3;
881   parentPubKey.pubKey.key = tpm_malloc(parentPubKey.pubKey.keyLength);
882   if (parentPubKey.pubKey.key == NULL) {
883     tpm_free(buf);
884     return TPM_NOSPACE;
885   }
886   tpm_rsa_export_modulus(&parent->key, parentPubKey.pubKey.key, NULL);
887   if (tpm_setup_key_parms(parent, &parentPubKey.algorithmParms) != 0) {
888     debug("tpm_setup_key_parms() failed.");
889     tpm_free(parentPubKey.pubKey.key);
890     tpm_free(buf);
891     return TPM_FAIL;
892   }
893   if (tpm_compute_pubkey_digest(&parentPubKey, &parentDigest) != 0) {
894     debug("tpm_compute_pubkey_digest() failed.");
895     free_TPM_PUBKEY(parentPubKey);
896     tpm_free(buf);
897     return TPM_FAIL;
898   }
899   free_TPM_PUBKEY(parentPubKey);
900   /* compute digest of msaList */
901   len = sizeof_TPM_MSA_COMPOSITE((*msaList));
902   ptr = buf2 = tpm_malloc(len);
903   if (buf2 == NULL || tpm_marshal_TPM_MSA_COMPOSITE(&ptr, &len, msaList)) {
904     debug("tpm_marshal_TPM_MSA_COMPOSITE() failed");
905     tpm_free(buf2);
906     tpm_free(buf);
907     return TPM_FAIL;
908   }
909   tpm_sha1_init(&sha1_ctx);
910   tpm_sha1_update(&sha1_ctx, buf2, sizeof_TPM_MSA_COMPOSITE((*msaList)));
911   tpm_sha1_final(&sha1_ctx, msaListDigest.digest);
912   tpm_free(buf2);
913   /* compute digest of restrictedTicket */
914   len = sizeof_TPM_CMK_AUTH((*restrictTicket));
915   ptr = buf2 = tpm_malloc(len);
916   if (buf2 == NULL || tpm_marshal_TPM_CMK_AUTH(&ptr, &len, restrictTicket)) {
917     debug("tpm_marshal_TPM_CMK_AUTH() failed");
918     tpm_free(buf2);
919     tpm_free(buf);
920     return TPM_FAIL;
921   }
922   tpm_sha1_init(&sha1_ctx);
923   tpm_sha1_update(&sha1_ctx, buf2, sizeof_TPM_CMK_AUTH((*restrictTicket)));
924   tpm_sha1_final(&sha1_ctx, ticketDigest.digest);
925   tpm_free(buf2);
926   /* verify decoded data */
927   tpm_sha1_init(&sha1_ctx);
928   tpm_sha1_update(&sha1_ctx, msaListDigest.digest, sizeof(TPM_DIGEST));
929   tpm_sha1_update(&sha1_ctx, migKeyDigest.digest, sizeof(TPM_DIGEST));
930   tpm_sha1_final(&sha1_ctx, hmac);
931   if (memcmp(&buf[20], hmac, sizeof(TPM_DIGEST)) != 0) {
932     tpm_free(buf);
933     return TPM_INVALID_STRUCTURE;
934   }
935   /* create a TPM_STORE_ASYMKEY structure */
936   for (ptr = &buf[40]; *ptr == 0x00; ptr++);
937   if (ptr[0] != 0x01 || ptr[1] != TPM_PT_CMK_MIGRATE) {
938     debug("OAEP encoding is invalid");
939     tpm_free(buf);
940     return TPM_DECRYPT_ERROR;
941   }
942   ptr += 2;
943   len = buf_len - (ptr - buf);
944   store.payload = TPM_PT_MIGRATE_EXTERNAL;
945   tpm_unmarshal_TPM_SECRET(&ptr, &len, &store.usageAuth);
946   tpm_unmarshal_TPM_DIGEST(&ptr, &len, &store.pubDataDigest);
947   tpm_unmarshal_UINT32(&ptr, &len, &store.privKey.keyLength);
948   store.privKey.keyLength += 16;
949   if (store.privKey.keyLength != len + 16) {
950     error("invalid key length %d; expected %d",
951           store.privKey.keyLength, len + 16);
952     tpm_free(buf);
953     return TPM_DECRYPT_ERROR;
954   }
955   memmove(&buf[20], ptr, len);
956   store.privKey.key = &buf[4];
957   tag[0] = (TPM_TAG_CMK_MIGAUTH >> 8) & 0xff;
958   tag[1] = TPM_TAG_CMK_MIGAUTH & 0xff;
959   tpm_hmac_init(&hmac_ctx, tpmData.permanent.data.tpmProof.nonce, sizeof(TPM_NONCE));
960   tpm_hmac_update(&hmac_ctx, tag, 2);
961   tpm_hmac_update(&hmac_ctx, msaListDigest.digest, sizeof(TPM_DIGEST));
962   tpm_hmac_update(&hmac_ctx, migKeyDigest.digest, sizeof(TPM_DIGEST));
963   tpm_hmac_final(&hmac_ctx, store.migrationAuth);
964   /* verify the migration destination */
965   for (i = 0; i < msaList->MSAlist; i++) {
966     /* create hmac of TPM_CMK_SIGTICKET */
967     tag[0] = (TPM_TAG_CMK_SIGTICKET >> 8) & 0xff;
968     tag[1] = TPM_TAG_CMK_SIGTICKET & 0xff;
969     tpm_hmac_init(&hmac_ctx, tpmData.permanent.data.tpmProof.nonce,
970                   sizeof(TPM_NONCE));
971     tpm_hmac_update(&hmac_ctx, tag, 2);
972     tpm_hmac_update(&hmac_ctx, msaList->migAuthDigest[i].digest,
973                     sizeof(TPM_DIGEST));
974     tpm_hmac_update(&hmac_ctx, ticketDigest.digest, sizeof(TPM_DIGEST));
975     tpm_hmac_final(&hmac_ctx, hmac);
976     if (memcmp(hmac, sigTicket->digest, sizeof(TPM_DIGEST)) == 0) break;
977   }
978   if (i >= msaList->MSAlist) {
979     tpm_free(buf);
980     return TPM_MA_AUTHORITY;
981   }
982   if (memcmp(&restrictTicket->destinationKeyDigest, &parentDigest,
983              sizeof(TPM_DIGEST)) != 0) {
984     tpm_free(buf);
985     return TPM_MA_DESTINATION;
986   }
987   if (memcmp(&restrictTicket->sourceKeyDigest, &migKeyDigest,
988              sizeof(TPM_DIGEST)) != 0) {
989     tpm_free(buf);
990     return TPM_MA_SOURCE;
991   }
992   /* encrypt private key */
993   *outDataSize = parent->key.size >> 3;
994   *outData = tpm_malloc(*outDataSize);
995   if (*outData == NULL) {
996     tpm_free(buf);
997     return TPM_NOSPACE;
998   }
999   if (tpm_encrypt_private_key(parent, &store, *outData, outDataSize)) {
1000     debug("tpm_encrypt_private_key() failed");
1001     tpm_free(*outData);
1002     tpm_free(buf);
1003     return TPM_ENCRYPT_ERROR;
1004   }
1005   tpm_free(buf);
1006   return TPM_SUCCESS;
1007 }
1008