Stefan Thom / SPITIS_TPM20
Committer:
LordOfDorks
Date:
Mon Mar 23 19:03:50 2015 +0000
Revision:
0:b11c8971edd9
Child:
1:fd0a59e55a85
First release verified with STMicro TPM 2.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
LordOfDorks 0:b11c8971edd9 1 /* mbed TCG TIS 1.3 SPI TPM 2.0 Library,
LordOfDorks 0:b11c8971edd9 2 * Copyright (c) 2015, Microsoft Coprporation Inc.
LordOfDorks 0:b11c8971edd9 3 * by Stefan Thom (LordOfDorks) StefanTh@Microsoft.com, Stefan@ThomsR.Us
LordOfDorks 0:b11c8971edd9 4 *
LordOfDorks 0:b11c8971edd9 5 * Permission is hereby granted, free of charge, to any person obtaining a copy
LordOfDorks 0:b11c8971edd9 6 * of this software and associated documentation files (the "Software"), to deal
LordOfDorks 0:b11c8971edd9 7 * in the Software without restriction, including without limitation the rights
LordOfDorks 0:b11c8971edd9 8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
LordOfDorks 0:b11c8971edd9 9 * copies of the Software, and to permit persons to whom the Software is
LordOfDorks 0:b11c8971edd9 10 * furnished to do so, subject to the following conditions:
LordOfDorks 0:b11c8971edd9 11 *
LordOfDorks 0:b11c8971edd9 12 * The above copyright notice and this permission notice shall be included in
LordOfDorks 0:b11c8971edd9 13 * all copies or substantial portions of the Software.
LordOfDorks 0:b11c8971edd9 14 *
LordOfDorks 0:b11c8971edd9 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
LordOfDorks 0:b11c8971edd9 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
LordOfDorks 0:b11c8971edd9 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
LordOfDorks 0:b11c8971edd9 18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LordOfDorks 0:b11c8971edd9 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
LordOfDorks 0:b11c8971edd9 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
LordOfDorks 0:b11c8971edd9 21 * THE SOFTWARE.
LordOfDorks 0:b11c8971edd9 22 */
LordOfDorks 0:b11c8971edd9 23
LordOfDorks 0:b11c8971edd9 24 #include "SPITIS_TPM20.h"
LordOfDorks 0:b11c8971edd9 25
LordOfDorks 0:b11c8971edd9 26 TISTPM20::TISTPM20(
LordOfDorks 0:b11c8971edd9 27 PinName mosi,
LordOfDorks 0:b11c8971edd9 28 PinName miso,
LordOfDorks 0:b11c8971edd9 29 PinName clk,
LordOfDorks 0:b11c8971edd9 30 PinName cs
LordOfDorks 0:b11c8971edd9 31 )
LordOfDorks 0:b11c8971edd9 32 {
LordOfDorks 0:b11c8971edd9 33 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 34 printf("TIS.Init: ");
LordOfDorks 0:b11c8971edd9 35 #endif
LordOfDorks 0:b11c8971edd9 36 m_SPITpmDev = new SPI(mosi, miso, clk);
LordOfDorks 0:b11c8971edd9 37 m_SPITpmDev->format(8, 0);
LordOfDorks 0:b11c8971edd9 38 m_SPITpmDev->frequency(4000000);
LordOfDorks 0:b11c8971edd9 39 m_SPICSTpmDev = new DigitalOut(cs);
LordOfDorks 0:b11c8971edd9 40 *m_SPICSTpmDev = 1;
LordOfDorks 0:b11c8971edd9 41 m_ExclusiveAccess = false;
LordOfDorks 0:b11c8971edd9 42 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 43 printf("OK.\n\r");
LordOfDorks 0:b11c8971edd9 44 #endif
LordOfDorks 0:b11c8971edd9 45 }
LordOfDorks 0:b11c8971edd9 46
LordOfDorks 0:b11c8971edd9 47 // Release all held resources
LordOfDorks 0:b11c8971edd9 48 TISTPM20::~TISTPM20()
LordOfDorks 0:b11c8971edd9 49 {
LordOfDorks 0:b11c8971edd9 50 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 51 printf("TIS.Destroy: ");
LordOfDorks 0:b11c8971edd9 52 #endif
LordOfDorks 0:b11c8971edd9 53 if(m_SPITpmDev != NULL)
LordOfDorks 0:b11c8971edd9 54 {
LordOfDorks 0:b11c8971edd9 55 delete m_SPITpmDev;
LordOfDorks 0:b11c8971edd9 56 m_SPITpmDev = NULL;
LordOfDorks 0:b11c8971edd9 57 }
LordOfDorks 0:b11c8971edd9 58 if(m_SPICSTpmDev != NULL)
LordOfDorks 0:b11c8971edd9 59 {
LordOfDorks 0:b11c8971edd9 60 delete m_SPICSTpmDev;
LordOfDorks 0:b11c8971edd9 61 m_SPICSTpmDev = NULL;
LordOfDorks 0:b11c8971edd9 62 }
LordOfDorks 0:b11c8971edd9 63 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 64 printf("OK.\n\r");
LordOfDorks 0:b11c8971edd9 65 #endif
LordOfDorks 0:b11c8971edd9 66 }
LordOfDorks 0:b11c8971edd9 67
LordOfDorks 0:b11c8971edd9 68 uint32_t
LordOfDorks 0:b11c8971edd9 69 TISTPM20::Execute(
LordOfDorks 0:b11c8971edd9 70 uint8_t locality,
LordOfDorks 0:b11c8971edd9 71 uint8_t* pbCmd,
LordOfDorks 0:b11c8971edd9 72 uint32_t cbCmd,
LordOfDorks 0:b11c8971edd9 73 uint8_t* pbRsp,
LordOfDorks 0:b11c8971edd9 74 uint32_t cbRsp,
LordOfDorks 0:b11c8971edd9 75 uint32_t timeout
LordOfDorks 0:b11c8971edd9 76 )
LordOfDorks 0:b11c8971edd9 77 {
LordOfDorks 0:b11c8971edd9 78 uint32_t result = 0;
LordOfDorks 0:b11c8971edd9 79 Timeout watchdog;
LordOfDorks 0:b11c8971edd9 80
LordOfDorks 0:b11c8971edd9 81 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 82 printf("TIS.ExecuteWaitForAccess.");
LordOfDorks 0:b11c8971edd9 83 #endif
LordOfDorks 0:b11c8971edd9 84
LordOfDorks 0:b11c8971edd9 85 // Only one caller should be talking to the TPM at any given time
LordOfDorks 0:b11c8971edd9 86 while(m_ExclusiveAccess)
LordOfDorks 0:b11c8971edd9 87 {
LordOfDorks 0:b11c8971edd9 88 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 89 printf(".");
LordOfDorks 0:b11c8971edd9 90 #endif
LordOfDorks 0:b11c8971edd9 91 wait_us(500);
LordOfDorks 0:b11c8971edd9 92 }
LordOfDorks 0:b11c8971edd9 93 m_ExclusiveAccess = true;
LordOfDorks 0:b11c8971edd9 94 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 95 printf("OK\n\r");
LordOfDorks 0:b11c8971edd9 96 #endif
LordOfDorks 0:b11c8971edd9 97
LordOfDorks 0:b11c8971edd9 98 // Set the requested locality for the call
LordOfDorks 0:b11c8971edd9 99 m_Locality = locality;
LordOfDorks 0:b11c8971edd9 100 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 101 printf("TIS.Locality = %d\n\r", m_Locality);
LordOfDorks 0:b11c8971edd9 102 #endif
LordOfDorks 0:b11c8971edd9 103
LordOfDorks 0:b11c8971edd9 104 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 105 printf("TIS.SetupTimeout\n\r");
LordOfDorks 0:b11c8971edd9 106 #endif
LordOfDorks 0:b11c8971edd9 107 // Setup TPM timeout
LordOfDorks 0:b11c8971edd9 108 m_TimeoutTriggered = false;
LordOfDorks 0:b11c8971edd9 109 watchdog.attach(this, &TISTPM20::TimeoutTrigger, 0.0001 * timeout);
LordOfDorks 0:b11c8971edd9 110
LordOfDorks 0:b11c8971edd9 111 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 112 printf("TIS.Execute: ");
LordOfDorks 0:b11c8971edd9 113 for(uint32_t n = 0; n < cbCmd; n++) printf("%02x ", pbCmd[n]);
LordOfDorks 0:b11c8971edd9 114 printf("\n\r");
LordOfDorks 0:b11c8971edd9 115 #endif
LordOfDorks 0:b11c8971edd9 116
LordOfDorks 0:b11c8971edd9 117 // Execute command on the TPM
LordOfDorks 0:b11c8971edd9 118 if((result = ExecuteTIS(pbCmd, cbCmd, pbRsp, cbRsp)) == 0)
LordOfDorks 0:b11c8971edd9 119 {
LordOfDorks 0:b11c8971edd9 120 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 121 printf("TIS.Failed\n\r");
LordOfDorks 0:b11c8971edd9 122 #endif
LordOfDorks 0:b11c8971edd9 123 goto Cleanup;
LordOfDorks 0:b11c8971edd9 124 }
LordOfDorks 0:b11c8971edd9 125
LordOfDorks 0:b11c8971edd9 126 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 127 printf("TIS.Response: ");
LordOfDorks 0:b11c8971edd9 128 for(uint32_t n = 0; n < result; n++) printf("%02x ", pbRsp[n]);
LordOfDorks 0:b11c8971edd9 129 printf("\n\r");
LordOfDorks 0:b11c8971edd9 130 #endif
LordOfDorks 0:b11c8971edd9 131
LordOfDorks 0:b11c8971edd9 132 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 133 printf("TIS.CancelTimeout\n\r");
LordOfDorks 0:b11c8971edd9 134 #endif
LordOfDorks 0:b11c8971edd9 135
LordOfDorks 0:b11c8971edd9 136 Cleanup:
LordOfDorks 0:b11c8971edd9 137 watchdog.detach();
LordOfDorks 0:b11c8971edd9 138 m_ExclusiveAccess = false;
LordOfDorks 0:b11c8971edd9 139 return result;
LordOfDorks 0:b11c8971edd9 140 }
LordOfDorks 0:b11c8971edd9 141
LordOfDorks 0:b11c8971edd9 142 uint32_t
LordOfDorks 0:b11c8971edd9 143 TISTPM20::ParseResponseHeader(
LordOfDorks 0:b11c8971edd9 144 uint8_t* pbRsp,
LordOfDorks 0:b11c8971edd9 145 uint32_t rspLen,
LordOfDorks 0:b11c8971edd9 146 uint16_t* rspTag,
LordOfDorks 0:b11c8971edd9 147 uint32_t* rspSize,
LordOfDorks 0:b11c8971edd9 148 uint32_t* cursor
LordOfDorks 0:b11c8971edd9 149 )
LordOfDorks 0:b11c8971edd9 150 {
LordOfDorks 0:b11c8971edd9 151 uint32_t rspResponseCode = 0;
LordOfDorks 0:b11c8971edd9 152
LordOfDorks 0:b11c8971edd9 153 // Check that the response header is well formatted
LordOfDorks 0:b11c8971edd9 154 if(rspLen < (sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t)))
LordOfDorks 0:b11c8971edd9 155 {
LordOfDorks 0:b11c8971edd9 156 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 157 printf("TIS.ResponseHdr.rspLen = 0x%08x\n\r", rspLen);
LordOfDorks 0:b11c8971edd9 158 #endif
LordOfDorks 0:b11c8971edd9 159 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:b11c8971edd9 160 goto Cleanup;
LordOfDorks 0:b11c8971edd9 161 }
LordOfDorks 0:b11c8971edd9 162
LordOfDorks 0:b11c8971edd9 163 // Read the header components
LordOfDorks 0:b11c8971edd9 164 *rspTag = BYTEARRAY_TO_UINT16(pbRsp, *cursor);
LordOfDorks 0:b11c8971edd9 165 *cursor += sizeof(uint16_t);
LordOfDorks 0:b11c8971edd9 166 *rspSize = BYTEARRAY_TO_UINT32(pbRsp, *cursor);
LordOfDorks 0:b11c8971edd9 167 *cursor += sizeof(uint32_t);
LordOfDorks 0:b11c8971edd9 168 rspResponseCode = BYTEARRAY_TO_UINT32(pbRsp, *cursor);
LordOfDorks 0:b11c8971edd9 169 *cursor += sizeof(uint32_t);
LordOfDorks 0:b11c8971edd9 170
LordOfDorks 0:b11c8971edd9 171 // Check the components
LordOfDorks 0:b11c8971edd9 172 if(((*rspTag != TPM_ST_NO_SESSIONS) && (*rspTag != TPM_ST_SESSIONS)) ||
LordOfDorks 0:b11c8971edd9 173 (*rspSize != rspLen))
LordOfDorks 0:b11c8971edd9 174 {
LordOfDorks 0:b11c8971edd9 175 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 176 printf("TIS.ResponseHdr.rspTag = 0x%04x.rspLen=0x%08x\n\r", *rspTag, rspLen);
LordOfDorks 0:b11c8971edd9 177 #endif
LordOfDorks 0:b11c8971edd9 178 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:b11c8971edd9 179 goto Cleanup;
LordOfDorks 0:b11c8971edd9 180 }
LordOfDorks 0:b11c8971edd9 181
LordOfDorks 0:b11c8971edd9 182 Cleanup:
LordOfDorks 0:b11c8971edd9 183 return rspResponseCode;
LordOfDorks 0:b11c8971edd9 184 }
LordOfDorks 0:b11c8971edd9 185
LordOfDorks 0:b11c8971edd9 186 uint32_t
LordOfDorks 0:b11c8971edd9 187 TISTPM20::TPM2_Startup(
LordOfDorks 0:b11c8971edd9 188 uint8_t locality,
LordOfDorks 0:b11c8971edd9 189 uint16_t startupType
LordOfDorks 0:b11c8971edd9 190 )
LordOfDorks 0:b11c8971edd9 191 {
LordOfDorks 0:b11c8971edd9 192 uint32_t rspLen = 0;
LordOfDorks 0:b11c8971edd9 193 uint16_t rspTag = 0;
LordOfDorks 0:b11c8971edd9 194 uint32_t rspSize = 0;
LordOfDorks 0:b11c8971edd9 195 uint32_t rspResponseCode = 0;
LordOfDorks 0:b11c8971edd9 196 uint32_t cursor = 0;
LordOfDorks 0:b11c8971edd9 197 uint8_t tpmCmd[] = {0x80, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x44, 0x00, 0x00};
LordOfDorks 0:b11c8971edd9 198 #ifndef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 199 uint32_t timeout = 2000;
LordOfDorks 0:b11c8971edd9 200 #else
LordOfDorks 0:b11c8971edd9 201 uint32_t timeout = 20000;
LordOfDorks 0:b11c8971edd9 202 #endif
LordOfDorks 0:b11c8971edd9 203 UINT16_TO_BYTEARRAY(startupType, tpmCmd, sizeof(tpmCmd) - 2);
LordOfDorks 0:b11c8971edd9 204
LordOfDorks 0:b11c8971edd9 205 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 206 printf("TIS.TPM2_Startup(0x%04x)\n\r", startupType);
LordOfDorks 0:b11c8971edd9 207 #endif
LordOfDorks 0:b11c8971edd9 208
LordOfDorks 0:b11c8971edd9 209 if((rspLen = Execute(locality, tpmCmd, sizeof(tpmCmd), tpmCmd, sizeof(tpmCmd), timeout)) == 0)
LordOfDorks 0:b11c8971edd9 210 {
LordOfDorks 0:b11c8971edd9 211 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:b11c8971edd9 212 goto Cleanup;
LordOfDorks 0:b11c8971edd9 213 }
LordOfDorks 0:b11c8971edd9 214 if((rspResponseCode = ParseResponseHeader(tpmCmd, rspLen, &rspTag, &rspSize, &cursor)) != TPM_RC_SUCCESS)
LordOfDorks 0:b11c8971edd9 215 {
LordOfDorks 0:b11c8971edd9 216 goto Cleanup;
LordOfDorks 0:b11c8971edd9 217 }
LordOfDorks 0:b11c8971edd9 218
LordOfDorks 0:b11c8971edd9 219 if(rspSize != 0x0000000a)
LordOfDorks 0:b11c8971edd9 220 {
LordOfDorks 0:b11c8971edd9 221 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:b11c8971edd9 222 }
LordOfDorks 0:b11c8971edd9 223
LordOfDorks 0:b11c8971edd9 224 Cleanup:
LordOfDorks 0:b11c8971edd9 225 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 226 printf("TIS.TPM2_Startup.ResponseCode = 0x%08x\n\r", rspResponseCode);
LordOfDorks 0:b11c8971edd9 227 #endif
LordOfDorks 0:b11c8971edd9 228 return rspResponseCode;
LordOfDorks 0:b11c8971edd9 229 }
LordOfDorks 0:b11c8971edd9 230
LordOfDorks 0:b11c8971edd9 231 uint32_t
LordOfDorks 0:b11c8971edd9 232 TISTPM20::TPM2_Shutdown(
LordOfDorks 0:b11c8971edd9 233 uint8_t locality,
LordOfDorks 0:b11c8971edd9 234 uint16_t shutdownType
LordOfDorks 0:b11c8971edd9 235 )
LordOfDorks 0:b11c8971edd9 236 {
LordOfDorks 0:b11c8971edd9 237 uint32_t rspLen = 0;
LordOfDorks 0:b11c8971edd9 238 uint16_t rspTag = 0;
LordOfDorks 0:b11c8971edd9 239 uint32_t rspSize = 0;
LordOfDorks 0:b11c8971edd9 240 uint32_t rspResponseCode = 0;
LordOfDorks 0:b11c8971edd9 241 uint32_t cursor = 0;
LordOfDorks 0:b11c8971edd9 242 uint8_t tpmCmd[] = {0x80, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x45, 0x00, 0x00};
LordOfDorks 0:b11c8971edd9 243 #ifndef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 244 uint32_t timeout = 2000;
LordOfDorks 0:b11c8971edd9 245 #else
LordOfDorks 0:b11c8971edd9 246 uint32_t timeout = 20000;
LordOfDorks 0:b11c8971edd9 247 #endif
LordOfDorks 0:b11c8971edd9 248 UINT16_TO_BYTEARRAY(shutdownType, tpmCmd, sizeof(tpmCmd) - 2);
LordOfDorks 0:b11c8971edd9 249
LordOfDorks 0:b11c8971edd9 250 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 251 printf("TIS.TPM2_Shutdown(0x%04x)\n\r", shutdownType);
LordOfDorks 0:b11c8971edd9 252 #endif
LordOfDorks 0:b11c8971edd9 253
LordOfDorks 0:b11c8971edd9 254 if((rspLen = Execute(locality, tpmCmd, sizeof(tpmCmd), tpmCmd, sizeof(tpmCmd), timeout)) == 0)
LordOfDorks 0:b11c8971edd9 255 {
LordOfDorks 0:b11c8971edd9 256 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:b11c8971edd9 257 goto Cleanup;
LordOfDorks 0:b11c8971edd9 258 }
LordOfDorks 0:b11c8971edd9 259 if((rspResponseCode = ParseResponseHeader(tpmCmd, rspLen, &rspTag, &rspSize, &cursor)) != TPM_RC_SUCCESS)
LordOfDorks 0:b11c8971edd9 260 {
LordOfDorks 0:b11c8971edd9 261 goto Cleanup;
LordOfDorks 0:b11c8971edd9 262 }
LordOfDorks 0:b11c8971edd9 263
LordOfDorks 0:b11c8971edd9 264 if(rspSize != 0x0000000a)
LordOfDorks 0:b11c8971edd9 265 {
LordOfDorks 0:b11c8971edd9 266 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:b11c8971edd9 267 }
LordOfDorks 0:b11c8971edd9 268
LordOfDorks 0:b11c8971edd9 269 Cleanup:
LordOfDorks 0:b11c8971edd9 270 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 271 printf("TIS.TPM2_Shutdown.ResponseCode = 0x%08x\n\r", rspResponseCode);
LordOfDorks 0:b11c8971edd9 272 #endif
LordOfDorks 0:b11c8971edd9 273 return rspResponseCode;
LordOfDorks 0:b11c8971edd9 274 }
LordOfDorks 0:b11c8971edd9 275
LordOfDorks 0:b11c8971edd9 276 uint32_t
LordOfDorks 0:b11c8971edd9 277 TISTPM20::TPM2_SelfTest(
LordOfDorks 0:b11c8971edd9 278 uint8_t locality,
LordOfDorks 0:b11c8971edd9 279 uint8_t fullTest
LordOfDorks 0:b11c8971edd9 280 )
LordOfDorks 0:b11c8971edd9 281 {
LordOfDorks 0:b11c8971edd9 282 uint32_t rspLen = 0;
LordOfDorks 0:b11c8971edd9 283 uint16_t rspTag = 0;
LordOfDorks 0:b11c8971edd9 284 uint32_t rspSize = 0;
LordOfDorks 0:b11c8971edd9 285 uint32_t rspResponseCode = 0;
LordOfDorks 0:b11c8971edd9 286 uint32_t cursor = 0;
LordOfDorks 0:b11c8971edd9 287 uint8_t tpmCmd[] = {0x80, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x43, 0x00};
LordOfDorks 0:b11c8971edd9 288 #ifndef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 289 uint32_t timeout = 2000;
LordOfDorks 0:b11c8971edd9 290 #else
LordOfDorks 0:b11c8971edd9 291 uint32_t timeout = 20000;
LordOfDorks 0:b11c8971edd9 292 #endif
LordOfDorks 0:b11c8971edd9 293 tpmCmd[sizeof(tpmCmd) - 1] = fullTest;
LordOfDorks 0:b11c8971edd9 294
LordOfDorks 0:b11c8971edd9 295 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 296 printf("TIS.TPM2_SelfTest(0x%02x)\n\r", fullTest);
LordOfDorks 0:b11c8971edd9 297 #endif
LordOfDorks 0:b11c8971edd9 298
LordOfDorks 0:b11c8971edd9 299 if((rspLen = Execute(locality, tpmCmd, sizeof(tpmCmd), tpmCmd, sizeof(tpmCmd), timeout)) == 0)
LordOfDorks 0:b11c8971edd9 300 {
LordOfDorks 0:b11c8971edd9 301 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:b11c8971edd9 302 goto Cleanup;
LordOfDorks 0:b11c8971edd9 303 }
LordOfDorks 0:b11c8971edd9 304 if((rspResponseCode = ParseResponseHeader(tpmCmd, rspLen, &rspTag, &rspSize, &cursor)) != TPM_RC_SUCCESS)
LordOfDorks 0:b11c8971edd9 305 {
LordOfDorks 0:b11c8971edd9 306 goto Cleanup;
LordOfDorks 0:b11c8971edd9 307 }
LordOfDorks 0:b11c8971edd9 308
LordOfDorks 0:b11c8971edd9 309 if(rspSize != 0x0000000a)
LordOfDorks 0:b11c8971edd9 310 {
LordOfDorks 0:b11c8971edd9 311 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:b11c8971edd9 312 }
LordOfDorks 0:b11c8971edd9 313
LordOfDorks 0:b11c8971edd9 314 Cleanup:
LordOfDorks 0:b11c8971edd9 315 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 316 printf("TIS.TPM2_SelfTest.ResponseCode = 0x%08x\n\r", rspResponseCode);
LordOfDorks 0:b11c8971edd9 317 #endif
LordOfDorks 0:b11c8971edd9 318 return rspResponseCode;
LordOfDorks 0:b11c8971edd9 319 }
LordOfDorks 0:b11c8971edd9 320
LordOfDorks 0:b11c8971edd9 321 uint32_t
LordOfDorks 0:b11c8971edd9 322 TISTPM20::TPM2_GetRandom(
LordOfDorks 0:b11c8971edd9 323 uint8_t locality,
LordOfDorks 0:b11c8971edd9 324 uint16_t bytesRequested,
LordOfDorks 0:b11c8971edd9 325 uint8_t* randomBytes
LordOfDorks 0:b11c8971edd9 326 )
LordOfDorks 0:b11c8971edd9 327 {
LordOfDorks 0:b11c8971edd9 328 uint32_t cursor = 0;
LordOfDorks 0:b11c8971edd9 329 uint32_t rspLen = 0;
LordOfDorks 0:b11c8971edd9 330 uint16_t rspTag = 0;
LordOfDorks 0:b11c8971edd9 331 uint32_t rspSize = 0;
LordOfDorks 0:b11c8971edd9 332 uint32_t rspResponseCode = 0;
LordOfDorks 0:b11c8971edd9 333 uint32_t tpmMax = sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint16_t) + bytesRequested;
LordOfDorks 0:b11c8971edd9 334 uint8_t* tpmCmd = new uint8_t[tpmMax];
LordOfDorks 0:b11c8971edd9 335 uint16_t bytesReturned = 0;
LordOfDorks 0:b11c8971edd9 336 #ifndef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 337 uint32_t timeout = 2000;
LordOfDorks 0:b11c8971edd9 338 #else
LordOfDorks 0:b11c8971edd9 339 uint32_t timeout = 20000;
LordOfDorks 0:b11c8971edd9 340 #endif
LordOfDorks 0:b11c8971edd9 341
LordOfDorks 0:b11c8971edd9 342 if(tpmCmd == NULL)
LordOfDorks 0:b11c8971edd9 343 {
LordOfDorks 0:b11c8971edd9 344 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:b11c8971edd9 345 goto Cleanup;
LordOfDorks 0:b11c8971edd9 346 }
LordOfDorks 0:b11c8971edd9 347
LordOfDorks 0:b11c8971edd9 348 // Build command
LordOfDorks 0:b11c8971edd9 349 UINT16_TO_BYTEARRAY(TPM_ST_NO_SESSIONS, tpmCmd, cursor);
LordOfDorks 0:b11c8971edd9 350 cursor += sizeof(uint16_t) + sizeof(cursor);
LordOfDorks 0:b11c8971edd9 351 UINT32_TO_BYTEARRAY(TPM_CC_GetRandom, tpmCmd, cursor);
LordOfDorks 0:b11c8971edd9 352 cursor += sizeof(TPM_CC_GetRandom);
LordOfDorks 0:b11c8971edd9 353 UINT16_TO_BYTEARRAY(bytesRequested, tpmCmd, cursor);
LordOfDorks 0:b11c8971edd9 354 cursor += sizeof(bytesRequested);
LordOfDorks 0:b11c8971edd9 355 UINT32_TO_BYTEARRAY(cursor, tpmCmd, sizeof(uint16_t));
LordOfDorks 0:b11c8971edd9 356
LordOfDorks 0:b11c8971edd9 357 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 358 printf("TIS.TPM2_GetRandom(%d)\n\r", bytesRequested);
LordOfDorks 0:b11c8971edd9 359 #endif
LordOfDorks 0:b11c8971edd9 360
LordOfDorks 0:b11c8971edd9 361 if((rspLen = Execute(locality, tpmCmd, cursor, tpmCmd, tpmMax, timeout)) == 0)
LordOfDorks 0:b11c8971edd9 362 {
LordOfDorks 0:b11c8971edd9 363 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:b11c8971edd9 364 goto Cleanup;
LordOfDorks 0:b11c8971edd9 365 }
LordOfDorks 0:b11c8971edd9 366 cursor = 0;
LordOfDorks 0:b11c8971edd9 367 if((rspResponseCode = ParseResponseHeader(tpmCmd, rspLen, &rspTag, &rspSize, &cursor)) != TPM_RC_SUCCESS)
LordOfDorks 0:b11c8971edd9 368 {
LordOfDorks 0:b11c8971edd9 369 goto Cleanup;
LordOfDorks 0:b11c8971edd9 370 }
LordOfDorks 0:b11c8971edd9 371
LordOfDorks 0:b11c8971edd9 372 if(rspSize != tpmMax)
LordOfDorks 0:b11c8971edd9 373 {
LordOfDorks 0:b11c8971edd9 374 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:b11c8971edd9 375 goto Cleanup;
LordOfDorks 0:b11c8971edd9 376 }
LordOfDorks 0:b11c8971edd9 377
LordOfDorks 0:b11c8971edd9 378 // Copy the random bytes out
LordOfDorks 0:b11c8971edd9 379 bytesReturned = BYTEARRAY_TO_UINT16(tpmCmd, cursor);
LordOfDorks 0:b11c8971edd9 380 cursor += sizeof(uint16_t);
LordOfDorks 0:b11c8971edd9 381 memcpy(randomBytes, &tpmCmd[cursor], (size_t)min(bytesReturned, bytesRequested));
LordOfDorks 0:b11c8971edd9 382
LordOfDorks 0:b11c8971edd9 383 Cleanup:
LordOfDorks 0:b11c8971edd9 384 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 385 printf("TIS.TPM2_GetRandom.ResponseCode = 0x%08x\n\r", rspResponseCode);
LordOfDorks 0:b11c8971edd9 386 #endif
LordOfDorks 0:b11c8971edd9 387 if(tpmCmd != NULL)
LordOfDorks 0:b11c8971edd9 388 {
LordOfDorks 0:b11c8971edd9 389 delete[] tpmCmd;
LordOfDorks 0:b11c8971edd9 390 tpmCmd = NULL;
LordOfDorks 0:b11c8971edd9 391 }
LordOfDorks 0:b11c8971edd9 392 return rspResponseCode;
LordOfDorks 0:b11c8971edd9 393 }
LordOfDorks 0:b11c8971edd9 394
LordOfDorks 0:b11c8971edd9 395 uint32_t
LordOfDorks 0:b11c8971edd9 396 TISTPM20::TPM2_StirRandom(
LordOfDorks 0:b11c8971edd9 397 uint8_t locality,
LordOfDorks 0:b11c8971edd9 398 uint16_t inDataLen,
LordOfDorks 0:b11c8971edd9 399 uint8_t* inData
LordOfDorks 0:b11c8971edd9 400 )
LordOfDorks 0:b11c8971edd9 401 {
LordOfDorks 0:b11c8971edd9 402 uint32_t cursor = 0;
LordOfDorks 0:b11c8971edd9 403 uint32_t rspLen = 0;
LordOfDorks 0:b11c8971edd9 404 uint16_t rspTag = 0;
LordOfDorks 0:b11c8971edd9 405 uint32_t rspSize = 0;
LordOfDorks 0:b11c8971edd9 406 uint32_t rspResponseCode = 0;
LordOfDorks 0:b11c8971edd9 407 uint32_t tpmMax = sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint16_t) + inDataLen;
LordOfDorks 0:b11c8971edd9 408 uint8_t* tpmCmd = new uint8_t[tpmMax];
LordOfDorks 0:b11c8971edd9 409 #ifndef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 410 uint32_t timeout = 2000;
LordOfDorks 0:b11c8971edd9 411 #else
LordOfDorks 0:b11c8971edd9 412 uint32_t timeout = 20000;
LordOfDorks 0:b11c8971edd9 413 #endif
LordOfDorks 0:b11c8971edd9 414
LordOfDorks 0:b11c8971edd9 415 if(tpmCmd == NULL)
LordOfDorks 0:b11c8971edd9 416 {
LordOfDorks 0:b11c8971edd9 417 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:b11c8971edd9 418 goto Cleanup;
LordOfDorks 0:b11c8971edd9 419 }
LordOfDorks 0:b11c8971edd9 420
LordOfDorks 0:b11c8971edd9 421 // Build command
LordOfDorks 0:b11c8971edd9 422 UINT16_TO_BYTEARRAY(TPM_ST_NO_SESSIONS, tpmCmd, cursor);
LordOfDorks 0:b11c8971edd9 423 cursor += sizeof(uint16_t) + sizeof(cursor);
LordOfDorks 0:b11c8971edd9 424 UINT32_TO_BYTEARRAY(TPM_CC_StirRandom, tpmCmd, cursor);
LordOfDorks 0:b11c8971edd9 425 cursor += sizeof(TPM_CC_GetRandom);
LordOfDorks 0:b11c8971edd9 426 UINT16_TO_BYTEARRAY(inDataLen, tpmCmd, cursor);
LordOfDorks 0:b11c8971edd9 427 cursor += sizeof(inDataLen);
LordOfDorks 0:b11c8971edd9 428 memcpy(&tpmCmd[cursor], inData, inDataLen);
LordOfDorks 0:b11c8971edd9 429 cursor += inDataLen;
LordOfDorks 0:b11c8971edd9 430 UINT32_TO_BYTEARRAY(cursor, tpmCmd, sizeof(uint16_t));
LordOfDorks 0:b11c8971edd9 431
LordOfDorks 0:b11c8971edd9 432 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 433 printf("TIS.TPM2_StirRandom(%d)\n\r", inDataLen);
LordOfDorks 0:b11c8971edd9 434 #endif
LordOfDorks 0:b11c8971edd9 435
LordOfDorks 0:b11c8971edd9 436 if((rspLen = Execute(locality, tpmCmd, cursor, tpmCmd, tpmMax, timeout)) == 0)
LordOfDorks 0:b11c8971edd9 437 {
LordOfDorks 0:b11c8971edd9 438 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:b11c8971edd9 439 goto Cleanup;
LordOfDorks 0:b11c8971edd9 440 }
LordOfDorks 0:b11c8971edd9 441 cursor = 0;
LordOfDorks 0:b11c8971edd9 442 if((rspResponseCode = ParseResponseHeader(tpmCmd, rspLen, &rspTag, &rspSize, &cursor)) != TPM_RC_SUCCESS)
LordOfDorks 0:b11c8971edd9 443 {
LordOfDorks 0:b11c8971edd9 444 goto Cleanup;
LordOfDorks 0:b11c8971edd9 445 }
LordOfDorks 0:b11c8971edd9 446
LordOfDorks 0:b11c8971edd9 447 if(rspSize != 0x0000000a)
LordOfDorks 0:b11c8971edd9 448 {
LordOfDorks 0:b11c8971edd9 449 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:b11c8971edd9 450 goto Cleanup;
LordOfDorks 0:b11c8971edd9 451 }
LordOfDorks 0:b11c8971edd9 452
LordOfDorks 0:b11c8971edd9 453 Cleanup:
LordOfDorks 0:b11c8971edd9 454 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 455 printf("TIS.TPM2_StirRandom.ResponseCode = 0x%08x\n\r", rspResponseCode);
LordOfDorks 0:b11c8971edd9 456 #endif
LordOfDorks 0:b11c8971edd9 457 if(tpmCmd != NULL)
LordOfDorks 0:b11c8971edd9 458 {
LordOfDorks 0:b11c8971edd9 459 delete[] tpmCmd;
LordOfDorks 0:b11c8971edd9 460 tpmCmd = NULL;
LordOfDorks 0:b11c8971edd9 461 }
LordOfDorks 0:b11c8971edd9 462 return rspResponseCode;
LordOfDorks 0:b11c8971edd9 463 }
LordOfDorks 0:b11c8971edd9 464
LordOfDorks 0:b11c8971edd9 465 void
LordOfDorks 0:b11c8971edd9 466 TISTPM20::TimeoutTrigger(
LordOfDorks 0:b11c8971edd9 467 void
LordOfDorks 0:b11c8971edd9 468 )
LordOfDorks 0:b11c8971edd9 469 {
LordOfDorks 0:b11c8971edd9 470 m_TimeoutTriggered = true;
LordOfDorks 0:b11c8971edd9 471 }
LordOfDorks 0:b11c8971edd9 472
LordOfDorks 0:b11c8971edd9 473 uint32_t
LordOfDorks 0:b11c8971edd9 474 TISTPM20::ExecuteTIS(
LordOfDorks 0:b11c8971edd9 475 uint8_t* pbCmd,
LordOfDorks 0:b11c8971edd9 476 uint32_t cbCmd,
LordOfDorks 0:b11c8971edd9 477 uint8_t* pbRsp,
LordOfDorks 0:b11c8971edd9 478 uint32_t cbRsp
LordOfDorks 0:b11c8971edd9 479 )
LordOfDorks 0:b11c8971edd9 480 {
LordOfDorks 0:b11c8971edd9 481 uint32_t result = 0;
LordOfDorks 0:b11c8971edd9 482 uint8_t tisStatus = 0xFF;
LordOfDorks 0:b11c8971edd9 483 uint32_t index = 0;
LordOfDorks 0:b11c8971edd9 484 uint32_t rspSize = 0;
LordOfDorks 0:b11c8971edd9 485 uint16_t tisBurstCount = 0;
LordOfDorks 0:b11c8971edd9 486
LordOfDorks 0:b11c8971edd9 487 // Lock the requested locality
LordOfDorks 0:b11c8971edd9 488 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 489 printf("TIS.RequestLocality\r\n");
LordOfDorks 0:b11c8971edd9 490 #endif
LordOfDorks 0:b11c8971edd9 491 if(!RequestLocality())
LordOfDorks 0:b11c8971edd9 492 {
LordOfDorks 0:b11c8971edd9 493 goto Cleanup;
LordOfDorks 0:b11c8971edd9 494 }
LordOfDorks 0:b11c8971edd9 495
LordOfDorks 0:b11c8971edd9 496 // Check the status before writing the command
LordOfDorks 0:b11c8971edd9 497 if(!GetStatus(&tisStatus))
LordOfDorks 0:b11c8971edd9 498 {
LordOfDorks 0:b11c8971edd9 499 goto Cleanup;
LordOfDorks 0:b11c8971edd9 500 }
LordOfDorks 0:b11c8971edd9 501 // Abort anything that may still be stuck in the TPM
LordOfDorks 0:b11c8971edd9 502 if((tisStatus & TIS_STS_COMMAND_READY) == 0)
LordOfDorks 0:b11c8971edd9 503 {
LordOfDorks 0:b11c8971edd9 504 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 505 printf("TIS.GetReady\r\n");
LordOfDorks 0:b11c8971edd9 506 #endif
LordOfDorks 0:b11c8971edd9 507 uint8_t mask = TIS_STS_COMMAND_READY;
LordOfDorks 0:b11c8971edd9 508 if(!Abort() || !WaitForStatus(mask))
LordOfDorks 0:b11c8971edd9 509 {
LordOfDorks 0:b11c8971edd9 510 goto Cleanup;
LordOfDorks 0:b11c8971edd9 511 }
LordOfDorks 0:b11c8971edd9 512 }
LordOfDorks 0:b11c8971edd9 513 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 514 printf("TIS.ReadyForCommand\r\n");
LordOfDorks 0:b11c8971edd9 515 #endif
LordOfDorks 0:b11c8971edd9 516
LordOfDorks 0:b11c8971edd9 517 // Send the command to the TPM
LordOfDorks 0:b11c8971edd9 518 do
LordOfDorks 0:b11c8971edd9 519 {
LordOfDorks 0:b11c8971edd9 520 uint16_t cbIteration = 0;
LordOfDorks 0:b11c8971edd9 521
LordOfDorks 0:b11c8971edd9 522 // Get the maximum bytes we can send for this iteration
LordOfDorks 0:b11c8971edd9 523 if((!GetBurstCount(&tisBurstCount)) || (tisBurstCount == 0))
LordOfDorks 0:b11c8971edd9 524 {
LordOfDorks 0:b11c8971edd9 525 goto Cleanup;
LordOfDorks 0:b11c8971edd9 526 }
LordOfDorks 0:b11c8971edd9 527 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 528 printf("TIS.GetBurstCount = %d\r\n", tisBurstCount);
LordOfDorks 0:b11c8971edd9 529 #endif
LordOfDorks 0:b11c8971edd9 530
LordOfDorks 0:b11c8971edd9 531 // Assemble the buffer for transmission
LordOfDorks 0:b11c8971edd9 532 cbIteration = min((cbCmd - index), min(tisBurstCount, TIS_MAX_HW_FRAME_SIZE));
LordOfDorks 0:b11c8971edd9 533 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 534 printf("TIS.SendingBurst = %d\r\n", cbIteration);
LordOfDorks 0:b11c8971edd9 535 #endif
LordOfDorks 0:b11c8971edd9 536 if(!SPIFullDuplex(false, TIS_DATA_FIFO, &pbCmd[index], cbIteration))
LordOfDorks 0:b11c8971edd9 537 {
LordOfDorks 0:b11c8971edd9 538 goto Cleanup;
LordOfDorks 0:b11c8971edd9 539 }
LordOfDorks 0:b11c8971edd9 540
LordOfDorks 0:b11c8971edd9 541 // Update the counts
LordOfDorks 0:b11c8971edd9 542 index += cbIteration;
LordOfDorks 0:b11c8971edd9 543 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 544 printf("TIS.Remaining = %d\r\n", (cbCmd - index));
LordOfDorks 0:b11c8971edd9 545 #endif
LordOfDorks 0:b11c8971edd9 546 } while((cbCmd - index) > 0);
LordOfDorks 0:b11c8971edd9 547
LordOfDorks 0:b11c8971edd9 548 // Wait for the TPM to get ready and kick the command off
LordOfDorks 0:b11c8971edd9 549 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 550 printf("TIS.StatusValid\r\n");
LordOfDorks 0:b11c8971edd9 551 #endif
LordOfDorks 0:b11c8971edd9 552 if(!WaitForStatus(TIS_STS_VALID) || !Go())
LordOfDorks 0:b11c8971edd9 553 {
LordOfDorks 0:b11c8971edd9 554 goto Cleanup;
LordOfDorks 0:b11c8971edd9 555 }
LordOfDorks 0:b11c8971edd9 556
LordOfDorks 0:b11c8971edd9 557 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 558 printf("TIS.Go\r\n");
LordOfDorks 0:b11c8971edd9 559 #endif
LordOfDorks 0:b11c8971edd9 560
LordOfDorks 0:b11c8971edd9 561 // Wait for the TPM to finish the command execution
LordOfDorks 0:b11c8971edd9 562 do
LordOfDorks 0:b11c8971edd9 563 {
LordOfDorks 0:b11c8971edd9 564 wait_us(1000);
LordOfDorks 0:b11c8971edd9 565 tisStatus = 0xFF;
LordOfDorks 0:b11c8971edd9 566 if(!GetStatus(&tisStatus) || ((tisStatus & TIS_STS_VALID) == 0))
LordOfDorks 0:b11c8971edd9 567 {
LordOfDorks 0:b11c8971edd9 568 goto Cleanup;
LordOfDorks 0:b11c8971edd9 569 }
LordOfDorks 0:b11c8971edd9 570 }
LordOfDorks 0:b11c8971edd9 571 while(((tisStatus & TIS_STS_DATA_AVAIL) == 0) && (!m_TimeoutTriggered));
LordOfDorks 0:b11c8971edd9 572
LordOfDorks 0:b11c8971edd9 573 if(m_TimeoutTriggered)
LordOfDorks 0:b11c8971edd9 574 {
LordOfDorks 0:b11c8971edd9 575 goto Cleanup;
LordOfDorks 0:b11c8971edd9 576 }
LordOfDorks 0:b11c8971edd9 577
LordOfDorks 0:b11c8971edd9 578 // Get the response header from the TPM
LordOfDorks 0:b11c8971edd9 579 index = 0;
LordOfDorks 0:b11c8971edd9 580 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 581 printf("Tis.ReadResponseHeader\r\n");
LordOfDorks 0:b11c8971edd9 582 #endif
LordOfDorks 0:b11c8971edd9 583 if(!GetBurstCount(&tisBurstCount) ||
LordOfDorks 0:b11c8971edd9 584 (tisBurstCount < (sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t))) ||
LordOfDorks 0:b11c8971edd9 585 !SPIFullDuplex(true, TIS_DATA_FIFO, &pbRsp[index], (sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t))))
LordOfDorks 0:b11c8971edd9 586 {
LordOfDorks 0:b11c8971edd9 587 goto Cleanup;
LordOfDorks 0:b11c8971edd9 588 }
LordOfDorks 0:b11c8971edd9 589 index += (sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t));
LordOfDorks 0:b11c8971edd9 590
LordOfDorks 0:b11c8971edd9 591 rspSize = BYTEARRAY_TO_UINT32(pbRsp, sizeof(uint16_t));
LordOfDorks 0:b11c8971edd9 592 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 593 printf("Tis.ResponseSize = %d\r\n", rspSize);
LordOfDorks 0:b11c8971edd9 594 #endif
LordOfDorks 0:b11c8971edd9 595
LordOfDorks 0:b11c8971edd9 596 if(rspSize > index)
LordOfDorks 0:b11c8971edd9 597 {
LordOfDorks 0:b11c8971edd9 598 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 599 printf("Tis.ReadResponse\r\n");
LordOfDorks 0:b11c8971edd9 600 #endif
LordOfDorks 0:b11c8971edd9 601 do
LordOfDorks 0:b11c8971edd9 602 {
LordOfDorks 0:b11c8971edd9 603 uint16_t cbIteration = 0;
LordOfDorks 0:b11c8971edd9 604
LordOfDorks 0:b11c8971edd9 605 // Check to make sure the TPM has still data for us
LordOfDorks 0:b11c8971edd9 606 if(!GetStatus(&tisStatus) || ((tisStatus & TIS_STS_DATA_AVAIL) == 0))
LordOfDorks 0:b11c8971edd9 607 {
LordOfDorks 0:b11c8971edd9 608 goto Cleanup;
LordOfDorks 0:b11c8971edd9 609 }
LordOfDorks 0:b11c8971edd9 610
LordOfDorks 0:b11c8971edd9 611 // Get the number of available bytes for reading in this iteration
LordOfDorks 0:b11c8971edd9 612 if(!GetBurstCount(&tisBurstCount))
LordOfDorks 0:b11c8971edd9 613 {
LordOfDorks 0:b11c8971edd9 614 goto Cleanup;
LordOfDorks 0:b11c8971edd9 615 }
LordOfDorks 0:b11c8971edd9 616 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 617 printf("TIS.GetBurstCount = %d\r\n", tisBurstCount);
LordOfDorks 0:b11c8971edd9 618 #endif
LordOfDorks 0:b11c8971edd9 619
LordOfDorks 0:b11c8971edd9 620 cbIteration = min((rspSize - index), min((cbRsp - index), min(tisBurstCount, TIS_MAX_HW_FRAME_SIZE)));
LordOfDorks 0:b11c8971edd9 621 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 622 printf("TIS.ReceivingBurst = %d\r\n", cbIteration);
LordOfDorks 0:b11c8971edd9 623 #endif
LordOfDorks 0:b11c8971edd9 624
LordOfDorks 0:b11c8971edd9 625 // Read the data for this iteration
LordOfDorks 0:b11c8971edd9 626 if(!SPIFullDuplex(true, TIS_DATA_FIFO, &pbRsp[index], cbIteration))
LordOfDorks 0:b11c8971edd9 627 {
LordOfDorks 0:b11c8971edd9 628 goto Cleanup;
LordOfDorks 0:b11c8971edd9 629 }
LordOfDorks 0:b11c8971edd9 630 index += cbIteration;
LordOfDorks 0:b11c8971edd9 631 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 632 printf("TIS.Remaining = %d\r\n", (min(rspSize, cbRsp) - index));
LordOfDorks 0:b11c8971edd9 633 #endif
LordOfDorks 0:b11c8971edd9 634 }
LordOfDorks 0:b11c8971edd9 635 while(index < min(rspSize, cbRsp));
LordOfDorks 0:b11c8971edd9 636 }
LordOfDorks 0:b11c8971edd9 637
LordOfDorks 0:b11c8971edd9 638 result = index;
LordOfDorks 0:b11c8971edd9 639
LordOfDorks 0:b11c8971edd9 640 Cleanup:
LordOfDorks 0:b11c8971edd9 641 // Always leave the TPM in a clean state if somethign fishy happened
LordOfDorks 0:b11c8971edd9 642 if(result == 0)
LordOfDorks 0:b11c8971edd9 643 {
LordOfDorks 0:b11c8971edd9 644 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 645 printf("TIS.Abort\r\n");
LordOfDorks 0:b11c8971edd9 646 #endif
LordOfDorks 0:b11c8971edd9 647 Abort();
LordOfDorks 0:b11c8971edd9 648 }
LordOfDorks 0:b11c8971edd9 649
LordOfDorks 0:b11c8971edd9 650 // Release the locality again
LordOfDorks 0:b11c8971edd9 651 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 652 printf("TIS.ReleaseLocality\r\n");
LordOfDorks 0:b11c8971edd9 653 #endif
LordOfDorks 0:b11c8971edd9 654 ReleaseLocality();
LordOfDorks 0:b11c8971edd9 655 return result;
LordOfDorks 0:b11c8971edd9 656 }
LordOfDorks 0:b11c8971edd9 657
LordOfDorks 0:b11c8971edd9 658 bool
LordOfDorks 0:b11c8971edd9 659 TISTPM20::SPIFullDuplex(
LordOfDorks 0:b11c8971edd9 660 bool readCycle,
LordOfDorks 0:b11c8971edd9 661 uint8_t tisRegister,
LordOfDorks 0:b11c8971edd9 662 uint8_t* pbBuffer,
LordOfDorks 0:b11c8971edd9 663 uint16_t cbBuffer
LordOfDorks 0:b11c8971edd9 664 )
LordOfDorks 0:b11c8971edd9 665 {
LordOfDorks 0:b11c8971edd9 666 bool result = false;
LordOfDorks 0:b11c8971edd9 667 uint8_t dataByteIn;
LordOfDorks 0:b11c8971edd9 668 uint8_t dataByteOut;
LordOfDorks 0:b11c8971edd9 669
LordOfDorks 0:b11c8971edd9 670 // Lock the bus for this operation
LordOfDorks 0:b11c8971edd9 671 *m_SPICSTpmDev = 0;
LordOfDorks 0:b11c8971edd9 672
LordOfDorks 0:b11c8971edd9 673 // Send the TIS header
LordOfDorks 0:b11c8971edd9 674 uint32_t tisHdr = TIS_HEADER(m_Locality, readCycle, tisRegister, cbBuffer);
LordOfDorks 0:b11c8971edd9 675 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 676 printf("TIS(LC:%d,RG:%02x,SZ:%02x,%s):", m_Locality, tisRegister, cbBuffer, (readCycle) ? "RD" : "WR");
LordOfDorks 0:b11c8971edd9 677 #endif
LordOfDorks 0:b11c8971edd9 678
LordOfDorks 0:b11c8971edd9 679 for(uint8_t n = 0; n < sizeof(tisHdr); n++)
LordOfDorks 0:b11c8971edd9 680 {
LordOfDorks 0:b11c8971edd9 681 dataByteOut = tisHdr >> (8 * (3 - n));
LordOfDorks 0:b11c8971edd9 682 dataByteIn = m_SPITpmDev->write(dataByteOut);
LordOfDorks 0:b11c8971edd9 683 }
LordOfDorks 0:b11c8971edd9 684
LordOfDorks 0:b11c8971edd9 685 // The last read bit is the wait state indicator
LordOfDorks 0:b11c8971edd9 686 if((dataByteIn & 0x01) == 0)
LordOfDorks 0:b11c8971edd9 687 {
LordOfDorks 0:b11c8971edd9 688 do
LordOfDorks 0:b11c8971edd9 689 {
LordOfDorks 0:b11c8971edd9 690 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 691 printf(".");
LordOfDorks 0:b11c8971edd9 692 #endif
LordOfDorks 0:b11c8971edd9 693 // Do we still have to wait?
LordOfDorks 0:b11c8971edd9 694 if((dataByteIn = m_SPITpmDev->write(0xFF)) != 0x01)
LordOfDorks 0:b11c8971edd9 695 {
LordOfDorks 0:b11c8971edd9 696 wait_us(10);
LordOfDorks 0:b11c8971edd9 697 }
LordOfDorks 0:b11c8971edd9 698 }
LordOfDorks 0:b11c8971edd9 699 while((dataByteIn != 0x01) && (!m_TimeoutTriggered));
LordOfDorks 0:b11c8971edd9 700
LordOfDorks 0:b11c8971edd9 701 // Check if we timed out
LordOfDorks 0:b11c8971edd9 702 if((dataByteIn != 0x01) && (m_TimeoutTriggered))
LordOfDorks 0:b11c8971edd9 703 {
LordOfDorks 0:b11c8971edd9 704 goto Cleanup;
LordOfDorks 0:b11c8971edd9 705 }
LordOfDorks 0:b11c8971edd9 706 }
LordOfDorks 0:b11c8971edd9 707
LordOfDorks 0:b11c8971edd9 708 // Do the remaining bytes now
LordOfDorks 0:b11c8971edd9 709 for(uint8_t n = 0; n < cbBuffer; n++)
LordOfDorks 0:b11c8971edd9 710 {
LordOfDorks 0:b11c8971edd9 711 dataByteOut = (readCycle) ? 0xFF : pbBuffer[n];
LordOfDorks 0:b11c8971edd9 712 dataByteIn = m_SPITpmDev->write(dataByteOut);
LordOfDorks 0:b11c8971edd9 713 if(readCycle) pbBuffer[n] = dataByteIn;
LordOfDorks 0:b11c8971edd9 714 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 715 printf("0x%02x ", (readCycle) ? dataByteIn : dataByteOut);
LordOfDorks 0:b11c8971edd9 716 #endif
LordOfDorks 0:b11c8971edd9 717 }
LordOfDorks 0:b11c8971edd9 718 result = true;
LordOfDorks 0:b11c8971edd9 719 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 720 printf("\r\n");
LordOfDorks 0:b11c8971edd9 721 #endif
LordOfDorks 0:b11c8971edd9 722
LordOfDorks 0:b11c8971edd9 723 Cleanup:
LordOfDorks 0:b11c8971edd9 724 // Make sure to release the bus before we leave
LordOfDorks 0:b11c8971edd9 725 *m_SPICSTpmDev = 1;
LordOfDorks 0:b11c8971edd9 726 return result;
LordOfDorks 0:b11c8971edd9 727 }
LordOfDorks 0:b11c8971edd9 728
LordOfDorks 0:b11c8971edd9 729 bool
LordOfDorks 0:b11c8971edd9 730 TISTPM20::RequestLocality()
LordOfDorks 0:b11c8971edd9 731 {
LordOfDorks 0:b11c8971edd9 732 do
LordOfDorks 0:b11c8971edd9 733 {
LordOfDorks 0:b11c8971edd9 734 // Do we have access already?
LordOfDorks 0:b11c8971edd9 735 uint8_t dataByte = 0xFF;
LordOfDorks 0:b11c8971edd9 736 if(!SPIFullDuplex(true, TIS_ACCESS_REGISTER, &dataByte, sizeof(dataByte)))
LordOfDorks 0:b11c8971edd9 737 {
LordOfDorks 0:b11c8971edd9 738 return false;
LordOfDorks 0:b11c8971edd9 739 }
LordOfDorks 0:b11c8971edd9 740 if((dataByte & TIS_ACCESS_ACTIVE_LOCALITY) &&
LordOfDorks 0:b11c8971edd9 741 (dataByte & TIS_ACCESS_VALID))
LordOfDorks 0:b11c8971edd9 742 {
LordOfDorks 0:b11c8971edd9 743 break;
LordOfDorks 0:b11c8971edd9 744 }
LordOfDorks 0:b11c8971edd9 745
LordOfDorks 0:b11c8971edd9 746 // Request access
LordOfDorks 0:b11c8971edd9 747 dataByte = TIS_ACCESS_REQUEST_USE;
LordOfDorks 0:b11c8971edd9 748 if(!SPIFullDuplex(false, TIS_ACCESS_REGISTER, &dataByte, sizeof(dataByte)))
LordOfDorks 0:b11c8971edd9 749 {
LordOfDorks 0:b11c8971edd9 750 return false;
LordOfDorks 0:b11c8971edd9 751 }
LordOfDorks 0:b11c8971edd9 752 if(m_TimeoutTriggered)
LordOfDorks 0:b11c8971edd9 753 {
LordOfDorks 0:b11c8971edd9 754 // We give up eventually
LordOfDorks 0:b11c8971edd9 755 return false;
LordOfDorks 0:b11c8971edd9 756 }
LordOfDorks 0:b11c8971edd9 757 wait_us(10);
LordOfDorks 0:b11c8971edd9 758 }
LordOfDorks 0:b11c8971edd9 759 while(1);
LordOfDorks 0:b11c8971edd9 760 return true;
LordOfDorks 0:b11c8971edd9 761 }
LordOfDorks 0:b11c8971edd9 762
LordOfDorks 0:b11c8971edd9 763 bool TISTPM20::ReleaseLocality()
LordOfDorks 0:b11c8971edd9 764 {
LordOfDorks 0:b11c8971edd9 765 do
LordOfDorks 0:b11c8971edd9 766 {
LordOfDorks 0:b11c8971edd9 767 // Do we even have access?
LordOfDorks 0:b11c8971edd9 768 uint8_t dataByte = 0xFF;
LordOfDorks 0:b11c8971edd9 769 if(!SPIFullDuplex(true, TIS_ACCESS_REGISTER, &dataByte, sizeof(dataByte)))
LordOfDorks 0:b11c8971edd9 770 {
LordOfDorks 0:b11c8971edd9 771 return false;
LordOfDorks 0:b11c8971edd9 772 }
LordOfDorks 0:b11c8971edd9 773 if(!(dataByte & TIS_ACCESS_ACTIVE_LOCALITY) &&
LordOfDorks 0:b11c8971edd9 774 (dataByte & TIS_ACCESS_VALID))
LordOfDorks 0:b11c8971edd9 775 {
LordOfDorks 0:b11c8971edd9 776 break;
LordOfDorks 0:b11c8971edd9 777 }
LordOfDorks 0:b11c8971edd9 778
LordOfDorks 0:b11c8971edd9 779 // Release access
LordOfDorks 0:b11c8971edd9 780 dataByte = TIS_ACCESS_ACTIVE_LOCALITY;
LordOfDorks 0:b11c8971edd9 781 if(!SPIFullDuplex(false, TIS_ACCESS_REGISTER, &dataByte, sizeof(dataByte)))
LordOfDorks 0:b11c8971edd9 782 {
LordOfDorks 0:b11c8971edd9 783 return false;
LordOfDorks 0:b11c8971edd9 784 }
LordOfDorks 0:b11c8971edd9 785 if(m_TimeoutTriggered)
LordOfDorks 0:b11c8971edd9 786 {
LordOfDorks 0:b11c8971edd9 787 // We give up eventually
LordOfDorks 0:b11c8971edd9 788 return false;
LordOfDorks 0:b11c8971edd9 789 }
LordOfDorks 0:b11c8971edd9 790 wait_us(10);
LordOfDorks 0:b11c8971edd9 791 }
LordOfDorks 0:b11c8971edd9 792 while(1);
LordOfDorks 0:b11c8971edd9 793 return true;
LordOfDorks 0:b11c8971edd9 794 }
LordOfDorks 0:b11c8971edd9 795
LordOfDorks 0:b11c8971edd9 796 bool
LordOfDorks 0:b11c8971edd9 797 TISTPM20::GetBurstCount(
LordOfDorks 0:b11c8971edd9 798 uint16_t* pBurstCount
LordOfDorks 0:b11c8971edd9 799 )
LordOfDorks 0:b11c8971edd9 800 {
LordOfDorks 0:b11c8971edd9 801 uint8_t dataBytes[sizeof(*pBurstCount)] = {0};
LordOfDorks 0:b11c8971edd9 802 do
LordOfDorks 0:b11c8971edd9 803 {
LordOfDorks 0:b11c8971edd9 804 if(!SPIFullDuplex(true, TIS_BURSTCOUNT_REGISTER, dataBytes, sizeof(dataBytes)))
LordOfDorks 0:b11c8971edd9 805 {
LordOfDorks 0:b11c8971edd9 806 return false;
LordOfDorks 0:b11c8971edd9 807 }
LordOfDorks 0:b11c8971edd9 808 *pBurstCount = (uint16_t)dataBytes[0] | (uint16_t)(dataBytes[1] << 8);
LordOfDorks 0:b11c8971edd9 809
LordOfDorks 0:b11c8971edd9 810 // Burst count can be 0 if we are too fast
LordOfDorks 0:b11c8971edd9 811 if(*pBurstCount != 0)
LordOfDorks 0:b11c8971edd9 812 {
LordOfDorks 0:b11c8971edd9 813 break;
LordOfDorks 0:b11c8971edd9 814 }
LordOfDorks 0:b11c8971edd9 815 if(m_TimeoutTriggered)
LordOfDorks 0:b11c8971edd9 816 {
LordOfDorks 0:b11c8971edd9 817 // We give up eventually
LordOfDorks 0:b11c8971edd9 818 return false;
LordOfDorks 0:b11c8971edd9 819 }
LordOfDorks 0:b11c8971edd9 820 wait_us(10);
LordOfDorks 0:b11c8971edd9 821 }
LordOfDorks 0:b11c8971edd9 822 while(1);
LordOfDorks 0:b11c8971edd9 823 return true;
LordOfDorks 0:b11c8971edd9 824 }
LordOfDorks 0:b11c8971edd9 825
LordOfDorks 0:b11c8971edd9 826 bool
LordOfDorks 0:b11c8971edd9 827 TISTPM20::GetStatus(
LordOfDorks 0:b11c8971edd9 828 uint8_t* pStatus
LordOfDorks 0:b11c8971edd9 829 )
LordOfDorks 0:b11c8971edd9 830 {
LordOfDorks 0:b11c8971edd9 831 bool result = SPIFullDuplex(true, TIS_STATUS_REGISTER, pStatus, sizeof(*pStatus));
LordOfDorks 0:b11c8971edd9 832 return result;
LordOfDorks 0:b11c8971edd9 833 }
LordOfDorks 0:b11c8971edd9 834
LordOfDorks 0:b11c8971edd9 835 bool
LordOfDorks 0:b11c8971edd9 836 TISTPM20::WaitForStatus(
LordOfDorks 0:b11c8971edd9 837 uint8_t statusMask
LordOfDorks 0:b11c8971edd9 838 )
LordOfDorks 0:b11c8971edd9 839 {
LordOfDorks 0:b11c8971edd9 840 bool result = false;
LordOfDorks 0:b11c8971edd9 841 uint8_t tisStatus = 0xFF;
LordOfDorks 0:b11c8971edd9 842
LordOfDorks 0:b11c8971edd9 843 do
LordOfDorks 0:b11c8971edd9 844 {
LordOfDorks 0:b11c8971edd9 845 if(!GetStatus(&tisStatus))
LordOfDorks 0:b11c8971edd9 846 {
LordOfDorks 0:b11c8971edd9 847 goto Cleanup;
LordOfDorks 0:b11c8971edd9 848 }
LordOfDorks 0:b11c8971edd9 849 if((tisStatus & statusMask) == statusMask)
LordOfDorks 0:b11c8971edd9 850 {
LordOfDorks 0:b11c8971edd9 851 result = true;
LordOfDorks 0:b11c8971edd9 852 break;
LordOfDorks 0:b11c8971edd9 853 }
LordOfDorks 0:b11c8971edd9 854 wait_us(10);
LordOfDorks 0:b11c8971edd9 855 }
LordOfDorks 0:b11c8971edd9 856 while(!m_TimeoutTriggered);
LordOfDorks 0:b11c8971edd9 857
LordOfDorks 0:b11c8971edd9 858 Cleanup:
LordOfDorks 0:b11c8971edd9 859 return result;
LordOfDorks 0:b11c8971edd9 860 }
LordOfDorks 0:b11c8971edd9 861
LordOfDorks 0:b11c8971edd9 862 bool
LordOfDorks 0:b11c8971edd9 863 TISTPM20::Abort()
LordOfDorks 0:b11c8971edd9 864 {
LordOfDorks 0:b11c8971edd9 865 uint8_t dataByte = TIS_STS_COMMAND_READY;
LordOfDorks 0:b11c8971edd9 866 return SPIFullDuplex(false, TIS_STATUS_REGISTER, &dataByte, sizeof(dataByte));
LordOfDorks 0:b11c8971edd9 867 }
LordOfDorks 0:b11c8971edd9 868
LordOfDorks 0:b11c8971edd9 869 bool
LordOfDorks 0:b11c8971edd9 870 TISTPM20::Go()
LordOfDorks 0:b11c8971edd9 871 {
LordOfDorks 0:b11c8971edd9 872 uint8_t dataByte = TIS_STS_GO;
LordOfDorks 0:b11c8971edd9 873 return SPIFullDuplex(false, TIS_STATUS_REGISTER, &dataByte, sizeof(dataByte));
LordOfDorks 0:b11c8971edd9 874 }