Home | History | Annotate | Download | only in tpm2
      1 // This file was extracted from the TCG Published
      2 // Trusted Platform Module Library
      3 // Part 3: Commands
      4 // Family "2.0"
      5 // Level 00 Revision 01.16
      6 // October 30, 2014
      7 
      8 #include "InternalRoutines.h"
      9 #include "StartAuthSession_fp.h"
     10 //
     11 //
     12 //     Error Returns                     Meaning
     13 //
     14 //     TPM_RC_ATTRIBUTES                 tpmKey does not reference a decrypt key
     15 //     TPM_RC_CONTEXT_GAP                the difference between the most recently created active context and
     16 //                                       the oldest active context is at the limits of the TPM
     17 //     TPM_RC_HANDLE                     input decrypt key handle only has public portion loaded
     18 //     TPM_RC_MODE                       symmetric specifies a block cipher but the mode is not
     19 //                                       TPM_ALG_CFB.
     20 //     TPM_RC_SESSION_HANDLES            no session handle is available
     21 //     TPM_RC_SESSION_MEMORY             no more slots for loading a session
     22 //     TPM_RC_SIZE                       nonce less than 16 octets or greater than the size of the digest
     23 //                                       produced by authHash
     24 //     TPM_RC_VALUE                      secret size does not match decrypt key type; or the recovered secret
     25 //                                       is larger than the digest size of the nameAlg of tpmKey; or, for an
     26 //                                       RSA decrypt key, if encryptedSecret is greater than the public
     27 //                                       exponent of tpmKey.
     28 //
     29 TPM_RC
     30 TPM2_StartAuthSession(
     31    StartAuthSession_In       *in,                   // IN: input parameter buffer
     32    StartAuthSession_Out      *out                   // OUT: output parameter buffer
     33    )
     34 {
     35    TPM_RC                     result = TPM_RC_SUCCESS;
     36    OBJECT                    *tpmKey;                // TPM key for decrypt salt
     37    SESSION                   *session;               // session internal data
     38    TPM2B_DATA                 salt;
     39 
     40 // Input Validation
     41 
     42    // Check input nonce size. IT should be at least 16 bytes but not larger
     43    // than the digest size of session hash.
     44    if(    in->nonceCaller.t.size < 16
     45        || in->nonceCaller.t.size > CryptGetHashDigestSize(in->authHash))
     46        return TPM_RC_SIZE + RC_StartAuthSession_nonceCaller;
     47 
     48    // If an decrypt key is passed in, check its validation
     49    if(in->tpmKey != TPM_RH_NULL)
     50    {
     51        // secret size cannot be 0
     52        if(in->encryptedSalt.t.size == 0)
     53            return TPM_RC_VALUE + RC_StartAuthSession_encryptedSalt;
     54 
     55        // Get pointer to loaded decrypt key
     56        tpmKey = ObjectGet(in->tpmKey);
     57 
     58        // Decrypting salt requires accessing the private portion of a key.
     59        // Therefore, tmpKey can not be a key with only public portion loaded
     60        if(tpmKey->attributes.publicOnly)
     61            return TPM_RC_HANDLE + RC_StartAuthSession_tpmKey;
     62 
     63        // HMAC session input handle check.
     64          // tpmKey should be a decryption key
     65          if(tpmKey->publicArea.objectAttributes.decrypt != SET)
     66              return TPM_RC_ATTRIBUTES + RC_StartAuthSession_tpmKey;
     67 
     68          // Secret Decryption. A TPM_RC_VALUE, TPM_RC_KEY or Unmarshal errors
     69          // may be returned at this point
     70          result = CryptSecretDecrypt(in->tpmKey, &in->nonceCaller, "SECRET",
     71                                      &in->encryptedSalt, &salt);
     72          if(result != TPM_RC_SUCCESS)
     73              return TPM_RC_VALUE + RC_StartAuthSession_encryptedSalt;
     74 
     75   }
     76   else
     77   {
     78       // secret size must be 0
     79       if(in->encryptedSalt.t.size != 0)
     80           return TPM_RC_VALUE + RC_StartAuthSession_encryptedSalt;
     81       salt.t.size = 0;
     82   }
     83   // If the bind handle references a transient object, make sure that the
     84   // sensitive area is loaded so that the authValue can be accessed.
     85   if(     HandleGetType(in->bind) == TPM_HT_TRANSIENT
     86       && ObjectGet(in->bind)->attributes.publicOnly == SET)
     87       return TPM_RC_HANDLE + RC_StartAuthSession_bind;
     88 
     89   // If 'symmetric' is a symmetric block cipher (not TPM_ALG_NULL or TPM_ALG_XOR)
     90   // then the mode must be CFB.
     91   if(    in->symmetric.algorithm != TPM_ALG_NULL
     92       && in->symmetric.algorithm != TPM_ALG_XOR
     93       && in->symmetric.mode.sym != TPM_ALG_CFB)
     94       return TPM_RC_MODE + RC_StartAuthSession_symmetric;
     95 
     96 // Internal Data Update
     97 
     98   // Create internal session structure. TPM_RC_CONTEXT_GAP, TPM_RC_NO_HANDLES
     99   // or TPM_RC_SESSION_MEMORY errors may be returned returned at this point.
    100   //
    101   // The detailed actions for creating the session context are not shown here
    102   // as the details are implementation dependent
    103   // SessionCreate sets the output handle
    104   result = SessionCreate(in->sessionType, in->authHash,
    105                          &in->nonceCaller, &in->symmetric,
    106                          in->bind, &salt, &out->sessionHandle);
    107 
    108   if(result != TPM_RC_SUCCESS)
    109       return result;
    110 
    111 // Command Output
    112 
    113   // Get session pointer
    114   session = SessionGet(out->sessionHandle);
    115 
    116   // Copy nonceTPM
    117   out->nonceTPM = session->nonceTPM;
    118 
    119    return TPM_RC_SUCCESS;
    120 }
    121