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