1*e9c5048cSAhmad Fatoum // SPDX-License-Identifier: GPL-2.0-only
2*e9c5048cSAhmad Fatoum /*
3*e9c5048cSAhmad Fatoum  * Copyright (C) 2021 Pengutronix, Ahmad Fatoum <kernel@pengutronix.de>
4*e9c5048cSAhmad Fatoum  */
5*e9c5048cSAhmad Fatoum 
6*e9c5048cSAhmad Fatoum #include <keys/trusted_caam.h>
7*e9c5048cSAhmad Fatoum #include <keys/trusted-type.h>
8*e9c5048cSAhmad Fatoum #include <linux/build_bug.h>
9*e9c5048cSAhmad Fatoum #include <linux/key-type.h>
10*e9c5048cSAhmad Fatoum #include <soc/fsl/caam-blob.h>
11*e9c5048cSAhmad Fatoum 
12*e9c5048cSAhmad Fatoum static struct caam_blob_priv *blobifier;
13*e9c5048cSAhmad Fatoum 
14*e9c5048cSAhmad Fatoum #define KEYMOD "SECURE_KEY"
15*e9c5048cSAhmad Fatoum 
16*e9c5048cSAhmad Fatoum static_assert(MAX_KEY_SIZE + CAAM_BLOB_OVERHEAD <= CAAM_BLOB_MAX_LEN);
17*e9c5048cSAhmad Fatoum static_assert(MAX_BLOB_SIZE <= CAAM_BLOB_MAX_LEN);
18*e9c5048cSAhmad Fatoum 
trusted_caam_seal(struct trusted_key_payload * p,char * datablob)19*e9c5048cSAhmad Fatoum static int trusted_caam_seal(struct trusted_key_payload *p, char *datablob)
20*e9c5048cSAhmad Fatoum {
21*e9c5048cSAhmad Fatoum 	int ret;
22*e9c5048cSAhmad Fatoum 	struct caam_blob_info info = {
23*e9c5048cSAhmad Fatoum 		.input  = p->key,  .input_len   = p->key_len,
24*e9c5048cSAhmad Fatoum 		.output = p->blob, .output_len  = MAX_BLOB_SIZE,
25*e9c5048cSAhmad Fatoum 		.key_mod = KEYMOD, .key_mod_len = sizeof(KEYMOD) - 1,
26*e9c5048cSAhmad Fatoum 	};
27*e9c5048cSAhmad Fatoum 
28*e9c5048cSAhmad Fatoum 	ret = caam_encap_blob(blobifier, &info);
29*e9c5048cSAhmad Fatoum 	if (ret)
30*e9c5048cSAhmad Fatoum 		return ret;
31*e9c5048cSAhmad Fatoum 
32*e9c5048cSAhmad Fatoum 	p->blob_len = info.output_len;
33*e9c5048cSAhmad Fatoum 	return 0;
34*e9c5048cSAhmad Fatoum }
35*e9c5048cSAhmad Fatoum 
trusted_caam_unseal(struct trusted_key_payload * p,char * datablob)36*e9c5048cSAhmad Fatoum static int trusted_caam_unseal(struct trusted_key_payload *p, char *datablob)
37*e9c5048cSAhmad Fatoum {
38*e9c5048cSAhmad Fatoum 	int ret;
39*e9c5048cSAhmad Fatoum 	struct caam_blob_info info = {
40*e9c5048cSAhmad Fatoum 		.input   = p->blob,  .input_len  = p->blob_len,
41*e9c5048cSAhmad Fatoum 		.output  = p->key,   .output_len = MAX_KEY_SIZE,
42*e9c5048cSAhmad Fatoum 		.key_mod = KEYMOD,  .key_mod_len = sizeof(KEYMOD) - 1,
43*e9c5048cSAhmad Fatoum 	};
44*e9c5048cSAhmad Fatoum 
45*e9c5048cSAhmad Fatoum 	ret = caam_decap_blob(blobifier, &info);
46*e9c5048cSAhmad Fatoum 	if (ret)
47*e9c5048cSAhmad Fatoum 		return ret;
48*e9c5048cSAhmad Fatoum 
49*e9c5048cSAhmad Fatoum 	p->key_len = info.output_len;
50*e9c5048cSAhmad Fatoum 	return 0;
51*e9c5048cSAhmad Fatoum }
52*e9c5048cSAhmad Fatoum 
trusted_caam_init(void)53*e9c5048cSAhmad Fatoum static int trusted_caam_init(void)
54*e9c5048cSAhmad Fatoum {
55*e9c5048cSAhmad Fatoum 	int ret;
56*e9c5048cSAhmad Fatoum 
57*e9c5048cSAhmad Fatoum 	blobifier = caam_blob_gen_init();
58*e9c5048cSAhmad Fatoum 	if (IS_ERR(blobifier))
59*e9c5048cSAhmad Fatoum 		return PTR_ERR(blobifier);
60*e9c5048cSAhmad Fatoum 
61*e9c5048cSAhmad Fatoum 	ret = register_key_type(&key_type_trusted);
62*e9c5048cSAhmad Fatoum 	if (ret)
63*e9c5048cSAhmad Fatoum 		caam_blob_gen_exit(blobifier);
64*e9c5048cSAhmad Fatoum 
65*e9c5048cSAhmad Fatoum 	return ret;
66*e9c5048cSAhmad Fatoum }
67*e9c5048cSAhmad Fatoum 
trusted_caam_exit(void)68*e9c5048cSAhmad Fatoum static void trusted_caam_exit(void)
69*e9c5048cSAhmad Fatoum {
70*e9c5048cSAhmad Fatoum 	unregister_key_type(&key_type_trusted);
71*e9c5048cSAhmad Fatoum 	caam_blob_gen_exit(blobifier);
72*e9c5048cSAhmad Fatoum }
73*e9c5048cSAhmad Fatoum 
74*e9c5048cSAhmad Fatoum struct trusted_key_ops trusted_key_caam_ops = {
75*e9c5048cSAhmad Fatoum 	.migratable = 0, /* non-migratable */
76*e9c5048cSAhmad Fatoum 	.init = trusted_caam_init,
77*e9c5048cSAhmad Fatoum 	.seal = trusted_caam_seal,
78*e9c5048cSAhmad Fatoum 	.unseal = trusted_caam_unseal,
79*e9c5048cSAhmad Fatoum 	.exit = trusted_caam_exit,
80*e9c5048cSAhmad Fatoum };
81