Skip to content

Commit ee3feea

Browse files
author
Fox Snowpatch
committed
1 parent 484dba3 commit ee3feea

File tree

10 files changed

+563
-14
lines changed

10 files changed

+563
-14
lines changed

Documentation/admin-guide/kernel-parameters.txt

+13
Original file line numberDiff line numberDiff line change
@@ -6684,6 +6684,7 @@
66846684
- "tpm"
66856685
- "tee"
66866686
- "caam"
6687+
- "dcp"
66876688
If not specified then it defaults to iterating through
66886689
the trust source list starting with TPM and assigns the
66896690
first trust source as a backend which is initialized
@@ -6699,6 +6700,18 @@
66996700
If not specified, "default" is used. In this case,
67006701
the RNG's choice is left to each individual trust source.
67016702

6703+
trusted.dcp_use_otp_key
6704+
This is intended to be used in combination with
6705+
trusted.source=dcp and will select the DCP OTP key
6706+
instead of the DCP UNIQUE key blob encryption.
6707+
6708+
trusted.dcp_skip_zk_test
6709+
This is intended to be used in combination with
6710+
trusted.source=dcp and will disable the check if all
6711+
the blob key is zero'ed. This is helpful for situations where
6712+
having this key zero'ed is acceptable. E.g. in testing
6713+
scenarios.
6714+
67026715
tsc= Disable clocksource stability checks for TSC.
67036716
Format: <string>
67046717
[x86] reliable: mark tsc clocksource as reliable, this

Documentation/security/keys/trusted-encrypted.rst

+85
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ safe.
4242
randomly generated and fused into each SoC at manufacturing time.
4343
Otherwise, a common fixed test key is used instead.
4444

45+
(4) DCP (Data Co-Processor: crypto accelerator of various i.MX SoCs)
46+
47+
Rooted to a one-time programmable key (OTP) that is generally burnt
48+
in the on-chip fuses and is accessible to the DCP encryption engine only.
49+
DCP provides two keys that can be used as root of trust: the OTP key
50+
and the UNIQUE key. Default is to use the UNIQUE key, but selecting
51+
the OTP key can be done via a module parameter (dcp_use_otp_key).
52+
4553
* Execution isolation
4654

4755
(1) TPM
@@ -57,6 +65,12 @@ safe.
5765

5866
Fixed set of operations running in isolated execution environment.
5967

68+
(4) DCP
69+
70+
Fixed set of cryptographic operations running in isolated execution
71+
environment. Only basic blob key encryption is executed there.
72+
The actual key sealing/unsealing is done on main processor/kernel space.
73+
6074
* Optional binding to platform integrity state
6175

6276
(1) TPM
@@ -79,6 +93,11 @@ safe.
7993
Relies on the High Assurance Boot (HAB) mechanism of NXP SoCs
8094
for platform integrity.
8195

96+
(4) DCP
97+
98+
Relies on Secure/Trusted boot process (called HAB by vendor) for
99+
platform integrity.
100+
82101
* Interfaces and APIs
83102

84103
(1) TPM
@@ -94,6 +113,11 @@ safe.
94113

95114
Interface is specific to silicon vendor.
96115

116+
(4) DCP
117+
118+
Vendor-specific API that is implemented as part of the DCP crypto driver in
119+
``drivers/crypto/mxs-dcp.c``.
120+
97121
* Threat model
98122

99123
The strength and appropriateness of a particular trust source for a given
@@ -129,6 +153,13 @@ selected trust source:
129153
CAAM HWRNG, enable CRYPTO_DEV_FSL_CAAM_RNG_API and ensure the device
130154
is probed.
131155

156+
* DCP (Data Co-Processor: crypto accelerator of various i.MX SoCs)
157+
158+
The DCP hardware device itself does not provide a dedicated RNG interface,
159+
so the kernel default RNG is used. SoCs with DCP like the i.MX6ULL do have
160+
a dedicated hardware RNG that is independent from DCP which can be enabled
161+
to back the kernel RNG.
162+
132163
Users may override this by specifying ``trusted.rng=kernel`` on the kernel
133164
command-line to override the used RNG with the kernel's random number pool.
134165

@@ -231,6 +262,19 @@ Usage::
231262
CAAM-specific format. The key length for new keys is always in bytes.
232263
Trusted Keys can be 32 - 128 bytes (256 - 1024 bits).
233264

