tpm.c 30 KB

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