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 //** Includes, Defines, and Types
36 #include    "Tpm.h"
37 #include    <stdio.h>
38 #include    <assert.h>
39 
40 #if RUNTIME_SIZE_CHECKS
41 
42 #if TABLE_DRIVEN_MARSHAL
43 extern uint32_t    MarshalDataSize;
44 #endif
45 
46 static      int once = 0;
47 
48 //** TpmSizeChecks()
49 // This function is used during the development process to make sure that the
50 // vendor-specific values result in a consistent implementation. When possible,
51 // the code contains #if to do compile-time checks. However, in some cases, the
52 // values require the use of "sizeof()" and that can't be used in an #if.
53 BOOL
TpmSizeChecks(void)54 TpmSizeChecks(
55     void
56     )
57 {
58     BOOL        PASS = TRUE;
59 #if DEBUG
60 //
61     if(once++ != 0)
62         return 1;
63     {
64         UINT32      maxAsymSecurityStrength = MAX_ASYM_SECURITY_STRENGTH;
65         UINT32      maxHashSecurityStrength = MAX_HASH_SECURITY_STRENGTH;
66         UINT32      maxSymSecurityStrength = MAX_SYM_SECURITY_STRENGTH;
67         UINT32      maxSecurityStrengthBits = MAX_SECURITY_STRENGTH_BITS;
68         UINT32      proofSize = PROOF_SIZE;
69         UINT32      compliantProofSize = COMPLIANT_PROOF_SIZE;
70         UINT32      compliantPrimarySeedSize = COMPLIANT_PRIMARY_SEED_SIZE;
71         UINT32      primarySeedSize = PRIMARY_SEED_SIZE;
72 
73         UINT32      cmacState = sizeof(tpmCmacState_t);
74         UINT32      hashState = sizeof(HASH_STATE);
75         UINT32      keyScheduleSize = sizeof(tpmCryptKeySchedule_t);
76     //
77         NOT_REFERENCED(cmacState);
78         NOT_REFERENCED(hashState);
79         NOT_REFERENCED(keyScheduleSize);
80         NOT_REFERENCED(maxAsymSecurityStrength);
81         NOT_REFERENCED(maxHashSecurityStrength);
82         NOT_REFERENCED(maxSymSecurityStrength);
83         NOT_REFERENCED(maxSecurityStrengthBits);
84         NOT_REFERENCED(proofSize);
85         NOT_REFERENCED(compliantProofSize);
86         NOT_REFERENCED(compliantPrimarySeedSize);
87         NOT_REFERENCED(primarySeedSize);
88 
89 
90         {
91             TPMT_SENSITIVE           *p;
92             // This assignment keeps compiler from complaining about a conditional
93             // comparison being between two constants
94             UINT16                    max_rsa_key_bytes = MAX_RSA_KEY_BYTES;
95             if((max_rsa_key_bytes / 2) != (sizeof(p->sensitive.rsa.t.buffer) / 5))
96             {
97                 printf("Sensitive part of TPMT_SENSITIVE is undersized. May be caused"
98                        " by use of wrong version of Part 2.\n");
99                 PASS = FALSE;
100             }
101         }
102 #if TABLE_DRIVEN_MARSHAL
103         printf("sizeof(MarshalData) = %zu\n", sizeof(MarshalData_st));
104 #endif
105 
106         printf("Size of OBJECT = %zu\n", sizeof(OBJECT));
107         printf("Size of components in TPMT_SENSITIVE = %zu\n", sizeof(TPMT_SENSITIVE));
108         printf("    TPMI_ALG_PUBLIC                 %zu\n", sizeof(TPMI_ALG_PUBLIC));
109         printf("    TPM2B_AUTH                      %zu\n", sizeof(TPM2B_AUTH));
110         printf("    TPM2B_DIGEST                    %zu\n", sizeof(TPM2B_DIGEST));
111         printf("    TPMU_SENSITIVE_COMPOSITE        %zu\n",
112                sizeof(TPMU_SENSITIVE_COMPOSITE));
113     }
114         // Make sure that the size of the context blob is large enough for the largest
115         // context
116         // TPMS_CONTEXT_DATA contains two TPM2B values. That is not how this is
117         // implemented. Rather, the size field of the TPM2B_CONTEXT_DATA is used to
118         // determine the amount of data in the encrypted data. That part is not
119         // independently sized. This makes the actual size 2 bytes smaller than
120         // calculated using Part 2. Since this is opaque to the caller, it is not
121         // necessary to fix. The actual size is returned by TPM2_GetCapabilties().
122 
123         // Initialize output handle.  At the end of command action, the output
124         // handle of an object will be replaced, while the output handle
125         // for a session will be the same as input
126 
127         // Get the size of fingerprint in context blob.  The sequence value in
128         // TPMS_CONTEXT structure is used as the fingerprint
129     {
130         UINT32  fingerprintSize = sizeof(UINT64);
131         UINT32  integritySize = sizeof(UINT16)
132             + CryptHashGetDigestSize(CONTEXT_INTEGRITY_HASH_ALG);
133         UINT32  biggestObject = MAX(MAX(sizeof(HASH_OBJECT), sizeof(OBJECT)),
134                                     sizeof(SESSION));
135         UINT32  biggestContext = fingerprintSize + integritySize + biggestObject;
136 
137         // round required size up to nearest 8 byte boundary.
138         biggestContext = 8 * ((biggestContext + 7) / 8);
139 
140         if(MAX_CONTEXT_SIZE < biggestContext)
141         {
142             printf("MAX_CONTEXT_SIZE needs to be increased to at least %d (%d)\n",
143                    biggestContext, MAX_CONTEXT_SIZE);
144             PASS = FALSE;
145         }
146         else if (MAX_CONTEXT_SIZE > biggestContext)
147         {
148             printf("MAX_CONTEXT_SIZE can be reduced to %d (%d)\n",
149                    biggestContext, MAX_CONTEXT_SIZE);
150         }
151     }
152     {
153         union u
154         {
155             TPMA_OBJECT             attributes;
156             UINT32                  uint32Value;
157         } u;
158         // these are defined so that compiler doesn't complain about conditional
159         // expressions comparing two constants.
160         int                         aSize = sizeof(u.attributes);
161         int                         uSize = sizeof(u.uint32Value);
162         u.uint32Value = 0;
163         SET_ATTRIBUTE(u.attributes, TPMA_OBJECT, fixedTPM);
164         if(u.uint32Value != 2)
165         {
166             printf("The bit allocation in a TPMA_OBJECT is not as expected");
167             PASS = FALSE;
168         }
169         if(aSize != uSize)  // comparison of two sizeof() values annoys compiler
170         {
171             printf("A TPMA_OBJECT is not the expected size.");
172             PASS = FALSE;
173         }
174     }
175     // Check that the platorm implementes each of the ACT that the TPM thinks are
176     // present
177     {
178         uint32_t            act;
179         for(act = 0; act < 16; act++)
180         {
181             switch(act)
182             {
183                 FOR_EACH_ACT(CASE_ACT_NUMBER)
184                     if(!_plat__ACT_GetImplemented(act))
185                     {
186                         printf("TPM_RH_ACT_%1X is not implemented by platform\n",
187                                act);
188                         PASS = FALSE;
189                     }
190                 default:
191                     break;
192             }
193         }
194     }
195 #endif // DEBUG
196     return (PASS);
197 }
198 
199 #endif // RUNTIME_SIZE_CHECKS