PageRenderTime 54ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/tboot-1.7.0/tboot/common/tpm.c

#
C | 2132 lines | 1604 code | 325 blank | 203 comment | 329 complexity | 71ffc436c183b2797fc2729663aebc4c MD5 | raw file
  1. /*
  2. * tpm.c: TPM-related support functions
  3. *
  4. * Copyright (c) 2006-2010, Intel Corporation
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * * Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * * Redistributions in binary form must reproduce the above
  14. * copyright notice, this list of conditions and the following
  15. * disclaimer in the documentation and/or other materials provided
  16. * with the distribution.
  17. * * Neither the name of the Intel Corporation nor the names of its
  18. * contributors may be used to endorse or promote products derived
  19. * from this software without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  25. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  27. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  28. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  30. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  31. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  32. * OF THE POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. */
  35. #include <config.h>
  36. #include <types.h>
  37. #include <stdbool.h>
  38. #include <printk.h>
  39. #include <misc.h>
  40. #include <compiler.h>
  41. #include <processor.h>
  42. #include <io.h>
  43. #include <string.h>
  44. #include <tpm.h>
  45. #include <sha1.h>
  46. /* un-comment to enable detailed command tracing */
  47. //#define TPM_TRACE
  48. /* ~5 secs are required for Infineon that requires this, so leave some extra */
  49. #define MAX_SAVESTATE_RETRIES 60
  50. #define TPM_TAG_RQU_COMMAND 0x00C1
  51. #define TPM_TAG_RQU_AUTH1_COMMAND 0x00C2
  52. #define TPM_TAG_RQU_AUTH2_COMMAND 0x00C3
  53. #define TPM_ORD_PCR_EXTEND 0x00000014
  54. #define TPM_ORD_PCR_READ 0x00000015
  55. #define TPM_ORD_PCR_RESET 0x000000C8
  56. #define TPM_ORD_NV_READ_VALUE 0x000000CF
  57. #define TPM_ORD_NV_WRITE_VALUE 0x000000CD
  58. #define TPM_ORD_GET_CAPABILITY 0x00000065
  59. #define TPM_ORD_SEAL 0x00000017
  60. #define TPM_ORD_UNSEAL 0x00000018
  61. #define TPM_ORD_OSAP 0x0000000B
  62. #define TPM_ORD_OIAP 0x0000000A
  63. #define TPM_ORD_SAVE_STATE 0x00000098
  64. #define TPM_ORD_GET_RANDOM 0x00000046
  65. #define TPM_TAG_PCR_INFO_LONG 0x0006
  66. #define TPM_TAG_STORED_DATA12 0x0016
  67. /*
  68. * TPM registers and data structures
  69. *
  70. * register values are offsets from each locality base
  71. * see {read,write}_tpm_reg() for data struct format
  72. */
  73. /* TPM_ACCESS_x */
  74. #define TPM_REG_ACCESS 0x00
  75. typedef union {
  76. u8 _raw[1]; /* 1-byte reg */
  77. struct __packed {
  78. u8 tpm_establishment : 1; /* RO, 0=T/OS has been established
  79. before */
  80. u8 request_use : 1; /* RW, 1=locality is requesting TPM use */
  81. u8 pending_request : 1; /* RO, 1=other locality is requesting
  82. TPM usage */
  83. u8 seize : 1; /* WO, 1=seize locality */
  84. u8 been_seized : 1; /* RW, 1=locality seized while active */
  85. u8 active_locality : 1; /* RW, 1=locality is active */
  86. u8 reserved : 1;
  87. u8 tpm_reg_valid_sts : 1; /* RO, 1=other bits are valid */
  88. };
  89. } tpm_reg_access_t;
  90. /* TPM_STS_x */
  91. #define TPM_REG_STS 0x18
  92. typedef union {
  93. u8 _raw[3]; /* 3-byte reg */
  94. struct __packed {
  95. u8 reserved1 : 1;
  96. u8 response_retry : 1; /* WO, 1=re-send response */
  97. u8 reserved2 : 1;
  98. u8 expect : 1; /* RO, 1=more data for command expected */
  99. u8 data_avail : 1; /* RO, 0=no more data for response */
  100. u8 tpm_go : 1; /* WO, 1=execute sent command */
  101. u8 command_ready : 1; /* RW, 1=TPM ready to receive new cmd */
  102. u8 sts_valid : 1; /* RO, 1=data_avail and expect bits are
  103. valid */
  104. u16 burst_count : 16; /* RO, # read/writes bytes before wait */
  105. };
  106. } tpm_reg_sts_t;
  107. /* TPM_DATA_FIFO_x */
  108. #define TPM_REG_DATA_FIFO 0x24
  109. typedef union {
  110. uint8_t _raw[1]; /* 1-byte reg */
  111. } tpm_reg_data_fifo_t;
  112. /*
  113. * assumes that all reg types follow above format:
  114. * - packed
  115. * - member named '_raw' which is array whose size is that of data to read
  116. */
  117. #define read_tpm_reg(locality, reg, pdata) \
  118. _read_tpm_reg(locality, reg, (pdata)->_raw, sizeof(*(pdata)))
  119. #define write_tpm_reg(locality, reg, pdata) \
  120. _write_tpm_reg(locality, reg, (pdata)->_raw, sizeof(*(pdata)))
  121. static void _read_tpm_reg(int locality, u32 reg, u8 *_raw, size_t size)
  122. {
  123. for ( size_t i = 0; i < size; i++ )
  124. _raw[i] = readb((TPM_LOCALITY_BASE_N(locality) | reg) + i);
  125. }
  126. static void _write_tpm_reg(int locality, u32 reg, u8 *_raw, size_t size)
  127. {
  128. for ( size_t i = 0; i < size; i++ )
  129. writeb((TPM_LOCALITY_BASE_N(locality) | reg) + i, _raw[i]);
  130. }
  131. /*
  132. * the following inline function reversely copy the bytes from 'in' to
  133. * 'out', the byte number to copy is given in count.
  134. */
  135. #define reverse_copy(out, in, count) \
  136. _reverse_copy((uint8_t *)(out), (uint8_t *)(in), count)
  137. static inline void _reverse_copy(uint8_t *out, uint8_t *in, uint32_t count)
  138. {
  139. for ( uint32_t i = 0; i < count; i++ )
  140. out[i] = in[count - i - 1];
  141. }
  142. #define TPM_VALIDATE_LOCALITY_TIME_OUT 0x100
  143. static bool tpm_validate_locality(uint32_t locality)
  144. {
  145. uint32_t i;
  146. tpm_reg_access_t reg_acc;
  147. for ( i = TPM_VALIDATE_LOCALITY_TIME_OUT; i > 0; i-- ) {
  148. /*
  149. * TCG spec defines reg_acc.tpm_reg_valid_sts bit to indicate whether
  150. * other bits of access reg are valid.( but this bit will also be 1
  151. * while this locality is not available, so check seize bit too)
  152. * It also defines that reading reg_acc.seize should always return 0
  153. */
  154. read_tpm_reg(locality, TPM_REG_ACCESS, &reg_acc);
  155. if ( reg_acc.tpm_reg_valid_sts == 1 && reg_acc.seize == 0)
  156. return true;
  157. cpu_relax();
  158. }
  159. if ( i <= 0 )
  160. printk("TPM: tpm_validate_locality timeout\n");
  161. return false;
  162. }
  163. #define TIMEOUT_UNIT (0x100000 / 330) /* ~1ms, 1 tpm r/w need > 330ns */
  164. #define TIMEOUT_A 750 /* 750ms */
  165. #define TIMEOUT_B 2000 /* 2s */
  166. #define TIMEOUT_C 750 /* 750ms */
  167. #define TIMEOUT_D 750 /* 750ms */
  168. typedef struct __packed {
  169. uint32_t timeout_a;
  170. uint32_t timeout_b;
  171. uint32_t timeout_c;
  172. uint32_t timeout_d;
  173. } tpm_timeout_t;
  174. static tpm_timeout_t g_timeout = {TIMEOUT_A,
  175. TIMEOUT_B,
  176. TIMEOUT_C,
  177. TIMEOUT_D};
  178. #define TPM_ACTIVE_LOCALITY_TIME_OUT \
  179. (TIMEOUT_UNIT * g_timeout.timeout_a) /* according to spec */
  180. #define TPM_CMD_READY_TIME_OUT \
  181. (TIMEOUT_UNIT * g_timeout.timeout_b) /* according to spec */
  182. #define TPM_CMD_WRITE_TIME_OUT \
  183. (TIMEOUT_UNIT * g_timeout.timeout_d) /* let it long enough */
  184. #define TPM_DATA_AVAIL_TIME_OUT \
  185. (TIMEOUT_UNIT * g_timeout.timeout_c) /* let it long enough */
  186. #define TPM_RSP_READ_TIME_OUT \
  187. (TIMEOUT_UNIT * g_timeout.timeout_d) /* let it long enough */
  188. static uint32_t tpm_wait_cmd_ready(uint32_t locality)
  189. {
  190. uint32_t i;
  191. tpm_reg_access_t reg_acc;
  192. tpm_reg_sts_t reg_sts;
  193. /* ensure the contents of the ACCESS register are valid */
  194. read_tpm_reg(locality, TPM_REG_ACCESS, &reg_acc);
  195. #ifdef TPM_TRACE
  196. printk("TPM: Access reg content: 0x%02x\n", (uint32_t)reg_acc._raw[0]);
  197. #endif
  198. if ( reg_acc.tpm_reg_valid_sts == 0 ) {
  199. printk("TPM: Access reg not valid\n");
  200. return TPM_FAIL;
  201. }
  202. /* request access to the TPM from locality N */
  203. reg_acc._raw[0] = 0;
  204. reg_acc.request_use = 1;
  205. write_tpm_reg(locality, TPM_REG_ACCESS, &reg_acc);
  206. i = 0;
  207. do {
  208. read_tpm_reg(locality, TPM_REG_ACCESS, &reg_acc);
  209. if ( reg_acc.active_locality == 1 )
  210. break;
  211. else
  212. cpu_relax();
  213. i++;
  214. } while ( i <= TPM_ACTIVE_LOCALITY_TIME_OUT);
  215. if ( i > TPM_ACTIVE_LOCALITY_TIME_OUT ) {
  216. printk("TPM: access reg request use timeout\n");
  217. return TPM_FAIL;
  218. }
  219. /* ensure the TPM is ready to accept a command */
  220. #ifdef TPM_TRACE
  221. printk("TPM: wait for cmd ready ");
  222. #endif
  223. i = 0;
  224. do {
  225. /* write 1 to TPM_STS_x.commandReady to let TPM enter ready state */
  226. memset((void *)&reg_sts, 0, sizeof(reg_sts));
  227. reg_sts.command_ready = 1;
  228. write_tpm_reg(locality, TPM_REG_STS, &reg_sts);
  229. cpu_relax();
  230. /* then see if it has */
  231. read_tpm_reg(locality, TPM_REG_STS, &reg_sts);
  232. #ifdef TPM_TRACE
  233. printk(".");
  234. #endif
  235. if ( reg_sts.command_ready == 1 )
  236. break;
  237. else
  238. cpu_relax();
  239. i++;
  240. } while ( i <= TPM_CMD_READY_TIME_OUT );
  241. #ifdef TPM_TRACE
  242. printk("\n");
  243. #endif
  244. if ( i > TPM_CMD_READY_TIME_OUT ) {
  245. printk("TPM: status reg content: %02x %02x %02x\n",
  246. (uint32_t)reg_sts._raw[0],
  247. (uint32_t)reg_sts._raw[1],
  248. (uint32_t)reg_sts._raw[2]);
  249. printk("TPM: tpm timeout for command_ready\n");
  250. goto RelinquishControl;
  251. }
  252. return TPM_SUCCESS;
  253. RelinquishControl:
  254. /* deactivate current locality */
  255. reg_acc._raw[0] = 0;
  256. reg_acc.active_locality = 1;
  257. write_tpm_reg(locality, TPM_REG_ACCESS, &reg_acc);
  258. return TPM_FAIL;
  259. }
  260. /*
  261. * locality : TPM locality (0 - 3)
  262. * in : All bytes for a single TPM command, including TAG, SIZE,
  263. * ORDINAL, and other arguments. All data should be in big-endian
  264. * style. The in MUST NOT be NULL, containing at least 10 bytes.
  265. * 0 1 2 3 4 5 6 7 8 9 10 ...
  266. * -------------------------------------------------------------
  267. * | TAG | SIZE | ORDINAL | arguments ...
  268. * -------------------------------------------------------------
  269. * in_size : The size of the whole command contained within the in buffer.
  270. * It should equal to the SIZE contained in the in buffer.
  271. * out : All bytes of the TPM response to a single command. All data
  272. * within it will be in big-endian style. The out MUST not be
  273. * NULL, and will return at least 10 bytes.
  274. * 0 1 2 3 4 5 6 7 8 9 10 ...
  275. * -------------------------------------------------------------
  276. * | TAG | SIZE | RETURN CODE | other data ...
  277. * -------------------------------------------------------------
  278. * out_size : In/out paramter. As in, it is the size of the out buffer;
  279. * as out, it is the size of the response within the out buffer.
  280. * The out_size MUST NOT be NULL.
  281. * return : 0 = success; if not 0, it equal to the RETURN CODE in out buf.
  282. */
  283. #define CMD_HEAD_SIZE 10
  284. #define RSP_HEAD_SIZE 10
  285. #define CMD_SIZE_OFFSET 2
  286. #define CMD_ORD_OFFSET 6
  287. #define RSP_SIZE_OFFSET 2
  288. #define RSP_RST_OFFSET 6
  289. static uint32_t tpm_write_cmd_fifo(uint32_t locality, uint8_t *in,
  290. uint32_t in_size, uint8_t *out,
  291. uint32_t *out_size)
  292. {
  293. uint32_t i, rsp_size, offset, ret;
  294. uint16_t row_size;
  295. tpm_reg_access_t reg_acc;
  296. tpm_reg_sts_t reg_sts;
  297. if ( locality >= TPM_NR_LOCALITIES ) {
  298. printk("TPM: Invalid locality for tpm_write_cmd_fifo()\n");
  299. return TPM_BAD_PARAMETER;
  300. }
  301. if ( in == NULL || out == NULL || out_size == NULL ) {
  302. printk("TPM: Invalid parameter for tpm_write_cmd_fifo()\n");
  303. return TPM_BAD_PARAMETER;
  304. }
  305. if ( in_size < CMD_HEAD_SIZE || *out_size < RSP_HEAD_SIZE ) {
  306. printk("TPM: in/out buf size must be larger than 10 bytes\n");
  307. return TPM_BAD_PARAMETER;
  308. }
  309. if ( !tpm_validate_locality(locality) ) {
  310. printk("TPM: Locality %d is not open\n", locality);
  311. return TPM_FAIL;
  312. }
  313. ret = tpm_wait_cmd_ready(locality);
  314. if ( ret != TPM_SUCCESS )
  315. return ret;
  316. #ifdef TPM_TRACE
  317. {
  318. printk("TPM: cmd size = %d\nTPM: cmd content: ", in_size);
  319. print_hex("TPM: \t", in, in_size);
  320. }
  321. #endif
  322. /* write the command to the TPM FIFO */
  323. offset = 0;
  324. do {
  325. i = 0;
  326. do {
  327. read_tpm_reg(locality, TPM_REG_STS, &reg_sts);
  328. /* find out how many bytes the TPM can accept in a row */
  329. row_size = reg_sts.burst_count;
  330. if ( row_size > 0 )
  331. break;
  332. else
  333. cpu_relax();
  334. i++;
  335. } while ( i <= TPM_CMD_WRITE_TIME_OUT );
  336. if ( i > TPM_CMD_WRITE_TIME_OUT ) {
  337. printk("TPM: write cmd timeout\n");
  338. ret = TPM_FAIL;
  339. goto RelinquishControl;
  340. }
  341. for ( ; row_size > 0 && offset < in_size; row_size--, offset++ )
  342. write_tpm_reg(locality, TPM_REG_DATA_FIFO,
  343. (tpm_reg_data_fifo_t *)&in[offset]);
  344. } while ( offset < in_size );
  345. i = 0;
  346. do {
  347. read_tpm_reg(locality,TPM_REG_STS, &reg_sts);
  348. #ifdef TPM_TRACE
  349. printk("Wait on Expect = 0, Status register %02x\n", reg_sts._raw[0]);
  350. #endif
  351. if ( reg_sts.sts_valid == 1 && reg_sts.expect == 0 )
  352. break;
  353. else
  354. cpu_relax();
  355. i++;
  356. } while ( i <= TPM_DATA_AVAIL_TIME_OUT );
  357. if ( i > TPM_DATA_AVAIL_TIME_OUT ) {
  358. printk("TPM: wait for expect becoming 0 timeout\n");
  359. ret = TPM_FAIL;
  360. goto RelinquishControl;
  361. }
  362. /* command has been written to the TPM, it is time to execute it. */
  363. memset(&reg_sts, 0, sizeof(reg_sts));
  364. reg_sts.tpm_go = 1;
  365. write_tpm_reg(locality, TPM_REG_STS, &reg_sts);
  366. /* check for data available */
  367. i = 0;
  368. do {
  369. read_tpm_reg(locality,TPM_REG_STS, &reg_sts);
  370. #ifdef TPM_TRACE
  371. printk("Waiting for DA Flag, Status register %02x\n", reg_sts._raw[0]);
  372. #endif
  373. if ( reg_sts.sts_valid == 1 && reg_sts.data_avail == 1 )
  374. break;
  375. else
  376. cpu_relax();
  377. i++;
  378. } while ( i <= TPM_DATA_AVAIL_TIME_OUT );
  379. if ( i > TPM_DATA_AVAIL_TIME_OUT ) {
  380. printk("TPM: wait for data available timeout\n");
  381. ret = TPM_FAIL;
  382. goto RelinquishControl;
  383. }
  384. rsp_size = 0;
  385. offset = 0;
  386. do {
  387. /* find out how many bytes the TPM returned in a row */
  388. i = 0;
  389. do {
  390. read_tpm_reg(locality, TPM_REG_STS, &reg_sts);
  391. row_size = reg_sts.burst_count;
  392. if ( row_size > 0 )
  393. break;
  394. else
  395. cpu_relax();
  396. i++;
  397. } while ( i <= TPM_RSP_READ_TIME_OUT );
  398. if ( i > TPM_RSP_READ_TIME_OUT ) {
  399. printk("TPM: read rsp timeout\n");
  400. ret = TPM_FAIL;
  401. goto RelinquishControl;
  402. }
  403. for ( ; row_size > 0 && offset < *out_size; row_size--, offset++ ) {
  404. if ( offset < *out_size )
  405. read_tpm_reg(locality, TPM_REG_DATA_FIFO,
  406. (tpm_reg_data_fifo_t *)&out[offset]);
  407. else {
  408. /* discard the responded bytes exceeding out buf size */
  409. tpm_reg_data_fifo_t discard;
  410. read_tpm_reg(locality, TPM_REG_DATA_FIFO,
  411. (tpm_reg_data_fifo_t *)&discard);
  412. }
  413. /* get outgoing data size */
  414. if ( offset == RSP_RST_OFFSET - 1 ) {
  415. reverse_copy(&rsp_size, &out[RSP_SIZE_OFFSET],
  416. sizeof(rsp_size));
  417. }
  418. }
  419. } while ( offset < RSP_RST_OFFSET ||
  420. (offset < rsp_size && offset < *out_size) );
  421. *out_size = (*out_size > rsp_size) ? rsp_size : *out_size;
  422. /* out buffer contains the complete outgoing data, get return code */
  423. reverse_copy(&ret, &out[RSP_RST_OFFSET], sizeof(ret));
  424. #ifdef TPM_TRACE
  425. {
  426. printk("TPM: response size = %d\n", *out_size);
  427. printk("TPM: response content: ");
  428. print_hex("TPM: \t", out, *out_size);
  429. }
  430. #endif
  431. memset(&reg_sts, 0, sizeof(reg_sts));
  432. reg_sts.command_ready = 1;
  433. write_tpm_reg(locality, TPM_REG_STS, &reg_sts);
  434. RelinquishControl:
  435. /* deactivate current locality */
  436. reg_acc._raw[0] = 0;
  437. reg_acc.active_locality = 1;
  438. write_tpm_reg(locality, TPM_REG_ACCESS, &reg_acc);
  439. return ret;
  440. }
  441. /*
  442. * The _tpm_submit_cmd function comes with 2 global buffers: cmd_buf & rsp_buf.
  443. * Before calling, caller should fill cmd arguements into cmd_buf via
  444. * WRAPPER_IN_BUF macro. After calling, caller should fetch result from
  445. * rsp_buffer via WRAPPER_OUT_BUF macro.
  446. * cmd_buf content:
  447. * 0 1 2 3 4 5 6 7 8 9 10 ...
  448. * -------------------------------------------------------------
  449. * | TAG | SIZE | ORDINAL | arguments ...
  450. * -------------------------------------------------------------
  451. * rsp_buf content:
  452. * 0 1 2 3 4 5 6 7 8 9 10 ...
  453. * -------------------------------------------------------------
  454. * | TAG | SIZE | RETURN CODE | other data ...
  455. * -------------------------------------------------------------
  456. *
  457. * locality : TPM locality (0 - 4)
  458. * tag : The TPM command tag
  459. * cmd : The TPM command ordinal
  460. * arg_size : Size of argument data.
  461. * out_size : IN/OUT paramter. The IN is the expected size of out data;
  462. * the OUT is the size of output data within out buffer.
  463. * The out_size MUST NOT be NULL.
  464. * return : TPM_SUCCESS for success, for other error code, refer to the .h
  465. */
  466. static uint8_t cmd_buf[TPM_CMD_SIZE_MAX];
  467. static uint8_t rsp_buf[TPM_RSP_SIZE_MAX];
  468. #define WRAPPER_IN_BUF (cmd_buf + CMD_HEAD_SIZE)
  469. #define WRAPPER_OUT_BUF (rsp_buf + RSP_HEAD_SIZE)
  470. #define WRAPPER_IN_MAX_SIZE (TPM_CMD_SIZE_MAX - CMD_HEAD_SIZE)
  471. #define WRAPPER_OUT_MAX_SIZE (TPM_RSP_SIZE_MAX - RSP_HEAD_SIZE)
  472. static uint32_t _tpm_submit_cmd(uint32_t locality, uint16_t tag, uint32_t cmd,
  473. uint32_t arg_size, uint32_t *out_size)
  474. {
  475. uint32_t ret;
  476. uint32_t cmd_size, rsp_size = 0;
  477. if ( out_size == NULL ) {
  478. printk("TPM: invalid param for _tpm_submit_cmd()\n");
  479. return TPM_BAD_PARAMETER;
  480. }
  481. /*
  482. * real cmd size should add 10 more bytes:
  483. * 2 bytes for tag
  484. * 4 bytes for size
  485. * 4 bytes for ordinal
  486. */
  487. cmd_size = CMD_HEAD_SIZE + arg_size;
  488. if ( cmd_size > TPM_CMD_SIZE_MAX ) {
  489. printk("TPM: cmd exceeds the max supported size.\n");
  490. return TPM_BAD_PARAMETER;
  491. }
  492. /* copy tag, size & ordinal into buf in a reversed byte order */
  493. reverse_copy(cmd_buf, &tag, sizeof(tag));
  494. reverse_copy(cmd_buf + CMD_SIZE_OFFSET, &cmd_size, sizeof(cmd_size));
  495. reverse_copy(cmd_buf + CMD_ORD_OFFSET, &cmd, sizeof(cmd));
  496. rsp_size = RSP_HEAD_SIZE + *out_size;
  497. rsp_size = (rsp_size > TPM_RSP_SIZE_MAX) ? TPM_RSP_SIZE_MAX: rsp_size;
  498. ret = tpm_write_cmd_fifo(locality, cmd_buf, cmd_size, rsp_buf, &rsp_size);
  499. /*
  500. * should subtract 10 bytes from real response size:
  501. * 2 bytes for tag
  502. * 4 bytes for size
  503. * 4 bytes for return code
  504. */
  505. rsp_size -= (rsp_size > RSP_HEAD_SIZE) ? RSP_HEAD_SIZE : rsp_size;
  506. if ( ret != TPM_SUCCESS )
  507. return ret;
  508. if ( *out_size == 0 || rsp_size == 0 )
  509. *out_size = 0;
  510. else
  511. *out_size = (rsp_size < *out_size) ? rsp_size : *out_size;
  512. return ret;
  513. }
  514. static inline uint32_t tpm_submit_cmd(uint32_t locality, uint32_t cmd,
  515. uint32_t arg_size, uint32_t *out_size)
  516. {
  517. return _tpm_submit_cmd(locality, TPM_TAG_RQU_COMMAND, cmd,
  518. arg_size, out_size);
  519. }
  520. static inline uint32_t tpm_submit_cmd_auth1(uint32_t locality, uint32_t cmd,
  521. uint32_t arg_size, uint32_t *out_size)
  522. {
  523. return _tpm_submit_cmd(locality, TPM_TAG_RQU_AUTH1_COMMAND, cmd,
  524. arg_size, out_size);
  525. }
  526. static inline uint32_t tpm_submit_cmd_auth2(uint32_t locality, uint32_t cmd,
  527. uint32_t arg_size, uint32_t *out_size)
  528. {
  529. return _tpm_submit_cmd(locality, TPM_TAG_RQU_AUTH2_COMMAND, cmd,
  530. arg_size, out_size);
  531. }
  532. uint32_t tpm_pcr_read(uint32_t locality, uint32_t pcr, tpm_pcr_value_t *out)
  533. {
  534. uint32_t ret, out_size = sizeof(*out);
  535. if ( out == NULL )
  536. return TPM_BAD_PARAMETER;
  537. if ( pcr >= TPM_NR_PCRS )
  538. return TPM_BAD_PARAMETER;
  539. /* copy pcr into buf in reversed byte order */
  540. reverse_copy(WRAPPER_IN_BUF, &pcr, sizeof(pcr));
  541. ret = tpm_submit_cmd(locality, TPM_ORD_PCR_READ, sizeof(pcr), &out_size);
  542. #ifdef TPM_TRACE
  543. printk("TPM: Pcr %d Read return value = %08X\n", pcr, ret);
  544. #endif
  545. if ( ret != TPM_SUCCESS ) {
  546. printk("TPM: Pcr %d Read return value = %08X\n", pcr, ret);
  547. return ret;
  548. }
  549. if ( out_size > sizeof(*out) )
  550. out_size = sizeof(*out);
  551. memcpy((void *)out, WRAPPER_OUT_BUF, out_size);
  552. #ifdef TPM_TRACE
  553. {
  554. printk("TPM: ");
  555. print_hex(NULL, out->digest, out_size);
  556. }
  557. #endif
  558. return ret;
  559. }
  560. uint32_t tpm_pcr_extend(uint32_t locality, uint32_t pcr,
  561. const tpm_digest_t* in, tpm_pcr_value_t* out)
  562. {
  563. uint32_t ret, in_size = 0, out_size;
  564. if ( in == NULL )
  565. return TPM_BAD_PARAMETER;
  566. if ( pcr >= TPM_NR_PCRS )
  567. return TPM_BAD_PARAMETER;
  568. if ( out == NULL )
  569. out_size = 0;
  570. else
  571. out_size = sizeof(*out);
  572. /* copy pcr into buf in reversed byte order, then copy in data */
  573. reverse_copy(WRAPPER_IN_BUF, &pcr, sizeof(pcr));
  574. in_size += sizeof(pcr);
  575. memcpy(WRAPPER_IN_BUF + in_size, (void *)in, sizeof(*in));
  576. in_size += sizeof(*in);
  577. ret = tpm_submit_cmd(locality, TPM_ORD_PCR_EXTEND, in_size, &out_size);
  578. #ifdef TPM_TRACE
  579. printk("TPM: Pcr %d extend, return value = %08X\n", pcr, ret);
  580. #endif
  581. if ( ret != TPM_SUCCESS ) {
  582. printk("TPM: Pcr %d extend, return value = %08X\n", pcr, ret);
  583. return ret;
  584. }
  585. if ( out != NULL && out_size > 0 ) {
  586. out_size = (out_size > sizeof(*out)) ? sizeof(*out) : out_size;
  587. memcpy((void *)out, WRAPPER_OUT_BUF, out_size);
  588. }
  589. #ifdef TPM_TRACE
  590. {
  591. printk("TPM: ");
  592. print_hex(NULL, out->digest, out_size);
  593. }
  594. #endif
  595. return ret;
  596. }
  597. typedef struct __packed {
  598. uint16_t size_of_select;
  599. uint8_t pcr_select[3];
  600. } tpm_pcr_selection_t;
  601. uint32_t tpm_pcr_reset(uint32_t locality, uint32_t pcr)
  602. {
  603. uint32_t ret, in_size, out_size = 0;
  604. uint16_t size_of_select;
  605. tpm_pcr_selection_t pcr_sel = {0,{0,}};
  606. if ( pcr >= TPM_NR_PCRS || pcr < TPM_PCR_RESETABLE_MIN )
  607. return TPM_BAD_PARAMETER;
  608. /* the pcr_sel.pcr_select[size_of_select - 1] should not be 0 */
  609. size_of_select = pcr / 8 + 1;
  610. reverse_copy(&pcr_sel.size_of_select, &size_of_select,
  611. sizeof(size_of_select));
  612. pcr_sel.pcr_select[pcr / 8] = 1 << (pcr % 8);
  613. in_size = sizeof(pcr_sel);
  614. memcpy(WRAPPER_IN_BUF, (void *)&pcr_sel, in_size);
  615. ret = tpm_submit_cmd(locality, TPM_ORD_PCR_RESET, in_size, &out_size);
  616. printk("TPM: Pcr %d reset, return value = %08X\n", pcr, ret);
  617. return ret;
  618. }
  619. uint32_t tpm_nv_read_value(uint32_t locality, tpm_nv_index_t index,
  620. uint32_t offset, uint8_t *data,
  621. uint32_t *data_size)
  622. {
  623. uint32_t ret, in_size = 0, out_size;
  624. if ( data == NULL || data_size == NULL )
  625. return TPM_BAD_PARAMETER;
  626. if ( *data_size == 0 )
  627. return TPM_BAD_PARAMETER;
  628. if ( *data_size > TPM_NV_READ_VALUE_DATA_SIZE_MAX )
  629. *data_size = TPM_NV_READ_VALUE_DATA_SIZE_MAX;
  630. /* copy the index, offset and *data_size into buf in reversed byte order */
  631. reverse_copy(WRAPPER_IN_BUF, &index, sizeof(index));
  632. in_size += sizeof(index);
  633. reverse_copy(WRAPPER_IN_BUF + in_size, &offset, sizeof(offset));
  634. in_size += sizeof(offset);
  635. reverse_copy(WRAPPER_IN_BUF + in_size, data_size, sizeof(*data_size));
  636. in_size += sizeof(*data_size);
  637. out_size = *data_size + sizeof(*data_size);
  638. ret = tpm_submit_cmd(locality, TPM_ORD_NV_READ_VALUE, in_size, &out_size);
  639. #ifdef TPM_TRACE
  640. printk("TPM: read nv index %08x from offset %08x, return value = %08X\n",
  641. index, offset, ret);
  642. #endif
  643. if ( ret != TPM_SUCCESS ) {
  644. printk("TPM: read nv index %08x offset %08x, return value = %08X\n",
  645. index, offset, ret);
  646. return ret;
  647. }
  648. #ifdef TPM_TRACE
  649. {
  650. printk("TPM: ");
  651. print_hex(NULL, WRAPPER_OUT_BUF, out_size);
  652. }
  653. #endif
  654. if ( out_size <= sizeof(*data_size) ) {
  655. *data_size = 0;
  656. return ret;
  657. }
  658. out_size -= sizeof(*data_size);
  659. reverse_copy(data_size, WRAPPER_OUT_BUF, sizeof(*data_size));
  660. *data_size = (*data_size > out_size) ? out_size : *data_size;
  661. if( *data_size > 0 )
  662. memcpy(data, WRAPPER_OUT_BUF + sizeof(*data_size), *data_size);
  663. return ret;
  664. }
  665. uint32_t tpm_nv_write_value(uint32_t locality, tpm_nv_index_t index,
  666. uint32_t offset, const uint8_t *data,
  667. uint32_t data_size)
  668. {
  669. uint32_t ret, in_size = 0, out_size = 0;
  670. if ( data == NULL )
  671. return TPM_BAD_PARAMETER;
  672. if ( data_size == 0 || data_size > TPM_NV_WRITE_VALUE_DATA_SIZE_MAX )
  673. return TPM_BAD_PARAMETER;
  674. /* copy index, offset and *data_size into buf in reversed byte order */
  675. reverse_copy(WRAPPER_IN_BUF, &index, sizeof(index));
  676. in_size += sizeof(index);
  677. reverse_copy(WRAPPER_IN_BUF + in_size, &offset, sizeof(offset));
  678. in_size += sizeof(offset);
  679. reverse_copy(WRAPPER_IN_BUF + in_size, &data_size, sizeof(data_size));
  680. in_size += sizeof(data_size);
  681. memcpy(WRAPPER_IN_BUF + in_size, data, data_size);
  682. in_size += data_size;
  683. ret = tpm_submit_cmd(locality, TPM_ORD_NV_WRITE_VALUE,
  684. in_size, &out_size);
  685. #ifdef TPM_TRACE
  686. printk("TPM: write nv %08x, offset %08x, %08x bytes, return = %08X\n",
  687. index, offset, data_size, ret);
  688. #endif
  689. if ( ret != TPM_SUCCESS )
  690. printk("TPM: write nv %08x, offset %08x, %08x bytes, return = %08X\n",
  691. index, offset, data_size, ret);
  692. return ret;
  693. }
  694. #define TPM_CAP_VERSION_VAL 0x1A
  695. typedef uint16_t tpm_structure_tag_t;
  696. typedef struct __packed {
  697. uint8_t major;
  698. uint8_t minor;
  699. uint8_t rev_major;
  700. uint8_t rev_minor;
  701. } tpm_version_t;
  702. typedef struct __packed {
  703. tpm_structure_tag_t tag;
  704. tpm_version_t version;
  705. uint16_t specLevel;
  706. uint8_t errataRev;
  707. uint8_t tpmVendorID[4];
  708. uint16_t vendorSpecificSize;
  709. uint8_t vendorSpecific[];
  710. } tpm_cap_version_info_t;
  711. /* get tpm module version */
  712. uint32_t tpm_get_version(uint8_t *major, uint8_t *minor)
  713. {
  714. uint32_t ret, in_size = 0, out_size;
  715. uint32_t cap_area = TPM_CAP_VERSION_VAL;
  716. uint32_t sub_cap_size = 0;
  717. uint32_t resp_size = 0;
  718. tpm_cap_version_info_t *cap_version;
  719. if ( major == NULL || minor == NULL )
  720. return TPM_BAD_PARAMETER;
  721. reverse_copy(WRAPPER_IN_BUF, &cap_area, sizeof(cap_area));
  722. in_size += sizeof(cap_area);
  723. reverse_copy(WRAPPER_IN_BUF+in_size, &sub_cap_size, sizeof(sub_cap_size));
  724. in_size += sizeof(sub_cap_size);
  725. out_size = sizeof(resp_size) + sizeof(tpm_cap_version_info_t);
  726. ret = tpm_submit_cmd(0, TPM_ORD_GET_CAPABILITY, in_size, &out_size);
  727. #ifdef TPM_TRACE
  728. printk("TPM: get version, return value = %08X\n", ret);
  729. #endif
  730. if ( ret != TPM_SUCCESS ) {
  731. printk("TPM: get version, return value = %08X\n", ret);
  732. return ret;
  733. }
  734. #ifdef TPM_TRACE
  735. {
  736. printk("TPM: ");
  737. print_hex(NULL, WRAPPER_OUT_BUF, out_size);
  738. }
  739. #endif
  740. reverse_copy(&resp_size, WRAPPER_OUT_BUF, sizeof(resp_size));
  741. cap_version = (tpm_cap_version_info_t *)
  742. (WRAPPER_OUT_BUF + sizeof(resp_size));
  743. *major = cap_version->version.major;
  744. *minor = cap_version->version.minor;
  745. return ret;
  746. }
  747. #define HMAC_BLOCK_SIZE 64
  748. #define HMAC_OUTPUT_SIZE 20
  749. static bool hmac(const uint8_t key[HMAC_OUTPUT_SIZE], const uint8_t *msg,
  750. uint32_t len, uint8_t md[HMAC_OUTPUT_SIZE])
  751. {
  752. uint8_t ipad[HMAC_BLOCK_SIZE], opad[HMAC_BLOCK_SIZE];
  753. uint32_t i;
  754. SHA_CTX ctx;
  755. COMPILE_TIME_ASSERT(HMAC_OUTPUT_SIZE <= HMAC_BLOCK_SIZE);
  756. for ( i = 0; i < HMAC_BLOCK_SIZE; i++ ) {
  757. ipad[i] = 0x36;
  758. opad[i] = 0x5C;
  759. }
  760. for ( i = 0; i < HMAC_OUTPUT_SIZE; i++ ) {
  761. ipad[i] ^= key[i];
  762. opad[i] ^= key[i];
  763. }
  764. SHA1_Init(&ctx);
  765. SHA1_Update(&ctx, ipad, HMAC_BLOCK_SIZE);
  766. SHA1_Update(&ctx, msg, len);
  767. SHA1_Final(md, &ctx);
  768. SHA1_Init(&ctx);
  769. SHA1_Update(&ctx, opad, HMAC_BLOCK_SIZE);
  770. SHA1_Update(&ctx, md, HMAC_OUTPUT_SIZE);
  771. SHA1_Final(md, &ctx);
  772. return true;
  773. }
  774. typedef uint16_t tpm_entity_type_t;
  775. typedef uint32_t tpm_authhandle_t;
  776. typedef struct __packed {
  777. uint8_t nonce[20];
  778. } tpm_nonce_t;
  779. #define TPM_ET_SRK 0x0004
  780. #define TPM_KH_SRK 0x40000000
  781. typedef uint32_t tpm_key_handle_t;
  782. typedef tpm_digest_t tpm_composite_hash_t;
  783. typedef struct __packed {
  784. tpm_structure_tag_t tag;
  785. tpm_locality_selection_t locality_at_creation;
  786. tpm_locality_selection_t locality_at_release;
  787. tpm_pcr_selection_t creation_pcr_selection;
  788. tpm_pcr_selection_t release_pcr_selection;
  789. tpm_composite_hash_t digest_at_creation;
  790. tpm_composite_hash_t digest_at_release;
  791. } tpm_pcr_info_long_t;
  792. typedef uint8_t tpm_authdata_t[20];
  793. typedef tpm_authdata_t tpm_encauth_t;
  794. typedef struct __packed {
  795. tpm_structure_tag_t tag;
  796. tpm_entity_type_t et;
  797. uint32_t seal_info_size;
  798. } tpm_stored_data12_header_t;
  799. typedef struct __packed {
  800. tpm_stored_data12_header_t header;
  801. uint32_t enc_data_size;
  802. uint8_t enc_data[];
  803. } tpm_stored_data12_short_t;
  804. typedef struct __packed {
  805. tpm_stored_data12_header_t header;
  806. tpm_pcr_info_long_t seal_info;
  807. uint32_t enc_data_size;
  808. uint8_t enc_data[];
  809. } tpm_stored_data12_t;
  810. #define UNLOAD_INTEGER(buf, offset, var) {\
  811. reverse_copy(buf + offset, &(var), sizeof(var));\
  812. offset += sizeof(var);\
  813. }
  814. #define UNLOAD_BLOB(buf, offset, blob, size) {\
  815. memcpy(buf + offset, blob, size);\
  816. offset += size;\
  817. }
  818. #define UNLOAD_BLOB_TYPE(buf, offset, blob) \
  819. UNLOAD_BLOB(buf, offset, blob, sizeof(*(blob)))
  820. #define UNLOAD_PCR_SELECTION(buf, offset, sel) {\
  821. UNLOAD_INTEGER(buf, offset, (sel)->size_of_select);\
  822. UNLOAD_BLOB(buf, offset, (sel)->pcr_select, (sel)->size_of_select);\
  823. }
  824. #define UNLOAD_PCR_INFO_LONG(buf, offset, info) {\
  825. UNLOAD_INTEGER(buf, offset, (info)->tag);\
  826. UNLOAD_BLOB_TYPE(buf, offset, &(info)->locality_at_creation);\
  827. UNLOAD_BLOB_TYPE(buf, offset, &(info)->locality_at_release);\
  828. UNLOAD_PCR_SELECTION(buf, offset, &(info)->creation_pcr_selection);\
  829. UNLOAD_PCR_SELECTION(buf, offset, &(info)->release_pcr_selection);\
  830. UNLOAD_BLOB_TYPE(buf, offset, &(info)->digest_at_creation);\
  831. UNLOAD_BLOB_TYPE(buf, offset, &(info)->digest_at_release);\
  832. }
  833. #define UNLOAD_STORED_DATA12(buf, offset, hdr) {\
  834. UNLOAD_INTEGER(buf, offset, ((tpm_stored_data12_header_t *)(hdr))->tag);\
  835. UNLOAD_INTEGER(buf, offset, ((tpm_stored_data12_header_t *)(hdr))->et);\
  836. UNLOAD_INTEGER(buf, offset,\
  837. ((tpm_stored_data12_header_t *)(hdr))->seal_info_size);\
  838. if ( ((tpm_stored_data12_header_t *)(hdr))->seal_info_size == 0 ) {\
  839. UNLOAD_INTEGER(buf, offset,\
  840. ((tpm_stored_data12_short_t *)hdr)->enc_data_size);\
  841. UNLOAD_BLOB(buf, offset,\
  842. ((tpm_stored_data12_short_t *)hdr)->enc_data,\
  843. ((tpm_stored_data12_short_t *)hdr)->enc_data_size);\
  844. }\
  845. else {\
  846. UNLOAD_PCR_INFO_LONG(buf, offset,\
  847. &((tpm_stored_data12_t *)hdr)->seal_info);\
  848. UNLOAD_INTEGER(buf, offset,\
  849. ((tpm_stored_data12_t *)hdr)->enc_data_size);\
  850. UNLOAD_BLOB(buf, offset,\
  851. ((tpm_stored_data12_t *)hdr)->enc_data,\
  852. ((tpm_stored_data12_t *)hdr)->enc_data_size);\
  853. }\
  854. }
  855. #define LOAD_INTEGER(buf, offset, var) {\
  856. reverse_copy(&(var), buf + offset, sizeof(var));\
  857. offset += sizeof(var);\
  858. }
  859. #define LOAD_BLOB(buf, offset, blob, size) {\
  860. memcpy(blob, buf + offset, size);\
  861. offset += size;\
  862. }
  863. #define LOAD_BLOB_TYPE(buf, offset, blob) \
  864. LOAD_BLOB(buf, offset, blob, sizeof(*(blob)))
  865. #define LOAD_PCR_SELECTION(buf, offset, sel) {\
  866. LOAD_INTEGER(buf, offset, (sel)->size_of_select);\
  867. LOAD_BLOB(buf, offset, (sel)->pcr_select, (sel)->size_of_select);\
  868. }
  869. #define LOAD_PCR_INFO_LONG(buf, offset, info) {\
  870. LOAD_INTEGER(buf, offset, (info)->tag);\
  871. LOAD_BLOB_TYPE(buf, offset, &(info)->locality_at_creation);\
  872. LOAD_BLOB_TYPE(buf, offset, &(info)->locality_at_release);\
  873. LOAD_PCR_SELECTION(buf, offset, &(info)->creation_pcr_selection);\
  874. LOAD_PCR_SELECTION(buf, offset, &(info)->release_pcr_selection);\
  875. LOAD_BLOB_TYPE(buf, offset, &(info)->digest_at_creation);\
  876. LOAD_BLOB_TYPE(buf, offset, &(info)->digest_at_release);\
  877. }
  878. #define LOAD_STORED_DATA12(buf, offset, hdr) {\
  879. LOAD_INTEGER(buf, offset, ((tpm_stored_data12_header_t *)(hdr))->tag);\
  880. LOAD_INTEGER(buf, offset, ((tpm_stored_data12_header_t *)(hdr))->et);\
  881. LOAD_INTEGER(buf, offset, \
  882. ((tpm_stored_data12_header_t *)(hdr))->seal_info_size);\
  883. if ( ((tpm_stored_data12_header_t *)(hdr))->seal_info_size == 0 ) {\
  884. LOAD_INTEGER(buf, offset,\
  885. ((tpm_stored_data12_short_t *)hdr)->enc_data_size);\
  886. LOAD_BLOB(buf, offset,\
  887. ((tpm_stored_data12_short_t *)hdr)->enc_data,\
  888. ((tpm_stored_data12_short_t *)hdr)->enc_data_size);\
  889. }\
  890. else {\
  891. LOAD_PCR_INFO_LONG(buf, offset,\
  892. &((tpm_stored_data12_t *)hdr)->seal_info);\
  893. LOAD_INTEGER(buf, offset,\
  894. ((tpm_stored_data12_t *)hdr)->enc_data_size);\
  895. LOAD_BLOB(buf, offset,\
  896. ((tpm_stored_data12_t *)hdr)->enc_data,\
  897. ((tpm_stored_data12_t *)hdr)->enc_data_size);\
  898. }\
  899. }
  900. static uint32_t tpm_oiap(uint32_t locality, tpm_authhandle_t *hauth,
  901. tpm_nonce_t *nonce_even)
  902. {
  903. uint32_t ret, offset, out_size;
  904. if ( hauth == NULL || nonce_even == NULL )
  905. return TPM_BAD_PARAMETER;
  906. offset = 0;
  907. out_size = sizeof(*hauth) + sizeof(*nonce_even);
  908. ret = tpm_submit_cmd(locality, TPM_ORD_OIAP, offset, &out_size);
  909. #ifdef TPM_TRACE
  910. printk("TPM: start OIAP, return value = %08X\n", ret);
  911. #endif
  912. if ( ret != TPM_SUCCESS ) {
  913. printk("TPM: start OIAP, return value = %08X\n", ret);
  914. return ret;
  915. }
  916. #ifdef TPM_TRACE
  917. {
  918. printk("TPM: ");
  919. print_hex(NULL, WRAPPER_OUT_BUF, out_size);
  920. }
  921. #endif
  922. offset = 0;
  923. LOAD_INTEGER(WRAPPER_OUT_BUF, offset, *hauth);
  924. LOAD_BLOB_TYPE(WRAPPER_OUT_BUF, offset, nonce_even);
  925. return ret;
  926. }
  927. static uint32_t tpm_osap(uint32_t locality, tpm_entity_type_t ent_type,
  928. uint32_t ent_value, const tpm_nonce_t *odd_osap,
  929. tpm_authhandle_t *hauth, tpm_nonce_t *nonce_even,
  930. tpm_nonce_t *even_osap)
  931. {
  932. uint32_t ret, offset, out_size;
  933. if ( odd_osap == NULL || hauth == NULL ||
  934. nonce_even == NULL || even_osap == NULL )
  935. return TPM_BAD_PARAMETER;
  936. offset = 0;
  937. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, ent_type);
  938. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, ent_value);
  939. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, odd_osap);
  940. out_size = sizeof(*hauth) + sizeof(*nonce_even) + sizeof(*even_osap);
  941. ret = tpm_submit_cmd(locality, TPM_ORD_OSAP, offset, &out_size);
  942. #ifdef TPM_TRACE
  943. printk("TPM: start OSAP, return value = %08X\n", ret);
  944. #endif
  945. if ( ret != TPM_SUCCESS ) {
  946. printk("TPM: start OSAP, return value = %08X\n", ret);
  947. return ret;
  948. }
  949. #ifdef TPM_TRACE
  950. {
  951. printk("TPM: ");
  952. print_hex(NULL, WRAPPER_OUT_BUF, out_size);
  953. }
  954. #endif
  955. offset = 0;
  956. LOAD_INTEGER(WRAPPER_OUT_BUF, offset, *hauth);
  957. LOAD_BLOB_TYPE(WRAPPER_OUT_BUF, offset, nonce_even);
  958. LOAD_BLOB_TYPE(WRAPPER_OUT_BUF, offset, even_osap);
  959. return ret;
  960. }
  961. static uint32_t _tpm_seal(uint32_t locality, tpm_key_handle_t hkey,
  962. const tpm_encauth_t *enc_auth, uint32_t pcr_info_size,
  963. const tpm_pcr_info_long_t *pcr_info, uint32_t in_data_size,
  964. const uint8_t *in_data,
  965. tpm_authhandle_t hauth, const tpm_nonce_t *nonce_odd,
  966. uint8_t *cont_session, const tpm_authdata_t *pub_auth,
  967. uint32_t *sealed_data_size, uint8_t *sealed_data,
  968. tpm_nonce_t *nonce_even, tpm_authdata_t *res_auth)
  969. {
  970. uint32_t ret, offset, out_size;
  971. if ( enc_auth == NULL || pcr_info == NULL || in_data == NULL ||
  972. nonce_odd == NULL || cont_session == NULL || pub_auth == NULL ||
  973. sealed_data_size == NULL || sealed_data == NULL ||
  974. nonce_even == NULL || res_auth == NULL ) {
  975. printk("TPM: _tpm_seal() bad parameter\n");
  976. return TPM_BAD_PARAMETER;
  977. }
  978. offset = 0;
  979. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, hkey);
  980. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, enc_auth);
  981. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, pcr_info_size);
  982. UNLOAD_PCR_INFO_LONG(WRAPPER_IN_BUF, offset, pcr_info);
  983. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, in_data_size);
  984. UNLOAD_BLOB(WRAPPER_IN_BUF, offset, in_data, in_data_size);
  985. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, hauth);
  986. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, nonce_odd);
  987. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, *cont_session);
  988. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, pub_auth);
  989. out_size = WRAPPER_OUT_MAX_SIZE;
  990. ret = tpm_submit_cmd_auth1(locality, TPM_ORD_SEAL, offset, &out_size);
  991. #ifdef TPM_TRACE
  992. printk("TPM: seal data, return value = %08X\n", ret);
  993. #endif
  994. if ( ret != TPM_SUCCESS ) {
  995. printk("TPM: seal data, return value = %08X\n", ret);
  996. return ret;
  997. }
  998. #ifdef TPM_TRACE
  999. {
  1000. printk("TPM: ");
  1001. print_hex(NULL, WRAPPER_OUT_BUF, out_size);
  1002. }
  1003. #endif
  1004. if ( *sealed_data_size <
  1005. ( out_size - sizeof(*nonce_even) - sizeof(*cont_session)
  1006. - sizeof(*res_auth) ) ) {
  1007. printk("TPM: sealed blob is too small\n");
  1008. return TPM_NOSPACE;
  1009. }
  1010. offset = 0;
  1011. LOAD_STORED_DATA12(WRAPPER_OUT_BUF, offset, sealed_data);
  1012. *sealed_data_size = offset;
  1013. LOAD_BLOB_TYPE(WRAPPER_OUT_BUF, offset, nonce_even);
  1014. LOAD_INTEGER(WRAPPER_OUT_BUF, offset, *cont_session);
  1015. LOAD_BLOB_TYPE(WRAPPER_OUT_BUF, offset, res_auth);
  1016. return ret;
  1017. }
  1018. static uint32_t _tpm_unseal(uint32_t locality, tpm_key_handle_t hkey,
  1019. const uint8_t *in_data,
  1020. tpm_authhandle_t hauth, const tpm_nonce_t *nonce_odd,
  1021. uint8_t *cont_session, const tpm_authdata_t *auth,
  1022. tpm_authhandle_t hauth_d, const tpm_nonce_t *nonce_odd_d,
  1023. uint8_t *cont_session_d, const tpm_authdata_t *auth_d,
  1024. uint32_t *secret_size, uint8_t *secret,
  1025. tpm_nonce_t *nonce_even, tpm_authdata_t *res_auth,
  1026. tpm_nonce_t *nonce_even_d, tpm_authdata_t *res_auth_d)
  1027. {
  1028. uint32_t ret, offset, out_size;
  1029. if ( in_data == NULL || nonce_odd == NULL || cont_session == NULL ||
  1030. auth == NULL || nonce_odd_d == NULL || cont_session_d == NULL ||
  1031. auth_d == NULL || secret_size == NULL || secret == NULL ||
  1032. nonce_even == NULL || res_auth == NULL || nonce_even_d == NULL ||
  1033. res_auth_d == NULL ) {
  1034. printk("TPM: _tpm_unseal() bad parameter\n");
  1035. return TPM_BAD_PARAMETER;
  1036. }
  1037. offset = 0;
  1038. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, hkey);
  1039. UNLOAD_STORED_DATA12(WRAPPER_IN_BUF, offset, in_data);
  1040. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, hauth);
  1041. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, nonce_odd);
  1042. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, *cont_session);
  1043. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, auth);
  1044. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, hauth_d);
  1045. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, nonce_odd_d);
  1046. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, *cont_session_d);
  1047. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, auth_d);
  1048. out_size = WRAPPER_OUT_MAX_SIZE;
  1049. ret = tpm_submit_cmd_auth2(locality, TPM_ORD_UNSEAL, offset, &out_size);
  1050. #ifdef TPM_TRACE
  1051. printk("TPM: unseal data, return value = %08X\n", ret);
  1052. #endif
  1053. if ( ret != TPM_SUCCESS ) {
  1054. printk("TPM: unseal data, return value = %08X\n", ret);
  1055. return ret;
  1056. }
  1057. #ifdef TPM_TRACE
  1058. {
  1059. printk("TPM: ");
  1060. print_hex(NULL, WRAPPER_OUT_BUF, out_size);
  1061. }
  1062. #endif
  1063. if ( *secret_size <
  1064. ( out_size - sizeof(*secret_size) - sizeof(*nonce_even)
  1065. - sizeof(*cont_session) - sizeof(*res_auth) - sizeof(*nonce_even_d)
  1066. - sizeof(*cont_session_d) - sizeof(*res_auth_d) ) ) {
  1067. printk("TPM: unsealed data too small\n");
  1068. return TPM_NOSPACE;
  1069. }
  1070. offset = 0;
  1071. LOAD_INTEGER(WRAPPER_OUT_BUF, offset, *secret_size);
  1072. LOAD_BLOB(WRAPPER_OUT_BUF, offset, secret, *secret_size);
  1073. LOAD_BLOB_TYPE(WRAPPER_OUT_BUF, offset, nonce_even);
  1074. LOAD_INTEGER(WRAPPER_OUT_BUF, offset, *cont_session);
  1075. LOAD_BLOB_TYPE(WRAPPER_OUT_BUF, offset, res_auth);
  1076. LOAD_BLOB_TYPE(WRAPPER_OUT_BUF, offset, nonce_even_d);
  1077. LOAD_INTEGER(WRAPPER_OUT_BUF, offset, *cont_session_d);
  1078. LOAD_BLOB_TYPE(WRAPPER_OUT_BUF, offset, res_auth_d);
  1079. return ret;
  1080. }
  1081. #define XOR_BLOB_TYPE(data, pad) {\
  1082. for ( uint32_t i = 0; i < sizeof(*(data)); i++ ) \
  1083. ((uint8_t *)data)[i] ^= ((uint8_t *)pad)[i % sizeof(*(pad))];\
  1084. }
  1085. static const tpm_authdata_t srk_authdata =
  1086. {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  1087. static const tpm_authdata_t blob_authdata =
  1088. {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  1089. static uint32_t _tpm_wrap_seal(uint32_t locality,
  1090. const tpm_pcr_info_long_t *pcr_info,
  1091. uint32_t in_data_size, const uint8_t *in_data,
  1092. uint32_t *sealed_data_size, uint8_t *sealed_data)
  1093. {
  1094. uint32_t ret;
  1095. tpm_nonce_t odd_osap, even_osap, nonce_even, nonce_odd;
  1096. tpm_authhandle_t hauth;
  1097. tpm_authdata_t shared_secret, pub_auth, res_auth;
  1098. tpm_encauth_t enc_auth;
  1099. uint8_t cont_session = false;
  1100. tpm_key_handle_t hkey = TPM_KH_SRK;
  1101. uint32_t pcr_info_size = sizeof(*pcr_info);
  1102. uint32_t offset;
  1103. uint32_t ordinal = TPM_ORD_SEAL;
  1104. tpm_digest_t digest;
  1105. /* skip generate nonce for odd_osap, just use the random value in stack */
  1106. /* establish a osap session */
  1107. ret = tpm_osap(locality, TPM_ET_SRK, TPM_KH_SRK, &odd_osap, &hauth,
  1108. &nonce_even, &even_osap);
  1109. if ( ret != TPM_SUCCESS )
  1110. return ret;
  1111. /* calculate the shared secret
  1112. shared-secret = HMAC(srk_auth, even_osap || odd_osap) */
  1113. offset = 0;
  1114. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &even_osap);
  1115. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &odd_osap);
  1116. hmac((uint8_t *)&srk_authdata, WRAPPER_IN_BUF, offset,
  1117. (uint8_t *)&shared_secret);
  1118. /* generate ecrypted authdata for data
  1119. enc_auth = XOR(authdata, sha1(shared_secret || last_even_nonce)) */
  1120. offset = 0;
  1121. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &shared_secret);
  1122. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_even);
  1123. sha1_buffer(WRAPPER_IN_BUF, offset, (uint8_t *)&digest);
  1124. memcpy(&enc_auth, &blob_authdata, sizeof(blob_authdata));
  1125. XOR_BLOB_TYPE(&enc_auth, &digest);
  1126. /* skip generate nonce for nonce_odd, just use the random value in stack */
  1127. /* calculate authdata */
  1128. /* in_param_digest = sha1(1S ~ 6S) */
  1129. offset = 0;
  1130. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, ordinal);
  1131. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &enc_auth);
  1132. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, pcr_info_size);
  1133. UNLOAD_PCR_INFO_LONG(WRAPPER_IN_BUF, offset, pcr_info);
  1134. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, in_data_size);
  1135. UNLOAD_BLOB(WRAPPER_IN_BUF, offset, in_data, in_data_size);
  1136. sha1_buffer(WRAPPER_IN_BUF, offset, (uint8_t *)&digest);
  1137. /* authdata = hmac(key, in_param_digest || auth_params) */
  1138. offset = 0;
  1139. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &digest);
  1140. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_even);
  1141. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_odd);
  1142. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, cont_session);
  1143. hmac((uint8_t *)&shared_secret, WRAPPER_IN_BUF, offset,
  1144. (uint8_t *)&pub_auth);
  1145. /* call the simple seal function */
  1146. ret = _tpm_seal(locality, hkey, (const tpm_encauth_t *)&enc_auth,
  1147. pcr_info_size, pcr_info, in_data_size, in_data,
  1148. hauth, &nonce_odd, &cont_session,
  1149. (const tpm_authdata_t *)&pub_auth,
  1150. sealed_data_size, sealed_data,
  1151. &nonce_even, &res_auth);
  1152. /* skip check for res_auth */
  1153. return ret;
  1154. }
  1155. static uint32_t _tpm_wrap_unseal(uint32_t locality, const uint8_t *in_data,
  1156. uint32_t *secret_size, uint8_t *secret)
  1157. {
  1158. uint32_t ret;
  1159. tpm_nonce_t odd_osap, even_osap;
  1160. tpm_nonce_t nonce_even, nonce_odd, nonce_even_d, nonce_odd_d;
  1161. tpm_authhandle_t hauth, hauth_d;
  1162. tpm_authdata_t shared_secret;
  1163. tpm_authdata_t pub_auth, res_auth, pub_auth_d, res_auth_d;
  1164. uint8_t cont_session = false, cont_session_d = false;
  1165. tpm_key_handle_t hkey = TPM_KH_SRK;
  1166. uint32_t offset;
  1167. uint32_t ordinal = TPM_ORD_UNSEAL;
  1168. tpm_digest_t digest;
  1169. /* skip generate nonce for odd_osap, just use the random value in stack */
  1170. /* establish a osap session */
  1171. ret = tpm_osap(locality, TPM_ET_SRK, TPM_KH_SRK, &odd_osap, &hauth,
  1172. &nonce_even, &even_osap);
  1173. if ( ret != TPM_SUCCESS )
  1174. return ret;
  1175. /* calculate the shared secret
  1176. shared-secret = HMAC(auth, even_osap || odd_osap) */
  1177. offset = 0;
  1178. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &even_osap);
  1179. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &odd_osap);
  1180. hmac((uint8_t *)&srk_authdata, WRAPPER_IN_BUF, offset,
  1181. (uint8_t *)&shared_secret);
  1182. /* establish a oiap session */
  1183. ret = tpm_oiap(locality, &hauth_d, &nonce_even_d);
  1184. if ( ret != TPM_SUCCESS )
  1185. return ret;
  1186. /* skip generate nonce_odd & nonce_odd_d, just use the random values */
  1187. /* calculate authdata */
  1188. /* in_param_digest = sha1(1S ~ 6S) */
  1189. offset = 0;
  1190. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, ordinal);
  1191. UNLOAD_STORED_DATA12(WRAPPER_IN_BUF, offset, in_data);
  1192. sha1_buffer(WRAPPER_IN_BUF, offset, (uint8_t *)&digest);
  1193. /* authdata1 = hmac(key, in_param_digest || auth_params1) */
  1194. offset = 0;
  1195. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &digest);
  1196. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_even);
  1197. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_odd);
  1198. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, cont_session);
  1199. hmac((uint8_t *)&shared_secret, WRAPPER_IN_BUF, offset,
  1200. (uint8_t *)&pub_auth);
  1201. /* authdata2 = hmac(key, in_param_digest || auth_params2) */
  1202. offset = 0;
  1203. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &digest);
  1204. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_even_d);
  1205. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_odd_d);
  1206. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, cont_session_d);
  1207. hmac((uint8_t *)&blob_authdata, WRAPPER_IN_BUF, offset,
  1208. (uint8_t *)&pub_auth_d);
  1209. /* call the simple seal function */
  1210. ret = _tpm_unseal(locality, hkey, in_data,
  1211. hauth, &nonce_odd, &cont_session,
  1212. (const tpm_authdata_t *)&pub_auth,
  1213. hauth_d, &nonce_odd_d, &cont_session_d,
  1214. (const tpm_authdata_t *)&pub_auth_d,
  1215. secret_size, secret,
  1216. &nonce_even, &res_auth, &nonce_even_d, &res_auth_d);
  1217. /* skip check for res_auth */
  1218. return ret;
  1219. }
  1220. static bool init_pcr_info(uint32_t locality,
  1221. tpm_locality_selection_t release_locs,
  1222. uint32_t nr_create, const uint8_t indcs_create[],
  1223. uint32_t nr_release, const uint8_t indcs_release[],
  1224. const tpm_pcr_value_t *values_release[],
  1225. tpm_pcr_info_long_t *pcr_info)
  1226. {
  1227. uint32_t offset;
  1228. uint32_t i, blob_size;
  1229. static tpm_locality_selection_t localities[TPM_NR_LOCALITIES] = {
  1230. TPM_LOC_ZERO, TPM_LOC_ONE, TPM_LOC_TWO, TPM_LOC_THREE, TPM_LOC_FOUR
  1231. };
  1232. if ( (release_locs & TPM_LOC_RSVD) != 0 )
  1233. return TPM_BAD_PARAMETER;
  1234. if ( pcr_info == NULL )
  1235. return TPM_BAD_PARAMETER;
  1236. if ( locality >= TPM_NR_LOCALITIES )
  1237. return TPM_BAD_PARAMETER;
  1238. if ( indcs_create == NULL )
  1239. nr_create = 0;
  1240. if ( indcs_release == NULL || values_release == NULL )
  1241. nr_release = 0;
  1242. for ( i = 0; i < nr_create; i++ )
  1243. if ( indcs_create[i] >= TPM_NR_PCRS )
  1244. return TPM_BAD_PARAMETER;
  1245. for ( i = 0; i < nr_release; i++ ) {
  1246. if ( indcs_release[i] >= TPM_NR_PCRS || values_release[i] == NULL )
  1247. return TPM_BAD_PARAMETER;
  1248. }
  1249. memset(pcr_info, 0, sizeof(*pcr_info));
  1250. pcr_info->tag = TPM_TAG_PCR_INFO_LONG;
  1251. pcr_info->locality_at_creation = localities[locality];
  1252. pcr_info->locality_at_release = release_locs;
  1253. pcr_info->creation_pcr_selection.size_of_select = 3;
  1254. for ( i = 0; i < nr_create; i++ )
  1255. pcr_info->creation_pcr_selection.pcr_select[indcs_create[i]/8] |=
  1256. 1 << (indcs_create[i] % 8);
  1257. pcr_info->release_pcr_selection.size_of_select = 3;
  1258. for ( i = 0; i < nr_release; i++ )
  1259. pcr_info->release_pcr_selection.pcr_select[indcs_release[i]/8] |=
  1260. 1 << (indcs_release[i] % 8);
  1261. if ( nr_release > 0 ) {
  1262. offset = 0;
  1263. UNLOAD_PCR_SELECTION(WRAPPER_IN_BUF, offset,
  1264. &pcr_info->release_pcr_selection);
  1265. blob_size = sizeof(tpm_pcr_value_t) * nr_release;
  1266. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, blob_size);
  1267. for ( i = 0; i < nr_release; i++ )
  1268. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, values_release[i]);
  1269. sha1_buffer(WRAPPER_IN_BUF, offset,
  1270. (uint8_t *)&pcr_info->digest_at_release);
  1271. }
  1272. return true;
  1273. }
  1274. uint32_t tpm_seal(uint32_t locality, tpm_locality_selection_t release_locs,
  1275. uint32_t pcr_nr_create, const uint8_t pcr_indcs_create[],
  1276. uint32_t pcr_nr_release, const uint8_t pcr_indcs_release[],
  1277. const tpm_pcr_value_t *pcr_values_release[],
  1278. uint32_t in_data_size, const uint8_t *in_data,
  1279. uint32_t *sealed_data_size, uint8_t *sealed_data)
  1280. {
  1281. uint32_t ret;
  1282. tpm_pcr_info_long_t pcr_info;
  1283. if ( locality >= TPM_NR_LOCALITIES ||
  1284. in_data_size == 0 || in_data == NULL ||
  1285. sealed_data_size == NULL || sealed_data == NULL ||
  1286. *sealed_data_size == 0 ) {
  1287. printk("TPM: tpm_seal() bad parameter\n");
  1288. return TPM_BAD_PARAMETER;
  1289. }
  1290. if ( !init_pcr_info(locality, release_locs, pcr_nr_create,
  1291. pcr_indcs_create, pcr_nr_release, pcr_indcs_release,
  1292. pcr_values_release, &pcr_info) ) {
  1293. printk("TPM: tpm_seal() bad parameter\n");
  1294. return TPM_BAD_PARAMETER;
  1295. }
  1296. ret = _tpm_wrap_seal(locality, &pcr_info, in_data_size, in_data,
  1297. sealed_data_size, sealed_data);
  1298. return ret;
  1299. }
  1300. static bool check_sealed_data(uint32_t size, const uint8_t *data)
  1301. {
  1302. if ( size < sizeof(tpm_stored_data12_header_t) )
  1303. return false;
  1304. if ( ((tpm_stored_data12_header_t *)data)->tag != TPM_TAG_STORED_DATA12 )
  1305. return false;
  1306. if ( ((tpm_stored_data12_header_t *)data)->seal_info_size == 0 ) {
  1307. tpm_stored_data12_short_t *data12_s;
  1308. if ( size < sizeof(*data12_s) )
  1309. return false;
  1310. data12_s = (tpm_stored_data12_short_t *)data;
  1311. if ( size != sizeof(*data12_s) + data12_s->enc_data_size )
  1312. return false;
  1313. }
  1314. else {
  1315. tpm_stored_data12_t *data12;
  1316. if ( size < sizeof(*data12) )
  1317. return false;
  1318. data12 = (tpm_stored_data12_t *)data;
  1319. if ( size != sizeof(*data12) + data12->enc_data_size )
  1320. return false;
  1321. }
  1322. return true;
  1323. }
  1324. uint32_t tpm_unseal(uint32_t locality,
  1325. uint32_t sealed_data_size, const uint8_t *sealed_data,
  1326. uint32_t *secret_size, uint8_t *secret)
  1327. {
  1328. uint32_t ret;
  1329. if ( sealed_data == NULL ||
  1330. secret_size == NULL || secret == NULL ) {
  1331. printk("TPM: tpm_unseal() bad parameter\n");
  1332. return TPM_BAD_PARAMETER;
  1333. }
  1334. if ( !check_sealed_data(sealed_data_size, sealed_data) ) {
  1335. printk("TPM: tpm_unseal() blob invalid\n");
  1336. return TPM_BAD_PARAMETER;
  1337. }
  1338. ret = _tpm_wrap_unseal(locality, sealed_data, secret_size, secret);
  1339. return ret;
  1340. }
  1341. static void calc_pcr_composition(uint32_t nr, const uint8_t indcs[],
  1342. const tpm_pcr_value_t *values[],
  1343. tpm_composite_hash_t *composite)
  1344. {
  1345. uint32_t i, offset, blob_size;
  1346. tpm_pcr_selection_t sel;
  1347. if ( nr == 0 || indcs == NULL || values == NULL || composite == NULL)
  1348. return;
  1349. sel.size_of_select = 3;
  1350. sel.pcr_select[0] = sel.pcr_select[1] = sel.pcr_select[2] = 0;
  1351. for ( i = 0; i < nr; i++ )
  1352. sel.pcr_select[indcs[i]/8] |= 1 << (indcs[i] % 8);
  1353. offset = 0;
  1354. UNLOAD_PCR_SELECTION(WRAPPER_IN_BUF, offset, &sel);
  1355. blob_size = sizeof(tpm_pcr_value_t) * nr;
  1356. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, blob_size);
  1357. for ( i = 0; i < nr; i++ )
  1358. UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, values[i]);
  1359. sha1_buffer(WRAPPER_IN_BUF, offset, (uint8_t *)composite);
  1360. }
  1361. static tpm_composite_hash_t *get_cre_pcr_composite(uint8_t *data)
  1362. {
  1363. if ( ((tpm_stored_data12_header_t *)data)->seal_info_size == 0 )
  1364. return NULL;
  1365. else
  1366. return &((tpm_stored_data12_t *)data)->seal_info.digest_at_creation;
  1367. }
  1368. bool tpm_cmp_creation_pcrs(uint32_t pcr_nr_create,
  1369. const uint8_t pcr_indcs_create[],
  1370. const tpm_pcr_value_t *pcr_values_create[],
  1371. uint32_t sealed_data_size, uint8_t *sealed_data)
  1372. {
  1373. uint32_t i;
  1374. tpm_composite_hash_t composite = {{0,}}, *cre_composite;
  1375. if ( pcr_indcs_create == NULL )
  1376. pcr_nr_create = 0;
  1377. for ( i = 0; i < pcr_nr_create; i++ ) {
  1378. if ( pcr_indcs_create[i] >= TPM_NR_PCRS )
  1379. return false;
  1380. }
  1381. if ( !check_sealed_data(sealed_data_size, sealed_data) ) {
  1382. printk("TPM: Bad blob.\n");
  1383. return false;
  1384. }
  1385. if ( pcr_nr_create > 0 )
  1386. calc_pcr_composition(pcr_nr_create, pcr_indcs_create,
  1387. pcr_values_create, &composite);
  1388. cre_composite = get_cre_pcr_composite(sealed_data);
  1389. if ( cre_composite == NULL )
  1390. return false;
  1391. if ( memcmp(&composite, cre_composite, sizeof(composite)) ) {
  1392. printk("TPM: Not equal to creation composition:\n");
  1393. print_hex(NULL, (uint8_t *)&composite, sizeof(composite));
  1394. print_hex(NULL, (uint8_t *)cre_composite, sizeof(composite));
  1395. return false;
  1396. }
  1397. return true;
  1398. }
  1399. typedef uint32_t tpm_capability_area_t;
  1400. #define TPM_CAP_NV_INDEX 0x00000011
  1401. static uint32_t tpm_get_capability(
  1402. uint32_t locality, tpm_capability_area_t cap_area,
  1403. uint32_t sub_cap_size, const uint8_t *sub_cap,
  1404. uint32_t *resp_size, uint8_t *resp)
  1405. {
  1406. uint32_t ret, offset, out_size;
  1407. if ( sub_cap == NULL || resp_size == NULL || resp == NULL ) {
  1408. printk("TPM: tpm_get_capability() bad parameter\n");
  1409. return TPM_BAD_PARAMETER;
  1410. }
  1411. offset = 0;
  1412. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, cap_area);
  1413. UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, sub_cap_size);
  1414. UNLOAD_BLOB(WRAPPER_IN_BUF, offset, sub_cap, sub_cap_size);
  1415. out_size = sizeof(*resp_size) + *resp_size;
  1416. ret = tpm_submit_cmd(locality, TPM_ORD_GET_CAPABILITY, offset, &out_size);
  1417. #ifdef TPM_TRACE
  1418. printk("TPM: get capability, return value = %08X\n", ret);
  1419. #endif
  1420. if ( ret != TPM_SUCCESS ) {
  1421. printk("TPM: get capability, return value = %08X\n", ret);
  1422. return ret;
  1423. }
  1424. offset = 0;
  1425. LOAD_INTEGER(WRAPPER_OUT_BUF, offset, *resp_size);
  1426. if ( out_size < sizeof(*resp_size) + *resp_size ) {
  1427. printk("TPM: capability response too small\n");
  1428. return TPM_FAIL;
  1429. }
  1430. LOAD_BLOB(WRAPPER_OUT_BUF, offset, resp, *resp_size);
  1431. return ret;
  1432. }
  1433. typedef struct __packed {
  1434. tpm_pcr_selection_t pcr_selection;
  1435. tpm_locality_selection_t locality_at_release;
  1436. tpm_composite_hash_t digest_at_release;
  1437. } tpm_pcr_info_short_t;
  1438. typedef struct __packed {
  1439. tpm_structure_tag_t tag;
  1440. uint32_t attributes;
  1441. } tpm_nv_attributes_t;
  1442. typedef struct __packed {
  1443. tpm_structure_tag_t tag;
  1444. tpm_nv_index_t nv_index;
  1445. tpm_pcr_info_short_t pcr_info_read;
  1446. tpm_pcr_info_short_t pcr_info_write;
  1447. tpm_nv_attributes_t permission;
  1448. uint8_t b_read_st_clear;
  1449. uint8_t b_write_st_clear;
  1450. uint8_t b_write_define;
  1451. uint32_t data_size;
  1452. } tpm_nv_data_public_t;
  1453. uint32_t tpm_get_nvindex_size(uint32_t locality,
  1454. tpm_nv_index_t index, uint32_t *size)
  1455. {
  1456. uint32_t ret, offset, resp_size;
  1457. uint8_t sub_cap[sizeof(index)];
  1458. uint8_t resp[sizeof(tpm_nv_data_public_t)];
  1459. tpm_nv_index_t idx;
  1460. if ( size == NULL ) {
  1461. printk("TPM: tpm_get_nvindex_size() bad parameter\n");
  1462. return TPM_BAD_PARAMETER;
  1463. }
  1464. offset = 0;
  1465. UNLOAD_INTEGER(sub_cap, offset, index);
  1466. resp_size = sizeof(resp);
  1467. ret = tpm_get_capability(locality, TPM_CAP_NV_INDEX, sizeof(sub_cap),
  1468. sub_cap, &resp_size, resp);
  1469. #ifdef TPM_TRACE
  1470. printk("TPM: get nvindex size, return value = %08X\n", ret);
  1471. #endif
  1472. if ( ret != TPM_SUCCESS ) {
  1473. printk("TPM: fail to get public data of 0x%08X in TPM NV\n", index);
  1474. return ret;
  1475. }
  1476. #ifdef TPM_TRACE
  1477. {
  1478. printk("TPM: ");
  1479. print_hex(NULL, resp, resp_size);
  1480. }
  1481. #endif
  1482. /* check size */
  1483. if ( resp_size == 0 ) {
  1484. printk("TPM: Index 0x%08X does not exist\n", index);
  1485. return TPM_BADINDEX;
  1486. }
  1487. /* check index */
  1488. offset = sizeof(tpm_structure_tag_t);
  1489. LOAD_INTEGER(resp, offset, idx);
  1490. #ifdef TPM_TRACE
  1491. printk("TPM: get index value = %08X\n", idx);
  1492. #endif
  1493. if ( idx != index ) {
  1494. printk("TPM: Index 0x%08X is not the one expected 0x%08X\n",
  1495. idx, index);
  1496. return TPM_BADINDEX;
  1497. }
  1498. if ( resp_size != sizeof(resp) ) {
  1499. printk("TPM: public data size of Index 0x%08X responsed incorrect\n",
  1500. index);
  1501. return TPM_FAIL;
  1502. }
  1503. offset = resp_size - sizeof(uint32_t);
  1504. LOAD_INTEGER(resp, offset, *size);
  1505. return ret;
  1506. }
  1507. typedef struct __packed {
  1508. tpm_structure_tag_t tag;
  1509. uint8_t disable;
  1510. uint8_t ownership;
  1511. uint8_t deactivated;
  1512. uint8_t read_pubek;
  1513. uint8_t disable_owner_clear;
  1514. uint8_t allow_maintenance;
  1515. uint8_t physical_presence_lifetime_lock;
  1516. uint8_t physical_presence_hw_enable;
  1517. uint8_t physical_presence_cmd_enable;
  1518. uint8_t cekp_used;
  1519. uint8_t tpm_post;
  1520. uint8_t tpm_post_lock;
  1521. uint8_t fips;
  1522. uint8_t operator;
  1523. uint8_t enable_revoke_ek;
  1524. uint8_t nv_locked;
  1525. uint8_t read_srk_pub;
  1526. uint8_t tpm_established;
  1527. uint8_t maintenance_done;
  1528. uint8_t disable_full_da_logic_info;
  1529. } tpm_permanent_flags_t;
  1530. typedef struct __packed {
  1531. tpm_structure_tag_t tag;
  1532. uint8_t deactivated;
  1533. uint8_t disable_force_clear;
  1534. uint8_t physical_presence;
  1535. uint8_t phycical_presence_lock;
  1536. uint8_t b_global_lock;
  1537. } tpm_stclear_flags_t;
  1538. #define TPM_CAP_FLAG 0x00000004
  1539. #define TPM_CAP_FLAG_PERMANENT 0x00000108
  1540. #define TPM_CAP_FLAG_VOLATILE 0x00000109
  1541. static uint32_t tpm_get_flags(uint32_t locality, uint32_t flag_id,
  1542. uint8_t *flags, uint32_t flag_size)
  1543. {
  1544. uint32_t ret, offset, resp_size;
  1545. uint8_t sub_cap[sizeof(flag_id)];
  1546. tpm_structure_tag_t tag;
  1547. if ( flags == NULL ) {
  1548. printk("TPM: tpm_get_flags() bad parameter\n");
  1549. return TPM_BAD_PARAMETER;
  1550. }
  1551. offset = 0;
  1552. UNLOAD_INTEGER(sub_cap, offset, flag_id);
  1553. resp_size = flag_size;
  1554. ret = tpm_get_capability(locality, TPM_CAP_FLAG, sizeof(sub_cap),
  1555. sub_cap, &resp_size, flags);
  1556. #ifdef TPM_TRACE
  1557. printk("TPM: get flags %08X, return value = %08X\n", flag_id, ret);
  1558. #endif
  1559. if ( ret != TPM_SUCCESS )
  1560. return ret;
  1561. /* 1.2 spec, main part 2, rev 103 add one more byte to permanent flags, to
  1562. be backward compatible, not assume all expected bytes can be gotten */
  1563. if ( resp_size > flag_size ) {
  1564. printk("TPM: tpm_get_flags() response size too small\n");
  1565. return TPM_FAIL;
  1566. }
  1567. offset = 0;
  1568. LOAD_INTEGER(flags, offset, tag);
  1569. offset = 0;
  1570. UNLOAD_BLOB_TYPE(flags, offset, &tag);
  1571. return ret;
  1572. }
  1573. #define TPM_CAP_PROPERTY 0x00000005
  1574. #define TPM_CAP_PROP_TIS_TIMEOUT 0x00000115
  1575. static uint32_t tpm_get_timeout(uint32_t locality,
  1576. uint8_t *prop, uint32_t prop_size)
  1577. {
  1578. uint32_t ret, offset, resp_size, prop_id = TPM_CAP_PROP_TIS_TIMEOUT;
  1579. uint8_t sub_cap[sizeof(prop_id)];
  1580. uint32_t resp[4];
  1581. if ( (prop == NULL) || (prop_size < sizeof(resp)) ) {
  1582. printk("TPM: tpm_get_timeout() bad parameter\n");
  1583. return TPM_BAD_PARAMETER;
  1584. }
  1585. offset = 0;
  1586. UNLOAD_INTEGER(sub_cap, offset, prop_id);
  1587. resp_size = prop_size;
  1588. ret = tpm_get_capability(locality, TPM_CAP_PROPERTY, sizeof(sub_cap),
  1589. sub_cap, &resp_size, prop);
  1590. #ifdef TPM_TRACE
  1591. printk("TPM: get prop %08X, return value = %08X\n", prop_id, ret);
  1592. #endif
  1593. if ( ret != TPM_SUCCESS )
  1594. return ret;
  1595. if ( resp_size != prop_size ) {
  1596. printk("TPM: tpm_get_property() response size incorrect\n");
  1597. return TPM_FAIL;
  1598. }
  1599. offset = 0;
  1600. LOAD_INTEGER(prop, offset, resp);
  1601. offset = 0;
  1602. UNLOAD_BLOB_TYPE(prop, offset, &resp);
  1603. return ret;
  1604. }
  1605. bool release_locality(uint32_t locality)
  1606. {
  1607. uint32_t i;
  1608. #ifdef TPM_TRACE
  1609. printk("TPM: releasing locality %u\n", locality);
  1610. #endif
  1611. if ( !tpm_validate_locality(locality) )
  1612. return true;
  1613. tpm_reg_access_t reg_acc;
  1614. read_tpm_reg(locality, TPM_REG_ACCESS, &reg_acc);
  1615. if ( reg_acc.active_locality == 0 )
  1616. return true;
  1617. /* make inactive by writing a 1 */
  1618. reg_acc._raw[0] = 0;
  1619. reg_acc.active_locality = 1;
  1620. write_tpm_reg(locality, TPM_REG_ACCESS, &reg_acc);
  1621. i = 0;
  1622. do {
  1623. read_tpm_reg(locality, TPM_REG_ACCESS, &reg_acc);
  1624. if ( reg_acc.active_locality == 0 )
  1625. return true;
  1626. else
  1627. cpu_relax();
  1628. i++;
  1629. } while ( i <= TPM_ACTIVE_LOCALITY_TIME_OUT );
  1630. printk("TPM: access reg release locality timeout\n");
  1631. return false;
  1632. }
  1633. bool prepare_tpm(void)
  1634. {
  1635. /*
  1636. * must ensure TPM_ACCESS_0.activeLocality bit is clear
  1637. * (: locality is not active)
  1638. */
  1639. return release_locality(0);
  1640. }
  1641. /* ensure TPM is ready to accept commands */
  1642. bool is_tpm_ready(uint32_t locality)
  1643. {
  1644. tpm_permanent_flags_t pflags;
  1645. tpm_stclear_flags_t vflags;
  1646. uint32_t timeout[4];
  1647. uint32_t ret;
  1648. if ( !tpm_validate_locality(locality) ) {
  1649. printk("TPM is not available.\n");
  1650. return false;
  1651. }
  1652. /* make sure tpm is not disabled/deactivated */
  1653. memset(&pflags, 0, sizeof(pflags));
  1654. ret = tpm_get_flags(locality, TPM_CAP_FLAG_PERMANENT,
  1655. (uint8_t *)&pflags, sizeof(pflags));
  1656. if ( ret != TPM_SUCCESS ) {
  1657. printk("TPM is disabled or deactivated.\n");
  1658. return false;
  1659. }
  1660. if ( pflags.disable ) {
  1661. printk("TPM is disabled.\n");
  1662. return false;
  1663. }
  1664. memset(&vflags, 0, sizeof(vflags));
  1665. ret = tpm_get_flags(locality, TPM_CAP_FLAG_VOLATILE,
  1666. (uint8_t *)&vflags, sizeof(vflags));
  1667. if ( ret != TPM_SUCCESS ) {
  1668. printk("TPM is disabled or deactivated.\n");
  1669. return false;
  1670. }
  1671. if ( vflags.deactivated ) {
  1672. printk("TPM is deactivated.\n");
  1673. return false;
  1674. }
  1675. printk("TPM is ready\n");
  1676. printk("TPM nv_locked: %s\n", (pflags.nv_locked != 0) ? "TRUE" : "FALSE");
  1677. /* get tpm timeout values */
  1678. ret = tpm_get_timeout(locality, (uint8_t *)&timeout, sizeof(timeout));
  1679. if ( ret != TPM_SUCCESS )
  1680. printk("TPM timeout values are not achieved, "
  1681. "default values will be used.\n");
  1682. else {
  1683. /*
  1684. * timeout_x represents the number of milliseconds for the timeout
  1685. * and timeout[x] represents the number of microseconds.
  1686. */
  1687. g_timeout.timeout_a = timeout[0]/1000;
  1688. g_timeout.timeout_b = timeout[1]/1000;
  1689. g_timeout.timeout_c = timeout[2]/1000;
  1690. g_timeout.timeout_d = timeout[3]/1000;
  1691. printk("TPM timeout values: A: %u, B: %u, C: %u, D: %u\n",
  1692. g_timeout.timeout_a, g_timeout.timeout_b, g_timeout.timeout_c,
  1693. g_timeout.timeout_d);
  1694. /*
  1695. * if any timeout values are less than default values, set to default
  1696. * value (due to bug with some TPMs)
  1697. */
  1698. if ( g_timeout.timeout_a < TIMEOUT_A ) {
  1699. g_timeout.timeout_a = TIMEOUT_A;
  1700. printk("Wrong timeout A, fallback to %u\n", TIMEOUT_A);
  1701. }
  1702. if ( g_timeout.timeout_b < TIMEOUT_B ) {
  1703. g_timeout.timeout_b = TIMEOUT_B;
  1704. printk("Wrong timeout B, fallback to %u\n", TIMEOUT_B);
  1705. }
  1706. if ( g_timeout.timeout_c < TIMEOUT_C ) {
  1707. g_timeout.timeout_c = TIMEOUT_C;
  1708. printk("Wrong timeout C, fallback to %u\n", TIMEOUT_C);
  1709. }
  1710. if ( g_timeout.timeout_d < TIMEOUT_D ) {
  1711. g_timeout.timeout_d = TIMEOUT_D;
  1712. printk("Wrong timeout D, fallback to %u\n", TIMEOUT_D);
  1713. }
  1714. }
  1715. return true;
  1716. }
  1717. uint32_t tpm_save_state(uint32_t locality)
  1718. {
  1719. uint32_t ret, offset, out_size;
  1720. uint32_t retries = 0;
  1721. do {
  1722. offset = 0;
  1723. out_size = 0;
  1724. ret = tpm_submit_cmd(locality, TPM_ORD_SAVE_STATE, offset, &out_size);
  1725. if ( retries == 0 )
  1726. printk("TPM: save state, return value = %08X\n", ret);
  1727. else if ( retries == 1 )
  1728. printk("retrying command: .");
  1729. else
  1730. printk(".");
  1731. if ( ret != TPM_RETRY )
  1732. break;
  1733. retries++;
  1734. delay(100);
  1735. } while ( retries < MAX_SAVESTATE_RETRIES );
  1736. if ( retries >= MAX_SAVESTATE_RETRIES )
  1737. printk("TIMEOUT!");
  1738. if ( retries > 0 )
  1739. printk("\n");
  1740. return ret;
  1741. }
  1742. uint32_t tpm_get_random(uint32_t locality, uint8_t *random_data,
  1743. uint32_t *data_size)
  1744. {
  1745. uint32_t ret, in_size = 0, out_size, requested_size;
  1746. static bool first_attempt;
  1747. if ( random_data == NULL || data_size == NULL )
  1748. return TPM_BAD_PARAMETER;
  1749. if ( *data_size == 0 )
  1750. return TPM_BAD_PARAMETER;
  1751. first_attempt = true;
  1752. requested_size = *data_size;
  1753. /* copy the *data_size into buf in reversed byte order */
  1754. reverse_copy(WRAPPER_IN_BUF + in_size, data_size, sizeof(*data_size));
  1755. in_size += sizeof(*data_size);
  1756. out_size = *data_size + sizeof(*data_size);
  1757. ret = tpm_submit_cmd(locality, TPM_ORD_GET_RANDOM, in_size, &out_size);
  1758. #ifdef TPM_TRACE
  1759. printk("TPM: get random %u bytes, return value = %08X\n", *data_size, ret);
  1760. #endif
  1761. if ( ret != TPM_SUCCESS ) {
  1762. printk("TPM: get random %u bytes, return value = %08X\n", *data_size,
  1763. ret);
  1764. return ret;
  1765. }
  1766. #ifdef TPM_TRACE
  1767. {
  1768. printk("TPM: ");
  1769. print_hex(NULL, WRAPPER_OUT_BUF, out_size);
  1770. }
  1771. #endif
  1772. if ( out_size <= sizeof(*data_size) ) {
  1773. *data_size = 0;
  1774. return ret;
  1775. }
  1776. out_size -= sizeof(*data_size);
  1777. reverse_copy(data_size, WRAPPER_OUT_BUF, sizeof(*data_size));
  1778. if ( *data_size > 0 )
  1779. memcpy(random_data, WRAPPER_OUT_BUF + sizeof(*data_size), *data_size);
  1780. /* data might be used as key, so clear from buffer memory */
  1781. memset(WRAPPER_OUT_BUF + sizeof(*data_size), 0, *data_size);
  1782. /* if TPM doesn't return all requested random bytes, try one more time */
  1783. if ( *data_size < requested_size ) {
  1784. printk("requested %x random bytes but only got %x\n", requested_size,
  1785. *data_size);
  1786. /* we're only going to try twice */
  1787. if ( first_attempt ) {
  1788. first_attempt = false;
  1789. uint32_t second_size = requested_size - *data_size;
  1790. printk("trying one more time to get remaining %x bytes\n",
  1791. second_size);
  1792. ret = tpm_get_random(locality, random_data + *data_size,
  1793. &second_size);
  1794. *data_size += second_size;
  1795. }
  1796. }
  1797. return ret;
  1798. }
  1799. /*
  1800. * Local variables:
  1801. * mode: C
  1802. * c-set-style: "BSD"
  1803. * c-basic-offset: 4
  1804. * tab-width: 4
  1805. * indent-tabs-mode: nil
  1806. * End:
  1807. */