diff options
-rw-r--r-- | arch/arm64/Kconfig | 4 | ||||
-rw-r--r-- | arch/powerpc/Kconfig | 5 | ||||
-rw-r--r-- | arch/s390/Kconfig | 3 | ||||
-rw-r--r-- | arch/sparc/Kconfig | 3 | ||||
-rw-r--r-- | arch/x86/Kconfig | 4 | ||||
-rw-r--r-- | crypto/asymmetric_keys/verify_pefile.c | 4 | ||||
-rw-r--r-- | crypto/asymmetric_keys/x509_cert_parser.c | 1 | ||||
-rw-r--r-- | include/linux/key.h | 1 | ||||
-rw-r--r-- | include/uapi/linux/keyctl.h | 4 | ||||
-rw-r--r-- | security/keys/Kconfig | 6 | ||||
-rw-r--r-- | security/keys/dh.c | 300 | ||||
-rw-r--r-- | security/keys/encrypted-keys/encrypted.c | 204 | ||||
-rw-r--r-- | security/keys/gc.c | 4 | ||||
-rw-r--r-- | security/keys/key.c | 16 | ||||
-rw-r--r-- | security/keys/keyctl.c | 16 | ||||
-rw-r--r-- | security/keys/keyring.c | 12 | ||||
-rw-r--r-- | security/keys/process_keys.c | 7 | ||||
-rw-r--r-- | security/keys/trusted.c | 50 | ||||
-rw-r--r-- | security/keys/user_defined.c | 16 |
19 files changed, 330 insertions, 330 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 3dcd7ec69bca..b2024db225a9 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig | |||
@@ -1084,10 +1084,6 @@ config SYSVIPC_COMPAT | |||
1084 | def_bool y | 1084 | def_bool y |
1085 | depends on COMPAT && SYSVIPC | 1085 | depends on COMPAT && SYSVIPC |
1086 | 1086 | ||
1087 | config KEYS_COMPAT | ||
1088 | def_bool y | ||
1089 | depends on COMPAT && KEYS | ||
1090 | |||
1091 | endmenu | 1087 | endmenu |
1092 | 1088 | ||
1093 | menu "Power management options" | 1089 | menu "Power management options" |
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 964da1891ea9..bf4391d18923 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -1199,11 +1199,6 @@ source "arch/powerpc/Kconfig.debug" | |||
1199 | 1199 | ||
1200 | source "security/Kconfig" | 1200 | source "security/Kconfig" |
1201 | 1201 | ||
1202 | config KEYS_COMPAT | ||
1203 | bool | ||
1204 | depends on COMPAT && KEYS | ||
1205 | default y | ||
1206 | |||
1207 | source "crypto/Kconfig" | 1202 | source "crypto/Kconfig" |
1208 | 1203 | ||
1209 | config PPC_LIB_RHEAP | 1204 | config PPC_LIB_RHEAP |
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index e161fafb495b..6967addc6a89 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -363,9 +363,6 @@ config COMPAT | |||
363 | config SYSVIPC_COMPAT | 363 | config SYSVIPC_COMPAT |
364 | def_bool y if COMPAT && SYSVIPC | 364 | def_bool y if COMPAT && SYSVIPC |
365 | 365 | ||
366 | config KEYS_COMPAT | ||
367 | def_bool y if COMPAT && KEYS | ||
368 | |||
369 | config SMP | 366 | config SMP |
370 | def_bool y | 367 | def_bool y |
371 | prompt "Symmetric multi-processing support" | 368 | prompt "Symmetric multi-processing support" |
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index b558c9e29de3..5639c9fe5b55 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
@@ -577,9 +577,6 @@ config SYSVIPC_COMPAT | |||
577 | depends on COMPAT && SYSVIPC | 577 | depends on COMPAT && SYSVIPC |
578 | default y | 578 | default y |
579 | 579 | ||
580 | config KEYS_COMPAT | ||
581 | def_bool y if COMPAT && KEYS | ||
582 | |||
583 | endmenu | 580 | endmenu |
584 | 581 | ||
585 | source "net/Kconfig" | 582 | source "net/Kconfig" |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 4ccfacc7232a..0efb4c9497bc 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -2776,10 +2776,6 @@ config COMPAT_FOR_U64_ALIGNMENT | |||
2776 | config SYSVIPC_COMPAT | 2776 | config SYSVIPC_COMPAT |
2777 | def_bool y | 2777 | def_bool y |
2778 | depends on SYSVIPC | 2778 | depends on SYSVIPC |
2779 | |||
2780 | config KEYS_COMPAT | ||
2781 | def_bool y | ||
2782 | depends on KEYS | ||
2783 | endif | 2779 | endif |
2784 | 2780 | ||
2785 | endmenu | 2781 | endmenu |
diff --git a/crypto/asymmetric_keys/verify_pefile.c b/crypto/asymmetric_keys/verify_pefile.c index 672a94c2c3ff..d178650fd524 100644 --- a/crypto/asymmetric_keys/verify_pefile.c +++ b/crypto/asymmetric_keys/verify_pefile.c | |||
@@ -381,7 +381,7 @@ static int pefile_digest_pe(const void *pebuf, unsigned int pelen, | |||
381 | } | 381 | } |
382 | 382 | ||
383 | error: | 383 | error: |
384 | kfree(desc); | 384 | kzfree(desc); |
385 | error_no_desc: | 385 | error_no_desc: |
386 | crypto_free_shash(tfm); | 386 | crypto_free_shash(tfm); |
387 | kleave(" = %d", ret); | 387 | kleave(" = %d", ret); |
@@ -450,6 +450,6 @@ int verify_pefile_signature(const void *pebuf, unsigned pelen, | |||
450 | ret = pefile_digest_pe(pebuf, pelen, &ctx); | 450 | ret = pefile_digest_pe(pebuf, pelen, &ctx); |
451 | 451 | ||
452 | error: | 452 | error: |
453 | kfree(ctx.digest); | 453 | kzfree(ctx.digest); |
454 | return ret; | 454 | return ret; |
455 | } | 455 | } |
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c index c80765b211cf..dd03fead1ca3 100644 --- a/crypto/asymmetric_keys/x509_cert_parser.c +++ b/crypto/asymmetric_keys/x509_cert_parser.c | |||
@@ -102,6 +102,7 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen) | |||
102 | } | 102 | } |
103 | } | 103 | } |
104 | 104 | ||
105 | ret = -ENOMEM; | ||
105 | cert->pub->key = kmemdup(ctx->key, ctx->key_size, GFP_KERNEL); | 106 | cert->pub->key = kmemdup(ctx->key, ctx->key_size, GFP_KERNEL); |
106 | if (!cert->pub->key) | 107 | if (!cert->pub->key) |
107 | goto error_decode; | 108 | goto error_decode; |
diff --git a/include/linux/key.h b/include/linux/key.h index 0c9b93b0d1f7..78e25aabedaf 100644 --- a/include/linux/key.h +++ b/include/linux/key.h | |||
@@ -173,7 +173,6 @@ struct key { | |||
173 | #ifdef KEY_DEBUGGING | 173 | #ifdef KEY_DEBUGGING |
174 | unsigned magic; | 174 | unsigned magic; |
175 | #define KEY_DEBUG_MAGIC 0x18273645u | 175 | #define KEY_DEBUG_MAGIC 0x18273645u |
176 | #define KEY_DEBUG_MAGIC_X 0xf8e9dacbu | ||
177 | #endif | 176 | #endif |
178 | 177 | ||
179 | unsigned long flags; /* status flags (change with bitops) */ | 178 | unsigned long flags; /* status flags (change with bitops) */ |
diff --git a/include/uapi/linux/keyctl.h b/include/uapi/linux/keyctl.h index 201c6644b237..ef16df06642a 100644 --- a/include/uapi/linux/keyctl.h +++ b/include/uapi/linux/keyctl.h | |||
@@ -70,8 +70,8 @@ struct keyctl_dh_params { | |||
70 | }; | 70 | }; |
71 | 71 | ||
72 | struct keyctl_kdf_params { | 72 | struct keyctl_kdf_params { |
73 | char *hashname; | 73 | char __user *hashname; |
74 | char *otherinfo; | 74 | char __user *otherinfo; |
75 | __u32 otherinfolen; | 75 | __u32 otherinfolen; |
76 | __u32 __spare[8]; | 76 | __u32 __spare[8]; |
77 | }; | 77 | }; |
diff --git a/security/keys/Kconfig b/security/keys/Kconfig index 6fd95f76bfae..a7a23b5541f8 100644 --- a/security/keys/Kconfig +++ b/security/keys/Kconfig | |||
@@ -20,6 +20,10 @@ config KEYS | |||
20 | 20 | ||
21 | If you are unsure as to whether this is required, answer N. | 21 | If you are unsure as to whether this is required, answer N. |
22 | 22 | ||
23 | config KEYS_COMPAT | ||
24 | def_bool y | ||
25 | depends on COMPAT && KEYS | ||
26 | |||
23 | config PERSISTENT_KEYRINGS | 27 | config PERSISTENT_KEYRINGS |
24 | bool "Enable register of persistent per-UID keyrings" | 28 | bool "Enable register of persistent per-UID keyrings" |
25 | depends on KEYS | 29 | depends on KEYS |
@@ -89,9 +93,9 @@ config ENCRYPTED_KEYS | |||
89 | config KEY_DH_OPERATIONS | 93 | config KEY_DH_OPERATIONS |
90 | bool "Diffie-Hellman operations on retained keys" | 94 | bool "Diffie-Hellman operations on retained keys" |
91 | depends on KEYS | 95 | depends on KEYS |
92 | select MPILIB | ||
93 | select CRYPTO | 96 | select CRYPTO |
94 | select CRYPTO_HASH | 97 | select CRYPTO_HASH |
98 | select CRYPTO_DH | ||
95 | help | 99 | help |
96 | This option provides support for calculating Diffie-Hellman | 100 | This option provides support for calculating Diffie-Hellman |
97 | public keys and shared secrets using values stored as keys | 101 | public keys and shared secrets using values stored as keys |
diff --git a/security/keys/dh.c b/security/keys/dh.c index e603bd912e4c..4755d4b4f945 100644 --- a/security/keys/dh.c +++ b/security/keys/dh.c | |||
@@ -8,34 +8,17 @@ | |||
8 | * 2 of the License, or (at your option) any later version. | 8 | * 2 of the License, or (at your option) any later version. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/mpi.h> | ||
12 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
13 | #include <linux/uaccess.h> | 12 | #include <linux/uaccess.h> |
13 | #include <linux/scatterlist.h> | ||
14 | #include <linux/crypto.h> | 14 | #include <linux/crypto.h> |
15 | #include <crypto/hash.h> | 15 | #include <crypto/hash.h> |
16 | #include <crypto/kpp.h> | ||
17 | #include <crypto/dh.h> | ||
16 | #include <keys/user-type.h> | 18 | #include <keys/user-type.h> |
17 | #include "internal.h" | 19 | #include "internal.h" |
18 | 20 | ||
19 | /* | 21 | static ssize_t dh_data_from_key(key_serial_t keyid, void **data) |
20 | * Public key or shared secret generation function [RFC2631 sec 2.1.1] | ||
21 | * | ||
22 | * ya = g^xa mod p; | ||
23 | * or | ||
24 | * ZZ = yb^xa mod p; | ||
25 | * | ||
26 | * where xa is the local private key, ya is the local public key, g is | ||
27 | * the generator, p is the prime, yb is the remote public key, and ZZ | ||
28 | * is the shared secret. | ||
29 | * | ||
30 | * Both are the same calculation, so g or yb are the "base" and ya or | ||
31 | * ZZ are the "result". | ||
32 | */ | ||
33 | static int do_dh(MPI result, MPI base, MPI xa, MPI p) | ||
34 | { | ||
35 | return mpi_powm(result, base, xa, p); | ||
36 | } | ||
37 | |||
38 | static ssize_t mpi_from_key(key_serial_t keyid, size_t maxlen, MPI *mpi) | ||
39 | { | 22 | { |
40 | struct key *key; | 23 | struct key *key; |
41 | key_ref_t key_ref; | 24 | key_ref_t key_ref; |
@@ -56,19 +39,17 @@ static ssize_t mpi_from_key(key_serial_t keyid, size_t maxlen, MPI *mpi) | |||
56 | status = key_validate(key); | 39 | status = key_validate(key); |
57 | if (status == 0) { | 40 | if (status == 0) { |
58 | const struct user_key_payload *payload; | 41 | const struct user_key_payload *payload; |
42 | uint8_t *duplicate; | ||
59 | 43 | ||
60 | payload = user_key_payload_locked(key); | 44 | payload = user_key_payload_locked(key); |
61 | 45 | ||
62 | if (maxlen == 0) { | 46 | duplicate = kmemdup(payload->data, payload->datalen, |
63 | *mpi = NULL; | 47 | GFP_KERNEL); |
48 | if (duplicate) { | ||
49 | *data = duplicate; | ||
64 | ret = payload->datalen; | 50 | ret = payload->datalen; |
65 | } else if (payload->datalen <= maxlen) { | ||
66 | *mpi = mpi_read_raw_data(payload->data, | ||
67 | payload->datalen); | ||
68 | if (*mpi) | ||
69 | ret = payload->datalen; | ||
70 | } else { | 51 | } else { |
71 | ret = -EINVAL; | 52 | ret = -ENOMEM; |
72 | } | 53 | } |
73 | } | 54 | } |
74 | up_read(&key->sem); | 55 | up_read(&key->sem); |
@@ -79,6 +60,29 @@ error: | |||
79 | return ret; | 60 | return ret; |
80 | } | 61 | } |
81 | 62 | ||
63 | static void dh_free_data(struct dh *dh) | ||
64 | { | ||
65 | kzfree(dh->key); | ||
66 | kzfree(dh->p); | ||
67 | kzfree(dh->g); | ||
68 | } | ||
69 | |||
70 | struct dh_completion { | ||
71 | struct completion completion; | ||
72 | int err; | ||
73 | }; | ||
74 | |||
75 | static void dh_crypto_done(struct crypto_async_request *req, int err) | ||
76 | { | ||
77 | struct dh_completion *compl = req->data; | ||
78 | |||
79 | if (err == -EINPROGRESS) | ||
80 | return; | ||
81 | |||
82 | compl->err = err; | ||
83 | complete(&compl->completion); | ||
84 | } | ||
85 | |||
82 | struct kdf_sdesc { | 86 | struct kdf_sdesc { |
83 | struct shash_desc shash; | 87 | struct shash_desc shash; |
84 | char ctx[]; | 88 | char ctx[]; |
@@ -89,6 +93,7 @@ static int kdf_alloc(struct kdf_sdesc **sdesc_ret, char *hashname) | |||
89 | struct crypto_shash *tfm; | 93 | struct crypto_shash *tfm; |
90 | struct kdf_sdesc *sdesc; | 94 | struct kdf_sdesc *sdesc; |
91 | int size; | 95 | int size; |
96 | int err; | ||
92 | 97 | ||
93 | /* allocate synchronous hash */ | 98 | /* allocate synchronous hash */ |
94 | tfm = crypto_alloc_shash(hashname, 0, 0); | 99 | tfm = crypto_alloc_shash(hashname, 0, 0); |
@@ -97,16 +102,25 @@ static int kdf_alloc(struct kdf_sdesc **sdesc_ret, char *hashname) | |||
97 | return PTR_ERR(tfm); | 102 | return PTR_ERR(tfm); |
98 | } | 103 | } |
99 | 104 | ||
105 | err = -EINVAL; | ||
106 | if (crypto_shash_digestsize(tfm) == 0) | ||
107 | goto out_free_tfm; | ||
108 | |||
109 | err = -ENOMEM; | ||
100 | size = sizeof(struct shash_desc) + crypto_shash_descsize(tfm); | 110 | size = sizeof(struct shash_desc) + crypto_shash_descsize(tfm); |
101 | sdesc = kmalloc(size, GFP_KERNEL); | 111 | sdesc = kmalloc(size, GFP_KERNEL); |
102 | if (!sdesc) | 112 | if (!sdesc) |
103 | return -ENOMEM; | 113 | goto out_free_tfm; |
104 | sdesc->shash.tfm = tfm; | 114 | sdesc->shash.tfm = tfm; |
105 | sdesc->shash.flags = 0x0; | 115 | sdesc->shash.flags = 0x0; |
106 | 116 | ||
107 | *sdesc_ret = sdesc; | 117 | *sdesc_ret = sdesc; |
108 | 118 | ||
109 | return 0; | 119 | return 0; |
120 | |||
121 | out_free_tfm: | ||
122 | crypto_free_shash(tfm); | ||
123 | return err; | ||
110 | } | 124 | } |
111 | 125 | ||
112 | static void kdf_dealloc(struct kdf_sdesc *sdesc) | 126 | static void kdf_dealloc(struct kdf_sdesc *sdesc) |
@@ -120,14 +134,6 @@ static void kdf_dealloc(struct kdf_sdesc *sdesc) | |||
120 | kzfree(sdesc); | 134 | kzfree(sdesc); |
121 | } | 135 | } |
122 | 136 | ||
123 | /* convert 32 bit integer into its string representation */ | ||
124 | static inline void crypto_kw_cpu_to_be32(u32 val, u8 *buf) | ||
125 | { | ||
126 | __be32 *a = (__be32 *)buf; | ||
127 | |||
128 | *a = cpu_to_be32(val); | ||
129 | } | ||
130 | |||
131 | /* | 137 | /* |
132 | * Implementation of the KDF in counter mode according to SP800-108 section 5.1 | 138 | * Implementation of the KDF in counter mode according to SP800-108 section 5.1 |
133 | * as well as SP800-56A section 5.8.1 (Single-step KDF). | 139 | * as well as SP800-56A section 5.8.1 (Single-step KDF). |
@@ -138,25 +144,39 @@ static inline void crypto_kw_cpu_to_be32(u32 val, u8 *buf) | |||
138 | * 5.8.1.2). | 144 | * 5.8.1.2). |
139 | */ | 145 | */ |
140 | static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen, | 146 | static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen, |
141 | u8 *dst, unsigned int dlen) | 147 | u8 *dst, unsigned int dlen, unsigned int zlen) |
142 | { | 148 | { |
143 | struct shash_desc *desc = &sdesc->shash; | 149 | struct shash_desc *desc = &sdesc->shash; |
144 | unsigned int h = crypto_shash_digestsize(desc->tfm); | 150 | unsigned int h = crypto_shash_digestsize(desc->tfm); |
145 | int err = 0; | 151 | int err = 0; |
146 | u8 *dst_orig = dst; | 152 | u8 *dst_orig = dst; |
147 | u32 i = 1; | 153 | __be32 counter = cpu_to_be32(1); |
148 | u8 iteration[sizeof(u32)]; | ||
149 | 154 | ||
150 | while (dlen) { | 155 | while (dlen) { |
151 | err = crypto_shash_init(desc); | 156 | err = crypto_shash_init(desc); |
152 | if (err) | 157 | if (err) |
153 | goto err; | 158 | goto err; |
154 | 159 | ||
155 | crypto_kw_cpu_to_be32(i, iteration); | 160 | err = crypto_shash_update(desc, (u8 *)&counter, sizeof(__be32)); |
156 | err = crypto_shash_update(desc, iteration, sizeof(u32)); | ||
157 | if (err) | 161 | if (err) |
158 | goto err; | 162 | goto err; |
159 | 163 | ||
164 | if (zlen && h) { | ||
165 | u8 tmpbuffer[h]; | ||
166 | size_t chunk = min_t(size_t, zlen, h); | ||
167 | memset(tmpbuffer, 0, chunk); | ||
168 | |||
169 | do { | ||
170 | err = crypto_shash_update(desc, tmpbuffer, | ||
171 | chunk); | ||
172 | if (err) | ||
173 | goto err; | ||
174 | |||
175 | zlen -= chunk; | ||
176 | chunk = min_t(size_t, zlen, h); | ||
177 | } while (zlen); | ||
178 | } | ||
179 | |||
160 | if (src && slen) { | 180 | if (src && slen) { |
161 | err = crypto_shash_update(desc, src, slen); | 181 | err = crypto_shash_update(desc, src, slen); |
162 | if (err) | 182 | if (err) |
@@ -179,7 +199,7 @@ static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen, | |||
179 | 199 | ||
180 | dlen -= h; | 200 | dlen -= h; |
181 | dst += h; | 201 | dst += h; |
182 | i++; | 202 | counter = cpu_to_be32(be32_to_cpu(counter) + 1); |
183 | } | 203 | } |
184 | } | 204 | } |
185 | 205 | ||
@@ -192,7 +212,7 @@ err: | |||
192 | 212 | ||
193 | static int keyctl_dh_compute_kdf(struct kdf_sdesc *sdesc, | 213 | static int keyctl_dh_compute_kdf(struct kdf_sdesc *sdesc, |
194 | char __user *buffer, size_t buflen, | 214 | char __user *buffer, size_t buflen, |
195 | uint8_t *kbuf, size_t kbuflen) | 215 | uint8_t *kbuf, size_t kbuflen, size_t lzero) |
196 | { | 216 | { |
197 | uint8_t *outbuf = NULL; | 217 | uint8_t *outbuf = NULL; |
198 | int ret; | 218 | int ret; |
@@ -203,7 +223,7 @@ static int keyctl_dh_compute_kdf(struct kdf_sdesc *sdesc, | |||
203 | goto err; | 223 | goto err; |
204 | } | 224 | } |
205 | 225 | ||
206 | ret = kdf_ctr(sdesc, kbuf, kbuflen, outbuf, buflen); | 226 | ret = kdf_ctr(sdesc, kbuf, kbuflen, outbuf, buflen, lzero); |
207 | if (ret) | 227 | if (ret) |
208 | goto err; | 228 | goto err; |
209 | 229 | ||
@@ -221,21 +241,26 @@ long __keyctl_dh_compute(struct keyctl_dh_params __user *params, | |||
221 | struct keyctl_kdf_params *kdfcopy) | 241 | struct keyctl_kdf_params *kdfcopy) |
222 | { | 242 | { |
223 | long ret; | 243 | long ret; |
224 | MPI base, private, prime, result; | 244 | ssize_t dlen; |
225 | unsigned nbytes; | 245 | int secretlen; |
246 | int outlen; | ||
226 | struct keyctl_dh_params pcopy; | 247 | struct keyctl_dh_params pcopy; |
227 | uint8_t *kbuf; | 248 | struct dh dh_inputs; |
228 | ssize_t keylen; | 249 | struct scatterlist outsg; |
229 | size_t resultlen; | 250 | struct dh_completion compl; |
251 | struct crypto_kpp *tfm; | ||
252 | struct kpp_request *req; | ||
253 | uint8_t *secret; | ||
254 | uint8_t *outbuf; | ||
230 | struct kdf_sdesc *sdesc = NULL; | 255 | struct kdf_sdesc *sdesc = NULL; |
231 | 256 | ||
232 | if (!params || (!buffer && buflen)) { | 257 | if (!params || (!buffer && buflen)) { |
233 | ret = -EINVAL; | 258 | ret = -EINVAL; |
234 | goto out; | 259 | goto out1; |
235 | } | 260 | } |
236 | if (copy_from_user(&pcopy, params, sizeof(pcopy)) != 0) { | 261 | if (copy_from_user(&pcopy, params, sizeof(pcopy)) != 0) { |
237 | ret = -EFAULT; | 262 | ret = -EFAULT; |
238 | goto out; | 263 | goto out1; |
239 | } | 264 | } |
240 | 265 | ||
241 | if (kdfcopy) { | 266 | if (kdfcopy) { |
@@ -244,104 +269,147 @@ long __keyctl_dh_compute(struct keyctl_dh_params __user *params, | |||
244 | if (buflen > KEYCTL_KDF_MAX_OUTPUT_LEN || | 269 | if (buflen > KEYCTL_KDF_MAX_OUTPUT_LEN || |
245 | kdfcopy->otherinfolen > KEYCTL_KDF_MAX_OI_LEN) { | 270 | kdfcopy->otherinfolen > KEYCTL_KDF_MAX_OI_LEN) { |
246 | ret = -EMSGSIZE; | 271 | ret = -EMSGSIZE; |
247 | goto out; | 272 | goto out1; |
248 | } | 273 | } |
249 | 274 | ||
250 | /* get KDF name string */ | 275 | /* get KDF name string */ |
251 | hashname = strndup_user(kdfcopy->hashname, CRYPTO_MAX_ALG_NAME); | 276 | hashname = strndup_user(kdfcopy->hashname, CRYPTO_MAX_ALG_NAME); |
252 | if (IS_ERR(hashname)) { | 277 | if (IS_ERR(hashname)) { |
253 | ret = PTR_ERR(hashname); | 278 | ret = PTR_ERR(hashname); |
254 | goto out; | 279 | goto out1; |
255 | } | 280 | } |
256 | 281 | ||
257 | /* allocate KDF from the kernel crypto API */ | 282 | /* allocate KDF from the kernel crypto API */ |
258 | ret = kdf_alloc(&sdesc, hashname); | 283 | ret = kdf_alloc(&sdesc, hashname); |
259 | kfree(hashname); | 284 | kfree(hashname); |
260 | if (ret) | 285 | if (ret) |
261 | goto out; | 286 | goto out1; |
262 | } | 287 | } |
263 | 288 | ||
264 | /* | 289 | memset(&dh_inputs, 0, sizeof(dh_inputs)); |
265 | * If the caller requests postprocessing with a KDF, allow an | 290 | |
266 | * arbitrary output buffer size since the KDF ensures proper truncation. | 291 | dlen = dh_data_from_key(pcopy.prime, &dh_inputs.p); |
267 | */ | 292 | if (dlen < 0) { |
268 | keylen = mpi_from_key(pcopy.prime, kdfcopy ? SIZE_MAX : buflen, &prime); | 293 | ret = dlen; |
269 | if (keylen < 0 || !prime) { | 294 | goto out1; |
270 | /* buflen == 0 may be used to query the required buffer size, | 295 | } |
271 | * which is the prime key length. | 296 | dh_inputs.p_size = dlen; |
272 | */ | 297 | |
273 | ret = keylen; | 298 | dlen = dh_data_from_key(pcopy.base, &dh_inputs.g); |
274 | goto out; | 299 | if (dlen < 0) { |
300 | ret = dlen; | ||
301 | goto out2; | ||
275 | } | 302 | } |
303 | dh_inputs.g_size = dlen; | ||
276 | 304 | ||
277 | /* The result is never longer than the prime */ | 305 | dlen = dh_data_from_key(pcopy.private, &dh_inputs.key); |
278 | resultlen = keylen; | 306 | if (dlen < 0) { |
307 | ret = dlen; | ||
308 | goto out2; | ||
309 | } | ||
310 | dh_inputs.key_size = dlen; | ||
279 | 311 | ||
280 | keylen = mpi_from_key(pcopy.base, SIZE_MAX, &base); | 312 | secretlen = crypto_dh_key_len(&dh_inputs); |
281 | if (keylen < 0 || !base) { | 313 | secret = kmalloc(secretlen, GFP_KERNEL); |
282 | ret = keylen; | 314 | if (!secret) { |
283 | goto error1; | 315 | ret = -ENOMEM; |
316 | goto out2; | ||
284 | } | 317 | } |
318 | ret = crypto_dh_encode_key(secret, secretlen, &dh_inputs); | ||
319 | if (ret) | ||
320 | goto out3; | ||
285 | 321 | ||
286 | keylen = mpi_from_key(pcopy.private, SIZE_MAX, &private); | 322 | tfm = crypto_alloc_kpp("dh", CRYPTO_ALG_TYPE_KPP, 0); |
287 | if (keylen < 0 || !private) { | 323 | if (IS_ERR(tfm)) { |
288 | ret = keylen; | 324 | ret = PTR_ERR(tfm); |
289 | goto error2; | 325 | goto out3; |
326 | } | ||
327 | |||
328 | ret = crypto_kpp_set_secret(tfm, secret, secretlen); | ||
329 | if (ret) | ||
330 | goto out4; | ||
331 | |||
332 | outlen = crypto_kpp_maxsize(tfm); | ||
333 | |||
334 | if (!kdfcopy) { | ||
335 | /* | ||
336 | * When not using a KDF, buflen 0 is used to read the | ||
337 | * required buffer length | ||
338 | */ | ||
339 | if (buflen == 0) { | ||
340 | ret = outlen; | ||
341 | goto out4; | ||
342 | } else if (outlen > buflen) { | ||
343 | ret = -EOVERFLOW; | ||
344 | goto out4; | ||
345 | } | ||
290 | } | 346 | } |
291 | 347 | ||
292 | result = mpi_alloc(0); | 348 | outbuf = kzalloc(kdfcopy ? (outlen + kdfcopy->otherinfolen) : outlen, |
293 | if (!result) { | 349 | GFP_KERNEL); |
350 | if (!outbuf) { | ||
294 | ret = -ENOMEM; | 351 | ret = -ENOMEM; |
295 | goto error3; | 352 | goto out4; |
296 | } | 353 | } |
297 | 354 | ||
298 | /* allocate space for DH shared secret and SP800-56A otherinfo */ | 355 | sg_init_one(&outsg, outbuf, outlen); |
299 | kbuf = kmalloc(kdfcopy ? (resultlen + kdfcopy->otherinfolen) : resultlen, | 356 | |
300 | GFP_KERNEL); | 357 | req = kpp_request_alloc(tfm, GFP_KERNEL); |
301 | if (!kbuf) { | 358 | if (!req) { |
302 | ret = -ENOMEM; | 359 | ret = -ENOMEM; |
303 | goto error4; | 360 | goto out5; |
304 | } | 361 | } |
305 | 362 | ||
363 | kpp_request_set_input(req, NULL, 0); | ||
364 | kpp_request_set_output(req, &outsg, outlen); | ||
365 | init_completion(&compl.completion); | ||
366 | kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | | ||
367 | CRYPTO_TFM_REQ_MAY_SLEEP, | ||
368 | dh_crypto_done, &compl); | ||
369 | |||
306 | /* | 370 | /* |
307 | * Concatenate SP800-56A otherinfo past DH shared secret -- the | 371 | * For DH, generate_public_key and generate_shared_secret are |
308 | * input to the KDF is (DH shared secret || otherinfo) | 372 | * the same calculation |
309 | */ | 373 | */ |
310 | if (kdfcopy && kdfcopy->otherinfo && | 374 | ret = crypto_kpp_generate_public_key(req); |
311 | copy_from_user(kbuf + resultlen, kdfcopy->otherinfo, | 375 | if (ret == -EINPROGRESS) { |
312 | kdfcopy->otherinfolen) != 0) { | 376 | wait_for_completion(&compl.completion); |
313 | ret = -EFAULT; | 377 | ret = compl.err; |
314 | goto error5; | 378 | if (ret) |
379 | goto out6; | ||
315 | } | 380 | } |
316 | 381 | ||
317 | ret = do_dh(result, base, private, prime); | ||
318 | if (ret) | ||
319 | goto error5; | ||
320 | |||
321 | ret = mpi_read_buffer(result, kbuf, resultlen, &nbytes, NULL); | ||
322 | if (ret != 0) | ||
323 | goto error5; | ||
324 | |||
325 | if (kdfcopy) { | 382 | if (kdfcopy) { |
326 | ret = keyctl_dh_compute_kdf(sdesc, buffer, buflen, kbuf, | 383 | /* |
327 | resultlen + kdfcopy->otherinfolen); | 384 | * Concatenate SP800-56A otherinfo past DH shared secret -- the |
328 | } else { | 385 | * input to the KDF is (DH shared secret || otherinfo) |
329 | ret = nbytes; | 386 | */ |
330 | if (copy_to_user(buffer, kbuf, nbytes) != 0) | 387 | if (copy_from_user(outbuf + req->dst_len, kdfcopy->otherinfo, |
388 | kdfcopy->otherinfolen) != 0) { | ||
331 | ret = -EFAULT; | 389 | ret = -EFAULT; |
390 | goto out6; | ||
391 | } | ||
392 | |||
393 | ret = keyctl_dh_compute_kdf(sdesc, buffer, buflen, outbuf, | ||
394 | req->dst_len + kdfcopy->otherinfolen, | ||
395 | outlen - req->dst_len); | ||
396 | } else if (copy_to_user(buffer, outbuf, req->dst_len) == 0) { | ||
397 | ret = req->dst_len; | ||
398 | } else { | ||
399 | ret = -EFAULT; | ||
332 | } | 400 | } |
333 | 401 | ||
334 | error5: | 402 | out6: |
335 | kzfree(kbuf); | 403 | kpp_request_free(req); |
336 | error4: | 404 | out5: |
337 | mpi_free(result); | 405 | kzfree(outbuf); |
338 | error3: | 406 | out4: |
339 | mpi_free(private); | 407 | crypto_free_kpp(tfm); |
340 | error2: | 408 | out3: |
341 | mpi_free(base); | 409 | kzfree(secret); |
342 | error1: | 410 | out2: |
343 | mpi_free(prime); | 411 | dh_free_data(&dh_inputs); |
344 | out: | 412 | out1: |
345 | kdf_dealloc(sdesc); | 413 | kdf_dealloc(sdesc); |
346 | return ret; | 414 | return ret; |
347 | } | 415 | } |
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c index 0010955d7876..bb6324d1ccec 100644 --- a/security/keys/encrypted-keys/encrypted.c +++ b/security/keys/encrypted-keys/encrypted.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/scatterlist.h> | 30 | #include <linux/scatterlist.h> |
31 | #include <linux/ctype.h> | 31 | #include <linux/ctype.h> |
32 | #include <crypto/aes.h> | 32 | #include <crypto/aes.h> |
33 | #include <crypto/algapi.h> | ||
33 | #include <crypto/hash.h> | 34 | #include <crypto/hash.h> |
34 | #include <crypto/sha.h> | 35 | #include <crypto/sha.h> |
35 | #include <crypto/skcipher.h> | 36 | #include <crypto/skcipher.h> |
@@ -54,13 +55,7 @@ static int blksize; | |||
54 | #define MAX_DATA_SIZE 4096 | 55 | #define MAX_DATA_SIZE 4096 |
55 | #define MIN_DATA_SIZE 20 | 56 | #define MIN_DATA_SIZE 20 |
56 | 57 | ||
57 | struct sdesc { | 58 | static struct crypto_shash *hash_tfm; |
58 | struct shash_desc shash; | ||
59 | char ctx[]; | ||
60 | }; | ||
61 | |||
62 | static struct crypto_shash *hashalg; | ||
63 | static struct crypto_shash *hmacalg; | ||
64 | 59 | ||
65 | enum { | 60 | enum { |
66 | Opt_err = -1, Opt_new, Opt_load, Opt_update | 61 | Opt_err = -1, Opt_new, Opt_load, Opt_update |
@@ -141,23 +136,22 @@ static int valid_ecryptfs_desc(const char *ecryptfs_desc) | |||
141 | */ | 136 | */ |
142 | static int valid_master_desc(const char *new_desc, const char *orig_desc) | 137 | static int valid_master_desc(const char *new_desc, const char *orig_desc) |
143 | { | 138 | { |
144 | if (!memcmp(new_desc, KEY_TRUSTED_PREFIX, KEY_TRUSTED_PREFIX_LEN)) { | 139 | int prefix_len; |
145 | if (strlen(new_desc) == KEY_TRUSTED_PREFIX_LEN) | 140 | |
146 | goto out; | 141 | if (!strncmp(new_desc, KEY_TRUSTED_PREFIX, KEY_TRUSTED_PREFIX_LEN)) |
147 | if (orig_desc) | 142 | prefix_len = KEY_TRUSTED_PREFIX_LEN; |
148 | if (memcmp(new_desc, orig_desc, KEY_TRUSTED_PREFIX_LEN)) | 143 | else if (!strncmp(new_desc, KEY_USER_PREFIX, KEY_USER_PREFIX_LEN)) |
149 | goto out; | 144 | prefix_len = KEY_USER_PREFIX_LEN; |
150 | } else if (!memcmp(new_desc, KEY_USER_PREFIX, KEY_USER_PREFIX_LEN)) { | 145 | else |
151 | if (strlen(new_desc) == KEY_USER_PREFIX_LEN) | 146 | return -EINVAL; |
152 | goto out; | 147 | |
153 | if (orig_desc) | 148 | if (!new_desc[prefix_len]) |
154 | if (memcmp(new_desc, orig_desc, KEY_USER_PREFIX_LEN)) | 149 | return -EINVAL; |
155 | goto out; | 150 | |
156 | } else | 151 | if (orig_desc && strncmp(new_desc, orig_desc, prefix_len)) |
157 | goto out; | 152 | return -EINVAL; |
153 | |||
158 | return 0; | 154 | return 0; |
159 | out: | ||
160 | return -EINVAL; | ||
161 | } | 155 | } |
162 | 156 | ||
163 | /* | 157 | /* |
@@ -321,53 +315,38 @@ error: | |||
321 | return ukey; | 315 | return ukey; |
322 | } | 316 | } |
323 | 317 | ||
324 | static struct sdesc *alloc_sdesc(struct crypto_shash *alg) | 318 | static int calc_hash(struct crypto_shash *tfm, u8 *digest, |
325 | { | ||
326 | struct sdesc *sdesc; | ||
327 | int size; | ||
328 | |||
329 | size = sizeof(struct shash_desc) + crypto_shash_descsize(alg); | ||
330 | sdesc = kmalloc(size, GFP_KERNEL); | ||
331 | if (!sdesc) | ||
332 | return ERR_PTR(-ENOMEM); | ||
333 | sdesc->shash.tfm = alg; | ||
334 | sdesc->shash.flags = 0x0; | ||
335 | return sdesc; | ||
336 | } | ||
337 | |||
338 | static int calc_hmac(u8 *digest, const u8 *key, unsigned int keylen, | ||
339 | const u8 *buf, unsigned int buflen) | 319 | const u8 *buf, unsigned int buflen) |
340 | { | 320 | { |
341 | struct sdesc *sdesc; | 321 | SHASH_DESC_ON_STACK(desc, tfm); |
342 | int ret; | 322 | int err; |
343 | 323 | ||
344 | sdesc = alloc_sdesc(hmacalg); | 324 | desc->tfm = tfm; |
345 | if (IS_ERR(sdesc)) { | 325 | desc->flags = 0; |
346 | pr_info("encrypted_key: can't alloc %s\n", hmac_alg); | ||
347 | return PTR_ERR(sdesc); | ||
348 | } | ||
349 | 326 | ||
350 | ret = crypto_shash_setkey(hmacalg, key, keylen); | 327 | err = crypto_shash_digest(desc, buf, buflen, digest); |
351 | if (!ret) | 328 | shash_desc_zero(desc); |
352 | ret = crypto_shash_digest(&sdesc->shash, buf, buflen, digest); | 329 | return err; |
353 | kfree(sdesc); | ||
354 | return ret; | ||
355 | } | 330 | } |
356 | 331 | ||
357 | static int calc_hash(u8 *digest, const u8 *buf, unsigned int buflen) | 332 | static int calc_hmac(u8 *digest, const u8 *key, unsigned int keylen, |
333 | const u8 *buf, unsigned int buflen) | ||
358 | { | 334 | { |
359 | struct sdesc *sdesc; | 335 | struct crypto_shash *tfm; |
360 | int ret; | 336 | int err; |
361 | 337 | ||
362 | sdesc = alloc_sdesc(hashalg); | 338 | tfm = crypto_alloc_shash(hmac_alg, 0, CRYPTO_ALG_ASYNC); |
363 | if (IS_ERR(sdesc)) { | 339 | if (IS_ERR(tfm)) { |
364 | pr_info("encrypted_key: can't alloc %s\n", hash_alg); | 340 | pr_err("encrypted_key: can't alloc %s transform: %ld\n", |
365 | return PTR_ERR(sdesc); | 341 | hmac_alg, PTR_ERR(tfm)); |
342 | return PTR_ERR(tfm); | ||
366 | } | 343 | } |
367 | 344 | ||
368 | ret = crypto_shash_digest(&sdesc->shash, buf, buflen, digest); | 345 | err = crypto_shash_setkey(tfm, key, keylen); |
369 | kfree(sdesc); | 346 | if (!err) |
370 | return ret; | 347 | err = calc_hash(tfm, digest, buf, buflen); |
348 | crypto_free_shash(tfm); | ||
349 | return err; | ||
371 | } | 350 | } |
372 | 351 | ||
373 | enum derived_key_type { ENC_KEY, AUTH_KEY }; | 352 | enum derived_key_type { ENC_KEY, AUTH_KEY }; |
@@ -385,10 +364,9 @@ static int get_derived_key(u8 *derived_key, enum derived_key_type key_type, | |||
385 | derived_buf_len = HASH_SIZE; | 364 | derived_buf_len = HASH_SIZE; |
386 | 365 | ||
387 | derived_buf = kzalloc(derived_buf_len, GFP_KERNEL); | 366 | derived_buf = kzalloc(derived_buf_len, GFP_KERNEL); |
388 | if (!derived_buf) { | 367 | if (!derived_buf) |
389 | pr_err("encrypted_key: out of memory\n"); | ||
390 | return -ENOMEM; | 368 | return -ENOMEM; |
391 | } | 369 | |
392 | if (key_type) | 370 | if (key_type) |
393 | strcpy(derived_buf, "AUTH_KEY"); | 371 | strcpy(derived_buf, "AUTH_KEY"); |
394 | else | 372 | else |
@@ -396,8 +374,8 @@ static int get_derived_key(u8 *derived_key, enum derived_key_type key_type, | |||
396 | 374 | ||
397 | memcpy(derived_buf + strlen(derived_buf) + 1, master_key, | 375 | memcpy(derived_buf + strlen(derived_buf) + 1, master_key, |
398 | master_keylen); | 376 | master_keylen); |
399 | ret = calc_hash(derived_key, derived_buf, derived_buf_len); | 377 | ret = calc_hash(hash_tfm, derived_key, derived_buf, derived_buf_len); |
400 | kfree(derived_buf); | 378 | kzfree(derived_buf); |
401 | return ret; | 379 | return ret; |
402 | } | 380 | } |
403 | 381 | ||
@@ -480,12 +458,9 @@ static int derived_key_encrypt(struct encrypted_key_payload *epayload, | |||
480 | struct skcipher_request *req; | 458 | struct skcipher_request *req; |
481 | unsigned int encrypted_datalen; | 459 | unsigned int encrypted_datalen; |
482 | u8 iv[AES_BLOCK_SIZE]; | 460 | u8 iv[AES_BLOCK_SIZE]; |
483 | unsigned int padlen; | ||
484 | char pad[16]; | ||
485 | int ret; | 461 | int ret; |
486 | 462 | ||
487 | encrypted_datalen = roundup(epayload->decrypted_datalen, blksize); | 463 | encrypted_datalen = roundup(epayload->decrypted_datalen, blksize); |
488 | padlen = encrypted_datalen - epayload->decrypted_datalen; | ||
489 | 464 | ||
490 | req = init_skcipher_req(derived_key, derived_keylen); | 465 | req = init_skcipher_req(derived_key, derived_keylen); |
491 | ret = PTR_ERR(req); | 466 | ret = PTR_ERR(req); |
@@ -493,11 +468,10 @@ static int derived_key_encrypt(struct encrypted_key_payload *epayload, | |||
493 | goto out; | 468 | goto out; |
494 | dump_decrypted_data(epayload); | 469 | dump_decrypted_data(epayload); |
495 | 470 | ||
496 | memset(pad, 0, sizeof pad); | ||
497 | sg_init_table(sg_in, 2); | 471 | sg_init_table(sg_in, 2); |
498 | sg_set_buf(&sg_in[0], epayload->decrypted_data, | 472 | sg_set_buf(&sg_in[0], epayload->decrypted_data, |
499 | epayload->decrypted_datalen); | 473 | epayload->decrypted_datalen); |
500 | sg_set_buf(&sg_in[1], pad, padlen); | 474 | sg_set_page(&sg_in[1], ZERO_PAGE(0), AES_BLOCK_SIZE, 0); |
501 | 475 | ||
502 | sg_init_table(sg_out, 1); | 476 | sg_init_table(sg_out, 1); |
503 | sg_set_buf(sg_out, epayload->encrypted_data, encrypted_datalen); | 477 | sg_set_buf(sg_out, epayload->encrypted_data, encrypted_datalen); |
@@ -533,6 +507,7 @@ static int datablob_hmac_append(struct encrypted_key_payload *epayload, | |||
533 | if (!ret) | 507 | if (!ret) |
534 | dump_hmac(NULL, digest, HASH_SIZE); | 508 | dump_hmac(NULL, digest, HASH_SIZE); |
535 | out: | 509 | out: |
510 | memzero_explicit(derived_key, sizeof(derived_key)); | ||
536 | return ret; | 511 | return ret; |
537 | } | 512 | } |
538 | 513 | ||
@@ -561,8 +536,8 @@ static int datablob_hmac_verify(struct encrypted_key_payload *epayload, | |||
561 | ret = calc_hmac(digest, derived_key, sizeof derived_key, p, len); | 536 | ret = calc_hmac(digest, derived_key, sizeof derived_key, p, len); |
562 | if (ret < 0) | 537 | if (ret < 0) |
563 | goto out; | 538 | goto out; |
564 | ret = memcmp(digest, epayload->format + epayload->datablob_len, | 539 | ret = crypto_memneq(digest, epayload->format + epayload->datablob_len, |
565 | sizeof digest); | 540 | sizeof(digest)); |
566 | if (ret) { | 541 | if (ret) { |
567 | ret = -EINVAL; | 542 | ret = -EINVAL; |
568 | dump_hmac("datablob", | 543 | dump_hmac("datablob", |
@@ -571,6 +546,7 @@ static int datablob_hmac_verify(struct encrypted_key_payload *epayload, | |||
571 | dump_hmac("calc", digest, HASH_SIZE); | 546 | dump_hmac("calc", digest, HASH_SIZE); |
572 | } | 547 | } |
573 | out: | 548 | out: |
549 | memzero_explicit(derived_key, sizeof(derived_key)); | ||
574 | return ret; | 550 | return ret; |
575 | } | 551 | } |
576 | 552 | ||
@@ -584,9 +560,14 @@ static int derived_key_decrypt(struct encrypted_key_payload *epayload, | |||
584 | struct skcipher_request *req; | 560 | struct skcipher_request *req; |
585 | unsigned int encrypted_datalen; | 561 | unsigned int encrypted_datalen; |
586 | u8 iv[AES_BLOCK_SIZE]; | 562 | u8 iv[AES_BLOCK_SIZE]; |
587 | char pad[16]; | 563 | u8 *pad; |
588 | int ret; | 564 | int ret; |
589 | 565 | ||
566 | /* Throwaway buffer to hold the unused zero padding at the end */ | ||
567 | pad = kmalloc(AES_BLOCK_SIZE, GFP_KERNEL); | ||
568 | if (!pad) | ||
569 | return -ENOMEM; | ||
570 | |||
590 | encrypted_datalen = roundup(epayload->decrypted_datalen, blksize); | 571 | encrypted_datalen = roundup(epayload->decrypted_datalen, blksize); |
591 | req = init_skcipher_req(derived_key, derived_keylen); | 572 | req = init_skcipher_req(derived_key, derived_keylen); |
592 | ret = PTR_ERR(req); | 573 | ret = PTR_ERR(req); |
@@ -594,13 +575,12 @@ static int derived_key_decrypt(struct encrypted_key_payload *epayload, | |||
594 | goto out; | 575 | goto out; |
595 | dump_encrypted_data(epayload, encrypted_datalen); | 576 | dump_encrypted_data(epayload, encrypted_datalen); |
596 | 577 | ||
597 | memset(pad, 0, sizeof pad); | ||
598 | sg_init_table(sg_in, 1); | 578 | sg_init_table(sg_in, 1); |
599 | sg_init_table(sg_out, 2); | 579 | sg_init_table(sg_out, 2); |
600 | sg_set_buf(sg_in, epayload->encrypted_data, encrypted_datalen); | 580 | sg_set_buf(sg_in, epayload->encrypted_data, encrypted_datalen); |
601 | sg_set_buf(&sg_out[0], epayload->decrypted_data, | 581 | sg_set_buf(&sg_out[0], epayload->decrypted_data, |
602 | epayload->decrypted_datalen); | 582 | epayload->decrypted_datalen); |
603 | sg_set_buf(&sg_out[1], pad, sizeof pad); | 583 | sg_set_buf(&sg_out[1], pad, AES_BLOCK_SIZE); |
604 | 584 | ||
605 | memcpy(iv, epayload->iv, sizeof(iv)); | 585 | memcpy(iv, epayload->iv, sizeof(iv)); |
606 | skcipher_request_set_crypt(req, sg_in, sg_out, encrypted_datalen, iv); | 586 | skcipher_request_set_crypt(req, sg_in, sg_out, encrypted_datalen, iv); |
@@ -612,6 +592,7 @@ static int derived_key_decrypt(struct encrypted_key_payload *epayload, | |||
612 | goto out; | 592 | goto out; |
613 | dump_decrypted_data(epayload); | 593 | dump_decrypted_data(epayload); |
614 | out: | 594 | out: |
595 | kfree(pad); | ||
615 | return ret; | 596 | return ret; |
616 | } | 597 | } |
617 | 598 | ||
@@ -722,6 +703,7 @@ static int encrypted_key_decrypt(struct encrypted_key_payload *epayload, | |||
722 | out: | 703 | out: |
723 | up_read(&mkey->sem); | 704 | up_read(&mkey->sem); |
724 | key_put(mkey); | 705 | key_put(mkey); |
706 | memzero_explicit(derived_key, sizeof(derived_key)); | ||
725 | return ret; | 707 | return ret; |
726 | } | 708 | } |
727 | 709 | ||
@@ -828,13 +810,13 @@ static int encrypted_instantiate(struct key *key, | |||
828 | ret = encrypted_init(epayload, key->description, format, master_desc, | 810 | ret = encrypted_init(epayload, key->description, format, master_desc, |
829 | decrypted_datalen, hex_encoded_iv); | 811 | decrypted_datalen, hex_encoded_iv); |
830 | if (ret < 0) { | 812 | if (ret < 0) { |
831 | kfree(epayload); | 813 | kzfree(epayload); |
832 | goto out; | 814 | goto out; |
833 | } | 815 | } |
834 | 816 | ||
835 | rcu_assign_keypointer(key, epayload); | 817 | rcu_assign_keypointer(key, epayload); |
836 | out: | 818 | out: |
837 | kfree(datablob); | 819 | kzfree(datablob); |
838 | return ret; | 820 | return ret; |
839 | } | 821 | } |
840 | 822 | ||
@@ -843,8 +825,7 @@ static void encrypted_rcu_free(struct rcu_head *rcu) | |||
843 | struct encrypted_key_payload *epayload; | 825 | struct encrypted_key_payload *epayload; |
844 | 826 | ||
845 | epayload = container_of(rcu, struct encrypted_key_payload, rcu); | 827 | epayload = container_of(rcu, struct encrypted_key_payload, rcu); |
846 | memset(epayload->decrypted_data, 0, epayload->decrypted_datalen); | 828 | kzfree(epayload); |
847 | kfree(epayload); | ||
848 | } | 829 | } |
849 | 830 | ||
850 | /* | 831 | /* |
@@ -902,7 +883,7 @@ static int encrypted_update(struct key *key, struct key_preparsed_payload *prep) | |||
902 | rcu_assign_keypointer(key, new_epayload); | 883 | rcu_assign_keypointer(key, new_epayload); |
903 | call_rcu(&epayload->rcu, encrypted_rcu_free); | 884 | call_rcu(&epayload->rcu, encrypted_rcu_free); |
904 | out: | 885 | out: |
905 | kfree(buf); | 886 | kzfree(buf); |
906 | return ret; | 887 | return ret; |
907 | } | 888 | } |
908 | 889 | ||
@@ -960,33 +941,26 @@ static long encrypted_read(const struct key *key, char __user *buffer, | |||
960 | 941 | ||
961 | up_read(&mkey->sem); | 942 | up_read(&mkey->sem); |
962 | key_put(mkey); | 943 | key_put(mkey); |
944 | memzero_explicit(derived_key, sizeof(derived_key)); | ||
963 | 945 | ||
964 | if (copy_to_user(buffer, ascii_buf, asciiblob_len) != 0) | 946 | if (copy_to_user(buffer, ascii_buf, asciiblob_len) != 0) |
965 | ret = -EFAULT; | 947 | ret = -EFAULT; |
966 | kfree(ascii_buf); | 948 | kzfree(ascii_buf); |
967 | 949 | ||
968 | return asciiblob_len; | 950 | return asciiblob_len; |
969 | out: | 951 | out: |
970 | up_read(&mkey->sem); | 952 | up_read(&mkey->sem); |
971 | key_put(mkey); | 953 | key_put(mkey); |
954 | memzero_explicit(derived_key, sizeof(derived_key)); | ||
972 | return ret; | 955 | return ret; |
973 | } | 956 | } |
974 | 957 | ||
975 | /* | 958 | /* |
976 | * encrypted_destroy - before freeing the key, clear the decrypted data | 959 | * encrypted_destroy - clear and free the key's payload |
977 | * | ||
978 | * Before freeing the key, clear the memory containing the decrypted | ||
979 | * key data. | ||
980 | */ | 960 | */ |
981 | static void encrypted_destroy(struct key *key) | 961 | static void encrypted_destroy(struct key *key) |
982 | { | 962 | { |
983 | struct encrypted_key_payload *epayload = key->payload.data[0]; | 963 | kzfree(key->payload.data[0]); |
984 | |||
985 | if (!epayload) | ||
986 | return; | ||
987 | |||
988 | memzero_explicit(epayload->decrypted_data, epayload->decrypted_datalen); | ||
989 | kfree(key->payload.data[0]); | ||
990 | } | 964 | } |
991 | 965 | ||
992 | struct key_type key_type_encrypted = { | 966 | struct key_type key_type_encrypted = { |
@@ -999,47 +973,17 @@ struct key_type key_type_encrypted = { | |||
999 | }; | 973 | }; |
1000 | EXPORT_SYMBOL_GPL(key_type_encrypted); | 974 | EXPORT_SYMBOL_GPL(key_type_encrypted); |
1001 | 975 | ||
1002 | static void encrypted_shash_release(void) | 976 | static int __init init_encrypted(void) |
1003 | { | ||
1004 | if (hashalg) | ||
1005 | crypto_free_shash(hashalg); | ||
1006 | if (hmacalg) | ||
1007 | crypto_free_shash(hmacalg); | ||
1008 | } | ||
1009 | |||
1010 | static int __init encrypted_shash_alloc(void) | ||
1011 | { | 977 | { |
1012 | int ret; | 978 | int ret; |
1013 | 979 | ||
1014 | hmacalg = crypto_alloc_shash(hmac_alg, 0, CRYPTO_ALG_ASYNC); | 980 | hash_tfm = crypto_alloc_shash(hash_alg, 0, CRYPTO_ALG_ASYNC); |
1015 | if (IS_ERR(hmacalg)) { | 981 | if (IS_ERR(hash_tfm)) { |
1016 | pr_info("encrypted_key: could not allocate crypto %s\n", | 982 | pr_err("encrypted_key: can't allocate %s transform: %ld\n", |
1017 | hmac_alg); | 983 | hash_alg, PTR_ERR(hash_tfm)); |
1018 | return PTR_ERR(hmacalg); | 984 | return PTR_ERR(hash_tfm); |
1019 | } | ||
1020 | |||
1021 | hashalg = crypto_alloc_shash(hash_alg, 0, CRYPTO_ALG_ASYNC); | ||
1022 | if (IS_ERR(hashalg)) { | ||
1023 | pr_info("encrypted_key: could not allocate crypto %s\n", | ||
1024 | hash_alg); | ||
1025 | ret = PTR_ERR(hashalg); | ||
1026 | goto hashalg_fail; | ||
1027 | } | 985 | } |
1028 | 986 | ||
1029 | return 0; | ||
1030 | |||
1031 | hashalg_fail: | ||
1032 | crypto_free_shash(hmacalg); | ||
1033 | return ret; | ||
1034 | } | ||
1035 | |||
1036 | static int __init init_encrypted(void) | ||
1037 | { | ||
1038 | int ret; | ||
1039 | |||
1040 | ret = encrypted_shash_alloc(); | ||
1041 | if (ret < 0) | ||
1042 | return ret; | ||
1043 | ret = aes_get_sizes(); | 987 | ret = aes_get_sizes(); |
1044 | if (ret < 0) | 988 | if (ret < 0) |
1045 | goto out; | 989 | goto out; |
@@ -1048,14 +992,14 @@ static int __init init_encrypted(void) | |||
1048 | goto out; | 992 | goto out; |
1049 | return 0; | 993 | return 0; |
1050 | out: | 994 | out: |
1051 | encrypted_shash_release(); | 995 | crypto_free_shash(hash_tfm); |
1052 | return ret; | 996 | return ret; |
1053 | 997 | ||
1054 | } | 998 | } |
1055 | 999 | ||
1056 | static void __exit cleanup_encrypted(void) | 1000 | static void __exit cleanup_encrypted(void) |
1057 | { | 1001 | { |
1058 | encrypted_shash_release(); | 1002 | crypto_free_shash(hash_tfm); |
1059 | unregister_key_type(&key_type_encrypted); | 1003 | unregister_key_type(&key_type_encrypted); |
1060 | } | 1004 | } |
1061 | 1005 | ||
diff --git a/security/keys/gc.c b/security/keys/gc.c index 595becc6d0d2..87cb260e4890 100644 --- a/security/keys/gc.c +++ b/security/keys/gc.c | |||
@@ -158,9 +158,7 @@ static noinline void key_gc_unused_keys(struct list_head *keys) | |||
158 | 158 | ||
159 | kfree(key->description); | 159 | kfree(key->description); |
160 | 160 | ||
161 | #ifdef KEY_DEBUGGING | 161 | memzero_explicit(key, sizeof(*key)); |
162 | key->magic = KEY_DEBUG_MAGIC_X; | ||
163 | #endif | ||
164 | kmem_cache_free(key_jar, key); | 162 | kmem_cache_free(key_jar, key); |
165 | } | 163 | } |
166 | } | 164 | } |
diff --git a/security/keys/key.c b/security/keys/key.c index 455c04d80bbb..83da68d98b40 100644 --- a/security/keys/key.c +++ b/security/keys/key.c | |||
@@ -660,14 +660,11 @@ not_found: | |||
660 | goto error; | 660 | goto error; |
661 | 661 | ||
662 | found: | 662 | found: |
663 | /* pretend it doesn't exist if it is awaiting deletion */ | 663 | /* A key is allowed to be looked up only if someone still owns a |
664 | if (refcount_read(&key->usage) == 0) | 664 | * reference to it - otherwise it's awaiting the gc. |
665 | goto not_found; | ||
666 | |||
667 | /* this races with key_put(), but that doesn't matter since key_put() | ||
668 | * doesn't actually change the key | ||
669 | */ | 665 | */ |
670 | __key_get(key); | 666 | if (!refcount_inc_not_zero(&key->usage)) |
667 | goto not_found; | ||
671 | 668 | ||
672 | error: | 669 | error: |
673 | spin_unlock(&key_serial_lock); | 670 | spin_unlock(&key_serial_lock); |
@@ -966,12 +963,11 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen) | |||
966 | /* the key must be writable */ | 963 | /* the key must be writable */ |
967 | ret = key_permission(key_ref, KEY_NEED_WRITE); | 964 | ret = key_permission(key_ref, KEY_NEED_WRITE); |
968 | if (ret < 0) | 965 | if (ret < 0) |
969 | goto error; | 966 | return ret; |
970 | 967 | ||
971 | /* attempt to update it if supported */ | 968 | /* attempt to update it if supported */ |
972 | ret = -EOPNOTSUPP; | ||
973 | if (!key->type->update) | 969 | if (!key->type->update) |
974 | goto error; | 970 | return -EOPNOTSUPP; |
975 | 971 | ||
976 | memset(&prep, 0, sizeof(prep)); | 972 | memset(&prep, 0, sizeof(prep)); |
977 | prep.data = payload; | 973 | prep.data = payload; |
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 447a7d5cee0f..ab0b337c84b4 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -99,7 +99,7 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type, | |||
99 | /* pull the payload in if one was supplied */ | 99 | /* pull the payload in if one was supplied */ |
100 | payload = NULL; | 100 | payload = NULL; |
101 | 101 | ||
102 | if (_payload) { | 102 | if (plen) { |
103 | ret = -ENOMEM; | 103 | ret = -ENOMEM; |
104 | payload = kvmalloc(plen, GFP_KERNEL); | 104 | payload = kvmalloc(plen, GFP_KERNEL); |
105 | if (!payload) | 105 | if (!payload) |
@@ -132,7 +132,10 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type, | |||
132 | 132 | ||
133 | key_ref_put(keyring_ref); | 133 | key_ref_put(keyring_ref); |
134 | error3: | 134 | error3: |
135 | kvfree(payload); | 135 | if (payload) { |
136 | memzero_explicit(payload, plen); | ||
137 | kvfree(payload); | ||
138 | } | ||
136 | error2: | 139 | error2: |
137 | kfree(description); | 140 | kfree(description); |
138 | error: | 141 | error: |
@@ -324,7 +327,7 @@ long keyctl_update_key(key_serial_t id, | |||
324 | 327 | ||
325 | /* pull the payload in if one was supplied */ | 328 | /* pull the payload in if one was supplied */ |
326 | payload = NULL; | 329 | payload = NULL; |
327 | if (_payload) { | 330 | if (plen) { |
328 | ret = -ENOMEM; | 331 | ret = -ENOMEM; |
329 | payload = kmalloc(plen, GFP_KERNEL); | 332 | payload = kmalloc(plen, GFP_KERNEL); |
330 | if (!payload) | 333 | if (!payload) |
@@ -347,7 +350,7 @@ long keyctl_update_key(key_serial_t id, | |||
347 | 350 | ||
348 | key_ref_put(key_ref); | 351 | key_ref_put(key_ref); |
349 | error2: | 352 | error2: |
350 | kfree(payload); | 353 | kzfree(payload); |
351 | error: | 354 | error: |
352 | return ret; | 355 | return ret; |
353 | } | 356 | } |
@@ -1093,7 +1096,10 @@ long keyctl_instantiate_key_common(key_serial_t id, | |||
1093 | keyctl_change_reqkey_auth(NULL); | 1096 | keyctl_change_reqkey_auth(NULL); |
1094 | 1097 | ||
1095 | error2: | 1098 | error2: |
1096 | kvfree(payload); | 1099 | if (payload) { |
1100 | memzero_explicit(payload, plen); | ||
1101 | kvfree(payload); | ||
1102 | } | ||
1097 | error: | 1103 | error: |
1098 | return ret; | 1104 | return ret; |
1099 | } | 1105 | } |
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index 4d1678e4586f..de81793f9920 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
@@ -706,7 +706,7 @@ descend_to_keyring: | |||
706 | * Non-keyrings avoid the leftmost branch of the root entirely (root | 706 | * Non-keyrings avoid the leftmost branch of the root entirely (root |
707 | * slots 1-15). | 707 | * slots 1-15). |
708 | */ | 708 | */ |
709 | ptr = ACCESS_ONCE(keyring->keys.root); | 709 | ptr = READ_ONCE(keyring->keys.root); |
710 | if (!ptr) | 710 | if (!ptr) |
711 | goto not_this_keyring; | 711 | goto not_this_keyring; |
712 | 712 | ||
@@ -720,7 +720,7 @@ descend_to_keyring: | |||
720 | if ((shortcut->index_key[0] & ASSOC_ARRAY_FAN_MASK) != 0) | 720 | if ((shortcut->index_key[0] & ASSOC_ARRAY_FAN_MASK) != 0) |
721 | goto not_this_keyring; | 721 | goto not_this_keyring; |
722 | 722 | ||
723 | ptr = ACCESS_ONCE(shortcut->next_node); | 723 | ptr = READ_ONCE(shortcut->next_node); |
724 | node = assoc_array_ptr_to_node(ptr); | 724 | node = assoc_array_ptr_to_node(ptr); |
725 | goto begin_node; | 725 | goto begin_node; |
726 | } | 726 | } |
@@ -740,7 +740,7 @@ descend_to_node: | |||
740 | if (assoc_array_ptr_is_shortcut(ptr)) { | 740 | if (assoc_array_ptr_is_shortcut(ptr)) { |
741 | shortcut = assoc_array_ptr_to_shortcut(ptr); | 741 | shortcut = assoc_array_ptr_to_shortcut(ptr); |
742 | smp_read_barrier_depends(); | 742 | smp_read_barrier_depends(); |
743 | ptr = ACCESS_ONCE(shortcut->next_node); | 743 | ptr = READ_ONCE(shortcut->next_node); |
744 | BUG_ON(!assoc_array_ptr_is_node(ptr)); | 744 | BUG_ON(!assoc_array_ptr_is_node(ptr)); |
745 | } | 745 | } |
746 | node = assoc_array_ptr_to_node(ptr); | 746 | node = assoc_array_ptr_to_node(ptr); |
@@ -752,7 +752,7 @@ begin_node: | |||
752 | ascend_to_node: | 752 | ascend_to_node: |
753 | /* Go through the slots in a node */ | 753 | /* Go through the slots in a node */ |
754 | for (; slot < ASSOC_ARRAY_FAN_OUT; slot++) { | 754 | for (; slot < ASSOC_ARRAY_FAN_OUT; slot++) { |
755 | ptr = ACCESS_ONCE(node->slots[slot]); | 755 | ptr = READ_ONCE(node->slots[slot]); |
756 | 756 | ||
757 | if (assoc_array_ptr_is_meta(ptr) && node->back_pointer) | 757 | if (assoc_array_ptr_is_meta(ptr) && node->back_pointer) |
758 | goto descend_to_node; | 758 | goto descend_to_node; |
@@ -790,13 +790,13 @@ ascend_to_node: | |||
790 | /* We've dealt with all the slots in the current node, so now we need | 790 | /* We've dealt with all the slots in the current node, so now we need |
791 | * to ascend to the parent and continue processing there. | 791 | * to ascend to the parent and continue processing there. |
792 | */ | 792 | */ |
793 | ptr = ACCESS_ONCE(node->back_pointer); | 793 | ptr = READ_ONCE(node->back_pointer); |
794 | slot = node->parent_slot; | 794 | slot = node->parent_slot; |
795 | 795 | ||
796 | if (ptr && assoc_array_ptr_is_shortcut(ptr)) { | 796 | if (ptr && assoc_array_ptr_is_shortcut(ptr)) { |
797 | shortcut = assoc_array_ptr_to_shortcut(ptr); | 797 | shortcut = assoc_array_ptr_to_shortcut(ptr); |
798 | smp_read_barrier_depends(); | 798 | smp_read_barrier_depends(); |
799 | ptr = ACCESS_ONCE(shortcut->back_pointer); | 799 | ptr = READ_ONCE(shortcut->back_pointer); |
800 | slot = shortcut->parent_slot; | 800 | slot = shortcut->parent_slot; |
801 | } | 801 | } |
802 | if (!ptr) | 802 | if (!ptr) |
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 2217dfec7996..86bced9fdbdf 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c | |||
@@ -809,15 +809,14 @@ long join_session_keyring(const char *name) | |||
809 | ret = PTR_ERR(keyring); | 809 | ret = PTR_ERR(keyring); |
810 | goto error2; | 810 | goto error2; |
811 | } else if (keyring == new->session_keyring) { | 811 | } else if (keyring == new->session_keyring) { |
812 | key_put(keyring); | ||
813 | ret = 0; | 812 | ret = 0; |
814 | goto error2; | 813 | goto error3; |
815 | } | 814 | } |
816 | 815 | ||
817 | /* we've got a keyring - now to install it */ | 816 | /* we've got a keyring - now to install it */ |
818 | ret = install_session_keyring_to_cred(new, keyring); | 817 | ret = install_session_keyring_to_cred(new, keyring); |
819 | if (ret < 0) | 818 | if (ret < 0) |
820 | goto error2; | 819 | goto error3; |
821 | 820 | ||
822 | commit_creds(new); | 821 | commit_creds(new); |
823 | mutex_unlock(&key_session_mutex); | 822 | mutex_unlock(&key_session_mutex); |
@@ -827,6 +826,8 @@ long join_session_keyring(const char *name) | |||
827 | okay: | 826 | okay: |
828 | return ret; | 827 | return ret; |
829 | 828 | ||
829 | error3: | ||
830 | key_put(keyring); | ||
830 | error2: | 831 | error2: |
831 | mutex_unlock(&key_session_mutex); | 832 | mutex_unlock(&key_session_mutex); |
832 | error: | 833 | error: |
diff --git a/security/keys/trusted.c b/security/keys/trusted.c index 2ae31c5a87de..435e86e13879 100644 --- a/security/keys/trusted.c +++ b/security/keys/trusted.c | |||
@@ -70,7 +70,7 @@ static int TSS_sha1(const unsigned char *data, unsigned int datalen, | |||
70 | } | 70 | } |
71 | 71 | ||
72 | ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest); | 72 | ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest); |
73 | kfree(sdesc); | 73 | kzfree(sdesc); |
74 | return ret; | 74 | return ret; |
75 | } | 75 | } |
76 | 76 | ||
@@ -114,7 +114,7 @@ static int TSS_rawhmac(unsigned char *digest, const unsigned char *key, | |||
114 | if (!ret) | 114 | if (!ret) |
115 | ret = crypto_shash_final(&sdesc->shash, digest); | 115 | ret = crypto_shash_final(&sdesc->shash, digest); |
116 | out: | 116 | out: |
117 | kfree(sdesc); | 117 | kzfree(sdesc); |
118 | return ret; | 118 | return ret; |
119 | } | 119 | } |
120 | 120 | ||
@@ -165,7 +165,7 @@ static int TSS_authhmac(unsigned char *digest, const unsigned char *key, | |||
165 | paramdigest, TPM_NONCE_SIZE, h1, | 165 | paramdigest, TPM_NONCE_SIZE, h1, |
166 | TPM_NONCE_SIZE, h2, 1, &c, 0, 0); | 166 | TPM_NONCE_SIZE, h2, 1, &c, 0, 0); |
167 | out: | 167 | out: |
168 | kfree(sdesc); | 168 | kzfree(sdesc); |
169 | return ret; | 169 | return ret; |
170 | } | 170 | } |
171 | 171 | ||
@@ -246,7 +246,7 @@ static int TSS_checkhmac1(unsigned char *buffer, | |||
246 | if (memcmp(testhmac, authdata, SHA1_DIGEST_SIZE)) | 246 | if (memcmp(testhmac, authdata, SHA1_DIGEST_SIZE)) |
247 | ret = -EINVAL; | 247 | ret = -EINVAL; |
248 | out: | 248 | out: |
249 | kfree(sdesc); | 249 | kzfree(sdesc); |
250 | return ret; | 250 | return ret; |
251 | } | 251 | } |
252 | 252 | ||
@@ -347,7 +347,7 @@ static int TSS_checkhmac2(unsigned char *buffer, | |||
347 | if (memcmp(testhmac2, authdata2, SHA1_DIGEST_SIZE)) | 347 | if (memcmp(testhmac2, authdata2, SHA1_DIGEST_SIZE)) |
348 | ret = -EINVAL; | 348 | ret = -EINVAL; |
349 | out: | 349 | out: |
350 | kfree(sdesc); | 350 | kzfree(sdesc); |
351 | return ret; | 351 | return ret; |
352 | } | 352 | } |
353 | 353 | ||
@@ -564,7 +564,7 @@ static int tpm_seal(struct tpm_buf *tb, uint16_t keytype, | |||
564 | *bloblen = storedsize; | 564 | *bloblen = storedsize; |
565 | } | 565 | } |
566 | out: | 566 | out: |
567 | kfree(td); | 567 | kzfree(td); |
568 | return ret; | 568 | return ret; |
569 | } | 569 | } |
570 | 570 | ||
@@ -678,7 +678,7 @@ static int key_seal(struct trusted_key_payload *p, | |||
678 | if (ret < 0) | 678 | if (ret < 0) |
679 | pr_info("trusted_key: srkseal failed (%d)\n", ret); | 679 | pr_info("trusted_key: srkseal failed (%d)\n", ret); |
680 | 680 | ||
681 | kfree(tb); | 681 | kzfree(tb); |
682 | return ret; | 682 | return ret; |
683 | } | 683 | } |
684 | 684 | ||
@@ -703,7 +703,7 @@ static int key_unseal(struct trusted_key_payload *p, | |||
703 | /* pull migratable flag out of sealed key */ | 703 | /* pull migratable flag out of sealed key */ |
704 | p->migratable = p->key[--p->key_len]; | 704 | p->migratable = p->key[--p->key_len]; |
705 | 705 | ||
706 | kfree(tb); | 706 | kzfree(tb); |
707 | return ret; | 707 | return ret; |
708 | } | 708 | } |
709 | 709 | ||
@@ -1037,12 +1037,12 @@ static int trusted_instantiate(struct key *key, | |||
1037 | if (!ret && options->pcrlock) | 1037 | if (!ret && options->pcrlock) |
1038 | ret = pcrlock(options->pcrlock); | 1038 | ret = pcrlock(options->pcrlock); |
1039 | out: | 1039 | out: |
1040 | kfree(datablob); | 1040 | kzfree(datablob); |
1041 | kfree(options); | 1041 | kzfree(options); |
1042 | if (!ret) | 1042 | if (!ret) |
1043 | rcu_assign_keypointer(key, payload); | 1043 | rcu_assign_keypointer(key, payload); |
1044 | else | 1044 | else |
1045 | kfree(payload); | 1045 | kzfree(payload); |
1046 | return ret; | 1046 | return ret; |
1047 | } | 1047 | } |
1048 | 1048 | ||
@@ -1051,8 +1051,7 @@ static void trusted_rcu_free(struct rcu_head *rcu) | |||
1051 | struct trusted_key_payload *p; | 1051 | struct trusted_key_payload *p; |
1052 | 1052 | ||
1053 | p = container_of(rcu, struct trusted_key_payload, rcu); | 1053 | p = container_of(rcu, struct trusted_key_payload, rcu); |
1054 | memset(p->key, 0, p->key_len); | 1054 | kzfree(p); |
1055 | kfree(p); | ||
1056 | } | 1055 | } |
1057 | 1056 | ||
1058 | /* | 1057 | /* |
@@ -1094,13 +1093,13 @@ static int trusted_update(struct key *key, struct key_preparsed_payload *prep) | |||
1094 | ret = datablob_parse(datablob, new_p, new_o); | 1093 | ret = datablob_parse(datablob, new_p, new_o); |
1095 | if (ret != Opt_update) { | 1094 | if (ret != Opt_update) { |
1096 | ret = -EINVAL; | 1095 | ret = -EINVAL; |
1097 | kfree(new_p); | 1096 | kzfree(new_p); |
1098 | goto out; | 1097 | goto out; |
1099 | } | 1098 | } |
1100 | 1099 | ||
1101 | if (!new_o->keyhandle) { | 1100 | if (!new_o->keyhandle) { |
1102 | ret = -EINVAL; | 1101 | ret = -EINVAL; |
1103 | kfree(new_p); | 1102 | kzfree(new_p); |
1104 | goto out; | 1103 | goto out; |
1105 | } | 1104 | } |
1106 | 1105 | ||
@@ -1114,22 +1113,22 @@ static int trusted_update(struct key *key, struct key_preparsed_payload *prep) | |||
1114 | ret = key_seal(new_p, new_o); | 1113 | ret = key_seal(new_p, new_o); |
1115 | if (ret < 0) { | 1114 | if (ret < 0) { |
1116 | pr_info("trusted_key: key_seal failed (%d)\n", ret); | 1115 | pr_info("trusted_key: key_seal failed (%d)\n", ret); |
1117 | kfree(new_p); | 1116 | kzfree(new_p); |
1118 | goto out; | 1117 | goto out; |
1119 | } | 1118 | } |
1120 | if (new_o->pcrlock) { | 1119 | if (new_o->pcrlock) { |
1121 | ret = pcrlock(new_o->pcrlock); | 1120 | ret = pcrlock(new_o->pcrlock); |
1122 | if (ret < 0) { | 1121 | if (ret < 0) { |
1123 | pr_info("trusted_key: pcrlock failed (%d)\n", ret); | 1122 | pr_info("trusted_key: pcrlock failed (%d)\n", ret); |
1124 | kfree(new_p); | 1123 | kzfree(new_p); |
1125 | goto out; | 1124 | goto out; |
1126 | } | 1125 | } |
1127 | } | 1126 | } |
1128 | rcu_assign_keypointer(key, new_p); | 1127 | rcu_assign_keypointer(key, new_p); |
1129 | call_rcu(&p->rcu, trusted_rcu_free); | 1128 | call_rcu(&p->rcu, trusted_rcu_free); |
1130 | out: | 1129 | out: |
1131 | kfree(datablob); | 1130 | kzfree(datablob); |
1132 | kfree(new_o); | 1131 | kzfree(new_o); |
1133 | return ret; | 1132 | return ret; |
1134 | } | 1133 | } |
1135 | 1134 | ||
@@ -1158,24 +1157,19 @@ static long trusted_read(const struct key *key, char __user *buffer, | |||
1158 | for (i = 0; i < p->blob_len; i++) | 1157 | for (i = 0; i < p->blob_len; i++) |
1159 | bufp = hex_byte_pack(bufp, p->blob[i]); | 1158 | bufp = hex_byte_pack(bufp, p->blob[i]); |
1160 | if ((copy_to_user(buffer, ascii_buf, 2 * p->blob_len)) != 0) { | 1159 | if ((copy_to_user(buffer, ascii_buf, 2 * p->blob_len)) != 0) { |
1161 | kfree(ascii_buf); | 1160 | kzfree(ascii_buf); |
1162 | return -EFAULT; | 1161 | return -EFAULT; |
1163 | } | 1162 | } |
1164 | kfree(ascii_buf); | 1163 | kzfree(ascii_buf); |
1165 | return 2 * p->blob_len; | 1164 | return 2 * p->blob_len; |
1166 | } | 1165 | } |
1167 | 1166 | ||
1168 | /* | 1167 | /* |
1169 | * trusted_destroy - before freeing the key, clear the decrypted data | 1168 | * trusted_destroy - clear and free the key's payload |
1170 | */ | 1169 | */ |
1171 | static void trusted_destroy(struct key *key) | 1170 | static void trusted_destroy(struct key *key) |
1172 | { | 1171 | { |
1173 | struct trusted_key_payload *p = key->payload.data[0]; | 1172 | kzfree(key->payload.data[0]); |
1174 | |||
1175 | if (!p) | ||
1176 | return; | ||
1177 | memset(p->key, 0, p->key_len); | ||
1178 | kfree(key->payload.data[0]); | ||
1179 | } | 1173 | } |
1180 | 1174 | ||
1181 | struct key_type key_type_trusted = { | 1175 | struct key_type key_type_trusted = { |
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c index 26605134f17a..3d8c68eba516 100644 --- a/security/keys/user_defined.c +++ b/security/keys/user_defined.c | |||
@@ -86,10 +86,18 @@ EXPORT_SYMBOL_GPL(user_preparse); | |||
86 | */ | 86 | */ |
87 | void user_free_preparse(struct key_preparsed_payload *prep) | 87 | void user_free_preparse(struct key_preparsed_payload *prep) |
88 | { | 88 | { |
89 | kfree(prep->payload.data[0]); | 89 | kzfree(prep->payload.data[0]); |
90 | } | 90 | } |
91 | EXPORT_SYMBOL_GPL(user_free_preparse); | 91 | EXPORT_SYMBOL_GPL(user_free_preparse); |
92 | 92 | ||
93 | static void user_free_payload_rcu(struct rcu_head *head) | ||
94 | { | ||
95 | struct user_key_payload *payload; | ||
96 | |||
97 | payload = container_of(head, struct user_key_payload, rcu); | ||
98 | kzfree(payload); | ||
99 | } | ||
100 | |||
93 | /* | 101 | /* |
94 | * update a user defined key | 102 | * update a user defined key |
95 | * - the key's semaphore is write-locked | 103 | * - the key's semaphore is write-locked |
@@ -112,7 +120,7 @@ int user_update(struct key *key, struct key_preparsed_payload *prep) | |||
112 | prep->payload.data[0] = NULL; | 120 | prep->payload.data[0] = NULL; |
113 | 121 | ||
114 | if (zap) | 122 | if (zap) |
115 | kfree_rcu(zap, rcu); | 123 | call_rcu(&zap->rcu, user_free_payload_rcu); |
116 | return ret; | 124 | return ret; |
117 | } | 125 | } |
118 | EXPORT_SYMBOL_GPL(user_update); | 126 | EXPORT_SYMBOL_GPL(user_update); |
@@ -130,7 +138,7 @@ void user_revoke(struct key *key) | |||
130 | 138 | ||
131 | if (upayload) { | 139 | if (upayload) { |
132 | rcu_assign_keypointer(key, NULL); | 140 | rcu_assign_keypointer(key, NULL); |
133 | kfree_rcu(upayload, rcu); | 141 | call_rcu(&upayload->rcu, user_free_payload_rcu); |
134 | } | 142 | } |
135 | } | 143 | } |
136 | 144 | ||
@@ -143,7 +151,7 @@ void user_destroy(struct key *key) | |||
143 | { | 151 | { |
144 | struct user_key_payload *upayload = key->payload.data[0]; | 152 | struct user_key_payload *upayload = key->payload.data[0]; |
145 | 153 | ||
146 | kfree(upayload); | 154 | kzfree(upayload); |
147 | } | 155 | } |
148 | 156 | ||
149 | EXPORT_SYMBOL_GPL(user_destroy); | 157 | EXPORT_SYMBOL_GPL(user_destroy); |