diff options
author | Denis Kenzior <denkenz@gmail.com> | 2018-10-09 17:49:13 +0100 |
---|---|---|
committer | James Morris <james.morris@microsoft.com> | 2018-10-26 09:30:47 +0100 |
commit | a335974ae0883e045151a2160093a22aa02c3626 (patch) | |
tree | 90f9e64662c93ffaea99de3dc9097550ccd6020a /crypto | |
parent | f884fe5a158f750e232b029e1fac0283e388e062 (diff) | |
download | linux-stable-a335974ae0883e045151a2160093a22aa02c3626.tar.gz linux-stable-a335974ae0883e045151a2160093a22aa02c3626.tar.bz2 linux-stable-a335974ae0883e045151a2160093a22aa02c3626.zip |
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>
Diffstat (limited to 'crypto')
-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, info->max_enc_size = len; info->max_dec_size = tk->key_len / 8; - info->supported_ops = KEYCTL_SUPPORTS_ENCRYPT; + info->supported_ops = KEYCTL_SUPPORTS_ENCRYPT | + KEYCTL_SUPPORTS_DECRYPT; ret = 0; error_free_tfm: @@ -411,6 +412,58 @@ error_free_tfm: } /* + * Decryption operation is performed with the private key in the TPM. + */ +static int tpm_key_decrypt(struct tpm_key *tk, + struct kernel_pkey_params *params, + const void *in, void *out) +{ + struct tpm_buf *tb; + uint32_t keyhandle; + uint8_t srkauth[SHA1_DIGEST_SIZE]; + uint8_t keyauth[SHA1_DIGEST_SIZE]; + int r; + + pr_devel("==>%s()\n", __func__); + + if (params->hash_algo) + return -ENOPKG; + + if (strcmp(params->encoding, "pkcs1")) + return -ENOPKG; + + tb = kzalloc(sizeof(*tb), GFP_KERNEL); + if (!tb) + return -ENOMEM; + + /* TODO: Handle a non-all zero SRK authorization */ + memset(srkauth, 0, sizeof(srkauth)); + + r = tpm_loadkey2(tb, SRKHANDLE, srkauth, + tk->blob, tk->blob_len, &keyhandle); + if (r < 0) { + pr_devel("loadkey2 failed (%d)\n", r); + goto error; + } + + /* TODO: Handle a non-all zero key authorization */ + memset(keyauth, 0, sizeof(keyauth)); + + r = tpm_unbind(tb, keyhandle, keyauth, + in, params->in_len, out, params->out_len); + if (r < 0) + pr_devel("tpm_unbind failed (%d)\n", r); + + if (tpm_flushspecific(tb, keyhandle) < 0) + pr_devel("flushspecific failed (%d)\n", r); + +error: + kzfree(tb); + pr_devel("<==%s() = %d\n", __func__, r); + return r; +} + +/* * Do encryption, decryption and signing ops. */ 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, case kernel_pkey_encrypt: ret = tpm_key_encrypt(tk, params, in, out); break; + case kernel_pkey_decrypt: + ret = tpm_key_decrypt(tk, params, in, out); + break; default: BUG(); } |