Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tpm: Use HMAC-SHA256 library instead of open-coded HMAC

Now that there are easy-to-use HMAC-SHA256 library functions, use these
in tpm2-sessions.c instead of open-coding the HMAC algorithm.

Note that the new implementation correctly handles keys longer than 64
bytes (SHA256_BLOCK_SIZE), whereas the old implementation handled such
keys incorrectly. But it doesn't appear that such keys were being used.

Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>

authored by

Eric Biggers and committed by
Jarkko Sakkinen
64a7cfbc 2c2615c8

+27 -71
+27 -71
drivers/char/tpm/tpm2-sessions.c
··· 69 69 #include <linux/unaligned.h> 70 70 #include <crypto/kpp.h> 71 71 #include <crypto/ecdh.h> 72 - #include <crypto/hash.h> 73 - #include <crypto/hmac.h> 72 + #include <crypto/sha2.h> 74 73 #include <crypto/utils.h> 75 74 76 75 /* maximum number of names the TPM must remember for authorization */ ··· 385 386 u32 *handle, u8 *name); 386 387 387 388 /* 388 - * It turns out the crypto hmac(sha256) is hard for us to consume 389 - * because it assumes a fixed key and the TPM seems to change the key 390 - * on every operation, so we weld the hmac init and final functions in 391 - * here to give it the same usage characteristics as a regular hash 392 - */ 393 - static void tpm2_hmac_init(struct sha256_ctx *sctx, u8 *key, u32 key_len) 394 - { 395 - u8 pad[SHA256_BLOCK_SIZE]; 396 - int i; 397 - 398 - sha256_init(sctx); 399 - for (i = 0; i < sizeof(pad); i++) { 400 - if (i < key_len) 401 - pad[i] = key[i]; 402 - else 403 - pad[i] = 0; 404 - pad[i] ^= HMAC_IPAD_VALUE; 405 - } 406 - sha256_update(sctx, pad, sizeof(pad)); 407 - } 408 - 409 - static void tpm2_hmac_final(struct sha256_ctx *sctx, u8 *key, u32 key_len, 410 - u8 *out) 411 - { 412 - u8 pad[SHA256_BLOCK_SIZE]; 413 - int i; 414 - 415 - for (i = 0; i < sizeof(pad); i++) { 416 - if (i < key_len) 417 - pad[i] = key[i]; 418 - else 419 - pad[i] = 0; 420 - pad[i] ^= HMAC_OPAD_VALUE; 421 - } 422 - 423 - /* collect the final hash; use out as temporary storage */ 424 - sha256_final(sctx, out); 425 - 426 - sha256_init(sctx); 427 - sha256_update(sctx, pad, sizeof(pad)); 428 - sha256_update(sctx, out, SHA256_DIGEST_SIZE); 429 - sha256_final(sctx, out); 430 - } 431 - 432 - /* 433 389 * assume hash sha256 and nonces u, v of size SHA256_DIGEST_SIZE but 434 390 * otherwise standard tpm2_KDFa. Note output is in bytes not bits. 435 391 */ ··· 395 441 const __be32 bits = cpu_to_be32(bytes * 8); 396 442 397 443 while (bytes > 0) { 398 - struct sha256_ctx sctx; 444 + struct hmac_sha256_ctx hctx; 399 445 __be32 c = cpu_to_be32(counter); 400 446 401 - tpm2_hmac_init(&sctx, key, key_len); 402 - sha256_update(&sctx, (u8 *)&c, sizeof(c)); 403 - sha256_update(&sctx, label, strlen(label)+1); 404 - sha256_update(&sctx, u, SHA256_DIGEST_SIZE); 405 - sha256_update(&sctx, v, SHA256_DIGEST_SIZE); 406 - sha256_update(&sctx, (u8 *)&bits, sizeof(bits)); 407 - tpm2_hmac_final(&sctx, key, key_len, out); 447 + hmac_sha256_init_usingrawkey(&hctx, key, key_len); 448 + hmac_sha256_update(&hctx, (u8 *)&c, sizeof(c)); 449 + hmac_sha256_update(&hctx, label, strlen(label) + 1); 450 + hmac_sha256_update(&hctx, u, SHA256_DIGEST_SIZE); 451 + hmac_sha256_update(&hctx, v, SHA256_DIGEST_SIZE); 452 + hmac_sha256_update(&hctx, (u8 *)&bits, sizeof(bits)); 453 + hmac_sha256_final(&hctx, out); 408 454 409 455 bytes -= SHA256_DIGEST_SIZE; 410 456 counter++; ··· 548 594 u32 attrs; 549 595 u8 cphash[SHA256_DIGEST_SIZE]; 550 596 struct sha256_ctx sctx; 597 + struct hmac_sha256_ctx hctx; 551 598 552 599 if (!auth) 553 600 return; ··· 660 705 sha256_final(&sctx, cphash); 661 706 662 707 /* now calculate the hmac */ 663 - tpm2_hmac_init(&sctx, auth->session_key, sizeof(auth->session_key) 664 - + auth->passphrase_len); 665 - sha256_update(&sctx, cphash, sizeof(cphash)); 666 - sha256_update(&sctx, auth->our_nonce, sizeof(auth->our_nonce)); 667 - sha256_update(&sctx, auth->tpm_nonce, sizeof(auth->tpm_nonce)); 668 - sha256_update(&sctx, &auth->attrs, 1); 669 - tpm2_hmac_final(&sctx, auth->session_key, sizeof(auth->session_key) 670 - + auth->passphrase_len, hmac); 708 + hmac_sha256_init_usingrawkey(&hctx, auth->session_key, 709 + sizeof(auth->session_key) + 710 + auth->passphrase_len); 711 + hmac_sha256_update(&hctx, cphash, sizeof(cphash)); 712 + hmac_sha256_update(&hctx, auth->our_nonce, sizeof(auth->our_nonce)); 713 + hmac_sha256_update(&hctx, auth->tpm_nonce, sizeof(auth->tpm_nonce)); 714 + hmac_sha256_update(&hctx, &auth->attrs, 1); 715 + hmac_sha256_final(&hctx, hmac); 671 716 } 672 717 EXPORT_SYMBOL(tpm_buf_fill_hmac_session); 673 718 ··· 707 752 u8 rphash[SHA256_DIGEST_SIZE]; 708 753 u32 attrs, cc; 709 754 struct sha256_ctx sctx; 755 + struct hmac_sha256_ctx hctx; 710 756 u16 tag = be16_to_cpu(head->tag); 711 757 int parm_len, len, i, handles; 712 758 ··· 777 821 sha256_final(&sctx, rphash); 778 822 779 823 /* now calculate the hmac */ 780 - tpm2_hmac_init(&sctx, auth->session_key, sizeof(auth->session_key) 781 - + auth->passphrase_len); 782 - sha256_update(&sctx, rphash, sizeof(rphash)); 783 - sha256_update(&sctx, auth->tpm_nonce, sizeof(auth->tpm_nonce)); 784 - sha256_update(&sctx, auth->our_nonce, sizeof(auth->our_nonce)); 785 - sha256_update(&sctx, &auth->attrs, 1); 824 + hmac_sha256_init_usingrawkey(&hctx, auth->session_key, 825 + sizeof(auth->session_key) + 826 + auth->passphrase_len); 827 + hmac_sha256_update(&hctx, rphash, sizeof(rphash)); 828 + hmac_sha256_update(&hctx, auth->tpm_nonce, sizeof(auth->tpm_nonce)); 829 + hmac_sha256_update(&hctx, auth->our_nonce, sizeof(auth->our_nonce)); 830 + hmac_sha256_update(&hctx, &auth->attrs, 1); 786 831 /* we're done with the rphash, so put our idea of the hmac there */ 787 - tpm2_hmac_final(&sctx, auth->session_key, sizeof(auth->session_key) 788 - + auth->passphrase_len, rphash); 832 + hmac_sha256_final(&hctx, rphash); 789 833 if (crypto_memneq(rphash, &buf->data[offset_s], SHA256_DIGEST_SIZE)) { 790 834 dev_err(&chip->dev, "TPM: HMAC check failed\n"); 791 835 goto out;