blob: 80f97aac7ae019d795c4919daefcd3724fc81b3b [file] [log] [blame]
/* Software-based Trusted Platform Module (TPM) Emulator
* Copyright (C) 2004-2010 Mario Strasser <mast@gmx.net>
* 2005-2008 Heiko Stamer <stamer@gaos.org>
*
* This module is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This module is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* $Id: tpm_deprecated.c 364 2010-02-11 10:24:45Z mast $
*/
#include "tpm_emulator.h"
#include "tpm_commands.h"
#include "tpm_data.h"
#include "tpm_handles.h"
#include "tpm_marshalling.h"
#include "crypto/rsa.h"
#include "crypto/sha1.h"
#include "crypto/hmac.h"
#define SAVE_KEY_CONTEXT_LABEL ((uint8_t*)"SaveKeyContext..")
#define SAVE_AUTH_CONTEXT_LABEL ((uint8_t*)"SaveAuthContext.")
/*
* Deprecated commands ([TPM_Part3], Section 28)
* This section covers the commands that were in version 1.1 but now have
* new functionality in other functions. The deprecated commands are still
* available in 1.2 but all new software should use the new functionality.
* There is no requirement that the deprecated commands work with new
* structures.
*/
TPM_RESULT TPM_EvictKey(TPM_KEY_HANDLE evictHandle)
{
info("TPM_EvictKey()");
return TPM_FlushSpecific(evictHandle, TPM_RT_KEY);
}
TPM_RESULT TPM_Terminate_Handle(TPM_AUTHHANDLE handle)
{
info("TPM_Terminate_Handle()");
return TPM_FlushSpecific(handle, TPM_RT_AUTH);
}
TPM_RESULT TPM_SaveKeyContext(TPM_KEY_HANDLE keyHandle,
UINT32 *keyContextSize, BYTE **keyContextBlob)
{
TPM_RESULT res;
TPM_CONTEXT_BLOB contextBlob;
BYTE *ptr;
UINT32 len;
info("TPM_SaveKeyContext()");
res = TPM_SaveContext(keyHandle, TPM_RT_KEY, SAVE_KEY_CONTEXT_LABEL,
keyContextSize, &contextBlob);
if (res != TPM_SUCCESS) return res;
len = *keyContextSize;
*keyContextBlob = ptr = tpm_malloc(len);
if (ptr == NULL
|| tpm_marshal_TPM_CONTEXT_BLOB(&ptr, &len, &contextBlob)) res = TPM_FAIL;
else res = TPM_SUCCESS;
free_TPM_CONTEXT_BLOB(contextBlob);
return res;
}
TPM_RESULT TPM_LoadKeyContext(UINT32 keyContextSize,
BYTE *keyContextBlob, TPM_KEY_HANDLE *keyHandle)
{
TPM_CONTEXT_BLOB contextBlob;
UINT32 len = keyContextSize;
info("TPM_LoadKeyContext()");
if (tpm_unmarshal_TPM_CONTEXT_BLOB(&keyContextBlob,
&len, &contextBlob)) return TPM_FAIL;
return TPM_LoadContext(FALSE, TPM_INVALID_HANDLE, keyContextSize,
&contextBlob, keyHandle);
}
TPM_RESULT TPM_SaveAuthContext(TPM_AUTHHANDLE authHandle,
UINT32 *authContextSize, BYTE **authContextBlob)
{
TPM_RESULT res;
TPM_CONTEXT_BLOB contextBlob;
BYTE *ptr;
UINT32 len;
info("TPM_SaveAuthContext()");
res = TPM_SaveContext(authHandle, TPM_RT_KEY, SAVE_AUTH_CONTEXT_LABEL,
authContextSize, &contextBlob);
if (res != TPM_SUCCESS) return res;
len = *authContextSize;
*authContextBlob = ptr = tpm_malloc(len);
if (ptr == NULL
|| tpm_marshal_TPM_CONTEXT_BLOB(&ptr, &len, &contextBlob)) res = TPM_FAIL;
else res = TPM_SUCCESS;
free_TPM_CONTEXT_BLOB(contextBlob);
return res;
}
TPM_RESULT TPM_LoadAuthContext(UINT32 authContextSize, BYTE *authContextBlob,
TPM_KEY_HANDLE *authHandle)
{
TPM_CONTEXT_BLOB contextBlob;
UINT32 len = authContextSize;
info("TPM_LoadAuthContext()");
if (tpm_unmarshal_TPM_CONTEXT_BLOB(&authContextBlob,
&len, &contextBlob)) return TPM_FAIL;
return TPM_LoadContext(FALSE, TPM_INVALID_HANDLE, authContextSize,
&contextBlob, authHandle);
}
TPM_RESULT TPM_DirWriteAuth(TPM_DIRINDEX dirIndex,
TPM_DIRVALUE *newContents, TPM_AUTH *auth1)
{
TPM_RESULT res;
info("TPM_DirWriteAuth()");
res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
if (res != TPM_SUCCESS) return res;
if (dirIndex != 0) return TPM_BADINDEX;
memcpy(tpmData.permanent.data.nvData
+ tpmData.permanent.data.nvStorage[0].dataIndex,
newContents, sizeof(TPM_DIRVALUE));
return TPM_SUCCESS;
}
TPM_RESULT TPM_DirRead(TPM_DIRINDEX dirIndex, TPM_DIRVALUE *dirContents)
{
info("TPM_DirRead()");
if (dirIndex != 0) return TPM_BADINDEX;
memcpy(dirContents, tpmData.permanent.data.nvData
+ tpmData.permanent.data.nvStorage[0].dataIndex,
sizeof(TPM_DIRVALUE));
return TPM_SUCCESS;
}
TPM_RESULT TPM_ChangeAuthAsymStart(TPM_KEY_HANDLE idHandle,
TPM_NONCE *antiReplay,
TPM_KEY_PARMS *inTempKey,
TPM_AUTH *auth1,
TPM_CERTIFY_INFO *certifyInfo,
UINT32 *sigSize, BYTE **sig,
TPM_KEY_HANDLE *ephHandle,
TPM_KEY *outTempKey)
{
TPM_RESULT res;
TPM_KEY_DATA *idKey;
tpm_rsa_private_key_t k1;
UINT32 key_length;
TPM_STORE_ASYMKEY store;
TPM_KEY ephKey;
UINT32 len, size;
BYTE *ptr, *buf;
info("TPM_ChangeAuthAsymStart()");
/* 1. The TPM SHALL verify the AuthData to use the TPM identity key held in
idHandle. The TPM MUST verify that the key is a TPM identity key. */
/* get identity key */
idKey = tpm_get_key(idHandle);
if (idKey == NULL) return TPM_INVALID_KEYHANDLE;
/* verify authorization */
if (auth1->authHandle != TPM_INVALID_HANDLE
|| idKey->authDataUsage != TPM_AUTH_NEVER) {
res = tpm_verify_auth(auth1, idKey->usageAuth, idHandle);
if (res != TPM_SUCCESS) return res;
}
/* verify key parameters */
if (idKey->keyUsage != TPM_KEY_IDENTITY) return TPM_INVALID_KEYUSAGE;
/* 2. The TPM SHALL validate the algorithm parameters for the key to create
from the tempKey parameter. */
/* 3. Recommended key type is RSA */
/* 4. Minimum RSA key size MUST is 512 bits, recommended RSA key size
is 1024 */
/* 5. For other key types the minimum key size strength MUST be
comparable to RSA 512 */
/* 6. If the TPM is not designed to create a key of the requested type,
return the error code TPM_BAD_KEY_PROPERTY */
if (inTempKey->algorithmID != TPM_ALG_RSA
|| inTempKey->encScheme != TPM_ES_RSAESOAEP_SHA1_MGF1
|| inTempKey->parmSize == 0
|| inTempKey->parms.rsa.keyLength < 512
|| inTempKey->parms.rsa.numPrimes != 2
|| inTempKey->parms.rsa.exponentSize != 0)
return TPM_BAD_KEY_PROPERTY;
/* 7. The TPM SHALL create a new key (k1) in accordance with the
algorithm parameter.
The newly created key is pointed to by ephHandle. */
/* generate key */
key_length = inTempKey->parms.rsa.keyLength;
if (tpm_rsa_generate_key(&k1, key_length)) {
debug("TPM_ChangeAuthAsymStart(): tpm_rsa_generate_key() failed.");
return TPM_FAIL;
}
/* setup private key store */
store.payload = TPM_PT_ASYM;
memcpy(store.usageAuth, tpmData.permanent.data.tpmProof.nonce,
sizeof(TPM_SECRET));
memcpy(store.migrationAuth, tpmData.permanent.data.tpmProof.nonce,
sizeof(TPM_SECRET));
store.privKey.keyLength = key_length >> 4;
store.privKey.key = tpm_malloc(store.privKey.keyLength);
if (store.privKey.key == NULL) {
tpm_rsa_release_private_key(&k1);
return TPM_NOSPACE;
}
tpm_rsa_export_prime1(&k1, store.privKey.key, NULL);
/* setup ephKey */
ephKey.tag = 0x0101;
ephKey.fill = 0x0000;
ephKey.keyUsage = TPM_KEY_AUTHCHANGE;
ephKey.keyFlags = TPM_KEY_FLAG_VOLATILE;
ephKey.authDataUsage = TPM_AUTH_NEVER;
ephKey.algorithmParms.algorithmID = inTempKey->algorithmID;
ephKey.algorithmParms.encScheme = inTempKey->encScheme;
ephKey.algorithmParms.sigScheme = inTempKey->sigScheme;
ephKey.algorithmParms.parmSize = inTempKey->parmSize;
switch (ephKey.algorithmParms.algorithmID) {
case TPM_ALG_RSA:
ephKey.algorithmParms.parms.rsa.keyLength =
inTempKey->parms.rsa.keyLength;
ephKey.algorithmParms.parms.rsa.numPrimes =
inTempKey->parms.rsa.numPrimes;
ephKey.algorithmParms.parms.rsa.exponentSize =
inTempKey->parms.rsa.exponentSize;
break;
default:
tpm_rsa_release_private_key(&k1);
return TPM_BAD_KEY_PROPERTY;
}
ephKey.PCRInfoSize = 0;
ephKey.pubKey.keyLength = key_length >> 3;
ephKey.pubKey.key = tpm_malloc(ephKey.pubKey.keyLength);
if (ephKey.pubKey.key == NULL) {
tpm_rsa_release_private_key(&k1);
tpm_free(store.privKey.key);
return TPM_NOSPACE;
}
tpm_rsa_export_modulus(&k1, ephKey.pubKey.key, NULL);
tpm_rsa_release_private_key(&k1);
ephKey.encDataSize = key_length >> 3;
ephKey.encData = tpm_malloc(ephKey.encDataSize);
if (ephKey.encData == NULL) {
tpm_free(store.privKey.key);
tpm_free(ephKey.pubKey.key);
return TPM_NOSPACE;
}
if (tpm_compute_key_digest(&ephKey, &store.pubDataDigest)) {
tpm_free(store.privKey.key);
tpm_free(ephKey.pubKey.key);
tpm_free(ephKey.encData);
debug("TPM_ChangeAuthAsymStart(): tpm_compute_key_digest() failed.");
return TPM_FAIL;
}
if (tpm_encrypt_private_key(&tpmData.permanent.data.srk, &store,
ephKey.encData, &ephKey.encDataSize)) {
tpm_free(store.privKey.key);
tpm_free(ephKey.pubKey.key);
tpm_free(ephKey.encData);
debug("TPM_ChangeAuthAsymStart(): tpm_encrypt_private_key() failed.");
return TPM_ENCRYPT_ERROR;
}
tpm_free(store.privKey.key);
/* assign a handle and store ephKey by calling internal_TPM_LoadKey() */
res = internal_TPM_LoadKey(&ephKey, ephHandle);
if (res != TPM_SUCCESS) {
tpm_free(ephKey.pubKey.key);
tpm_free(ephKey.encData);
return res;
}
tpm_free(ephKey.pubKey.key);
tpm_free(ephKey.encData);
/* 8. The TPM SHALL fill in all fields in tempKey using k1 for the
information. The TPM_KEY->encSize MUST be 0. */
outTempKey->tag = ephKey.tag;
outTempKey->fill = ephKey.fill;
outTempKey->keyUsage = ephKey.keyUsage;
outTempKey->keyFlags = ephKey.keyFlags;
outTempKey->authDataUsage = ephKey.authDataUsage;
outTempKey->algorithmParms.algorithmID = ephKey.algorithmParms.algorithmID;
outTempKey->algorithmParms.encScheme = ephKey.algorithmParms.encScheme;
outTempKey->algorithmParms.sigScheme = ephKey.algorithmParms.sigScheme;
outTempKey->algorithmParms.parmSize = ephKey.algorithmParms.parmSize;
outTempKey->algorithmParms.parms.rsa.keyLength =
ephKey.algorithmParms.parms.rsa.keyLength;
outTempKey->algorithmParms.parms.rsa.numPrimes =
ephKey.algorithmParms.parms.rsa.numPrimes;
outTempKey->algorithmParms.parms.rsa.exponentSize =
ephKey.algorithmParms.parms.rsa.exponentSize;
outTempKey->PCRInfoSize = ephKey.PCRInfoSize;
outTempKey->pubKey.keyLength = ephKey.pubKey.keyLength;
outTempKey->pubKey.key = tpm_malloc(outTempKey->pubKey.keyLength);
if (outTempKey->pubKey.key == NULL) return TPM_NOSPACE;
memcpy(outTempKey->pubKey.key, ephKey.pubKey.key, outTempKey->pubKey.keyLength);
outTempKey->encDataSize = 0;
outTempKey->encData = NULL;
/* 9. The TPM SHALL fill in certifyInfo using k1 for the information.
The certifyInfo->data field is supplied by the antiReplay. */
/* "Version" field is set according to the deprecated TPM_VERSION
structure from the old v1.1 specification. */
memcpy(&certifyInfo->tag, &tpmData.permanent.data.version, 2);
memcpy(&certifyInfo->fill, &tpmData.permanent.data.version + 2, 1);
memcpy(&certifyInfo->payloadType, &tpmData.permanent.data.version + 3, 1);
/* Other fields are filled according to Section 27.4.1 [TPM, Part 3]. */
certifyInfo->keyUsage = ephKey.keyUsage;
certifyInfo->keyFlags = ephKey.keyFlags;
certifyInfo->authDataUsage = ephKey.authDataUsage;
certifyInfo->algorithmParms.algorithmID = ephKey.algorithmParms.algorithmID;
certifyInfo->algorithmParms.encScheme = ephKey.algorithmParms.encScheme;
certifyInfo->algorithmParms.sigScheme = ephKey.algorithmParms.sigScheme;
certifyInfo->algorithmParms.parmSize = ephKey.algorithmParms.parmSize;
certifyInfo->algorithmParms.parms.rsa.keyLength =
ephKey.algorithmParms.parms.rsa.keyLength;
certifyInfo->algorithmParms.parms.rsa.numPrimes =
ephKey.algorithmParms.parms.rsa.numPrimes;
certifyInfo->algorithmParms.parms.rsa.exponentSize =
ephKey.algorithmParms.parms.rsa.exponentSize;
memcpy(&certifyInfo->pubkeyDigest, &store.pubDataDigest, sizeof(TPM_DIGEST));
memcpy(&certifyInfo->data, antiReplay, sizeof(TPM_NONCE));
certifyInfo->parentPCRStatus = FALSE;
certifyInfo->PCRInfoSize = 0;
/* 10. The TPM then signs the certifyInfo parameter using the key
pointed to by idHandle. The resulting signed blob is returned
in sig parameter. */
size = len = sizeof_TPM_CERTIFY_INFO((*certifyInfo));
buf = ptr = tpm_malloc(size);
if (buf == NULL) {
return TPM_NOSPACE;
}
if (tpm_marshal_TPM_CERTIFY_INFO(&ptr, &len, certifyInfo) || (len != 0)) {
debug("TPM_ChangeAuthAsymStart(): tpm_marshal_TPM_CERTIFY_INFO() failed.");
tpm_free(buf);
return TPM_FAIL;
}
res = tpm_sign(idKey, auth1, FALSE, buf, size, sig, sigSize);
tpm_free(buf);
return res;
}
TPM_RESULT TPM_ChangeAuthAsymFinish(TPM_KEY_HANDLE parentHandle,
TPM_KEY_HANDLE ephHandle,
TPM_ENTITY_TYPE entityType,
TPM_HMAC *newAuthLink,
UINT32 newAuthSize, BYTE *encNewAuth,
UINT32 encDataSize, BYTE *encData,
TPM_AUTH *auth1,
UINT32 *outDataSize, BYTE **outData,
TPM_NONCE *saltNonce,
TPM_DIGEST *changeProof)
{
TPM_RESULT res;
TPM_KEY_DATA *parentKey, *ephKey;
TPM_SEALED_DATA e1_seal;
TPM_STORE_ASYMKEY e1_store;
BYTE *e1_seal_buf, *e1_key_buf;
int scheme;
TPM_CHANGEAUTH_VALIDATE a1;
tpm_hmac_ctx_t hmac_ctx;
UINT32 len;
size_t size;
BYTE *ptr, *buf;
TPM_SECRET oldAuthSecret;
TPM_HMAC b1;
info("TPM_ChangeAuthAsymFinish()");
/* 1. The TPM SHALL validate that the authHandle parameter authorizes
use of the key in parentHandle. */
/* get parent key */
parentKey = tpm_get_key(parentHandle);
if (parentKey == NULL) return TPM_INVALID_KEYHANDLE;
/* verify authorization */
if (auth1->authHandle != TPM_INVALID_HANDLE
|| parentKey->authDataUsage != TPM_AUTH_NEVER) {
res = tpm_verify_auth(auth1, parentKey->usageAuth, parentHandle);
if (res != TPM_SUCCESS) return res;
}
/* get ephemeral key */
ephKey = tpm_get_key(ephHandle);
if (ephKey == NULL) return TPM_INVALID_KEYHANDLE;
/* 2. The encData field MUST be the encData field from TPM_STORED_DATA
or TPM_KEY. */
if (encDataSize != (parentKey->key.size >> 3))
return TPM_BAD_PARAMETER;
/* 3. The TPM SHALL create e1 by decrypting the entity held in the
encData parameter. */
switch (entityType) {
case TPM_ET_DATA:
/* decrypt seal data */
if (tpm_decrypt_sealed_data(parentKey, encData, encDataSize,
&e1_seal, &e1_seal_buf)) return TPM_DECRYPT_ERROR;
memcpy(oldAuthSecret, e1_seal.authData, sizeof(TPM_SECRET));
tpm_free(e1_seal_buf);
break;
case TPM_ET_KEY:
/* decrypt key data */
if (tpm_decrypt_private_key(parentKey, encData, encDataSize,
&e1_store, &e1_key_buf, NULL)) return TPM_DECRYPT_ERROR;
memcpy(oldAuthSecret, e1_store.usageAuth, sizeof(TPM_SECRET));
tpm_free(e1_key_buf);
break;
default:
return TPM_BAD_PARAMETER;
}
/* 4. The TPM SHALL create a1 by decrypting encNewAuth using the
ephHandle->TPM_KEY_AUTHCHANGE private key. a1 is a structure
of type TPM_CHANGEAUTH_VALIDATE. */
switch (ephKey->encScheme) {
case TPM_ES_RSAESOAEP_SHA1_MGF1: scheme = RSA_ES_OAEP_SHA1; break;
case TPM_ES_RSAESPKCSv15: scheme = RSA_ES_PKCSV15; break;
default: return TPM_BAD_PARAMETER;
}
len = newAuthSize;
buf = ptr = tpm_malloc(len);
if (buf == NULL) return TPM_NOSPACE;
if (tpm_rsa_decrypt(&ephKey->key, scheme, encNewAuth, newAuthSize,
buf, &size)
|| (len = size) == 0
|| tpm_unmarshal_TPM_CHANGEAUTH_VALIDATE(&ptr, &len, &a1)) {
debug("TPM_ChangeAuthAsymFinish(): tpm_rsa_decrypt() failed.");
tpm_free(buf);
return TPM_DECRYPT_ERROR;
}
tpm_free(buf);
/* 5. The TPM SHALL create b1 by performing the following HMAC
calculation: b1 = HMAC(a1->newAuthSecret). The secret for
this calculation is encData->currentAuth. This means that
b1 is a value built from the current AuthData value
(encData->currentAuth) and the new AuthData value
(a1->newAuthSecret). */
tpm_hmac_init(&hmac_ctx, oldAuthSecret, sizeof(TPM_SECRET));
tpm_hmac_update(&hmac_ctx, a1.newAuthSecret, sizeof(TPM_SECRET));
tpm_hmac_final(&hmac_ctx, b1.digest);
/* 6. The TPM SHALL compare b1 with newAuthLink. The TPM SHALL
indicate a failure if the values do not match. */
if (memcmp(&b1, &newAuthLink, sizeof(TPM_HMAC))) {
debug("TPM_ChangeAuthAsymFinish(): newAuthLink value does not match.");
return TPM_FAIL;
}
/* 7. The TPM SHALL replace e1->authData with a1->newAuthSecret */
switch (entityType) {
case TPM_ET_DATA:
memcpy(e1_seal.authData, a1.newAuthSecret, sizeof(TPM_SECRET));
break;
case TPM_ET_KEY:
memcpy(e1_store.usageAuth, a1.newAuthSecret, sizeof(TPM_SECRET));
break;
}
/* 8. The TPM SHALL encrypt e1 using the appropriate functions for
the entity type. The key to encrypt with is parentHandle. */
switch (entityType) {
case TPM_ET_DATA:
if (tpm_encrypt_sealed_data(parentKey, &e1_seal,
*outData, outDataSize)) {
tpm_free(outData);
return TPM_ENCRYPT_ERROR;
}
break;
case TPM_ET_KEY:
if (tpm_encrypt_private_key(parentKey, &e1_store,
*outData, outDataSize)) {
tpm_free(outData);
return TPM_ENCRYPT_ERROR;
}
break;
}
/* 9. The TPM SHALL create slatNonce by taking the next 20 bytes
from the TPM RNG. */
tpm_get_random_bytes(saltNonce->nonce, sizeof(TPM_NONCE));
/* 10. The TPM SHALL create changeProof a HMAC of (saltNonce
concatenated with a1->n1) using a1->newAuthSecret as the
HMAC secret. */
tpm_hmac_init(&hmac_ctx, a1.newAuthSecret, sizeof(a1.newAuthSecret));
tpm_hmac_update(&hmac_ctx, saltNonce->nonce, sizeof(TPM_NONCE));
tpm_hmac_update(&hmac_ctx, a1.n1.nonce, sizeof(TPM_NONCE));
tpm_hmac_final(&hmac_ctx, changeProof->digest);
/* 11. The TPM MUST destroy the TPM_KEY_AUTHCHANGE key associated
with the authorization session. */
tpm_rsa_release_private_key(&ephKey->key);
memset(ephKey, 0, sizeof(*ephKey));
tpm_invalidate_sessions(ephHandle);
return TPM_SUCCESS;
}
TPM_RESULT TPM_Reset()
{
int i;
info("TPM_Reset()");
/* invalidate all authorization sessions */
for (i = 0; i < TPM_MAX_SESSIONS; i++) {
TPM_SESSION_DATA *session = &tpmData.stany.data.sessions[i];
if (session->type == TPM_ST_OIAP || session->type == TPM_ST_OSAP)
memset(session, 0, sizeof(*session));
}
return TPM_SUCCESS;
}
TPM_RESULT TPM_CertifySelfTest(TPM_KEY_HANDLE keyHandle, TPM_NONCE *antiReplay,
TPM_AUTH *auth1, UINT32 *sigSize, BYTE **sig)
{
TPM_RESULT res;
TPM_KEY_DATA *key;
BYTE buf[35];
info("TPM_CertifySelfTest()");
key = tpm_get_key(keyHandle);
if (key == NULL) return TPM_INVALID_KEYHANDLE;
/* perform self test */
res = TPM_SelfTestFull();
if (res != TPM_SUCCESS) return res;
/* verify authorization */
if (auth1->authHandle != TPM_INVALID_HANDLE
|| key->authDataUsage != TPM_AUTH_NEVER) {
res = tpm_verify_auth(auth1, key->usageAuth, keyHandle);
if (res != TPM_SUCCESS) return res;
}
if (key->keyUsage != TPM_KEY_SIGNING && key->keyUsage != TPM_KEY_LEGACY
&& key->keyUsage != TPM_KEY_IDENTITY) return TPM_INVALID_KEYUSAGE;
/* not neccessary, because a vendor specific signature is allowed
if (key->sigScheme != TPM_SS_RSASSAPKCS1v15_SHA1)
return TPM_BAD_SCHEME;
*/
/* setup and sign result */
memcpy(&buf, "Test Passed", 11);
memcpy(&buf[11], antiReplay->nonce, sizeof(TPM_NONCE));
memcpy(&buf[31], "\x52\x00\x00\x00", 4);
return tpm_sign(key, auth1, FALSE, buf, sizeof(buf), sig, sigSize);
}
TPM_RESULT TPM_OwnerReadPubek(TPM_AUTH *auth1, TPM_PUBKEY *pubEndorsementKey)
{
TPM_RESULT res;
info("TPM_OwnerReadPubek()");
/* verify authorization */
res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
if (res != TPM_SUCCESS) return res;
res = tpm_get_pubek(pubEndorsementKey);
if (res != TPM_SUCCESS) return res;
return TPM_SUCCESS;
}