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 #include "NationZ_TPM20.h"
LordOfDorks 0:7cd000305b05 25
LordOfDorks 0:7cd000305b05 26 // Constructor for the I2C variant of the chip
LordOfDorks 0:7cd000305b05 27 NTZTPM20::NTZTPM20(
LordOfDorks 0:7cd000305b05 28 PinName sda,
LordOfDorks 0:7cd000305b05 29 PinName scl
LordOfDorks 0:7cd000305b05 30 )
LordOfDorks 0:7cd000305b05 31 {
LordOfDorks 0:7cd000305b05 32 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 33 printf("NTZI2C.Init: ");
LordOfDorks 0:7cd000305b05 34 #endif
LordOfDorks 0:7cd000305b05 35 m_SPITpmDev = NULL;
LordOfDorks 0:7cd000305b05 36 m_SPICSTpmDev = NULL;
LordOfDorks 0:7cd000305b05 37 m_I2CTpmDev = new I2C(sda, scl);
LordOfDorks 0:7cd000305b05 38 m_I2CTpmDev->frequency(400000);
LordOfDorks 0:7cd000305b05 39 m_ExclusiveAccess = false;
LordOfDorks 0:7cd000305b05 40 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 41 printf("OK.\n\r");
LordOfDorks 0:7cd000305b05 42 #endif
LordOfDorks 0:7cd000305b05 43 }
LordOfDorks 0:7cd000305b05 44
LordOfDorks 0:7cd000305b05 45 // Constructor for the SPI variant of the chip
LordOfDorks 0:7cd000305b05 46 NTZTPM20::NTZTPM20(
LordOfDorks 0:7cd000305b05 47 PinName mosi,
LordOfDorks 0:7cd000305b05 48 PinName miso,
LordOfDorks 0:7cd000305b05 49 PinName clk,
LordOfDorks 0:7cd000305b05 50 PinName cs
LordOfDorks 0:7cd000305b05 51 )
LordOfDorks 0:7cd000305b05 52 {
LordOfDorks 0:7cd000305b05 53 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 54 printf("NTZSPI.Init: ");
LordOfDorks 0:7cd000305b05 55 #endif
LordOfDorks 0:7cd000305b05 56 m_I2CTpmDev = NULL;
LordOfDorks 0:7cd000305b05 57 m_SPITpmDev = new SPI(mosi, miso, clk);
LordOfDorks 0:7cd000305b05 58 m_SPITpmDev->format(8, 0);
LordOfDorks 0:7cd000305b05 59 m_SPITpmDev->frequency(5000000);
LordOfDorks 0:7cd000305b05 60 m_SPICSTpmDev = new DigitalOut(cs);
LordOfDorks 0:7cd000305b05 61 *m_SPICSTpmDev = 1;
LordOfDorks 0:7cd000305b05 62 m_ExclusiveAccess = false;
LordOfDorks 0:7cd000305b05 63 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 64 printf("OK.\n\r");
LordOfDorks 0:7cd000305b05 65 #endif
LordOfDorks 0:7cd000305b05 66 }
LordOfDorks 0:7cd000305b05 67
LordOfDorks 0:7cd000305b05 68 // Release all held resources
LordOfDorks 0:7cd000305b05 69 NTZTPM20::~NTZTPM20()
LordOfDorks 0:7cd000305b05 70 {
LordOfDorks 0:7cd000305b05 71 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 72 printf("NTZ.Destroy: ");
LordOfDorks 0:7cd000305b05 73 #endif
LordOfDorks 0:7cd000305b05 74 if(m_I2CTpmDev != NULL)
LordOfDorks 0:7cd000305b05 75 {
LordOfDorks 0:7cd000305b05 76 delete m_I2CTpmDev;
LordOfDorks 0:7cd000305b05 77 m_I2CTpmDev = NULL;
LordOfDorks 0:7cd000305b05 78 }
LordOfDorks 0:7cd000305b05 79 if(m_SPITpmDev != NULL)
LordOfDorks 0:7cd000305b05 80 {
LordOfDorks 0:7cd000305b05 81 delete m_SPITpmDev;
LordOfDorks 0:7cd000305b05 82 m_SPITpmDev = NULL;
LordOfDorks 0:7cd000305b05 83 }
LordOfDorks 0:7cd000305b05 84 if(m_SPICSTpmDev != NULL)
LordOfDorks 0:7cd000305b05 85 {
LordOfDorks 0:7cd000305b05 86 delete m_SPICSTpmDev;
LordOfDorks 0:7cd000305b05 87 m_SPICSTpmDev = NULL;
LordOfDorks 0:7cd000305b05 88 }
LordOfDorks 0:7cd000305b05 89 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 90 printf("OK.\n\r");
LordOfDorks 0:7cd000305b05 91 #endif
LordOfDorks 0:7cd000305b05 92 }
LordOfDorks 0:7cd000305b05 93
LordOfDorks 0:7cd000305b05 94 uint32_t
LordOfDorks 0:7cd000305b05 95 NTZTPM20::Execute(
LordOfDorks 0:7cd000305b05 96 uint8_t* pbCmd,
LordOfDorks 0:7cd000305b05 97 uint32_t cbCmd,
LordOfDorks 0:7cd000305b05 98 uint8_t* pbRsp,
LordOfDorks 0:7cd000305b05 99 uint32_t cbRsp,
LordOfDorks 0:7cd000305b05 100 uint32_t timeout
LordOfDorks 0:7cd000305b05 101 )
LordOfDorks 0:7cd000305b05 102 {
LordOfDorks 0:7cd000305b05 103 uint32_t result = 0;
LordOfDorks 0:7cd000305b05 104 Timeout watchdog;
LordOfDorks 0:7cd000305b05 105
LordOfDorks 0:7cd000305b05 106 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 107 printf("NTZ.ExecuteWaitForAccess.");
LordOfDorks 0:7cd000305b05 108 #endif
LordOfDorks 0:7cd000305b05 109
LordOfDorks 0:7cd000305b05 110 // Only one caller should be talking to the TPM at any given time
LordOfDorks 0:7cd000305b05 111 while(m_ExclusiveAccess)
LordOfDorks 0:7cd000305b05 112 {
LordOfDorks 0:7cd000305b05 113 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 114 printf(".");
LordOfDorks 0:7cd000305b05 115 #endif
LordOfDorks 0:7cd000305b05 116 wait_us(500);
LordOfDorks 0:7cd000305b05 117 }
LordOfDorks 0:7cd000305b05 118 m_ExclusiveAccess = true;
LordOfDorks 0:7cd000305b05 119 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 120 printf("OK\n\r");
LordOfDorks 0:7cd000305b05 121 #endif
LordOfDorks 0:7cd000305b05 122
LordOfDorks 0:7cd000305b05 123 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 124 printf("NTZ.SetupTimeout\n\r");
LordOfDorks 0:7cd000305b05 125 #endif
LordOfDorks 0:7cd000305b05 126 // Setup TPM timeout
LordOfDorks 0:7cd000305b05 127 m_TimeoutTriggered = false;
LordOfDorks 0:7cd000305b05 128 watchdog.attach(this, &NTZTPM20::TimeoutTrigger, 0.0001 * timeout);
LordOfDorks 0:7cd000305b05 129
LordOfDorks 0:7cd000305b05 130 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 131 printf("NTZ.Execute: ");
LordOfDorks 0:7cd000305b05 132 for(uint32_t n = 0; n < cbCmd; n++) printf("%02x ", pbCmd[n]);
LordOfDorks 0:7cd000305b05 133 printf("\n\r");
LordOfDorks 0:7cd000305b05 134 #endif
LordOfDorks 0:7cd000305b05 135
LordOfDorks 0:7cd000305b05 136 // Execute command on the TPM
LordOfDorks 0:7cd000305b05 137 if(m_I2CTpmDev != NULL)
LordOfDorks 0:7cd000305b05 138 {
LordOfDorks 0:7cd000305b05 139 result = ExecuteI2C(pbCmd, cbCmd, pbRsp, cbRsp);
LordOfDorks 0:7cd000305b05 140 }
LordOfDorks 0:7cd000305b05 141 else if(m_SPITpmDev != NULL)
LordOfDorks 0:7cd000305b05 142 {
LordOfDorks 0:7cd000305b05 143 result = ExecuteSPI(pbCmd, cbCmd, pbRsp, cbRsp);
LordOfDorks 0:7cd000305b05 144 }
LordOfDorks 0:7cd000305b05 145
LordOfDorks 0:7cd000305b05 146 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 147 printf("NTZ.Response: ");
LordOfDorks 0:7cd000305b05 148 for(uint32_t n = 0; n < result; n++) printf("%02x ", pbRsp[n]);
LordOfDorks 0:7cd000305b05 149 printf("\n\r");
LordOfDorks 0:7cd000305b05 150 #endif
LordOfDorks 0:7cd000305b05 151
LordOfDorks 0:7cd000305b05 152 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 153 printf("NTZ.CancelTimeout\n\r");
LordOfDorks 0:7cd000305b05 154 #endif
LordOfDorks 0:7cd000305b05 155 // Cleanup
LordOfDorks 0:7cd000305b05 156 watchdog.detach();
LordOfDorks 0:7cd000305b05 157 m_ExclusiveAccess = false;
LordOfDorks 0:7cd000305b05 158 return result;
LordOfDorks 0:7cd000305b05 159 }
LordOfDorks 0:7cd000305b05 160
LordOfDorks 0:7cd000305b05 161 uint32_t
LordOfDorks 0:7cd000305b05 162 NTZTPM20::ParseResponseHeader(
LordOfDorks 0:7cd000305b05 163 uint8_t* pbRsp,
LordOfDorks 0:7cd000305b05 164 uint32_t rspLen,
LordOfDorks 0:7cd000305b05 165 uint16_t* rspTag,
LordOfDorks 0:7cd000305b05 166 uint32_t* rspSize,
LordOfDorks 0:7cd000305b05 167 uint32_t* cursor
LordOfDorks 0:7cd000305b05 168 )
LordOfDorks 0:7cd000305b05 169 {
LordOfDorks 0:7cd000305b05 170 uint32_t rspResponseCode = 0;
LordOfDorks 0:7cd000305b05 171
LordOfDorks 0:7cd000305b05 172 // Check that the response header is well formatted
LordOfDorks 0:7cd000305b05 173 if(rspLen < (sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t)))
LordOfDorks 0:7cd000305b05 174 {
LordOfDorks 0:7cd000305b05 175 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 176 printf("NTZ.ResponseHdr.rspLen = 0x%08x\n\r", rspLen);
LordOfDorks 0:7cd000305b05 177 #endif
LordOfDorks 0:7cd000305b05 178 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:7cd000305b05 179 goto Cleanup;
LordOfDorks 0:7cd000305b05 180 }
LordOfDorks 0:7cd000305b05 181
LordOfDorks 0:7cd000305b05 182 // Read the header components
LordOfDorks 0:7cd000305b05 183 *rspTag = BYTEARRAY_TO_UINT16(pbRsp, *cursor);
LordOfDorks 0:7cd000305b05 184 *cursor += sizeof(uint16_t);
LordOfDorks 0:7cd000305b05 185 *rspSize = BYTEARRAY_TO_UINT32(pbRsp, *cursor);
LordOfDorks 0:7cd000305b05 186 *cursor += sizeof(uint32_t);
LordOfDorks 0:7cd000305b05 187 rspResponseCode = BYTEARRAY_TO_UINT32(pbRsp, *cursor);
LordOfDorks 0:7cd000305b05 188 *cursor += sizeof(uint32_t);
LordOfDorks 0:7cd000305b05 189
LordOfDorks 0:7cd000305b05 190 // Check the components
LordOfDorks 0:7cd000305b05 191 if(((*rspTag != TPM_ST_NO_SESSIONS) && (*rspTag != TPM_ST_SESSIONS)) ||
LordOfDorks 0:7cd000305b05 192 (*rspSize != rspLen))
LordOfDorks 0:7cd000305b05 193 {
LordOfDorks 0:7cd000305b05 194 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 195 printf("NTZ.ResponseHdr.rspTag = 0x%04x.rspLen=0x%08x\n\r", *rspTag, rspLen);
LordOfDorks 0:7cd000305b05 196 #endif
LordOfDorks 0:7cd000305b05 197 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:7cd000305b05 198 goto Cleanup;
LordOfDorks 0:7cd000305b05 199 }
LordOfDorks 0:7cd000305b05 200
LordOfDorks 0:7cd000305b05 201 Cleanup:
LordOfDorks 0:7cd000305b05 202 return rspResponseCode;
LordOfDorks 0:7cd000305b05 203 }
LordOfDorks 0:7cd000305b05 204
LordOfDorks 0:7cd000305b05 205 uint32_t
LordOfDorks 0:7cd000305b05 206 NTZTPM20::TPM2_Startup(
LordOfDorks 0:7cd000305b05 207 uint16_t startupType
LordOfDorks 0:7cd000305b05 208 )
LordOfDorks 0:7cd000305b05 209 {
LordOfDorks 0:7cd000305b05 210 uint32_t rspLen = 0;
LordOfDorks 0:7cd000305b05 211 uint16_t rspTag = 0;
LordOfDorks 0:7cd000305b05 212 uint32_t rspSize = 0;
LordOfDorks 0:7cd000305b05 213 uint32_t rspResponseCode = 0;
LordOfDorks 0:7cd000305b05 214 uint32_t cursor = 0;
LordOfDorks 0:7cd000305b05 215 uint8_t tpmCmd[] = {0x80, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x44, 0x00, 0x00};
LordOfDorks 0:7cd000305b05 216 UINT16_TO_BYTEARRAY(startupType, tpmCmd, sizeof(tpmCmd) - 2);
LordOfDorks 0:7cd000305b05 217
LordOfDorks 0:7cd000305b05 218 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 219 printf("NTZ.TPM2_Startup(0x%04x)\n\r", startupType);
LordOfDorks 0:7cd000305b05 220 #endif
LordOfDorks 0:7cd000305b05 221
LordOfDorks 0:7cd000305b05 222 if((rspLen = Execute(tpmCmd, sizeof(tpmCmd), tpmCmd, sizeof(tpmCmd), 10000)) == 0)
LordOfDorks 0:7cd000305b05 223 {
LordOfDorks 0:7cd000305b05 224 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:7cd000305b05 225 goto Cleanup;
LordOfDorks 0:7cd000305b05 226 }
LordOfDorks 0:7cd000305b05 227 if((rspResponseCode = ParseResponseHeader(tpmCmd, rspLen, &rspTag, &rspSize, &cursor)) != TPM_RC_SUCCESS)
LordOfDorks 0:7cd000305b05 228 {
LordOfDorks 0:7cd000305b05 229 goto Cleanup;
LordOfDorks 0:7cd000305b05 230 }
LordOfDorks 0:7cd000305b05 231
LordOfDorks 0:7cd000305b05 232 if(rspSize != 0x0000000a)
LordOfDorks 0:7cd000305b05 233 {
LordOfDorks 0:7cd000305b05 234 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:7cd000305b05 235 }
LordOfDorks 0:7cd000305b05 236
LordOfDorks 0:7cd000305b05 237 Cleanup:
LordOfDorks 0:7cd000305b05 238 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 239 printf("NTZ.TPM2_Startup.ResponseCode = 0x%08x\n\r", rspResponseCode);
LordOfDorks 0:7cd000305b05 240 #endif
LordOfDorks 0:7cd000305b05 241 return rspResponseCode;
LordOfDorks 0:7cd000305b05 242 }
LordOfDorks 0:7cd000305b05 243
LordOfDorks 0:7cd000305b05 244 uint32_t
LordOfDorks 0:7cd000305b05 245 NTZTPM20::TPM2_Shutdown(
LordOfDorks 0:7cd000305b05 246 uint16_t shutdownType
LordOfDorks 0:7cd000305b05 247 )
LordOfDorks 0:7cd000305b05 248 {
LordOfDorks 0:7cd000305b05 249 uint32_t rspLen = 0;
LordOfDorks 0:7cd000305b05 250 uint16_t rspTag = 0;
LordOfDorks 0:7cd000305b05 251 uint32_t rspSize = 0;
LordOfDorks 0:7cd000305b05 252 uint32_t rspResponseCode = 0;
LordOfDorks 0:7cd000305b05 253 uint32_t cursor = 0;
LordOfDorks 0:7cd000305b05 254 uint8_t tpmCmd[] = {0x80, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x45, 0x00, 0x00};
LordOfDorks 0:7cd000305b05 255 UINT16_TO_BYTEARRAY(shutdownType, tpmCmd, sizeof(tpmCmd) - 2);
LordOfDorks 0:7cd000305b05 256
LordOfDorks 0:7cd000305b05 257 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 258 printf("NTZ.TPM2_Shutdown(0x%04x)\n\r", shutdownType);
LordOfDorks 0:7cd000305b05 259 #endif
LordOfDorks 0:7cd000305b05 260
LordOfDorks 0:7cd000305b05 261 if((rspLen = Execute(tpmCmd, sizeof(tpmCmd), tpmCmd, sizeof(tpmCmd), 120000)) == 0)
LordOfDorks 0:7cd000305b05 262 {
LordOfDorks 0:7cd000305b05 263 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:7cd000305b05 264 goto Cleanup;
LordOfDorks 0:7cd000305b05 265 }
LordOfDorks 0:7cd000305b05 266 if((rspResponseCode = ParseResponseHeader(tpmCmd, rspLen, &rspTag, &rspSize, &cursor)) != TPM_RC_SUCCESS)
LordOfDorks 0:7cd000305b05 267 {
LordOfDorks 0:7cd000305b05 268 goto Cleanup;
LordOfDorks 0:7cd000305b05 269 }
LordOfDorks 0:7cd000305b05 270
LordOfDorks 0:7cd000305b05 271 if(rspSize != 0x0000000a)
LordOfDorks 0:7cd000305b05 272 {
LordOfDorks 0:7cd000305b05 273 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:7cd000305b05 274 }
LordOfDorks 0:7cd000305b05 275
LordOfDorks 0:7cd000305b05 276 Cleanup:
LordOfDorks 0:7cd000305b05 277 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 278 printf("NTZ.TPM2_Shutdown.ResponseCode = 0x%08x\n\r", rspResponseCode);
LordOfDorks 0:7cd000305b05 279 #endif
LordOfDorks 0:7cd000305b05 280 return rspResponseCode;
LordOfDorks 0:7cd000305b05 281 }
LordOfDorks 0:7cd000305b05 282
LordOfDorks 0:7cd000305b05 283 uint32_t
LordOfDorks 0:7cd000305b05 284 NTZTPM20::TPM2_SelfTest(
LordOfDorks 0:7cd000305b05 285 uint8_t fullTest
LordOfDorks 0:7cd000305b05 286 )
LordOfDorks 0:7cd000305b05 287 {
LordOfDorks 0:7cd000305b05 288 uint32_t rspLen = 0;
LordOfDorks 0:7cd000305b05 289 uint16_t rspTag = 0;
LordOfDorks 0:7cd000305b05 290 uint32_t rspSize = 0;
LordOfDorks 0:7cd000305b05 291 uint32_t rspResponseCode = 0;
LordOfDorks 0:7cd000305b05 292 uint32_t cursor = 0;
LordOfDorks 0:7cd000305b05 293 uint8_t tpmCmd[] = {0x80, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x43, 0x00};
LordOfDorks 0:7cd000305b05 294 tpmCmd[sizeof(tpmCmd) - 1] = fullTest;
LordOfDorks 0:7cd000305b05 295
LordOfDorks 0:7cd000305b05 296 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 297 printf("NTZ.TPM2_SelfTest(0x%02x)\n\r", fullTest);
LordOfDorks 0:7cd000305b05 298 #endif
LordOfDorks 0:7cd000305b05 299
LordOfDorks 0:7cd000305b05 300 if((rspLen = Execute(tpmCmd, sizeof(tpmCmd), tpmCmd, sizeof(tpmCmd), 5000)) == 0)
LordOfDorks 0:7cd000305b05 301 {
LordOfDorks 0:7cd000305b05 302 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:7cd000305b05 303 goto Cleanup;
LordOfDorks 0:7cd000305b05 304 }
LordOfDorks 0:7cd000305b05 305 if((rspResponseCode = ParseResponseHeader(tpmCmd, rspLen, &rspTag, &rspSize, &cursor)) != TPM_RC_SUCCESS)
LordOfDorks 0:7cd000305b05 306 {
LordOfDorks 0:7cd000305b05 307 goto Cleanup;
LordOfDorks 0:7cd000305b05 308 }
LordOfDorks 0:7cd000305b05 309
LordOfDorks 0:7cd000305b05 310 if(rspSize != 0x0000000a)
LordOfDorks 0:7cd000305b05 311 {
LordOfDorks 0:7cd000305b05 312 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:7cd000305b05 313 }
LordOfDorks 0:7cd000305b05 314
LordOfDorks 0:7cd000305b05 315 Cleanup:
LordOfDorks 0:7cd000305b05 316 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 317 printf("NTZ.TPM2_SelfTest.ResponseCode = 0x%08x\n\r", rspResponseCode);
LordOfDorks 0:7cd000305b05 318 #endif
LordOfDorks 0:7cd000305b05 319 return rspResponseCode;
LordOfDorks 0:7cd000305b05 320 }
LordOfDorks 0:7cd000305b05 321
LordOfDorks 0:7cd000305b05 322 uint32_t
LordOfDorks 0:7cd000305b05 323 NTZTPM20::TPM2_GetRandom(
LordOfDorks 0:7cd000305b05 324 uint16_t bytesRequested,
LordOfDorks 0:7cd000305b05 325 uint8_t* randomBytes
LordOfDorks 0:7cd000305b05 326 )
LordOfDorks 0:7cd000305b05 327 {
LordOfDorks 0:7cd000305b05 328 uint32_t cursor = 0;
LordOfDorks 0:7cd000305b05 329 uint32_t rspLen = 0;
LordOfDorks 0:7cd000305b05 330 uint16_t rspTag = 0;
LordOfDorks 0:7cd000305b05 331 uint32_t rspSize = 0;
LordOfDorks 0:7cd000305b05 332 uint32_t rspResponseCode = 0;
LordOfDorks 0:7cd000305b05 333 uint32_t tpmMax = sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint16_t) + bytesRequested;
LordOfDorks 0:7cd000305b05 334 uint8_t* tpmCmd = new uint8_t[tpmMax];
LordOfDorks 0:7cd000305b05 335 uint16_t bytesReturned = 0;
LordOfDorks 0:7cd000305b05 336
LordOfDorks 0:7cd000305b05 337 if(tpmCmd == NULL)
LordOfDorks 0:7cd000305b05 338 {
LordOfDorks 0:7cd000305b05 339 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:7cd000305b05 340 goto Cleanup;
LordOfDorks 0:7cd000305b05 341 }
LordOfDorks 0:7cd000305b05 342
LordOfDorks 0:7cd000305b05 343 // Build command
LordOfDorks 0:7cd000305b05 344 UINT16_TO_BYTEARRAY(TPM_ST_NO_SESSIONS, tpmCmd, cursor);
LordOfDorks 0:7cd000305b05 345 cursor += sizeof(uint16_t) + sizeof(cursor);
LordOfDorks 0:7cd000305b05 346 UINT32_TO_BYTEARRAY(TPM_CC_GetRandom, tpmCmd, cursor);
LordOfDorks 0:7cd000305b05 347 cursor += sizeof(TPM_CC_GetRandom);
LordOfDorks 0:7cd000305b05 348 UINT16_TO_BYTEARRAY(bytesRequested, tpmCmd, cursor);
LordOfDorks 0:7cd000305b05 349 cursor += sizeof(bytesRequested);
LordOfDorks 0:7cd000305b05 350 UINT32_TO_BYTEARRAY(cursor, tpmCmd, sizeof(uint16_t));
LordOfDorks 0:7cd000305b05 351
LordOfDorks 0:7cd000305b05 352 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 353 printf("NTZ.TPM2_GetRandom(%d)\n\r", bytesRequested);
LordOfDorks 0:7cd000305b05 354 #endif
LordOfDorks 0:7cd000305b05 355
LordOfDorks 0:7cd000305b05 356 if((rspLen = Execute(tpmCmd, cursor, tpmCmd, tpmMax, 5000)) == 0)
LordOfDorks 0:7cd000305b05 357 {
LordOfDorks 0:7cd000305b05 358 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:7cd000305b05 359 goto Cleanup;
LordOfDorks 0:7cd000305b05 360 }
LordOfDorks 0:7cd000305b05 361 cursor = 0;
LordOfDorks 0:7cd000305b05 362 if((rspResponseCode = ParseResponseHeader(tpmCmd, rspLen, &rspTag, &rspSize, &cursor)) != TPM_RC_SUCCESS)
LordOfDorks 0:7cd000305b05 363 {
LordOfDorks 0:7cd000305b05 364 goto Cleanup;
LordOfDorks 0:7cd000305b05 365 }
LordOfDorks 0:7cd000305b05 366
LordOfDorks 0:7cd000305b05 367 if(rspSize != tpmMax)
LordOfDorks 0:7cd000305b05 368 {
LordOfDorks 0:7cd000305b05 369 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:7cd000305b05 370 goto Cleanup;
LordOfDorks 0:7cd000305b05 371 }
LordOfDorks 0:7cd000305b05 372
LordOfDorks 0:7cd000305b05 373 // Copy the random bytes out
LordOfDorks 0:7cd000305b05 374 bytesReturned = BYTEARRAY_TO_UINT16(tpmCmd, cursor);
LordOfDorks 0:7cd000305b05 375 cursor += sizeof(uint16_t);
LordOfDorks 0:7cd000305b05 376 memcpy(randomBytes, &tpmCmd[cursor], (size_t)min(bytesReturned, bytesRequested));
LordOfDorks 0:7cd000305b05 377
LordOfDorks 0:7cd000305b05 378 Cleanup:
LordOfDorks 0:7cd000305b05 379 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 380 printf("NTZ.TPM2_GetRandom.ResponseCode = 0x%08x\n\r", rspResponseCode);
LordOfDorks 0:7cd000305b05 381 #endif
LordOfDorks 0:7cd000305b05 382 if(tpmCmd != NULL)
LordOfDorks 0:7cd000305b05 383 {
LordOfDorks 0:7cd000305b05 384 delete[] tpmCmd;
LordOfDorks 0:7cd000305b05 385 tpmCmd = NULL;
LordOfDorks 0:7cd000305b05 386 }
LordOfDorks 0:7cd000305b05 387 return rspResponseCode;
LordOfDorks 0:7cd000305b05 388 }
LordOfDorks 0:7cd000305b05 389
LordOfDorks 0:7cd000305b05 390 uint32_t
LordOfDorks 0:7cd000305b05 391 NTZTPM20::TPM2_StirRandom(
LordOfDorks 0:7cd000305b05 392 uint16_t inDataLen,
LordOfDorks 0:7cd000305b05 393 uint8_t* inData
LordOfDorks 0:7cd000305b05 394 )
LordOfDorks 0:7cd000305b05 395 {
LordOfDorks 0:7cd000305b05 396 uint32_t cursor = 0;
LordOfDorks 0:7cd000305b05 397 uint32_t rspLen = 0;
LordOfDorks 0:7cd000305b05 398 uint16_t rspTag = 0;
LordOfDorks 0:7cd000305b05 399 uint32_t rspSize = 0;
LordOfDorks 0:7cd000305b05 400 uint32_t rspResponseCode = 0;
LordOfDorks 0:7cd000305b05 401 uint32_t tpmMax = sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint16_t) + inDataLen;
LordOfDorks 0:7cd000305b05 402 uint8_t* tpmCmd = new uint8_t[tpmMax];
LordOfDorks 0:7cd000305b05 403
LordOfDorks 0:7cd000305b05 404 if(tpmCmd == NULL)
LordOfDorks 0:7cd000305b05 405 {
LordOfDorks 0:7cd000305b05 406 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:7cd000305b05 407 goto Cleanup;
LordOfDorks 0:7cd000305b05 408 }
LordOfDorks 0:7cd000305b05 409
LordOfDorks 0:7cd000305b05 410 // Build command
LordOfDorks 0:7cd000305b05 411 UINT16_TO_BYTEARRAY(TPM_ST_NO_SESSIONS, tpmCmd, cursor);
LordOfDorks 0:7cd000305b05 412 cursor += sizeof(uint16_t) + sizeof(cursor);
LordOfDorks 0:7cd000305b05 413 UINT32_TO_BYTEARRAY(TPM_CC_StirRandom, tpmCmd, cursor);
LordOfDorks 0:7cd000305b05 414 cursor += sizeof(TPM_CC_GetRandom);
LordOfDorks 0:7cd000305b05 415 UINT16_TO_BYTEARRAY(inDataLen, tpmCmd, cursor);
LordOfDorks 0:7cd000305b05 416 cursor += sizeof(inDataLen);
LordOfDorks 0:7cd000305b05 417 memcpy(&tpmCmd[cursor], inData, inDataLen);
LordOfDorks 0:7cd000305b05 418 cursor += inDataLen;
LordOfDorks 0:7cd000305b05 419 UINT32_TO_BYTEARRAY(cursor, tpmCmd, sizeof(uint16_t));
LordOfDorks 0:7cd000305b05 420
LordOfDorks 0:7cd000305b05 421 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 422 printf("NTZ.TPM2_StirRandom(%d)\n\r", inDataLen);
LordOfDorks 0:7cd000305b05 423 #endif
LordOfDorks 0:7cd000305b05 424
LordOfDorks 0:7cd000305b05 425 if((rspLen = Execute(tpmCmd, cursor, tpmCmd, tpmMax, 5000)) == 0)
LordOfDorks 0:7cd000305b05 426 {
LordOfDorks 0:7cd000305b05 427 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:7cd000305b05 428 goto Cleanup;
LordOfDorks 0:7cd000305b05 429 }
LordOfDorks 0:7cd000305b05 430 cursor = 0;
LordOfDorks 0:7cd000305b05 431 if((rspResponseCode = ParseResponseHeader(tpmCmd, rspLen, &rspTag, &rspSize, &cursor)) != TPM_RC_SUCCESS)
LordOfDorks 0:7cd000305b05 432 {
LordOfDorks 0:7cd000305b05 433 goto Cleanup;
LordOfDorks 0:7cd000305b05 434 }
LordOfDorks 0:7cd000305b05 435
LordOfDorks 0:7cd000305b05 436 if(rspSize != 0x0000000a)
LordOfDorks 0:7cd000305b05 437 {
LordOfDorks 0:7cd000305b05 438 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:7cd000305b05 439 goto Cleanup;
LordOfDorks 0:7cd000305b05 440 }
LordOfDorks 0:7cd000305b05 441
LordOfDorks 0:7cd000305b05 442 Cleanup:
LordOfDorks 0:7cd000305b05 443 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 444 printf("NTZ.TPM2_StirRandom.ResponseCode = 0x%08x\n\r", rspResponseCode);
LordOfDorks 0:7cd000305b05 445 #endif
LordOfDorks 0:7cd000305b05 446 if(tpmCmd != NULL)
LordOfDorks 0:7cd000305b05 447 {
LordOfDorks 0:7cd000305b05 448 delete[] tpmCmd;
LordOfDorks 0:7cd000305b05 449 tpmCmd = NULL;
LordOfDorks 0:7cd000305b05 450 }
LordOfDorks 0:7cd000305b05 451 return rspResponseCode;
LordOfDorks 0:7cd000305b05 452 }
LordOfDorks 0:7cd000305b05 453
LordOfDorks 0:7cd000305b05 454 void
LordOfDorks 0:7cd000305b05 455 NTZTPM20::TimeoutTrigger(
LordOfDorks 0:7cd000305b05 456 void
LordOfDorks 0:7cd000305b05 457 )
LordOfDorks 0:7cd000305b05 458 {
LordOfDorks 0:7cd000305b05 459 m_TimeoutTriggered = true;
LordOfDorks 0:7cd000305b05 460 }
LordOfDorks 0:7cd000305b05 461
LordOfDorks 0:7cd000305b05 462 uint32_t
LordOfDorks 0:7cd000305b05 463 NTZTPM20::ExecuteI2C(
LordOfDorks 0:7cd000305b05 464 uint8_t* pbCmd,
LordOfDorks 0:7cd000305b05 465 uint32_t cbCmd,
LordOfDorks 0:7cd000305b05 466 uint8_t* pbRsp,
LordOfDorks 0:7cd000305b05 467 uint32_t cbRsp
LordOfDorks 0:7cd000305b05 468 )
LordOfDorks 0:7cd000305b05 469 {
LordOfDorks 0:7cd000305b05 470 uint32_t result = 0;
LordOfDorks 0:7cd000305b05 471 uint32_t waitPeriod = 0;
LordOfDorks 0:7cd000305b05 472 uint8_t retry = 0;
LordOfDorks 0:7cd000305b05 473 uint32_t index = 0;
LordOfDorks 0:7cd000305b05 474 uint32_t rspLen = 0;
LordOfDorks 0:7cd000305b05 475
LordOfDorks 0:7cd000305b05 476 // Send the command buffer. Since the TPM may be sleeping we have to retry until the command is accepted
LordOfDorks 0:7cd000305b05 477 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 478 printf("NTZI2C.DeviceWakeup.");
LordOfDorks 0:7cd000305b05 479 #endif
LordOfDorks 0:7cd000305b05 480 while((m_I2CTpmDev->write(m_I2CDevice_Address, (const char *)pbCmd, cbCmd, false) != 0) && (!m_TimeoutTriggered))
LordOfDorks 0:7cd000305b05 481 {
LordOfDorks 0:7cd000305b05 482 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 483 printf(".");
LordOfDorks 0:7cd000305b05 484 #endif
LordOfDorks 0:7cd000305b05 485 wait_us(100);
LordOfDorks 0:7cd000305b05 486 }
LordOfDorks 0:7cd000305b05 487
LordOfDorks 0:7cd000305b05 488 // See if device wakeup timed out
LordOfDorks 0:7cd000305b05 489 if(m_TimeoutTriggered)
LordOfDorks 0:7cd000305b05 490 {
LordOfDorks 0:7cd000305b05 491 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 492 printf("Timeout\n\r");
LordOfDorks 0:7cd000305b05 493 #endif
LordOfDorks 0:7cd000305b05 494 goto Cleanup;
LordOfDorks 0:7cd000305b05 495 }
LordOfDorks 0:7cd000305b05 496
LordOfDorks 0:7cd000305b05 497 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 498 printf("OK\n\rNTZI2C.SentBytes = %d\n\rNTZI2C.WaitForCompletion.", cbCmd);
LordOfDorks 0:7cd000305b05 499 #endif
LordOfDorks 0:7cd000305b05 500
LordOfDorks 0:7cd000305b05 501 // Wait for the TPM to have a response and then read the TPM response header consisting of TAG, SIZE and RETURNCODE
LordOfDorks 0:7cd000305b05 502 waitPeriod = 100;
LordOfDorks 0:7cd000305b05 503 while((m_I2CTpmDev->read(m_I2CDevice_Address, (char *)&pbRsp[index], (sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t)), false) != 0) && (!m_TimeoutTriggered))
LordOfDorks 0:7cd000305b05 504 {
LordOfDorks 0:7cd000305b05 505 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 506 printf(".");
LordOfDorks 0:7cd000305b05 507 #endif
LordOfDorks 0:7cd000305b05 508 wait_us(waitPeriod);
LordOfDorks 0:7cd000305b05 509
LordOfDorks 0:7cd000305b05 510 // Progressively wait longer to give the TPM some time to think
LordOfDorks 0:7cd000305b05 511 if(retry++ > 10)
LordOfDorks 0:7cd000305b05 512 {
LordOfDorks 0:7cd000305b05 513 waitPeriod *= 10;
LordOfDorks 0:7cd000305b05 514 retry = 0;
LordOfDorks 0:7cd000305b05 515 }
LordOfDorks 0:7cd000305b05 516 }
LordOfDorks 0:7cd000305b05 517
LordOfDorks 0:7cd000305b05 518 if(m_TimeoutTriggered)
LordOfDorks 0:7cd000305b05 519 {
LordOfDorks 0:7cd000305b05 520 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 521 printf("Timeout\n\r");
LordOfDorks 0:7cd000305b05 522 #endif
LordOfDorks 0:7cd000305b05 523 goto Cleanup;
LordOfDorks 0:7cd000305b05 524 }
LordOfDorks 0:7cd000305b05 525
LordOfDorks 0:7cd000305b05 526 // Move the write pointer
LordOfDorks 0:7cd000305b05 527 index += (sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t));
LordOfDorks 0:7cd000305b05 528
LordOfDorks 0:7cd000305b05 529 // Get the response size from the buffer and see how much we can read
LordOfDorks 0:7cd000305b05 530 rspLen = min(BYTEARRAY_TO_UINT32(pbRsp, sizeof(uint16_t)), cbRsp);
LordOfDorks 0:7cd000305b05 531
LordOfDorks 0:7cd000305b05 532 // Read the remaining data from the TPM
LordOfDorks 0:7cd000305b05 533 if((rspLen - index) > 0)
LordOfDorks 0:7cd000305b05 534 {
LordOfDorks 0:7cd000305b05 535 while((m_I2CTpmDev->read(m_I2CDevice_Address, (char *)&pbRsp[index], rspLen - index, false) != 0) && (!m_TimeoutTriggered))
LordOfDorks 0:7cd000305b05 536 {
LordOfDorks 0:7cd000305b05 537 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 538 printf(".");
LordOfDorks 0:7cd000305b05 539 #endif
LordOfDorks 0:7cd000305b05 540 wait_us(100);
LordOfDorks 0:7cd000305b05 541 }
LordOfDorks 0:7cd000305b05 542 if(m_TimeoutTriggered)
LordOfDorks 0:7cd000305b05 543 {
LordOfDorks 0:7cd000305b05 544 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 545 printf("Timeout\n\r");
LordOfDorks 0:7cd000305b05 546 #endif
LordOfDorks 0:7cd000305b05 547 goto Cleanup;
LordOfDorks 0:7cd000305b05 548 }
LordOfDorks 0:7cd000305b05 549 }
LordOfDorks 0:7cd000305b05 550
LordOfDorks 0:7cd000305b05 551 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 552 printf("OK\n\rNTZI2C.ReadBytes = %d\r\n", rspLen);
LordOfDorks 0:7cd000305b05 553 #endif
LordOfDorks 0:7cd000305b05 554
LordOfDorks 0:7cd000305b05 555 result = rspLen;
LordOfDorks 0:7cd000305b05 556
LordOfDorks 0:7cd000305b05 557 Cleanup:
LordOfDorks 0:7cd000305b05 558 return result;
LordOfDorks 0:7cd000305b05 559 }
LordOfDorks 0:7cd000305b05 560
LordOfDorks 0:7cd000305b05 561 uint32_t
LordOfDorks 0:7cd000305b05 562 NTZTPM20::ExecuteSPI(
LordOfDorks 0:7cd000305b05 563 uint8_t* pbCmd,
LordOfDorks 0:7cd000305b05 564 uint32_t cbCmd,
LordOfDorks 0:7cd000305b05 565 uint8_t* pbRsp,
LordOfDorks 0:7cd000305b05 566 uint32_t cbRsp
LordOfDorks 0:7cd000305b05 567 )
LordOfDorks 0:7cd000305b05 568 {
LordOfDorks 0:7cd000305b05 569 uint32_t result = 0;
LordOfDorks 0:7cd000305b05 570 uint32_t waitPeriod = 0;
LordOfDorks 0:7cd000305b05 571 uint8_t retry = 0;
LordOfDorks 0:7cd000305b05 572 uint8_t statusByte = 0;
LordOfDorks 0:7cd000305b05 573 uint32_t index = 0;
LordOfDorks 0:7cd000305b05 574
LordOfDorks 0:7cd000305b05 575 // Lock the SPI bus for this operation
LordOfDorks 0:7cd000305b05 576 *m_SPICSTpmDev = 0;
LordOfDorks 0:7cd000305b05 577
LordOfDorks 0:7cd000305b05 578 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 579 printf("NTZSPI.Wakeup.");
LordOfDorks 0:7cd000305b05 580 #endif
LordOfDorks 0:7cd000305b05 581
LordOfDorks 0:7cd000305b05 582 // Wake the TPM up
LordOfDorks 0:7cd000305b05 583 do
LordOfDorks 0:7cd000305b05 584 {
LordOfDorks 0:7cd000305b05 585 if((statusByte = m_SPITpmDev->write(0xAA)) != 0xAA)
LordOfDorks 0:7cd000305b05 586 {
LordOfDorks 0:7cd000305b05 587 wait_us(10);
LordOfDorks 0:7cd000305b05 588 }
LordOfDorks 0:7cd000305b05 589 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 590 printf(".");
LordOfDorks 0:7cd000305b05 591 #endif
LordOfDorks 0:7cd000305b05 592 } while((statusByte != 0xAA) && (!m_TimeoutTriggered));
LordOfDorks 0:7cd000305b05 593
LordOfDorks 0:7cd000305b05 594 // If the operation timed out bail
LordOfDorks 0:7cd000305b05 595 if((statusByte != 0xAA) && (m_TimeoutTriggered))
LordOfDorks 0:7cd000305b05 596 {
LordOfDorks 0:7cd000305b05 597 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 598 printf("Timeout\r\n");
LordOfDorks 0:7cd000305b05 599 #endif
LordOfDorks 0:7cd000305b05 600 goto Cleanup;
LordOfDorks 0:7cd000305b05 601 }
LordOfDorks 0:7cd000305b05 602
LordOfDorks 0:7cd000305b05 603 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 604 printf("OK\r\nNTZSPI.CommandReady\r\n");
LordOfDorks 0:7cd000305b05 605 #endif
LordOfDorks 0:7cd000305b05 606 // Signal commandReady to the TPM
LordOfDorks 0:7cd000305b05 607 m_SPITpmDev->write(0xA5);
LordOfDorks 0:7cd000305b05 608
LordOfDorks 0:7cd000305b05 609 // Send the command buffer
LordOfDorks 0:7cd000305b05 610 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 611 printf("NTZSPI.SendBytes = %d\r\n", cbCmd);
LordOfDorks 0:7cd000305b05 612 #endif
LordOfDorks 0:7cd000305b05 613 for(uint32_t n = 0; n < cbCmd; n ++)
LordOfDorks 0:7cd000305b05 614 {
LordOfDorks 0:7cd000305b05 615 m_SPITpmDev->write(pbCmd[n]);
LordOfDorks 0:7cd000305b05 616 }
LordOfDorks 0:7cd000305b05 617
LordOfDorks 0:7cd000305b05 618 // Release the bus while the TPM is thinking
LordOfDorks 0:7cd000305b05 619 *m_SPICSTpmDev = 1;
LordOfDorks 0:7cd000305b05 620
LordOfDorks 0:7cd000305b05 621 // Wait for a response
LordOfDorks 0:7cd000305b05 622 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 623 printf("NTZSPI.WaitForCompletion.");
LordOfDorks 0:7cd000305b05 624 #endif
LordOfDorks 0:7cd000305b05 625 waitPeriod = 100;
LordOfDorks 0:7cd000305b05 626 do
LordOfDorks 0:7cd000305b05 627 {
LordOfDorks 0:7cd000305b05 628 wait_us(waitPeriod);
LordOfDorks 0:7cd000305b05 629
LordOfDorks 0:7cd000305b05 630 // Progressively wait longer to give the TPM some time to think
LordOfDorks 0:7cd000305b05 631 if(retry++ > 10)
LordOfDorks 0:7cd000305b05 632 {
LordOfDorks 0:7cd000305b05 633 waitPeriod *= 10;
LordOfDorks 0:7cd000305b05 634 retry = 0;
LordOfDorks 0:7cd000305b05 635 }
LordOfDorks 0:7cd000305b05 636 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 637 printf(".");
LordOfDorks 0:7cd000305b05 638 #endif
LordOfDorks 0:7cd000305b05 639
LordOfDorks 0:7cd000305b05 640 // Lock the bus for this operation
LordOfDorks 0:7cd000305b05 641 *m_SPICSTpmDev = 0;
LordOfDorks 0:7cd000305b05 642
LordOfDorks 0:7cd000305b05 643 // Poke the TPM so see if it is ready
LordOfDorks 0:7cd000305b05 644 if((pbRsp[index] = m_SPITpmDev->write(0xAA)) != 0xAA)
LordOfDorks 0:7cd000305b05 645 {
LordOfDorks 0:7cd000305b05 646 index++;
LordOfDorks 0:7cd000305b05 647
LordOfDorks 0:7cd000305b05 648 // Read the TPM response header
LordOfDorks 0:7cd000305b05 649 for(; index < (sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t)); index++)
LordOfDorks 0:7cd000305b05 650 {
LordOfDorks 0:7cd000305b05 651 pbRsp[index] = m_SPITpmDev->write(0xFF);
LordOfDorks 0:7cd000305b05 652 }
LordOfDorks 0:7cd000305b05 653
LordOfDorks 0:7cd000305b05 654 uint32_t rspLen = BYTEARRAY_TO_UINT32(pbRsp, sizeof(uint16_t));
LordOfDorks 0:7cd000305b05 655 result = min(rspLen, cbRsp);
LordOfDorks 0:7cd000305b05 656
LordOfDorks 0:7cd000305b05 657 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 658 if(result < rspLen)
LordOfDorks 0:7cd000305b05 659 {
LordOfDorks 0:7cd000305b05 660 printf("NTZSPI.ResponseBufferTooShortBy = %d", rspLen - result);
LordOfDorks 0:7cd000305b05 661 }
LordOfDorks 0:7cd000305b05 662 #endif
LordOfDorks 0:7cd000305b05 663
LordOfDorks 0:7cd000305b05 664 // Read the remainder of the response if there is one
LordOfDorks 0:7cd000305b05 665 for(; index < result; index++)
LordOfDorks 0:7cd000305b05 666 {
LordOfDorks 0:7cd000305b05 667 pbRsp[index] = m_SPITpmDev->write(0xFF);
LordOfDorks 0:7cd000305b05 668 }
LordOfDorks 0:7cd000305b05 669 }
LordOfDorks 0:7cd000305b05 670
LordOfDorks 0:7cd000305b05 671 // release the bus
LordOfDorks 0:7cd000305b05 672 *m_SPICSTpmDev = 1;
LordOfDorks 0:7cd000305b05 673 }
LordOfDorks 0:7cd000305b05 674 while((pbRsp[0] == 0xAA) && (!m_TimeoutTriggered));
LordOfDorks 0:7cd000305b05 675
LordOfDorks 0:7cd000305b05 676 if((pbRsp[0] == 0xAA) && (m_TimeoutTriggered))
LordOfDorks 0:7cd000305b05 677 {
LordOfDorks 0:7cd000305b05 678 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 679 printf("Timeout\r\n");
LordOfDorks 0:7cd000305b05 680 #endif
LordOfDorks 0:7cd000305b05 681 goto Cleanup;
LordOfDorks 0:7cd000305b05 682 }
LordOfDorks 0:7cd000305b05 683
LordOfDorks 0:7cd000305b05 684 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 685 printf("OK\n\rNTZSPI.ReadBytes = %d\n\r", index);
LordOfDorks 0:7cd000305b05 686 #endif
LordOfDorks 0:7cd000305b05 687
LordOfDorks 0:7cd000305b05 688 Cleanup:
LordOfDorks 0:7cd000305b05 689 // Make sure to release the bus
LordOfDorks 0:7cd000305b05 690 *m_SPICSTpmDev = 1;
LordOfDorks 0:7cd000305b05 691
LordOfDorks 0:7cd000305b05 692 // Send the TPM back to sleep
LordOfDorks 0:7cd000305b05 693 #ifdef TPM_NTZ_DEBUG_OUTPUT
LordOfDorks 0:7cd000305b05 694 printf("NTZSPI.Sleep\r\n");
LordOfDorks 0:7cd000305b05 695 #endif
LordOfDorks 0:7cd000305b05 696 *m_SPICSTpmDev = 0;
LordOfDorks 0:7cd000305b05 697 m_SPITpmDev->write(0x5A);
LordOfDorks 0:7cd000305b05 698 *m_SPICSTpmDev = 1;
LordOfDorks 0:7cd000305b05 699 return result;
LordOfDorks 0:7cd000305b05 700 }
LordOfDorks 1:be4b399d5099 701