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