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 //** Introduction
36 // This file contains the code to perform the various self-test functions.
37 //
38 // NOTE: In this implementation, large local variables are made static to minimize
39 // stack usage, which is critical for stack-constrained platforms.
40
41 //** Includes and Defines
42 #include "Tpm.h"
43
44 #define SELF_TEST_DATA
45
46 #if SELF_TEST
47
48 // These includes pull in the data structures. They contain data definitions for the
49 // various tests.
50 #include "SelfTest.h"
51 #include "SymmetricTest.h"
52 #include "RsaTestData.h"
53 #include "EccTestData.h"
54 #include "HashTestData.h"
55 #include "KdfTestData.h"
56
57 #define TEST_DEFAULT_TEST_HASH(vector) \
58 if(TEST_BIT(DEFAULT_TEST_HASH, g_toTest)) \
59 TestHash(DEFAULT_TEST_HASH, vector);
60
61 // Make sure that the algorithm has been tested
62 #define CLEAR_BOTH(alg) { CLEAR_BIT(alg, *toTest); \
63 if(toTest != &g_toTest) \
64 CLEAR_BIT(alg, g_toTest); }
65
66 #define SET_BOTH(alg) { SET_BIT(alg, *toTest); \
67 if(toTest != &g_toTest) \
68 SET_BIT(alg, g_toTest); }
69
70 #define TEST_BOTH(alg) ((toTest != &g_toTest) \
71 ? TEST_BIT(alg, *toTest) || TEST_BIT(alg, g_toTest) \
72 : TEST_BIT(alg, *toTest))
73
74 // Can only cancel if doing a list.
75 #define CHECK_CANCELED \
76 if(_plat__IsCanceled() && toTest != &g_toTest) \
77 return TPM_RC_CANCELED;
78
79 //** Hash Tests
80
81 //*** Description
82 // The hash test does a known-value HMAC using the specified hash algorithm.
83
84 //*** TestHash()
85 // The hash test function.
86 static TPM_RC
TestHash(TPM_ALG_ID hashAlg,ALGORITHM_VECTOR * toTest)87 TestHash(
88 TPM_ALG_ID hashAlg,
89 ALGORITHM_VECTOR *toTest
90 )
91 {
92 static TPM2B_DIGEST computed; // value computed
93 static HMAC_STATE state;
94 UINT16 digestSize;
95 const TPM2B *testDigest = NULL;
96 // TPM2B_TYPE(HMAC_BLOCK, DEFAULT_TEST_HASH_BLOCK_SIZE);
97
98 pAssert(hashAlg != TPM_ALG_NULL);
99 #define HASH_CASE_FOR_TEST(HASH, hash) case ALG_##HASH##_VALUE: \
100 testDigest = &c_##HASH##_digest.b; \
101 break;
102 switch(hashAlg)
103 {
104 FOR_EACH_HASH(HASH_CASE_FOR_TEST)
105
106 default:
107 FAIL(FATAL_ERROR_INTERNAL);
108 }
109 // Clear the to-test bits
110 CLEAR_BOTH(hashAlg);
111
112 // If there is an algorithm without test vectors, then assume that things are OK.
113 if(testDigest == NULL || testDigest->size == 0)
114 return TPM_RC_SUCCESS;
115
116 // Set the HMAC key to twice the digest size
117 digestSize = CryptHashGetDigestSize(hashAlg);
118 CryptHmacStart(&state, hashAlg, digestSize * 2,
119 (BYTE *)c_hashTestKey.t.buffer);
120 CryptDigestUpdate(&state.hashState, 2 * CryptHashGetBlockSize(hashAlg),
121 (BYTE *)c_hashTestData.t.buffer);
122 computed.t.size = digestSize;
123 CryptHmacEnd(&state, digestSize, computed.t.buffer);
124 if((testDigest->size != computed.t.size)
125 || (memcmp(testDigest->buffer, computed.t.buffer, computed.b.size) != 0))
126 SELF_TEST_FAILURE;
127 return TPM_RC_SUCCESS;
128 }
129
130 //** Symmetric Test Functions
131
132 //*** MakeIv()
133 // Internal function to make the appropriate IV depending on the mode.
134 static UINT32
MakeIv(TPM_ALG_ID mode,UINT32 size,BYTE * iv)135 MakeIv(
136 TPM_ALG_ID mode, // IN: symmetric mode
137 UINT32 size, // IN: block size of the algorithm
138 BYTE *iv // OUT: IV to fill in
139 )
140 {
141 BYTE i;
142
143 if(mode == TPM_ALG_ECB)
144 return 0;
145 if(mode == TPM_ALG_CTR)
146 {
147 // The test uses an IV that has 0xff in the last byte
148 for(i = 1; i <= size; i++)
149 *iv++ = 0xff - (BYTE)(size - i);
150 }
151 else
152 {
153 for(i = 0; i < size; i++)
154 *iv++ = i;
155 }
156 return size;
157 }
158
159 //*** TestSymmetricAlgorithm()
160 // Function to test a specific algorithm, key size, and mode.
161 static void
TestSymmetricAlgorithm(const SYMMETRIC_TEST_VECTOR * test,TPM_ALG_ID mode)162 TestSymmetricAlgorithm(
163 const SYMMETRIC_TEST_VECTOR *test, //
164 TPM_ALG_ID mode //
165 )
166 {
167 static BYTE encrypted[MAX_SYM_BLOCK_SIZE * 2];
168 static BYTE decrypted[MAX_SYM_BLOCK_SIZE * 2];
169 static TPM2B_IV iv;
170 //
171 // Get the appropriate IV
172 iv.t.size = (UINT16)MakeIv(mode, test->ivSize, iv.t.buffer);
173
174 // Encrypt known data
175 CryptSymmetricEncrypt(encrypted, test->alg, test->keyBits, test->key, &iv,
176 mode, test->dataInOutSize, test->dataIn);
177 // Check that it matches the expected value
178 if(!MemoryEqual(encrypted, test->dataOut[mode - TPM_ALG_CTR],
179 test->dataInOutSize))
180 SELF_TEST_FAILURE;
181 // Reinitialize the iv for decryption
182 MakeIv(mode, test->ivSize, iv.t.buffer);
183 CryptSymmetricDecrypt(decrypted, test->alg, test->keyBits, test->key, &iv,
184 mode, test->dataInOutSize,
185 test->dataOut[mode - TPM_ALG_CTR]);
186 // Make sure that it matches what we started with
187 if(!MemoryEqual(decrypted, test->dataIn, test->dataInOutSize))
188 SELF_TEST_FAILURE;
189 }
190
191 //*** AllSymsAreDone()
192 // Checks if both symmetric algorithms have been tested. This is put here
193 // so that addition of a symmetric algorithm will be relatively easy to handle.
194 //
195 // Return Type: BOOL
196 // TRUE(1) all symmetric algorithms tested
197 // FALSE(0) not all symmetric algorithms tested
198 static BOOL
AllSymsAreDone(ALGORITHM_VECTOR * toTest)199 AllSymsAreDone(
200 ALGORITHM_VECTOR *toTest
201 )
202 {
203 return (!TEST_BOTH(TPM_ALG_AES) && !TEST_BOTH(TPM_ALG_SM4));
204 }
205
206 //*** AllModesAreDone()
207 // Checks if all the modes have been tested.
208 //
209 // Return Type: BOOL
210 // TRUE(1) all modes tested
211 // FALSE(0) all modes not tested
212 static BOOL
AllModesAreDone(ALGORITHM_VECTOR * toTest)213 AllModesAreDone(
214 ALGORITHM_VECTOR *toTest
215 )
216 {
217 TPM_ALG_ID alg;
218 for(alg = SYM_MODE_FIRST; alg <= SYM_MODE_LAST; alg++)
219 if(TEST_BOTH(alg))
220 return FALSE;
221 return TRUE;
222 }
223
224 //*** TestSymmetric()
225 // If 'alg' is a symmetric block cipher, then all of the modes that are selected are
226 // tested. If 'alg' is a mode, then all algorithms of that mode are tested.
227 static TPM_RC
TestSymmetric(TPM_ALG_ID alg,ALGORITHM_VECTOR * toTest)228 TestSymmetric(
229 TPM_ALG_ID alg,
230 ALGORITHM_VECTOR *toTest
231 )
232 {
233 SYM_INDEX index;
234 TPM_ALG_ID mode;
235 //
236 if(!TEST_BIT(alg, *toTest))
237 return TPM_RC_SUCCESS;
238 if(alg == TPM_ALG_AES || alg == TPM_ALG_SM4 || alg == TPM_ALG_CAMELLIA)
239 {
240 // Will test the algorithm for all modes and key sizes
241 CLEAR_BOTH(alg);
242
243 // A test this algorithm for all modes
244 for(index = 0; index < NUM_SYMS; index++)
245 {
246 if(c_symTestValues[index].alg == alg)
247 {
248 for(mode = SYM_MODE_FIRST;
249 mode <= SYM_MODE_LAST;
250 mode++)
251 {
252 if(TEST_BIT(mode, *toTest))
253 TestSymmetricAlgorithm(&c_symTestValues[index], mode);
254 }
255 }
256 }
257 // if all the symmetric tests are done
258 if(AllSymsAreDone(toTest))
259 {
260 // all symmetric algorithms tested so no modes should be set
261 for(alg = SYM_MODE_FIRST; alg <= SYM_MODE_LAST; alg++)
262 CLEAR_BOTH(alg);
263 }
264 }
265 else if(SYM_MODE_FIRST <= alg && alg <= SYM_MODE_LAST)
266 {
267 // Test this mode for all key sizes and algorithms
268 for(index = 0; index < NUM_SYMS; index++)
269 {
270 // The mode testing only comes into play when doing self tests
271 // by command. When doing self tests by command, the block ciphers are
272 // tested first. That means that all of their modes would have been
273 // tested for all key sizes. If there is no block cipher left to
274 // test, then clear this mode bit.
275 if(!TEST_BIT(TPM_ALG_AES, *toTest)
276 && !TEST_BIT(TPM_ALG_SM4, *toTest))
277 {
278 CLEAR_BOTH(alg);
279 }
280 else
281 {
282 for(index = 0; index < NUM_SYMS; index++)
283 {
284 if(TEST_BIT(c_symTestValues[index].alg, *toTest))
285 TestSymmetricAlgorithm(&c_symTestValues[index], alg);
286 }
287 // have tested this mode for all algorithms
288 CLEAR_BOTH(alg);
289 }
290 }
291 if(AllModesAreDone(toTest))
292 {
293 CLEAR_BOTH(TPM_ALG_AES);
294 CLEAR_BOTH(TPM_ALG_SM4);
295 }
296 }
297 else
298 pAssert(alg == 0 && alg != 0);
299 return TPM_RC_SUCCESS;
300 }
301
302 //** RSA Tests
303 #if ALG_RSA
304
305 //*** Introduction
306 // The tests are for public key only operations and for private key operations.
307 // Signature verification and encryption are public key operations. They are tested
308 // by using a KVT. For signature verification, this means that a known good
309 // signature is checked by CryptRsaValidateSignature(). If it fails, then the
310 // TPM enters failure mode. For encryption, the TPM encrypts known values using
311 // the selected scheme and checks that the returned value matches the expected
312 // value.
313 //
314 // For private key operations, a full scheme check is used. For a signing key, a
315 // known key is used to sign a known message. Then that signature is verified.
316 // since the signature may involve use of random values, the signature will be
317 // different each time and we can't always check that the signature matches a
318 // known value. The same technique is used for decryption (RSADP/RSAEP).
319 //
320 // When an operation uses the public key and the verification has not been
321 // tested, the TPM will do a KVT.
322 //
323 // The test for the signing algorithm is built into the call for the algorithm
324
325 //*** RsaKeyInitialize()
326 // The test key is defined by a public modulus and a private prime. The TPM's RSA
327 // code computes the second prime and the private exponent.
328 static void
RsaKeyInitialize(OBJECT * testObject)329 RsaKeyInitialize(
330 OBJECT *testObject
331 )
332 {
333 MemoryCopy2B(&testObject->publicArea.unique.rsa.b, (P2B)&c_rsaPublicModulus,
334 sizeof(c_rsaPublicModulus));
335 MemoryCopy2B(&testObject->sensitive.sensitive.rsa.b, (P2B)&c_rsaPrivatePrime,
336 sizeof(testObject->sensitive.sensitive.rsa.t.buffer));
337 testObject->publicArea.parameters.rsaDetail.keyBits = RSA_TEST_KEY_SIZE * 8;
338 // Use the default exponent
339 testObject->publicArea.parameters.rsaDetail.exponent = 0;
340 }
341
342 //*** TestRsaEncryptDecrypt()
343 // These tests are for a public key encryption that uses a random value.
344 static TPM_RC
TestRsaEncryptDecrypt(TPM_ALG_ID scheme,ALGORITHM_VECTOR * toTest)345 TestRsaEncryptDecrypt(
346 TPM_ALG_ID scheme, // IN: the scheme
347 ALGORITHM_VECTOR *toTest //
348 )
349 {
350 static TPM2B_PUBLIC_KEY_RSA testInput;
351 static TPM2B_PUBLIC_KEY_RSA testOutput;
352 static OBJECT testObject;
353 const TPM2B_RSA_TEST_KEY *kvtValue = NULL;
354 TPM_RC result = TPM_RC_SUCCESS;
355 const TPM2B *testLabel = NULL;
356 TPMT_RSA_DECRYPT rsaScheme;
357 //
358 // Don't need to initialize much of the test object
359 RsaKeyInitialize(&testObject);
360 rsaScheme.scheme = scheme;
361 rsaScheme.details.anySig.hashAlg = DEFAULT_TEST_HASH;
362 CLEAR_BOTH(scheme);
363 CLEAR_BOTH(TPM_ALG_NULL);
364 if(scheme == TPM_ALG_NULL)
365 {
366 // This is an encryption scheme using the private key without any encoding.
367 memcpy(testInput.t.buffer, c_RsaTestValue, sizeof(c_RsaTestValue));
368 testInput.t.size = sizeof(c_RsaTestValue);
369 if(TPM_RC_SUCCESS != CryptRsaEncrypt(&testOutput, &testInput.b,
370 &testObject, &rsaScheme, NULL, NULL))
371 SELF_TEST_FAILURE;
372 if(!MemoryEqual(testOutput.t.buffer, c_RsaepKvt.buffer, c_RsaepKvt.size))
373 SELF_TEST_FAILURE;
374 MemoryCopy2B(&testInput.b, &testOutput.b, sizeof(testInput.t.buffer));
375 if(TPM_RC_SUCCESS != CryptRsaDecrypt(&testOutput.b, &testInput.b,
376 &testObject, &rsaScheme, NULL))
377 SELF_TEST_FAILURE;
378 if(!MemoryEqual(testOutput.t.buffer, c_RsaTestValue,
379 sizeof(c_RsaTestValue)))
380 SELF_TEST_FAILURE;
381 }
382 else
383 {
384 // TPM_ALG_RSAES:
385 // This is an decryption scheme using padding according to
386 // PKCS#1v2.1, 7.2. This padding uses random bits. To test a public
387 // key encryption that uses random data, encrypt a value and then
388 // decrypt the value and see that we get the encrypted data back.
389 // The hash is not used by this encryption so it can be TMP_ALG_NULL
390
391 // TPM_ALG_OAEP:
392 // This is also an decryption scheme and it also uses a
393 // pseudo-random
394 // value. However, this also uses a hash algorithm. So, we may need
395 // to test that algorithm before use.
396 if(scheme == TPM_ALG_OAEP)
397 {
398 TEST_DEFAULT_TEST_HASH(toTest);
399 kvtValue = &c_OaepKvt;
400 testLabel = OAEP_TEST_STRING;
401 }
402 else if(scheme == TPM_ALG_RSAES)
403 {
404 kvtValue = &c_RsaesKvt;
405 testLabel = NULL;
406 }
407 else
408 SELF_TEST_FAILURE;
409 // Only use a digest-size portion of the test value
410 memcpy(testInput.t.buffer, c_RsaTestValue, DEFAULT_TEST_DIGEST_SIZE);
411 testInput.t.size = DEFAULT_TEST_DIGEST_SIZE;
412
413 // See if the encryption works
414 if(TPM_RC_SUCCESS != CryptRsaEncrypt(&testOutput, &testInput.b,
415 &testObject, &rsaScheme, testLabel,
416 NULL))
417 SELF_TEST_FAILURE;
418 MemoryCopy2B(&testInput.b, &testOutput.b, sizeof(testInput.t.buffer));
419 // see if we can decrypt this value and get the original data back
420 if(TPM_RC_SUCCESS != CryptRsaDecrypt(&testOutput.b, &testInput.b,
421 &testObject, &rsaScheme, testLabel))
422 SELF_TEST_FAILURE;
423 // See if the results compare
424 if(testOutput.t.size != DEFAULT_TEST_DIGEST_SIZE
425 || !MemoryEqual(testOutput.t.buffer, c_RsaTestValue,
426 DEFAULT_TEST_DIGEST_SIZE))
427 SELF_TEST_FAILURE;
428 // Now check that the decryption works on a known value
429 MemoryCopy2B(&testInput.b, (P2B)kvtValue,
430 sizeof(testInput.t.buffer));
431 if(TPM_RC_SUCCESS != CryptRsaDecrypt(&testOutput.b, &testInput.b,
432 &testObject, &rsaScheme, testLabel))
433 SELF_TEST_FAILURE;
434 if(testOutput.t.size != DEFAULT_TEST_DIGEST_SIZE
435 || !MemoryEqual(testOutput.t.buffer, c_RsaTestValue,
436 DEFAULT_TEST_DIGEST_SIZE))
437 SELF_TEST_FAILURE;
438 }
439 return result;
440 }
441
442 //*** TestRsaSignAndVerify()
443 // This function does the testing of the RSA sign and verification functions. This
444 // test does a KVT.
445 static TPM_RC
TestRsaSignAndVerify(TPM_ALG_ID scheme,ALGORITHM_VECTOR * toTest)446 TestRsaSignAndVerify(
447 TPM_ALG_ID scheme,
448 ALGORITHM_VECTOR *toTest
449 )
450 {
451 TPM_RC result = TPM_RC_SUCCESS;
452 static OBJECT testObject;
453 static TPM2B_DIGEST testDigest;
454 static TPMT_SIGNATURE testSig;
455
456 // Do a sign and signature verification.
457 // RSASSA:
458 // This is a signing scheme according to PKCS#1-v2.1 8.2. It does not
459 // use random data so there is a KVT for the signing operation. On
460 // first use of the scheme for signing, use the TPM's RSA key to
461 // sign a portion of c_RsaTestData and compare the results to c_RsassaKvt. Then
462 // decrypt the data to see that it matches the starting value. This verifies
463 // the signature with a KVT
464
465 // Clear the bits indicating that the function has not been checked. This is to
466 // prevent looping
467 CLEAR_BOTH(scheme);
468 CLEAR_BOTH(TPM_ALG_NULL);
469 CLEAR_BOTH(TPM_ALG_RSA);
470
471 RsaKeyInitialize(&testObject);
472 memcpy(testDigest.t.buffer, (BYTE *)c_RsaTestValue, DEFAULT_TEST_DIGEST_SIZE);
473 testDigest.t.size = DEFAULT_TEST_DIGEST_SIZE;
474 testSig.sigAlg = scheme;
475 testSig.signature.rsapss.hash = DEFAULT_TEST_HASH;
476
477 // RSAPSS:
478 // This is a signing scheme a according to PKCS#1-v2.2 8.1 it uses
479 // random data in the signature so there is no KVT for the signing
480 // operation. To test signing, the TPM will use the TPM's RSA key
481 // to sign a portion of c_RsaTestValue and then it will verify the
482 // signature. For verification, c_RsapssKvt is verified before the
483 // user signature blob is verified. The worst case for testing of this
484 // algorithm is two private and one public key operation.
485
486 // The process is to sign known data. If RSASSA is being done, verify that the
487 // signature matches the precomputed value. For both, use the signed value and
488 // see that the verification says that it is a good signature. Then
489 // if testing RSAPSS, do a verify of a known good signature. This ensures that
490 // the validation function works.
491
492 if(TPM_RC_SUCCESS != CryptRsaSign(&testSig, &testObject, &testDigest, NULL))
493 SELF_TEST_FAILURE;
494 // For RSASSA, make sure the results is what we are looking for
495 if(testSig.sigAlg == TPM_ALG_RSASSA)
496 {
497 if(testSig.signature.rsassa.sig.t.size != RSA_TEST_KEY_SIZE
498 || !MemoryEqual(c_RsassaKvt.buffer,
499 testSig.signature.rsassa.sig.t.buffer,
500 RSA_TEST_KEY_SIZE))
501 SELF_TEST_FAILURE;
502 }
503 // See if the TPM will validate its own signatures
504 if(TPM_RC_SUCCESS != CryptRsaValidateSignature(&testSig, &testObject,
505 &testDigest))
506 SELF_TEST_FAILURE;
507 // If this is RSAPSS, check the verification with known signature
508 // Have to copy because CrytpRsaValidateSignature() eats the signature
509 if(TPM_ALG_RSAPSS == scheme)
510 {
511 MemoryCopy2B(&testSig.signature.rsapss.sig.b, (P2B)&c_RsapssKvt,
512 sizeof(testSig.signature.rsapss.sig.t.buffer));
513 if(TPM_RC_SUCCESS != CryptRsaValidateSignature(&testSig, &testObject,
514 &testDigest))
515 SELF_TEST_FAILURE;
516 }
517 return result;
518 }
519
520 //*** TestRSA()
521 // Function uses the provided vector to indicate which tests to run. It will clear
522 // the vector after each test is run and also clear g_toTest
523 static TPM_RC
TestRsa(TPM_ALG_ID alg,ALGORITHM_VECTOR * toTest)524 TestRsa(
525 TPM_ALG_ID alg,
526 ALGORITHM_VECTOR *toTest
527 )
528 {
529 TPM_RC result = TPM_RC_SUCCESS;
530 //
531 switch(alg)
532 {
533 case TPM_ALG_NULL:
534 // This is the RSAEP/RSADP function. If we are processing a list, don't
535 // need to test these now because any other test will validate
536 // RSAEP/RSADP. Can tell this is list of test by checking to see if
537 // 'toTest' is pointing at g_toTest. If so, this is an isolated test
538 // an need to go ahead and do the test;
539 if((toTest == &g_toTest)
540 || (!TEST_BIT(TPM_ALG_RSASSA, *toTest)
541 && !TEST_BIT(TPM_ALG_RSAES, *toTest)
542 && !TEST_BIT(TPM_ALG_RSAPSS, *toTest)
543 && !TEST_BIT(TPM_ALG_OAEP, *toTest)))
544 // Not running a list of tests or no other tests on the list
545 // so run the test now
546 result = TestRsaEncryptDecrypt(alg, toTest);
547 // if not running the test now, leave the bit on, just in case things
548 // get interrupted
549 break;
550 case TPM_ALG_OAEP:
551 case TPM_ALG_RSAES:
552 result = TestRsaEncryptDecrypt(alg, toTest);
553 break;
554 case TPM_ALG_RSAPSS:
555 case TPM_ALG_RSASSA:
556 result = TestRsaSignAndVerify(alg, toTest);
557 break;
558 default:
559 SELF_TEST_FAILURE;
560 }
561 return result;
562 }
563
564 #endif // ALG_RSA
565
566 //** ECC Tests
567
568 #if ALG_ECC
569
570 //*** LoadEccParameter()
571 // This function is mostly for readability and type checking
572 static void
LoadEccParameter(TPM2B_ECC_PARAMETER * to,const TPM2B_EC_TEST * from)573 LoadEccParameter(
574 TPM2B_ECC_PARAMETER *to, // target
575 const TPM2B_EC_TEST *from // source
576 )
577 {
578 MemoryCopy2B(&to->b, &from->b, sizeof(to->t.buffer));
579 }
580
581 //*** LoadEccPoint()
582 static void
LoadEccPoint(TPMS_ECC_POINT * point,const TPM2B_EC_TEST * x,const TPM2B_EC_TEST * y)583 LoadEccPoint(
584 TPMS_ECC_POINT *point, // target
585 const TPM2B_EC_TEST *x, // source
586 const TPM2B_EC_TEST *y
587 )
588 {
589 MemoryCopy2B(&point->x.b, (TPM2B *)x, sizeof(point->x.t.buffer));
590 MemoryCopy2B(&point->y.b, (TPM2B *)y, sizeof(point->y.t.buffer));
591 }
592
593 //*** TestECDH()
594 // This test does a KVT on a point multiply.
595 static TPM_RC
TestECDH(TPM_ALG_ID scheme,ALGORITHM_VECTOR * toTest)596 TestECDH(
597 TPM_ALG_ID scheme, // IN: for consistency
598 ALGORITHM_VECTOR *toTest // IN/OUT: modified after test is run
599 )
600 {
601 static TPMS_ECC_POINT Z;
602 static TPMS_ECC_POINT Qe;
603 static TPM2B_ECC_PARAMETER ds;
604 TPM_RC result = TPM_RC_SUCCESS;
605 //
606 NOT_REFERENCED(scheme);
607 CLEAR_BOTH(TPM_ALG_ECDH);
608 LoadEccParameter(&ds, &c_ecTestKey_ds);
609 LoadEccPoint(&Qe, &c_ecTestKey_QeX, &c_ecTestKey_QeY);
610 if(TPM_RC_SUCCESS != CryptEccPointMultiply(&Z, c_testCurve, &Qe, &ds,
611 NULL, NULL))
612 SELF_TEST_FAILURE;
613 if(!MemoryEqual2B(&c_ecTestEcdh_X.b, &Z.x.b)
614 || !MemoryEqual2B(&c_ecTestEcdh_Y.b, &Z.y.b))
615 SELF_TEST_FAILURE;
616 return result;
617 }
618
619 //*** TestEccSignAndVerify()
620 static TPM_RC
TestEccSignAndVerify(TPM_ALG_ID scheme,ALGORITHM_VECTOR * toTest)621 TestEccSignAndVerify(
622 TPM_ALG_ID scheme,
623 ALGORITHM_VECTOR *toTest
624 )
625 {
626 static OBJECT testObject;
627 static TPMT_SIGNATURE testSig;
628 static TPMT_ECC_SCHEME eccScheme;
629
630 testSig.sigAlg = scheme;
631 testSig.signature.ecdsa.hash = DEFAULT_TEST_HASH;
632
633 eccScheme.scheme = scheme;
634 eccScheme.details.anySig.hashAlg = DEFAULT_TEST_HASH;
635
636 CLEAR_BOTH(scheme);
637 CLEAR_BOTH(TPM_ALG_ECDH);
638
639 // ECC signature verification testing uses a KVT.
640 switch(scheme)
641 {
642 case TPM_ALG_ECDSA:
643 LoadEccParameter(&testSig.signature.ecdsa.signatureR, &c_TestEcDsa_r);
644 LoadEccParameter(&testSig.signature.ecdsa.signatureS, &c_TestEcDsa_s);
645 break;
646 case TPM_ALG_ECSCHNORR:
647 LoadEccParameter(&testSig.signature.ecschnorr.signatureR,
648 &c_TestEcSchnorr_r);
649 LoadEccParameter(&testSig.signature.ecschnorr.signatureS,
650 &c_TestEcSchnorr_s);
651 break;
652 case TPM_ALG_SM2:
653 // don't have a test for SM2
654 return TPM_RC_SUCCESS;
655 default:
656 SELF_TEST_FAILURE;
657 break;
658 }
659 TEST_DEFAULT_TEST_HASH(toTest);
660
661 // Have to copy the key. This is because the size used in the test vectors
662 // is the size of the ECC parameter for the test key while the size of a point
663 // is TPM dependent
664 MemoryCopy2B(&testObject.sensitive.sensitive.ecc.b, &c_ecTestKey_ds.b,
665 sizeof(testObject.sensitive.sensitive.ecc.t.buffer));
666 LoadEccPoint(&testObject.publicArea.unique.ecc, &c_ecTestKey_QsX,
667 &c_ecTestKey_QsY);
668 testObject.publicArea.parameters.eccDetail.curveID = c_testCurve;
669
670 if(TPM_RC_SUCCESS != CryptEccValidateSignature(&testSig, &testObject,
671 (TPM2B_DIGEST *)&c_ecTestValue.b))
672 {
673 SELF_TEST_FAILURE;
674 }
675 CHECK_CANCELED;
676
677 // Now sign and verify some data
678 if(TPM_RC_SUCCESS != CryptEccSign(&testSig, &testObject,
679 (TPM2B_DIGEST *)&c_ecTestValue,
680 &eccScheme, NULL))
681 SELF_TEST_FAILURE;
682
683 CHECK_CANCELED;
684
685 if(TPM_RC_SUCCESS != CryptEccValidateSignature(&testSig, &testObject,
686 (TPM2B_DIGEST *)&c_ecTestValue))
687 SELF_TEST_FAILURE;
688
689 CHECK_CANCELED;
690
691 return TPM_RC_SUCCESS;
692 }
693
694 //*** TestKDFa()
695 static TPM_RC
TestKDFa(ALGORITHM_VECTOR * toTest)696 TestKDFa(
697 ALGORITHM_VECTOR *toTest
698 )
699 {
700 static TPM2B_KDF_TEST_KEY keyOut;
701 UINT32 counter = 0;
702 //
703 CLEAR_BOTH(TPM_ALG_KDF1_SP800_108);
704
705 keyOut.t.size = CryptKDFa(KDF_TEST_ALG, &c_kdfTestKeyIn.b, &c_kdfTestLabel.b,
706 &c_kdfTestContextU.b, &c_kdfTestContextV.b,
707 TEST_KDF_KEY_SIZE * 8, keyOut.t.buffer,
708 &counter, FALSE);
709 if ( keyOut.t.size != TEST_KDF_KEY_SIZE
710 || !MemoryEqual(keyOut.t.buffer, c_kdfTestKeyOut.t.buffer,
711 TEST_KDF_KEY_SIZE))
712 SELF_TEST_FAILURE;
713
714 return TPM_RC_SUCCESS;
715 }
716
717 //*** TestEcc()
718 static TPM_RC
TestEcc(TPM_ALG_ID alg,ALGORITHM_VECTOR * toTest)719 TestEcc(
720 TPM_ALG_ID alg,
721 ALGORITHM_VECTOR *toTest
722 )
723 {
724 TPM_RC result = TPM_RC_SUCCESS;
725 NOT_REFERENCED(toTest);
726 switch(alg)
727 {
728 case TPM_ALG_ECC:
729 case TPM_ALG_ECDH:
730 // If this is in a loop then see if another test is going to deal with
731 // this.
732 // If toTest is not a self-test list
733 if((toTest == &g_toTest)
734 // or this is the only ECC test in the list
735 || !(TEST_BIT(TPM_ALG_ECDSA, *toTest)
736 || TEST_BIT(ALG_ECSCHNORR, *toTest)
737 || TEST_BIT(TPM_ALG_SM2, *toTest)))
738 {
739 result = TestECDH(alg, toTest);
740 }
741 break;
742 case TPM_ALG_ECDSA:
743 case TPM_ALG_ECSCHNORR:
744 case TPM_ALG_SM2:
745 result = TestEccSignAndVerify(alg, toTest);
746 break;
747 default:
748 SELF_TEST_FAILURE;
749 break;
750 }
751 return result;
752 }
753
754 #endif // ALG_ECC
755
756 //*** TestAlgorithm()
757 // Dispatches to the correct test function for the algorithm or gets a list of
758 // testable algorithms.
759 //
760 // If 'toTest' is not NULL, then the test decisions are based on the algorithm
761 // selections in 'toTest'. Otherwise, 'g_toTest' is used. When bits are clear in
762 // 'g_toTest' they will also be cleared 'toTest'.
763 //
764 // If there doesn't happen to be a test for the algorithm, its associated bit is
765 // quietly cleared.
766 //
767 // If 'alg' is zero (TPM_ALG_ERROR), then the toTest vector is cleared of any bits
768 // for which there is no test (i.e. no tests are actually run but the vector is
769 // cleared).
770 //
771 // Note: 'toTest' will only ever have bits set for implemented algorithms but 'alg'
772 // can be anything.
773 //
774 // Return Type: TPM_RC
775 // TPM_RC_CANCELED test was canceled
776 LIB_EXPORT
777 TPM_RC
TestAlgorithm(TPM_ALG_ID alg,ALGORITHM_VECTOR * toTest)778 TestAlgorithm(
779 TPM_ALG_ID alg,
780 ALGORITHM_VECTOR *toTest
781 )
782 {
783 TPM_ALG_ID first = (alg == TPM_ALG_ERROR) ? TPM_ALG_FIRST : alg;
784 TPM_ALG_ID last = (alg == TPM_ALG_ERROR) ? TPM_ALG_LAST : alg;
785 BOOL doTest = (alg != TPM_ALG_ERROR);
786 TPM_RC result = TPM_RC_SUCCESS;
787
788 if(toTest == NULL)
789 toTest = &g_toTest;
790
791 // This is kind of strange. This function will either run a test of the selected
792 // algorithm or just clear a bit if there is no test for the algorithm. So,
793 // either this loop will be executed once for the selected algorithm or once for
794 // each of the possible algorithms. If it is executed more than once ('alg' ==
795 // ALG_ERROR), then no test will be run but bits will be cleared for
796 // unimplemented algorithms. This was done this way so that there is only one
797 // case statement with all of the algorithms. It was easier to have one case
798 // statement than to have multiple ones to manage whenever an algorithm ID is
799 // added.
800 for(alg = first; (alg <= last); alg++)
801 {
802 // if 'alg' was TPM_ALG_ERROR, then we will be cycling through
803 // values, some of which may not be implemented. If the bit in toTest
804 // happens to be set, then we could either generated an assert, or just
805 // silently CLEAR it. Decided to just clear.
806 if(!TEST_BIT(alg, g_implementedAlgorithms))
807 {
808 CLEAR_BIT(alg, *toTest);
809 continue;
810 }
811 // Process whatever is left.
812 // NOTE: since this switch will only be called if the algorithm is
813 // implemented, it is not necessary to modify this list except to comment
814 // out the algorithms for which there is no test
815 switch(alg)
816 {
817 // Symmetric block ciphers
818 #if ALG_AES
819 case TPM_ALG_AES:
820 #endif // ALG_AES
821 #if ALG_SM4
822 // if SM4 is implemented, its test is like other block ciphers but there
823 // aren't any test vectors for it yet
824 // case TPM_ALG_SM4:
825 #endif // ALG_SM4
826 #if ALG_CAMELLIA
827 // no test vectors for camellia
828 // case TPM_ALG_CAMELLIA:
829 #endif
830 // Symmetric modes
831 #if !ALG_CFB
832 # error CFB is required in all TPM implementations
833 #endif // !ALG_CFB
834 case TPM_ALG_CFB:
835 if(doTest)
836 result = TestSymmetric(alg, toTest);
837 break;
838 #if ALG_CTR
839 case TPM_ALG_CTR:
840 #endif // ALG_CRT
841 #if ALG_OFB
842 case TPM_ALG_OFB:
843 #endif // ALG_OFB
844 #if ALG_CBC
845 case TPM_ALG_CBC:
846 #endif // ALG_CBC
847 #if ALG_ECB
848 case TPM_ALG_ECB:
849 #endif
850 if(doTest)
851 result = TestSymmetric(alg, toTest);
852 else
853 // If doing the initialization of g_toTest vector, only need
854 // to test one of the modes for the symmetric algorithms. If
855 // initializing for a SelfTest(FULL_TEST), allow all the modes.
856 if(toTest == &g_toTest)
857 CLEAR_BIT(alg, *toTest);
858 break;
859 #if !ALG_HMAC
860 # error HMAC is required in all TPM implementations
861 #endif
862 case TPM_ALG_HMAC:
863 // Clear the bit that indicates that HMAC is required because
864 // HMAC is used as the basic test for all hash algorithms.
865 CLEAR_BOTH(alg);
866 // Testing HMAC means test the default hash
867 if(doTest)
868 TestHash(DEFAULT_TEST_HASH, toTest);
869 else
870 // If not testing, then indicate that the hash needs to be
871 // tested because this uses HMAC
872 SET_BOTH(DEFAULT_TEST_HASH);
873 break;
874 // Have to use two arguments for the macro even though only the first is used in the
875 // expansion.
876 #define HASH_CASE_TEST(HASH, hash) \
877 case ALG_##HASH##_VALUE:
878 FOR_EACH_HASH(HASH_CASE_TEST)
879 #undef HASH_CASE_TEST
880 if(doTest)
881 result = TestHash(alg, toTest);
882 break;
883 // RSA-dependent
884 #if ALG_RSA
885 case TPM_ALG_RSA:
886 CLEAR_BOTH(alg);
887 if(doTest)
888 result = TestRsa(TPM_ALG_NULL, toTest);
889 else
890 SET_BOTH(TPM_ALG_NULL);
891 break;
892 case TPM_ALG_RSASSA:
893 case TPM_ALG_RSAES:
894 case TPM_ALG_RSAPSS:
895 case TPM_ALG_OAEP:
896 case TPM_ALG_NULL: // used or RSADP
897 if(doTest)
898 result = TestRsa(alg, toTest);
899 break;
900 #endif // ALG_RSA
901 #if ALG_KDF1_SP800_108
902 case TPM_ALG_KDF1_SP800_108:
903 if(doTest)
904 result = TestKDFa(toTest);
905 break;
906 #endif // ALG_KDF1_SP800_108
907 #if ALG_ECC
908 // ECC dependent but no tests
909 // case TPM_ALG_ECDAA:
910 // case TPM_ALG_ECMQV:
911 // case TPM_ALG_KDF1_SP800_56a:
912 // case TPM_ALG_KDF2:
913 // case TPM_ALG_MGF1:
914 case TPM_ALG_ECC:
915 CLEAR_BOTH(alg);
916 if(doTest)
917 result = TestEcc(TPM_ALG_ECDH, toTest);
918 else
919 SET_BOTH(TPM_ALG_ECDH);
920 break;
921 case TPM_ALG_ECDSA:
922 case TPM_ALG_ECDH:
923 case TPM_ALG_ECSCHNORR:
924 // case TPM_ALG_SM2:
925 if(doTest)
926 result = TestEcc(alg, toTest);
927 break;
928 #endif // ALG_ECC
929 default:
930 CLEAR_BIT(alg, *toTest);
931 break;
932 }
933 if(result != TPM_RC_SUCCESS)
934 break;
935 }
936 return result;
937 }
938
939 #endif // SELF_TESTS