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.
NationZ_TPM20.h@2:7ef8655b8dca, 2015-03-19 (annotated)
- 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?
User | Revision | Line number | New 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 | }; |