diff options
author | Denis Kenzior <denkenz@gmail.com> | 2018-10-09 12:49:13 -0400 |
---|---|---|
committer | James Morris <james.morris@microsoft.com> | 2018-10-26 04:30:47 -0400 |
commit | a335974ae0883e045151a2160093a22aa02c3626 (patch) | |
tree | 90f9e64662c93ffaea99de3dc9097550ccd6020a | |
parent | f884fe5a158f750e232b029e1fac0283e388e062 (diff) |
KEYS: asym_tpm: Implement the decrypt operation [ver #2]
This patch implements the pkey_decrypt operation using the private key
blob. The blob is first loaded into the TPM via tpm_loadkey2. Once the
handle is obtained, tpm_unbind operation is used to decrypt the data on
the TPM and the result is returned. The key loaded by tpm_loadkey2 is
then evicted via tpm_flushspecific operation.
This patch assumes that the SRK authorization is a well known 20-byte of
zeros and the same holds for the key authorization of the provided key.
Signed-off-by: Denis Kenzior <denkenz@gmail.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Tested-by: Marcel Holtmann <marcel@holtmann.org>
Reviewed-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: James Morris <james.morris@microsoft.com>
-rw-r--r-- | crypto/asymmetric_keys/asym_tpm.c | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/crypto/asymmetric_keys/asym_tpm.c b/crypto/asymmetric_keys/asym_tpm.c index e893b5212222..6f5d5cf98910 100644 --- a/crypto/asymmetric_keys/asym_tpm.c +++ b/crypto/asymmetric_keys/asym_tpm.c | |||
@@ -341,7 +341,8 @@ static int tpm_key_query(const struct kernel_pkey_params *params, | |||
341 | info->max_enc_size = len; | 341 | info->max_enc_size = len; |
342 | info->max_dec_size = tk->key_len / 8; | 342 | info->max_dec_size = tk->key_len / 8; |
343 | 343 | ||
344 | info->supported_ops = KEYCTL_SUPPORTS_ENCRYPT; | 344 | info->supported_ops = KEYCTL_SUPPORTS_ENCRYPT | |
345 | KEYCTL_SUPPORTS_DECRYPT; | ||
345 | 346 | ||
346 | ret = 0; | 347 | ret = 0; |
347 | error_free_tfm: | 348 | error_free_tfm: |
@@ -411,6 +412,58 @@ error_free_tfm: | |||
411 | } | 412 | } |
412 | 413 | ||
413 | /* | 414 | /* |
415 | * Decryption operation is performed with the private key in the TPM. | ||
416 | */ | ||
417 | static int tpm_key_decrypt(struct tpm_key *tk, | ||
418 | struct kernel_pkey_params *params, | ||
419 | const void *in, void *out) | ||
420 | { | ||
421 | struct tpm_buf *tb; | ||
422 | uint32_t keyhandle; | ||
423 | uint8_t srkauth[SHA1_DIGEST_SIZE]; | ||
424 | uint8_t keyauth[SHA1_DIGEST_SIZE]; | ||
425 | int r; | ||
426 | |||
427 | pr_devel("==>%s()\n", __func__); | ||
428 | |||
429 | if (params->hash_algo) | ||
430 | return -ENOPKG; | ||
431 | |||
432 | if (strcmp(params->encoding, "pkcs1")) | ||
433 | return -ENOPKG; | ||
434 | |||
435 | tb = kzalloc(sizeof(*tb), GFP_KERNEL); | ||
436 | if (!tb) | ||
437 | return -ENOMEM; | ||
438 | |||
439 | /* TODO: Handle a non-all zero SRK authorization */ | ||
440 | memset(srkauth, 0, sizeof(srkauth)); | ||
441 | |||
442 | r = tpm_loadkey2(tb, SRKHANDLE, srkauth, | ||
443 | tk->blob, tk->blob_len, &keyhandle); | ||
444 | if (r < 0) { | ||
445 | pr_devel("loadkey2 failed (%d)\n", r); | ||
446 | goto error; | ||
447 | } | ||
448 | |||
449 | /* TODO: Handle a non-all zero key authorization */ | ||
450 | memset(keyauth, 0, sizeof(keyauth)); | ||
451 | |||
452 | r = tpm_unbind(tb, keyhandle, keyauth, | ||
453 | in, params->in_len, out, params->out_len); | ||
454 | if (r < 0) | ||
455 | pr_devel("tpm_unbind failed (%d)\n", r); | ||
456 | |||
457 | if (tpm_flushspecific(tb, keyhandle) < 0) | ||
458 | pr_devel("flushspecific failed (%d)\n", r); | ||
459 | |||
460 | error: | ||
461 | kzfree(tb); | ||
462 | pr_devel("<==%s() = %d\n", __func__, r); | ||
463 | return r; | ||
464 | } | ||
465 | |||
466 | /* | ||
414 | * Do encryption, decryption and signing ops. | 467 | * Do encryption, decryption and signing ops. |
415 | */ | 468 | */ |
416 | static int tpm_key_eds_op(struct kernel_pkey_params *params, | 469 | static int tpm_key_eds_op(struct kernel_pkey_params *params, |
@@ -424,6 +477,9 @@ static int tpm_key_eds_op(struct kernel_pkey_params *params, | |||
424 | case kernel_pkey_encrypt: | 477 | case kernel_pkey_encrypt: |
425 | ret = tpm_key_encrypt(tk, params, in, out); | 478 | ret = tpm_key_encrypt(tk, params, in, out); |
426 | break; | 479 | break; |
480 | case kernel_pkey_decrypt: | ||
481 | ret = tpm_key_decrypt(tk, params, in, out); | ||
482 | break; | ||
427 | default: | 483 | default: |
428 | BUG(); | 484 | BUG(); |
429 | } | 485 | } |