• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Microsoft Reference Implementation for TPM 2.0
2  *
3  *  The copyright in this software is being made available under the BSD License,
4  *  included below. This software may be subject to other third party and
5  *  contributor rights, including patent rights, and no such rights are granted
6  *  under this license.
7  *
8  *  Copyright (c) Microsoft Corporation
9  *
10  *  All rights reserved.
11  *
12  *  BSD License
13  *
14  *  Redistribution and use in source and binary forms, with or without modification,
15  *  are permitted provided that the following conditions are met:
16  *
17  *  Redistributions of source code must retain the above copyright notice, this list
18  *  of conditions and the following disclaimer.
19  *
20  *  Redistributions in binary form must reproduce the above copyright notice, this
21  *  list of conditions and the following disclaimer in the documentation and/or
22  *  other materials provided with the distribution.
23  *
24  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
25  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27  *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28  *  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31  *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 #include "Tpm.h"
36 #include "StartAuthSession_fp.h"
37 
38 #if CC_StartAuthSession  // Conditional expansion of this file
39 
40 /*(See part 3 specification)
41 // Start an authorization session
42 */
43 //  Return Type: TPM_RC
44 //      TPM_RC_ATTRIBUTES       'tpmKey' does not reference a decrypt key
45 //      TPM_RC_CONTEXT_GAP      the difference between the most recently created
46 //                              active context and the oldest active context is at
47 //                              the limits of the TPM
48 //      TPM_RC_HANDLE           input decrypt key handle only has public portion
49 //                              loaded
50 //      TPM_RC_MODE             'symmetric' specifies a block cipher but the mode
51 //                              is not TPM_ALG_CFB.
52 //      TPM_RC_SESSION_HANDLES  no session handle is available
53 //      TPM_RC_SESSION_MEMORY   no more slots for loading a session
54 //      TPM_RC_SIZE             nonce less than 16 octets or greater than the size
55 //                              of the digest produced by 'authHash'
56 //      TPM_RC_VALUE            secret size does not match decrypt key type; or the
57 //                              recovered secret is larger than the digest size of
58 //                              the nameAlg of 'tpmKey'; or, for an RSA decrypt key,
59 //                              if 'encryptedSecret' is greater than the
60 //                              public modulus of 'tpmKey'.
61 TPM_RC
TPM2_StartAuthSession(StartAuthSession_In * in,StartAuthSession_Out * out)62 TPM2_StartAuthSession(
63     StartAuthSession_In     *in,            // IN: input parameter buffer
64     StartAuthSession_Out    *out            // OUT: output parameter buffer
65     )
66 {
67     TPM_RC                   result = TPM_RC_SUCCESS;
68     OBJECT                  *tpmKey;                // TPM key for decrypt salt
69     TPM2B_DATA               salt;
70 
71 // Input Validation
72 
73     // Check input nonce size.  IT should be at least 16 bytes but not larger
74     // than the digest size of session hash.
75     if(in->nonceCaller.t.size < 16
76        || in->nonceCaller.t.size > CryptHashGetDigestSize(in->authHash))
77         return TPM_RCS_SIZE + RC_StartAuthSession_nonceCaller;
78 
79     // If an decrypt key is passed in, check its validation
80     if(in->tpmKey != TPM_RH_NULL)
81     {
82         // Get pointer to loaded decrypt key
83         tpmKey = HandleToObject(in->tpmKey);
84 
85         // key must be asymmetric with its sensitive area loaded. Since this
86         // command does not require authorization, the presence of the sensitive
87         // area was not already checked as it is with most other commands that
88         // use the sensitive are so check it here
89         if(!CryptIsAsymAlgorithm(tpmKey->publicArea.type))
90             return TPM_RCS_KEY + RC_StartAuthSession_tpmKey;
91         // secret size cannot be 0
92         if(in->encryptedSalt.t.size == 0)
93             return TPM_RCS_VALUE + RC_StartAuthSession_encryptedSalt;
94         // Decrypting salt requires accessing the private portion of a key.
95         // Therefore, tmpKey can not be a key with only public portion loaded
96         if(tpmKey->attributes.publicOnly)
97             return TPM_RCS_HANDLE + RC_StartAuthSession_tpmKey;
98         // HMAC session input handle check.
99         // tpmKey should be a decryption key
100         if(!IS_ATTRIBUTE(tpmKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
101             return TPM_RCS_ATTRIBUTES + RC_StartAuthSession_tpmKey;
102         // Secret Decryption.  A TPM_RC_VALUE, TPM_RC_KEY or Unmarshal errors
103         // may be returned at this point
104         result = CryptSecretDecrypt(tpmKey, &in->nonceCaller, SECRET_KEY,
105                                     &in->encryptedSalt, &salt);
106         if(result != TPM_RC_SUCCESS)
107             return TPM_RCS_VALUE + RC_StartAuthSession_encryptedSalt;
108     }
109     else
110     {
111         // secret size must be 0
112         if(in->encryptedSalt.t.size != 0)
113             return TPM_RCS_VALUE + RC_StartAuthSession_encryptedSalt;
114         salt.t.size = 0;
115     }
116     switch(HandleGetType(in->bind))
117     {
118         case TPM_HT_TRANSIENT:
119         {
120             OBJECT      *object = HandleToObject(in->bind);
121             // If the bind handle references a transient object, make sure that we
122             // can get to the authorization value. Also, make sure that the object
123             // has a proper Name (nameAlg != TPM_ALG_NULL). If it doesn't, then
124             // it might be possible to bind to an object where the authValue is
125             // known. This does not create a real issue in that, if you know the
126             // authorization value, you can actually bind to the object. However,
127             // there is a potential
128             if(object->attributes.publicOnly == SET)
129                 return TPM_RCS_HANDLE + RC_StartAuthSession_bind;
130             break;
131         }
132         case TPM_HT_NV_INDEX:
133         // a PIN index can't be a bind object
134         {
135             NV_INDEX       *nvIndex = NvGetIndexInfo(in->bind, NULL);
136             if(IsNvPinPassIndex(nvIndex->publicArea.attributes)
137                || IsNvPinFailIndex(nvIndex->publicArea.attributes))
138                 return TPM_RCS_HANDLE + RC_StartAuthSession_bind;
139             break;
140         }
141         default:
142             break;
143     }
144     // If 'symmetric' is a symmetric block cipher (not TPM_ALG_NULL or TPM_ALG_XOR)
145     // then the mode must be CFB.
146     if(in->symmetric.algorithm != TPM_ALG_NULL
147        && in->symmetric.algorithm != TPM_ALG_XOR
148        && in->symmetric.mode.sym != TPM_ALG_CFB)
149         return TPM_RCS_MODE + RC_StartAuthSession_symmetric;
150 
151 // Internal Data Update and command output
152 
153     // Create internal session structure.  TPM_RC_CONTEXT_GAP, TPM_RC_NO_HANDLES
154     // or TPM_RC_SESSION_MEMORY errors may be returned at this point.
155     //
156     // The detailed actions for creating the session context are not shown here
157     // as the details are implementation dependent
158     // SessionCreate sets the output handle and nonceTPM
159     result = SessionCreate(in->sessionType, in->authHash, &in->nonceCaller,
160                            &in->symmetric, in->bind, &salt, &out->sessionHandle,
161                            &out->nonceTPM);
162     return result;
163 }
164 
165 #endif // CC_StartAuthSession