1// 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#ifndef _CRYPT_PRI_H
9#define _CRYPT_PRI_H
10#include     <stddef.h>
11#include     "TpmBuildSwitches.h"
12#include     "BaseTypes.h"
13#include     "TpmError.h"
14#include     "swap.h"
15#include     "Implementation.h"
16#include     "TPM_Types.h"
17//#include     "TPMB.h"
18#include     "bool.h"
19#include     "Platform.h"
20#ifndef NULL
21#define NULL     0
22#endif
23typedef UINT16 NUMBYTES;          // When a size is a number of bytes
24typedef UINT32 NUMDIGITS;         // When a size is a number of "digits"
25//        General Purpose Macros
26//
27#ifndef MAX
28#   define MAX(a, b) ((a) > (b) ? (a) : b)
29#endif
30//
31//     This is the definition of a bit array with one bit per algorithm
32//
33typedef BYTE         ALGORITHM_VECTOR[(ALG_LAST_VALUE + 7) / 8];
34//
35//
36//        Self-test
37//
38//     This structure is used to contain self-test tracking information for the crypto engine. Each of the major
39//     modules is given a 32-bit value in which it may maintain its own self test information. The convention for
40//     this state is that when all of the bits in this structure are 0, all functions need to be tested.
41//
42typedef struct {
43   UINT32       rng;
44   UINT32       hash;
45   UINT32       sym;
46#ifdef TPM_ALG_RSA
47   UINT32       rsa;
48#endif
49#ifdef TPM_ALG_ECC
50   UINT32       ecc;
51#endif
52} CRYPTO_SELF_TEST_STATE;
53//
54//
55//        Hash-related Structures
56//
57typedef struct {
58   const TPM_ALG_ID              alg;
59   const NUMBYTES                digestSize;
60   const NUMBYTES                blockSize;
61   const NUMBYTES                derSize;
62   const BYTE                    der[20];
63} HASH_INFO;
64//
65//     This value will change with each implementation. The value of 16 is used to account for any slop in the
66//     context values. The overall size needs to be as large as any of the hash contexts. The structure needs to
67//     start on an alignment boundary and be an even multiple of the alignment
68//
69#define ALIGNED_SIZE(x, b) ((((x) + (b) - 1) / (b)) * (b))
70#define MAX_HASH_STATE_SIZE ((2 * MAX_HASH_BLOCK_SIZE) + 16)
71#if defined USER_MIN_HASH_STATE_SIZE && \
72  (MAX_HASH_STATE_SIZE < (USER_MIN_HASH_STATE_SIZE))
73#define REQUIRED_HASH_STATE_SIZE USER_MIN_HASH_STATE_SIZE
74#else
75#define REQUIRED_HASH_STATE_SIZE MAX_HASH_STATE_SIZE
76#endif
77#define MAX_HASH_STATE_SIZE_ALIGNED                                                              \
78                   ALIGNED_SIZE(REQUIRED_HASH_STATE_SIZE, CRYPTO_ALIGNMENT)
79//
80//     This is an byte array that will hold any of the hash contexts.
81//
82typedef CRYPTO_ALIGNED BYTE ALIGNED_HASH_STATE[MAX_HASH_STATE_SIZE_ALIGNED];
83//
84//     Macro to align an address to the next higher size
85//
86#define AlignPointer(address, align)                                                             \
87  ((((intptr_t)&(address)) + (align - 1)) & ~(align - 1))
88//
89//     Macro to test alignment
90//
91#define IsAddressAligned(address, align)                                                         \
92                   (((intptr_t)(address) & (align - 1)) == 0)
93//
94//     This is the structure that is used for passing a context into the hashing functions. It should be the same
95//     size as the function context used within the hashing functions. This is checked when the hash function is
96//     initialized. This version uses a new layout for the contexts and a different definition. The state buffer is an
97//     array of HASH_UNIT values so that a decent compiler will put the structure on a HASH_UNIT boundary.
98//     If the structure is not properly aligned, the code that manipulates the structure will copy to a properly
99//     aligned structure before it is used and copy the result back. This just makes things slower.
100//
101typedef struct _HASH_STATE
102{
103   ALIGNED_HASH_STATE       state;
104   TPM_ALG_ID               hashAlg;
105} CPRI_HASH_STATE, *PCPRI_HASH_STATE;
106extern const HASH_INFO   g_hashData[HASH_COUNT + 1];
107//
108//     This is for the external hash state. This implementation assumes that the size of the exported hash state
109//     is no larger than the internal hash state. There is a compile-time check to make sure that this is true.
110//
111typedef struct {
112   ALIGNED_HASH_STATE             buffer;
113   TPM_ALG_ID                     hashAlg;
114} EXPORT_HASH_STATE;
115typedef enum {
116   IMPORT_STATE,             // Converts externally formatted state to internal
117   EXPORT_STATE              // Converts internal formatted state to external
118} IMPORT_EXPORT;
119//
120//     Values and structures for the random number generator. These values are defined in this header file so
121//     that the size of the RNG state can be known to TPM.lib. This allows the allocation of some space in NV
122//     memory for the state to be stored on an orderly shutdown. The GET_PUT enum is used by
123//     _cpri__DrbgGetPutState() to indicate the direction of data flow.
124//
125typedef enum {
126   GET_STATE,           // Get the state to save to NV
127   PUT_STATE            // Restore the state from NV
128} GET_PUT;
129//
130//     The DRBG based on a symmetric block cipher is defined by three values,
131//     a) the key size
132//     b) the block size (the IV size)
133//     c) the symmetric algorithm
134//
135#define DRBG_KEY_SIZE_BITS       MAX_AES_KEY_BITS
136#define DRBG_IV_SIZE_BITS        (MAX_AES_BLOCK_SIZE_BYTES * 8)
137#define DRBG_ALGORITHM           TPM_ALG_AES
138#if ((DRBG_KEY_SIZE_BITS % 8) != 0) || ((DRBG_IV_SIZE_BITS % 8) != 0)
139#error "Key size and IV for DRBG must be even multiples of 8"
140#endif
141#if (DRBG_KEY_SIZE_BITS % DRBG_IV_SIZE_BITS) != 0
142#error "Key size for DRBG must be even multiple of the cypher block size"
143#endif
144typedef UINT32     DRBG_SEED[(DRBG_KEY_SIZE_BITS + DRBG_IV_SIZE_BITS) / 32];
145typedef struct {
146   UINT64       reseedCounter;
147   UINT32       magic;
148   DRBG_SEED    seed; // contains the key and IV for the counter mode DRBG
149   UINT32       lastValue[4];   // used when the TPM does continuous self-test
150                                // for FIPS compliance of DRBG
151} DRBG_STATE, *pDRBG_STATE;
152//
153//
154//           Asymmetric Structures and Values
155//
156#ifdef TPM_ALG_ECC
157//
158//
159//          ECC-related Structures
160//
161//      This structure replicates the structure definition in TPM_Types.h. It is duplicated to avoid inclusion of all of
162//      TPM_Types.h This structure is similar to the RSA_KEY structure below. The purpose of these structures
163//      is to reduce the overhead of a function call and to make the code less dependent on key types as much
164//      as possible.
165//
166typedef struct {
167   UINT32                        curveID;            // The curve identifier
168   TPMS_ECC_POINT               *publicPoint;        // Pointer to the public point
169   TPM2B_ECC_PARAMETER          *privateKey;         // Pointer to the private key
170} ECC_KEY;
171#endif // TPM_ALG_ECC
172#ifdef TPM_ALG_RSA
173//
174//
175//          RSA-related Structures
176//
177//      This structure is a succinct representation of the cryptographic components of an RSA key.
178//
179typedef struct {
180   UINT32        exponent;                 // The public exponent pointer
181   TPM2B        *publicKey;                // Pointer to the public modulus
182   TPM2B        *privateKey;               // The private exponent (not a prime)
183} RSA_KEY;
184#endif // TPM_ALG_RSA
185//
186//
187//           Miscelaneous
188//
189#ifdef TPM_ALG_RSA
190#   ifdef TPM_ALG_ECC
191#       if    MAX_RSA_KEY_BYTES > MAX_ECC_KEY_BYTES
192#            define MAX_NUMBER_SIZE          MAX_RSA_KEY_BYTES
193#       else
194#            define MAX_NUMBER_SIZE          MAX_ECC_KEY_BYTES
195#       endif
196#   else // RSA but no ECC
197#       define MAX_NUMBER_SIZE               MAX_RSA_KEY_BYTES
198#   endif
199#elif defined TPM_ALG_ECC
200#   define MAX_NUMBER_SIZE                  MAX_ECC_KEY_BYTES
201#else
202#   error No assymmetric algorithm implemented.
203#endif
204typedef INT16      CRYPT_RESULT;
205#define CRYPT_RESULT_MIN     INT16_MIN
206#define CRYPT_RESULT_MAX     INT16_MAX
207//
208//
209//      <0                                recoverable error
210//
211//      0                                 success
212//      >0                                command specific return value (generally a digest size)
213//
214#define CRYPT_FAIL                  ((CRYPT_RESULT) 1)
215#define CRYPT_SUCCESS               ((CRYPT_RESULT) 0)
216#define CRYPT_NO_RESULT             ((CRYPT_RESULT) -1)
217//
218#define CRYPT_SCHEME        ((CRYPT_RESULT) -2)
219#define CRYPT_PARAMETER     ((CRYPT_RESULT) -3)
220#define CRYPT_UNDERFLOW     ((CRYPT_RESULT) -4)
221#define CRYPT_POINT         ((CRYPT_RESULT) -5)
222#define CRYPT_CANCEL        ((CRYPT_RESULT) -6)
223#include    "CpriCryptPri_fp.h"
224#ifdef TPM_ALG_ECC
225#   include "CpriDataEcc.h"
226#   include "CpriECC_fp.h"
227#endif
228#include    "MathFunctions_fp.h"
229#include    "CpriRNG_fp.h"
230#include    "CpriHash_fp.h"
231#include    "CpriSym_fp.h"
232#ifdef TPM_ALG_RSA
233#   include    "CpriRSA_fp.h"
234#endif
235#endif // !_CRYPT_PRI_H
236