sys-session-util.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  1. /* SPDX-License-Identifier: BSD-2-Clause */
  2. /***********************************************************************
  3. * Copyright (c) 2017-2018, Intel Corporation
  4. *
  5. * All rights reserved.
  6. ***********************************************************************/
  7. #ifdef HAVE_CONFIG_H
  8. #include <config.h>
  9. #endif
  10. #include <inttypes.h>
  11. #include "session-util.h"
  12. #include "sys-util.h"
  13. #include "context-util.h"
  14. #include "util/tss2_endian.h"
  15. #define LOGMODULE test
  16. #include "util/log.h"
  17. static SESSION *sessions = NULL;
  18. SESSION *
  19. get_session(TPMI_SH_AUTH_SESSION hndl)
  20. {
  21. SESSION *s;
  22. HASH_FIND_INT(sessions, &hndl, s);
  23. return s;
  24. }
  25. static TSS2_RC
  26. start_auth_session(
  27. SESSION *session,
  28. TSS2_TCTI_CONTEXT *tctiContext)
  29. {
  30. TSS2_RC rval;
  31. TPM2B_ENCRYPTED_SECRET key;
  32. char label[] = "ATH";
  33. TSS2_SYS_CONTEXT *tmp_context;
  34. UINT16 bytes;
  35. key.size = 0;
  36. tmp_context = sys_init_from_tcti_ctx(tctiContext);
  37. if (tmp_context == NULL)
  38. return TSS2_SYS_RC_GENERAL_FAILURE;
  39. if (session->nonceOlder.size == 0)
  40. session->nonceOlder.size = GetDigestSize(session->authHash);
  41. memset(session->nonceOlder.buffer, '\0', session->nonceOlder.size);
  42. session->nonceNewer.size = session->nonceOlder.size;
  43. session->nonceTpmDecrypt.size = 0;
  44. session->nonceTpmEncrypt.size = 0;
  45. rval = Tss2_Sys_StartAuthSession(
  46. tmp_context, session->tpmKey, session->bind, 0,
  47. &session->nonceOlder, &session->encryptedSalt,
  48. session->sessionType, &session->symmetric,
  49. session->authHash, &session->sessionHandle,
  50. &session->nonceNewer, 0);
  51. if (rval != TPM2_RC_SUCCESS)
  52. goto out;
  53. if (session->tpmKey == TPM2_RH_NULL)
  54. session->salt.size = 0;
  55. if (session->bind == TPM2_RH_NULL)
  56. session->authValueBind.size = 0;
  57. session->sessionKey.size = 0;
  58. if (session->tpmKey == TPM2_RH_NULL && session->bind == TPM2_RH_NULL)
  59. goto out;
  60. /* Generate the key used as input to the KDF. */
  61. rval = ConcatSizedByteBuffer((TPM2B_MAX_BUFFER *)&key,
  62. (TPM2B *)&session->authValueBind);
  63. if (rval != TPM2_RC_SUCCESS) {
  64. Tss2_Sys_FlushContext(tmp_context, session->sessionHandle);
  65. goto out;
  66. }
  67. rval = ConcatSizedByteBuffer((TPM2B_MAX_BUFFER *)&key,
  68. (TPM2B *)&session->salt);
  69. if (rval != TPM2_RC_SUCCESS) {
  70. Tss2_Sys_FlushContext(tmp_context, session->sessionHandle);
  71. goto out;
  72. }
  73. bytes = GetDigestSize(session->authHash) * 8;
  74. rval = KDFa(session->authHash, (TPM2B *)&key, label,
  75. (TPM2B *)&session->nonceNewer,
  76. (TPM2B *)&session->nonceOlder,
  77. bytes, (TPM2B_MAX_BUFFER *)&session->sessionKey);
  78. out:
  79. sys_teardown(tmp_context);
  80. return rval;
  81. }
  82. static TSS2_RC
  83. compute_session_auth(
  84. TSS2_SYS_CONTEXT *sysContext,
  85. SESSION *session,
  86. TPMS_AUTH_COMMAND *pSessionDataIn,
  87. bool command,
  88. TPM2_HANDLE handle1,
  89. TPM2_HANDLE handle2,
  90. TPM2_HANDLE handle3,
  91. TPM2B_MAX_BUFFER *hmacKey)
  92. {
  93. TPM2B_DIGEST *buffer_list[7];
  94. TPM2B_DIGEST pHash = TPM2B_DIGEST_INIT;
  95. TPM2B_DIGEST sessionAttributesByteBuffer = {
  96. .size = 1,
  97. .buffer = { pSessionDataIn->sessionAttributes, }
  98. };
  99. UINT16 i;
  100. TSS2_RC rval;
  101. TPM2_CC cmdCode;
  102. rval = tpm_calc_phash(sysContext, handle1, handle2, handle3,
  103. session->authHash, command, &pHash);
  104. if (rval != TPM2_RC_SUCCESS)
  105. return rval;
  106. rval = Tss2_Sys_GetCommandCode(sysContext, (UINT8 *)&cmdCode);
  107. if (rval != TPM2_RC_SUCCESS)
  108. return rval;
  109. /* cmdCode comes back as BigEndian; not suited for comparisons below. */
  110. cmdCode = BE_TO_HOST_32(cmdCode);
  111. LOGBLOB_DEBUG(hmacKey->buffer, hmacKey->size, "hmacKey=");
  112. i = 0;
  113. buffer_list[i++] = (TPM2B_DIGEST *)&pHash;
  114. buffer_list[i++] = (TPM2B_DIGEST *)&session->nonceNewer;
  115. buffer_list[i++] = (TPM2B_DIGEST *)&session->nonceOlder;
  116. buffer_list[i++] = (TPM2B_DIGEST *)&session->nonceTpmDecrypt;
  117. buffer_list[i++] = (TPM2B_DIGEST *)&session->nonceTpmEncrypt;
  118. buffer_list[i++] = (TPM2B_DIGEST *)&sessionAttributesByteBuffer;
  119. buffer_list[i++] = 0;
  120. for (int j = 0; buffer_list[j] != 0; j++) {
  121. LOGBLOB_DEBUG(&buffer_list[j]->buffer[0],
  122. buffer_list[j]->size, "bufferlist[%d]:", j);
  123. ;
  124. }
  125. rval = hmac(session->authHash, hmacKey->buffer,
  126. hmacKey->size, buffer_list,
  127. (TPM2B_DIGEST *)&pSessionDataIn->hmac);
  128. if (rval != TPM2_RC_SUCCESS) {
  129. LOGBLOB_ERROR(pSessionDataIn->hmac.buffer,
  130. pSessionDataIn->hmac.size,
  131. "HMAC Failed rval = %d !!!", rval);
  132. return rval;
  133. }
  134. return rval;
  135. }
  136. TSS2_RC
  137. compute_command_hmac(
  138. TSS2_SYS_CONTEXT *sysContext,
  139. TPM2_HANDLE handle1,
  140. TPM2_HANDLE handle2,
  141. TPM2_HANDLE handle3,
  142. TSS2L_SYS_AUTH_COMMAND *pSessionsDataIn)
  143. {
  144. TPM2_HANDLE handles[3] = {handle1, handle2, handle3};
  145. ENTITY *entity;
  146. SESSION *session;
  147. TPM2B_MAX_BUFFER hmac_key;
  148. TSS2_RC rval = TPM2_RC_SUCCESS;
  149. unsigned int i;
  150. unsigned int count = pSessionsDataIn->count;
  151. if (count > 3) {
  152. LOG_ERROR("Bad value for session count: %" PRIu16, count);
  153. return TSS2_SYS_RC_GENERAL_FAILURE;
  154. }
  155. for (i = 0; i < count; i++) {
  156. if (handles[i] == TPM2_RH_NULL)
  157. break;
  158. entity = GetEntity(handles[i]);
  159. if (!entity)
  160. return TSS2_SYS_RC_GENERAL_FAILURE;
  161. session = get_session(pSessionsDataIn->auths[i].sessionHandle);
  162. if (!session)
  163. return TPM2_RC_SUCCESS;
  164. CopySizedByteBuffer((TPM2B *)&hmac_key, (TPM2B *)&session->sessionKey);
  165. if (handles[i] != session->bind || handles[i] == TPM2_RH_NULL)
  166. ConcatSizedByteBuffer(&hmac_key, (TPM2B *)&entity->entityAuth);
  167. rval = compute_session_auth(sysContext,
  168. session,
  169. &pSessionsDataIn->auths[i],
  170. true,
  171. handle1,
  172. handle2,
  173. handle3,
  174. &hmac_key);
  175. if (rval != TPM2_RC_SUCCESS)
  176. break;
  177. }
  178. return rval;
  179. }
  180. TSS2_RC check_response_hmac(
  181. TSS2_SYS_CONTEXT *sysContext,
  182. TSS2L_SYS_AUTH_COMMAND *pSessionsDataIn,
  183. TPM2_HANDLE handle1,
  184. TPM2_HANDLE handle2,
  185. TPM2_HANDLE handle3,
  186. TSS2L_SYS_AUTH_RESPONSE *pSessionsDataOut)
  187. {
  188. TPM2_HANDLE handles[3] = {handle1, handle2, handle3};
  189. ENTITY *entity;
  190. SESSION *session;
  191. TPM2B_MAX_BUFFER hmac_key;
  192. TSS2_RC rval = TPM2_RC_SUCCESS;
  193. unsigned int i;
  194. unsigned int count = pSessionsDataIn->count;
  195. if (count > 3) {
  196. LOG_ERROR("Bad value for session count: %" PRIu16, count);
  197. return TSS2_SYS_RC_GENERAL_FAILURE;
  198. }
  199. for (i = 0; i < count; i++) {
  200. if (handles[i] == TPM2_RH_NULL)
  201. break;
  202. entity = GetEntity(handles[i]);
  203. if (!entity)
  204. return TSS2_SYS_RC_GENERAL_FAILURE;
  205. session = get_session(pSessionsDataIn->auths[i].sessionHandle);
  206. if (!session)
  207. return TPM2_RC_SUCCESS;
  208. CopySizedByteBuffer((TPM2B *)&hmac_key, (TPM2B *)&session->sessionKey);
  209. if (handles[i] != session->bind)
  210. ConcatSizedByteBuffer(&hmac_key, (TPM2B *)&entity->entityAuth);
  211. rval = compute_session_auth(sysContext,
  212. session,
  213. &pSessionsDataIn->auths[i],
  214. false,
  215. handle1,
  216. handle2,
  217. handle3,
  218. &hmac_key);
  219. if (rval != TPM2_RC_SUCCESS)
  220. return rval;
  221. rval = CompareSizedByteBuffer((TPM2B *)&pSessionsDataIn->auths[i].hmac,
  222. (TPM2B *)&pSessionsDataOut->auths[i].hmac);
  223. if (rval != TPM2_RC_SUCCESS)
  224. return TSS2_SYS_RC_GENERAL_FAILURE;
  225. }
  226. return rval;
  227. }
  228. TSS2_RC create_auth_session(
  229. SESSION **psession,
  230. TPMI_DH_OBJECT tpmKey,
  231. TPM2B_MAX_BUFFER *salt,
  232. TPMI_DH_ENTITY bind,
  233. TPM2B_AUTH *bindAuth,
  234. TPM2B_NONCE *nonceCaller,
  235. TPM2B_ENCRYPTED_SECRET *encryptedSalt,
  236. TPM2_SE sessionType,
  237. TPMT_SYM_DEF *symmetric,
  238. TPMI_ALG_HASH algId,
  239. TSS2_TCTI_CONTEXT *tctiContext)
  240. {
  241. TSS2_RC rval;
  242. SESSION *session, *tmp;
  243. if (psession == NULL)
  244. return TSS2_SYS_RC_BAD_REFERENCE;
  245. session = calloc(1, sizeof(SESSION));
  246. if (!session)
  247. return TSS2_SYS_RC_GENERAL_FAILURE;
  248. session->bind = bind;
  249. session->tpmKey = tpmKey;
  250. CopySizedByteBuffer((TPM2B *)&session->nonceOlder, (TPM2B *)nonceCaller);
  251. CopySizedByteBuffer((TPM2B *)&session->encryptedSalt, (TPM2B *)encryptedSalt);
  252. session->sessionType = sessionType;
  253. session->symmetric.algorithm = symmetric->algorithm;
  254. session->symmetric.keyBits.sym = symmetric->keyBits.sym;
  255. session->symmetric.mode.sym = symmetric->mode.sym;
  256. session->authHash = algId;
  257. if (bindAuth != NULL)
  258. CopySizedByteBuffer((TPM2B *)&session->authValueBind, (TPM2B *)bindAuth);
  259. if (session->tpmKey != TPM2_RH_NULL)
  260. CopySizedByteBuffer((TPM2B *)&session->salt, (TPM2B *)salt);
  261. rval = start_auth_session(session, tctiContext);
  262. if (rval != TSS2_RC_SUCCESS) {
  263. free(session);
  264. return rval;
  265. }
  266. /* Make sure this session handle is not already in the table */
  267. HASH_FIND_INT(sessions, &session->sessionHandle, tmp);
  268. if (tmp)
  269. HASH_DEL(sessions, tmp);
  270. HASH_ADD_INT(sessions, sessionHandle, session);
  271. *psession = session;
  272. return TSS2_RC_SUCCESS;
  273. }
  274. void end_auth_session(SESSION *session)
  275. {
  276. HASH_DEL(sessions, session);
  277. free(session);
  278. }
  279. void roll_nonces(SESSION *session, TPM2B_NONCE *new_nonce)
  280. {
  281. session->nonceOlder = session->nonceNewer;
  282. session->nonceNewer = *new_nonce;
  283. }
  284. TSS2_RC
  285. tpm_calc_phash(
  286. TSS2_SYS_CONTEXT *sysContext,
  287. TPM2_HANDLE handle1,
  288. TPM2_HANDLE handle2,
  289. TPM2_HANDLE handle3,
  290. TPMI_ALG_HASH authHash,
  291. bool command,
  292. TPM2B_DIGEST *pHash)
  293. {
  294. TSS2_RC rval = TPM2_RC_SUCCESS;
  295. TSS2_TCTI_CONTEXT *tcti_context;
  296. UINT32 i;
  297. TPM2B_NAME name1, name2, name3;
  298. TPM2B_MAX_BUFFER hashInput;
  299. UINT8 *hashInputPtr;
  300. size_t parametersSize;
  301. const uint8_t *startParams;
  302. TPM2_CC cmdCode;
  303. name1.size = 0;
  304. name2.size = 0;
  305. name3.size = 0;
  306. hashInput.size = 0;
  307. rval = Tss2_Sys_GetTctiContext(sysContext, &tcti_context);
  308. if (rval != TPM2_RC_SUCCESS)
  309. return rval;
  310. if (command) {
  311. rval = tpm_handle_to_name(tcti_context, handle1, &name1);
  312. if (rval != TPM2_RC_SUCCESS)
  313. return rval;
  314. rval = tpm_handle_to_name(tcti_context, handle2, &name2);
  315. if (rval != TPM2_RC_SUCCESS)
  316. return rval;
  317. rval = tpm_handle_to_name(tcti_context, handle3, &name3);
  318. if (rval != TPM2_RC_SUCCESS)
  319. return rval;
  320. rval = Tss2_Sys_GetCpBuffer(sysContext, &parametersSize, &startParams);
  321. if (rval != TPM2_RC_SUCCESS)
  322. return rval;
  323. } else {
  324. rval = Tss2_Sys_GetRpBuffer(sysContext, &parametersSize, &startParams);
  325. if (rval != TPM2_RC_SUCCESS)
  326. return rval;
  327. hashInputPtr = &(hashInput.buffer[hashInput.size]);
  328. /* This is response code. Assuming 0 (success) */
  329. *(UINT32 *)hashInputPtr = 0;
  330. hashInput.size += 4;
  331. }
  332. rval = Tss2_Sys_GetCommandCode(sysContext, (UINT8 *)&cmdCode);
  333. if (rval != TPM2_RC_SUCCESS)
  334. return rval;
  335. hashInputPtr = &(hashInput.buffer[hashInput.size]);
  336. *(UINT32 *)hashInputPtr = cmdCode;
  337. hashInput.size += 4;
  338. rval = ConcatSizedByteBuffer(&hashInput, (TPM2B *)&name1);
  339. if (rval != TPM2_RC_SUCCESS)
  340. return rval;
  341. rval = ConcatSizedByteBuffer(&hashInput, (TPM2B *)&name2);
  342. if (rval != TPM2_RC_SUCCESS)
  343. return rval;
  344. rval = ConcatSizedByteBuffer(&hashInput, (TPM2B *)&name3);
  345. if (rval != TPM2_RC_SUCCESS)
  346. return rval;
  347. if (hashInput.size + parametersSize > sizeof(hashInput.buffer))
  348. return TSS2_SYS_RC_INSUFFICIENT_BUFFER;
  349. for(i = 0; i < parametersSize; i++)
  350. hashInput.buffer[hashInput.size + i ] = startParams[i];
  351. hashInput.size += (UINT16)parametersSize;
  352. LOGBLOB_DEBUG(&hashInput.buffer[0], hashInput.size, "PHASH input bytes=");
  353. if (hashInput.size > sizeof(hashInput.buffer))
  354. return TSS2_SYS_RC_INSUFFICIENT_BUFFER;
  355. rval = hash(authHash, hashInput.buffer, hashInput.size, pHash);
  356. if (rval != TPM2_RC_SUCCESS)
  357. return rval;
  358. LOGBLOB_DEBUG(&pHash->buffer[0], pHash->size, "PHASH =");
  359. return rval;
  360. }
  361. UINT32 tpm_handle_to_name(
  362. TSS2_TCTI_CONTEXT *tcti_context,
  363. TPM2_HANDLE handle,
  364. TPM2B_NAME *name)
  365. {
  366. TSS2_RC rval;
  367. TPM2B_NAME qualified_name = TPM2B_NAME_INIT;
  368. TPM2B_PUBLIC public;
  369. TPM2B_NV_PUBLIC nvPublic;
  370. TSS2_SYS_CONTEXT *sysContext;
  371. UINT8 *namePtr;
  372. if (!tcti_context || !name)
  373. return TSS2_SYS_RC_BAD_VALUE;
  374. namePtr = name->name;
  375. if (handle == TPM2_RH_NULL) {
  376. name->size = 0;
  377. return TSS2_RC_SUCCESS;
  378. }
  379. switch(handle >> TPM2_HR_SHIFT)
  380. {
  381. case TPM2_HT_NV_INDEX:
  382. sysContext = sys_init_from_tcti_ctx(tcti_context);
  383. if (sysContext == NULL)
  384. return TSS2_SYS_RC_GENERAL_FAILURE;
  385. nvPublic.size = 0;
  386. rval = Tss2_Sys_NV_ReadPublic(sysContext, handle, 0,
  387. &nvPublic, name, 0);
  388. sys_teardown(sysContext);
  389. break;
  390. case TPM2_HT_TRANSIENT:
  391. case TPM2_HT_PERSISTENT:
  392. sysContext = sys_init_from_tcti_ctx(tcti_context);
  393. if (sysContext == NULL)
  394. return TSS2_SYS_RC_GENERAL_FAILURE;
  395. public.size = 0;
  396. rval = Tss2_Sys_ReadPublic(sysContext, handle, 0,
  397. &public, name, &qualified_name, 0);
  398. sys_teardown(sysContext);
  399. break;
  400. default:
  401. rval = TPM2_RC_SUCCESS;
  402. name->size = sizeof(TPM2_HANDLE);
  403. *(TPM2_HANDLE *)namePtr = BE_TO_HOST_32(handle);
  404. }
  405. return rval;
  406. }
  407. TSS2_RC
  408. KDFa(
  409. TPMI_ALG_HASH hash,
  410. TPM2B *key,
  411. const char *label,
  412. TPM2B *contextU,
  413. TPM2B *contextV,
  414. UINT16 bits,
  415. TPM2B_MAX_BUFFER *result_key)
  416. {
  417. TPM2B_DIGEST digest;
  418. TPM2B_DIGEST tpm2blabel, tpm2bbits, tpm2bctr;
  419. TPM2B_DIGEST *buffer_list[8];
  420. UINT32 counter;
  421. TSS2_RC rval;
  422. int i, j;
  423. UINT16 bytes = bits / 8;
  424. result_key->size = 0;
  425. tpm2bctr.size = 4;
  426. tpm2bbits.size = 4;
  427. counter = BE_TO_HOST_32(bits);
  428. memcpy(tpm2bbits.buffer, &counter, 4);
  429. tpm2blabel.size = strlen(label) + 1;
  430. memcpy(tpm2blabel.buffer, label, tpm2blabel.size);
  431. LOG_DEBUG("KDFA, hash = %4.4x", hash);
  432. LOGBLOB_DEBUG(&key->buffer[0], key->size, "KDFA, key =");
  433. LOGBLOB_DEBUG(&tpm2blabel.buffer[0], tpm2blabel.size, "KDFA, tpm2blabel =");
  434. LOGBLOB_DEBUG(&contextU->buffer[0], contextU->size, "KDFA, contextU =");
  435. LOGBLOB_DEBUG(&contextV->buffer[0], contextV->size, "KDFA, contextV =");
  436. for (i = 1, j = 0; result_key->size < bytes; j = 0) {
  437. counter = BE_TO_HOST_32(i++);
  438. memcpy(tpm2bctr.buffer, &counter, 4);
  439. buffer_list[j++] = (TPM2B_DIGEST *)&tpm2bctr;
  440. buffer_list[j++] = (TPM2B_DIGEST *)&tpm2blabel;
  441. buffer_list[j++] = (TPM2B_DIGEST *)contextU;
  442. buffer_list[j++] = (TPM2B_DIGEST *)contextV;
  443. buffer_list[j++] = (TPM2B_DIGEST *)&tpm2bbits;
  444. buffer_list[j++] = NULL;
  445. for (j = 0; buffer_list[j] != NULL; j++) {
  446. LOGBLOB_DEBUG(&buffer_list[j]->buffer[0], buffer_list[j]->size, "bufferlist[%d]:", j);
  447. ;
  448. }
  449. rval = hmac(hash, key->buffer, key->size, buffer_list, &digest);
  450. if (rval != TPM2_RC_SUCCESS) {
  451. LOGBLOB_ERROR(digest.buffer, digest.size, "HMAC Failed rval = %d", rval);
  452. return rval;
  453. }
  454. ConcatSizedByteBuffer(result_key, (TPM2B *)&digest);
  455. }
  456. /* Truncate the result to the desired size. */
  457. result_key->size = bytes;
  458. LOGBLOB_DEBUG(result_key->buffer, result_key->size, "KDFA, key = ");
  459. return TPM2_RC_SUCCESS;
  460. }
  461. static TSS2_RC
  462. gen_session_key(
  463. SESSION *session,
  464. TPM2B_MAX_BUFFER *session_key,
  465. TPM2B_IV *iv,
  466. TPM2B_AUTH *auth_value)
  467. {
  468. TSS2_RC rval = TSS2_RC_SUCCESS;
  469. UINT32 aes_block_size = 16;
  470. TPM2B_MAX_BUFFER key, sessionValue;
  471. if (iv == NULL || session_key == NULL)
  472. return TSS2_SYS_RC_BAD_VALUE;
  473. CopySizedByteBuffer((TPM2B *)&sessionValue, (TPM2B *)&session->sessionKey);
  474. CatSizedByteBuffer((TPM2B *)&sessionValue, (TPM2B *)auth_value);
  475. rval = KDFa (session->authHash,
  476. (TPM2B *)&sessionValue,
  477. "CFB",
  478. (TPM2B *)&session->nonceNewer,
  479. (TPM2B *)&session->nonceOlder,
  480. session->symmetric.keyBits.sym + aes_block_size * 8,
  481. &key);
  482. if (rval != TSS2_RC_SUCCESS)
  483. return rval;
  484. if (key.size != (session->symmetric.keyBits.sym / 8) + aes_block_size)
  485. return TSS2_SYS_RC_GENERAL_FAILURE;
  486. iv->size = aes_block_size;
  487. session_key->size = (session->symmetric.keyBits.sym) / 8;
  488. UINT16 total_size = session_key->size + iv->size;
  489. if (iv->size > sizeof (iv->buffer) ||
  490. (total_size) > TPM2_MAX_DIGEST_BUFFER)
  491. return TSS2_SYS_RC_GENERAL_FAILURE;
  492. memcpy (iv->buffer, &key.buffer[session_key->size], iv->size);
  493. memcpy (session_key->buffer, key.buffer, session_key->size);
  494. return rval;
  495. }
  496. static TSS2_RC
  497. encrypt_param_cfb(
  498. SESSION *session,
  499. TPM2B_MAX_BUFFER *encrypted_data,
  500. TPM2B_MAX_BUFFER *clear_data,
  501. TPM2B_AUTH *auth_value)
  502. {
  503. TSS2_RC rval = TSS2_RC_SUCCESS;
  504. TPM2B_MAX_BUFFER encryptKey = TPM2B_MAX_BUFFER_INIT;
  505. TPM2B_IV iv = TPM2B_IV_INIT;
  506. rval = gen_session_key(session, &encryptKey, &iv, auth_value);
  507. if (rval)
  508. return rval;
  509. return encrypt_cfb(encrypted_data, clear_data, &encryptKey, &iv);
  510. }
  511. static TSS2_RC
  512. decrypt_param_cfb(
  513. SESSION *session,
  514. TPM2B_MAX_BUFFER *clear_data,
  515. TPM2B_MAX_BUFFER *encrypted_data,
  516. TPM2B_AUTH *auth_value)
  517. {
  518. TSS2_RC rval = TSS2_RC_SUCCESS;
  519. TPM2B_MAX_BUFFER encryptKey = TPM2B_MAX_BUFFER_INIT;
  520. TPM2B_IV iv = TPM2B_IV_INIT;
  521. rval = gen_session_key(session, &encryptKey, &iv, auth_value);
  522. if (rval)
  523. return rval;
  524. return decrypt_cfb(clear_data, encrypted_data, &encryptKey, &iv);
  525. }
  526. static TSS2_RC
  527. encrypt_decrypt_xor(
  528. SESSION *session,
  529. TPM2B_MAX_BUFFER *output_data,
  530. TPM2B_MAX_BUFFER *input_data,
  531. TPM2B_AUTH *auth_value)
  532. {
  533. TSS2_RC rval = TSS2_RC_SUCCESS;
  534. TPM2B_MAX_BUFFER key;
  535. TPM2B_MAX_BUFFER mask = { .size = 0, .buffer = 0 };
  536. UINT16 i;
  537. UINT16 size = input_data->size;
  538. if (size > TPM2_MAX_DIGEST_BUFFER) {
  539. LOG_ERROR("Bad value for inputData size: %" PRIu16, size);
  540. return TSS2_SYS_RC_GENERAL_FAILURE;
  541. }
  542. CopySizedByteBuffer((TPM2B *)&key, (TPM2B *)&session->sessionKey);
  543. CatSizedByteBuffer((TPM2B *)&key, (TPM2B *)auth_value);
  544. rval = KDFa(session->authHash,
  545. (TPM2B *)&key,
  546. "XOR",
  547. (TPM2B *)&session->nonceNewer,
  548. (TPM2B *)&session->nonceOlder,
  549. input_data->size * 8, &mask);
  550. if (rval)
  551. return rval;
  552. for (i = 0; i < size; i++)
  553. output_data->buffer[i] = input_data->buffer[i] ^ mask.buffer[i];
  554. output_data->size = size;
  555. return rval;
  556. }
  557. TSS2_RC
  558. encrypt_command_param(
  559. SESSION *session,
  560. TPM2B_MAX_BUFFER *encrypted_data,
  561. TPM2B_MAX_BUFFER *clear_data,
  562. TPM2B_AUTH *auth_value)
  563. {
  564. return session->symmetric.algorithm == TPM2_ALG_AES ?
  565. encrypt_param_cfb(session, encrypted_data, clear_data, auth_value) :
  566. encrypt_decrypt_xor(session, encrypted_data, clear_data, auth_value);
  567. }
  568. TSS2_RC
  569. decrypt_response_param(
  570. SESSION *session,
  571. TPM2B_MAX_BUFFER *clear_data,
  572. TPM2B_MAX_BUFFER *encrypted_data,
  573. TPM2B_AUTH *auth_value)
  574. {
  575. return session->symmetric.algorithm == TPM2_ALG_AES ?
  576. decrypt_param_cfb(session, clear_data, encrypted_data, auth_value) :
  577. encrypt_decrypt_xor(session, clear_data, encrypted_data, auth_value);
  578. }