265+
Trusted Keys usage: DCP
266+
-----------------------
267+
268+
Usage::
269+
270+
keyctl add trusted name "new keylen" ring
271+
keyctl add trusted name "load hex_blob" ring
272+
keyctl print keyid
273+
274+
"keyctl print" returns an ASCII hex copy of the sealed key, which is in format
275+
specific to this DCP key-blob implementation. The key length for new keys is
276+
always in bytes. Trusted Keys can be 32 - 128 bytes (256 - 1024 bits).
277+
234278
Encrypted Keys usage
235279
--------------------
236280

@@ -426,3 +470,44 @@ string length.
426470
privkey is the binary representation of TPM2B_PUBLIC excluding the
427471
initial TPM2B header which can be reconstructed from the ASN.1 octed
428472
string length.
473+
474+
DCP Blob Format
475+
---------------
476+
477+
The Data Co-Processor (DCP) provides hardware-bound AES keys using its
478+
AES encryption engine only. It does not provide direct key sealing/unsealing.
479+
To make DCP hardware encryption keys usable as trust source, we define
480+
our own custom format that uses a hardware-bound key to secure the sealing
481+
key stored in the key blob.
482+
483+
Whenever a new trusted key using DCP is generated, we generate a random 128-bit
484+
blob encryption key (BEK) and 128-bit nonce. The BEK and nonce are used to
485+
encrypt the trusted key payload using AES-128-GCM.
486+
487+
The BEK itself is encrypted using the hardware-bound key using the DCP's AES
488+
encryption engine with AES-128-ECB. The encrypted BEK, generated nonce,
489+
BEK-encrypted payload and authentication tag make up the blob format together
490+
with a version number, payload length and authentication tag::
491+
492+
/*
493+
* struct dcp_blob_fmt - DCP BLOB format.
494+
*
495+
* @fmt_version: Format version, currently being %1
496+
* @blob_key: Random AES 128 key which is used to encrypt @payload,
497+
* @blob_key itself is encrypted with OTP or UNIQUE device key in
498+
* AES-128-ECB mode by DCP.
499+
* @nonce: Random nonce used for @payload encryption.
500+
* @payload_len: Length of the plain text @payload.
501+
* @payload: The payload itself, encrypted using AES-128-GCM and @blob_key,
502+
* GCM auth tag of size AES_BLOCK_SIZE is attached at the end of it.
503+
*
504+
* The total size of a DCP BLOB is sizeof(struct dcp_blob_fmt) + @payload_len +
505+
* AES_BLOCK_SIZE.
506+
*/
507+
struct dcp_blob_fmt {
508+
__u8 fmt_version;
509+
__u8 blob_key[AES_KEYSIZE_128];
510+
__u8 nonce[AES_KEYSIZE_128];
511+
__le32 payload_len;
512+
__u8 payload[];
513+
} __packed;

MAINTAINERS

+9
Original file line numberDiff line numberDiff line change
@@ -11920,6 +11920,15 @@ S: Maintained
1192011920
F: include/keys/trusted_caam.h
1192111921
F: security/keys/trusted-keys/trusted_caam.c
1192211922

11923+
KEYS-TRUSTED-DCP
11924+
M: David Gstir <[email protected]>
11925+
R: sigma star Kernel Team <[email protected]>
11926+
11927+
11928+
S: Supported
11929+
F: include/keys/trusted_dcp.h
11930+
F: security/keys/trusted-keys/trusted_dcp.c
11931+
1192311932
KEYS-TRUSTED-TEE
1192411933
M: Sumit Garg <[email protected]>
1192511934

drivers/crypto/mxs-dcp.c

+93-11
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/platform_device.h>
1616
#include <linux/stmp_device.h>
1717
#include <linux/clk.h>
18+
#include <soc/fsl/dcp.h>
1819

1920
#include <crypto/aes.h>
2021
#include <crypto/sha1.h>
@@ -101,6 +102,7 @@ struct dcp_async_ctx {
101102
struct crypto_skcipher *fallback;
102103
unsigned int key_len;
103104
uint8_t key[AES_KEYSIZE_128];
105+
bool key_referenced;
104106
};
105107

