tpm.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097
  1. /*
  2. * Copyright (c) 2013 The Chromium OS Authors.
  3. * Coypright (c) 2013 Guntermann & Drunck GmbH
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. #include <common.h>
  8. #include <dm.h>
  9. #include <tpm.h>
  10. #include <asm/unaligned.h>
  11. #include <u-boot/sha1.h>
  12. /* Internal error of TPM command library */
  13. #define TPM_LIB_ERROR ((uint32_t)~0u)
  14. /* Useful constants */
  15. enum {
  16. COMMAND_BUFFER_SIZE = 256,
  17. TPM_REQUEST_HEADER_LENGTH = 10,
  18. TPM_RESPONSE_HEADER_LENGTH = 10,
  19. PCR_DIGEST_LENGTH = 20,
  20. DIGEST_LENGTH = 20,
  21. TPM_REQUEST_AUTH_LENGTH = 45,
  22. TPM_RESPONSE_AUTH_LENGTH = 41,
  23. /* some max lengths, valid for RSA keys <= 2048 bits */
  24. TPM_KEY12_MAX_LENGTH = 618,
  25. TPM_PUBKEY_MAX_LENGTH = 288,
  26. };
  27. #ifdef CONFIG_TPM_AUTH_SESSIONS
  28. #ifndef CONFIG_SHA1
  29. #error "TPM_AUTH_SESSIONS require SHA1 to be configured, too"
  30. #endif /* !CONFIG_SHA1 */
  31. struct session_data {
  32. int valid;
  33. uint32_t handle;
  34. uint8_t nonce_even[DIGEST_LENGTH];
  35. uint8_t nonce_odd[DIGEST_LENGTH];
  36. };
  37. static struct session_data oiap_session = {0, };
  38. #endif /* CONFIG_TPM_AUTH_SESSIONS */
  39. /**
  40. * Pack data into a byte string. The data types are specified in
  41. * the format string: 'b' means unsigned byte, 'w' unsigned word,
  42. * 'd' unsigned double word, and 's' byte string. The data are a
  43. * series of offsets and values (for type byte string there are also
  44. * lengths). The data values are packed into the byte string
  45. * sequentially, and so a latter value could over-write a former
  46. * value.
  47. *
  48. * @param str output string
  49. * @param size size of output string
  50. * @param format format string
  51. * @param ... data points
  52. * @return 0 on success, non-0 on error
  53. */
  54. int pack_byte_string(uint8_t *str, size_t size, const char *format, ...)
  55. {
  56. va_list args;
  57. size_t offset = 0, length = 0;
  58. uint8_t *data = NULL;
  59. uint32_t value = 0;
  60. va_start(args, format);
  61. for (; *format; format++) {
  62. switch (*format) {
  63. case 'b':
  64. offset = va_arg(args, size_t);
  65. value = va_arg(args, int);
  66. length = 1;
  67. break;
  68. case 'w':
  69. offset = va_arg(args, size_t);
  70. value = va_arg(args, int);
  71. length = 2;
  72. break;
  73. case 'd':
  74. offset = va_arg(args, size_t);
  75. value = va_arg(args, uint32_t);
  76. length = 4;
  77. break;
  78. case 's':
  79. offset = va_arg(args, size_t);
  80. data = va_arg(args, uint8_t *);
  81. length = va_arg(args, uint32_t);
  82. break;
  83. default:
  84. debug("Couldn't recognize format string\n");
  85. va_end(args);
  86. return -1;
  87. }
  88. if (offset + length > size) {
  89. va_end(args);
  90. return -1;
  91. }
  92. switch (*format) {
  93. case 'b':
  94. str[offset] = value;
  95. break;
  96. case 'w':
  97. put_unaligned_be16(value, str + offset);
  98. break;
  99. case 'd':
  100. put_unaligned_be32(value, str + offset);
  101. break;
  102. case 's':
  103. memcpy(str + offset, data, length);
  104. break;
  105. }
  106. }
  107. va_end(args);
  108. return 0;
  109. }
  110. /**
  111. * Unpack data from a byte string. The data types are specified in
  112. * the format string: 'b' means unsigned byte, 'w' unsigned word,
  113. * 'd' unsigned double word, and 's' byte string. The data are a
  114. * series of offsets and pointers (for type byte string there are also
  115. * lengths).
  116. *
  117. * @param str output string
  118. * @param size size of output string
  119. * @param format format string
  120. * @param ... data points
  121. * @return 0 on success, non-0 on error
  122. */
  123. int unpack_byte_string(const uint8_t *str, size_t size, const char *format, ...)
  124. {
  125. va_list args;
  126. size_t offset = 0, length = 0;
  127. uint8_t *ptr8 = NULL;
  128. uint16_t *ptr16 = NULL;
  129. uint32_t *ptr32 = NULL;
  130. va_start(args, format);
  131. for (; *format; format++) {
  132. switch (*format) {
  133. case 'b':
  134. offset = va_arg(args, size_t);
  135. ptr8 = va_arg(args, uint8_t *);
  136. length = 1;
  137. break;
  138. case 'w':
  139. offset = va_arg(args, size_t);
  140. ptr16 = va_arg(args, uint16_t *);
  141. length = 2;
  142. break;
  143. case 'd':
  144. offset = va_arg(args, size_t);
  145. ptr32 = va_arg(args, uint32_t *);
  146. length = 4;
  147. break;
  148. case 's':
  149. offset = va_arg(args, size_t);
  150. ptr8 = va_arg(args, uint8_t *);
  151. length = va_arg(args, uint32_t);
  152. break;
  153. default:
  154. va_end(args);
  155. debug("Couldn't recognize format string\n");
  156. return -1;
  157. }
  158. if (offset + length > size) {
  159. va_end(args);
  160. return -1;
  161. }
  162. switch (*format) {
  163. case 'b':
  164. *ptr8 = str[offset];
  165. break;
  166. case 'w':
  167. *ptr16 = get_unaligned_be16(str + offset);
  168. break;
  169. case 'd':
  170. *ptr32 = get_unaligned_be32(str + offset);
  171. break;
  172. case 's':
  173. memcpy(ptr8, str + offset, length);
  174. break;
  175. }
  176. }
  177. va_end(args);
  178. return 0;
  179. }
  180. /**
  181. * Get TPM command size.
  182. *
  183. * @param command byte string of TPM command
  184. * @return command size of the TPM command
  185. */
  186. static uint32_t tpm_command_size(const void *command)
  187. {
  188. const size_t command_size_offset = 2;
  189. return get_unaligned_be32(command + command_size_offset);
  190. }
  191. /**
  192. * Get TPM response return code, which is one of TPM_RESULT values.
  193. *
  194. * @param response byte string of TPM response
  195. * @return return code of the TPM response
  196. */
  197. static uint32_t tpm_return_code(const void *response)
  198. {
  199. const size_t return_code_offset = 6;
  200. return get_unaligned_be32(response + return_code_offset);
  201. }
  202. /**
  203. * Send a TPM command and return response's return code, and optionally
  204. * return response to caller.
  205. *
  206. * @param command byte string of TPM command
  207. * @param response output buffer for TPM response, or NULL if the
  208. * caller does not care about it
  209. * @param size_ptr output buffer size (input parameter) and TPM
  210. * response length (output parameter); this parameter
  211. * is a bidirectional
  212. * @return return code of the TPM response
  213. */
  214. static uint32_t tpm_sendrecv_command(const void *command,
  215. void *response, size_t *size_ptr)
  216. {
  217. struct udevice *dev;
  218. int err, ret;
  219. uint8_t response_buffer[COMMAND_BUFFER_SIZE];
  220. size_t response_length;
  221. if (response) {
  222. response_length = *size_ptr;
  223. } else {
  224. response = response_buffer;
  225. response_length = sizeof(response_buffer);
  226. }
  227. ret = uclass_first_device_err(UCLASS_TPM, &dev);
  228. if (ret)
  229. return ret;
  230. err = tpm_xfer(dev, command, tpm_command_size(command),
  231. response, &response_length);
  232. if (err < 0)
  233. return TPM_LIB_ERROR;
  234. if (size_ptr)
  235. *size_ptr = response_length;
  236. return tpm_return_code(response);
  237. }
  238. int tpm_init(void)
  239. {
  240. int err;
  241. struct udevice *dev;
  242. err = uclass_first_device_err(UCLASS_TPM, &dev);
  243. if (err)
  244. return err;
  245. return tpm_open(dev);
  246. }
  247. uint32_t tpm_startup(enum tpm_startup_type mode)
  248. {
  249. const uint8_t command[12] = {
  250. 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x0,
  251. };
  252. const size_t mode_offset = 10;
  253. uint8_t buf[COMMAND_BUFFER_SIZE];
  254. if (pack_byte_string(buf, sizeof(buf), "sw",
  255. 0, command, sizeof(command),
  256. mode_offset, mode))
  257. return TPM_LIB_ERROR;
  258. return tpm_sendrecv_command(buf, NULL, NULL);
  259. }
  260. uint32_t tpm_self_test_full(void)
  261. {
  262. const uint8_t command[10] = {
  263. 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50,
  264. };
  265. return tpm_sendrecv_command(command, NULL, NULL);
  266. }
  267. uint32_t tpm_continue_self_test(void)
  268. {
  269. const uint8_t command[10] = {
  270. 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x53,
  271. };
  272. return tpm_sendrecv_command(command, NULL, NULL);
  273. }
  274. uint32_t tpm_nv_define_space(uint32_t index, uint32_t perm, uint32_t size)
  275. {
  276. const uint8_t command[101] = {
  277. 0x0, 0xc1, /* TPM_TAG */
  278. 0x0, 0x0, 0x0, 0x65, /* parameter size */
  279. 0x0, 0x0, 0x0, 0xcc, /* TPM_COMMAND_CODE */
  280. /* TPM_NV_DATA_PUBLIC->... */
  281. 0x0, 0x18, /* ...->TPM_STRUCTURE_TAG */
  282. 0, 0, 0, 0, /* ...->TPM_NV_INDEX */
  283. /* TPM_NV_DATA_PUBLIC->TPM_PCR_INFO_SHORT */
  284. 0x0, 0x3,
  285. 0, 0, 0,
  286. 0x1f,
  287. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  288. /* TPM_NV_DATA_PUBLIC->TPM_PCR_INFO_SHORT */
  289. 0x0, 0x3,
  290. 0, 0, 0,
  291. 0x1f,
  292. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  293. /* TPM_NV_ATTRIBUTES->... */
  294. 0x0, 0x17, /* ...->TPM_STRUCTURE_TAG */
  295. 0, 0, 0, 0, /* ...->attributes */
  296. /* End of TPM_NV_ATTRIBUTES */
  297. 0, /* bReadSTClear */
  298. 0, /* bWriteSTClear */
  299. 0, /* bWriteDefine */
  300. 0, 0, 0, 0, /* size */
  301. };
  302. const size_t index_offset = 12;
  303. const size_t perm_offset = 70;
  304. const size_t size_offset = 77;
  305. uint8_t buf[COMMAND_BUFFER_SIZE];
  306. if (pack_byte_string(buf, sizeof(buf), "sddd",
  307. 0, command, sizeof(command),
  308. index_offset, index,
  309. perm_offset, perm,
  310. size_offset, size))
  311. return TPM_LIB_ERROR;
  312. return tpm_sendrecv_command(buf, NULL, NULL);
  313. }
  314. uint32_t tpm_nv_read_value(uint32_t index, void *data, uint32_t count)
  315. {
  316. const uint8_t command[22] = {
  317. 0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0xcf,
  318. };
  319. const size_t index_offset = 10;
  320. const size_t length_offset = 18;
  321. const size_t data_size_offset = 10;
  322. const size_t data_offset = 14;
  323. uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
  324. size_t response_length = sizeof(response);
  325. uint32_t data_size;
  326. uint32_t err;
  327. if (pack_byte_string(buf, sizeof(buf), "sdd",
  328. 0, command, sizeof(command),
  329. index_offset, index,
  330. length_offset, count))
  331. return TPM_LIB_ERROR;
  332. err = tpm_sendrecv_command(buf, response, &response_length);
  333. if (err)
  334. return err;
  335. if (unpack_byte_string(response, response_length, "d",
  336. data_size_offset, &data_size))
  337. return TPM_LIB_ERROR;
  338. if (data_size > count)
  339. return TPM_LIB_ERROR;
  340. if (unpack_byte_string(response, response_length, "s",
  341. data_offset, data, data_size))
  342. return TPM_LIB_ERROR;
  343. return 0;
  344. }
  345. uint32_t tpm_nv_write_value(uint32_t index, const void *data, uint32_t length)
  346. {
  347. const uint8_t command[256] = {
  348. 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd,
  349. };
  350. const size_t command_size_offset = 2;
  351. const size_t index_offset = 10;
  352. const size_t length_offset = 18;
  353. const size_t data_offset = 22;
  354. const size_t write_info_size = 12;
  355. const uint32_t total_length =
  356. TPM_REQUEST_HEADER_LENGTH + write_info_size + length;
  357. uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
  358. size_t response_length = sizeof(response);
  359. uint32_t err;
  360. if (pack_byte_string(buf, sizeof(buf), "sddds",
  361. 0, command, sizeof(command),
  362. command_size_offset, total_length,
  363. index_offset, index,
  364. length_offset, length,
  365. data_offset, data, length))
  366. return TPM_LIB_ERROR;
  367. err = tpm_sendrecv_command(buf, response, &response_length);
  368. if (err)
  369. return err;
  370. return 0;
  371. }
  372. uint32_t tpm_extend(uint32_t index, const void *in_digest, void *out_digest)
  373. {
  374. const uint8_t command[34] = {
  375. 0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x14,
  376. };
  377. const size_t index_offset = 10;
  378. const size_t in_digest_offset = 14;
  379. const size_t out_digest_offset = 10;
  380. uint8_t buf[COMMAND_BUFFER_SIZE];
  381. uint8_t response[TPM_RESPONSE_HEADER_LENGTH + PCR_DIGEST_LENGTH];
  382. size_t response_length = sizeof(response);
  383. uint32_t err;
  384. if (pack_byte_string(buf, sizeof(buf), "sds",
  385. 0, command, sizeof(command),
  386. index_offset, index,
  387. in_digest_offset, in_digest,
  388. PCR_DIGEST_LENGTH))
  389. return TPM_LIB_ERROR;
  390. err = tpm_sendrecv_command(buf, response, &response_length);
  391. if (err)
  392. return err;
  393. if (unpack_byte_string(response, response_length, "s",
  394. out_digest_offset, out_digest,
  395. PCR_DIGEST_LENGTH))
  396. return TPM_LIB_ERROR;
  397. return 0;
  398. }
  399. uint32_t tpm_pcr_read(uint32_t index, void *data, size_t count)
  400. {
  401. const uint8_t command[14] = {
  402. 0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x15,
  403. };
  404. const size_t index_offset = 10;
  405. const size_t out_digest_offset = 10;
  406. uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
  407. size_t response_length = sizeof(response);
  408. uint32_t err;
  409. if (count < PCR_DIGEST_LENGTH)
  410. return TPM_LIB_ERROR;
  411. if (pack_byte_string(buf, sizeof(buf), "sd",
  412. 0, command, sizeof(command),
  413. index_offset, index))
  414. return TPM_LIB_ERROR;
  415. err = tpm_sendrecv_command(buf, response, &response_length);
  416. if (err)
  417. return err;
  418. if (unpack_byte_string(response, response_length, "s",
  419. out_digest_offset, data, PCR_DIGEST_LENGTH))
  420. return TPM_LIB_ERROR;
  421. return 0;
  422. }
  423. uint32_t tpm_tsc_physical_presence(uint16_t presence)
  424. {
  425. const uint8_t command[12] = {
  426. 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x0,
  427. };
  428. const size_t presence_offset = 10;
  429. uint8_t buf[COMMAND_BUFFER_SIZE];
  430. if (pack_byte_string(buf, sizeof(buf), "sw",
  431. 0, command, sizeof(command),
  432. presence_offset, presence))
  433. return TPM_LIB_ERROR;
  434. return tpm_sendrecv_command(buf, NULL, NULL);
  435. }
  436. uint32_t tpm_read_pubek(void *data, size_t count)
  437. {
  438. const uint8_t command[30] = {
  439. 0x0, 0xc1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x7c,
  440. };
  441. const size_t response_size_offset = 2;
  442. const size_t data_offset = 10;
  443. const size_t header_and_checksum_size = TPM_RESPONSE_HEADER_LENGTH + 20;
  444. uint8_t response[COMMAND_BUFFER_SIZE + TPM_PUBEK_SIZE];
  445. size_t response_length = sizeof(response);
  446. uint32_t data_size;
  447. uint32_t err;
  448. err = tpm_sendrecv_command(command, response, &response_length);
  449. if (err)
  450. return err;
  451. if (unpack_byte_string(response, response_length, "d",
  452. response_size_offset, &data_size))
  453. return TPM_LIB_ERROR;
  454. if (data_size < header_and_checksum_size)
  455. return TPM_LIB_ERROR;
  456. data_size -= header_and_checksum_size;
  457. if (data_size > count)
  458. return TPM_LIB_ERROR;
  459. if (unpack_byte_string(response, response_length, "s",
  460. data_offset, data, data_size))
  461. return TPM_LIB_ERROR;
  462. return 0;
  463. }
  464. uint32_t tpm_force_clear(void)
  465. {
  466. const uint8_t command[10] = {
  467. 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x5d,
  468. };
  469. return tpm_sendrecv_command(command, NULL, NULL);
  470. }
  471. uint32_t tpm_physical_enable(void)
  472. {
  473. const uint8_t command[10] = {
  474. 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x6f,
  475. };
  476. return tpm_sendrecv_command(command, NULL, NULL);
  477. }
  478. uint32_t tpm_physical_disable(void)
  479. {
  480. const uint8_t command[10] = {
  481. 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x70,
  482. };
  483. return tpm_sendrecv_command(command, NULL, NULL);
  484. }
  485. uint32_t tpm_physical_set_deactivated(uint8_t state)
  486. {
  487. const uint8_t command[11] = {
  488. 0x0, 0xc1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72,
  489. };
  490. const size_t state_offset = 10;
  491. uint8_t buf[COMMAND_BUFFER_SIZE];
  492. if (pack_byte_string(buf, sizeof(buf), "sb",
  493. 0, command, sizeof(command),
  494. state_offset, state))
  495. return TPM_LIB_ERROR;
  496. return tpm_sendrecv_command(buf, NULL, NULL);
  497. }
  498. uint32_t tpm_get_capability(uint32_t cap_area, uint32_t sub_cap,
  499. void *cap, size_t count)
  500. {
  501. const uint8_t command[22] = {
  502. 0x0, 0xc1, /* TPM_TAG */
  503. 0x0, 0x0, 0x0, 0x16, /* parameter size */
  504. 0x0, 0x0, 0x0, 0x65, /* TPM_COMMAND_CODE */
  505. 0x0, 0x0, 0x0, 0x0, /* TPM_CAPABILITY_AREA */
  506. 0x0, 0x0, 0x0, 0x4, /* subcap size */
  507. 0x0, 0x0, 0x0, 0x0, /* subcap value */
  508. };
  509. const size_t cap_area_offset = 10;
  510. const size_t sub_cap_offset = 18;
  511. const size_t cap_offset = 14;
  512. const size_t cap_size_offset = 10;
  513. uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
  514. size_t response_length = sizeof(response);
  515. uint32_t cap_size;
  516. uint32_t err;
  517. if (pack_byte_string(buf, sizeof(buf), "sdd",
  518. 0, command, sizeof(command),
  519. cap_area_offset, cap_area,
  520. sub_cap_offset, sub_cap))
  521. return TPM_LIB_ERROR;
  522. err = tpm_sendrecv_command(buf, response, &response_length);
  523. if (err)
  524. return err;
  525. if (unpack_byte_string(response, response_length, "d",
  526. cap_size_offset, &cap_size))
  527. return TPM_LIB_ERROR;
  528. if (cap_size > response_length || cap_size > count)
  529. return TPM_LIB_ERROR;
  530. if (unpack_byte_string(response, response_length, "s",
  531. cap_offset, cap, cap_size))
  532. return TPM_LIB_ERROR;
  533. return 0;
  534. }
  535. uint32_t tpm_get_permanent_flags(struct tpm_permanent_flags *pflags)
  536. {
  537. const uint8_t command[22] = {
  538. 0x0, 0xc1, /* TPM_TAG */
  539. 0x0, 0x0, 0x0, 0x16, /* parameter size */
  540. 0x0, 0x0, 0x0, 0x65, /* TPM_COMMAND_CODE */
  541. 0x0, 0x0, 0x0, 0x4, /* TPM_CAP_FLAG_PERM */
  542. 0x0, 0x0, 0x0, 0x4, /* subcap size */
  543. 0x0, 0x0, 0x1, 0x8, /* subcap value */
  544. };
  545. const size_t data_size_offset = TPM_HEADER_SIZE;
  546. const size_t data_offset = TPM_HEADER_SIZE + sizeof (uint32_t);
  547. uint8_t response[COMMAND_BUFFER_SIZE];
  548. size_t response_length = sizeof(response);
  549. uint32_t err;
  550. uint32_t data_size;
  551. err = tpm_sendrecv_command(command, response, &response_length);
  552. if (err)
  553. return err;
  554. if (unpack_byte_string(response, response_length, "d",
  555. data_size_offset, &data_size))
  556. return TPM_LIB_ERROR;
  557. if (data_size < sizeof(*pflags))
  558. return TPM_LIB_ERROR;
  559. if (unpack_byte_string(response, response_length, "s",
  560. data_offset, pflags, sizeof(*pflags)))
  561. return TPM_LIB_ERROR;
  562. return 0;
  563. }
  564. uint32_t tpm_get_permissions(uint32_t index, uint32_t *perm)
  565. {
  566. const uint8_t command[22] = {
  567. 0x0, 0xc1, /* TPM_TAG */
  568. 0x0, 0x0, 0x0, 0x16, /* parameter size */
  569. 0x0, 0x0, 0x0, 0x65, /* TPM_COMMAND_CODE */
  570. 0x0, 0x0, 0x0, 0x11,
  571. 0x0, 0x0, 0x0, 0x4,
  572. };
  573. const size_t index_offset = 18;
  574. const size_t perm_offset = 60;
  575. uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
  576. size_t response_length = sizeof(response);
  577. uint32_t err;
  578. if (pack_byte_string(buf, sizeof(buf), "d", 0, command, sizeof(command),
  579. index_offset, index))
  580. return TPM_LIB_ERROR;
  581. err = tpm_sendrecv_command(buf, response, &response_length);
  582. if (err)
  583. return err;
  584. if (unpack_byte_string(response, response_length, "d",
  585. perm_offset, perm))
  586. return TPM_LIB_ERROR;
  587. return 0;
  588. }
  589. #ifdef CONFIG_TPM_FLUSH_RESOURCES
  590. uint32_t tpm_flush_specific(uint32_t key_handle, uint32_t resource_type)
  591. {
  592. const uint8_t command[18] = {
  593. 0x00, 0xc1, /* TPM_TAG */
  594. 0x00, 0x00, 0x00, 0x12, /* parameter size */
  595. 0x00, 0x00, 0x00, 0xba, /* TPM_COMMAND_CODE */
  596. 0x00, 0x00, 0x00, 0x00, /* key handle */
  597. 0x00, 0x00, 0x00, 0x00, /* resource type */
  598. };
  599. const size_t key_handle_offset = 10;
  600. const size_t resource_type_offset = 14;
  601. uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
  602. size_t response_length = sizeof(response);
  603. uint32_t err;
  604. if (pack_byte_string(buf, sizeof(buf), "sdd",
  605. 0, command, sizeof(command),
  606. key_handle_offset, key_handle,
  607. resource_type_offset, resource_type))
  608. return TPM_LIB_ERROR;
  609. err = tpm_sendrecv_command(buf, response, &response_length);
  610. if (err)
  611. return err;
  612. return 0;
  613. }
  614. #endif /* CONFIG_TPM_FLUSH_RESOURCES */
  615. #ifdef CONFIG_TPM_AUTH_SESSIONS
  616. /**
  617. * Fill an authentication block in a request.
  618. * This func can create the first as well as the second auth block (for
  619. * double authorized commands).
  620. *
  621. * @param request pointer to the request (w/ uninitialised auth data)
  622. * @param request_len0 length of the request without auth data
  623. * @param handles_len length of the handles area in request
  624. * @param auth_session pointer to the (valid) auth session to be used
  625. * @param request_auth pointer to the auth block of the request to be filled
  626. * @param auth authentication data (HMAC key)
  627. */
  628. static uint32_t create_request_auth(const void *request, size_t request_len0,
  629. size_t handles_len,
  630. struct session_data *auth_session,
  631. void *request_auth, const void *auth)
  632. {
  633. uint8_t hmac_data[DIGEST_LENGTH * 3 + 1];
  634. sha1_context hash_ctx;
  635. const size_t command_code_offset = 6;
  636. const size_t auth_nonce_odd_offset = 4;
  637. const size_t auth_continue_offset = 24;
  638. const size_t auth_auth_offset = 25;
  639. if (!auth_session || !auth_session->valid)
  640. return TPM_LIB_ERROR;
  641. sha1_starts(&hash_ctx);
  642. sha1_update(&hash_ctx, request + command_code_offset, 4);
  643. if (request_len0 > TPM_REQUEST_HEADER_LENGTH + handles_len)
  644. sha1_update(&hash_ctx,
  645. request + TPM_REQUEST_HEADER_LENGTH + handles_len,
  646. request_len0 - TPM_REQUEST_HEADER_LENGTH
  647. - handles_len);
  648. sha1_finish(&hash_ctx, hmac_data);
  649. sha1_starts(&hash_ctx);
  650. sha1_update(&hash_ctx, auth_session->nonce_odd, DIGEST_LENGTH);
  651. sha1_update(&hash_ctx, hmac_data, sizeof(hmac_data));
  652. sha1_finish(&hash_ctx, auth_session->nonce_odd);
  653. if (pack_byte_string(request_auth, TPM_REQUEST_AUTH_LENGTH, "dsb",
  654. 0, auth_session->handle,
  655. auth_nonce_odd_offset, auth_session->nonce_odd,
  656. DIGEST_LENGTH,
  657. auth_continue_offset, 1))
  658. return TPM_LIB_ERROR;
  659. if (pack_byte_string(hmac_data, sizeof(hmac_data), "ss",
  660. DIGEST_LENGTH,
  661. auth_session->nonce_even,
  662. DIGEST_LENGTH,
  663. 2 * DIGEST_LENGTH,
  664. request_auth + auth_nonce_odd_offset,
  665. DIGEST_LENGTH + 1))
  666. return TPM_LIB_ERROR;
  667. sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
  668. request_auth + auth_auth_offset);
  669. return TPM_SUCCESS;
  670. }
  671. /**
  672. * Verify an authentication block in a response.
  673. * Since this func updates the nonce_even in the session data it has to be
  674. * called when receiving a succesfull AUTH response.
  675. * This func can verify the first as well as the second auth block (for
  676. * double authorized commands).
  677. *
  678. * @param command_code command code of the request
  679. * @param response pointer to the request (w/ uninitialised auth data)
  680. * @param handles_len length of the handles area in response
  681. * @param auth_session pointer to the (valid) auth session to be used
  682. * @param response_auth pointer to the auth block of the response to be verified
  683. * @param auth authentication data (HMAC key)
  684. */
  685. static uint32_t verify_response_auth(uint32_t command_code,
  686. const void *response, size_t response_len0,
  687. size_t handles_len,
  688. struct session_data *auth_session,
  689. const void *response_auth, const void *auth)
  690. {
  691. uint8_t hmac_data[DIGEST_LENGTH * 3 + 1];
  692. uint8_t computed_auth[DIGEST_LENGTH];
  693. sha1_context hash_ctx;
  694. const size_t return_code_offset = 6;
  695. const size_t auth_continue_offset = 20;
  696. const size_t auth_auth_offset = 21;
  697. uint8_t auth_continue;
  698. if (!auth_session || !auth_session->valid)
  699. return TPM_AUTHFAIL;
  700. if (pack_byte_string(hmac_data, sizeof(hmac_data), "d",
  701. 0, command_code))
  702. return TPM_LIB_ERROR;
  703. if (response_len0 < TPM_RESPONSE_HEADER_LENGTH)
  704. return TPM_LIB_ERROR;
  705. sha1_starts(&hash_ctx);
  706. sha1_update(&hash_ctx, response + return_code_offset, 4);
  707. sha1_update(&hash_ctx, hmac_data, 4);
  708. if (response_len0 > TPM_RESPONSE_HEADER_LENGTH + handles_len)
  709. sha1_update(&hash_ctx,
  710. response + TPM_RESPONSE_HEADER_LENGTH + handles_len,
  711. response_len0 - TPM_RESPONSE_HEADER_LENGTH
  712. - handles_len);
  713. sha1_finish(&hash_ctx, hmac_data);
  714. memcpy(auth_session->nonce_even, response_auth, DIGEST_LENGTH);
  715. auth_continue = ((uint8_t *)response_auth)[auth_continue_offset];
  716. if (pack_byte_string(hmac_data, sizeof(hmac_data), "ssb",
  717. DIGEST_LENGTH,
  718. response_auth,
  719. DIGEST_LENGTH,
  720. 2 * DIGEST_LENGTH,
  721. auth_session->nonce_odd,
  722. DIGEST_LENGTH,
  723. 3 * DIGEST_LENGTH,
  724. auth_continue))
  725. return TPM_LIB_ERROR;
  726. sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
  727. computed_auth);
  728. if (memcmp(computed_auth, response_auth + auth_auth_offset,
  729. DIGEST_LENGTH))
  730. return TPM_AUTHFAIL;
  731. return TPM_SUCCESS;
  732. }
  733. uint32_t tpm_terminate_auth_session(uint32_t auth_handle)
  734. {
  735. const uint8_t command[18] = {
  736. 0x00, 0xc1, /* TPM_TAG */
  737. 0x00, 0x00, 0x00, 0x00, /* parameter size */
  738. 0x00, 0x00, 0x00, 0xba, /* TPM_COMMAND_CODE */
  739. 0x00, 0x00, 0x00, 0x00, /* TPM_HANDLE */
  740. 0x00, 0x00, 0x00, 0x02, /* TPM_RESSOURCE_TYPE */
  741. };
  742. const size_t req_handle_offset = TPM_REQUEST_HEADER_LENGTH;
  743. uint8_t request[COMMAND_BUFFER_SIZE];
  744. if (pack_byte_string(request, sizeof(request), "sd",
  745. 0, command, sizeof(command),
  746. req_handle_offset, auth_handle))
  747. return TPM_LIB_ERROR;
  748. if (oiap_session.valid && oiap_session.handle == auth_handle)
  749. oiap_session.valid = 0;
  750. return tpm_sendrecv_command(request, NULL, NULL);
  751. }
  752. uint32_t tpm_end_oiap(void)
  753. {
  754. uint32_t err = TPM_SUCCESS;
  755. if (oiap_session.valid)
  756. err = tpm_terminate_auth_session(oiap_session.handle);
  757. return err;
  758. }
  759. uint32_t tpm_oiap(uint32_t *auth_handle)
  760. {
  761. const uint8_t command[10] = {
  762. 0x00, 0xc1, /* TPM_TAG */
  763. 0x00, 0x00, 0x00, 0x0a, /* parameter size */
  764. 0x00, 0x00, 0x00, 0x0a, /* TPM_COMMAND_CODE */
  765. };
  766. const size_t res_auth_handle_offset = TPM_RESPONSE_HEADER_LENGTH;
  767. const size_t res_nonce_even_offset = TPM_RESPONSE_HEADER_LENGTH + 4;
  768. uint8_t response[COMMAND_BUFFER_SIZE];
  769. size_t response_length = sizeof(response);
  770. uint32_t err;
  771. if (oiap_session.valid)
  772. tpm_terminate_auth_session(oiap_session.handle);
  773. err = tpm_sendrecv_command(command, response, &response_length);
  774. if (err)
  775. return err;
  776. if (unpack_byte_string(response, response_length, "ds",
  777. res_auth_handle_offset, &oiap_session.handle,
  778. res_nonce_even_offset, &oiap_session.nonce_even,
  779. (uint32_t)DIGEST_LENGTH))
  780. return TPM_LIB_ERROR;
  781. oiap_session.valid = 1;
  782. if (auth_handle)
  783. *auth_handle = oiap_session.handle;
  784. return 0;
  785. }
  786. uint32_t tpm_load_key2_oiap(uint32_t parent_handle,
  787. const void *key, size_t key_length,
  788. const void *parent_key_usage_auth,
  789. uint32_t *key_handle)
  790. {
  791. const uint8_t command[14] = {
  792. 0x00, 0xc2, /* TPM_TAG */
  793. 0x00, 0x00, 0x00, 0x00, /* parameter size */
  794. 0x00, 0x00, 0x00, 0x41, /* TPM_COMMAND_CODE */
  795. 0x00, 0x00, 0x00, 0x00, /* parent handle */
  796. };
  797. const size_t req_size_offset = 2;
  798. const size_t req_parent_handle_offset = TPM_REQUEST_HEADER_LENGTH;
  799. const size_t req_key_offset = TPM_REQUEST_HEADER_LENGTH + 4;
  800. const size_t res_handle_offset = TPM_RESPONSE_HEADER_LENGTH;
  801. uint8_t request[sizeof(command) + TPM_KEY12_MAX_LENGTH
  802. + TPM_REQUEST_AUTH_LENGTH];
  803. uint8_t response[COMMAND_BUFFER_SIZE];
  804. size_t response_length = sizeof(response);
  805. uint32_t err;
  806. if (!oiap_session.valid) {
  807. err = tpm_oiap(NULL);
  808. if (err)
  809. return err;
  810. }
  811. if (pack_byte_string(request, sizeof(request), "sdds",
  812. 0, command, sizeof(command),
  813. req_size_offset,
  814. sizeof(command) + key_length
  815. + TPM_REQUEST_AUTH_LENGTH,
  816. req_parent_handle_offset, parent_handle,
  817. req_key_offset, key, key_length
  818. ))
  819. return TPM_LIB_ERROR;
  820. err = create_request_auth(request, sizeof(command) + key_length, 4,
  821. &oiap_session,
  822. request + sizeof(command) + key_length,
  823. parent_key_usage_auth);
  824. if (err)
  825. return err;
  826. err = tpm_sendrecv_command(request, response, &response_length);
  827. if (err) {
  828. if (err == TPM_AUTHFAIL)
  829. oiap_session.valid = 0;
  830. return err;
  831. }
  832. err = verify_response_auth(0x00000041, response,
  833. response_length - TPM_RESPONSE_AUTH_LENGTH,
  834. 4, &oiap_session,
  835. response + response_length - TPM_RESPONSE_AUTH_LENGTH,
  836. parent_key_usage_auth);
  837. if (err)
  838. return err;
  839. if (key_handle) {
  840. if (unpack_byte_string(response, response_length, "d",
  841. res_handle_offset, key_handle))
  842. return TPM_LIB_ERROR;
  843. }
  844. return 0;
  845. }
  846. uint32_t tpm_get_pub_key_oiap(uint32_t key_handle, const void *usage_auth,
  847. void *pubkey, size_t *pubkey_len)
  848. {
  849. const uint8_t command[14] = {
  850. 0x00, 0xc2, /* TPM_TAG */
  851. 0x00, 0x00, 0x00, 0x00, /* parameter size */
  852. 0x00, 0x00, 0x00, 0x21, /* TPM_COMMAND_CODE */
  853. 0x00, 0x00, 0x00, 0x00, /* key handle */
  854. };
  855. const size_t req_size_offset = 2;
  856. const size_t req_key_handle_offset = TPM_REQUEST_HEADER_LENGTH;
  857. const size_t res_pubkey_offset = TPM_RESPONSE_HEADER_LENGTH;
  858. uint8_t request[sizeof(command) + TPM_REQUEST_AUTH_LENGTH];
  859. uint8_t response[TPM_RESPONSE_HEADER_LENGTH + TPM_PUBKEY_MAX_LENGTH
  860. + TPM_RESPONSE_AUTH_LENGTH];
  861. size_t response_length = sizeof(response);
  862. uint32_t err;
  863. if (!oiap_session.valid) {
  864. err = tpm_oiap(NULL);
  865. if (err)
  866. return err;
  867. }
  868. if (pack_byte_string(request, sizeof(request), "sdd",
  869. 0, command, sizeof(command),
  870. req_size_offset,
  871. (uint32_t)(sizeof(command)
  872. + TPM_REQUEST_AUTH_LENGTH),
  873. req_key_handle_offset, key_handle
  874. ))
  875. return TPM_LIB_ERROR;
  876. err = create_request_auth(request, sizeof(command), 4, &oiap_session,
  877. request + sizeof(command), usage_auth);
  878. if (err)
  879. return err;
  880. err = tpm_sendrecv_command(request, response, &response_length);
  881. if (err) {
  882. if (err == TPM_AUTHFAIL)
  883. oiap_session.valid = 0;
  884. return err;
  885. }
  886. err = verify_response_auth(0x00000021, response,
  887. response_length - TPM_RESPONSE_AUTH_LENGTH,
  888. 0, &oiap_session,
  889. response + response_length - TPM_RESPONSE_AUTH_LENGTH,
  890. usage_auth);
  891. if (err)
  892. return err;
  893. if (pubkey) {
  894. if ((response_length - TPM_RESPONSE_HEADER_LENGTH
  895. - TPM_RESPONSE_AUTH_LENGTH) > *pubkey_len)
  896. return TPM_LIB_ERROR;
  897. *pubkey_len = response_length - TPM_RESPONSE_HEADER_LENGTH
  898. - TPM_RESPONSE_AUTH_LENGTH;
  899. memcpy(pubkey, response + res_pubkey_offset,
  900. response_length - TPM_RESPONSE_HEADER_LENGTH
  901. - TPM_RESPONSE_AUTH_LENGTH);
  902. }
  903. return 0;
  904. }
  905. #ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
  906. uint32_t tpm_find_key_sha1(const uint8_t auth[20], const uint8_t
  907. pubkey_digest[20], uint32_t *handle)
  908. {
  909. uint16_t key_count;
  910. uint32_t key_handles[10];
  911. uint8_t buf[288];
  912. uint8_t *ptr;
  913. uint32_t err;
  914. uint8_t digest[20];
  915. size_t buf_len;
  916. unsigned int i;
  917. /* fetch list of already loaded keys in the TPM */
  918. err = tpm_get_capability(TPM_CAP_HANDLE, TPM_RT_KEY, buf, sizeof(buf));
  919. if (err)
  920. return -1;
  921. key_count = get_unaligned_be16(buf);
  922. ptr = buf + 2;
  923. for (i = 0; i < key_count; ++i, ptr += 4)
  924. key_handles[i] = get_unaligned_be32(ptr);
  925. /* now search a(/ the) key which we can access with the given auth */
  926. for (i = 0; i < key_count; ++i) {
  927. buf_len = sizeof(buf);
  928. err = tpm_get_pub_key_oiap(key_handles[i], auth, buf, &buf_len);
  929. if (err && err != TPM_AUTHFAIL)
  930. return -1;
  931. if (err)
  932. continue;
  933. sha1_csum(buf, buf_len, digest);
  934. if (!memcmp(digest, pubkey_digest, 20)) {
  935. *handle = key_handles[i];
  936. return 0;
  937. }
  938. }
  939. return 1;
  940. }
  941. #endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
  942. #endif /* CONFIG_TPM_AUTH_SESSIONS */
  943. uint32_t tpm_get_random(void *data, uint32_t count)
  944. {
  945. const uint8_t command[14] = {
  946. 0x0, 0xc1, /* TPM_TAG */
  947. 0x0, 0x0, 0x0, 0xe, /* parameter size */
  948. 0x0, 0x0, 0x0, 0x46, /* TPM_COMMAND_CODE */
  949. };
  950. const size_t length_offset = 10;
  951. const size_t data_size_offset = 10;
  952. const size_t data_offset = 14;
  953. uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
  954. size_t response_length = sizeof(response);
  955. uint32_t data_size;
  956. uint8_t *out = data;
  957. while (count > 0) {
  958. uint32_t this_bytes = min((size_t)count,
  959. sizeof (response) - data_offset);
  960. uint32_t err;
  961. if (pack_byte_string(buf, sizeof(buf), "sd",
  962. 0, command, sizeof(command),
  963. length_offset, this_bytes))
  964. return TPM_LIB_ERROR;
  965. err = tpm_sendrecv_command(buf, response, &response_length);
  966. if (err)
  967. return err;
  968. if (unpack_byte_string(response, response_length, "d",
  969. data_size_offset, &data_size))
  970. return TPM_LIB_ERROR;
  971. if (data_size > count)
  972. return TPM_LIB_ERROR;
  973. if (unpack_byte_string(response, response_length, "s",
  974. data_offset, out, data_size))
  975. return TPM_LIB_ERROR;
  976. count -= data_size;
  977. out += data_size;
  978. }
  979. return 0;
  980. }