summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2019-08-19 10:17:33 -0400
committerMike Snitzer <snitzer@redhat.com>2019-09-03 16:44:57 -0400
commitbe1eb7f78aa8fbe34779c56c266ccd0364604e71 (patch)
tree7930cd51bfb57e9c6b0547677a7eb7e3dc7a82e3
parentc1499a044d7c2bbd9ea3d9c17e17f16595ae6d69 (diff)
crypto: essiv - create wrapper template for ESSIV generation
Implement a template that wraps a (skcipher,shash) or (aead,shash) tuple so that we can consolidate the ESSIV handling in fscrypt and dm-crypt and move it into the crypto API. This will result in better test coverage, and will allow future changes to make the bare cipher interface internal to the crypto subsystem, in order to increase robustness of the API against misuse. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Acked-by: Herbert Xu <herbert@gondor.apana.org.au> Tested-by: Milan Broz <gmazyland@gmail.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
-rw-r--r--crypto/Kconfig28
-rw-r--r--crypto/Makefile1
-rw-r--r--crypto/essiv.c663
3 files changed, 692 insertions, 0 deletions
diff --git a/crypto/Kconfig b/crypto/Kconfig
index e801450bcb1c..1e8390d32b6d 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -568,6 +568,34 @@ config CRYPTO_ADIANTUM
568 568
569 If unsure, say N. 569 If unsure, say N.
570 570
571config CRYPTO_ESSIV
572 tristate "ESSIV support for block encryption"
573 select CRYPTO_AUTHENC
574 help
575 Encrypted salt-sector initialization vector (ESSIV) is an IV
576 generation method that is used in some cases by fscrypt and/or
577 dm-crypt. It uses the hash of the block encryption key as the
578 symmetric key for a block encryption pass applied to the input
579 IV, making low entropy IV sources more suitable for block
580 encryption.
581
582 This driver implements a crypto API template that can be
583 instantiated either as a skcipher or as a aead (depending on the
584 type of the first template argument), and which defers encryption
585 and decryption requests to the encapsulated cipher after applying
586 ESSIV to the input IV. Note that in the aead case, it is assumed
587 that the keys are presented in the same format used by the authenc
588 template, and that the IV appears at the end of the authenticated
589 associated data (AAD) region (which is how dm-crypt uses it.)
590
591 Note that the use of ESSIV is not recommended for new deployments,
592 and so this only needs to be enabled when interoperability with
593 existing encrypted volumes of filesystems is required, or when
594 building for a particular system that requires it (e.g., when
595 the SoC in question has accelerated CBC but not XTS, making CBC
596 combined with ESSIV the only feasible mode for h/w accelerated
597 block encryption)
598
571comment "Hash modes" 599comment "Hash modes"
572 600
573config CRYPTO_CMAC 601config CRYPTO_CMAC
diff --git a/crypto/Makefile b/crypto/Makefile
index 9479e1a45d8c..157cb0a324df 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -147,6 +147,7 @@ obj-$(CONFIG_CRYPTO_USER_API_AEAD) += algif_aead.o
147obj-$(CONFIG_CRYPTO_ZSTD) += zstd.o 147obj-$(CONFIG_CRYPTO_ZSTD) += zstd.o
148obj-$(CONFIG_CRYPTO_OFB) += ofb.o 148obj-$(CONFIG_CRYPTO_OFB) += ofb.o
149obj-$(CONFIG_CRYPTO_ECC) += ecc.o 149obj-$(CONFIG_CRYPTO_ECC) += ecc.o
150obj-$(CONFIG_CRYPTO_ESSIV) += essiv.o
150 151
151ecdh_generic-y += ecdh.o 152ecdh_generic-y += ecdh.o
152ecdh_generic-y += ecdh_helper.o 153ecdh_generic-y += ecdh_helper.o
diff --git a/crypto/essiv.c b/crypto/essiv.c
new file mode 100644
index 000000000000..a8befc8fb06e
--- /dev/null
+++ b/crypto/essiv.c
@@ -0,0 +1,663 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * ESSIV skcipher and aead template for block encryption
4 *
5 * This template encapsulates the ESSIV IV generation algorithm used by
6 * dm-crypt and fscrypt, which converts the initial vector for the skcipher
7 * used for block encryption, by encrypting it using the hash of the
8 * skcipher key as encryption key. Usually, the input IV is a 64-bit sector
9 * number in LE representation zero-padded to the size of the IV, but this
10 * is not assumed by this driver.
11 *
12 * The typical use of this template is to instantiate the skcipher
13 * 'essiv(cbc(aes),sha256)', which is the only instantiation used by
14 * fscrypt, and the most relevant one for dm-crypt. However, dm-crypt
15 * also permits ESSIV to be used in combination with the authenc template,
16 * e.g., 'essiv(authenc(hmac(sha256),cbc(aes)),sha256)', in which case
17 * we need to instantiate an aead that accepts the same special key format
18 * as the authenc template, and deals with the way the encrypted IV is
19 * embedded into the AAD area of the aead request. This means the AEAD
20 * flavor produced by this template is tightly coupled to the way dm-crypt
21 * happens to use it.
22 *
23 * Copyright (c) 2019 Linaro, Ltd. <ard.biesheuvel@linaro.org>
24 *
25 * Heavily based on:
26 * adiantum length-preserving encryption mode
27 *
28 * Copyright 2018 Google LLC
29 */
30
31#include <crypto/authenc.h>
32#include <crypto/internal/aead.h>
33#include <crypto/internal/hash.h>
34#include <crypto/internal/skcipher.h>
35#include <crypto/scatterwalk.h>
36#include <linux/module.h>
37
38#include "internal.h"
39
40struct essiv_instance_ctx {
41 union {
42 struct crypto_skcipher_spawn skcipher_spawn;
43 struct crypto_aead_spawn aead_spawn;
44 } u;
45 char essiv_cipher_name[CRYPTO_MAX_ALG_NAME];
46 char shash_driver_name[CRYPTO_MAX_ALG_NAME];
47};
48
49struct essiv_tfm_ctx {
50 union {
51 struct crypto_skcipher *skcipher;
52 struct crypto_aead *aead;
53 } u;
54 struct crypto_cipher *essiv_cipher;
55 struct crypto_shash *hash;
56 int ivoffset;
57};
58
59struct essiv_aead_request_ctx {
60 struct scatterlist sg[4];
61 u8 *assoc;
62 struct aead_request aead_req;
63};
64
65static int essiv_skcipher_setkey(struct crypto_skcipher *tfm,
66 const u8 *key, unsigned int keylen)
67{
68 struct essiv_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
69 SHASH_DESC_ON_STACK(desc, tctx->hash);
70 u8 salt[HASH_MAX_DIGESTSIZE];
71 int err;
72
73 crypto_skcipher_clear_flags(tctx->u.skcipher, CRYPTO_TFM_REQ_MASK);
74 crypto_skcipher_set_flags(tctx->u.skcipher,
75 crypto_skcipher_get_flags(tfm) &
76 CRYPTO_TFM_REQ_MASK);
77 err = crypto_skcipher_setkey(tctx->u.skcipher, key, keylen);
78 crypto_skcipher_set_flags(tfm,
79 crypto_skcipher_get_flags(tctx->u.skcipher) &
80 CRYPTO_TFM_RES_MASK);
81 if (err)
82 return err;
83
84 desc->tfm = tctx->hash;
85 err = crypto_shash_digest(desc, key, keylen, salt);
86 if (err)
87 return err;
88
89 crypto_cipher_clear_flags(tctx->essiv_cipher, CRYPTO_TFM_REQ_MASK);
90 crypto_cipher_set_flags(tctx->essiv_cipher,
91 crypto_skcipher_get_flags(tfm) &
92 CRYPTO_TFM_REQ_MASK);
93 err = crypto_cipher_setkey(tctx->essiv_cipher, salt,
94 crypto_shash_digestsize(tctx->hash));
95 crypto_skcipher_set_flags(tfm,
96 crypto_cipher_get_flags(tctx->essiv_cipher) &
97 CRYPTO_TFM_RES_MASK);
98
99 return err;
100}
101
102static int essiv_aead_setkey(struct crypto_aead *tfm, const u8 *key,
103 unsigned int keylen)
104{
105 struct essiv_tfm_ctx *tctx = crypto_aead_ctx(tfm);
106 SHASH_DESC_ON_STACK(desc, tctx->hash);
107 struct crypto_authenc_keys keys;
108 u8 salt[HASH_MAX_DIGESTSIZE];
109 int err;
110
111 crypto_aead_clear_flags(tctx->u.aead, CRYPTO_TFM_REQ_MASK);
112 crypto_aead_set_flags(tctx->u.aead, crypto_aead_get_flags(tfm) &
113 CRYPTO_TFM_REQ_MASK);
114 err = crypto_aead_setkey(tctx->u.aead, key, keylen);
115 crypto_aead_set_flags(tfm, crypto_aead_get_flags(tctx->u.aead) &
116 CRYPTO_TFM_RES_MASK);
117 if (err)
118 return err;
119
120 if (crypto_authenc_extractkeys(&keys, key, keylen) != 0) {
121 crypto_aead_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
122 return -EINVAL;
123 }
124
125 desc->tfm = tctx->hash;
126 err = crypto_shash_init(desc) ?:
127 crypto_shash_update(desc, keys.enckey, keys.enckeylen) ?:
128 crypto_shash_finup(desc, keys.authkey, keys.authkeylen, salt);
129 if (err)
130 return err;
131
132 crypto_cipher_clear_flags(tctx->essiv_cipher, CRYPTO_TFM_REQ_MASK);
133 crypto_cipher_set_flags(tctx->essiv_cipher, crypto_aead_get_flags(tfm) &
134 CRYPTO_TFM_REQ_MASK);
135 err = crypto_cipher_setkey(tctx->essiv_cipher, salt,
136 crypto_shash_digestsize(tctx->hash));
137 crypto_aead_set_flags(tfm, crypto_cipher_get_flags(tctx->essiv_cipher) &
138 CRYPTO_TFM_RES_MASK);
139
140 return err;
141}
142
143static int essiv_aead_setauthsize(struct crypto_aead *tfm,
144 unsigned int authsize)
145{
146 struct essiv_tfm_ctx *tctx = crypto_aead_ctx(tfm);
147
148 return crypto_aead_setauthsize(tctx->u.aead, authsize);
149}
150
151static void essiv_skcipher_done(struct crypto_async_request *areq, int err)
152{
153 struct skcipher_request *req = areq->data;
154
155 skcipher_request_complete(req, err);
156}
157
158static int essiv_skcipher_crypt(struct skcipher_request *req, bool enc)
159{
160 struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
161 const struct essiv_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
162 struct skcipher_request *subreq = skcipher_request_ctx(req);
163
164 crypto_cipher_encrypt_one(tctx->essiv_cipher, req->iv, req->iv);
165
166 skcipher_request_set_tfm(subreq, tctx->u.skcipher);
167 skcipher_request_set_crypt(subreq, req->src, req->dst, req->cryptlen,
168 req->iv);
169 skcipher_request_set_callback(subreq, skcipher_request_flags(req),
170 essiv_skcipher_done, req);
171
172 return enc ? crypto_skcipher_encrypt(subreq) :
173 crypto_skcipher_decrypt(subreq);
174}
175
176static int essiv_skcipher_encrypt(struct skcipher_request *req)
177{
178 return essiv_skcipher_crypt(req, true);
179}
180
181static int essiv_skcipher_decrypt(struct skcipher_request *req)
182{
183 return essiv_skcipher_crypt(req, false);
184}
185
186static void essiv_aead_done(struct crypto_async_request *areq, int err)
187{
188 struct aead_request *req = areq->data;
189 struct essiv_aead_request_ctx *rctx = aead_request_ctx(req);
190
191 if (rctx->assoc)
192 kfree(rctx->assoc);
193 aead_request_complete(req, err);
194}
195
196static int essiv_aead_crypt(struct aead_request *req, bool enc)
197{
198 struct crypto_aead *tfm = crypto_aead_reqtfm(req);
199 const struct essiv_tfm_ctx *tctx = crypto_aead_ctx(tfm);
200 struct essiv_aead_request_ctx *rctx = aead_request_ctx(req);
201 struct aead_request *subreq = &rctx->aead_req;
202 struct scatterlist *src = req->src;
203 int err;
204
205 crypto_cipher_encrypt_one(tctx->essiv_cipher, req->iv, req->iv);
206
207 /*
208 * dm-crypt embeds the sector number and the IV in the AAD region, so
209 * we have to copy the converted IV into the right scatterlist before
210 * we pass it on.
211 */
212 rctx->assoc = NULL;
213 if (req->src == req->dst || !enc) {
214 scatterwalk_map_and_copy(req->iv, req->dst,
215 req->assoclen - crypto_aead_ivsize(tfm),
216 crypto_aead_ivsize(tfm), 1);
217 } else {
218 u8 *iv = (u8 *)aead_request_ctx(req) + tctx->ivoffset;
219 int ivsize = crypto_aead_ivsize(tfm);
220 int ssize = req->assoclen - ivsize;
221 struct scatterlist *sg;
222 int nents;
223
224 if (ssize < 0)
225 return -EINVAL;
226
227 nents = sg_nents_for_len(req->src, ssize);
228 if (nents < 0)
229 return -EINVAL;
230
231 memcpy(iv, req->iv, ivsize);
232 sg_init_table(rctx->sg, 4);
233
234 if (unlikely(nents > 1)) {
235 /*
236 * This is a case that rarely occurs in practice, but
237 * for correctness, we have to deal with it nonetheless.
238 */
239 rctx->assoc = kmalloc(ssize, GFP_ATOMIC);
240 if (!rctx->assoc)
241 return -ENOMEM;
242
243 scatterwalk_map_and_copy(rctx->assoc, req->src, 0,
244 ssize, 0);
245 sg_set_buf(rctx->sg, rctx->assoc, ssize);
246 } else {
247 sg_set_page(rctx->sg, sg_page(req->src), ssize,
248 req->src->offset);
249 }
250
251 sg_set_buf(rctx->sg + 1, iv, ivsize);
252 sg = scatterwalk_ffwd(rctx->sg + 2, req->src, req->assoclen);
253 if (sg != rctx->sg + 2)
254 sg_chain(rctx->sg, 3, sg);
255
256 src = rctx->sg;
257 }
258
259 aead_request_set_tfm(subreq, tctx->u.aead);
260 aead_request_set_ad(subreq, req->assoclen);
261 aead_request_set_callback(subreq, aead_request_flags(req),
262 essiv_aead_done, req);
263 aead_request_set_crypt(subreq, src, req->dst, req->cryptlen, req->iv);
264
265 err = enc ? crypto_aead_encrypt(subreq) :
266 crypto_aead_decrypt(subreq);
267
268 if (rctx->assoc && err != -EINPROGRESS)
269 kfree(rctx->assoc);
270 return err;
271}
272
273static int essiv_aead_encrypt(struct aead_request *req)
274{
275 return essiv_aead_crypt(req, true);
276}
277
278static int essiv_aead_decrypt(struct aead_request *req)
279{
280 return essiv_aead_crypt(req, false);
281}
282
283static int essiv_init_tfm(struct essiv_instance_ctx *ictx,
284 struct essiv_tfm_ctx *tctx)
285{
286 struct crypto_cipher *essiv_cipher;
287 struct crypto_shash *hash;
288 int err;
289
290 essiv_cipher = crypto_alloc_cipher(ictx->essiv_cipher_name, 0, 0);
291 if (IS_ERR(essiv_cipher))
292 return PTR_ERR(essiv_cipher);
293
294 hash = crypto_alloc_shash(ictx->shash_driver_name, 0, 0);
295 if (IS_ERR(hash)) {
296 err = PTR_ERR(hash);
297 goto err_free_essiv_cipher;
298 }
299
300 tctx->essiv_cipher = essiv_cipher;
301 tctx->hash = hash;
302
303 return 0;
304
305err_free_essiv_cipher:
306 crypto_free_cipher(essiv_cipher);
307 return err;
308}
309
310static int essiv_skcipher_init_tfm(struct crypto_skcipher *tfm)
311{
312 struct skcipher_instance *inst = skcipher_alg_instance(tfm);
313 struct essiv_instance_ctx *ictx = skcipher_instance_ctx(inst);
314 struct essiv_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
315 struct crypto_skcipher *skcipher;
316 int err;
317
318 skcipher = crypto_spawn_skcipher(&ictx->u.skcipher_spawn);
319 if (IS_ERR(skcipher))
320 return PTR_ERR(skcipher);
321
322 crypto_skcipher_set_reqsize(tfm, sizeof(struct skcipher_request) +
323 crypto_skcipher_reqsize(skcipher));
324
325 err = essiv_init_tfm(ictx, tctx);
326 if (err) {
327 crypto_free_skcipher(skcipher);
328 return err;
329 }
330
331 tctx->u.skcipher = skcipher;
332 return 0;
333}
334
335static int essiv_aead_init_tfm(struct crypto_aead *tfm)
336{
337 struct aead_instance *inst = aead_alg_instance(tfm);
338 struct essiv_instance_ctx *ictx = aead_instance_ctx(inst);
339 struct essiv_tfm_ctx *tctx = crypto_aead_ctx(tfm);
340 struct crypto_aead *aead;
341 unsigned int subreq_size;
342 int err;
343
344 BUILD_BUG_ON(offsetofend(struct essiv_aead_request_ctx, aead_req) !=
345 sizeof(struct essiv_aead_request_ctx));
346
347 aead = crypto_spawn_aead(&ictx->u.aead_spawn);
348 if (IS_ERR(aead))
349 return PTR_ERR(aead);
350
351 subreq_size = FIELD_SIZEOF(struct essiv_aead_request_ctx, aead_req) +
352 crypto_aead_reqsize(aead);
353
354 tctx->ivoffset = offsetof(struct essiv_aead_request_ctx, aead_req) +
355 subreq_size;
356 crypto_aead_set_reqsize(tfm, tctx->ivoffset + crypto_aead_ivsize(aead));
357
358 err = essiv_init_tfm(ictx, tctx);
359 if (err) {
360 crypto_free_aead(aead);
361 return err;
362 }
363
364 tctx->u.aead = aead;
365 return 0;
366}
367
368static void essiv_skcipher_exit_tfm(struct crypto_skcipher *tfm)
369{
370 struct essiv_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
371
372 crypto_free_skcipher(tctx->u.skcipher);
373 crypto_free_cipher(tctx->essiv_cipher);
374 crypto_free_shash(tctx->hash);
375}
376
377static void essiv_aead_exit_tfm(struct crypto_aead *tfm)
378{
379 struct essiv_tfm_ctx *tctx = crypto_aead_ctx(tfm);
380
381 crypto_free_aead(tctx->u.aead);
382 crypto_free_cipher(tctx->essiv_cipher);
383 crypto_free_shash(tctx->hash);
384}
385
386static void essiv_skcipher_free_instance(struct skcipher_instance *inst)
387{
388 struct essiv_instance_ctx *ictx = skcipher_instance_ctx(inst);
389
390 crypto_drop_skcipher(&ictx->u.skcipher_spawn);
391 kfree(inst);
392}
393
394static void essiv_aead_free_instance(struct aead_instance *inst)
395{
396 struct essiv_instance_ctx *ictx = aead_instance_ctx(inst);
397
398 crypto_drop_aead(&ictx->u.aead_spawn);
399 kfree(inst);
400}
401
402static bool parse_cipher_name(char *essiv_cipher_name, const char *cra_name)
403{
404 const char *p, *q;
405 int len;
406
407 /* find the last opening parens */
408 p = strrchr(cra_name, '(');
409 if (!p++)
410 return false;
411
412 /* find the first closing parens in the tail of the string */
413 q = strchr(p, ')');
414 if (!q)
415 return false;
416
417 len = q - p;
418 if (len >= CRYPTO_MAX_ALG_NAME)
419 return false;
420
421 memcpy(essiv_cipher_name, p, len);
422 essiv_cipher_name[len] = '\0';
423 return true;
424}
425
426static bool essiv_supported_algorithms(const char *essiv_cipher_name,
427 struct shash_alg *hash_alg,
428 int ivsize)
429{
430 struct crypto_alg *alg;
431 bool ret = false;
432
433 alg = crypto_alg_mod_lookup(essiv_cipher_name,
434 CRYPTO_ALG_TYPE_CIPHER,
435 CRYPTO_ALG_TYPE_MASK);
436 if (IS_ERR(alg))
437 return false;
438
439 if (hash_alg->digestsize < alg->cra_cipher.cia_min_keysize ||
440 hash_alg->digestsize > alg->cra_cipher.cia_max_keysize)
441 goto out;
442
443 if (ivsize != alg->cra_blocksize)
444 goto out;
445
446 if (crypto_shash_alg_has_setkey(hash_alg))
447 goto out;
448
449 ret = true;
450
451out:
452 crypto_mod_put(alg);
453 return ret;
454}
455
456static int essiv_create(struct crypto_template *tmpl, struct rtattr **tb)
457{
458 struct crypto_attr_type *algt;
459 const char *inner_cipher_name;
460 const char *shash_name;
461 struct skcipher_instance *skcipher_inst = NULL;
462 struct aead_instance *aead_inst = NULL;
463 struct crypto_instance *inst;
464 struct crypto_alg *base, *block_base;
465 struct essiv_instance_ctx *ictx;
466 struct skcipher_alg *skcipher_alg = NULL;
467 struct aead_alg *aead_alg = NULL;
468 struct crypto_alg *_hash_alg;
469 struct shash_alg *hash_alg;
470 int ivsize;
471 u32 type;
472 int err;
473
474 algt = crypto_get_attr_type(tb);
475 if (IS_ERR(algt))
476 return PTR_ERR(algt);
477
478 inner_cipher_name = crypto_attr_alg_name(tb[1]);
479 if (IS_ERR(inner_cipher_name))
480 return PTR_ERR(inner_cipher_name);
481
482 shash_name = crypto_attr_alg_name(tb[2]);
483 if (IS_ERR(shash_name))
484 return PTR_ERR(shash_name);
485
486 type = algt->type & algt->mask;
487
488 switch (type) {
489 case CRYPTO_ALG_TYPE_BLKCIPHER:
490 skcipher_inst = kzalloc(sizeof(*skcipher_inst) +
491 sizeof(*ictx), GFP_KERNEL);
492 if (!skcipher_inst)
493 return -ENOMEM;
494 inst = skcipher_crypto_instance(skcipher_inst);
495 base = &skcipher_inst->alg.base;
496 ictx = crypto_instance_ctx(inst);
497
498 /* Symmetric cipher, e.g., "cbc(aes)" */
499 crypto_set_skcipher_spawn(&ictx->u.skcipher_spawn, inst);
500 err = crypto_grab_skcipher(&ictx->u.skcipher_spawn,
501 inner_cipher_name, 0,
502 crypto_requires_sync(algt->type,
503 algt->mask));
504 if (err)
505 goto out_free_inst;
506 skcipher_alg = crypto_spawn_skcipher_alg(&ictx->u.skcipher_spawn);
507 block_base = &skcipher_alg->base;
508 ivsize = crypto_skcipher_alg_ivsize(skcipher_alg);
509 break;
510
511 case CRYPTO_ALG_TYPE_AEAD:
512 aead_inst = kzalloc(sizeof(*aead_inst) +
513 sizeof(*ictx), GFP_KERNEL);
514 if (!aead_inst)
515 return -ENOMEM;
516 inst = aead_crypto_instance(aead_inst);
517 base = &aead_inst->alg.base;
518 ictx = crypto_instance_ctx(inst);
519
520 /* AEAD cipher, e.g., "authenc(hmac(sha256),cbc(aes))" */
521 crypto_set_aead_spawn(&ictx->u.aead_spawn, inst);
522 err = crypto_grab_aead(&ictx->u.aead_spawn,
523 inner_cipher_name, 0,
524 crypto_requires_sync(algt->type,
525 algt->mask));
526 if (err)
527 goto out_free_inst;
528 aead_alg = crypto_spawn_aead_alg(&ictx->u.aead_spawn);
529 block_base = &aead_alg->base;
530 if (!strstarts(block_base->cra_name, "authenc(")) {
531 pr_warn("Only authenc() type AEADs are supported by ESSIV\n");
532 err = -EINVAL;
533 goto out_drop_skcipher;
534 }
535 ivsize = aead_alg->ivsize;
536 break;
537
538 default:
539 return -EINVAL;
540 }
541
542 if (!parse_cipher_name(ictx->essiv_cipher_name, block_base->cra_name)) {
543 pr_warn("Failed to parse ESSIV cipher name from skcipher cra_name\n");
544 err = -EINVAL;
545 goto out_drop_skcipher;
546 }
547
548 /* Synchronous hash, e.g., "sha256" */
549 _hash_alg = crypto_alg_mod_lookup(shash_name,
550 CRYPTO_ALG_TYPE_SHASH,
551 CRYPTO_ALG_TYPE_MASK);
552 if (IS_ERR(_hash_alg)) {
553 err = PTR_ERR(_hash_alg);
554 goto out_drop_skcipher;
555 }
556 hash_alg = __crypto_shash_alg(_hash_alg);
557
558 /* Check the set of algorithms */
559 if (!essiv_supported_algorithms(ictx->essiv_cipher_name, hash_alg,
560 ivsize)) {
561 pr_warn("Unsupported essiv instantiation: essiv(%s,%s)\n",
562 block_base->cra_name, hash_alg->base.cra_name);
563 err = -EINVAL;
564 goto out_free_hash;
565 }
566
567 /* record the driver name so we can instantiate this exact algo later */
568 strlcpy(ictx->shash_driver_name, hash_alg->base.cra_driver_name,
569 CRYPTO_MAX_ALG_NAME);
570
571 /* Instance fields */
572
573 err = -ENAMETOOLONG;
574 if (snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME,
575 "essiv(%s,%s)", block_base->cra_name,
576 hash_alg->base.cra_name) >= CRYPTO_MAX_ALG_NAME)
577 goto out_free_hash;
578 if (snprintf(base->cra_driver_name, CRYPTO_MAX_ALG_NAME,
579 "essiv(%s,%s)", block_base->cra_driver_name,
580 hash_alg->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
581 goto out_free_hash;
582
583 base->cra_flags = block_base->cra_flags & CRYPTO_ALG_ASYNC;
584 base->cra_blocksize = block_base->cra_blocksize;
585 base->cra_ctxsize = sizeof(struct essiv_tfm_ctx);
586 base->cra_alignmask = block_base->cra_alignmask;
587 base->cra_priority = block_base->cra_priority;
588
589 if (type == CRYPTO_ALG_TYPE_BLKCIPHER) {
590 skcipher_inst->alg.setkey = essiv_skcipher_setkey;
591 skcipher_inst->alg.encrypt = essiv_skcipher_encrypt;
592 skcipher_inst->alg.decrypt = essiv_skcipher_decrypt;
593 skcipher_inst->alg.init = essiv_skcipher_init_tfm;
594 skcipher_inst->alg.exit = essiv_skcipher_exit_tfm;
595
596 skcipher_inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(skcipher_alg);
597 skcipher_inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(skcipher_alg);
598 skcipher_inst->alg.ivsize = ivsize;
599 skcipher_inst->alg.chunksize = crypto_skcipher_alg_chunksize(skcipher_alg);
600 skcipher_inst->alg.walksize = crypto_skcipher_alg_walksize(skcipher_alg);
601
602 skcipher_inst->free = essiv_skcipher_free_instance;
603
604 err = skcipher_register_instance(tmpl, skcipher_inst);
605 } else {
606 aead_inst->alg.setkey = essiv_aead_setkey;
607 aead_inst->alg.setauthsize = essiv_aead_setauthsize;
608 aead_inst->alg.encrypt = essiv_aead_encrypt;
609 aead_inst->alg.decrypt = essiv_aead_decrypt;
610 aead_inst->alg.init = essiv_aead_init_tfm;
611 aead_inst->alg.exit = essiv_aead_exit_tfm;
612
613 aead_inst->alg.ivsize = ivsize;
614 aead_inst->alg.maxauthsize = crypto_aead_alg_maxauthsize(aead_alg);
615 aead_inst->alg.chunksize = crypto_aead_alg_chunksize(aead_alg);
616
617 aead_inst->free = essiv_aead_free_instance;
618
619 err = aead_register_instance(tmpl, aead_inst);
620 }
621
622 if (err)
623 goto out_free_hash;
624
625 crypto_mod_put(_hash_alg);
626 return 0;
627
628out_free_hash:
629 crypto_mod_put(_hash_alg);
630out_drop_skcipher:
631 if (type == CRYPTO_ALG_TYPE_BLKCIPHER)
632 crypto_drop_skcipher(&ictx->u.skcipher_spawn);
633 else
634 crypto_drop_aead(&ictx->u.aead_spawn);
635out_free_inst:
636 kfree(skcipher_inst);
637 kfree(aead_inst);
638 return err;
639}
640
641/* essiv(cipher_name, shash_name) */
642static struct crypto_template essiv_tmpl = {
643 .name = "essiv",
644 .create = essiv_create,
645 .module = THIS_MODULE,
646};
647
648static int __init essiv_module_init(void)
649{
650 return crypto_register_template(&essiv_tmpl);
651}
652
653static void __exit essiv_module_exit(void)
654{
655 crypto_unregister_template(&essiv_tmpl);
656}
657
658subsys_initcall(essiv_module_init);
659module_exit(essiv_module_exit);
660
661MODULE_DESCRIPTION("ESSIV skcipher/aead wrapper for block encryption");
662MODULE_LICENSE("GPL v2");
663MODULE_ALIAS_CRYPTO("essiv");