aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorMimi Zohar <zohar@linux.vnet.ibm.com>2010-11-23 18:55:35 -0500
committerJames Morris <jmorris@namei.org>2010-11-28 16:55:29 -0500
commit7e70cb4978507cf31d76b90e4cfb4c28cad87f0c (patch)
treec5df493eef8d30dcb40d647b0528970eb4a391c6 /security
parentd00a1c72f7f4661212299e6cb132dfa58030bcdb (diff)
keys: add new key-type encrypted
Define a new kernel key-type called 'encrypted'. Encrypted keys are kernel generated random numbers, which are encrypted/decrypted with a 'trusted' symmetric key. Encrypted keys are created/encrypted/decrypted in the kernel. Userspace only ever sees/stores encrypted blobs. Changelog: - bug fix: replaced master-key rcu based locking with semaphore (reported by David Howells) - Removed memset of crypto_shash_digest() digest output - Replaced verification of 'key-type:key-desc' using strcspn(), with one based on string constants. - Moved documentation to Documentation/keys-trusted-encrypted.txt - Replace hash with shash (based on comments by David Howells) - Make lengths/counts size_t where possible (based on comments by David Howells) Could not convert most lengths, as crypto expects 'unsigned int' (size_t: on 32 bit is defined as unsigned int, but on 64 bit is unsigned long) - Add 'const' where possible (based on comments by David Howells) - allocate derived_buf dynamically to support arbitrary length master key (fixed by Roberto Sassu) - wait until late_initcall for crypto libraries to be registered - cleanup security/Kconfig - Add missing 'update' keyword (reported/fixed by Roberto Sassu) - Free epayload on failure to create key (reported/fixed by Roberto Sassu) - Increase the data size limit (requested by Roberto Sassu) - Crypto return codes are always 0 on success and negative on failure, remove unnecessary tests. - Replaced kzalloc() with kmalloc() Signed-off-by: Mimi Zohar <zohar@us.ibm.com> Signed-off-by: David Safford <safford@watson.ibm.com> Reviewed-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security')
-rw-r--r--security/Kconfig16
-rw-r--r--security/keys/Makefile1
-rw-r--r--security/keys/encrypted_defined.c907
-rw-r--r--security/keys/encrypted_defined.h56
4 files changed, 980 insertions, 0 deletions
diff --git a/security/Kconfig b/security/Kconfig
index 24b8f9b491b8..95accd442d55 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -36,6 +36,22 @@ config TRUSTED_KEYS
36 36
37 If you are unsure as to whether this is required, answer N. 37 If you are unsure as to whether this is required, answer N.
38 38
39config ENCRYPTED_KEYS
40 tristate "ENCRYPTED KEYS"
41 depends on KEYS && TRUSTED_KEYS
42 select CRYPTO_AES
43 select CRYPTO_CBC
44 select CRYPTO_SHA256
45 select CRYPTO_RNG
46 help
47 This option provides support for create/encrypting/decrypting keys
48 in the kernel. Encrypted keys are kernel generated random numbers,
49 which are encrypted/decrypted with a 'master' symmetric key. The
50 'master' key can be either a trusted-key or user-key type.
51 Userspace only ever sees/stores encrypted blobs.
52
53 If you are unsure as to whether this is required, answer N.
54
39config KEYS_DEBUG_PROC_KEYS 55config KEYS_DEBUG_PROC_KEYS
40 bool "Enable the /proc/keys file by which keys may be viewed" 56 bool "Enable the /proc/keys file by which keys may be viewed"
41 depends on KEYS 57 depends on KEYS
diff --git a/security/keys/Makefile b/security/keys/Makefile
index fcb107020b4a..6c941050f573 100644
--- a/security/keys/Makefile
+++ b/security/keys/Makefile
@@ -14,6 +14,7 @@ obj-y := \
14 user_defined.o 14 user_defined.o
15 15
16obj-$(CONFIG_TRUSTED_KEYS) += trusted_defined.o 16obj-$(CONFIG_TRUSTED_KEYS) += trusted_defined.o
17obj-$(CONFIG_ENCRYPTED_KEYS) += encrypted_defined.o
17obj-$(CONFIG_KEYS_COMPAT) += compat.o 18obj-$(CONFIG_KEYS_COMPAT) += compat.o
18obj-$(CONFIG_PROC_FS) += proc.o 19obj-$(CONFIG_PROC_FS) += proc.o
19obj-$(CONFIG_SYSCTL) += sysctl.o 20obj-$(CONFIG_SYSCTL) += sysctl.o
diff --git a/security/keys/encrypted_defined.c b/security/keys/encrypted_defined.c
new file mode 100644
index 000000000000..0e558dcad92f
--- /dev/null
+++ b/security/keys/encrypted_defined.c
@@ -0,0 +1,907 @@
1/*
2 * Copyright (C) 2010 IBM Corporation
3 *
4 * Author:
5 * Mimi Zohar <zohar@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, version 2 of the License.
10 *
11 * See Documentation/keys-trusted-encrypted.txt
12 */
13
14#include <linux/uaccess.h>
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/slab.h>
18#include <linux/parser.h>
19#include <linux/string.h>
20#include <keys/user-type.h>
21#include <keys/trusted-type.h>
22#include <keys/encrypted-type.h>
23#include <linux/key-type.h>
24#include <linux/random.h>
25#include <linux/rcupdate.h>
26#include <linux/scatterlist.h>
27#include <linux/crypto.h>
28#include <crypto/hash.h>
29#include <crypto/sha.h>
30#include <crypto/aes.h>
31
32#include "encrypted_defined.h"
33
34#define KEY_TRUSTED_PREFIX "trusted:"
35#define KEY_TRUSTED_PREFIX_LEN (sizeof (KEY_TRUSTED_PREFIX) - 1)
36#define KEY_USER_PREFIX "user:"
37#define KEY_USER_PREFIX_LEN (sizeof (KEY_USER_PREFIX) - 1)
38
39#define HASH_SIZE SHA256_DIGEST_SIZE
40#define MAX_DATA_SIZE 4096
41#define MIN_DATA_SIZE 20
42
43static const char hash_alg[] = "sha256";
44static const char hmac_alg[] = "hmac(sha256)";
45static const char blkcipher_alg[] = "cbc(aes)";
46static unsigned int ivsize;
47static int blksize;
48
49struct sdesc {
50 struct shash_desc shash;
51 char ctx[];
52};
53
54static struct crypto_shash *hashalg;
55static struct crypto_shash *hmacalg;
56
57enum {
58 Opt_err = -1, Opt_new, Opt_load, Opt_update
59};
60
61static const match_table_t key_tokens = {
62 {Opt_new, "new"},
63 {Opt_load, "load"},
64 {Opt_update, "update"},
65 {Opt_err, NULL}
66};
67
68static int aes_get_sizes(void)
69{
70 struct crypto_blkcipher *tfm;
71
72 tfm = crypto_alloc_blkcipher(blkcipher_alg, 0, CRYPTO_ALG_ASYNC);
73 if (IS_ERR(tfm)) {
74 pr_err("encrypted_key: failed to alloc_cipher (%ld)\n",
75 PTR_ERR(tfm));
76 return PTR_ERR(tfm);
77 }
78 ivsize = crypto_blkcipher_ivsize(tfm);
79 blksize = crypto_blkcipher_blocksize(tfm);
80 crypto_free_blkcipher(tfm);
81 return 0;
82}
83
84/*
85 * valid_master_desc - verify the 'key-type:desc' of a new/updated master-key
86 *
87 * key-type:= "trusted:" | "encrypted:"
88 * desc:= master-key description
89 *
90 * Verify that 'key-type' is valid and that 'desc' exists. On key update,
91 * only the master key description is permitted to change, not the key-type.
92 * The key-type remains constant.
93 *
94 * On success returns 0, otherwise -EINVAL.
95 */
96static int valid_master_desc(const char *new_desc, const char *orig_desc)
97{
98 if (!memcmp(new_desc, KEY_TRUSTED_PREFIX, KEY_TRUSTED_PREFIX_LEN)) {
99 if (strlen(new_desc) == KEY_TRUSTED_PREFIX_LEN)
100 goto out;
101 if (orig_desc)
102 if (memcmp(new_desc, orig_desc, KEY_TRUSTED_PREFIX_LEN))
103 goto out;
104 } else if (!memcmp(new_desc, KEY_USER_PREFIX, KEY_USER_PREFIX_LEN)) {
105 if (strlen(new_desc) == KEY_USER_PREFIX_LEN)
106 goto out;
107 if (orig_desc)
108 if (memcmp(new_desc, orig_desc, KEY_USER_PREFIX_LEN))
109 goto out;
110 } else
111 goto out;
112 return 0;
113out:
114 return -EINVAL;
115}
116
117/*
118 * datablob_parse - parse the keyctl data
119 *
120 * datablob format:
121 * new <master-key name> <decrypted data length>
122 * load <master-key name> <decrypted data length> <encrypted iv + data>
123 * update <new-master-key name>
124 *
125 * Tokenizes a copy of the keyctl data, returning a pointer to each token,
126 * which is null terminated.
127 *
128 * On success returns 0, otherwise -EINVAL.
129 */
130static int datablob_parse(char *datablob, char **master_desc,
131 char **decrypted_datalen, char **hex_encoded_iv,
132 char **hex_encoded_data)
133{
134 substring_t args[MAX_OPT_ARGS];
135 int ret = -EINVAL;
136 int key_cmd;
137 char *p;
138
139 p = strsep(&datablob, " \t");
140 if (!p)
141 return ret;
142 key_cmd = match_token(p, key_tokens, args);
143
144 *master_desc = strsep(&datablob, " \t");
145 if (!*master_desc)
146 goto out;
147
148 if (valid_master_desc(*master_desc, NULL) < 0)
149 goto out;
150
151 if (decrypted_datalen) {
152 *decrypted_datalen = strsep(&datablob, " \t");
153 if (!*decrypted_datalen)
154 goto out;
155 }
156
157 switch (key_cmd) {
158 case Opt_new:
159 if (!decrypted_datalen)
160 break;
161 ret = 0;
162 break;
163 case Opt_load:
164 if (!decrypted_datalen)
165 break;
166 *hex_encoded_iv = strsep(&datablob, " \t");
167 if (!*hex_encoded_iv)
168 break;
169 *hex_encoded_data = *hex_encoded_iv + (2 * ivsize) + 2;
170 ret = 0;
171 break;
172 case Opt_update:
173 if (decrypted_datalen)
174 break;
175 ret = 0;
176 break;
177 case Opt_err:
178 break;
179 }
180out:
181 return ret;
182}
183
184/*
185 * datablob_format - format as an ascii string, before copying to userspace
186 */
187static char *datablob_format(struct encrypted_key_payload *epayload,
188 size_t asciiblob_len)
189{
190 char *ascii_buf, *bufp;
191 u8 *iv = epayload->iv;
192 int len;
193 int i;
194
195 ascii_buf = kmalloc(asciiblob_len + 1, GFP_KERNEL);
196 if (!ascii_buf)
197 goto out;
198
199 ascii_buf[asciiblob_len] = '\0';
200
201 /* copy datablob master_desc and datalen strings */
202 len = sprintf(ascii_buf, "%s %s ", epayload->master_desc,
203 epayload->datalen);
204
205 /* convert the hex encoded iv, encrypted-data and HMAC to ascii */
206 bufp = &ascii_buf[len];
207 for (i = 0; i < (asciiblob_len - len) / 2; i++)
208 bufp = pack_hex_byte(bufp, iv[i]);
209out:
210 return ascii_buf;
211}
212
213/*
214 * request_trusted_key - request the trusted key
215 *
216 * Trusted keys are sealed to PCRs and other metadata. Although userspace
217 * manages both trusted/encrypted key-types, like the encrypted key type
218 * data, trusted key type data is not visible decrypted from userspace.
219 */
220static struct key *request_trusted_key(const char *trusted_desc,
221 u8 **master_key,
222 unsigned int *master_keylen)
223{
224 struct trusted_key_payload *tpayload;
225 struct key *tkey;
226
227 tkey = request_key(&key_type_trusted, trusted_desc, NULL);
228 if (IS_ERR(tkey))
229 goto error;
230
231 down_read(&tkey->sem);
232 tpayload = rcu_dereference(tkey->payload.data);
233 *master_key = tpayload->key;
234 *master_keylen = tpayload->key_len;
235error:
236 return tkey;
237}
238
239/*
240 * request_user_key - request the user key
241 *
242 * Use a user provided key to encrypt/decrypt an encrypted-key.
243 */
244static struct key *request_user_key(const char *master_desc, u8 **master_key,
245 unsigned int *master_keylen)
246{
247 struct user_key_payload *upayload;
248 struct key *ukey;
249
250 ukey = request_key(&key_type_user, master_desc, NULL);
251 if (IS_ERR(ukey))
252 goto error;
253
254 down_read(&ukey->sem);
255 upayload = rcu_dereference(ukey->payload.data);
256 *master_key = upayload->data;
257 *master_keylen = upayload->datalen;
258error:
259 return ukey;
260}
261
262static struct sdesc *init_sdesc(struct crypto_shash *alg)
263{
264 struct sdesc *sdesc;
265 int size;
266
267 size = sizeof(struct shash_desc) + crypto_shash_descsize(alg);
268 sdesc = kmalloc(size, GFP_KERNEL);
269 if (!sdesc)
270 return ERR_PTR(-ENOMEM);
271 sdesc->shash.tfm = alg;
272 sdesc->shash.flags = 0x0;
273 return sdesc;
274}
275
276static int calc_hmac(u8 *digest, const u8 *key, const unsigned int keylen,
277 const u8 *buf, const unsigned int buflen)
278{
279 struct sdesc *sdesc;
280 int ret;
281
282 sdesc = init_sdesc(hmacalg);
283 if (IS_ERR(sdesc)) {
284 pr_info("encrypted_key: can't alloc %s\n", hmac_alg);
285 return PTR_ERR(sdesc);
286 }
287
288 ret = crypto_shash_setkey(hmacalg, key, keylen);
289 if (!ret)
290 ret = crypto_shash_digest(&sdesc->shash, buf, buflen, digest);
291 kfree(sdesc);
292 return ret;
293}
294
295static int calc_hash(u8 *digest, const u8 *buf, const unsigned int buflen)
296{
297 struct sdesc *sdesc;
298 int ret;
299
300 sdesc = init_sdesc(hashalg);
301 if (IS_ERR(sdesc)) {
302 pr_info("encrypted_key: can't alloc %s\n", hash_alg);
303 return PTR_ERR(sdesc);
304 }
305
306 ret = crypto_shash_digest(&sdesc->shash, buf, buflen, digest);
307 kfree(sdesc);
308 return ret;
309}
310
311enum derived_key_type { ENC_KEY, AUTH_KEY };
312
313/* Derive authentication/encryption key from trusted key */
314static int get_derived_key(u8 *derived_key, enum derived_key_type key_type,
315 const u8 *master_key,
316 const unsigned int master_keylen)
317{
318 u8 *derived_buf;
319 unsigned int derived_buf_len;
320 int ret;
321
322 derived_buf_len = strlen("AUTH_KEY") + 1 + master_keylen;
323 if (derived_buf_len < HASH_SIZE)
324 derived_buf_len = HASH_SIZE;
325
326 derived_buf = kzalloc(derived_buf_len, GFP_KERNEL);
327 if (!derived_buf) {
328 pr_err("encrypted_key: out of memory\n");
329 return -ENOMEM;
330 }
331 if (key_type)
332 strcpy(derived_buf, "AUTH_KEY");
333 else
334 strcpy(derived_buf, "ENC_KEY");
335
336 memcpy(derived_buf + strlen(derived_buf) + 1, master_key,
337 master_keylen);
338 ret = calc_hash(derived_key, derived_buf, derived_buf_len);
339 kfree(derived_buf);
340 return ret;
341}
342
343static int init_blkcipher_desc(struct blkcipher_desc *desc, const u8 *key,
344 const unsigned int key_len, const u8 *iv,
345 const unsigned int ivsize)
346{
347 int ret;
348
349 desc->tfm = crypto_alloc_blkcipher(blkcipher_alg, 0, CRYPTO_ALG_ASYNC);
350 if (IS_ERR(desc->tfm)) {
351 pr_err("encrypted_key: failed to load %s transform (%ld)\n",
352 blkcipher_alg, PTR_ERR(desc->tfm));
353 return PTR_ERR(desc->tfm);
354 }
355 desc->flags = 0;
356
357 ret = crypto_blkcipher_setkey(desc->tfm, key, key_len);
358 if (ret < 0) {
359 pr_err("encrypted_key: failed to setkey (%d)\n", ret);
360 crypto_free_blkcipher(desc->tfm);
361 return ret;
362 }
363 crypto_blkcipher_set_iv(desc->tfm, iv, ivsize);
364 return 0;
365}
366
367static struct key *request_master_key(struct encrypted_key_payload *epayload,
368 u8 **master_key,
369 unsigned int *master_keylen)
370{
371 struct key *mkey = NULL;
372
373 if (!strncmp(epayload->master_desc, KEY_TRUSTED_PREFIX,
374 KEY_TRUSTED_PREFIX_LEN)) {
375 mkey = request_trusted_key(epayload->master_desc +
376 KEY_TRUSTED_PREFIX_LEN,
377 master_key, master_keylen);
378 } else if (!strncmp(epayload->master_desc, KEY_USER_PREFIX,
379 KEY_USER_PREFIX_LEN)) {
380 mkey = request_user_key(epayload->master_desc +
381 KEY_USER_PREFIX_LEN,
382 master_key, master_keylen);
383 } else
384 goto out;
385
386 if (IS_ERR(mkey))
387 pr_info("encrypted_key: key %s not found",
388 epayload->master_desc);
389 if (mkey)
390 dump_master_key(*master_key, *master_keylen);
391out:
392 return mkey;
393}
394
395/* Before returning data to userspace, encrypt decrypted data. */
396static int derived_key_encrypt(struct encrypted_key_payload *epayload,
397 const u8 *derived_key,
398 const unsigned int derived_keylen)
399{
400 struct scatterlist sg_in[2];
401 struct scatterlist sg_out[1];
402 struct blkcipher_desc desc;
403 unsigned int encrypted_datalen;
404 unsigned int padlen;
405 char pad[16];
406 int ret;
407
408 encrypted_datalen = roundup(epayload->decrypted_datalen, blksize);
409 padlen = encrypted_datalen - epayload->decrypted_datalen;
410
411 ret = init_blkcipher_desc(&desc, derived_key, derived_keylen,
412 epayload->iv, ivsize);
413 if (ret < 0)
414 goto out;
415 dump_decrypted_data(epayload);
416
417 memset(pad, 0, sizeof pad);
418 sg_init_table(sg_in, 2);
419 sg_set_buf(&sg_in[0], epayload->decrypted_data,
420 epayload->decrypted_datalen);
421 sg_set_buf(&sg_in[1], pad, padlen);
422
423 sg_init_table(sg_out, 1);
424 sg_set_buf(sg_out, epayload->encrypted_data, encrypted_datalen);
425
426 ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in, encrypted_datalen);
427 crypto_free_blkcipher(desc.tfm);
428 if (ret < 0)
429 pr_err("encrypted_key: failed to encrypt (%d)\n", ret);
430 else
431 dump_encrypted_data(epayload, encrypted_datalen);
432out:
433 return ret;
434}
435
436static int datablob_hmac_append(struct encrypted_key_payload *epayload,
437 const u8 *master_key,
438 const unsigned int master_keylen)
439{
440 u8 derived_key[HASH_SIZE];
441 u8 *digest;
442 int ret;
443
444 ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen);
445 if (ret < 0)
446 goto out;
447
448 digest = epayload->master_desc + epayload->datablob_len;
449 ret = calc_hmac(digest, derived_key, sizeof derived_key,
450 epayload->master_desc, epayload->datablob_len);
451 if (!ret)
452 dump_hmac(NULL, digest, HASH_SIZE);
453out:
454 return ret;
455}
456
457/* verify HMAC before decrypting encrypted key */
458static int datablob_hmac_verify(struct encrypted_key_payload *epayload,
459 const u8 *master_key,
460 const unsigned int master_keylen)
461{
462 u8 derived_key[HASH_SIZE];
463 u8 digest[HASH_SIZE];
464 int ret;
465
466 ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen);
467 if (ret < 0)
468 goto out;
469
470 ret = calc_hmac(digest, derived_key, sizeof derived_key,
471 epayload->master_desc, epayload->datablob_len);
472 if (ret < 0)
473 goto out;
474 ret = memcmp(digest, epayload->master_desc + epayload->datablob_len,
475 sizeof digest);
476 if (ret) {
477 ret = -EINVAL;
478 dump_hmac("datablob",
479 epayload->master_desc + epayload->datablob_len,
480 HASH_SIZE);
481 dump_hmac("calc", digest, HASH_SIZE);
482 }
483out:
484 return ret;
485}
486
487static int derived_key_decrypt(struct encrypted_key_payload *epayload,
488 const u8 *derived_key,
489 const unsigned int derived_keylen)
490{
491 struct scatterlist sg_in[1];
492 struct scatterlist sg_out[2];
493 struct blkcipher_desc desc;
494 unsigned int encrypted_datalen;
495 char pad[16];
496 int ret;
497
498 encrypted_datalen = roundup(epayload->decrypted_datalen, blksize);
499 ret = init_blkcipher_desc(&desc, derived_key, derived_keylen,
500 epayload->iv, ivsize);
501 if (ret < 0)
502 goto out;
503 dump_encrypted_data(epayload, encrypted_datalen);
504
505 memset(pad, 0, sizeof pad);
506 sg_init_table(sg_in, 1);
507 sg_init_table(sg_out, 2);
508 sg_set_buf(sg_in, epayload->encrypted_data, encrypted_datalen);
509 sg_set_buf(&sg_out[0], epayload->decrypted_data,
510 (unsigned int)epayload->decrypted_datalen);
511 sg_set_buf(&sg_out[1], pad, sizeof pad);
512
513 ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, encrypted_datalen);
514 crypto_free_blkcipher(desc.tfm);
515 if (ret < 0)
516 goto out;
517 dump_decrypted_data(epayload);
518out:
519 return ret;
520}
521
522/* Allocate memory for decrypted key and datablob. */
523static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
524 const char *master_desc,
525 const char *datalen)
526{
527 struct encrypted_key_payload *epayload = NULL;
528 unsigned short datablob_len;
529 unsigned short decrypted_datalen;
530 unsigned int encrypted_datalen;
531 long dlen;
532 int ret;
533
534 ret = strict_strtol(datalen, 10, &dlen);
535 if (ret < 0 || dlen < MIN_DATA_SIZE || dlen > MAX_DATA_SIZE)
536 return ERR_PTR(-EINVAL);
537
538 decrypted_datalen = dlen;
539 encrypted_datalen = roundup(decrypted_datalen, blksize);
540
541 datablob_len = strlen(master_desc) + 1 + strlen(datalen) + 1
542 + ivsize + 1 + encrypted_datalen;
543
544 ret = key_payload_reserve(key, decrypted_datalen + datablob_len
545 + HASH_SIZE + 1);
546 if (ret < 0)
547 return ERR_PTR(ret);
548
549 epayload = kzalloc(sizeof(*epayload) + decrypted_datalen +
550 datablob_len + HASH_SIZE + 1, GFP_KERNEL);
551 if (!epayload)
552 return ERR_PTR(-ENOMEM);
553
554 epayload->decrypted_datalen = decrypted_datalen;
555 epayload->datablob_len = datablob_len;
556 return epayload;
557}
558
559static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
560 const char *hex_encoded_iv,
561 const char *hex_encoded_data)
562{
563 struct key *mkey;
564 u8 derived_key[HASH_SIZE];
565 u8 *master_key;
566 u8 *hmac;
567 unsigned int master_keylen;
568 unsigned int encrypted_datalen;
569 int ret;
570
571 encrypted_datalen = roundup(epayload->decrypted_datalen, blksize);
572 hex2bin(epayload->iv, hex_encoded_iv, ivsize);
573 hex2bin(epayload->encrypted_data, hex_encoded_data, encrypted_datalen);
574
575 hmac = epayload->master_desc + epayload->datablob_len;
576 hex2bin(hmac, hex_encoded_data + (encrypted_datalen * 2), HASH_SIZE);
577
578 mkey = request_master_key(epayload, &master_key, &master_keylen);
579 if (IS_ERR(mkey))
580 return PTR_ERR(mkey);
581
582 ret = datablob_hmac_verify(epayload, master_key, master_keylen);
583 if (ret < 0) {
584 pr_err("encrypted_key: bad hmac (%d)\n", ret);
585 goto out;
586 }
587
588 ret = get_derived_key(derived_key, ENC_KEY, master_key, master_keylen);
589 if (ret < 0)
590 goto out;
591
592 ret = derived_key_decrypt(epayload, derived_key, sizeof derived_key);
593 if (ret < 0)
594 pr_err("encrypted_key: failed to decrypt key (%d)\n", ret);
595out:
596 up_read(&mkey->sem);
597 key_put(mkey);
598 return ret;
599}
600
601static void __ekey_init(struct encrypted_key_payload *epayload,
602 const char *master_desc, const char *datalen)
603{
604 epayload->master_desc = epayload->decrypted_data
605 + epayload->decrypted_datalen;
606 epayload->datalen = epayload->master_desc + strlen(master_desc) + 1;
607 epayload->iv = epayload->datalen + strlen(datalen) + 1;
608 epayload->encrypted_data = epayload->iv + ivsize + 1;
609
610 memcpy(epayload->master_desc, master_desc, strlen(master_desc));
611 memcpy(epayload->datalen, datalen, strlen(datalen));
612}
613
614/*
615 * encrypted_init - initialize an encrypted key
616 *
617 * For a new key, use a random number for both the iv and data
618 * itself. For an old key, decrypt the hex encoded data.
619 */
620static int encrypted_init(struct encrypted_key_payload *epayload,
621 const char *master_desc, const char *datalen,
622 const char *hex_encoded_iv,
623 const char *hex_encoded_data)
624{
625 int ret = 0;
626
627 __ekey_init(epayload, master_desc, datalen);
628 if (!hex_encoded_data) {
629 get_random_bytes(epayload->iv, ivsize);
630
631 get_random_bytes(epayload->decrypted_data,
632 epayload->decrypted_datalen);
633 } else
634 ret = encrypted_key_decrypt(epayload, hex_encoded_iv,
635 hex_encoded_data);
636 return ret;
637}
638
639/*
640 * encrypted_instantiate - instantiate an encrypted key
641 *
642 * Decrypt an existing encrypted datablob or create a new encrypted key
643 * based on a kernel random number.
644 *
645 * On success, return 0. Otherwise return errno.
646 */
647static int encrypted_instantiate(struct key *key, const void *data,
648 size_t datalen)
649{
650 struct encrypted_key_payload *epayload = NULL;
651 char *datablob = NULL;
652 char *master_desc = NULL;
653 char *decrypted_datalen = NULL;
654 char *hex_encoded_iv = NULL;
655 char *hex_encoded_data = NULL;
656 int ret;
657
658 if (datalen <= 0 || datalen > 32767 || !data)
659 return -EINVAL;
660
661 datablob = kmalloc(datalen + 1, GFP_KERNEL);
662 if (!datablob)
663 return -ENOMEM;
664 datablob[datalen] = 0;
665 memcpy(datablob, data, datalen);
666 ret = datablob_parse(datablob, &master_desc, &decrypted_datalen,
667 &hex_encoded_iv, &hex_encoded_data);
668 if (ret < 0)
669 goto out;
670
671 epayload = encrypted_key_alloc(key, master_desc, decrypted_datalen);
672 if (IS_ERR(epayload)) {
673 ret = PTR_ERR(epayload);
674 goto out;
675 }
676 ret = encrypted_init(epayload, master_desc, decrypted_datalen,
677 hex_encoded_iv, hex_encoded_data);
678 if (ret < 0) {
679 kfree(epayload);
680 goto out;
681 }
682
683 rcu_assign_pointer(key->payload.data, epayload);
684out:
685 kfree(datablob);
686 return ret;
687}
688
689static void encrypted_rcu_free(struct rcu_head *rcu)
690{
691 struct encrypted_key_payload *epayload;
692
693 epayload = container_of(rcu, struct encrypted_key_payload, rcu);
694 memset(epayload->decrypted_data, 0, epayload->decrypted_datalen);
695 kfree(epayload);
696}
697
698/*
699 * encrypted_update - update the master key description
700 *
701 * Change the master key description for an existing encrypted key.
702 * The next read will return an encrypted datablob using the new
703 * master key description.
704 *
705 * On success, return 0. Otherwise return errno.
706 */
707static int encrypted_update(struct key *key, const void *data, size_t datalen)
708{
709 struct encrypted_key_payload *epayload = key->payload.data;
710 struct encrypted_key_payload *new_epayload;
711 char *buf;
712 char *new_master_desc = NULL;
713 int ret = 0;
714
715 if (datalen <= 0 || datalen > 32767 || !data)
716 return -EINVAL;
717
718 buf = kmalloc(datalen + 1, GFP_KERNEL);
719 if (!buf)
720 return -ENOMEM;
721
722 buf[datalen] = 0;
723 memcpy(buf, data, datalen);
724 ret = datablob_parse(buf, &new_master_desc, NULL, NULL, NULL);
725 if (ret < 0)
726 goto out;
727
728 ret = valid_master_desc(new_master_desc, epayload->master_desc);
729 if (ret < 0)
730 goto out;
731
732 new_epayload = encrypted_key_alloc(key, new_master_desc,
733 epayload->datalen);
734 if (IS_ERR(new_epayload)) {
735 ret = PTR_ERR(new_epayload);
736 goto out;
737 }
738
739 __ekey_init(new_epayload, new_master_desc, epayload->datalen);
740
741 memcpy(new_epayload->iv, epayload->iv, ivsize);
742 memcpy(new_epayload->decrypted_data, epayload->decrypted_data,
743 epayload->decrypted_datalen);
744
745 rcu_assign_pointer(key->payload.data, new_epayload);
746 call_rcu(&epayload->rcu, encrypted_rcu_free);
747out:
748 kfree(buf);
749 return ret;
750}
751
752/*
753 * encrypted_read - format and copy the encrypted data to userspace
754 *
755 * The resulting datablob format is:
756 * <master-key name> <decrypted data length> <encrypted iv> <encrypted data>
757 *
758 * On success, return to userspace the encrypted key datablob size.
759 */
760static long encrypted_read(const struct key *key, char __user *buffer,
761 size_t buflen)
762{
763 struct encrypted_key_payload *epayload;
764 struct key *mkey;
765 u8 *master_key;
766 unsigned int master_keylen;
767 char derived_key[HASH_SIZE];
768 char *ascii_buf;
769 size_t asciiblob_len;
770 int ret;
771
772 epayload = rcu_dereference_protected(key->payload.data,
773 rwsem_is_locked(&((struct key *)key)->sem));
774
775 /* returns the hex encoded iv, encrypted-data, and hmac as ascii */
776 asciiblob_len = epayload->datablob_len + ivsize + 1
777 + roundup(epayload->decrypted_datalen, blksize)
778 + (HASH_SIZE * 2);
779
780 if (!buffer || buflen < asciiblob_len)
781 return asciiblob_len;
782
783 mkey = request_master_key(epayload, &master_key, &master_keylen);
784 if (IS_ERR(mkey))
785 return PTR_ERR(mkey);
786
787 ret = get_derived_key(derived_key, ENC_KEY, master_key, master_keylen);
788 if (ret < 0)
789 goto out;
790
791 ret = derived_key_encrypt(epayload, derived_key, sizeof derived_key);
792 if (ret < 0)
793 goto out;
794
795 ret = datablob_hmac_append(epayload, master_key, master_keylen);
796 if (ret < 0)
797 goto out;
798
799 ascii_buf = datablob_format(epayload, asciiblob_len);
800 if (!ascii_buf) {
801 ret = -ENOMEM;
802 goto out;
803 }
804
805 up_read(&mkey->sem);
806 key_put(mkey);
807
808 if (copy_to_user(buffer, ascii_buf, asciiblob_len) != 0)
809 ret = -EFAULT;
810 kfree(ascii_buf);
811
812 return asciiblob_len;
813out:
814 up_read(&mkey->sem);
815 key_put(mkey);
816 return ret;
817}
818
819/*
820 * encrypted_destroy - before freeing the key, clear the decrypted data
821 *
822 * Before freeing the key, clear the memory containing the decrypted
823 * key data.
824 */
825static void encrypted_destroy(struct key *key)
826{
827 struct encrypted_key_payload *epayload = key->payload.data;
828
829 if (!epayload)
830 return;
831
832 memset(epayload->decrypted_data, 0, epayload->decrypted_datalen);
833 kfree(key->payload.data);
834}
835
836struct key_type key_type_encrypted = {
837 .name = "encrypted",
838 .instantiate = encrypted_instantiate,
839 .update = encrypted_update,
840 .match = user_match,
841 .destroy = encrypted_destroy,
842 .describe = user_describe,
843 .read = encrypted_read,
844};
845EXPORT_SYMBOL_GPL(key_type_encrypted);
846
847static void encrypted_shash_release(void)
848{
849 if (hashalg)
850 crypto_free_shash(hashalg);
851 if (hmacalg)
852 crypto_free_shash(hmacalg);
853}
854
855static int __init encrypted_shash_alloc(void)
856{
857 int ret;
858
859 hmacalg = crypto_alloc_shash(hmac_alg, 0, CRYPTO_ALG_ASYNC);
860 if (IS_ERR(hmacalg)) {
861 pr_info("encrypted_key: could not allocate crypto %s\n",
862 hmac_alg);
863 return PTR_ERR(hmacalg);
864 }
865
866 hashalg = crypto_alloc_shash(hash_alg, 0, CRYPTO_ALG_ASYNC);
867 if (IS_ERR(hashalg)) {
868 pr_info("encrypted_key: could not allocate crypto %s\n",
869 hash_alg);
870 ret = PTR_ERR(hashalg);
871 goto hashalg_fail;
872 }
873
874 return 0;
875
876hashalg_fail:
877 crypto_free_shash(hmacalg);
878 return ret;
879}
880
881static int __init init_encrypted(void)
882{
883 int ret;
884
885 ret = encrypted_shash_alloc();
886 if (ret < 0)
887 return ret;
888 ret = register_key_type(&key_type_encrypted);
889 if (ret < 0)
890 goto out;
891 return aes_get_sizes();
892out:
893 encrypted_shash_release();
894 return ret;
895
896}
897
898static void __exit cleanup_encrypted(void)
899{
900 encrypted_shash_release();
901 unregister_key_type(&key_type_encrypted);
902}
903
904late_initcall(init_encrypted);
905module_exit(cleanup_encrypted);
906
907MODULE_LICENSE("GPL");
diff --git a/security/keys/encrypted_defined.h b/security/keys/encrypted_defined.h
new file mode 100644
index 000000000000..c298a3f1cf70
--- /dev/null
+++ b/security/keys/encrypted_defined.h
@@ -0,0 +1,56 @@
1#ifndef __ENCRYPTED_KEY_H
2#define __ENCRYPTED_KEY_H
3
4#define ENCRYPTED_DEBUG 0
5
6#if ENCRYPTED_DEBUG
7static inline void dump_master_key(const u8 *master_key,
8 unsigned int master_keylen)
9{
10 print_hex_dump(KERN_ERR, "master key: ", DUMP_PREFIX_NONE, 32, 1,
11 master_key, master_keylen, 0);
12}
13
14static inline void dump_decrypted_data(struct encrypted_key_payload *epayload)
15{
16 print_hex_dump(KERN_ERR, "decrypted data: ", DUMP_PREFIX_NONE, 32, 1,
17 epayload->decrypted_data,
18 epayload->decrypted_datalen, 0);
19}
20
21static inline void dump_encrypted_data(struct encrypted_key_payload *epayload,
22 unsigned int encrypted_datalen)
23{
24 print_hex_dump(KERN_ERR, "encrypted data: ", DUMP_PREFIX_NONE, 32, 1,
25 epayload->encrypted_data, encrypted_datalen, 0);
26}
27
28static inline void dump_hmac(const char *str, const u8 *digest,
29 unsigned int hmac_size)
30{
31 if (str)
32 pr_info("encrypted_key: %s", str);
33 print_hex_dump(KERN_ERR, "hmac: ", DUMP_PREFIX_NONE, 32, 1, digest,
34 hmac_size, 0);
35}
36#else
37static inline void dump_master_key(const u8 *master_key,
38 unsigned int master_keylen)
39{
40}
41
42static inline void dump_decrypted_data(struct encrypted_key_payload *epayload)
43{
44}
45
46static inline void dump_encrypted_data(struct encrypted_key_payload *epayload,
47 unsigned int encrypted_datalen)
48{
49}
50
51static inline void dump_hmac(const char *str, const u8 *digest,
52 unsigned int hmac_size)
53{
54}
55#endif
56#endif