aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-27 22:26:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-27 22:26:38 -0400
commit95b6886526bb510b8370b625a49bc0ab3b8ff10f (patch)
tree2862606224820d200be12d2092dcd26df1654b80 /security/keys
parent22712200e175e0df5c7f9edfe6c6bf5c94c23b83 (diff)
parent29412f0f6a19e34336368f13eab848091c343952 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6: (54 commits) tpm_nsc: Fix bug when loading multiple TPM drivers tpm: Move tpm_tis_reenable_interrupts out of CONFIG_PNP block tpm: Fix compilation warning when CONFIG_PNP is not defined TOMOYO: Update kernel-doc. tpm: Fix a typo tpm_tis: Probing function for Intel iTPM bug tpm_tis: Fix the probing for interrupts tpm_tis: Delay ACPI S3 suspend while the TPM is busy tpm_tis: Re-enable interrupts upon (S3) resume tpm: Fix display of data in pubek sysfs entry tpm_tis: Add timeouts sysfs entry tpm: Adjust interface timeouts if they are too small tpm: Use interface timeouts returned from the TPM tpm_tis: Introduce durations sysfs entry tpm: Adjust the durations if they are too small tpm: Use durations returned from TPM TOMOYO: Enable conditional ACL. TOMOYO: Allow using argv[]/envp[] of execve() as conditions. TOMOYO: Allow using executable's realpath and symlink's target as conditions. TOMOYO: Allow using owner/group etc. of file objects as conditions. ... Fix up trivial conflict in security/tomoyo/realpath.c
Diffstat (limited to 'security/keys')
-rw-r--r--security/keys/Makefile2
-rw-r--r--security/keys/ecryptfs_format.c81
-rw-r--r--security/keys/ecryptfs_format.h30
-rw-r--r--security/keys/encrypted.c251
-rw-r--r--security/keys/request_key_auth.c2
5 files changed, 313 insertions, 53 deletions
diff --git a/security/keys/Makefile b/security/keys/Makefile
index 1bf090a885f..b34cc6ee690 100644
--- a/security/keys/Makefile
+++ b/security/keys/Makefile
@@ -14,7 +14,7 @@ obj-y := \
14 user_defined.o 14 user_defined.o
15 15
16obj-$(CONFIG_TRUSTED_KEYS) += trusted.o 16obj-$(CONFIG_TRUSTED_KEYS) += trusted.o
17obj-$(CONFIG_ENCRYPTED_KEYS) += encrypted.o 17obj-$(CONFIG_ENCRYPTED_KEYS) += ecryptfs_format.o encrypted.o
18obj-$(CONFIG_KEYS_COMPAT) += compat.o 18obj-$(CONFIG_KEYS_COMPAT) += compat.o
19obj-$(CONFIG_PROC_FS) += proc.o 19obj-$(CONFIG_PROC_FS) += proc.o
20obj-$(CONFIG_SYSCTL) += sysctl.o 20obj-$(CONFIG_SYSCTL) += sysctl.o
diff --git a/security/keys/ecryptfs_format.c b/security/keys/ecryptfs_format.c
new file mode 100644
index 00000000000..6daa3b6ff9e
--- /dev/null
+++ b/security/keys/ecryptfs_format.c
@@ -0,0 +1,81 @@
1/*
2 * ecryptfs_format.c: helper functions for the encrypted key type
3 *
4 * Copyright (C) 2006 International Business Machines Corp.
5 * Copyright (C) 2010 Politecnico di Torino, Italy
6 * TORSEC group -- http://security.polito.it
7 *
8 * Authors:
9 * Michael A. Halcrow <mahalcro@us.ibm.com>
10 * Tyler Hicks <tyhicks@ou.edu>
11 * Roberto Sassu <roberto.sassu@polito.it>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation, version 2 of the License.
16 */
17
18#include <linux/module.h>
19#include "ecryptfs_format.h"
20
21u8 *ecryptfs_get_auth_tok_key(struct ecryptfs_auth_tok *auth_tok)
22{
23 return auth_tok->token.password.session_key_encryption_key;
24}
25EXPORT_SYMBOL(ecryptfs_get_auth_tok_key);
26
27/*
28 * ecryptfs_get_versions()
29 *
30 * Source code taken from the software 'ecryptfs-utils' version 83.
31 *
32 */
33void ecryptfs_get_versions(int *major, int *minor, int *file_version)
34{
35 *major = ECRYPTFS_VERSION_MAJOR;
36 *minor = ECRYPTFS_VERSION_MINOR;
37 if (file_version)
38 *file_version = ECRYPTFS_SUPPORTED_FILE_VERSION;
39}
40EXPORT_SYMBOL(ecryptfs_get_versions);
41
42/*
43 * ecryptfs_fill_auth_tok - fill the ecryptfs_auth_tok structure
44 *
45 * Fill the ecryptfs_auth_tok structure with required ecryptfs data.
46 * The source code is inspired to the original function generate_payload()
47 * shipped with the software 'ecryptfs-utils' version 83.
48 *
49 */
50int ecryptfs_fill_auth_tok(struct ecryptfs_auth_tok *auth_tok,
51 const char *key_desc)
52{
53 int major, minor;
54
55 ecryptfs_get_versions(&major, &minor, NULL);
56 auth_tok->version = (((uint16_t)(major << 8) & 0xFF00)
57 | ((uint16_t)minor & 0x00FF));
58 auth_tok->token_type = ECRYPTFS_PASSWORD;
59 strncpy((char *)auth_tok->token.password.signature, key_desc,
60 ECRYPTFS_PASSWORD_SIG_SIZE);
61 auth_tok->token.password.session_key_encryption_key_bytes =
62 ECRYPTFS_MAX_KEY_BYTES;
63 /*
64 * Removed auth_tok->token.password.salt and
65 * auth_tok->token.password.session_key_encryption_key
66 * initialization from the original code
67 */
68 /* TODO: Make the hash parameterizable via policy */
69 auth_tok->token.password.flags |=
70 ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET;
71 /* The kernel code will encrypt the session key. */
72 auth_tok->session_key.encrypted_key[0] = 0;
73 auth_tok->session_key.encrypted_key_size = 0;
74 /* Default; subject to change by kernel eCryptfs */
75 auth_tok->token.password.hash_algo = PGP_DIGEST_ALGO_SHA512;
76 auth_tok->token.password.flags &= ~(ECRYPTFS_PERSISTENT_PASSWORD);
77 return 0;
78}
79EXPORT_SYMBOL(ecryptfs_fill_auth_tok);
80
81MODULE_LICENSE("GPL");
diff --git a/security/keys/ecryptfs_format.h b/security/keys/ecryptfs_format.h
new file mode 100644
index 00000000000..40294de238b
--- /dev/null
+++ b/security/keys/ecryptfs_format.h
@@ -0,0 +1,30 @@
1/*
2 * ecryptfs_format.h: helper functions for the encrypted key type
3 *
4 * Copyright (C) 2006 International Business Machines Corp.
5 * Copyright (C) 2010 Politecnico di Torino, Italy
6 * TORSEC group -- http://security.polito.it
7 *
8 * Authors:
9 * Michael A. Halcrow <mahalcro@us.ibm.com>
10 * Tyler Hicks <tyhicks@ou.edu>
11 * Roberto Sassu <roberto.sassu@polito.it>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation, version 2 of the License.
16 */
17
18#ifndef __KEYS_ECRYPTFS_H
19#define __KEYS_ECRYPTFS_H
20
21#include <linux/ecryptfs.h>
22
23#define PGP_DIGEST_ALGO_SHA512 10
24
25u8 *ecryptfs_get_auth_tok_key(struct ecryptfs_auth_tok *auth_tok);
26void ecryptfs_get_versions(int *major, int *minor, int *file_version);
27int ecryptfs_fill_auth_tok(struct ecryptfs_auth_tok *auth_tok,
28 const char *key_desc);
29
30#endif /* __KEYS_ECRYPTFS_H */
diff --git a/security/keys/encrypted.c b/security/keys/encrypted.c
index b1cba5bf0a5..e7eca9ec4c6 100644
--- a/security/keys/encrypted.c
+++ b/security/keys/encrypted.c
@@ -1,8 +1,11 @@
1/* 1/*
2 * Copyright (C) 2010 IBM Corporation 2 * Copyright (C) 2010 IBM Corporation
3 * Copyright (C) 2010 Politecnico di Torino, Italy
4 * TORSEC group -- http://security.polito.it
3 * 5 *
4 * Author: 6 * Authors:
5 * Mimi Zohar <zohar@us.ibm.com> 7 * Mimi Zohar <zohar@us.ibm.com>
8 * Roberto Sassu <roberto.sassu@polito.it>
6 * 9 *
7 * This program is free software; you can redistribute it and/or modify 10 * 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 11 * it under the terms of the GNU General Public License as published by
@@ -26,22 +29,27 @@
26#include <linux/rcupdate.h> 29#include <linux/rcupdate.h>
27#include <linux/scatterlist.h> 30#include <linux/scatterlist.h>
28#include <linux/crypto.h> 31#include <linux/crypto.h>
32#include <linux/ctype.h>
29#include <crypto/hash.h> 33#include <crypto/hash.h>
30#include <crypto/sha.h> 34#include <crypto/sha.h>
31#include <crypto/aes.h> 35#include <crypto/aes.h>
32 36
33#include "encrypted.h" 37#include "encrypted.h"
38#include "ecryptfs_format.h"
34 39
35static const char KEY_TRUSTED_PREFIX[] = "trusted:"; 40static const char KEY_TRUSTED_PREFIX[] = "trusted:";
36static const char KEY_USER_PREFIX[] = "user:"; 41static const char KEY_USER_PREFIX[] = "user:";
37static const char hash_alg[] = "sha256"; 42static const char hash_alg[] = "sha256";
38static const char hmac_alg[] = "hmac(sha256)"; 43static const char hmac_alg[] = "hmac(sha256)";
39static const char blkcipher_alg[] = "cbc(aes)"; 44static const char blkcipher_alg[] = "cbc(aes)";
45static const char key_format_default[] = "default";
46static const char key_format_ecryptfs[] = "ecryptfs";
40static unsigned int ivsize; 47static unsigned int ivsize;
41static int blksize; 48static int blksize;
42 49
43#define KEY_TRUSTED_PREFIX_LEN (sizeof (KEY_TRUSTED_PREFIX) - 1) 50#define KEY_TRUSTED_PREFIX_LEN (sizeof (KEY_TRUSTED_PREFIX) - 1)
44#define KEY_USER_PREFIX_LEN (sizeof (KEY_USER_PREFIX) - 1) 51#define KEY_USER_PREFIX_LEN (sizeof (KEY_USER_PREFIX) - 1)
52#define KEY_ECRYPTFS_DESC_LEN 16
45#define HASH_SIZE SHA256_DIGEST_SIZE 53#define HASH_SIZE SHA256_DIGEST_SIZE
46#define MAX_DATA_SIZE 4096 54#define MAX_DATA_SIZE 4096
47#define MIN_DATA_SIZE 20 55#define MIN_DATA_SIZE 20
@@ -58,6 +66,16 @@ enum {
58 Opt_err = -1, Opt_new, Opt_load, Opt_update 66 Opt_err = -1, Opt_new, Opt_load, Opt_update
59}; 67};
60 68
69enum {
70 Opt_error = -1, Opt_default, Opt_ecryptfs
71};
72
73static const match_table_t key_format_tokens = {
74 {Opt_default, "default"},
75 {Opt_ecryptfs, "ecryptfs"},
76 {Opt_error, NULL}
77};
78
61static const match_table_t key_tokens = { 79static const match_table_t key_tokens = {
62 {Opt_new, "new"}, 80 {Opt_new, "new"},
63 {Opt_load, "load"}, 81 {Opt_load, "load"},
@@ -82,9 +100,37 @@ static int aes_get_sizes(void)
82} 100}
83 101
84/* 102/*
103 * valid_ecryptfs_desc - verify the description of a new/loaded encrypted key
104 *
105 * The description of a encrypted key with format 'ecryptfs' must contain
106 * exactly 16 hexadecimal characters.
107 *
108 */
109static int valid_ecryptfs_desc(const char *ecryptfs_desc)
110{
111 int i;
112
113 if (strlen(ecryptfs_desc) != KEY_ECRYPTFS_DESC_LEN) {
114 pr_err("encrypted_key: key description must be %d hexadecimal "
115 "characters long\n", KEY_ECRYPTFS_DESC_LEN);
116 return -EINVAL;
117 }
118
119 for (i = 0; i < KEY_ECRYPTFS_DESC_LEN; i++) {
120 if (!isxdigit(ecryptfs_desc[i])) {
121 pr_err("encrypted_key: key description must contain "
122 "only hexadecimal characters\n");
123 return -EINVAL;
124 }
125 }
126
127 return 0;
128}
129
130/*
85 * valid_master_desc - verify the 'key-type:desc' of a new/updated master-key 131 * valid_master_desc - verify the 'key-type:desc' of a new/updated master-key
86 * 132 *
87 * key-type:= "trusted:" | "encrypted:" 133 * key-type:= "trusted:" | "user:"
88 * desc:= master-key description 134 * desc:= master-key description
89 * 135 *
90 * Verify that 'key-type' is valid and that 'desc' exists. On key update, 136 * Verify that 'key-type' is valid and that 'desc' exists. On key update,
@@ -118,8 +164,9 @@ out:
118 * datablob_parse - parse the keyctl data 164 * datablob_parse - parse the keyctl data
119 * 165 *
120 * datablob format: 166 * datablob format:
121 * new <master-key name> <decrypted data length> 167 * new [<format>] <master-key name> <decrypted data length>
122 * load <master-key name> <decrypted data length> <encrypted iv + data> 168 * load [<format>] <master-key name> <decrypted data length>
169 * <encrypted iv + data>
123 * update <new-master-key name> 170 * update <new-master-key name>
124 * 171 *
125 * Tokenizes a copy of the keyctl data, returning a pointer to each token, 172 * Tokenizes a copy of the keyctl data, returning a pointer to each token,
@@ -127,52 +174,95 @@ out:
127 * 174 *
128 * On success returns 0, otherwise -EINVAL. 175 * On success returns 0, otherwise -EINVAL.
129 */ 176 */
130static int datablob_parse(char *datablob, char **master_desc, 177static int datablob_parse(char *datablob, const char **format,
131 char **decrypted_datalen, char **hex_encoded_iv) 178 char **master_desc, char **decrypted_datalen,
179 char **hex_encoded_iv)
132{ 180{
133 substring_t args[MAX_OPT_ARGS]; 181 substring_t args[MAX_OPT_ARGS];
134 int ret = -EINVAL; 182 int ret = -EINVAL;
135 int key_cmd; 183 int key_cmd;
136 char *p; 184 int key_format;
185 char *p, *keyword;
186
187 keyword = strsep(&datablob, " \t");
188 if (!keyword) {
189 pr_info("encrypted_key: insufficient parameters specified\n");
190 return ret;
191 }
192 key_cmd = match_token(keyword, key_tokens, args);
137 193
194 /* Get optional format: default | ecryptfs */
138 p = strsep(&datablob, " \t"); 195 p = strsep(&datablob, " \t");
139 if (!p) 196 if (!p) {
197 pr_err("encrypted_key: insufficient parameters specified\n");
140 return ret; 198 return ret;
141 key_cmd = match_token(p, key_tokens, args); 199 }
142 200
143 *master_desc = strsep(&datablob, " \t"); 201 key_format = match_token(p, key_format_tokens, args);
144 if (!*master_desc) 202 switch (key_format) {
203 case Opt_ecryptfs:
204 case Opt_default:
205 *format = p;
206 *master_desc = strsep(&datablob, " \t");
207 break;
208 case Opt_error:
209 *master_desc = p;
210 break;
211 }
212
213 if (!*master_desc) {
214 pr_info("encrypted_key: master key parameter is missing\n");
145 goto out; 215 goto out;
216 }
146 217
147 if (valid_master_desc(*master_desc, NULL) < 0) 218 if (valid_master_desc(*master_desc, NULL) < 0) {
219 pr_info("encrypted_key: master key parameter \'%s\' "
220 "is invalid\n", *master_desc);
148 goto out; 221 goto out;
222 }
149 223
150 if (decrypted_datalen) { 224 if (decrypted_datalen) {
151 *decrypted_datalen = strsep(&datablob, " \t"); 225 *decrypted_datalen = strsep(&datablob, " \t");
152 if (!*decrypted_datalen) 226 if (!*decrypted_datalen) {
227 pr_info("encrypted_key: keylen parameter is missing\n");
153 goto out; 228 goto out;
229 }
154 } 230 }
155 231
156 switch (key_cmd) { 232 switch (key_cmd) {
157 case Opt_new: 233 case Opt_new:
158 if (!decrypted_datalen) 234 if (!decrypted_datalen) {
235 pr_info("encrypted_key: keyword \'%s\' not allowed "
236 "when called from .update method\n", keyword);
159 break; 237 break;
238 }
160 ret = 0; 239 ret = 0;
161 break; 240 break;
162 case Opt_load: 241 case Opt_load:
163 if (!decrypted_datalen) 242 if (!decrypted_datalen) {
243 pr_info("encrypted_key: keyword \'%s\' not allowed "
244 "when called from .update method\n", keyword);
164 break; 245 break;
246 }
165 *hex_encoded_iv = strsep(&datablob, " \t"); 247 *hex_encoded_iv = strsep(&datablob, " \t");
166 if (!*hex_encoded_iv) 248 if (!*hex_encoded_iv) {
249 pr_info("encrypted_key: hex blob is missing\n");
167 break; 250 break;
251 }
168 ret = 0; 252 ret = 0;
169 break; 253 break;
170 case Opt_update: 254 case Opt_update:
171 if (decrypted_datalen) 255 if (decrypted_datalen) {
256 pr_info("encrypted_key: keyword \'%s\' not allowed "
257 "when called from .instantiate method\n",
258 keyword);
172 break; 259 break;
260 }
173 ret = 0; 261 ret = 0;
174 break; 262 break;
175 case Opt_err: 263 case Opt_err:
264 pr_info("encrypted_key: keyword \'%s\' not recognized\n",
265 keyword);
176 break; 266 break;
177 } 267 }
178out: 268out:
@@ -197,8 +287,8 @@ static char *datablob_format(struct encrypted_key_payload *epayload,
197 ascii_buf[asciiblob_len] = '\0'; 287 ascii_buf[asciiblob_len] = '\0';
198 288
199 /* copy datablob master_desc and datalen strings */ 289 /* copy datablob master_desc and datalen strings */
200 len = sprintf(ascii_buf, "%s %s ", epayload->master_desc, 290 len = sprintf(ascii_buf, "%s %s %s ", epayload->format,
201 epayload->datalen); 291 epayload->master_desc, epayload->datalen);
202 292
203 /* convert the hex encoded iv, encrypted-data and HMAC to ascii */ 293 /* convert the hex encoded iv, encrypted-data and HMAC to ascii */
204 bufp = &ascii_buf[len]; 294 bufp = &ascii_buf[len];
@@ -378,11 +468,13 @@ static struct key *request_master_key(struct encrypted_key_payload *epayload,
378 } else 468 } else
379 goto out; 469 goto out;
380 470
381 if (IS_ERR(mkey)) 471 if (IS_ERR(mkey)) {
382 pr_info("encrypted_key: key %s not found", 472 pr_info("encrypted_key: key %s not found",
383 epayload->master_desc); 473 epayload->master_desc);
384 if (mkey) 474 goto out;
385 dump_master_key(*master_key, *master_keylen); 475 }
476
477 dump_master_key(*master_key, *master_keylen);
386out: 478out:
387 return mkey; 479 return mkey;
388} 480}
@@ -439,9 +531,9 @@ static int datablob_hmac_append(struct encrypted_key_payload *epayload,
439 if (ret < 0) 531 if (ret < 0)
440 goto out; 532 goto out;
441 533
442 digest = epayload->master_desc + epayload->datablob_len; 534 digest = epayload->format + epayload->datablob_len;
443 ret = calc_hmac(digest, derived_key, sizeof derived_key, 535 ret = calc_hmac(digest, derived_key, sizeof derived_key,
444 epayload->master_desc, epayload->datablob_len); 536 epayload->format, epayload->datablob_len);
445 if (!ret) 537 if (!ret)
446 dump_hmac(NULL, digest, HASH_SIZE); 538 dump_hmac(NULL, digest, HASH_SIZE);
447out: 539out:
@@ -450,26 +542,35 @@ out:
450 542
451/* verify HMAC before decrypting encrypted key */ 543/* verify HMAC before decrypting encrypted key */
452static int datablob_hmac_verify(struct encrypted_key_payload *epayload, 544static int datablob_hmac_verify(struct encrypted_key_payload *epayload,
453 const u8 *master_key, size_t master_keylen) 545 const u8 *format, const u8 *master_key,
546 size_t master_keylen)
454{ 547{
455 u8 derived_key[HASH_SIZE]; 548 u8 derived_key[HASH_SIZE];
456 u8 digest[HASH_SIZE]; 549 u8 digest[HASH_SIZE];
457 int ret; 550 int ret;
551 char *p;
552 unsigned short len;
458 553
459 ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen); 554 ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen);
460 if (ret < 0) 555 if (ret < 0)
461 goto out; 556 goto out;
462 557
463 ret = calc_hmac(digest, derived_key, sizeof derived_key, 558 len = epayload->datablob_len;
464 epayload->master_desc, epayload->datablob_len); 559 if (!format) {
560 p = epayload->master_desc;
561 len -= strlen(epayload->format) + 1;
562 } else
563 p = epayload->format;
564
565 ret = calc_hmac(digest, derived_key, sizeof derived_key, p, len);
465 if (ret < 0) 566 if (ret < 0)
466 goto out; 567 goto out;
467 ret = memcmp(digest, epayload->master_desc + epayload->datablob_len, 568 ret = memcmp(digest, epayload->format + epayload->datablob_len,
468 sizeof digest); 569 sizeof digest);
469 if (ret) { 570 if (ret) {
470 ret = -EINVAL; 571 ret = -EINVAL;
471 dump_hmac("datablob", 572 dump_hmac("datablob",
472 epayload->master_desc + epayload->datablob_len, 573 epayload->format + epayload->datablob_len,
473 HASH_SIZE); 574 HASH_SIZE);
474 dump_hmac("calc", digest, HASH_SIZE); 575 dump_hmac("calc", digest, HASH_SIZE);
475 } 576 }
@@ -514,13 +615,16 @@ out:
514 615
515/* Allocate memory for decrypted key and datablob. */ 616/* Allocate memory for decrypted key and datablob. */
516static struct encrypted_key_payload *encrypted_key_alloc(struct key *key, 617static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
618 const char *format,
517 const char *master_desc, 619 const char *master_desc,
518 const char *datalen) 620 const char *datalen)
519{ 621{
520 struct encrypted_key_payload *epayload = NULL; 622 struct encrypted_key_payload *epayload = NULL;
521 unsigned short datablob_len; 623 unsigned short datablob_len;
522 unsigned short decrypted_datalen; 624 unsigned short decrypted_datalen;
625 unsigned short payload_datalen;
523 unsigned int encrypted_datalen; 626 unsigned int encrypted_datalen;
627 unsigned int format_len;
524 long dlen; 628 long dlen;
525 int ret; 629 int ret;
526 630
@@ -528,29 +632,43 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
528 if (ret < 0 || dlen < MIN_DATA_SIZE || dlen > MAX_DATA_SIZE) 632 if (ret < 0 || dlen < MIN_DATA_SIZE || dlen > MAX_DATA_SIZE)
529 return ERR_PTR(-EINVAL); 633 return ERR_PTR(-EINVAL);
530 634
635 format_len = (!format) ? strlen(key_format_default) : strlen(format);
531 decrypted_datalen = dlen; 636 decrypted_datalen = dlen;
637 payload_datalen = decrypted_datalen;
638 if (format && !strcmp(format, key_format_ecryptfs)) {
639 if (dlen != ECRYPTFS_MAX_KEY_BYTES) {
640 pr_err("encrypted_key: keylen for the ecryptfs format "
641 "must be equal to %d bytes\n",
642 ECRYPTFS_MAX_KEY_BYTES);
643 return ERR_PTR(-EINVAL);
644 }
645 decrypted_datalen = ECRYPTFS_MAX_KEY_BYTES;
646 payload_datalen = sizeof(struct ecryptfs_auth_tok);
647 }
648
532 encrypted_datalen = roundup(decrypted_datalen, blksize); 649 encrypted_datalen = roundup(decrypted_datalen, blksize);
533 650
534 datablob_len = strlen(master_desc) + 1 + strlen(datalen) + 1 651 datablob_len = format_len + 1 + strlen(master_desc) + 1
535 + ivsize + 1 + encrypted_datalen; 652 + strlen(datalen) + 1 + ivsize + 1 + encrypted_datalen;
536 653
537 ret = key_payload_reserve(key, decrypted_datalen + datablob_len 654 ret = key_payload_reserve(key, payload_datalen + datablob_len
538 + HASH_SIZE + 1); 655 + HASH_SIZE + 1);
539 if (ret < 0) 656 if (ret < 0)
540 return ERR_PTR(ret); 657 return ERR_PTR(ret);
541 658
542 epayload = kzalloc(sizeof(*epayload) + decrypted_datalen + 659 epayload = kzalloc(sizeof(*epayload) + payload_datalen +
543 datablob_len + HASH_SIZE + 1, GFP_KERNEL); 660 datablob_len + HASH_SIZE + 1, GFP_KERNEL);
544 if (!epayload) 661 if (!epayload)
545 return ERR_PTR(-ENOMEM); 662 return ERR_PTR(-ENOMEM);
546 663
664 epayload->payload_datalen = payload_datalen;
547 epayload->decrypted_datalen = decrypted_datalen; 665 epayload->decrypted_datalen = decrypted_datalen;
548 epayload->datablob_len = datablob_len; 666 epayload->datablob_len = datablob_len;
549 return epayload; 667 return epayload;
550} 668}
551 669
552static int encrypted_key_decrypt(struct encrypted_key_payload *epayload, 670static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
553 const char *hex_encoded_iv) 671 const char *format, const char *hex_encoded_iv)
554{ 672{
555 struct key *mkey; 673 struct key *mkey;
556 u8 derived_key[HASH_SIZE]; 674 u8 derived_key[HASH_SIZE];
@@ -571,14 +689,14 @@ static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
571 hex2bin(epayload->iv, hex_encoded_iv, ivsize); 689 hex2bin(epayload->iv, hex_encoded_iv, ivsize);
572 hex2bin(epayload->encrypted_data, hex_encoded_data, encrypted_datalen); 690 hex2bin(epayload->encrypted_data, hex_encoded_data, encrypted_datalen);
573 691
574 hmac = epayload->master_desc + epayload->datablob_len; 692 hmac = epayload->format + epayload->datablob_len;
575 hex2bin(hmac, hex_encoded_data + (encrypted_datalen * 2), HASH_SIZE); 693 hex2bin(hmac, hex_encoded_data + (encrypted_datalen * 2), HASH_SIZE);
576 694
577 mkey = request_master_key(epayload, &master_key, &master_keylen); 695 mkey = request_master_key(epayload, &master_key, &master_keylen);
578 if (IS_ERR(mkey)) 696 if (IS_ERR(mkey))
579 return PTR_ERR(mkey); 697 return PTR_ERR(mkey);
580 698
581 ret = datablob_hmac_verify(epayload, master_key, master_keylen); 699 ret = datablob_hmac_verify(epayload, format, master_key, master_keylen);
582 if (ret < 0) { 700 if (ret < 0) {
583 pr_err("encrypted_key: bad hmac (%d)\n", ret); 701 pr_err("encrypted_key: bad hmac (%d)\n", ret);
584 goto out; 702 goto out;
@@ -598,13 +716,28 @@ out:
598} 716}
599 717
600static void __ekey_init(struct encrypted_key_payload *epayload, 718static void __ekey_init(struct encrypted_key_payload *epayload,
601 const char *master_desc, const char *datalen) 719 const char *format, const char *master_desc,
720 const char *datalen)
602{ 721{
603 epayload->master_desc = epayload->decrypted_data 722 unsigned int format_len;
604 + epayload->decrypted_datalen; 723
724 format_len = (!format) ? strlen(key_format_default) : strlen(format);
725 epayload->format = epayload->payload_data + epayload->payload_datalen;
726 epayload->master_desc = epayload->format + format_len + 1;
605 epayload->datalen = epayload->master_desc + strlen(master_desc) + 1; 727 epayload->datalen = epayload->master_desc + strlen(master_desc) + 1;
606 epayload->iv = epayload->datalen + strlen(datalen) + 1; 728 epayload->iv = epayload->datalen + strlen(datalen) + 1;
607 epayload->encrypted_data = epayload->iv + ivsize + 1; 729 epayload->encrypted_data = epayload->iv + ivsize + 1;
730 epayload->decrypted_data = epayload->payload_data;
731
732 if (!format)
733 memcpy(epayload->format, key_format_default, format_len);
734 else {
735 if (!strcmp(format, key_format_ecryptfs))
736 epayload->decrypted_data =
737 ecryptfs_get_auth_tok_key((struct ecryptfs_auth_tok *)epayload->payload_data);
738
739 memcpy(epayload->format, format, format_len);
740 }
608 741
609 memcpy(epayload->master_desc, master_desc, strlen(master_desc)); 742 memcpy(epayload->master_desc, master_desc, strlen(master_desc));
610 memcpy(epayload->datalen, datalen, strlen(datalen)); 743 memcpy(epayload->datalen, datalen, strlen(datalen));
@@ -617,19 +750,29 @@ static void __ekey_init(struct encrypted_key_payload *epayload,
617 * itself. For an old key, decrypt the hex encoded data. 750 * itself. For an old key, decrypt the hex encoded data.
618 */ 751 */
619static int encrypted_init(struct encrypted_key_payload *epayload, 752static int encrypted_init(struct encrypted_key_payload *epayload,
753 const char *key_desc, const char *format,
620 const char *master_desc, const char *datalen, 754 const char *master_desc, const char *datalen,
621 const char *hex_encoded_iv) 755 const char *hex_encoded_iv)
622{ 756{
623 int ret = 0; 757 int ret = 0;
624 758
625 __ekey_init(epayload, master_desc, datalen); 759 if (format && !strcmp(format, key_format_ecryptfs)) {
760 ret = valid_ecryptfs_desc(key_desc);
761 if (ret < 0)
762 return ret;
763
764 ecryptfs_fill_auth_tok((struct ecryptfs_auth_tok *)epayload->payload_data,
765 key_desc);
766 }
767
768 __ekey_init(epayload, format, master_desc, datalen);
626 if (!hex_encoded_iv) { 769 if (!hex_encoded_iv) {
627 get_random_bytes(epayload->iv, ivsize); 770 get_random_bytes(epayload->iv, ivsize);
628 771
629 get_random_bytes(epayload->decrypted_data, 772 get_random_bytes(epayload->decrypted_data,
630 epayload->decrypted_datalen); 773 epayload->decrypted_datalen);
631 } else 774 } else
632 ret = encrypted_key_decrypt(epayload, hex_encoded_iv); 775 ret = encrypted_key_decrypt(epayload, format, hex_encoded_iv);
633 return ret; 776 return ret;
634} 777}
635 778
@@ -646,6 +789,7 @@ static int encrypted_instantiate(struct key *key, const void *data,
646{ 789{
647 struct encrypted_key_payload *epayload = NULL; 790 struct encrypted_key_payload *epayload = NULL;
648 char *datablob = NULL; 791 char *datablob = NULL;
792 const char *format = NULL;
649 char *master_desc = NULL; 793 char *master_desc = NULL;
650 char *decrypted_datalen = NULL; 794 char *decrypted_datalen = NULL;
651 char *hex_encoded_iv = NULL; 795 char *hex_encoded_iv = NULL;
@@ -659,18 +803,19 @@ static int encrypted_instantiate(struct key *key, const void *data,
659 return -ENOMEM; 803 return -ENOMEM;
660 datablob[datalen] = 0; 804 datablob[datalen] = 0;
661 memcpy(datablob, data, datalen); 805 memcpy(datablob, data, datalen);
662 ret = datablob_parse(datablob, &master_desc, &decrypted_datalen, 806 ret = datablob_parse(datablob, &format, &master_desc,
663 &hex_encoded_iv); 807 &decrypted_datalen, &hex_encoded_iv);
664 if (ret < 0) 808 if (ret < 0)
665 goto out; 809 goto out;
666 810
667 epayload = encrypted_key_alloc(key, master_desc, decrypted_datalen); 811 epayload = encrypted_key_alloc(key, format, master_desc,
812 decrypted_datalen);
668 if (IS_ERR(epayload)) { 813 if (IS_ERR(epayload)) {
669 ret = PTR_ERR(epayload); 814 ret = PTR_ERR(epayload);
670 goto out; 815 goto out;
671 } 816 }
672 ret = encrypted_init(epayload, master_desc, decrypted_datalen, 817 ret = encrypted_init(epayload, key->description, format, master_desc,
673 hex_encoded_iv); 818 decrypted_datalen, hex_encoded_iv);
674 if (ret < 0) { 819 if (ret < 0) {
675 kfree(epayload); 820 kfree(epayload);
676 goto out; 821 goto out;
@@ -706,6 +851,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
706 struct encrypted_key_payload *new_epayload; 851 struct encrypted_key_payload *new_epayload;
707 char *buf; 852 char *buf;
708 char *new_master_desc = NULL; 853 char *new_master_desc = NULL;
854 const char *format = NULL;
709 int ret = 0; 855 int ret = 0;
710 856
711 if (datalen <= 0 || datalen > 32767 || !data) 857 if (datalen <= 0 || datalen > 32767 || !data)
@@ -717,7 +863,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
717 863
718 buf[datalen] = 0; 864 buf[datalen] = 0;
719 memcpy(buf, data, datalen); 865 memcpy(buf, data, datalen);
720 ret = datablob_parse(buf, &new_master_desc, NULL, NULL); 866 ret = datablob_parse(buf, &format, &new_master_desc, NULL, NULL);
721 if (ret < 0) 867 if (ret < 0)
722 goto out; 868 goto out;
723 869
@@ -725,18 +871,19 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
725 if (ret < 0) 871 if (ret < 0)
726 goto out; 872 goto out;
727 873
728 new_epayload = encrypted_key_alloc(key, new_master_desc, 874 new_epayload = encrypted_key_alloc(key, epayload->format,
729 epayload->datalen); 875 new_master_desc, epayload->datalen);
730 if (IS_ERR(new_epayload)) { 876 if (IS_ERR(new_epayload)) {
731 ret = PTR_ERR(new_epayload); 877 ret = PTR_ERR(new_epayload);
732 goto out; 878 goto out;
733 } 879 }
734 880
735 __ekey_init(new_epayload, new_master_desc, epayload->datalen); 881 __ekey_init(new_epayload, epayload->format, new_master_desc,
882 epayload->datalen);
736 883
737 memcpy(new_epayload->iv, epayload->iv, ivsize); 884 memcpy(new_epayload->iv, epayload->iv, ivsize);
738 memcpy(new_epayload->decrypted_data, epayload->decrypted_data, 885 memcpy(new_epayload->payload_data, epayload->payload_data,
739 epayload->decrypted_datalen); 886 epayload->payload_datalen);
740 887
741 rcu_assign_pointer(key->payload.data, new_epayload); 888 rcu_assign_pointer(key->payload.data, new_epayload);
742 call_rcu(&epayload->rcu, encrypted_rcu_free); 889 call_rcu(&epayload->rcu, encrypted_rcu_free);
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index 6cff37529b8..60d4e3f5e4b 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -251,6 +251,8 @@ struct key *key_get_instantiation_authkey(key_serial_t target_id)
251 251
252 if (IS_ERR(authkey_ref)) { 252 if (IS_ERR(authkey_ref)) {
253 authkey = ERR_CAST(authkey_ref); 253 authkey = ERR_CAST(authkey_ref);
254 if (authkey == ERR_PTR(-EAGAIN))
255 authkey = ERR_PTR(-ENOKEY);
254 goto error; 256 goto error;
255 } 257 }
256 258