This library provides support for NationZ I2C and SPI TPM 2.0 devices so they can be used as a hardware crypto library for the ARM processor. The TPM not only may be used for crypto offload, but also for isolated key storage, strong device identity and device attestation. The TPM 2.0 library specification @ www.TrustedComputingGroup.org provides all necessary documentation to interact with the TPM. This particular library offers only support for the NationZ devices, that employ a vendor specific CRB interface and does not offer support for the TCG defined TIS interface.

Committer:
LordOfDorks
Date:
Thu Mar 19 22:24:40 2015 +0000
Revision:
2:7ef8655b8dca
Parent:
1:be4b399d5099
Fixed TPM_ST_* storage sizes.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
LordOfDorks 1:be4b399d5099 1 /* mbed NationZ I2C/SPI TPM 2.0 Library,
LordOfDorks 0:7cd000305b05 2 * Copyright (c) 2015, Microsoft Coprporation Inc.
LordOfDorks 0:7cd000305b05 3 * by Stefan Thom (LordOfDorks) StefanTh@Microsoft.com, Stefan@ThomsR.Us
LordOfDorks 0:7cd000305b05 4 *
LordOfDorks 0:7cd000305b05 5 * Permission is hereby granted, free of charge, to any person obtaining a copy
LordOfDorks 0:7cd000305b05 6 * of this software and associated documentation files (the "Software"), to deal
LordOfDorks 0:7cd000305b05 7 * in the Software without restriction, including without limitation the rights
LordOfDorks 0:7cd000305b05 8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
LordOfDorks 0:7cd000305b05 9 * copies of the Software, and to permit persons to whom the Software is
LordOfDorks 0:7cd000305b05 10 * furnished to do so, subject to the following conditions:
LordOfDorks 0:7cd000305b05 11 *
LordOfDorks 0:7cd000305b05 12 * The above copyright notice and this permission notice shall be included in
LordOfDorks 0:7cd000305b05 13 * all copies or substantial portions of the Software.
LordOfDorks 0:7cd000305b05 14 *
LordOfDorks 0:7cd000305b05 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
LordOfDorks 0:7cd000305b05 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
LordOfDorks 0:7cd000305b05 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
LordOfDorks 0:7cd000305b05 18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LordOfDorks 0:7cd000305b05 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
LordOfDorks 0:7cd000305b05 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
LordOfDorks 0:7cd000305b05 21 * THE SOFTWARE.
LordOfDorks 0:7cd000305b05 22 *
LordOfDorks 0:7cd000305b05 23 *
LordOfDorks 0:7cd000305b05 24 * This code was developped and tested with a STMicro Nucleo-L152RE board with
LordOfDorks 0:7cd000305b05 25 * the NationZ (http://www.nationz.com.cn/en) I2C and SPI parts as TSSOP28
LordOfDorks 0:7cd000305b05 26 * connected in the following manner:
LordOfDorks 0:7cd000305b05 27 *
LordOfDorks 0:7cd000305b05 28 * -------------
LordOfDorks 0:7cd000305b05 29 * NC + 1 28 + NC
LordOfDorks 0:7cd000305b05 30 * NC + 2 N 27 + NC
LordOfDorks 0:7cd000305b05 31 * NC + 3 a 26 + NC
LordOfDorks 0:7cd000305b05 32 * GND + 4 t 25 + GND
LordOfDorks 0:7cd000305b05 33 * SCL/D15<-+ 3V + 5 i 24 + 3V
LordOfDorks 0:7cd000305b05 34 * 3V<-2K2<-+-SCL + 6 o 23 + NC
LordOfDorks 0:7cd000305b05 35 * NC<-PP + 7 n 22 + NC
LordOfDorks 0:7cd000305b05 36 * NC + 8 Z 21 + NC
LordOfDorks 0:7cd000305b05 37 * NC + 9 20 + NC
LordOfDorks 0:7cd000305b05 38 * 3V + 10 I 19 + 3V
LordOfDorks 0:7cd000305b05 39 * GND + 11 2 18 + GND
LordOfDorks 0:7cd000305b05 40 * NC + 12 C 17 + NC
LordOfDorks 0:7cd000305b05 41 * NC + 13 16 + #RST->3V
LordOfDorks 0:7cd000305b05 42 * NC + 14 15 + SDA-+->2k2->3V
LordOfDorks 0:7cd000305b05 43 * ------------- +->SDA/D14
LordOfDorks 0:7cd000305b05 44 *
LordOfDorks 0:7cd000305b05 45 * TestCode for I2C:
LordOfDorks 0:7cd000305b05 46 *
LordOfDorks 0:7cd000305b05 47 * NTZTPM20 tpm(I2C_SDA, I2C_SCL);
LordOfDorks 0:7cd000305b05 48 * uint8_t randBuf[32] = {0};
LordOfDorks 0:7cd000305b05 49 * uint32_t result = 0;
LordOfDorks 0:7cd000305b05 50 *
LordOfDorks 0:7cd000305b05 51 * result = tpm.TPM2_Startup(NTZTPM20::TPM_SU_CLEAR);
LordOfDorks 0:7cd000305b05 52 * printf("TPM2_Startup = 0x%08x\n\r", result);
LordOfDorks 0:7cd000305b05 53 * result =tpm.TPM2_SelfTest(0x01);
LordOfDorks 0:7cd000305b05 54 * printf("TPM2_SelfTest = 0x%08x\n\r", result);
LordOfDorks 0:7cd000305b05 55 * result =tpm.TPM2_GetRandom(sizeof(randBuf), randBuf);
LordOfDorks 0:7cd000305b05 56 * printf("TPM2_GetRandom = 0x%08x\n\r", result);
LordOfDorks 0:7cd000305b05 57 * result =tpm.TPM2_StirRandom(sizeof(randBuf), randBuf);
LordOfDorks 0:7cd000305b05 58 * printf("TPM2_StirRandom = 0x%08x\n\r", result);
LordOfDorks 0:7cd000305b05 59 * result =tpm.TPM2_Shutdown(NTZTPM20::TPM_SU_CLEAR);
LordOfDorks 0:7cd000305b05 60 * printf("TPM2_Shutdown = 0x%08x\n\r", result);
LordOfDorks 0:7cd000305b05 61 *
LordOfDorks 0:7cd000305b05 62 * -------------
LordOfDorks 0:7cd000305b05 63 * NC + 1 28 + NC
LordOfDorks 0:7cd000305b05 64 * NC + 2 N 27 + NC
LordOfDorks 0:7cd000305b05 65 * MOSI/D11<-MOSI + 3 a 26 + NC
LordOfDorks 0:7cd000305b05 66 * GND + 4 t 25 + GND
LordOfDorks 0:7cd000305b05 67 * 3V + 5 i 24 + 3V
LordOfDorks 0:7cd000305b05 68 * NC + 6 o 23 + NC
LordOfDorks 0:7cd000305b05 69 * NC<-PP + 7 n 22 + SPI_CS->CS/D10
LordOfDorks 0:7cd000305b05 70 * NC + 8 Z 21 + SPI_CLK->SCK/D13
LordOfDorks 0:7cd000305b05 71 * MISO/D12<-MISO + 9 20 + NC
LordOfDorks 0:7cd000305b05 72 * 3V + 10 S 19 + 3V
LordOfDorks 0:7cd000305b05 73 * GND + 11 P 18 + GND
LordOfDorks 0:7cd000305b05 74 * NC + 12 I 17 + NC
LordOfDorks 0:7cd000305b05 75 * NC + 13 16 + #RST->3V
LordOfDorks 0:7cd000305b05 76 * NC + 14 15 + NC
LordOfDorks 0:7cd000305b05 77 * -------------
LordOfDorks 0:7cd000305b05 78 *
LordOfDorks 0:7cd000305b05 79 * TestCode for SPI:
LordOfDorks 0:7cd000305b05 80 *
LordOfDorks 0:7cd000305b05 81 * NTZTPM20 tpm(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS);
LordOfDorks 0:7cd000305b05 82 * uint8_t randBuf[32] = {0};
LordOfDorks 0:7cd000305b05 83 * uint32_t result = 0;
LordOfDorks 0:7cd000305b05 84 *
LordOfDorks 0:7cd000305b05 85 * result = tpm.TPM2_Startup(NTZTPM20::TPM_SU_CLEAR);
LordOfDorks 0:7cd000305b05 86 * printf("TPM2_Startup = 0x%08x\n\r", result);
LordOfDorks 0:7cd000305b05 87 * result =tpm.TPM2_SelfTest(0x01);
LordOfDorks 0:7cd000305b05 88 * printf("TPM2_SelfTest = 0x%08x\n\r", result);
LordOfDorks 0:7cd000305b05 89 * result =tpm.TPM2_GetRandom(sizeof(randBuf), randBuf);
LordOfDorks 0:7cd000305b05 90 * printf("TPM2_GetRandom = 0x%08x\n\r", result);
LordOfDorks 0:7cd000305b05 91 * result =tpm.TPM2_StirRandom(sizeof(randBuf), randBuf);
LordOfDorks 0:7cd000305b05 92 * printf("TPM2_StirRandom = 0x%08x\n\r", result);
LordOfDorks 0:7cd000305b05 93 * result =tpm.TPM2_Shutdown(NTZTPM20::TPM_SU_CLEAR);
LordOfDorks 0:7cd000305b05 94 * printf("TPM2_Shutdown = 0x%08x\n\r", result);
LordOfDorks 0:7cd000305b05 95 *
LordOfDorks 0:7cd000305b05 96 * All TPM 2.0 commands and structures are defined in the TCG TPM 2.0 Library
LordOfDorks 0:7cd000305b05 97 * specification that can be found at:
LordOfDorks 0:7cd000305b05 98 * http://www.trustedcomputinggroup.org/resources/tpm_library_specification
LordOfDorks 0:7cd000305b05 99 * The NationZ TPM does provice a simple and easy to use vendor specific CBR
LordOfDorks 0:7cd000305b05 100 * interface and not the TCG defined TIS interface. It supports all major
LordOfDorks 0:7cd000305b05 101 * Algorithms (RSA, ECC, AES, SHA-HMAC) as well as the family of SMx algotithms.
LordOfDorks 0:7cd000305b05 102 *
LordOfDorks 0:7cd000305b05 103 */
LordOfDorks 0:7cd000305b05 104
LordOfDorks 0:7cd000305b05 105 #include "mbed.h"
LordOfDorks 0:7cd000305b05 106
LordOfDorks 0:7cd000305b05 107 //#define TPM_NTZ_DEBUG_OUTPUT 1
LordOfDorks 0:7cd000305b05 108
LordOfDorks 0:7cd000305b05 109 #ifndef min
LordOfDorks 0:7cd000305b05 110 #define min(a,b) (((a) < (b)) ? (a) : (b))
LordOfDorks 0:7cd000305b05 111 #endif
LordOfDorks 0:7cd000305b05 112
LordOfDorks 0:7cd000305b05 113 #define UINT16_TO_BYTEARRAY(__dataIn, __array, __offset)\
LordOfDorks 0:7cd000305b05 114 __array[__offset] = (uint8_t)((__dataIn >> 8) & 0x00ff);\
LordOfDorks 0:7cd000305b05 115 __array[__offset + 1] = (uint8_t)(__dataIn & 0x00ff);\
LordOfDorks 0:7cd000305b05 116
LordOfDorks 0:7cd000305b05 117 #define UINT32_TO_BYTEARRAY(__dataIn, __array, __offset)\
LordOfDorks 0:7cd000305b05 118 __array[__offset + 0] = (uint8_t)((__dataIn >> 24) & 0x000000ff);\
LordOfDorks 0:7cd000305b05 119 __array[__offset + 1] = (uint8_t)((__dataIn >> 16) & 0x000000ff);\
LordOfDorks 0:7cd000305b05 120 __array[__offset + 2] = (uint8_t)((__dataIn >> 8) & 0x000000ff);\
LordOfDorks 0:7cd000305b05 121 __array[__offset + 3] = (uint8_t)(__dataIn & 0x000000ff);\
LordOfDorks 0:7cd000305b05 122
LordOfDorks 0:7cd000305b05 123 #define BYTEARRAY_TO_UINT16(__arrayIn, __offset)\
LordOfDorks 0:7cd000305b05 124 ((((uint16_t)(__arrayIn[__offset])) << 8) | \
LordOfDorks 0:7cd000305b05 125 (uint16_t)(__arrayIn[__offset + 1])) \
LordOfDorks 0:7cd000305b05 126
LordOfDorks 0:7cd000305b05 127 #define BYTEARRAY_TO_UINT32(__arrayIn, __offset)\
LordOfDorks 0:7cd000305b05 128 ((((uint32_t)(__arrayIn[__offset])) << 24) | \
LordOfDorks 0:7cd000305b05 129 (((uint32_t)(__arrayIn[__offset + 1])) << 16) | \
LordOfDorks 0:7cd000305b05 130 (((uint32_t)(__arrayIn[__offset + 2])) << 8) | \
LordOfDorks 0:7cd000305b05 131 (uint32_t)(__arrayIn[__offset + 3])) \
LordOfDorks 0:7cd000305b05 132
LordOfDorks 0:7cd000305b05 133 class NTZTPM20
LordOfDorks 0:7cd000305b05 134 {
LordOfDorks 0:7cd000305b05 135 public:
LordOfDorks 0:7cd000305b05 136 // Subset of defined TCG constants
LordOfDorks 0:7cd000305b05 137 const static uint32_t TPM_RC_SUCCESS = 0x00000000;
LordOfDorks 0:7cd000305b05 138 const static uint32_t TPM_RC_FAILURE = 0x00000101;
LordOfDorks 2:7ef8655b8dca 139 const static uint16_t TPM_ST_NO_SESSIONS = 0x8001;
LordOfDorks 2:7ef8655b8dca 140 const static uint16_t TPM_ST_SESSIONS = 0x8002;
LordOfDorks 0:7cd000305b05 141 const static uint32_t TPM_CC_GetRandom = 0x0000017B;
LordOfDorks 0:7cd000305b05 142 const static uint32_t TPM_CC_StirRandom = 0x00000146;
LordOfDorks 0:7cd000305b05 143 const static uint16_t TPM_SU_CLEAR = 0x0000;
LordOfDorks 0:7cd000305b05 144 const static uint16_t TPM_SU_STATE = 0x0001;
LordOfDorks 0:7cd000305b05 145
LordOfDorks 0:7cd000305b05 146 // Constructor for the I2C variant of the chip
LordOfDorks 0:7cd000305b05 147 NTZTPM20(PinName sda, PinName scl);
LordOfDorks 0:7cd000305b05 148
LordOfDorks 0:7cd000305b05 149 // Constructor for the SPI variant of the chip
LordOfDorks 0:7cd000305b05 150 NTZTPM20(PinName mosi, PinName miso, PinName clk, PinName cs);
LordOfDorks 0:7cd000305b05 151
LordOfDorks 0:7cd000305b05 152 // Release all held resources
LordOfDorks 0:7cd000305b05 153 ~NTZTPM20();
LordOfDorks 0:7cd000305b05 154
LordOfDorks 0:7cd000305b05 155 // Execute command on the TPM
LordOfDorks 0:7cd000305b05 156 uint32_t Execute(uint8_t* pbCmd, uint32_t cbCmd, uint8_t* pbRsp, uint32_t cbRsp, uint32_t timeout);
LordOfDorks 0:7cd000305b05 157
LordOfDorks 0:7cd000305b05 158 // Perform TPM startup
LordOfDorks 0:7cd000305b05 159 uint32_t TPM2_Startup(uint16_t startupType);
LordOfDorks 0:7cd000305b05 160
LordOfDorks 0:7cd000305b05 161 // Perform TPM shutdown
LordOfDorks 0:7cd000305b05 162 uint32_t TPM2_Shutdown(uint16_t shutdownType);
LordOfDorks 0:7cd000305b05 163
LordOfDorks 0:7cd000305b05 164 // Perform TPM selftest
LordOfDorks 0:7cd000305b05 165 uint32_t TPM2_SelfTest(uint8_t fullTest);
LordOfDorks 0:7cd000305b05 166
LordOfDorks 0:7cd000305b05 167 // Get random number
LordOfDorks 0:7cd000305b05 168 uint32_t TPM2_GetRandom(uint16_t bytesRequested, uint8_t* randomBytes);
LordOfDorks 0:7cd000305b05 169
LordOfDorks 0:7cd000305b05 170 // Stir random number generator
LordOfDorks 0:7cd000305b05 171 uint32_t TPM2_StirRandom(uint16_t inDataLen, uint8_t* inData);
LordOfDorks 0:7cd000305b05 172
LordOfDorks 0:7cd000305b05 173 private:
LordOfDorks 0:7cd000305b05 174 // NationZ I2C device address on the bus
LordOfDorks 0:7cd000305b05 175 const static uint8_t m_I2CDevice_Address = (0x58 << 1);
LordOfDorks 0:7cd000305b05 176
LordOfDorks 0:7cd000305b05 177 // Timeout flag
LordOfDorks 0:7cd000305b05 178 volatile bool m_TimeoutTriggered;
LordOfDorks 0:7cd000305b05 179
LordOfDorks 0:7cd000305b05 180 // Poor mans execution synchronization
LordOfDorks 0:7cd000305b05 181 bool m_ExclusiveAccess;
LordOfDorks 0:7cd000305b05 182
LordOfDorks 0:7cd000305b05 183 // Device hook-up
LordOfDorks 0:7cd000305b05 184 I2C* m_I2CTpmDev;
LordOfDorks 0:7cd000305b05 185 SPI* m_SPITpmDev;
LordOfDorks 0:7cd000305b05 186 DigitalOut* m_SPICSTpmDev;
LordOfDorks 0:7cd000305b05 187
LordOfDorks 0:7cd000305b05 188 uint32_t ParseResponseHeader(uint8_t* pbRsp, uint32_t rspLen, uint16_t* rspTag, uint32_t* rspSize, uint32_t* cursor);
LordOfDorks 0:7cd000305b05 189 void TimeoutTrigger(void);
LordOfDorks 0:7cd000305b05 190 uint32_t ExecuteI2C(uint8_t* pbCmd, uint32_t cbCmd, uint8_t* pbRsp, uint32_t cbRsp);
LordOfDorks 0:7cd000305b05 191 uint32_t ExecuteSPI(uint8_t* pbCmd, uint32_t cbCmd, uint8_t* pbRsp, uint32_t cbRsp);
LordOfDorks 2:7ef8655b8dca 192 };