120 lines
4.9 KiB
C
120 lines
4.9 KiB
C
// This file was extracted from the TCG Published
|
|
// Trusted Platform Module Library
|
|
// Part 3: Commands
|
|
// Family "2.0"
|
|
// Level 00 Revision 01.16
|
|
// October 30, 2014
|
|
|
|
#include "InternalRoutines.h"
|
|
#include "StartAuthSession_fp.h"
|
|
//
|
|
//
|
|
// Error Returns Meaning
|
|
//
|
|
// TPM_RC_ATTRIBUTES tpmKey does not reference a decrypt key
|
|
// TPM_RC_CONTEXT_GAP the difference between the most recently created active context and
|
|
// the oldest active context is at the limits of the TPM
|
|
// TPM_RC_HANDLE input decrypt key handle only has public portion loaded
|
|
// TPM_RC_MODE symmetric specifies a block cipher but the mode is not
|
|
// TPM_ALG_CFB.
|
|
// TPM_RC_SESSION_HANDLES no session handle is available
|
|
// TPM_RC_SESSION_MEMORY no more slots for loading a session
|
|
// TPM_RC_SIZE nonce less than 16 octets or greater than the size of the digest
|
|
// produced by authHash
|
|
// TPM_RC_VALUE secret size does not match decrypt key type; or the recovered secret
|
|
// is larger than the digest size of the nameAlg of tpmKey; or, for an
|
|
// RSA decrypt key, if encryptedSecret is greater than the public
|
|
// exponent of tpmKey.
|
|
//
|
|
TPM_RC
|
|
TPM2_StartAuthSession(
|
|
StartAuthSession_In *in, // IN: input parameter buffer
|
|
StartAuthSession_Out *out // OUT: output parameter buffer
|
|
)
|
|
{
|
|
TPM_RC result = TPM_RC_SUCCESS;
|
|
OBJECT *tpmKey; // TPM key for decrypt salt
|
|
SESSION *session; // session internal data
|
|
TPM2B_DATA salt;
|
|
|
|
// Input Validation
|
|
|
|
// Check input nonce size. IT should be at least 16 bytes but not larger
|
|
// than the digest size of session hash.
|
|
if( in->nonceCaller.t.size < 16
|
|
|| in->nonceCaller.t.size > CryptGetHashDigestSize(in->authHash))
|
|
return TPM_RC_SIZE + RC_StartAuthSession_nonceCaller;
|
|
|
|
// If an decrypt key is passed in, check its validation
|
|
if(in->tpmKey != TPM_RH_NULL)
|
|
{
|
|
// secret size cannot be 0
|
|
if(in->encryptedSalt.t.size == 0)
|
|
return TPM_RC_VALUE + RC_StartAuthSession_encryptedSalt;
|
|
|
|
// Get pointer to loaded decrypt key
|
|
tpmKey = ObjectGet(in->tpmKey);
|
|
|
|
// Decrypting salt requires accessing the private portion of a key.
|
|
// Therefore, tmpKey can not be a key with only public portion loaded
|
|
if(tpmKey->attributes.publicOnly)
|
|
return TPM_RC_HANDLE + RC_StartAuthSession_tpmKey;
|
|
|
|
// HMAC session input handle check.
|
|
// tpmKey should be a decryption key
|
|
if(tpmKey->publicArea.objectAttributes.decrypt != SET)
|
|
return TPM_RC_ATTRIBUTES + RC_StartAuthSession_tpmKey;
|
|
|
|
// Secret Decryption. A TPM_RC_VALUE, TPM_RC_KEY or Unmarshal errors
|
|
// may be returned at this point
|
|
result = CryptSecretDecrypt(in->tpmKey, &in->nonceCaller, "SECRET",
|
|
&in->encryptedSalt, &salt);
|
|
if(result != TPM_RC_SUCCESS)
|
|
return TPM_RC_VALUE + RC_StartAuthSession_encryptedSalt;
|
|
|
|
}
|
|
else
|
|
{
|
|
// secret size must be 0
|
|
if(in->encryptedSalt.t.size != 0)
|
|
return TPM_RC_VALUE + RC_StartAuthSession_encryptedSalt;
|
|
salt.t.size = 0;
|
|
}
|
|
// If the bind handle references a transient object, make sure that the
|
|
// sensitive area is loaded so that the authValue can be accessed.
|
|
if( HandleGetType(in->bind) == TPM_HT_TRANSIENT
|
|
&& ObjectGet(in->bind)->attributes.publicOnly == SET)
|
|
return TPM_RC_HANDLE + RC_StartAuthSession_bind;
|
|
|
|
// If 'symmetric' is a symmetric block cipher (not TPM_ALG_NULL or TPM_ALG_XOR)
|
|
// then the mode must be CFB.
|
|
if( in->symmetric.algorithm != TPM_ALG_NULL
|
|
&& in->symmetric.algorithm != TPM_ALG_XOR
|
|
&& in->symmetric.mode.sym != TPM_ALG_CFB)
|
|
return TPM_RC_MODE + RC_StartAuthSession_symmetric;
|
|
|
|
// Internal Data Update
|
|
|
|
// Create internal session structure. TPM_RC_CONTEXT_GAP, TPM_RC_NO_HANDLES
|
|
// or TPM_RC_SESSION_MEMORY errors may be returned returned at this point.
|
|
//
|
|
// The detailed actions for creating the session context are not shown here
|
|
// as the details are implementation dependent
|
|
// SessionCreate sets the output handle
|
|
result = SessionCreate(in->sessionType, in->authHash,
|
|
&in->nonceCaller, &in->symmetric,
|
|
in->bind, &salt, &out->sessionHandle);
|
|
|
|
if(result != TPM_RC_SUCCESS)
|
|
return result;
|
|
|
|
// Command Output
|
|
|
|
// Get session pointer
|
|
session = SessionGet(out->sessionHandle);
|
|
|
|
// Copy nonceTPM
|
|
out->nonceTPM = session->nonceTPM;
|
|
|
|
return TPM_RC_SUCCESS;
|
|
}
|