aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Kenzior <denkenz@gmail.com>2018-10-09 12:49:13 -0400
committerJames Morris <james.morris@microsoft.com>2018-10-26 04:30:47 -0400
commita335974ae0883e045151a2160093a22aa02c3626 (patch)
tree90f9e64662c93ffaea99de3dc9097550ccd6020a
parentf884fe5a158f750e232b029e1fac0283e388e062 (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.c58
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;
347error_free_tfm: 348error_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 */
417static 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
460error:
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 */
416static int tpm_key_eds_op(struct kernel_pkey_params *params, 469static 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 }