diff options
-rw-r--r-- | crypto/ablkcipher.c | 158 | ||||
-rw-r--r-- | crypto/api.c | 19 | ||||
-rw-r--r-- | crypto/blkcipher.c | 4 | ||||
-rw-r--r-- | crypto/internal.h | 2 | ||||
-rw-r--r-- | include/crypto/internal/skcipher.h | 2 | ||||
-rw-r--r-- | include/linux/crypto.h | 9 |
6 files changed, 181 insertions, 13 deletions
diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c index 092d9659b861..d1df528c8fa3 100644 --- a/crypto/ablkcipher.c +++ b/crypto/ablkcipher.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/rtnetlink.h> | ||
22 | #include <linux/sched.h> | ||
21 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
22 | #include <linux/seq_file.h> | 24 | #include <linux/seq_file.h> |
23 | 25 | ||
@@ -68,6 +70,16 @@ static unsigned int crypto_ablkcipher_ctxsize(struct crypto_alg *alg, u32 type, | |||
68 | return alg->cra_ctxsize; | 70 | return alg->cra_ctxsize; |
69 | } | 71 | } |
70 | 72 | ||
73 | int skcipher_null_givencrypt(struct skcipher_givcrypt_request *req) | ||
74 | { | ||
75 | return crypto_ablkcipher_encrypt(&req->creq); | ||
76 | } | ||
77 | |||
78 | int skcipher_null_givdecrypt(struct skcipher_givcrypt_request *req) | ||
79 | { | ||
80 | return crypto_ablkcipher_decrypt(&req->creq); | ||
81 | } | ||
82 | |||
71 | static int crypto_init_ablkcipher_ops(struct crypto_tfm *tfm, u32 type, | 83 | static int crypto_init_ablkcipher_ops(struct crypto_tfm *tfm, u32 type, |
72 | u32 mask) | 84 | u32 mask) |
73 | { | 85 | { |
@@ -80,6 +92,10 @@ static int crypto_init_ablkcipher_ops(struct crypto_tfm *tfm, u32 type, | |||
80 | crt->setkey = setkey; | 92 | crt->setkey = setkey; |
81 | crt->encrypt = alg->encrypt; | 93 | crt->encrypt = alg->encrypt; |
82 | crt->decrypt = alg->decrypt; | 94 | crt->decrypt = alg->decrypt; |
95 | if (!alg->ivsize) { | ||
96 | crt->givencrypt = skcipher_null_givencrypt; | ||
97 | crt->givdecrypt = skcipher_null_givdecrypt; | ||
98 | } | ||
83 | crt->base = __crypto_ablkcipher_cast(tfm); | 99 | crt->base = __crypto_ablkcipher_cast(tfm); |
84 | crt->ivsize = alg->ivsize; | 100 | crt->ivsize = alg->ivsize; |
85 | 101 | ||
@@ -163,6 +179,108 @@ const char *crypto_default_geniv(const struct crypto_alg *alg) | |||
163 | return alg->cra_flags & CRYPTO_ALG_ASYNC ? "eseqiv" : "chainiv"; | 179 | return alg->cra_flags & CRYPTO_ALG_ASYNC ? "eseqiv" : "chainiv"; |
164 | } | 180 | } |
165 | 181 | ||
182 | static int crypto_givcipher_default(struct crypto_alg *alg, u32 type, u32 mask) | ||
183 | { | ||
184 | struct rtattr *tb[3]; | ||
185 | struct { | ||
186 | struct rtattr attr; | ||
187 | struct crypto_attr_type data; | ||
188 | } ptype; | ||
189 | struct { | ||
190 | struct rtattr attr; | ||
191 | struct crypto_attr_alg data; | ||
192 | } palg; | ||
193 | struct crypto_template *tmpl; | ||
194 | struct crypto_instance *inst; | ||
195 | struct crypto_alg *larval; | ||
196 | const char *geniv; | ||
197 | int err; | ||
198 | |||
199 | larval = crypto_larval_lookup(alg->cra_driver_name, | ||
200 | CRYPTO_ALG_TYPE_GIVCIPHER, | ||
201 | CRYPTO_ALG_TYPE_MASK); | ||
202 | err = PTR_ERR(larval); | ||
203 | if (IS_ERR(larval)) | ||
204 | goto out; | ||
205 | |||
206 | err = -EAGAIN; | ||
207 | if (!crypto_is_larval(larval)) | ||
208 | goto drop_larval; | ||
209 | |||
210 | ptype.attr.rta_len = sizeof(ptype); | ||
211 | ptype.attr.rta_type = CRYPTOA_TYPE; | ||
212 | ptype.data.type = type | CRYPTO_ALG_GENIV; | ||
213 | /* GENIV tells the template that we're making a default geniv. */ | ||
214 | ptype.data.mask = mask | CRYPTO_ALG_GENIV; | ||
215 | tb[0] = &ptype.attr; | ||
216 | |||
217 | palg.attr.rta_len = sizeof(palg); | ||
218 | palg.attr.rta_type = CRYPTOA_ALG; | ||
219 | /* Must use the exact name to locate ourselves. */ | ||
220 | memcpy(palg.data.name, alg->cra_driver_name, CRYPTO_MAX_ALG_NAME); | ||
221 | tb[1] = &palg.attr; | ||
222 | |||
223 | tb[2] = NULL; | ||
224 | |||
225 | if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == | ||
226 | CRYPTO_ALG_TYPE_BLKCIPHER) | ||
227 | geniv = alg->cra_blkcipher.geniv; | ||
228 | else | ||
229 | geniv = alg->cra_ablkcipher.geniv; | ||
230 | |||
231 | if (!geniv) | ||
232 | geniv = crypto_default_geniv(alg); | ||
233 | |||
234 | tmpl = crypto_lookup_template(geniv); | ||
235 | err = -ENOENT; | ||
236 | if (!tmpl) | ||
237 | goto kill_larval; | ||
238 | |||
239 | inst = tmpl->alloc(tb); | ||
240 | err = PTR_ERR(inst); | ||
241 | if (IS_ERR(inst)) | ||
242 | goto put_tmpl; | ||
243 | |||
244 | if ((err = crypto_register_instance(tmpl, inst))) { | ||
245 | tmpl->free(inst); | ||
246 | goto put_tmpl; | ||
247 | } | ||
248 | |||
249 | /* Redo the lookup to use the instance we just registered. */ | ||
250 | err = -EAGAIN; | ||
251 | |||
252 | put_tmpl: | ||
253 | crypto_tmpl_put(tmpl); | ||
254 | kill_larval: | ||
255 | crypto_larval_kill(larval); | ||
256 | drop_larval: | ||
257 | crypto_mod_put(larval); | ||
258 | out: | ||
259 | crypto_mod_put(alg); | ||
260 | return err; | ||
261 | } | ||
262 | |||
263 | static struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type, | ||
264 | u32 mask) | ||
265 | { | ||
266 | struct crypto_alg *alg; | ||
267 | |||
268 | alg = crypto_alg_mod_lookup(name, type, mask); | ||
269 | if (IS_ERR(alg)) | ||
270 | return alg; | ||
271 | |||
272 | if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == | ||
273 | CRYPTO_ALG_TYPE_GIVCIPHER) | ||
274 | return alg; | ||
275 | |||
276 | if (!((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == | ||
277 | CRYPTO_ALG_TYPE_BLKCIPHER ? alg->cra_blkcipher.ivsize : | ||
278 | alg->cra_ablkcipher.ivsize)) | ||
279 | return alg; | ||
280 | |||
281 | return ERR_PTR(crypto_givcipher_default(alg, type, mask)); | ||
282 | } | ||
283 | |||
166 | int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name, | 284 | int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name, |
167 | u32 type, u32 mask) | 285 | u32 type, u32 mask) |
168 | { | 286 | { |
@@ -172,7 +290,7 @@ int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name, | |||
172 | type = crypto_skcipher_type(type); | 290 | type = crypto_skcipher_type(type); |
173 | mask = crypto_skcipher_mask(mask); | 291 | mask = crypto_skcipher_mask(mask); |
174 | 292 | ||
175 | alg = crypto_alg_mod_lookup(name, type, mask); | 293 | alg = crypto_lookup_skcipher(name, type, mask); |
176 | if (IS_ERR(alg)) | 294 | if (IS_ERR(alg)) |
177 | return PTR_ERR(alg); | 295 | return PTR_ERR(alg); |
178 | 296 | ||
@@ -182,5 +300,43 @@ int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name, | |||
182 | } | 300 | } |
183 | EXPORT_SYMBOL_GPL(crypto_grab_skcipher); | 301 | EXPORT_SYMBOL_GPL(crypto_grab_skcipher); |
184 | 302 | ||
303 | struct crypto_ablkcipher *crypto_alloc_ablkcipher(const char *alg_name, | ||
304 | u32 type, u32 mask) | ||
305 | { | ||
306 | struct crypto_tfm *tfm; | ||
307 | int err; | ||
308 | |||
309 | type = crypto_skcipher_type(type); | ||
310 | mask = crypto_skcipher_mask(mask); | ||
311 | |||
312 | for (;;) { | ||
313 | struct crypto_alg *alg; | ||
314 | |||
315 | alg = crypto_lookup_skcipher(alg_name, type, mask); | ||
316 | if (IS_ERR(alg)) { | ||
317 | err = PTR_ERR(alg); | ||
318 | goto err; | ||
319 | } | ||
320 | |||
321 | tfm = __crypto_alloc_tfm(alg, type, mask); | ||
322 | if (!IS_ERR(tfm)) | ||
323 | return __crypto_ablkcipher_cast(tfm); | ||
324 | |||
325 | crypto_mod_put(alg); | ||
326 | err = PTR_ERR(tfm); | ||
327 | |||
328 | err: | ||
329 | if (err != -EAGAIN) | ||
330 | break; | ||
331 | if (signal_pending(current)) { | ||
332 | err = -EINTR; | ||
333 | break; | ||
334 | } | ||
335 | } | ||
336 | |||
337 | return ERR_PTR(err); | ||
338 | } | ||
339 | EXPORT_SYMBOL_GPL(crypto_alloc_ablkcipher); | ||
340 | |||
185 | MODULE_LICENSE("GPL"); | 341 | MODULE_LICENSE("GPL"); |
186 | MODULE_DESCRIPTION("Asynchronous block chaining cipher type"); | 342 | MODULE_DESCRIPTION("Asynchronous block chaining cipher type"); |
diff --git a/crypto/api.c b/crypto/api.c index 1f5c72477356..a2496d1bc6d4 100644 --- a/crypto/api.c +++ b/crypto/api.c | |||
@@ -137,7 +137,7 @@ static struct crypto_alg *crypto_larval_alloc(const char *name, u32 type, | |||
137 | return alg; | 137 | return alg; |
138 | } | 138 | } |
139 | 139 | ||
140 | static void crypto_larval_kill(struct crypto_alg *alg) | 140 | void crypto_larval_kill(struct crypto_alg *alg) |
141 | { | 141 | { |
142 | struct crypto_larval *larval = (void *)alg; | 142 | struct crypto_larval *larval = (void *)alg; |
143 | 143 | ||
@@ -147,6 +147,7 @@ static void crypto_larval_kill(struct crypto_alg *alg) | |||
147 | complete_all(&larval->completion); | 147 | complete_all(&larval->completion); |
148 | crypto_alg_put(alg); | 148 | crypto_alg_put(alg); |
149 | } | 149 | } |
150 | EXPORT_SYMBOL_GPL(crypto_larval_kill); | ||
150 | 151 | ||
151 | static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg) | 152 | static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg) |
152 | { | 153 | { |
@@ -176,11 +177,9 @@ static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type, | |||
176 | return alg; | 177 | return alg; |
177 | } | 178 | } |
178 | 179 | ||
179 | struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask) | 180 | struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask) |
180 | { | 181 | { |
181 | struct crypto_alg *alg; | 182 | struct crypto_alg *alg; |
182 | struct crypto_alg *larval; | ||
183 | int ok; | ||
184 | 183 | ||
185 | if (!name) | 184 | if (!name) |
186 | return ERR_PTR(-ENOENT); | 185 | return ERR_PTR(-ENOENT); |
@@ -193,7 +192,17 @@ struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask) | |||
193 | if (alg) | 192 | if (alg) |
194 | return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg; | 193 | return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg; |
195 | 194 | ||
196 | larval = crypto_larval_alloc(name, type, mask); | 195 | return crypto_larval_alloc(name, type, mask); |
196 | } | ||
197 | EXPORT_SYMBOL_GPL(crypto_larval_lookup); | ||
198 | |||
199 | struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask) | ||
200 | { | ||
201 | struct crypto_alg *alg; | ||
202 | struct crypto_alg *larval; | ||
203 | int ok; | ||
204 | |||
205 | larval = crypto_larval_lookup(name, type, mask); | ||
197 | if (IS_ERR(larval) || !crypto_is_larval(larval)) | 206 | if (IS_ERR(larval) || !crypto_is_larval(larval)) |
198 | return larval; | 207 | return larval; |
199 | 208 | ||
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c index ca6ef065cded..4a7e65c4df4d 100644 --- a/crypto/blkcipher.c +++ b/crypto/blkcipher.c | |||
@@ -450,6 +450,10 @@ static int crypto_init_blkcipher_ops_async(struct crypto_tfm *tfm) | |||
450 | crt->setkey = async_setkey; | 450 | crt->setkey = async_setkey; |
451 | crt->encrypt = async_encrypt; | 451 | crt->encrypt = async_encrypt; |
452 | crt->decrypt = async_decrypt; | 452 | crt->decrypt = async_decrypt; |
453 | if (!alg->ivsize) { | ||
454 | crt->givencrypt = skcipher_null_givencrypt; | ||
455 | crt->givdecrypt = skcipher_null_givdecrypt; | ||
456 | } | ||
453 | crt->base = __crypto_ablkcipher_cast(tfm); | 457 | crt->base = __crypto_ablkcipher_cast(tfm); |
454 | crt->ivsize = alg->ivsize; | 458 | crt->ivsize = alg->ivsize; |
455 | 459 | ||
diff --git a/crypto/internal.h b/crypto/internal.h index cb13952f82bf..32f4c2145603 100644 --- a/crypto/internal.h +++ b/crypto/internal.h | |||
@@ -93,6 +93,8 @@ void crypto_exit_digest_ops(struct crypto_tfm *tfm); | |||
93 | void crypto_exit_cipher_ops(struct crypto_tfm *tfm); | 93 | void crypto_exit_cipher_ops(struct crypto_tfm *tfm); |
94 | void crypto_exit_compress_ops(struct crypto_tfm *tfm); | 94 | void crypto_exit_compress_ops(struct crypto_tfm *tfm); |
95 | 95 | ||
96 | void crypto_larval_kill(struct crypto_alg *alg); | ||
97 | struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask); | ||
96 | void crypto_larval_error(const char *name, u32 type, u32 mask); | 98 | void crypto_larval_error(const char *name, u32 type, u32 mask); |
97 | 99 | ||
98 | void crypto_shoot_alg(struct crypto_alg *alg); | 100 | void crypto_shoot_alg(struct crypto_alg *alg); |
diff --git a/include/crypto/internal/skcipher.h b/include/crypto/internal/skcipher.h index 80c5bfb14a60..2071999d4b5e 100644 --- a/include/crypto/internal/skcipher.h +++ b/include/crypto/internal/skcipher.h | |||
@@ -53,6 +53,8 @@ static inline struct crypto_ablkcipher *crypto_spawn_skcipher( | |||
53 | crypto_skcipher_mask(0))); | 53 | crypto_skcipher_mask(0))); |
54 | } | 54 | } |
55 | 55 | ||
56 | int skcipher_null_givencrypt(struct skcipher_givcrypt_request *req); | ||
57 | int skcipher_null_givdecrypt(struct skcipher_givcrypt_request *req); | ||
56 | const char *crypto_default_geniv(const struct crypto_alg *alg); | 58 | const char *crypto_default_geniv(const struct crypto_alg *alg); |
57 | 59 | ||
58 | struct crypto_instance *skcipher_geniv_alloc(struct crypto_template *tmpl, | 60 | struct crypto_instance *skcipher_geniv_alloc(struct crypto_template *tmpl, |
diff --git a/include/linux/crypto.h b/include/linux/crypto.h index fa7afa9b9f4f..835dcaf3fe4e 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h | |||
@@ -561,13 +561,8 @@ static inline u32 crypto_skcipher_mask(u32 mask) | |||
561 | return mask; | 561 | return mask; |
562 | } | 562 | } |
563 | 563 | ||
564 | static inline struct crypto_ablkcipher *crypto_alloc_ablkcipher( | 564 | struct crypto_ablkcipher *crypto_alloc_ablkcipher(const char *alg_name, |
565 | const char *alg_name, u32 type, u32 mask) | 565 | u32 type, u32 mask); |
566 | { | ||
567 | return __crypto_ablkcipher_cast( | ||
568 | crypto_alloc_base(alg_name, crypto_skcipher_type(type), | ||
569 | crypto_skcipher_mask(mask))); | ||
570 | } | ||
571 | 566 | ||
572 | static inline struct crypto_tfm *crypto_ablkcipher_tfm( | 567 | static inline struct crypto_tfm *crypto_ablkcipher_tfm( |
573 | struct crypto_ablkcipher *tfm) | 568 | struct crypto_ablkcipher *tfm) |