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