• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /***********************************************************************;
3  * Copyright (c) 2015-2018, Intel Corporation
4  *
5  * All rights reserved.
6  ***********************************************************************/
7 
8 #ifdef HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11 
12 #include <string.h>
13 
14 #include "tss2_mu.h"
15 #include "sysapi_util.h"
16 #include "util/tss2_endian.h"
17 #define LOGMODULE sys
18 #include "util/log.h"
19 
InitSysContextFields(_TSS2_SYS_CONTEXT_BLOB * ctx)20 void InitSysContextFields(_TSS2_SYS_CONTEXT_BLOB *ctx)
21 {
22     ctx->decryptAllowed = 0;
23     ctx->encryptAllowed = 0;
24     ctx->decryptNull = 0;
25     ctx->authAllowed = 0;
26     ctx->nextData = 0;
27 }
28 
InitSysContextPtrs(_TSS2_SYS_CONTEXT_BLOB * ctx,size_t contextSize)29 void InitSysContextPtrs(
30     _TSS2_SYS_CONTEXT_BLOB *ctx,
31     size_t contextSize)
32 {
33     ctx->cmdBuffer = (UINT8 *)ctx + sizeof(_TSS2_SYS_CONTEXT_BLOB);
34     ctx->maxCmdSize = contextSize - sizeof(_TSS2_SYS_CONTEXT_BLOB);
35 }
36 
GetCommandSize(_TSS2_SYS_CONTEXT_BLOB * ctx)37 UINT32 GetCommandSize(_TSS2_SYS_CONTEXT_BLOB *ctx)
38 {
39     return BE_TO_HOST_32(req_header_from_cxt(ctx)->commandSize);
40 }
41 
CopyCommandHeader(_TSS2_SYS_CONTEXT_BLOB * ctx,TPM2_CC commandCode)42 TSS2_RC CopyCommandHeader(_TSS2_SYS_CONTEXT_BLOB *ctx, TPM2_CC commandCode)
43 {
44     TSS2_RC rval;
45 
46     if (!ctx)
47         return TSS2_SYS_RC_BAD_REFERENCE;
48 
49     ctx->nextData = 0;
50 
51     rval = Tss2_MU_TPM2_ST_Marshal(TPM2_ST_NO_SESSIONS, ctx->cmdBuffer,
52                                   ctx->maxCmdSize,
53                                   &ctx->nextData);
54     if (rval)
55         return rval;
56 
57     req_header_from_cxt(ctx)->commandCode = HOST_TO_BE_32(commandCode);
58     ctx->nextData = sizeof(TPM20_Header_In);
59     return rval;
60 }
61 
62 static int GetNumCommandHandles(TPM2_CC commandCode);
63 static int GetNumResponseHandles(TPM2_CC commandCode);
64 
CommonPreparePrologue(_TSS2_SYS_CONTEXT_BLOB * ctx,TPM2_CC commandCode)65 TSS2_RC CommonPreparePrologue(
66     _TSS2_SYS_CONTEXT_BLOB *ctx,
67     TPM2_CC commandCode)
68 {
69     int numCommandHandles;
70     TSS2_RC rval;
71 
72     if (!ctx)
73         return TSS2_SYS_RC_BAD_REFERENCE;
74 
75     InitSysContextFields(ctx);
76 
77     /* Need to check stage here. */
78     if (ctx->previousStage != CMD_STAGE_INITIALIZE &&
79         ctx->previousStage != CMD_STAGE_RECEIVE_RESPONSE &&
80         ctx->previousStage != CMD_STAGE_PREPARE)
81         return TSS2_SYS_RC_BAD_SEQUENCE;
82 
83     rval = CopyCommandHeader(ctx, commandCode);
84     if (rval)
85         return rval;
86 
87     ctx->commandCode = commandCode;
88     ctx->numResponseHandles = GetNumResponseHandles(commandCode);
89     ctx->rspParamsSize = (UINT32 *)(ctx->cmdBuffer + sizeof(TPM20_Header_Out) +
90                          (GetNumResponseHandles(commandCode) * sizeof(UINT32)));
91 
92     numCommandHandles = GetNumCommandHandles(commandCode);
93     ctx->cpBuffer = ctx->cmdBuffer + ctx->nextData +
94                                      (numCommandHandles * sizeof(UINT32));
95     return rval;
96 }
97 
CommonPrepareEpilogue(_TSS2_SYS_CONTEXT_BLOB * ctx)98 TSS2_RC CommonPrepareEpilogue(_TSS2_SYS_CONTEXT_BLOB *ctx)
99 {
100     ctx->cpBufferUsedSize = ctx->cmdBuffer + ctx->nextData - ctx->cpBuffer;
101     req_header_from_cxt(ctx)->commandSize = HOST_TO_BE_32(ctx->nextData);
102     ctx->previousStage = CMD_STAGE_PREPARE;
103 
104     return TSS2_RC_SUCCESS;
105 }
106 
CommonComplete(_TSS2_SYS_CONTEXT_BLOB * ctx)107 TSS2_RC CommonComplete(_TSS2_SYS_CONTEXT_BLOB *ctx)
108 {
109     UINT32 rspSize;
110     TPM2_ST tag;
111     size_t next = 0;
112     TSS2_RC rval;
113 
114     if (!ctx)
115         return TSS2_SYS_RC_BAD_REFERENCE;
116 
117     rspSize = BE_TO_HOST_32(resp_header_from_cxt(ctx)->responseSize);
118 
119     if(rspSize > ctx->maxCmdSize) {
120         return TSS2_SYS_RC_MALFORMED_RESPONSE;
121     }
122 
123     if (ctx->previousStage != CMD_STAGE_RECEIVE_RESPONSE)
124         return TSS2_SYS_RC_BAD_SEQUENCE;
125 
126     ctx->nextData = (UINT8 *)ctx->rspParamsSize - ctx->cmdBuffer;
127 
128     rval = Tss2_MU_TPM2_ST_Unmarshal(ctx->cmdBuffer,
129                                     ctx->maxCmdSize,
130                                     &next, &tag);
131     if (rval)
132         return rval;
133 
134     /* Skipping over response params size field */
135     if (tag == TPM2_ST_SESSIONS)
136         rval = Tss2_MU_UINT32_Unmarshal(ctx->cmdBuffer,
137                                         ctx->maxCmdSize,
138                                         &ctx->nextData,
139                                         NULL);
140 
141     return rval;
142 }
143 
CommonOneCall(_TSS2_SYS_CONTEXT_BLOB * ctx,TSS2L_SYS_AUTH_COMMAND const * cmdAuthsArray,TSS2L_SYS_AUTH_RESPONSE * rspAuthsArray)144 TSS2_RC CommonOneCall(
145     _TSS2_SYS_CONTEXT_BLOB *ctx,
146     TSS2L_SYS_AUTH_COMMAND const *cmdAuthsArray,
147     TSS2L_SYS_AUTH_RESPONSE *rspAuthsArray)
148 {
149     TSS2_RC rval;
150 
151     if (cmdAuthsArray) {
152         rval = Tss2_Sys_SetCmdAuths((TSS2_SYS_CONTEXT *)ctx, cmdAuthsArray);
153         if (rval)
154             return rval;
155     }
156 
157     rval = Tss2_Sys_Execute((TSS2_SYS_CONTEXT *)ctx);
158     if (rval)
159         return rval;
160 
161     if (ctx->rsp_header.responseCode)
162         return ctx->rsp_header.responseCode;
163 
164     if (BE_TO_HOST_16(resp_header_from_cxt(ctx)->tag) ==
165             TPM2_ST_SESSIONS && rspAuthsArray)
166         rval = Tss2_Sys_GetRspAuths((TSS2_SYS_CONTEXT *)ctx, rspAuthsArray);
167 
168     return rval;
169 }
170 
171 static const COMMAND_HANDLES commandArray[] =
172 {
173     { TPM2_CC_Startup, 0, 0 },
174     { TPM2_CC_Shutdown, 0, 0 },
175     { TPM2_CC_SelfTest, 0, 0 },
176     { TPM2_CC_IncrementalSelfTest, 0, 0 },
177     { TPM2_CC_GetTestResult, 0, 0 },
178     { TPM2_CC_StartAuthSession, 2, 1 },
179     { TPM2_CC_PolicyRestart, 1, 0 },
180     { TPM2_CC_Create, 1, 0 },
181     { TPM2_CC_Load, 1, 1 },
182     { TPM2_CC_LoadExternal, 0, 1 },
183     { TPM2_CC_ReadPublic, 1, 0 },
184     { TPM2_CC_ActivateCredential, 2, 0 },
185     { TPM2_CC_MakeCredential, 1, 0 },
186     { TPM2_CC_Unseal, 1, 0 },
187     { TPM2_CC_ObjectChangeAuth, 2, 0 },
188     { TPM2_CC_Duplicate, 2, 0 },
189     { TPM2_CC_Rewrap, 2, 0 },
190     { TPM2_CC_Import, 1, 0 },
191     { TPM2_CC_RSA_Encrypt, 1, 0 },
192     { TPM2_CC_RSA_Decrypt, 1, 0 },
193     { TPM2_CC_ECDH_KeyGen, 1, 0 },
194     { TPM2_CC_ECDH_ZGen, 1, 0 },
195     { TPM2_CC_ECC_Parameters, 0, 0 },
196     { TPM2_CC_ZGen_2Phase, 1, 0 },
197     { TPM2_CC_EncryptDecrypt, 1, 0 },
198     { TPM2_CC_EncryptDecrypt2, 1, 0 },
199     { TPM2_CC_Hash, 0, 0 },
200     { TPM2_CC_HMAC, 1, 0 },
201     { TPM2_CC_GetRandom, 0, 0 },
202     { TPM2_CC_StirRandom, 0, 0 },
203     { TPM2_CC_HMAC_Start, 1, 1 },
204     { TPM2_CC_HashSequenceStart, 0, 1 },
205     { TPM2_CC_SequenceUpdate, 1, 0 },
206     { TPM2_CC_SequenceComplete, 1, 0 },
207     { TPM2_CC_EventSequenceComplete, 2, 0 },
208     { TPM2_CC_Certify, 2, 0 },
209     { TPM2_CC_CertifyCreation, 2, 0 },
210     { TPM2_CC_Quote, 1, 0 },
211     { TPM2_CC_GetSessionAuditDigest, 3, 0 },
212     { TPM2_CC_GetCommandAuditDigest, 2, 0 },
213     { TPM2_CC_GetTime, 2, 0 },
214     { TPM2_CC_Commit, 1, 0 },
215     { TPM2_CC_EC_Ephemeral, 0, 0 },
216     { TPM2_CC_VerifySignature, 1, 0 },
217     { TPM2_CC_Sign, 1, 0 },
218     { TPM2_CC_SetCommandCodeAuditStatus, 1, 0 },
219     { TPM2_CC_PCR_Extend, 1, 0 },
220     { TPM2_CC_PCR_Event, 1, 0 },
221     { TPM2_CC_PCR_Read, 0, 0 },
222     { TPM2_CC_PCR_Allocate, 1, 0 },
223     { TPM2_CC_PCR_SetAuthPolicy, 1, 0 },
224     { TPM2_CC_PCR_SetAuthValue, 1, 0 },
225     { TPM2_CC_PCR_Reset, 1, 0 },
226     { TPM2_CC_PolicySigned, 2, 0 },
227     { TPM2_CC_PolicySecret, 2, 0 },
228     { TPM2_CC_PolicyTicket, 1, 0 },
229     { TPM2_CC_PolicyOR, 1, 0 },
230     { TPM2_CC_PolicyPCR, 1, 0 },
231     { TPM2_CC_PolicyLocality, 1, 0 },
232     { TPM2_CC_PolicyNV, 3, 0 },
233     { TPM2_CC_PolicyNvWritten, 1, 0 },
234     { TPM2_CC_PolicyCounterTimer, 1, 0 },
235     { TPM2_CC_PolicyCommandCode, 1, 0 },
236     { TPM2_CC_PolicyPhysicalPresence, 1, 0 },
237     { TPM2_CC_PolicyCpHash, 1, 0 },
238     { TPM2_CC_PolicyNameHash, 1, 0 },
239     { TPM2_CC_PolicyDuplicationSelect, 1, 0 },
240     { TPM2_CC_PolicyAuthorize, 1, 0 },
241     { TPM2_CC_PolicyAuthValue, 1, 0 },
242     { TPM2_CC_PolicyPassword, 1, 0 },
243     { TPM2_CC_PolicyGetDigest, 1, 0 },
244     { TPM2_CC_PolicyTemplate, 1, 0 },
245     { TPM2_CC_CreatePrimary, 1, 1 },
246     { TPM2_CC_HierarchyControl, 1, 0 },
247     { TPM2_CC_SetPrimaryPolicy, 1, 0 },
248     { TPM2_CC_ChangePPS, 1, 0 },
249     { TPM2_CC_ChangeEPS, 1, 0 },
250     { TPM2_CC_Clear, 1, 0 },
251     { TPM2_CC_ClearControl, 1, 0 },
252     { TPM2_CC_HierarchyChangeAuth, 1, 0 },
253     { TPM2_CC_DictionaryAttackLockReset, 1, 0 },
254     { TPM2_CC_DictionaryAttackParameters, 1, 0 },
255     { TPM2_CC_PP_Commands, 1, 0 },
256     { TPM2_CC_SetAlgorithmSet, 1, 0 },
257     { TPM2_CC_FieldUpgradeStart, 2, 0 },
258     { TPM2_CC_FieldUpgradeData, 0, 0 },
259     { TPM2_CC_FirmwareRead, 0, 0 },
260     { TPM2_CC_ContextSave, 1, 0 },
261     { TPM2_CC_ContextLoad, 0, 1 },
262     { TPM2_CC_FlushContext, 1, 0 },
263     { TPM2_CC_EvictControl, 2, 0 },
264     { TPM2_CC_ReadClock, 0, 0 },
265     { TPM2_CC_ClockSet, 1, 0 },
266     { TPM2_CC_ClockRateAdjust, 1, 0 },
267     { TPM2_CC_GetCapability, 0, 0 },
268     { TPM2_CC_TestParms, 0, 0 },
269     { TPM2_CC_NV_DefineSpace, 1, 0 },
270     { TPM2_CC_NV_UndefineSpace, 2, 0 },
271     { TPM2_CC_NV_UndefineSpaceSpecial, 2, 0 },
272     { TPM2_CC_NV_ReadPublic, 1, 0 },
273     { TPM2_CC_NV_Write, 2, 0 },
274     { TPM2_CC_NV_Increment, 2, 0 },
275     { TPM2_CC_NV_Extend, 2, 0 },
276     { TPM2_CC_NV_SetBits, 2, 0 },
277     { TPM2_CC_NV_WriteLock, 2, 0 },
278     { TPM2_CC_NV_GlobalWriteLock, 1, 0 },
279     { TPM2_CC_NV_Read, 2, 0 },
280     { TPM2_CC_NV_ReadLock, 2, 0 },
281     { TPM2_CC_NV_ChangeAuth, 1, 0 },
282     { TPM2_CC_NV_Certify, 3, 0 },
283     { TPM2_CC_CreateLoaded, 1, 1 },
284     { TPM2_CC_PolicyAuthorizeNV, 3, 0 },
285     { TPM2_CC_AC_GetCapability, 1, 0 },
286     { TPM2_CC_AC_Send, 3, 0 },
287     { TPM2_CC_Policy_AC_SendSelect, 1, 0 }
288 };
289 
GetNumHandles(TPM2_CC commandCode,bool req)290 static int GetNumHandles(TPM2_CC commandCode, bool req)
291 {
292     uint8_t i;
293 
294     for (i = 0; i < sizeof(commandArray) / sizeof(COMMAND_HANDLES); i++) {
295         if (commandCode == commandArray[i].commandCode) {
296             if (req)
297                 return commandArray[i].numCommandHandles;
298             else
299                 return commandArray[i].numResponseHandles;
300         }
301     }
302 
303     return 0;
304 }
305 
GetNumCommandHandles(TPM2_CC commandCode)306 static int GetNumCommandHandles(TPM2_CC commandCode)
307 {
308     return GetNumHandles(commandCode, 1);
309 }
310 
GetNumResponseHandles(TPM2_CC commandCode)311 static int GetNumResponseHandles(TPM2_CC commandCode)
312 {
313     return GetNumHandles(commandCode, 0);
314 }
315 
316 #ifdef DISABLE_WEAK_CRYPTO
IsAlgorithmWeak(TPM2_ALG_ID algorithm,TPM2_KEY_SIZE key_size)317 bool IsAlgorithmWeak(TPM2_ALG_ID algorithm, TPM2_KEY_SIZE key_size)
318 {
319     switch (algorithm) {
320         case TPM2_ALG_RSA:
321             if (key_size < 2048) {
322                 LOG_ERROR("Error: weak algorithm");
323                 return true;
324             }
325         break;
326         case TPM2_ALG_AES:
327         case TPM2_ALG_SM4:
328         case TPM2_ALG_CAMELLIA:
329         case TPM2_ALG_SYMCIPHER:
330             if (key_size < 128) {
331                 LOG_ERROR("Error: weak algorithm");
332                 return true;
333             }
334         break;
335         case TPM2_ALG_SHA1:
336             LOG_ERROR("Error: weak algorithm");
337             return true;
338         break;
339     }
340 
341     return false;
342 }
343 
ValidatePublicTemplate(const TPM2B_PUBLIC * pub)344 TSS2_RC ValidatePublicTemplate(const TPM2B_PUBLIC *pub)
345 {
346     const TPMT_PUBLIC *tmpl = &pub->publicArea;
347 
348     switch (tmpl->type) {
349         case TPM2_ALG_RSA:
350             if (IsAlgorithmWeak(tmpl->type, tmpl->parameters.rsaDetail.keyBits) ||
351                 IsAlgorithmWeak(tmpl->parameters.rsaDetail.symmetric.algorithm,
352                                tmpl->parameters.rsaDetail.symmetric.keyBits.sym))
353                 return TSS2_SYS_RC_BAD_VALUE;
354         break;
355         case TPM2_ALG_ECC:
356             if (IsAlgorithmWeak(tmpl->parameters.eccDetail.symmetric.algorithm,
357                                tmpl->parameters.eccDetail.symmetric.keyBits.sym))
358                 return TSS2_SYS_RC_BAD_VALUE;
359         break;
360         case TPM2_ALG_AES:
361         case TPM2_ALG_SM4:
362         case TPM2_ALG_CAMELLIA:
363         case TPM2_ALG_SYMCIPHER:
364             if (IsAlgorithmWeak(tmpl->type,
365                                tmpl->parameters.symDetail.sym.keyBits.sym))
366                 return TSS2_SYS_RC_BAD_VALUE;
367         break;
368         default:
369             if (IsAlgorithmWeak(tmpl->type, 0))
370                 return TSS2_SYS_RC_BAD_VALUE;
371 
372         if (IsAlgorithmWeak(tmpl->nameAlg, 0))
373             return TSS2_SYS_RC_BAD_VALUE;
374 
375     }
376     return TSS2_RC_SUCCESS;
377 }
378 
ValidateNV_Public(const TPM2B_NV_PUBLIC * nv_public_info)379 TSS2_RC ValidateNV_Public(const TPM2B_NV_PUBLIC *nv_public_info)
380 {
381     const TPMS_NV_PUBLIC *nv_public = &nv_public_info->nvPublic;
382 
383     if (IsAlgorithmWeak(nv_public->nameAlg, 0))
384         return TSS2_SYS_RC_BAD_VALUE;
385 
386     return TSS2_RC_SUCCESS;
387 }
388 
ValidateTPML_PCR_SELECTION(const TPML_PCR_SELECTION * pcr_selection)389 TSS2_RC ValidateTPML_PCR_SELECTION(const TPML_PCR_SELECTION *pcr_selection)
390 {
391 
392     UINT16 i;
393 
394     for (i = 0; i < pcr_selection->count; i++) {
395         const TPMS_PCR_SELECTION *selection = &pcr_selection->pcrSelections[i];
396 
397         if (IsAlgorithmWeak(selection->hash, 0))
398             return TSS2_SYS_RC_BAD_VALUE;
399     }
400 
401     return TSS2_RC_SUCCESS;
402 }
403 
404 #else
IsAlgorithmWeak(TPM2_ALG_ID algorithm,TPM2_KEY_SIZE key_size)405 bool IsAlgorithmWeak(TPM2_ALG_ID algorithm, TPM2_KEY_SIZE key_size)
406 {
407     (void) algorithm;
408     (void) key_size;
409 
410     return false;
411 }
412 
ValidateNV_Public(const TPM2B_NV_PUBLIC * nv_public_info)413 TSS2_RC ValidateNV_Public(const TPM2B_NV_PUBLIC *nv_public_info)
414 {
415     (void) nv_public_info;
416 
417     return TSS2_RC_SUCCESS;
418 }
419 
ValidatePublicTemplate(const TPM2B_PUBLIC * pub)420 TSS2_RC ValidatePublicTemplate(const TPM2B_PUBLIC *pub)
421 {
422     (void) pub;
423 
424     return TSS2_RC_SUCCESS;
425 }
426 
ValidateTPML_PCR_SELECTION(const TPML_PCR_SELECTION * pcr_selection)427 TSS2_RC ValidateTPML_PCR_SELECTION(const TPML_PCR_SELECTION *pcr_selection)
428 {
429     (void) pcr_selection;
430 
431     return TSS2_RC_SUCCESS;
432 }
433 #endif
434