1// SPDX-License-Identifier: GPL-2.0 2#define pr_fmt(fmt) "TPM-PARSER: "fmt 3#include <linux/module.h> 4#include <linux/kernel.h> 5#include <linux/export.h> 6#include <linux/slab.h> 7#include <linux/err.h> 8#include <keys/asymmetric-subtype.h> 9#include <keys/asymmetric-parser.h> 10#include <crypto/asym_tpm_subtype.h> 11#include "tpm.asn1.h" 12 13struct tpm_parse_context { 14 const void *blob; 15 u32 blob_len; 16}; 17 18/* 19 * Note the key data of the ASN.1 blob. 20 */ 21int tpm_note_key(void *context, size_t hdrlen, 22 unsigned char tag, 23 const void *value, size_t vlen) 24{ 25 struct tpm_parse_context *ctx = context; 26 27 ctx->blob = value; 28 ctx->blob_len = vlen; 29 30 return 0; 31} 32 33/* 34 * Parse a TPM-encrypted private key blob. 35 */ 36static struct tpm_key *tpm_parse(const void *data, size_t datalen) 37{ 38 struct tpm_parse_context ctx; 39 long ret; 40 41 memset(&ctx, 0, sizeof(ctx)); 42 43 /* Attempt to decode the private key */ 44 ret = asn1_ber_decoder(&tpm_decoder, &ctx, data, datalen); 45 if (ret < 0) 46 goto error; 47 48 return tpm_key_create(ctx.blob, ctx.blob_len); 49 50error: 51 return ERR_PTR(ret); 52} 53/* 54 * Attempt to parse a data blob for a key as a TPM private key blob. 55 */ 56static int tpm_key_preparse(struct key_preparsed_payload *prep) 57{ 58 struct tpm_key *tk; 59 60 /* 61 * TPM 1.2 keys are max 2048 bits long, so assume the blob is no 62 * more than 4x that 63 */ 64 if (prep->datalen > 256 * 4) 65 return -EMSGSIZE; 66 67 tk = tpm_parse(prep->data, prep->datalen); 68 69 if (IS_ERR(tk)) 70 return PTR_ERR(tk); 71 72 /* We're pinning the module by being linked against it */ 73 __module_get(asym_tpm_subtype.owner); 74 prep->payload.data[asym_subtype] = &asym_tpm_subtype; 75 prep->payload.data[asym_key_ids] = NULL; 76 prep->payload.data[asym_crypto] = tk; 77 prep->payload.data[asym_auth] = NULL; 78 prep->quotalen = 100; 79 return 0; 80} 81 82static struct asymmetric_key_parser tpm_key_parser = { 83 .owner = THIS_MODULE, 84 .name = "tpm_parser", 85 .parse = tpm_key_preparse, 86}; 87 88static int __init tpm_key_init(void) 89{ 90 return register_asymmetric_key_parser(&tpm_key_parser); 91} 92 93static void __exit tpm_key_exit(void) 94{ 95 unregister_asymmetric_key_parser(&tpm_key_parser); 96} 97 98module_init(tpm_key_init); 99module_exit(tpm_key_exit); 100 101MODULE_DESCRIPTION("TPM private key-blob parser"); 102MODULE_LICENSE("GPL v2"); 103