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 //
37 // This file contains the implementation of the symmetric block cipher modes
38 // allowed for a TPM. These functions only use the single block encryption functions
39 // of the selected symmetric cryptographic library.
40 
41 //** Includes, Defines, and Typedefs
42 #ifndef CRYPT_SYM_H
43 #define CRYPT_SYM_H
44 
45 #if ALG_AES
46 #   define IF_IMPLEMENTED_AES(op)    op(AES, aes)
47 #else
48 #   define IF_IMPLEMENTED_AES(op)
49 #endif
50 #if ALG_SM4
51 #   define IF_IMPLEMENTED_SM4(op)    op(SM4, sm4)
52 #else
53 #   define IF_IMPLEMENTED_SM4(op)
54 #endif
55 #if ALG_CAMELLIA
56 #   define IF_IMPLEMENTED_CAMELLIA(op)    op(CAMELLIA, camellia)
57 #else
58 #   define IF_IMPLEMENTED_CAMELLIA(op)
59 #endif
60 #if ALG_TDES
61 #   define IF_IMPLEMENTED_TDES(op)    op(TDES, tdes)
62 #else
63 #   define IF_IMPLEMENTED_TDES(op)
64 #endif
65 
66 #define FOR_EACH_SYM(op)        \
67     IF_IMPLEMENTED_AES(op)      \
68     IF_IMPLEMENTED_SM4(op)      \
69     IF_IMPLEMENTED_CAMELLIA(op) \
70     IF_IMPLEMENTED_TDES(op)
71 
72 // Macros for creating the key schedule union
73 #define     KEY_SCHEDULE(SYM, sym)      tpmKeySchedule##SYM sym;
74 #define     TDES    DES[3]
75 typedef union tpmCryptKeySchedule_t {
76     FOR_EACH_SYM(KEY_SCHEDULE)
77 
78 #if SYMMETRIC_ALIGNMENT == 8
79     uint64_t            alignment;
80 #else
81     uint32_t            alignment;
82 #endif
83 } tpmCryptKeySchedule_t;
84 
85 
86 // Each block cipher within a library is expected to conform to the same calling
87 // conventions with three parameters ('keySchedule', 'in', and 'out') in the same
88 // order. That means that all algorithms would use the same order of the same
89 // parameters. The code is written assuming the ('keySchedule', 'in', and 'out')
90 // order. However, if the library uses a different order, the order can be changed
91 // with a SWIZZLE macro that puts the parameters in the correct order.
92 // Note that all algorithms have to use the same order and number of parameters
93 // because the code to build the calling list is common for each call to encrypt
94 // or decrypt with the algorithm chosen by setting a function pointer to select
95 // the algorithm that is used.
96 
97 #   define ENCRYPT(keySchedule, in, out)                                            \
98       encrypt(SWIZZLE(keySchedule, in, out))
99 
100 #   define DECRYPT(keySchedule, in, out)                                            \
101       decrypt(SWIZZLE(keySchedule, in, out))
102 
103 // Note that the macros rely on 'encrypt' as local values in the
104 // functions that use these macros. Those parameters are set by the macro that
105 // set the key schedule to be used for the call.
106 
107 #define ENCRYPT_CASE(ALG, alg)                                                      \
108     case TPM_ALG_##ALG:                                                             \
109         TpmCryptSetEncryptKey##ALG(key, keySizeInBits, &keySchedule.alg);           \
110         encrypt = (TpmCryptSetSymKeyCall_t)TpmCryptEncrypt##ALG;                    \
111         break;
112 #define DECRYPT_CASE(ALG, alg)                                                      \
113     case TPM_ALG_##ALG:                                                             \
114         TpmCryptSetDecryptKey##ALG(key, keySizeInBits, &keySchedule.alg);           \
115         decrypt = (TpmCryptSetSymKeyCall_t)TpmCryptDecrypt##ALG;                    \
116         break;
117 
118 #endif // CRYPT_SYM_H