• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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