diff options
Diffstat (limited to 'crypto/ctr.c')
-rw-r--r-- | crypto/ctr.c | 172 |
1 files changed, 109 insertions, 63 deletions
diff --git a/crypto/ctr.c b/crypto/ctr.c index 095dcb66d72d..f2b94f27bb2c 100644 --- a/crypto/ctr.c +++ b/crypto/ctr.c | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <crypto/algapi.h> | 13 | #include <crypto/algapi.h> |
14 | #include <crypto/ctr.h> | 14 | #include <crypto/ctr.h> |
15 | #include <crypto/internal/skcipher.h> | ||
15 | #include <linux/err.h> | 16 | #include <linux/err.h> |
16 | #include <linux/init.h> | 17 | #include <linux/init.h> |
17 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
@@ -25,10 +26,15 @@ struct crypto_ctr_ctx { | |||
25 | }; | 26 | }; |
26 | 27 | ||
27 | struct crypto_rfc3686_ctx { | 28 | struct crypto_rfc3686_ctx { |
28 | struct crypto_blkcipher *child; | 29 | struct crypto_ablkcipher *child; |
29 | u8 nonce[CTR_RFC3686_NONCE_SIZE]; | 30 | u8 nonce[CTR_RFC3686_NONCE_SIZE]; |
30 | }; | 31 | }; |
31 | 32 | ||
33 | struct crypto_rfc3686_req_ctx { | ||
34 | u8 iv[CTR_RFC3686_BLOCK_SIZE]; | ||
35 | struct ablkcipher_request subreq CRYPTO_MINALIGN_ATTR; | ||
36 | }; | ||
37 | |||
32 | static int crypto_ctr_setkey(struct crypto_tfm *parent, const u8 *key, | 38 | static int crypto_ctr_setkey(struct crypto_tfm *parent, const u8 *key, |
33 | unsigned int keylen) | 39 | unsigned int keylen) |
34 | { | 40 | { |
@@ -243,11 +249,11 @@ static struct crypto_template crypto_ctr_tmpl = { | |||
243 | .module = THIS_MODULE, | 249 | .module = THIS_MODULE, |
244 | }; | 250 | }; |
245 | 251 | ||
246 | static int crypto_rfc3686_setkey(struct crypto_tfm *parent, const u8 *key, | 252 | static int crypto_rfc3686_setkey(struct crypto_ablkcipher *parent, |
247 | unsigned int keylen) | 253 | const u8 *key, unsigned int keylen) |
248 | { | 254 | { |
249 | struct crypto_rfc3686_ctx *ctx = crypto_tfm_ctx(parent); | 255 | struct crypto_rfc3686_ctx *ctx = crypto_ablkcipher_ctx(parent); |
250 | struct crypto_blkcipher *child = ctx->child; | 256 | struct crypto_ablkcipher *child = ctx->child; |
251 | int err; | 257 | int err; |
252 | 258 | ||
253 | /* the nonce is stored in bytes at end of key */ | 259 | /* the nonce is stored in bytes at end of key */ |
@@ -259,59 +265,64 @@ static int crypto_rfc3686_setkey(struct crypto_tfm *parent, const u8 *key, | |||
259 | 265 | ||
260 | keylen -= CTR_RFC3686_NONCE_SIZE; | 266 | keylen -= CTR_RFC3686_NONCE_SIZE; |
261 | 267 | ||
262 | crypto_blkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); | 268 | crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); |
263 | crypto_blkcipher_set_flags(child, crypto_tfm_get_flags(parent) & | 269 | crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(parent) & |
264 | CRYPTO_TFM_REQ_MASK); | 270 | CRYPTO_TFM_REQ_MASK); |
265 | err = crypto_blkcipher_setkey(child, key, keylen); | 271 | err = crypto_ablkcipher_setkey(child, key, keylen); |
266 | crypto_tfm_set_flags(parent, crypto_blkcipher_get_flags(child) & | 272 | crypto_ablkcipher_set_flags(parent, crypto_ablkcipher_get_flags(child) & |
267 | CRYPTO_TFM_RES_MASK); | 273 | CRYPTO_TFM_RES_MASK); |
268 | 274 | ||
269 | return err; | 275 | return err; |
270 | } | 276 | } |
271 | 277 | ||
272 | static int crypto_rfc3686_crypt(struct blkcipher_desc *desc, | 278 | static int crypto_rfc3686_crypt(struct ablkcipher_request *req) |
273 | struct scatterlist *dst, | ||
274 | struct scatterlist *src, unsigned int nbytes) | ||
275 | { | 279 | { |
276 | struct crypto_blkcipher *tfm = desc->tfm; | 280 | struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); |
277 | struct crypto_rfc3686_ctx *ctx = crypto_blkcipher_ctx(tfm); | 281 | struct crypto_rfc3686_ctx *ctx = crypto_ablkcipher_ctx(tfm); |
278 | struct crypto_blkcipher *child = ctx->child; | 282 | struct crypto_ablkcipher *child = ctx->child; |
279 | unsigned long alignmask = crypto_blkcipher_alignmask(tfm); | 283 | unsigned long align = crypto_ablkcipher_alignmask(tfm); |
280 | u8 ivblk[CTR_RFC3686_BLOCK_SIZE + alignmask]; | 284 | struct crypto_rfc3686_req_ctx *rctx = |
281 | u8 *iv = PTR_ALIGN(ivblk + 0, alignmask + 1); | 285 | (void *)PTR_ALIGN((u8 *)ablkcipher_request_ctx(req), align + 1); |
282 | u8 *info = desc->info; | 286 | struct ablkcipher_request *subreq = &rctx->subreq; |
283 | int err; | 287 | u8 *iv = rctx->iv; |
284 | 288 | ||
285 | /* set up counter block */ | 289 | /* set up counter block */ |
286 | memcpy(iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE); | 290 | memcpy(iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE); |
287 | memcpy(iv + CTR_RFC3686_NONCE_SIZE, info, CTR_RFC3686_IV_SIZE); | 291 | memcpy(iv + CTR_RFC3686_NONCE_SIZE, req->info, CTR_RFC3686_IV_SIZE); |
288 | 292 | ||
289 | /* initialize counter portion of counter block */ | 293 | /* initialize counter portion of counter block */ |
290 | *(__be32 *)(iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) = | 294 | *(__be32 *)(iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) = |
291 | cpu_to_be32(1); | 295 | cpu_to_be32(1); |
292 | 296 | ||
293 | desc->tfm = child; | 297 | ablkcipher_request_set_tfm(subreq, child); |
294 | desc->info = iv; | 298 | ablkcipher_request_set_callback(subreq, req->base.flags, |
295 | err = crypto_blkcipher_encrypt_iv(desc, dst, src, nbytes); | 299 | req->base.complete, req->base.data); |
296 | desc->tfm = tfm; | 300 | ablkcipher_request_set_crypt(subreq, req->src, req->dst, req->nbytes, |
297 | desc->info = info; | 301 | iv); |
298 | 302 | ||
299 | return err; | 303 | return crypto_ablkcipher_encrypt(subreq); |
300 | } | 304 | } |
301 | 305 | ||
302 | static int crypto_rfc3686_init_tfm(struct crypto_tfm *tfm) | 306 | static int crypto_rfc3686_init_tfm(struct crypto_tfm *tfm) |
303 | { | 307 | { |
304 | struct crypto_instance *inst = (void *)tfm->__crt_alg; | 308 | struct crypto_instance *inst = (void *)tfm->__crt_alg; |
305 | struct crypto_spawn *spawn = crypto_instance_ctx(inst); | 309 | struct crypto_skcipher_spawn *spawn = crypto_instance_ctx(inst); |
306 | struct crypto_rfc3686_ctx *ctx = crypto_tfm_ctx(tfm); | 310 | struct crypto_rfc3686_ctx *ctx = crypto_tfm_ctx(tfm); |
307 | struct crypto_blkcipher *cipher; | 311 | struct crypto_ablkcipher *cipher; |
312 | unsigned long align; | ||
308 | 313 | ||
309 | cipher = crypto_spawn_blkcipher(spawn); | 314 | cipher = crypto_spawn_skcipher(spawn); |
310 | if (IS_ERR(cipher)) | 315 | if (IS_ERR(cipher)) |
311 | return PTR_ERR(cipher); | 316 | return PTR_ERR(cipher); |
312 | 317 | ||
313 | ctx->child = cipher; | 318 | ctx->child = cipher; |
314 | 319 | ||
320 | align = crypto_tfm_alg_alignmask(tfm); | ||
321 | align &= ~(crypto_tfm_ctx_alignment() - 1); | ||
322 | tfm->crt_ablkcipher.reqsize = align + | ||
323 | sizeof(struct crypto_rfc3686_req_ctx) + | ||
324 | crypto_ablkcipher_reqsize(cipher); | ||
325 | |||
315 | return 0; | 326 | return 0; |
316 | } | 327 | } |
317 | 328 | ||
@@ -319,73 +330,108 @@ static void crypto_rfc3686_exit_tfm(struct crypto_tfm *tfm) | |||
319 | { | 330 | { |
320 | struct crypto_rfc3686_ctx *ctx = crypto_tfm_ctx(tfm); | 331 | struct crypto_rfc3686_ctx *ctx = crypto_tfm_ctx(tfm); |
321 | 332 | ||
322 | crypto_free_blkcipher(ctx->child); | 333 | crypto_free_ablkcipher(ctx->child); |
323 | } | 334 | } |
324 | 335 | ||
325 | static struct crypto_instance *crypto_rfc3686_alloc(struct rtattr **tb) | 336 | static struct crypto_instance *crypto_rfc3686_alloc(struct rtattr **tb) |
326 | { | 337 | { |
338 | struct crypto_attr_type *algt; | ||
327 | struct crypto_instance *inst; | 339 | struct crypto_instance *inst; |
328 | struct crypto_alg *alg; | 340 | struct crypto_alg *alg; |
341 | struct crypto_skcipher_spawn *spawn; | ||
342 | const char *cipher_name; | ||
329 | int err; | 343 | int err; |
330 | 344 | ||
331 | err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER); | 345 | algt = crypto_get_attr_type(tb); |
346 | if (IS_ERR(algt)) | ||
347 | return ERR_CAST(algt); | ||
348 | |||
349 | if ((algt->type ^ CRYPTO_ALG_TYPE_BLKCIPHER) & algt->mask) | ||
350 | return ERR_PTR(-EINVAL); | ||
351 | |||
352 | cipher_name = crypto_attr_alg_name(tb[1]); | ||
353 | if (IS_ERR(cipher_name)) | ||
354 | return ERR_CAST(cipher_name); | ||
355 | |||
356 | inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); | ||
357 | if (!inst) | ||
358 | return ERR_PTR(-ENOMEM); | ||
359 | |||
360 | spawn = crypto_instance_ctx(inst); | ||
361 | |||
362 | crypto_set_skcipher_spawn(spawn, inst); | ||
363 | err = crypto_grab_skcipher(spawn, cipher_name, 0, | ||
364 | crypto_requires_sync(algt->type, | ||
365 | algt->mask)); | ||
332 | if (err) | 366 | if (err) |
333 | return ERR_PTR(err); | 367 | goto err_free_inst; |
334 | 368 | ||
335 | alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_BLKCIPHER, | 369 | alg = crypto_skcipher_spawn_alg(spawn); |
336 | CRYPTO_ALG_TYPE_MASK); | ||
337 | if (IS_ERR(alg)) | ||
338 | return ERR_CAST(alg); | ||
339 | 370 | ||
340 | /* We only support 16-byte blocks. */ | 371 | /* We only support 16-byte blocks. */ |
341 | err = -EINVAL; | 372 | err = -EINVAL; |
342 | if (alg->cra_blkcipher.ivsize != CTR_RFC3686_BLOCK_SIZE) | 373 | if (alg->cra_ablkcipher.ivsize != CTR_RFC3686_BLOCK_SIZE) |
343 | goto out_put_alg; | 374 | goto err_drop_spawn; |
344 | 375 | ||
345 | /* Not a stream cipher? */ | 376 | /* Not a stream cipher? */ |
346 | if (alg->cra_blocksize != 1) | 377 | if (alg->cra_blocksize != 1) |
347 | goto out_put_alg; | 378 | goto err_drop_spawn; |
348 | 379 | ||
349 | inst = crypto_alloc_instance("rfc3686", alg); | 380 | err = -ENAMETOOLONG; |
350 | if (IS_ERR(inst)) | 381 | if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, "rfc3686(%s)", |
351 | goto out; | 382 | alg->cra_name) >= CRYPTO_MAX_ALG_NAME) |
383 | goto err_drop_spawn; | ||
384 | if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, | ||
385 | "rfc3686(%s)", alg->cra_driver_name) >= | ||
386 | CRYPTO_MAX_ALG_NAME) | ||
387 | goto err_drop_spawn; | ||
352 | 388 | ||
353 | inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER; | ||
354 | inst->alg.cra_priority = alg->cra_priority; | 389 | inst->alg.cra_priority = alg->cra_priority; |
355 | inst->alg.cra_blocksize = 1; | 390 | inst->alg.cra_blocksize = 1; |
356 | inst->alg.cra_alignmask = alg->cra_alignmask; | 391 | inst->alg.cra_alignmask = alg->cra_alignmask; |
357 | inst->alg.cra_type = &crypto_blkcipher_type; | ||
358 | 392 | ||
359 | inst->alg.cra_blkcipher.ivsize = CTR_RFC3686_IV_SIZE; | 393 | inst->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | |
360 | inst->alg.cra_blkcipher.min_keysize = alg->cra_blkcipher.min_keysize | 394 | (alg->cra_flags & CRYPTO_ALG_ASYNC); |
361 | + CTR_RFC3686_NONCE_SIZE; | 395 | inst->alg.cra_type = &crypto_ablkcipher_type; |
362 | inst->alg.cra_blkcipher.max_keysize = alg->cra_blkcipher.max_keysize | 396 | |
363 | + CTR_RFC3686_NONCE_SIZE; | 397 | inst->alg.cra_ablkcipher.ivsize = CTR_RFC3686_IV_SIZE; |
398 | inst->alg.cra_ablkcipher.min_keysize = | ||
399 | alg->cra_ablkcipher.min_keysize + CTR_RFC3686_NONCE_SIZE; | ||
400 | inst->alg.cra_ablkcipher.max_keysize = | ||
401 | alg->cra_ablkcipher.max_keysize + CTR_RFC3686_NONCE_SIZE; | ||
364 | 402 | ||
365 | inst->alg.cra_blkcipher.geniv = "seqiv"; | 403 | inst->alg.cra_ablkcipher.geniv = "seqiv"; |
404 | |||
405 | inst->alg.cra_ablkcipher.setkey = crypto_rfc3686_setkey; | ||
406 | inst->alg.cra_ablkcipher.encrypt = crypto_rfc3686_crypt; | ||
407 | inst->alg.cra_ablkcipher.decrypt = crypto_rfc3686_crypt; | ||
366 | 408 | ||
367 | inst->alg.cra_ctxsize = sizeof(struct crypto_rfc3686_ctx); | 409 | inst->alg.cra_ctxsize = sizeof(struct crypto_rfc3686_ctx); |
368 | 410 | ||
369 | inst->alg.cra_init = crypto_rfc3686_init_tfm; | 411 | inst->alg.cra_init = crypto_rfc3686_init_tfm; |
370 | inst->alg.cra_exit = crypto_rfc3686_exit_tfm; | 412 | inst->alg.cra_exit = crypto_rfc3686_exit_tfm; |
371 | 413 | ||
372 | inst->alg.cra_blkcipher.setkey = crypto_rfc3686_setkey; | ||
373 | inst->alg.cra_blkcipher.encrypt = crypto_rfc3686_crypt; | ||
374 | inst->alg.cra_blkcipher.decrypt = crypto_rfc3686_crypt; | ||
375 | |||
376 | out: | ||
377 | crypto_mod_put(alg); | ||
378 | return inst; | 414 | return inst; |
379 | 415 | ||
380 | out_put_alg: | 416 | err_drop_spawn: |
381 | inst = ERR_PTR(err); | 417 | crypto_drop_skcipher(spawn); |
382 | goto out; | 418 | err_free_inst: |
419 | kfree(inst); | ||
420 | return ERR_PTR(err); | ||
421 | } | ||
422 | |||
423 | static void crypto_rfc3686_free(struct crypto_instance *inst) | ||
424 | { | ||
425 | struct crypto_skcipher_spawn *spawn = crypto_instance_ctx(inst); | ||
426 | |||
427 | crypto_drop_skcipher(spawn); | ||
428 | kfree(inst); | ||
383 | } | 429 | } |
384 | 430 | ||
385 | static struct crypto_template crypto_rfc3686_tmpl = { | 431 | static struct crypto_template crypto_rfc3686_tmpl = { |
386 | .name = "rfc3686", | 432 | .name = "rfc3686", |
387 | .alloc = crypto_rfc3686_alloc, | 433 | .alloc = crypto_rfc3686_alloc, |
388 | .free = crypto_ctr_free, | 434 | .free = crypto_rfc3686_free, |
389 | .module = THIS_MODULE, | 435 | .module = THIS_MODULE, |
390 | }; | 436 | }; |
391 | 437 | ||