-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
KEYS: Add parser for TPM-based keys [ver #2]
For TPM based keys, the only standard seems to be described here: http://david.woodhou.se/draft-woodhouse-cert-best-practice.html#rfc.section.4.4 Quote from the relevant section: "Rather, a common form of storage for "wrapped" keys is to encode the binary TCPA_KEY structure in a single ASN.1 OCTET-STRING, and store the result in PEM format with the tag "-----BEGIN TSS KEY BLOB-----". " This patch implements the above behavior. It is assumed that the PEM encoding is stripped out by userspace and only the raw DER/BER format is provided. This is similar to how PKCS7, PKCS8 and X.509 keys are handled. 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>
- Loading branch information
Denis Kenzior
authored and
James Morris
committed
Oct 26, 2018
1 parent
f8c54e1
commit d5e7274
Showing
4 changed files
with
127 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
-- | ||
-- Unencryted TPM Blob. For details of the format, see: | ||
-- http://david.woodhou.se/draft-woodhouse-cert-best-practice.html#I-D.mavrogiannopoulos-tpmuri | ||
-- | ||
PrivateKeyInfo ::= OCTET STRING ({ tpm_note_key }) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
#define pr_fmt(fmt) "TPM-PARSER: "fmt | ||
#include <linux/module.h> | ||
#include <linux/kernel.h> | ||
#include <linux/export.h> | ||
#include <linux/slab.h> | ||
#include <linux/err.h> | ||
#include <keys/asymmetric-subtype.h> | ||
#include <keys/asymmetric-parser.h> | ||
#include <crypto/asym_tpm_subtype.h> | ||
#include "tpm.asn1.h" | ||
|
||
struct tpm_parse_context { | ||
const void *blob; | ||
u32 blob_len; | ||
}; | ||
|
||
/* | ||
* Note the key data of the ASN.1 blob. | ||
*/ | ||
int tpm_note_key(void *context, size_t hdrlen, | ||
unsigned char tag, | ||
const void *value, size_t vlen) | ||
{ | ||
struct tpm_parse_context *ctx = context; | ||
|
||
ctx->blob = value; | ||
ctx->blob_len = vlen; | ||
|
||
return 0; | ||
} | ||
|
||
/* | ||
* Parse a TPM-encrypted private key blob. | ||
*/ | ||
static struct tpm_key *tpm_parse(const void *data, size_t datalen) | ||
{ | ||
struct tpm_parse_context ctx; | ||
long ret; | ||
|
||
memset(&ctx, 0, sizeof(ctx)); | ||
|
||
/* Attempt to decode the private key */ | ||
ret = asn1_ber_decoder(&tpm_decoder, &ctx, data, datalen); | ||
if (ret < 0) | ||
goto error; | ||
|
||
return tpm_key_create(ctx.blob, ctx.blob_len); | ||
|
||
error: | ||
return ERR_PTR(ret); | ||
} | ||
/* | ||
* Attempt to parse a data blob for a key as a TPM private key blob. | ||
*/ | ||
static int tpm_key_preparse(struct key_preparsed_payload *prep) | ||
{ | ||
struct tpm_key *tk; | ||
|
||
/* | ||
* TPM 1.2 keys are max 2048 bits long, so assume the blob is no | ||
* more than 4x that | ||
*/ | ||
if (prep->datalen > 256 * 4) | ||
return -EMSGSIZE; | ||
|
||
tk = tpm_parse(prep->data, prep->datalen); | ||
|
||
if (IS_ERR(tk)) | ||
return PTR_ERR(tk); | ||
|
||
/* We're pinning the module by being linked against it */ | ||
__module_get(asym_tpm_subtype.owner); | ||
prep->payload.data[asym_subtype] = &asym_tpm_subtype; | ||
prep->payload.data[asym_key_ids] = NULL; | ||
prep->payload.data[asym_crypto] = tk; | ||
prep->payload.data[asym_auth] = NULL; | ||
prep->quotalen = 100; | ||
return 0; | ||
} | ||
|
||
static struct asymmetric_key_parser tpm_key_parser = { | ||
.owner = THIS_MODULE, | ||
.name = "tpm_parser", | ||
.parse = tpm_key_preparse, | ||
}; | ||
|
||
static int __init tpm_key_init(void) | ||
{ | ||
return register_asymmetric_key_parser(&tpm_key_parser); | ||
} | ||
|
||
static void __exit tpm_key_exit(void) | ||
{ | ||
unregister_asymmetric_key_parser(&tpm_key_parser); | ||
} | ||
|
||
module_init(tpm_key_init); | ||
module_exit(tpm_key_exit); | ||
|
||
MODULE_DESCRIPTION("TPM private key-blob parser"); | ||
MODULE_LICENSE("GPL v2"); |