diff options
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/blkcipher.c | 3 | ||||
-rw-r--r-- | crypto/cryptd.c | 9 | ||||
-rw-r--r-- | crypto/echainiv.c | 115 | ||||
-rw-r--r-- | crypto/rsa-pkcs1pad.c | 41 |
4 files changed, 57 insertions, 111 deletions
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c index 369999530108..a832426820e8 100644 --- a/crypto/blkcipher.c +++ b/crypto/blkcipher.c | |||
@@ -233,6 +233,8 @@ static int blkcipher_walk_next(struct blkcipher_desc *desc, | |||
233 | return blkcipher_walk_done(desc, walk, -EINVAL); | 233 | return blkcipher_walk_done(desc, walk, -EINVAL); |
234 | } | 234 | } |
235 | 235 | ||
236 | bsize = min(walk->walk_blocksize, n); | ||
237 | |||
236 | walk->flags &= ~(BLKCIPHER_WALK_SLOW | BLKCIPHER_WALK_COPY | | 238 | walk->flags &= ~(BLKCIPHER_WALK_SLOW | BLKCIPHER_WALK_COPY | |
237 | BLKCIPHER_WALK_DIFF); | 239 | BLKCIPHER_WALK_DIFF); |
238 | if (!scatterwalk_aligned(&walk->in, walk->alignmask) || | 240 | if (!scatterwalk_aligned(&walk->in, walk->alignmask) || |
@@ -245,7 +247,6 @@ static int blkcipher_walk_next(struct blkcipher_desc *desc, | |||
245 | } | 247 | } |
246 | } | 248 | } |
247 | 249 | ||
248 | bsize = min(walk->walk_blocksize, n); | ||
249 | n = scatterwalk_clamp(&walk->in, n); | 250 | n = scatterwalk_clamp(&walk->in, n); |
250 | n = scatterwalk_clamp(&walk->out, n); | 251 | n = scatterwalk_clamp(&walk->out, n); |
251 | 252 | ||
diff --git a/crypto/cryptd.c b/crypto/cryptd.c index 77207b41940c..0c654e59f215 100644 --- a/crypto/cryptd.c +++ b/crypto/cryptd.c | |||
@@ -631,9 +631,14 @@ static int cryptd_hash_export(struct ahash_request *req, void *out) | |||
631 | 631 | ||
632 | static int cryptd_hash_import(struct ahash_request *req, const void *in) | 632 | static int cryptd_hash_import(struct ahash_request *req, const void *in) |
633 | { | 633 | { |
634 | struct cryptd_hash_request_ctx *rctx = ahash_request_ctx(req); | 634 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); |
635 | struct cryptd_hash_ctx *ctx = crypto_ahash_ctx(tfm); | ||
636 | struct shash_desc *desc = cryptd_shash_desc(req); | ||
637 | |||
638 | desc->tfm = ctx->child; | ||
639 | desc->flags = req->base.flags; | ||
635 | 640 | ||
636 | return crypto_shash_import(&rctx->desc, in); | 641 | return crypto_shash_import(desc, in); |
637 | } | 642 | } |
638 | 643 | ||
639 | static int cryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb, | 644 | static int cryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb, |
diff --git a/crypto/echainiv.c b/crypto/echainiv.c index 1b01fe98e91f..e3d889b122e0 100644 --- a/crypto/echainiv.c +++ b/crypto/echainiv.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * echainiv: Encrypted Chain IV Generator | 2 | * echainiv: Encrypted Chain IV Generator |
3 | * | 3 | * |
4 | * This generator generates an IV based on a sequence number by xoring it | 4 | * This generator generates an IV based on a sequence number by multiplying |
5 | * with a salt and then encrypting it with the same key as used to encrypt | 5 | * it with a salt and then encrypting it with the same key as used to encrypt |
6 | * the plain text. This algorithm requires that the block size be equal | 6 | * the plain text. This algorithm requires that the block size be equal |
7 | * to the IV size. It is mainly useful for CBC. | 7 | * to the IV size. It is mainly useful for CBC. |
8 | * | 8 | * |
@@ -24,81 +24,17 @@ | |||
24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/mm.h> | ||
28 | #include <linux/module.h> | 27 | #include <linux/module.h> |
29 | #include <linux/percpu.h> | 28 | #include <linux/slab.h> |
30 | #include <linux/spinlock.h> | ||
31 | #include <linux/string.h> | 29 | #include <linux/string.h> |
32 | 30 | ||
33 | #define MAX_IV_SIZE 16 | ||
34 | |||
35 | static DEFINE_PER_CPU(u32 [MAX_IV_SIZE / sizeof(u32)], echainiv_iv); | ||
36 | |||
37 | /* We don't care if we get preempted and read/write IVs from the next CPU. */ | ||
38 | static void echainiv_read_iv(u8 *dst, unsigned size) | ||
39 | { | ||
40 | u32 *a = (u32 *)dst; | ||
41 | u32 __percpu *b = echainiv_iv; | ||
42 | |||
43 | for (; size >= 4; size -= 4) { | ||
44 | *a++ = this_cpu_read(*b); | ||
45 | b++; | ||
46 | } | ||
47 | } | ||
48 | |||
49 | static void echainiv_write_iv(const u8 *src, unsigned size) | ||
50 | { | ||
51 | const u32 *a = (const u32 *)src; | ||
52 | u32 __percpu *b = echainiv_iv; | ||
53 | |||
54 | for (; size >= 4; size -= 4) { | ||
55 | this_cpu_write(*b, *a); | ||
56 | a++; | ||
57 | b++; | ||
58 | } | ||
59 | } | ||
60 | |||
61 | static void echainiv_encrypt_complete2(struct aead_request *req, int err) | ||
62 | { | ||
63 | struct aead_request *subreq = aead_request_ctx(req); | ||
64 | struct crypto_aead *geniv; | ||
65 | unsigned int ivsize; | ||
66 | |||
67 | if (err == -EINPROGRESS) | ||
68 | return; | ||
69 | |||
70 | if (err) | ||
71 | goto out; | ||
72 | |||
73 | geniv = crypto_aead_reqtfm(req); | ||
74 | ivsize = crypto_aead_ivsize(geniv); | ||
75 | |||
76 | echainiv_write_iv(subreq->iv, ivsize); | ||
77 | |||
78 | if (req->iv != subreq->iv) | ||
79 | memcpy(req->iv, subreq->iv, ivsize); | ||
80 | |||
81 | out: | ||
82 | if (req->iv != subreq->iv) | ||
83 | kzfree(subreq->iv); | ||
84 | } | ||
85 | |||
86 | static void echainiv_encrypt_complete(struct crypto_async_request *base, | ||
87 | int err) | ||
88 | { | ||
89 | struct aead_request *req = base->data; | ||
90 | |||
91 | echainiv_encrypt_complete2(req, err); | ||
92 | aead_request_complete(req, err); | ||
93 | } | ||
94 | |||
95 | static int echainiv_encrypt(struct aead_request *req) | 31 | static int echainiv_encrypt(struct aead_request *req) |
96 | { | 32 | { |
97 | struct crypto_aead *geniv = crypto_aead_reqtfm(req); | 33 | struct crypto_aead *geniv = crypto_aead_reqtfm(req); |
98 | struct aead_geniv_ctx *ctx = crypto_aead_ctx(geniv); | 34 | struct aead_geniv_ctx *ctx = crypto_aead_ctx(geniv); |
99 | struct aead_request *subreq = aead_request_ctx(req); | 35 | struct aead_request *subreq = aead_request_ctx(req); |
100 | crypto_completion_t compl; | 36 | __be64 nseqno; |
101 | void *data; | 37 | u64 seqno; |
102 | u8 *info; | 38 | u8 *info; |
103 | unsigned int ivsize = crypto_aead_ivsize(geniv); | 39 | unsigned int ivsize = crypto_aead_ivsize(geniv); |
104 | int err; | 40 | int err; |
@@ -108,8 +44,6 @@ static int echainiv_encrypt(struct aead_request *req) | |||
108 | 44 | ||
109 | aead_request_set_tfm(subreq, ctx->child); | 45 | aead_request_set_tfm(subreq, ctx->child); |
110 | 46 | ||
111 | compl = echainiv_encrypt_complete; | ||
112 | data = req; | ||
113 | info = req->iv; | 47 | info = req->iv; |
114 | 48 | ||
115 | if (req->src != req->dst) { | 49 | if (req->src != req->dst) { |
@@ -127,29 +61,30 @@ static int echainiv_encrypt(struct aead_request *req) | |||
127 | return err; | 61 | return err; |
128 | } | 62 | } |
129 | 63 | ||
130 | if (unlikely(!IS_ALIGNED((unsigned long)info, | 64 | aead_request_set_callback(subreq, req->base.flags, |
131 | crypto_aead_alignmask(geniv) + 1))) { | 65 | req->base.complete, req->base.data); |
132 | info = kmalloc(ivsize, req->base.flags & | ||
133 | CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL: | ||
134 | GFP_ATOMIC); | ||
135 | if (!info) | ||
136 | return -ENOMEM; | ||
137 | |||
138 | memcpy(info, req->iv, ivsize); | ||
139 | } | ||
140 | |||
141 | aead_request_set_callback(subreq, req->base.flags, compl, data); | ||
142 | aead_request_set_crypt(subreq, req->dst, req->dst, | 66 | aead_request_set_crypt(subreq, req->dst, req->dst, |
143 | req->cryptlen, info); | 67 | req->cryptlen, info); |
144 | aead_request_set_ad(subreq, req->assoclen); | 68 | aead_request_set_ad(subreq, req->assoclen); |
145 | 69 | ||
146 | crypto_xor(info, ctx->salt, ivsize); | 70 | memcpy(&nseqno, info + ivsize - 8, 8); |
71 | seqno = be64_to_cpu(nseqno); | ||
72 | memset(info, 0, ivsize); | ||
73 | |||
147 | scatterwalk_map_and_copy(info, req->dst, req->assoclen, ivsize, 1); | 74 | scatterwalk_map_and_copy(info, req->dst, req->assoclen, ivsize, 1); |
148 | echainiv_read_iv(info, ivsize); | ||
149 | 75 | ||
150 | err = crypto_aead_encrypt(subreq); | 76 | do { |
151 | echainiv_encrypt_complete2(req, err); | 77 | u64 a; |
152 | return err; | 78 | |
79 | memcpy(&a, ctx->salt + ivsize - 8, 8); | ||
80 | |||
81 | a |= 1; | ||
82 | a *= seqno; | ||
83 | |||
84 | memcpy(info + ivsize - 8, &a, 8); | ||
85 | } while ((ivsize -= 8)); | ||
86 | |||
87 | return crypto_aead_encrypt(subreq); | ||
153 | } | 88 | } |
154 | 89 | ||
155 | static int echainiv_decrypt(struct aead_request *req) | 90 | static int echainiv_decrypt(struct aead_request *req) |
@@ -196,8 +131,7 @@ static int echainiv_aead_create(struct crypto_template *tmpl, | |||
196 | alg = crypto_spawn_aead_alg(spawn); | 131 | alg = crypto_spawn_aead_alg(spawn); |
197 | 132 | ||
198 | err = -EINVAL; | 133 | err = -EINVAL; |
199 | if (inst->alg.ivsize & (sizeof(u32) - 1) || | 134 | if (inst->alg.ivsize & (sizeof(u64) - 1) || !inst->alg.ivsize) |
200 | inst->alg.ivsize > MAX_IV_SIZE) | ||
201 | goto free_inst; | 135 | goto free_inst; |
202 | 136 | ||
203 | inst->alg.encrypt = echainiv_encrypt; | 137 | inst->alg.encrypt = echainiv_encrypt; |
@@ -206,7 +140,6 @@ static int echainiv_aead_create(struct crypto_template *tmpl, | |||
206 | inst->alg.init = aead_init_geniv; | 140 | inst->alg.init = aead_init_geniv; |
207 | inst->alg.exit = aead_exit_geniv; | 141 | inst->alg.exit = aead_exit_geniv; |
208 | 142 | ||
209 | inst->alg.base.cra_alignmask |= __alignof__(u32) - 1; | ||
210 | inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx); | 143 | inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx); |
211 | inst->alg.base.cra_ctxsize += inst->alg.ivsize; | 144 | inst->alg.base.cra_ctxsize += inst->alg.ivsize; |
212 | 145 | ||
diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c index 877019a6d3ea..8baab4307f7b 100644 --- a/crypto/rsa-pkcs1pad.c +++ b/crypto/rsa-pkcs1pad.c | |||
@@ -298,41 +298,48 @@ static int pkcs1pad_decrypt_complete(struct akcipher_request *req, int err) | |||
298 | struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); | 298 | struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); |
299 | struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); | 299 | struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); |
300 | struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); | 300 | struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); |
301 | unsigned int dst_len; | ||
301 | unsigned int pos; | 302 | unsigned int pos; |
302 | 303 | u8 *out_buf; | |
303 | if (err == -EOVERFLOW) | ||
304 | /* Decrypted value had no leading 0 byte */ | ||
305 | err = -EINVAL; | ||
306 | 304 | ||
307 | if (err) | 305 | if (err) |
308 | goto done; | 306 | goto done; |
309 | 307 | ||
310 | if (req_ctx->child_req.dst_len != ctx->key_size - 1) { | 308 | err = -EINVAL; |
311 | err = -EINVAL; | 309 | dst_len = req_ctx->child_req.dst_len; |
310 | if (dst_len < ctx->key_size - 1) | ||
312 | goto done; | 311 | goto done; |
312 | |||
313 | out_buf = req_ctx->out_buf; | ||
314 | if (dst_len == ctx->key_size) { | ||
315 | if (out_buf[0] != 0x00) | ||
316 | /* Decrypted value had no leading 0 byte */ | ||
317 | goto done; | ||
318 | |||
319 | dst_len--; | ||
320 | out_buf++; | ||
313 | } | 321 | } |
314 | 322 | ||
315 | if (req_ctx->out_buf[0] != 0x02) { | 323 | if (out_buf[0] != 0x02) |
316 | err = -EINVAL; | ||
317 | goto done; | 324 | goto done; |
318 | } | 325 | |
319 | for (pos = 1; pos < req_ctx->child_req.dst_len; pos++) | 326 | for (pos = 1; pos < dst_len; pos++) |
320 | if (req_ctx->out_buf[pos] == 0x00) | 327 | if (out_buf[pos] == 0x00) |
321 | break; | 328 | break; |
322 | if (pos < 9 || pos == req_ctx->child_req.dst_len) { | 329 | if (pos < 9 || pos == dst_len) |
323 | err = -EINVAL; | ||
324 | goto done; | 330 | goto done; |
325 | } | ||
326 | pos++; | 331 | pos++; |
327 | 332 | ||
328 | if (req->dst_len < req_ctx->child_req.dst_len - pos) | 333 | err = 0; |
334 | |||
335 | if (req->dst_len < dst_len - pos) | ||
329 | err = -EOVERFLOW; | 336 | err = -EOVERFLOW; |
330 | req->dst_len = req_ctx->child_req.dst_len - pos; | 337 | req->dst_len = dst_len - pos; |
331 | 338 | ||
332 | if (!err) | 339 | if (!err) |
333 | sg_copy_from_buffer(req->dst, | 340 | sg_copy_from_buffer(req->dst, |
334 | sg_nents_for_len(req->dst, req->dst_len), | 341 | sg_nents_for_len(req->dst, req->dst_len), |
335 | req_ctx->out_buf + pos, req->dst_len); | 342 | out_buf + pos, req->dst_len); |
336 | 343 | ||
337 | done: | 344 | done: |
338 | kzfree(req_ctx->out_buf); | 345 | kzfree(req_ctx->out_buf); |