Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (C) 2021 sigma star gmbh
  4 */
  5
  6#include <crypto/aead.h>
  7#include <crypto/aes.h>
  8#include <crypto/algapi.h>
  9#include <crypto/gcm.h>
 10#include <crypto/skcipher.h>
 11#include <keys/trusted-type.h>
 12#include <linux/key-type.h>
 13#include <linux/module.h>
 14#include <linux/printk.h>
 15#include <linux/random.h>
 16#include <linux/scatterlist.h>
 17#include <soc/fsl/dcp.h>
 18
 19#define DCP_BLOB_VERSION 1
 20#define DCP_BLOB_AUTHLEN 16
 21
 22/**
 23 * DOC: dcp blob format
 24 *
 25 * The Data Co-Processor (DCP) provides hardware-bound AES keys using its
 26 * AES encryption engine only. It does not provide direct key sealing/unsealing.
 27 * To make DCP hardware encryption keys usable as trust source, we define
 28 * our own custom format that uses a hardware-bound key to secure the sealing
 29 * key stored in the key blob.
 30 *
 31 * Whenever a new trusted key using DCP is generated, we generate a random 128-bit
 32 * blob encryption key (BEK) and 128-bit nonce. The BEK and nonce are used to
 33 * encrypt the trusted key payload using AES-128-GCM.
 34 *
 35 * The BEK itself is encrypted using the hardware-bound key using the DCP's AES
 36 * encryption engine with AES-128-ECB. The encrypted BEK, generated nonce,
 37 * BEK-encrypted payload and authentication tag make up the blob format together
 38 * with a version number, payload length and authentication tag.
 39 */
 40
 41/**
 42 * struct dcp_blob_fmt - DCP BLOB format.
 43 *
 44 * @fmt_version: Format version, currently being %1.
 45 * @blob_key: Random AES 128 key which is used to encrypt @payload,
 46 *            @blob_key itself is encrypted with OTP or UNIQUE device key in
 47 *            AES-128-ECB mode by DCP.
 48 * @nonce: Random nonce used for @payload encryption.
 49 * @payload_len: Length of the plain text @payload.
 50 * @payload: The payload itself, encrypted using AES-128-GCM and @blob_key,
 51 *           GCM auth tag of size DCP_BLOB_AUTHLEN is attached at the end of it.
 52 *
 53 * The total size of a DCP BLOB is sizeof(struct dcp_blob_fmt) + @payload_len +
 54 * DCP_BLOB_AUTHLEN.
 55 */
 56struct dcp_blob_fmt {
 57	__u8 fmt_version;
 58	__u8 blob_key[AES_KEYSIZE_128];
 59	__u8 nonce[AES_KEYSIZE_128];
 60	__le32 payload_len;
 61	__u8 payload[];
 62} __packed;
 63
 64static bool use_otp_key;
 65module_param_named(dcp_use_otp_key, use_otp_key, bool, 0);
 66MODULE_PARM_DESC(dcp_use_otp_key, "Use OTP instead of UNIQUE key for sealing");
 67
 68static bool skip_zk_test;
 69module_param_named(dcp_skip_zk_test, skip_zk_test, bool, 0);
 70MODULE_PARM_DESC(dcp_skip_zk_test, "Don't test whether device keys are zero'ed");
 71
 72static unsigned int calc_blob_len(unsigned int payload_len)
 73{
 74	return sizeof(struct dcp_blob_fmt) + payload_len + DCP_BLOB_AUTHLEN;
 75}
 76
 77static int do_dcp_crypto(u8 *in, u8 *out, bool do_encrypt)
 78{
 79	struct skcipher_request *req = NULL;
 80	struct scatterlist src_sg, dst_sg;
 81	struct crypto_skcipher *tfm;
 82	u8 paes_key[DCP_PAES_KEYSIZE];
 83	DECLARE_CRYPTO_WAIT(wait);
 84	int res = 0;
 85
 86	if (use_otp_key)
 87		paes_key[0] = DCP_PAES_KEY_OTP;
 88	else
 89		paes_key[0] = DCP_PAES_KEY_UNIQUE;
 90
 91	tfm = crypto_alloc_skcipher("ecb-paes-dcp", CRYPTO_ALG_INTERNAL,
 92				    CRYPTO_ALG_INTERNAL);
 93	if (IS_ERR(tfm)) {
 94		res = PTR_ERR(tfm);
 95		tfm = NULL;
 96		goto out;
 97	}
 98
 99	req = skcipher_request_alloc(tfm, GFP_NOFS);
100	if (!req) {
101		res = -ENOMEM;
102		goto out;
103	}
104
105	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
106				      CRYPTO_TFM_REQ_MAY_SLEEP,
107				      crypto_req_done, &wait);
108	res = crypto_skcipher_setkey(tfm, paes_key, sizeof(paes_key));
109	if (res < 0)
110		goto out;
111
112	sg_init_one(&src_sg, in, AES_KEYSIZE_128);
113	sg_init_one(&dst_sg, out, AES_KEYSIZE_128);
114	skcipher_request_set_crypt(req, &src_sg, &dst_sg, AES_KEYSIZE_128,
115				   NULL);
116
117	if (do_encrypt)
118		res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
119	else
120		res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
121
122out:
123	skcipher_request_free(req);
124	crypto_free_skcipher(tfm);
125
126	return res;
127}
128
129static int do_aead_crypto(u8 *in, u8 *out, size_t len, u8 *key, u8 *nonce,
130			  bool do_encrypt)
131{
132	struct aead_request *aead_req = NULL;
133	struct scatterlist src_sg, dst_sg;
134	struct crypto_aead *aead;
135	int ret;
136	DECLARE_CRYPTO_WAIT(wait);
137
138	aead = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
139	if (IS_ERR(aead)) {
140		ret = PTR_ERR(aead);
141		goto out;
142	}
143
144	ret = crypto_aead_setauthsize(aead, DCP_BLOB_AUTHLEN);
145	if (ret < 0) {
146		pr_err("Can't set crypto auth tag len: %d\n", ret);
147		goto free_aead;
148	}
149
150	aead_req = aead_request_alloc(aead, GFP_KERNEL);
151	if (!aead_req) {
152		ret = -ENOMEM;
153		goto free_aead;
154	}
155
156	sg_init_one(&src_sg, in, len);
157	if (do_encrypt) {
158		/*
159		 * If we encrypt our buffer has extra space for the auth tag.
160		 */
161		sg_init_one(&dst_sg, out, len + DCP_BLOB_AUTHLEN);
162	} else {
163		sg_init_one(&dst_sg, out, len);
164	}
165
166	aead_request_set_crypt(aead_req, &src_sg, &dst_sg, len, nonce);
167	aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_SLEEP,
168				  crypto_req_done, &wait);
169	aead_request_set_ad(aead_req, 0);
170
171	if (crypto_aead_setkey(aead, key, AES_KEYSIZE_128)) {
172		pr_err("Can't set crypto AEAD key\n");
173		ret = -EINVAL;
174		goto free_req;
175	}
176
177	if (do_encrypt)
178		ret = crypto_wait_req(crypto_aead_encrypt(aead_req), &wait);
179	else
180		ret = crypto_wait_req(crypto_aead_decrypt(aead_req), &wait);
181
182free_req:
183	aead_request_free(aead_req);
184free_aead:
185	crypto_free_aead(aead);
186out:
187	return ret;
188}
189
190static int decrypt_blob_key(u8 *encrypted_key, u8 *plain_key)
191{
192	return do_dcp_crypto(encrypted_key, plain_key, false);
193}
194
195static int encrypt_blob_key(u8 *plain_key, u8 *encrypted_key)
196{
197	return do_dcp_crypto(plain_key, encrypted_key, true);
198}
199
200static int trusted_dcp_seal(struct trusted_key_payload *p, char *datablob)
201{
202	struct dcp_blob_fmt *b = (struct dcp_blob_fmt *)p->blob;
203	int blen, ret;
204	u8 *plain_blob_key;
205
206	blen = calc_blob_len(p->key_len);
207	if (blen > MAX_BLOB_SIZE)
208		return -E2BIG;
209
210	plain_blob_key = kmalloc(AES_KEYSIZE_128, GFP_KERNEL);
211	if (!plain_blob_key)
212		return -ENOMEM;
213
214	b->fmt_version = DCP_BLOB_VERSION;
215	get_random_bytes(b->nonce, AES_KEYSIZE_128);
216	get_random_bytes(plain_blob_key, AES_KEYSIZE_128);
217
218	ret = do_aead_crypto(p->key, b->payload, p->key_len, plain_blob_key,
219			     b->nonce, true);
220	if (ret) {
221		pr_err("Unable to encrypt blob payload: %i\n", ret);
222		goto out;
223	}
224
225	ret = encrypt_blob_key(plain_blob_key, b->blob_key);
226	if (ret) {
227		pr_err("Unable to encrypt blob key: %i\n", ret);
228		goto out;
229	}
230
231	put_unaligned_le32(p->key_len, &b->payload_len);
232	p->blob_len = blen;
233	ret = 0;
234
235out:
236	memzero_explicit(plain_blob_key, AES_KEYSIZE_128);
237	kfree(plain_blob_key);
238
239	return ret;
240}
241
242static int trusted_dcp_unseal(struct trusted_key_payload *p, char *datablob)
243{
244	struct dcp_blob_fmt *b = (struct dcp_blob_fmt *)p->blob;
245	int blen, ret;
246	u8 *plain_blob_key = NULL;
247
248	if (b->fmt_version != DCP_BLOB_VERSION) {
249		pr_err("DCP blob has bad version: %i, expected %i\n",
250		       b->fmt_version, DCP_BLOB_VERSION);
251		ret = -EINVAL;
252		goto out;
253	}
254
255	p->key_len = le32_to_cpu(b->payload_len);
256	blen = calc_blob_len(p->key_len);
257	if (blen != p->blob_len) {
258		pr_err("DCP blob has bad length: %i != %i\n", blen,
259		       p->blob_len);
260		ret = -EINVAL;
261		goto out;
262	}
263
264	plain_blob_key = kmalloc(AES_KEYSIZE_128, GFP_KERNEL);
265	if (!plain_blob_key) {
266		ret = -ENOMEM;
267		goto out;
268	}
269
270	ret = decrypt_blob_key(b->blob_key, plain_blob_key);
271	if (ret) {
272		pr_err("Unable to decrypt blob key: %i\n", ret);
273		goto out;
274	}
275
276	ret = do_aead_crypto(b->payload, p->key, p->key_len + DCP_BLOB_AUTHLEN,
277			     plain_blob_key, b->nonce, false);
278	if (ret) {
279		pr_err("Unwrap of DCP payload failed: %i\n", ret);
280		goto out;
281	}
282
283	ret = 0;
284out:
285	if (plain_blob_key) {
286		memzero_explicit(plain_blob_key, AES_KEYSIZE_128);
287		kfree(plain_blob_key);
288	}
289
290	return ret;
291}
292
293static int test_for_zero_key(void)
294{
295	/*
296	 * Encrypting a plaintext of all 0x55 bytes will yield
297	 * this ciphertext in case the DCP test key is used.
298	 */
299	static const u8 bad[] = {0x9a, 0xda, 0xe0, 0x54, 0xf6, 0x3d, 0xfa, 0xff,
300				 0x5e, 0xa1, 0x8e, 0x45, 0xed, 0xf6, 0xea, 0x6f};
301	void *buf = NULL;
302	int ret = 0;
303
304	if (skip_zk_test)
305		goto out;
306
307	buf = kmalloc(AES_BLOCK_SIZE, GFP_KERNEL);
308	if (!buf) {
309		ret = -ENOMEM;
310		goto out;
311	}
312
313	memset(buf, 0x55, AES_BLOCK_SIZE);
314
315	ret = do_dcp_crypto(buf, buf, true);
316	if (ret)
317		goto out;
318
319	if (memcmp(buf, bad, AES_BLOCK_SIZE) == 0) {
320		pr_warn("Device neither in secure nor trusted mode!\n");
321		ret = -EINVAL;
322	}
323out:
324	kfree(buf);
325	return ret;
326}
327
328static int trusted_dcp_init(void)
329{
330	int ret;
331
332	if (use_otp_key)
333		pr_info("Using DCP OTP key\n");
334
335	ret = test_for_zero_key();
336	if (ret) {
337		pr_warn("Test for zero'ed keys failed: %i\n", ret);
338
339		return -EINVAL;
340	}
341
342	return register_key_type(&key_type_trusted);
343}
344
345static void trusted_dcp_exit(void)
346{
347	unregister_key_type(&key_type_trusted);
348}
349
350struct trusted_key_ops dcp_trusted_key_ops = {
351	.exit = trusted_dcp_exit,
352	.init = trusted_dcp_init,
353	.seal = trusted_dcp_seal,
354	.unseal = trusted_dcp_unseal,
355	.migratable = 0,
356};