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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'tpmdd-sessions-next-6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd

Pull more tpm updates from Jarkko Sakkinen:
"This is targeted for tpm2-sessions updates.

There's two bug fixes and two more cosmetic tweaks for HMAC protected
sessions. They provide a baseine for further improvements to be
implemented during the the course of the release cycle"

* tag 'tpmdd-sessions-next-6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd:
tpm2-sessions: Open code tpm_buf_append_hmac_session()
tpm2-sessions: Remove 'attributes' parameter from tpm_buf_append_auth
tpm2-sessions: Fix tpm2_read_public range checks
tpm2-sessions: Fix out of range indexing in name_size

+204 -116
+34 -8
drivers/char/tpm/tpm2-cmd.c
··· 11 11 * used by the kernel internally. 12 12 */ 13 13 14 + #include "linux/dev_printk.h" 15 + #include "linux/tpm.h" 14 16 #include "tpm.h" 15 17 #include <crypto/hash_info.h> 18 + #include <linux/unaligned.h> 16 19 17 20 static bool disable_pcr_integrity; 18 21 module_param(disable_pcr_integrity, bool, 0444); ··· 202 199 } 203 200 204 201 if (!disable_pcr_integrity) { 205 - tpm_buf_append_name(chip, &buf, pcr_idx, NULL); 202 + rc = tpm_buf_append_name(chip, &buf, pcr_idx, NULL); 203 + if (rc) { 204 + tpm_buf_destroy(&buf); 205 + return rc; 206 + } 206 207 tpm_buf_append_hmac_session(chip, &buf, 0, NULL, 0); 207 208 } else { 208 209 tpm_buf_append_handle(chip, &buf, pcr_idx); 209 - tpm_buf_append_auth(chip, &buf, 0, NULL, 0); 210 + tpm_buf_append_auth(chip, &buf, NULL, 0); 210 211 } 211 212 212 213 tpm_buf_append_u32(&buf, chip->nr_allocated_banks); ··· 221 214 chip->allocated_banks[i].digest_size); 222 215 } 223 216 224 - if (!disable_pcr_integrity) 225 - tpm_buf_fill_hmac_session(chip, &buf); 217 + if (!disable_pcr_integrity) { 218 + rc = tpm_buf_fill_hmac_session(chip, &buf); 219 + if (rc) { 220 + tpm_buf_destroy(&buf); 221 + return rc; 222 + } 223 + } 224 + 226 225 rc = tpm_transmit_cmd(chip, &buf, 0, "attempting extend a PCR value"); 227 226 if (!disable_pcr_integrity) 228 227 rc = tpm_buf_check_hmac_response(chip, &buf, rc); ··· 282 269 283 270 do { 284 271 tpm_buf_reset(&buf, TPM2_ST_SESSIONS, TPM2_CC_GET_RANDOM); 285 - tpm_buf_append_hmac_session_opt(chip, &buf, TPM2_SA_ENCRYPT 286 - | TPM2_SA_CONTINUE_SESSION, 287 - NULL, 0); 272 + if (tpm2_chip_auth(chip)) { 273 + tpm_buf_append_hmac_session(chip, &buf, 274 + TPM2_SA_ENCRYPT | 275 + TPM2_SA_CONTINUE_SESSION, 276 + NULL, 0); 277 + } else { 278 + offset = buf.handles * 4 + TPM_HEADER_SIZE; 279 + head = (struct tpm_header *)buf.data; 280 + if (tpm_buf_length(&buf) == offset) 281 + head->tag = cpu_to_be16(TPM2_ST_NO_SESSIONS); 282 + } 288 283 tpm_buf_append_u16(&buf, num_bytes); 289 - tpm_buf_fill_hmac_session(chip, &buf); 284 + err = tpm_buf_fill_hmac_session(chip, &buf); 285 + if (err) { 286 + tpm_buf_destroy(&buf); 287 + return err; 288 + } 289 + 290 290 err = tpm_transmit_cmd(chip, &buf, 291 291 offsetof(struct tpm2_get_random_out, 292 292 buffer),
+128 -71
drivers/char/tpm/tpm2-sessions.c
··· 144 144 /* 145 145 * Name Size based on TPM algorithm (assumes no hash bigger than 255) 146 146 */ 147 - static u8 name_size(const u8 *name) 147 + static int name_size(const u8 *name) 148 148 { 149 - static u8 size_map[] = { 150 - [TPM_ALG_SHA1] = SHA1_DIGEST_SIZE, 151 - [TPM_ALG_SHA256] = SHA256_DIGEST_SIZE, 152 - [TPM_ALG_SHA384] = SHA384_DIGEST_SIZE, 153 - [TPM_ALG_SHA512] = SHA512_DIGEST_SIZE, 154 - }; 155 - u16 alg = get_unaligned_be16(name); 156 - return size_map[alg] + 2; 149 + u16 hash_alg = get_unaligned_be16(name); 150 + 151 + switch (hash_alg) { 152 + case TPM_ALG_SHA1: 153 + return SHA1_DIGEST_SIZE + 2; 154 + case TPM_ALG_SHA256: 155 + return SHA256_DIGEST_SIZE + 2; 156 + case TPM_ALG_SHA384: 157 + return SHA384_DIGEST_SIZE + 2; 158 + case TPM_ALG_SHA512: 159 + return SHA512_DIGEST_SIZE + 2; 160 + default: 161 + pr_warn("tpm: unsupported name algorithm: 0x%04x\n", hash_alg); 162 + return -EINVAL; 163 + } 157 164 } 158 165 159 - static int tpm2_parse_read_public(char *name, struct tpm_buf *buf) 166 + static int tpm2_read_public(struct tpm_chip *chip, u32 handle, void *name) 160 167 { 161 - struct tpm_header *head = (struct tpm_header *)buf->data; 168 + u32 mso = tpm2_handle_mso(handle); 162 169 off_t offset = TPM_HEADER_SIZE; 163 - u32 tot_len = be32_to_cpu(head->length); 164 - u32 val; 165 - 166 - /* we're starting after the header so adjust the length */ 167 - tot_len -= TPM_HEADER_SIZE; 168 - 169 - /* skip public */ 170 - val = tpm_buf_read_u16(buf, &offset); 171 - if (val > tot_len) 172 - return -EINVAL; 173 - offset += val; 174 - /* name */ 175 - val = tpm_buf_read_u16(buf, &offset); 176 - if (val != name_size(&buf->data[offset])) 177 - return -EINVAL; 178 - memcpy(name, &buf->data[offset], val); 179 - /* forget the rest */ 180 - return 0; 181 - } 182 - 183 - static int tpm2_read_public(struct tpm_chip *chip, u32 handle, char *name) 184 - { 170 + int rc, name_size_alg; 185 171 struct tpm_buf buf; 186 - int rc; 172 + 173 + if (mso != TPM2_MSO_PERSISTENT && mso != TPM2_MSO_VOLATILE && 174 + mso != TPM2_MSO_NVRAM) { 175 + memcpy(name, &handle, sizeof(u32)); 176 + return sizeof(u32); 177 + } 187 178 188 179 rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_READ_PUBLIC); 189 180 if (rc) 190 181 return rc; 191 182 192 183 tpm_buf_append_u32(&buf, handle); 193 - rc = tpm_transmit_cmd(chip, &buf, 0, "read public"); 194 - if (rc == TPM2_RC_SUCCESS) 195 - rc = tpm2_parse_read_public(name, &buf); 196 184 197 - tpm_buf_destroy(&buf); 185 + rc = tpm_transmit_cmd(chip, &buf, 0, "TPM2_ReadPublic"); 186 + if (rc) { 187 + tpm_buf_destroy(&buf); 188 + return tpm_ret_to_err(rc); 189 + } 198 190 199 - return rc; 191 + /* Skip TPMT_PUBLIC: */ 192 + offset += tpm_buf_read_u16(&buf, &offset); 193 + 194 + /* 195 + * Ensure space for the length field of TPM2B_NAME and hashAlg field of 196 + * TPMT_HA (the extra four bytes). 197 + */ 198 + if (offset + 4 > tpm_buf_length(&buf)) { 199 + tpm_buf_destroy(&buf); 200 + return -EIO; 201 + } 202 + 203 + rc = tpm_buf_read_u16(&buf, &offset); 204 + name_size_alg = name_size(&buf.data[offset]); 205 + 206 + if (name_size_alg < 0) 207 + return name_size_alg; 208 + 209 + if (rc != name_size_alg) { 210 + tpm_buf_destroy(&buf); 211 + return -EIO; 212 + } 213 + 214 + if (offset + rc > tpm_buf_length(&buf)) { 215 + tpm_buf_destroy(&buf); 216 + return -EIO; 217 + } 218 + 219 + memcpy(name, &buf.data[offset], rc); 220 + return name_size_alg; 200 221 } 201 222 #endif /* CONFIG_TCG_TPM2_HMAC */ 202 223 ··· 242 221 * As with most tpm_buf operations, success is assumed because failure 243 222 * will be caused by an incorrect programming model and indicated by a 244 223 * kernel message. 224 + * 225 + * Ends the authorization session on failure. 245 226 */ 246 - void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf, 247 - u32 handle, u8 *name) 227 + int tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf, 228 + u32 handle, u8 *name) 248 229 { 249 230 #ifdef CONFIG_TCG_TPM2_HMAC 250 231 enum tpm2_mso_type mso = tpm2_handle_mso(handle); 251 232 struct tpm2_auth *auth; 233 + u16 name_size_alg; 252 234 int slot; 235 + int ret; 253 236 #endif 254 237 255 238 if (!tpm2_chip_auth(chip)) { 256 239 tpm_buf_append_handle(chip, buf, handle); 257 - return; 240 + return 0; 258 241 } 259 242 260 243 #ifdef CONFIG_TCG_TPM2_HMAC 261 244 slot = (tpm_buf_length(buf) - TPM_HEADER_SIZE) / 4; 262 245 if (slot >= AUTH_MAX_NAMES) { 263 - dev_err(&chip->dev, "TPM: too many handles\n"); 264 - return; 246 + dev_err(&chip->dev, "too many handles\n"); 247 + ret = -EIO; 248 + goto err; 265 249 } 266 250 auth = chip->auth; 267 - WARN(auth->session != tpm_buf_length(buf), 268 - "name added in wrong place\n"); 251 + if (auth->session != tpm_buf_length(buf)) { 252 + dev_err(&chip->dev, "session state malformed"); 253 + ret = -EIO; 254 + goto err; 255 + } 269 256 tpm_buf_append_u32(buf, handle); 270 257 auth->session += 4; 271 258 272 259 if (mso == TPM2_MSO_PERSISTENT || 273 260 mso == TPM2_MSO_VOLATILE || 274 261 mso == TPM2_MSO_NVRAM) { 275 - if (!name) 276 - tpm2_read_public(chip, handle, auth->name[slot]); 262 + if (!name) { 263 + ret = tpm2_read_public(chip, handle, auth->name[slot]); 264 + if (ret < 0) 265 + goto err; 266 + 267 + name_size_alg = ret; 268 + } 277 269 } else { 278 - if (name) 279 - dev_err(&chip->dev, "TPM: Handle does not require name but one is specified\n"); 270 + if (name) { 271 + dev_err(&chip->dev, "handle 0x%08x does not use a name\n", 272 + handle); 273 + ret = -EIO; 274 + goto err; 275 + } 280 276 } 281 277 282 278 auth->name_h[slot] = handle; 283 279 if (name) 284 - memcpy(auth->name[slot], name, name_size(name)); 280 + memcpy(auth->name[slot], name, name_size_alg); 281 + #endif 282 + return 0; 283 + 284 + #ifdef CONFIG_TCG_TPM2_HMAC 285 + err: 286 + tpm2_end_auth_session(chip); 287 + return tpm_ret_to_err(ret); 285 288 #endif 286 289 } 287 290 EXPORT_SYMBOL_GPL(tpm_buf_append_name); 288 291 289 292 void tpm_buf_append_auth(struct tpm_chip *chip, struct tpm_buf *buf, 290 - u8 attributes, u8 *passphrase, int passphrase_len) 293 + u8 *passphrase, int passphrase_len) 291 294 { 292 295 /* offset tells us where the sessions area begins */ 293 296 int offset = buf->handles * 4 + TPM_HEADER_SIZE; ··· 372 327 #endif 373 328 374 329 if (!tpm2_chip_auth(chip)) { 375 - tpm_buf_append_auth(chip, buf, attributes, passphrase, 376 - passphrase_len); 330 + tpm_buf_append_auth(chip, buf, passphrase, passphrase_len); 377 331 return; 378 332 } 379 333 ··· 577 533 * encryption key and encrypts the first parameter of the command 578 534 * buffer with it. 579 535 * 580 - * As with most tpm_buf operations, success is assumed because failure 581 - * will be caused by an incorrect programming model and indicated by a 582 - * kernel message. 536 + * Ends the authorization session on failure. 583 537 */ 584 - void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf) 538 + int tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf) 585 539 { 586 540 u32 cc, handles, val; 587 541 struct tpm2_auth *auth = chip->auth; ··· 591 549 u8 cphash[SHA256_DIGEST_SIZE]; 592 550 struct sha256_ctx sctx; 593 551 struct hmac_sha256_ctx hctx; 552 + int ret; 594 553 595 - if (!auth) 596 - return; 554 + if (!auth) { 555 + ret = -EIO; 556 + goto err; 557 + } 597 558 598 559 /* save the command code in BE format */ 599 560 auth->ordinal = head->ordinal; ··· 605 560 606 561 i = tpm2_find_cc(chip, cc); 607 562 if (i < 0) { 608 - dev_err(&chip->dev, "Command 0x%x not found in TPM\n", cc); 609 - return; 563 + dev_err(&chip->dev, "command 0x%08x not found\n", cc); 564 + ret = -EIO; 565 + goto err; 610 566 } 567 + 611 568 attrs = chip->cc_attrs_tbl[i]; 612 569 613 570 handles = (attrs >> TPM2_CC_ATTR_CHANDLES) & GENMASK(2, 0); ··· 623 576 u32 handle = tpm_buf_read_u32(buf, &offset_s); 624 577 625 578 if (auth->name_h[i] != handle) { 626 - dev_err(&chip->dev, "TPM: handle %d wrong for name\n", 627 - i); 628 - return; 579 + dev_err(&chip->dev, "invalid handle 0x%08x\n", handle); 580 + ret = -EIO; 581 + goto err; 629 582 } 630 583 } 631 584 /* point offset_s to the start of the sessions */ ··· 656 609 offset_s += len; 657 610 } 658 611 if (offset_s != offset_p) { 659 - dev_err(&chip->dev, "TPM session length is incorrect\n"); 660 - return; 612 + dev_err(&chip->dev, "session length is incorrect\n"); 613 + ret = -EIO; 614 + goto err; 661 615 } 662 616 if (!hmac) { 663 - dev_err(&chip->dev, "TPM could not find HMAC session\n"); 664 - return; 617 + dev_err(&chip->dev, "could not find HMAC session\n"); 618 + ret = -EIO; 619 + goto err; 665 620 } 666 621 667 622 /* encrypt before HMAC */ ··· 695 646 if (mso == TPM2_MSO_PERSISTENT || 696 647 mso == TPM2_MSO_VOLATILE || 697 648 mso == TPM2_MSO_NVRAM) { 698 - sha256_update(&sctx, auth->name[i], 699 - name_size(auth->name[i])); 649 + ret = name_size(auth->name[i]); 650 + if (ret < 0) 651 + goto err; 652 + 653 + sha256_update(&sctx, auth->name[i], ret); 700 654 } else { 701 655 __be32 h = cpu_to_be32(auth->name_h[i]); 702 656 ··· 720 668 hmac_sha256_update(&hctx, auth->tpm_nonce, sizeof(auth->tpm_nonce)); 721 669 hmac_sha256_update(&hctx, &auth->attrs, 1); 722 670 hmac_sha256_final(&hctx, hmac); 671 + return 0; 672 + 673 + err: 674 + tpm2_end_auth_session(chip); 675 + return ret; 723 676 } 724 677 EXPORT_SYMBOL(tpm_buf_fill_hmac_session); 725 678
+9 -29
include/linux/tpm.h
··· 529 529 #endif 530 530 } 531 531 532 - void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf, 533 - u32 handle, u8 *name); 532 + int tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf, 533 + u32 handle, u8 *name); 534 534 void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf, 535 535 u8 attributes, u8 *passphrase, 536 536 int passphraselen); 537 537 void tpm_buf_append_auth(struct tpm_chip *chip, struct tpm_buf *buf, 538 - u8 attributes, u8 *passphrase, int passphraselen); 539 - static inline void tpm_buf_append_hmac_session_opt(struct tpm_chip *chip, 540 - struct tpm_buf *buf, 541 - u8 attributes, 542 - u8 *passphrase, 543 - int passphraselen) 544 - { 545 - struct tpm_header *head; 546 - int offset; 547 - 548 - if (tpm2_chip_auth(chip)) { 549 - tpm_buf_append_hmac_session(chip, buf, attributes, passphrase, passphraselen); 550 - } else { 551 - offset = buf->handles * 4 + TPM_HEADER_SIZE; 552 - head = (struct tpm_header *)buf->data; 553 - 554 - /* 555 - * If the only sessions are optional, the command tag must change to 556 - * TPM2_ST_NO_SESSIONS. 557 - */ 558 - if (tpm_buf_length(buf) == offset) 559 - head->tag = cpu_to_be16(TPM2_ST_NO_SESSIONS); 560 - } 561 - } 538 + u8 *passphrase, int passphraselen); 562 539 563 540 #ifdef CONFIG_TCG_TPM2_HMAC 564 541 565 542 int tpm2_start_auth_session(struct tpm_chip *chip); 566 - void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf); 543 + int tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf); 567 544 int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf, 568 545 int rc); 569 546 void tpm2_end_auth_session(struct tpm_chip *chip); ··· 554 577 static inline void tpm2_end_auth_session(struct tpm_chip *chip) 555 578 { 556 579 } 557 - static inline void tpm_buf_fill_hmac_session(struct tpm_chip *chip, 558 - struct tpm_buf *buf) 580 + 581 + static inline int tpm_buf_fill_hmac_session(struct tpm_chip *chip, 582 + struct tpm_buf *buf) 559 583 { 584 + return 0; 560 585 } 586 + 561 587 static inline int tpm_buf_check_hmac_response(struct tpm_chip *chip, 562 588 struct tpm_buf *buf, 563 589 int rc)
+33 -8
security/keys/trusted-keys/trusted_tpm2.c
··· 268 268 goto out_put; 269 269 } 270 270 271 - tpm_buf_append_name(chip, &buf, options->keyhandle, NULL); 271 + rc = tpm_buf_append_name(chip, &buf, options->keyhandle, NULL); 272 + if (rc) 273 + goto out; 274 + 272 275 tpm_buf_append_hmac_session(chip, &buf, TPM2_SA_DECRYPT, 273 276 options->keyauth, TPM_DIGEST_SIZE); 274 277 ··· 319 316 goto out; 320 317 } 321 318 322 - tpm_buf_fill_hmac_session(chip, &buf); 319 + rc = tpm_buf_fill_hmac_session(chip, &buf); 320 + if (rc) 321 + goto out; 322 + 323 323 rc = tpm_transmit_cmd(chip, &buf, 4, "sealing data"); 324 324 rc = tpm_buf_check_hmac_response(chip, &buf, rc); 325 325 if (rc) ··· 433 427 return rc; 434 428 } 435 429 436 - tpm_buf_append_name(chip, &buf, options->keyhandle, NULL); 430 + rc = tpm_buf_append_name(chip, &buf, options->keyhandle, NULL); 431 + if (rc) 432 + goto out; 433 + 437 434 tpm_buf_append_hmac_session(chip, &buf, 0, options->keyauth, 438 435 TPM_DIGEST_SIZE); 439 436 ··· 448 439 goto out; 449 440 } 450 441 451 - tpm_buf_fill_hmac_session(chip, &buf); 442 + rc = tpm_buf_fill_hmac_session(chip, &buf); 443 + if (rc) 444 + goto out; 445 + 452 446 rc = tpm_transmit_cmd(chip, &buf, 4, "loading blob"); 453 447 rc = tpm_buf_check_hmac_response(chip, &buf, rc); 454 448 if (!rc) ··· 481 469 struct trusted_key_options *options, 482 470 u32 blob_handle) 483 471 { 472 + struct tpm_header *head; 484 473 struct tpm_buf buf; 485 474 u16 data_len; 475 + int offset; 486 476 u8 *data; 487 477 int rc; 488 478 ··· 498 484 return rc; 499 485 } 500 486 501 - tpm_buf_append_name(chip, &buf, blob_handle, NULL); 487 + rc = tpm_buf_append_name(chip, &buf, options->keyhandle, NULL); 488 + if (rc) 489 + goto out; 502 490 503 491 if (!options->policyhandle) { 504 492 tpm_buf_append_hmac_session(chip, &buf, TPM2_SA_ENCRYPT, ··· 521 505 tpm2_buf_append_auth(&buf, options->policyhandle, 522 506 NULL /* nonce */, 0, 0, 523 507 options->blobauth, options->blobauth_len); 524 - tpm_buf_append_hmac_session_opt(chip, &buf, TPM2_SA_ENCRYPT, 525 - NULL, 0); 508 + if (tpm2_chip_auth(chip)) { 509 + tpm_buf_append_hmac_session(chip, &buf, TPM2_SA_ENCRYPT, NULL, 0); 510 + } else { 511 + offset = buf.handles * 4 + TPM_HEADER_SIZE; 512 + head = (struct tpm_header *)buf.data; 513 + if (tpm_buf_length(&buf) == offset) 514 + head->tag = cpu_to_be16(TPM2_ST_NO_SESSIONS); 515 + } 526 516 } 527 517 528 - tpm_buf_fill_hmac_session(chip, &buf); 518 + rc = tpm_buf_fill_hmac_session(chip, &buf); 519 + if (rc) 520 + goto out; 521 + 529 522 rc = tpm_transmit_cmd(chip, &buf, 6, "unsealing"); 530 523 rc = tpm_buf_check_hmac_response(chip, &buf, rc); 531 524