Skip to content

Commit 0e28bf6

Browse files
iokilljarkkojs
authored andcommitted
KEYS: trusted: dcp: fix leak of blob encryption key
Trusted keys unseal the key blob on load, but keep the sealed payload in the blob field so that every subsequent read (export) will simply convert this field to hex and send it to userspace. With DCP-based trusted keys, we decrypt the blob encryption key (BEK) in the Kernel due hardware limitations and then decrypt the blob payload. BEK decryption is done in-place which means that the trusted key blob field is modified and it consequently holds the BEK in plain text. Every subsequent read of that key thus send the plain text BEK instead of the encrypted BEK to userspace. This issue only occurs when importing a trusted DCP-based key and then exporting it again. This should rarely happen as the common use cases are to either create a new trusted key and export it, or import a key blob and then just use it without exporting it again. Fix this by performing BEK decryption and encryption in a dedicated buffer. Further always wipe the plain text BEK buffer to prevent leaking the key via uninitialized memory. Cc: [email protected] # v6.10+ Fixes: 2e8a0f4 ("KEYS: trusted: Introduce NXP DCP-backed trusted keys") Signed-off-by: David Gstir <[email protected]> Reviewed-by: Jarkko Sakkinen <[email protected]> Signed-off-by: Jarkko Sakkinen <[email protected]>
1 parent 6486cad commit 0e28bf6

File tree

1 file changed

+21
-12
lines changed

1 file changed

+21
-12
lines changed

security/keys/trusted-keys/trusted_dcp.c

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -186,51 +186,58 @@ static int do_aead_crypto(u8 *in, u8 *out, size_t len, u8 *key, u8 *nonce,
186186
return ret;
187187
}
188188

189-
static int decrypt_blob_key(u8 *key)
189+
static int decrypt_blob_key(u8 *encrypted_key, u8 *plain_key)
190190
{
191-
return do_dcp_crypto(key, key, false);
191+
return do_dcp_crypto(encrypted_key, plain_key, false);
192192
}
193193

194-
static int encrypt_blob_key(u8 *key)
194+
static int encrypt_blob_key(u8 *plain_key, u8 *encrypted_key)
195195
{
196-
return do_dcp_crypto(key, key, true);
196+
return do_dcp_crypto(plain_key, encrypted_key, true);
197197
}
198198

199199
static int trusted_dcp_seal(struct trusted_key_payload *p, char *datablob)
200200
{
201201
struct dcp_blob_fmt *b = (struct dcp_blob_fmt *)p->blob;
202202
int blen, ret;
203+
u8 plain_blob_key[AES_KEYSIZE_128];
203204

204205
blen = calc_blob_len(p->key_len);
205206
if (blen > MAX_BLOB_SIZE)
206207
return -E2BIG;
207208

208209
b->fmt_version = DCP_BLOB_VERSION;
209210
get_random_bytes(b->nonce, AES_KEYSIZE_128);
210-
get_random_bytes(b->blob_key, AES_KEYSIZE_128);
211+
get_random_bytes(plain_blob_key, AES_KEYSIZE_128);
211212

212-
ret = do_aead_crypto(p->key, b->payload, p->key_len, b->blob_key,
213+
ret = do_aead_crypto(p->key, b->payload, p->key_len, plain_blob_key,
213214
b->nonce, true);
214215
if (ret) {
215216
pr_err("Unable to encrypt blob payload: %i\n", ret);
216-
return ret;
217+
goto out;
217218
}
218219

219-
ret = encrypt_blob_key(b->blob_key);
220+
ret = encrypt_blob_key(plain_blob_key, b->blob_key);
220221
if (ret) {
221222
pr_err("Unable to encrypt blob key: %i\n", ret);
222-
return ret;
223+
goto out;
223224
}
224225

225226
put_unaligned_le32(p->key_len, &b->payload_len);
226227
p->blob_len = blen;
227-
return 0;
228+
ret = 0;
229+
230+
out:
231+
memzero_explicit(plain_blob_key, sizeof(plain_blob_key));
232+
233+
return ret;
228234
}
229235

230236
static int trusted_dcp_unseal(struct trusted_key_payload *p, char *datablob)
231237
{
232238
struct dcp_blob_fmt *b = (struct dcp_blob_fmt *)p->blob;
233239
int blen, ret;
240+
u8 plain_blob_key[AES_KEYSIZE_128];
234241

235242
if (b->fmt_version != DCP_BLOB_VERSION) {
236243
pr_err("DCP blob has bad version: %i, expected %i\n",
@@ -248,21 +255,23 @@ static int trusted_dcp_unseal(struct trusted_key_payload *p, char *datablob)
248255
goto out;
249256
}
250257

251-
ret = decrypt_blob_key(b->blob_key);
258+
ret = decrypt_blob_key(b->blob_key, plain_blob_key);
252259
if (ret) {
253260
pr_err("Unable to decrypt blob key: %i\n", ret);
254261
goto out;
255262
}
256263

257264
ret = do_aead_crypto(b->payload, p->key, p->key_len + DCP_BLOB_AUTHLEN,
258-
b->blob_key, b->nonce, false);
265+
plain_blob_key, b->nonce, false);
259266
if (ret) {
260267
pr_err("Unwrap of DCP payload failed: %i\n", ret);
261268
goto out;
262269
}
263270

264271
ret = 0;
265272
out:
273+
memzero_explicit(plain_blob_key, sizeof(plain_blob_key));
274+
266275
return ret;
267276
}
268277

0 commit comments

Comments
 (0)