diff options
Diffstat (limited to 'security/keys/trusted.c')
-rw-r--r-- | security/keys/trusted.c | 54 |
1 files changed, 12 insertions, 42 deletions
diff --git a/security/keys/trusted.c b/security/keys/trusted.c index 2d5d041f2049..3f163d0489ad 100644 --- a/security/keys/trusted.c +++ b/security/keys/trusted.c | |||
@@ -369,38 +369,6 @@ static int trusted_tpm_send(const u32 chip_num, unsigned char *cmd, | |||
369 | } | 369 | } |
370 | 370 | ||
371 | /* | 371 | /* |
372 | * get a random value from TPM | ||
373 | */ | ||
374 | static int tpm_get_random(struct tpm_buf *tb, unsigned char *buf, uint32_t len) | ||
375 | { | ||
376 | int ret; | ||
377 | |||
378 | INIT_BUF(tb); | ||
379 | store16(tb, TPM_TAG_RQU_COMMAND); | ||
380 | store32(tb, TPM_GETRANDOM_SIZE); | ||
381 | store32(tb, TPM_ORD_GETRANDOM); | ||
382 | store32(tb, len); | ||
383 | ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, sizeof tb->data); | ||
384 | if (!ret) | ||
385 | memcpy(buf, tb->data + TPM_GETRANDOM_SIZE, len); | ||
386 | return ret; | ||
387 | } | ||
388 | |||
389 | static int my_get_random(unsigned char *buf, int len) | ||
390 | { | ||
391 | struct tpm_buf *tb; | ||
392 | int ret; | ||
393 | |||
394 | tb = kmalloc(sizeof *tb, GFP_KERNEL); | ||
395 | if (!tb) | ||
396 | return -ENOMEM; | ||
397 | ret = tpm_get_random(tb, buf, len); | ||
398 | |||
399 | kfree(tb); | ||
400 | return ret; | ||
401 | } | ||
402 | |||
403 | /* | ||
404 | * Lock a trusted key, by extending a selected PCR. | 372 | * Lock a trusted key, by extending a selected PCR. |
405 | * | 373 | * |
406 | * Prevents a trusted key that is sealed to PCRs from being accessed. | 374 | * Prevents a trusted key that is sealed to PCRs from being accessed. |
@@ -413,8 +381,8 @@ static int pcrlock(const int pcrnum) | |||
413 | 381 | ||
414 | if (!capable(CAP_SYS_ADMIN)) | 382 | if (!capable(CAP_SYS_ADMIN)) |
415 | return -EPERM; | 383 | return -EPERM; |
416 | ret = my_get_random(hash, SHA1_DIGEST_SIZE); | 384 | ret = tpm_get_random(TPM_ANY_NUM, hash, SHA1_DIGEST_SIZE); |
417 | if (ret < 0) | 385 | if (ret != SHA1_DIGEST_SIZE) |
418 | return ret; | 386 | return ret; |
419 | return tpm_pcr_extend(TPM_ANY_NUM, pcrnum, hash) ? -EINVAL : 0; | 387 | return tpm_pcr_extend(TPM_ANY_NUM, pcrnum, hash) ? -EINVAL : 0; |
420 | } | 388 | } |
@@ -429,8 +397,8 @@ static int osap(struct tpm_buf *tb, struct osapsess *s, | |||
429 | unsigned char ononce[TPM_NONCE_SIZE]; | 397 | unsigned char ononce[TPM_NONCE_SIZE]; |
430 | int ret; | 398 | int ret; |
431 | 399 | ||
432 | ret = tpm_get_random(tb, ononce, TPM_NONCE_SIZE); | 400 | ret = tpm_get_random(TPM_ANY_NUM, ononce, TPM_NONCE_SIZE); |
433 | if (ret < 0) | 401 | if (ret != TPM_NONCE_SIZE) |
434 | return ret; | 402 | return ret; |
435 | 403 | ||
436 | INIT_BUF(tb); | 404 | INIT_BUF(tb); |
@@ -524,8 +492,8 @@ static int tpm_seal(struct tpm_buf *tb, uint16_t keytype, | |||
524 | if (ret < 0) | 492 | if (ret < 0) |
525 | goto out; | 493 | goto out; |
526 | 494 | ||
527 | ret = tpm_get_random(tb, td->nonceodd, TPM_NONCE_SIZE); | 495 | ret = tpm_get_random(TPM_ANY_NUM, td->nonceodd, TPM_NONCE_SIZE); |
528 | if (ret < 0) | 496 | if (ret != TPM_NONCE_SIZE) |
529 | goto out; | 497 | goto out; |
530 | ordinal = htonl(TPM_ORD_SEAL); | 498 | ordinal = htonl(TPM_ORD_SEAL); |
531 | datsize = htonl(datalen); | 499 | datsize = htonl(datalen); |
@@ -634,8 +602,8 @@ static int tpm_unseal(struct tpm_buf *tb, | |||
634 | 602 | ||
635 | ordinal = htonl(TPM_ORD_UNSEAL); | 603 | ordinal = htonl(TPM_ORD_UNSEAL); |
636 | keyhndl = htonl(SRKHANDLE); | 604 | keyhndl = htonl(SRKHANDLE); |
637 | ret = tpm_get_random(tb, nonceodd, TPM_NONCE_SIZE); | 605 | ret = tpm_get_random(TPM_ANY_NUM, nonceodd, TPM_NONCE_SIZE); |
638 | if (ret < 0) { | 606 | if (ret != TPM_NONCE_SIZE) { |
639 | pr_info("trusted_key: tpm_get_random failed (%d)\n", ret); | 607 | pr_info("trusted_key: tpm_get_random failed (%d)\n", ret); |
640 | return ret; | 608 | return ret; |
641 | } | 609 | } |
@@ -935,6 +903,7 @@ static int trusted_instantiate(struct key *key, const void *data, | |||
935 | char *datablob; | 903 | char *datablob; |
936 | int ret = 0; | 904 | int ret = 0; |
937 | int key_cmd; | 905 | int key_cmd; |
906 | size_t key_len; | ||
938 | 907 | ||
939 | if (datalen <= 0 || datalen > 32767 || !data) | 908 | if (datalen <= 0 || datalen > 32767 || !data) |
940 | return -EINVAL; | 909 | return -EINVAL; |
@@ -974,8 +943,9 @@ static int trusted_instantiate(struct key *key, const void *data, | |||
974 | pr_info("trusted_key: key_unseal failed (%d)\n", ret); | 943 | pr_info("trusted_key: key_unseal failed (%d)\n", ret); |
975 | break; | 944 | break; |
976 | case Opt_new: | 945 | case Opt_new: |
977 | ret = my_get_random(payload->key, payload->key_len); | 946 | key_len = payload->key_len; |
978 | if (ret < 0) { | 947 | ret = tpm_get_random(TPM_ANY_NUM, payload->key, key_len); |
948 | if (ret != key_len) { | ||
979 | pr_info("trusted_key: key_create failed (%d)\n", ret); | 949 | pr_info("trusted_key: key_create failed (%d)\n", ret); |
980 | goto out; | 950 | goto out; |
981 | } | 951 | } |