106108
struct dcp_aes_req_ctx {
@@ -155,6 +157,7 @@ static struct dcp *global_sdcp;
155157
#define MXS_DCP_CONTROL0_HASH_TERM (1 << 13)
156158
#define MXS_DCP_CONTROL0_HASH_INIT (1 << 12)
157159
#define MXS_DCP_CONTROL0_PAYLOAD_KEY (1 << 11)
160+
#define MXS_DCP_CONTROL0_OTP_KEY (1 << 10)
158161
#define MXS_DCP_CONTROL0_CIPHER_ENCRYPT (1 << 8)
159162
#define MXS_DCP_CONTROL0_CIPHER_INIT (1 << 9)
160163
#define MXS_DCP_CONTROL0_ENABLE_HASH (1 << 6)
@@ -168,6 +171,8 @@ static struct dcp *global_sdcp;
168171
#define MXS_DCP_CONTROL1_CIPHER_MODE_ECB (0 << 4)
169172
#define MXS_DCP_CONTROL1_CIPHER_SELECT_AES128 (0 << 0)
170173

174+
#define MXS_DCP_CONTROL1_KEY_SELECT_SHIFT 8
175+
171176
static int mxs_dcp_start_dma(struct dcp_async_ctx *actx)
172177
{
173178
int dma_err;
@@ -224,13 +229,16 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx,
224229
struct dcp *sdcp = global_sdcp;
225230
struct dcp_dma_desc *desc = &sdcp->coh->desc[actx->chan];
226231
struct dcp_aes_req_ctx *rctx = skcipher_request_ctx(req);
232+
bool key_referenced = actx->key_referenced;
227233
int ret;
228234

229-
key_phys = dma_map_single(sdcp->dev, sdcp->coh->aes_key,
230-
2 * AES_KEYSIZE_128, DMA_TO_DEVICE);
231-
ret = dma_mapping_error(sdcp->dev, key_phys);
232-
if (ret)
233-
return ret;
235+
if (!key_referenced) {
236+
key_phys = dma_map_single(sdcp->dev, sdcp->coh->aes_key,
237+
2 * AES_KEYSIZE_128, DMA_TO_DEVICE);
238+
ret = dma_mapping_error(sdcp->dev, key_phys);
239+
if (ret)
240+
return ret;
241+
}
234242

235243
src_phys = dma_map_single(sdcp->dev, sdcp->coh->aes_in_buf,
236244
DCP_BUF_SZ, DMA_TO_DEVICE);
@@ -255,8 +263,12 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx,
255263
MXS_DCP_CONTROL0_INTERRUPT |
256264
MXS_DCP_CONTROL0_ENABLE_CIPHER;
257265

258-
/* Payload contains the key. */
259-
desc->control0 |= MXS_DCP_CONTROL0_PAYLOAD_KEY;
266+
if (key_referenced)
267+
/* Set OTP key bit to select the key via KEY_SELECT. */
268+
desc->control0 |= MXS_DCP_CONTROL0_OTP_KEY;
269+
else
270+
/* Payload contains the key. */
271+
desc->control0 |= MXS_DCP_CONTROL0_PAYLOAD_KEY;
260272

261273
if (rctx->enc)
262274
desc->control0 |= MXS_DCP_CONTROL0_CIPHER_ENCRYPT;
@@ -270,6 +282,9 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx,
270282
else
271283
desc->control1 |= MXS_DCP_CONTROL1_CIPHER_MODE_CBC;
272284

285+
if (key_referenced)
286+
desc->control1 |= sdcp->coh->aes_key[0] << MXS_DCP_CONTROL1_KEY_SELECT_SHIFT;
287+
273288
desc->next_cmd_addr = 0;
274289
desc->source = src_phys;
275290
desc->destination = dst_phys;
@@ -284,9 +299,9 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx,
284299
err_dst:
285300
dma_unmap_single(sdcp->dev, src_phys, DCP_BUF_SZ, DMA_TO_DEVICE);
286301
err_src:
287-
dma_unmap_single(sdcp->dev, key_phys, 2 * AES_KEYSIZE_128,
288-
DMA_TO_DEVICE);
289-
302+
if (!key_referenced)
303+
dma_unmap_single(sdcp->dev, key_phys, 2 * AES_KEYSIZE_128,
304+
DMA_TO_DEVICE);
290305
return ret;
291306
}
292307

@@ -453,7 +468,7 @@ static int mxs_dcp_aes_enqueue(struct skcipher_request *req, int enc, int ecb)
453468
struct dcp_aes_req_ctx *rctx = skcipher_request_ctx(req);
454469
int ret;
455470

456-
if (unlikely(actx->key_len != AES_KEYSIZE_128))
471+
if (unlikely(actx->key_len != AES_KEYSIZE_128 && !actx->key_referenced))
457472
return mxs_dcp_block_fallback(req, enc);
458473

459474
rctx->enc = enc;
@@ -500,6 +515,7 @@ static int mxs_dcp_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
500515
* there can still be an operation in progress.
501516
*/
502517
actx->key_len = len;
518+
actx->key_referenced = false;
503519
if (len == AES_KEYSIZE_128) {
504520
memcpy(actx->key, key, len);
505521
return 0;
@@ -516,6 +532,32 @@ static int mxs_dcp_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
516532
return crypto_skcipher_setkey(actx->fallback, key, len);
517533
}
518534

535+
static int mxs_dcp_aes_setrefkey(struct crypto_skcipher *tfm, const u8 *key,
536+
unsigned int len)
537+
{
538+
struct dcp_async_ctx *actx = crypto_skcipher_ctx(tfm);
539+
540+
if (len != DCP_PAES_KEYSIZE)
541+
return -EINVAL;
542+
543+
switch (key[0]) {
544+
case DCP_PAES_KEY_SLOT0:
545+
case DCP_PAES_KEY_SLOT1:
546+
case DCP_PAES_KEY_SLOT2:
547+
case DCP_PAES_KEY_SLOT3:
548+
case DCP_PAES_KEY_UNIQUE:
549+
case DCP_PAES_KEY_OTP:
550+
memcpy(actx->key, key, len);
551+
actx->key_len = len;
552+
actx->key_referenced = true;
553+
break;
554+
default:
555+
return -EINVAL;
556+
}
557+
558+
return 0;
559+
}
560+
519561
static int mxs_dcp_aes_fallback_init_tfm(struct crypto_skcipher *tfm)
520562
{
521563
const char *name = crypto_tfm_alg_name(crypto_skcipher_tfm(tfm));
@@ -539,6 +581,13 @@ static void mxs_dcp_aes_fallback_exit_tfm(struct crypto_skcipher *tfm)
539581
crypto_free_skcipher(actx->fallback);
540582
}
541583

584+
static int mxs_dcp_paes_init_tfm(struct crypto_skcipher *tfm)
585+
{
586+
crypto_skcipher_set_reqsize(tfm, sizeof(struct dcp_aes_req_ctx));
587+
588+
return 0;
589+
}
590+
542591
/*
543592
* Hashing (SHA1/SHA256)
544593
*/
@@ -889,6 +938,39 @@ static struct skcipher_alg dcp_aes_algs[] = {
889938
.ivsize = AES_BLOCK_SIZE,
890939
.init = mxs_dcp_aes_fallback_init_tfm,
891940
.exit = mxs_dcp_aes_fallback_exit_tfm,
941+
}, {
942+
.base.cra_name = "ecb(paes)",
943+
.base.cra_driver_name = "ecb-paes-dcp",
944+
.base.cra_priority = 401,
945+
.base.cra_alignmask = 15,
946+
.base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_INTERNAL,
947+
.base.cra_blocksize = AES_BLOCK_SIZE,
948+
.base.cra_ctxsize = sizeof(struct dcp_async_ctx),
949+
.base.cra_module = THIS_MODULE,
950+
951+
.min_keysize = DCP_PAES_KEYSIZE,
952+
.max_keysize = DCP_PAES_KEYSIZE,
953+
.setkey = mxs_dcp_aes_setrefkey,
954+
.encrypt = mxs_dcp_aes_ecb_encrypt,
955+
.decrypt = mxs_dcp_aes_ecb_decrypt,
956+
.init = mxs_dcp_paes_init_tfm,
957+
}, {
958+
.base.cra_name = "cbc(paes)",
959+
.base.cra_driver_name = "cbc-paes-dcp",
960+
.base.cra_priority = 401,
961+
.base.cra_alignmask = 15,
962+
.base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_INTERNAL,
963+
.base.cra_blocksize = AES_BLOCK_SIZE,
964+
.base.cra_ctxsize = sizeof(struct dcp_async_ctx),
965+
.base.cra_module = THIS_MODULE,
966+
967+
.min_keysize = DCP_PAES_KEYSIZE,
968+
.max_keysize = DCP_PAES_KEYSIZE,
969+
.setkey = mxs_dcp_aes_setrefkey,
970+
.encrypt = mxs_dcp_aes_cbc_encrypt,
971+
.decrypt = mxs_dcp_aes_cbc_decrypt,
972+
.ivsize = AES_BLOCK_SIZE,
973+
.init = mxs_dcp_paes_init_tfm,
892974
},
893975
};
894976

include/keys/trusted_dcp.h

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Copyright (C) 2021 sigma star gmbh
4+
*/
5+
6+
#ifndef TRUSTED_DCP_H
7+
#define TRUSTED_DCP_H
8+
9+
extern struct trusted_key_ops dcp_trusted_key_ops;
10+
11+
#endif

0 commit comments

Comments
 (0)