blob: 0a9e263e2344081dc5672822b7199edb077e5542 [file] [log] [blame]
Vadim Bendebury56797522015-05-20 10:32:25 -07001// This file was extracted from the TCG Published
2// Trusted Platform Module Library
3// Part 4: Supporting Routines
4// Family "2.0"
5// Level 00 Revision 01.16
6// October 30, 2014
7
8#include "Global.h"
9#include "CryptoEngine.h"
10#include "InternalRoutines.h"
11#include "AlgorithmCap_fp.h"
12//
13//
14// 10.4.2 Functions
15//
16// 10.4.2.1 RunSelfTest()
17//
18// Local function to run self-test
19//
20static TPM_RC
21CryptRunSelfTests(
22 ALGORITHM_VECTOR *toTest // IN: the vector of the algorithms to test
23 )
24{
25 TPM_ALG_ID alg;
26 // For each of the algorithms that are in the toTestVecor, need to run a
27 // test
28 for(alg = TPM_ALG_FIRST; alg <= TPM_ALG_LAST; alg++)
29 {
30 if(TEST_BIT(alg, *toTest))
31 {
32 TPM_RC result = CryptTestAlgorithm(alg, toTest);
33 if(result != TPM_RC_SUCCESS)
34 return result;
35 }
36 }
37 return TPM_RC_SUCCESS;
38}
39//
40//
41// 10.4.2.2 CryptSelfTest()
42//
43// This function is called to start/complete a full self-test. If fullTest is NO, then only the untested algorithms
44// will be run. If fullTest is YES, then g_untestedDecryptionAlgorithms is reinitialized and then all tests are
45// run. This implementation of the reference design does not support processing outside the framework of a
46// TPM command. As a consequence, this command does not complete until all tests are done. Since this
47// can take a long time, the TPM will check after each test to see if the command is canceled. If so, then the
48// TPM will returned TPM_RC_CANCELLED. To continue with the self-tests, call TPM2_SelfTest(fullTest ==
49// No) and the TPM will complete the testing.
50//
51// Error Returns Meaning
52//
53// TPM_RC_CANCELED if the command is canceled
54//
55LIB_EXPORT
56TPM_RC
57CryptSelfTest(
58 TPMI_YES_NO fullTest // IN: if full test is required
59 )
60{
61 if(g_forceFailureMode)
62 FAIL(FATAL_ERROR_FORCED);
63 // If the caller requested a full test, then reset the to test vector so that
64 // all the tests will be run
65 if(fullTest == YES)
66 {
67 MemoryCopy(g_toTest,
68 g_implementedAlgorithms,
69 sizeof(g_toTest), sizeof(g_toTest));
70 }
71 return CryptRunSelfTests(&g_toTest);
72}
73//
74//
75// 10.4.2.3 CryptIncrementalSelfTest()
76//
77// This function is used to perform an incremental self-test. This implementation will perform the toTest
78// values before returning. That is, it assumes that the TPM cannot perform background tasks between
79// commands.
80// This command may be canceled. If it is, then there is no return result. However, this command can be run
81// again and the incremental progress will not be lost.
82//
83// Error Returns Meaning
84//
85// TPM_RC_CANCELED processing of this command was canceled
86// TPM_RC_TESTING if toTest list is not empty
87// TPM_RC_VALUE an algorithm in the toTest list is not implemented
88//
89TPM_RC
90CryptIncrementalSelfTest(
91 TPML_ALG *toTest, // IN: list of algorithms to be tested
92 TPML_ALG *toDoList // OUT: list of algorithms needing test
93 )
94{
95 ALGORITHM_VECTOR toTestVector = {0};
96 TPM_ALG_ID alg;
97 UINT32 i;
98 pAssert(toTest != NULL && toDoList != NULL);
99 if(toTest->count > 0)
100 {
101 // Transcribe the toTest list into the toTestVector
102 for(i = 0; i < toTest->count; i++)
103 {
104 TPM_ALG_ID alg = toTest->algorithms[i];
105 // make sure that the algorithm value is not out of range
106 if((alg > TPM_ALG_LAST) || !TEST_BIT(alg, g_implementedAlgorithms))
107 return TPM_RC_VALUE;
108 SET_BIT(alg, toTestVector);
109 }
110 // Run the test
111 if(CryptRunSelfTests(&toTestVector) == TPM_RC_CANCELED)
112 return TPM_RC_CANCELED;
113 }
114 // Fill in the toDoList with the algorithms that are still untested
115 toDoList->count = 0;
116 for(alg = TPM_ALG_FIRST;
117 toDoList->count < MAX_ALG_LIST_SIZE && alg <= TPM_ALG_LAST;
118 alg++)
119 {
120 if(TEST_BIT(alg, g_toTest))
121 toDoList->algorithms[toDoList->count++] = alg;
122 }
123 return TPM_RC_SUCCESS;
124//
125}
126//
127//
128// 10.4.2.4 CryptInitializeToTest()
129//
130// This function will initialize the data structures for testing all the algorithms. This should not be called
131// unless CryptAlgsSetImplemented() has been called
132//
133void
134CryptInitializeToTest(
135 void
136 )
137{
138 MemoryCopy(g_toTest,
139 g_implementedAlgorithms,
140 sizeof(g_toTest),
141 sizeof(g_toTest));
142 // Setting the algorithm to null causes the test function to just clear
143 // out any algorithms for which there is no test.
144 CryptTestAlgorithm(TPM_ALG_ERROR, &g_toTest);
145 return;
146}
147//
148//
149// 10.4.2.5 CryptTestAlgorithm()
150//
151// Only point of contact with the actual self tests. If a self-test fails, there is no return and the TPM goes into
152// failure mode. The call to TestAlgorithm() uses an algorithms selector and a bit vector. When the test is
153// run, the corresponding bit in toTest and in g_toTest is CLEAR. If toTest is NULL, then only the bit in
154// g_toTest is CLEAR. There is a special case for the call to TestAlgorithm(). When alg is
155// TPM_ALG_ERROR, TestAlgorithm() will CLEAR any bit in toTest for which it has no test. This allows the
156// knowledge about which algorithms have test to be accessed through the interface that provides the test.
157//
158// Error Returns Meaning
159//
160// TPM_RC_SUCCESS test complete
161// TPM_RC_CANCELED test was canceled
162//
163LIB_EXPORT
164TPM_RC
165CryptTestAlgorithm(
166 TPM_ALG_ID alg,
167 ALGORITHM_VECTOR *toTest
168 )
169{
170 TPM_RC result = TPM_RC_SUCCESS;
171#ifdef SELF_TEST
172 // This is the function prototype for TestAlgorithms(). It is here and not
173 // in a _fp.h file to avoid a compiler error when SELF_TEST is not defined and
174 // AlgorithmTexts.c is not part of the build.
175 TPM_RC TestAlgorithm(TPM_ALG_ID alg, ALGORITHM_VECTOR *toTest);
176 result = TestAlgorithm(alg, toTest);
177#else
178 // If this is an attempt to determine the algorithms for which there is a
179 // self test, pretend that all of them do. We do that by not clearing any
180 // of the algorithm bits. When/if this function is called to run tests, it
181 // will over report. This can be changed so that any call to check on which
182 // algorithms have tests, 'toTest' can be cleared.
183 if(alg != TPM_ALG_ERROR)
184 {
185 CLEAR_BIT(alg, g_toTest);
186 if(toTest != NULL)
187 CLEAR_BIT(alg, *toTest);
188 }
189#endif
190 return result;
191}