Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-or-later
2 : : /*
3 : : * authencesn.c - AEAD wrapper for IPsec with extended sequence numbers,
4 : : * derived from authenc.c
5 : : *
6 : : * Copyright (C) 2010 secunet Security Networks AG
7 : : * Copyright (C) 2010 Steffen Klassert <steffen.klassert@secunet.com>
8 : : * Copyright (c) 2015 Herbert Xu <herbert@gondor.apana.org.au>
9 : : */
10 : :
11 : : #include <crypto/internal/aead.h>
12 : : #include <crypto/internal/hash.h>
13 : : #include <crypto/internal/skcipher.h>
14 : : #include <crypto/authenc.h>
15 : : #include <crypto/null.h>
16 : : #include <crypto/scatterwalk.h>
17 : : #include <linux/err.h>
18 : : #include <linux/init.h>
19 : : #include <linux/kernel.h>
20 : : #include <linux/module.h>
21 : : #include <linux/rtnetlink.h>
22 : : #include <linux/slab.h>
23 : : #include <linux/spinlock.h>
24 : :
25 : : struct authenc_esn_instance_ctx {
26 : : struct crypto_ahash_spawn auth;
27 : : struct crypto_skcipher_spawn enc;
28 : : };
29 : :
30 : : struct crypto_authenc_esn_ctx {
31 : : unsigned int reqoff;
32 : : struct crypto_ahash *auth;
33 : : struct crypto_skcipher *enc;
34 : : struct crypto_sync_skcipher *null;
35 : : };
36 : :
37 : : struct authenc_esn_request_ctx {
38 : : struct scatterlist src[2];
39 : : struct scatterlist dst[2];
40 : : char tail[];
41 : : };
42 : :
43 : 0 : static void authenc_esn_request_complete(struct aead_request *req, int err)
44 : : {
45 : 0 : if (err != -EINPROGRESS)
46 : 0 : aead_request_complete(req, err);
47 : : }
48 : :
49 : 0 : static int crypto_authenc_esn_setauthsize(struct crypto_aead *authenc_esn,
50 : : unsigned int authsize)
51 : : {
52 [ # # ]: 0 : if (authsize > 0 && authsize < 4)
53 : 0 : return -EINVAL;
54 : :
55 : : return 0;
56 : : }
57 : :
58 : 0 : static int crypto_authenc_esn_setkey(struct crypto_aead *authenc_esn, const u8 *key,
59 : : unsigned int keylen)
60 : : {
61 : 0 : struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
62 : 0 : struct crypto_ahash *auth = ctx->auth;
63 : 0 : struct crypto_skcipher *enc = ctx->enc;
64 : 0 : struct crypto_authenc_keys keys;
65 : 0 : int err = -EINVAL;
66 : :
67 [ # # ]: 0 : if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
68 : 0 : goto out;
69 : :
70 : 0 : crypto_ahash_clear_flags(auth, CRYPTO_TFM_REQ_MASK);
71 : 0 : crypto_ahash_set_flags(auth, crypto_aead_get_flags(authenc_esn) &
72 : : CRYPTO_TFM_REQ_MASK);
73 : 0 : err = crypto_ahash_setkey(auth, keys.authkey, keys.authkeylen);
74 [ # # ]: 0 : if (err)
75 : 0 : goto out;
76 : :
77 : 0 : crypto_skcipher_clear_flags(enc, CRYPTO_TFM_REQ_MASK);
78 : 0 : crypto_skcipher_set_flags(enc, crypto_aead_get_flags(authenc_esn) &
79 : : CRYPTO_TFM_REQ_MASK);
80 : 0 : err = crypto_skcipher_setkey(enc, keys.enckey, keys.enckeylen);
81 : 0 : out:
82 : 0 : memzero_explicit(&keys, sizeof(keys));
83 : 0 : return err;
84 : : }
85 : :
86 : : static int crypto_authenc_esn_genicv_tail(struct aead_request *req,
87 : : unsigned int flags)
88 : : {
89 : : struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
90 : : struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
91 : : struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
92 : : struct crypto_ahash *auth = ctx->auth;
93 : : u8 *hash = PTR_ALIGN((u8 *)areq_ctx->tail,
94 : : crypto_ahash_alignmask(auth) + 1);
95 : : unsigned int authsize = crypto_aead_authsize(authenc_esn);
96 : : unsigned int assoclen = req->assoclen;
97 : : unsigned int cryptlen = req->cryptlen;
98 : : struct scatterlist *dst = req->dst;
99 : : u32 tmp[2];
100 : :
101 : : /* Move high-order bits of sequence number back. */
102 : : scatterwalk_map_and_copy(tmp, dst, 4, 4, 0);
103 : : scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 0);
104 : : scatterwalk_map_and_copy(tmp, dst, 0, 8, 1);
105 : :
106 : : scatterwalk_map_and_copy(hash, dst, assoclen + cryptlen, authsize, 1);
107 : : return 0;
108 : : }
109 : :
110 : 0 : static void authenc_esn_geniv_ahash_done(struct crypto_async_request *areq,
111 : : int err)
112 : : {
113 : 0 : struct aead_request *req = areq->data;
114 : :
115 [ # # ]: 0 : err = err ?: crypto_authenc_esn_genicv_tail(req, 0);
116 : 0 : aead_request_complete(req, err);
117 : 0 : }
118 : :
119 : 0 : static int crypto_authenc_esn_genicv(struct aead_request *req,
120 : : unsigned int flags)
121 : : {
122 [ # # ]: 0 : struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
123 [ # # ]: 0 : struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
124 [ # # ]: 0 : struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
125 : 0 : struct crypto_ahash *auth = ctx->auth;
126 [ # # ]: 0 : u8 *hash = PTR_ALIGN((u8 *)areq_ctx->tail,
127 : : crypto_ahash_alignmask(auth) + 1);
128 : 0 : struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
129 [ # # ]: 0 : unsigned int authsize = crypto_aead_authsize(authenc_esn);
130 : 0 : unsigned int assoclen = req->assoclen;
131 : 0 : unsigned int cryptlen = req->cryptlen;
132 : 0 : struct scatterlist *dst = req->dst;
133 : 0 : u32 tmp[2];
134 : :
135 [ # # ]: 0 : if (!authsize)
136 : : return 0;
137 : :
138 : : /* Move high-order bits of sequence number to the end. */
139 : 0 : scatterwalk_map_and_copy(tmp, dst, 0, 8, 0);
140 : 0 : scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);
141 : 0 : scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
142 : :
143 : 0 : sg_init_table(areq_ctx->dst, 2);
144 : 0 : dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
145 : :
146 : 0 : ahash_request_set_tfm(ahreq, auth);
147 : 0 : ahash_request_set_crypt(ahreq, dst, hash, assoclen + cryptlen);
148 : 0 : ahash_request_set_callback(ahreq, flags,
149 : : authenc_esn_geniv_ahash_done, req);
150 : :
151 [ # # ]: 0 : return crypto_ahash_digest(ahreq) ?:
152 : 0 : crypto_authenc_esn_genicv_tail(req, aead_request_flags(req));
153 : : }
154 : :
155 : :
156 : 0 : static void crypto_authenc_esn_encrypt_done(struct crypto_async_request *req,
157 : : int err)
158 : : {
159 : 0 : struct aead_request *areq = req->data;
160 : :
161 [ # # ]: 0 : if (!err)
162 : 0 : err = crypto_authenc_esn_genicv(areq, 0);
163 : :
164 [ # # ]: 0 : authenc_esn_request_complete(areq, err);
165 : 0 : }
166 : :
167 : 0 : static int crypto_authenc_esn_copy(struct aead_request *req, unsigned int len)
168 : : {
169 : 0 : struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
170 : 0 : struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
171 : 0 : SYNC_SKCIPHER_REQUEST_ON_STACK(skreq, ctx->null);
172 : :
173 : 0 : skcipher_request_set_sync_tfm(skreq, ctx->null);
174 : 0 : skcipher_request_set_callback(skreq, aead_request_flags(req),
175 : : NULL, NULL);
176 : 0 : skcipher_request_set_crypt(skreq, req->src, req->dst, len, NULL);
177 : :
178 : 0 : return crypto_skcipher_encrypt(skreq);
179 : : }
180 : :
181 : 0 : static int crypto_authenc_esn_encrypt(struct aead_request *req)
182 : : {
183 : 0 : struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
184 : 0 : struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
185 : 0 : struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
186 : 0 : struct skcipher_request *skreq = (void *)(areq_ctx->tail +
187 : 0 : ctx->reqoff);
188 : 0 : struct crypto_skcipher *enc = ctx->enc;
189 : 0 : unsigned int assoclen = req->assoclen;
190 : 0 : unsigned int cryptlen = req->cryptlen;
191 : 0 : struct scatterlist *src, *dst;
192 : 0 : int err;
193 : :
194 : 0 : sg_init_table(areq_ctx->src, 2);
195 : 0 : src = scatterwalk_ffwd(areq_ctx->src, req->src, assoclen);
196 : 0 : dst = src;
197 : :
198 [ # # ]: 0 : if (req->src != req->dst) {
199 : 0 : err = crypto_authenc_esn_copy(req, assoclen);
200 [ # # ]: 0 : if (err)
201 : : return err;
202 : :
203 : 0 : sg_init_table(areq_ctx->dst, 2);
204 : 0 : dst = scatterwalk_ffwd(areq_ctx->dst, req->dst, assoclen);
205 : : }
206 : :
207 : 0 : skcipher_request_set_tfm(skreq, enc);
208 : 0 : skcipher_request_set_callback(skreq, aead_request_flags(req),
209 : : crypto_authenc_esn_encrypt_done, req);
210 : 0 : skcipher_request_set_crypt(skreq, src, dst, cryptlen, req->iv);
211 : :
212 : 0 : err = crypto_skcipher_encrypt(skreq);
213 [ # # ]: 0 : if (err)
214 : : return err;
215 : :
216 : 0 : return crypto_authenc_esn_genicv(req, aead_request_flags(req));
217 : : }
218 : :
219 : 0 : static int crypto_authenc_esn_decrypt_tail(struct aead_request *req,
220 : : unsigned int flags)
221 : : {
222 [ # # ]: 0 : struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
223 [ # # ]: 0 : unsigned int authsize = crypto_aead_authsize(authenc_esn);
224 [ # # ]: 0 : struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
225 [ # # ]: 0 : struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
226 : 0 : struct skcipher_request *skreq = (void *)(areq_ctx->tail +
227 : 0 : ctx->reqoff);
228 : 0 : struct crypto_ahash *auth = ctx->auth;
229 [ # # ]: 0 : u8 *ohash = PTR_ALIGN((u8 *)areq_ctx->tail,
230 : : crypto_ahash_alignmask(auth) + 1);
231 : 0 : unsigned int cryptlen = req->cryptlen - authsize;
232 : 0 : unsigned int assoclen = req->assoclen;
233 : 0 : struct scatterlist *dst = req->dst;
234 [ # # ]: 0 : u8 *ihash = ohash + crypto_ahash_digestsize(auth);
235 : 0 : u32 tmp[2];
236 : :
237 [ # # ]: 0 : if (!authsize)
238 : 0 : goto decrypt;
239 : :
240 : : /* Move high-order bits of sequence number back. */
241 : 0 : scatterwalk_map_and_copy(tmp, dst, 4, 4, 0);
242 : 0 : scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 0);
243 : 0 : scatterwalk_map_and_copy(tmp, dst, 0, 8, 1);
244 : :
245 [ # # ]: 0 : if (crypto_memneq(ihash, ohash, authsize))
246 : : return -EBADMSG;
247 : :
248 : 0 : decrypt:
249 : :
250 : 0 : sg_init_table(areq_ctx->dst, 2);
251 : 0 : dst = scatterwalk_ffwd(areq_ctx->dst, dst, assoclen);
252 : :
253 : 0 : skcipher_request_set_tfm(skreq, ctx->enc);
254 : 0 : skcipher_request_set_callback(skreq, flags,
255 : : req->base.complete, req->base.data);
256 : 0 : skcipher_request_set_crypt(skreq, dst, dst, cryptlen, req->iv);
257 : :
258 : 0 : return crypto_skcipher_decrypt(skreq);
259 : : }
260 : :
261 : 0 : static void authenc_esn_verify_ahash_done(struct crypto_async_request *areq,
262 : : int err)
263 : : {
264 : 0 : struct aead_request *req = areq->data;
265 : :
266 [ # # ]: 0 : err = err ?: crypto_authenc_esn_decrypt_tail(req, 0);
267 [ # # ]: 0 : authenc_esn_request_complete(req, err);
268 : 0 : }
269 : :
270 : 0 : static int crypto_authenc_esn_decrypt(struct aead_request *req)
271 : : {
272 [ # # ]: 0 : struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
273 [ # # ]: 0 : struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
274 [ # # ]: 0 : struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
275 : 0 : struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
276 [ # # ]: 0 : unsigned int authsize = crypto_aead_authsize(authenc_esn);
277 : 0 : struct crypto_ahash *auth = ctx->auth;
278 [ # # ]: 0 : u8 *ohash = PTR_ALIGN((u8 *)areq_ctx->tail,
279 : : crypto_ahash_alignmask(auth) + 1);
280 : 0 : unsigned int assoclen = req->assoclen;
281 : 0 : unsigned int cryptlen = req->cryptlen;
282 [ # # ]: 0 : u8 *ihash = ohash + crypto_ahash_digestsize(auth);
283 : 0 : struct scatterlist *dst = req->dst;
284 : 0 : u32 tmp[2];
285 : 0 : int err;
286 : :
287 : 0 : cryptlen -= authsize;
288 : :
289 [ # # ]: 0 : if (req->src != dst) {
290 : 0 : err = crypto_authenc_esn_copy(req, assoclen + cryptlen);
291 [ # # ]: 0 : if (err)
292 : : return err;
293 : : }
294 : :
295 : 0 : scatterwalk_map_and_copy(ihash, req->src, assoclen + cryptlen,
296 : : authsize, 0);
297 : :
298 [ # # ]: 0 : if (!authsize)
299 : 0 : goto tail;
300 : :
301 : : /* Move high-order bits of sequence number to the end. */
302 : 0 : scatterwalk_map_and_copy(tmp, dst, 0, 8, 0);
303 : 0 : scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);
304 : 0 : scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
305 : :
306 : 0 : sg_init_table(areq_ctx->dst, 2);
307 : 0 : dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
308 : :
309 : 0 : ahash_request_set_tfm(ahreq, auth);
310 : 0 : ahash_request_set_crypt(ahreq, dst, ohash, assoclen + cryptlen);
311 : 0 : ahash_request_set_callback(ahreq, aead_request_flags(req),
312 : : authenc_esn_verify_ahash_done, req);
313 : :
314 : 0 : err = crypto_ahash_digest(ahreq);
315 [ # # ]: 0 : if (err)
316 : : return err;
317 : :
318 : 0 : tail:
319 : 0 : return crypto_authenc_esn_decrypt_tail(req, aead_request_flags(req));
320 : : }
321 : :
322 : 0 : static int crypto_authenc_esn_init_tfm(struct crypto_aead *tfm)
323 : : {
324 : 0 : struct aead_instance *inst = aead_alg_instance(tfm);
325 : 0 : struct authenc_esn_instance_ctx *ictx = aead_instance_ctx(inst);
326 : 0 : struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(tfm);
327 : 0 : struct crypto_ahash *auth;
328 : 0 : struct crypto_skcipher *enc;
329 : 0 : struct crypto_sync_skcipher *null;
330 : 0 : int err;
331 : :
332 : 0 : auth = crypto_spawn_ahash(&ictx->auth);
333 [ # # ]: 0 : if (IS_ERR(auth))
334 : 0 : return PTR_ERR(auth);
335 : :
336 : 0 : enc = crypto_spawn_skcipher(&ictx->enc);
337 [ # # ]: 0 : err = PTR_ERR(enc);
338 [ # # ]: 0 : if (IS_ERR(enc))
339 : 0 : goto err_free_ahash;
340 : :
341 : 0 : null = crypto_get_default_null_skcipher();
342 [ # # ]: 0 : err = PTR_ERR(null);
343 [ # # ]: 0 : if (IS_ERR(null))
344 : 0 : goto err_free_skcipher;
345 : :
346 : 0 : ctx->auth = auth;
347 : 0 : ctx->enc = enc;
348 : 0 : ctx->null = null;
349 : :
350 : 0 : ctx->reqoff = ALIGN(2 * crypto_ahash_digestsize(auth),
351 : : crypto_ahash_alignmask(auth) + 1);
352 : :
353 : 0 : crypto_aead_set_reqsize(
354 : : tfm,
355 : : sizeof(struct authenc_esn_request_ctx) +
356 : 0 : ctx->reqoff +
357 : 0 : max_t(unsigned int,
358 : : crypto_ahash_reqsize(auth) +
359 : : sizeof(struct ahash_request),
360 : : sizeof(struct skcipher_request) +
361 : : crypto_skcipher_reqsize(enc)));
362 : :
363 : 0 : return 0;
364 : :
365 : : err_free_skcipher:
366 : 0 : crypto_free_skcipher(enc);
367 : 0 : err_free_ahash:
368 : 0 : crypto_free_ahash(auth);
369 : 0 : return err;
370 : : }
371 : :
372 : 0 : static void crypto_authenc_esn_exit_tfm(struct crypto_aead *tfm)
373 : : {
374 : 0 : struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(tfm);
375 : :
376 : 0 : crypto_free_ahash(ctx->auth);
377 : 0 : crypto_free_skcipher(ctx->enc);
378 : 0 : crypto_put_default_null_skcipher();
379 : 0 : }
380 : :
381 : 0 : static void crypto_authenc_esn_free(struct aead_instance *inst)
382 : : {
383 : 0 : struct authenc_esn_instance_ctx *ctx = aead_instance_ctx(inst);
384 : :
385 : 0 : crypto_drop_skcipher(&ctx->enc);
386 : 0 : crypto_drop_ahash(&ctx->auth);
387 : 0 : kfree(inst);
388 : 0 : }
389 : :
390 : 0 : static int crypto_authenc_esn_create(struct crypto_template *tmpl,
391 : : struct rtattr **tb)
392 : : {
393 : 0 : struct crypto_attr_type *algt;
394 : 0 : u32 mask;
395 : 0 : struct aead_instance *inst;
396 : 0 : struct authenc_esn_instance_ctx *ctx;
397 : 0 : struct hash_alg_common *auth;
398 : 0 : struct crypto_alg *auth_base;
399 : 0 : struct skcipher_alg *enc;
400 : 0 : int err;
401 : :
402 : 0 : algt = crypto_get_attr_type(tb);
403 [ # # ]: 0 : if (IS_ERR(algt))
404 : 0 : return PTR_ERR(algt);
405 : :
406 [ # # ]: 0 : if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
407 : : return -EINVAL;
408 : :
409 : 0 : mask = crypto_requires_sync(algt->type, algt->mask);
410 : :
411 : 0 : inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
412 [ # # ]: 0 : if (!inst)
413 : : return -ENOMEM;
414 : 0 : ctx = aead_instance_ctx(inst);
415 : :
416 : 0 : err = crypto_grab_ahash(&ctx->auth, aead_crypto_instance(inst),
417 : : crypto_attr_alg_name(tb[1]), 0, mask);
418 [ # # ]: 0 : if (err)
419 : 0 : goto err_free_inst;
420 : 0 : auth = crypto_spawn_ahash_alg(&ctx->auth);
421 : 0 : auth_base = &auth->base;
422 : :
423 : 0 : err = crypto_grab_skcipher(&ctx->enc, aead_crypto_instance(inst),
424 : : crypto_attr_alg_name(tb[2]), 0, mask);
425 [ # # ]: 0 : if (err)
426 : 0 : goto err_free_inst;
427 [ # # ]: 0 : enc = crypto_spawn_skcipher_alg(&ctx->enc);
428 : :
429 : 0 : err = -ENAMETOOLONG;
430 : 0 : if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
431 : 0 : "authencesn(%s,%s)", auth_base->cra_name,
432 [ # # ]: 0 : enc->base.cra_name) >= CRYPTO_MAX_ALG_NAME)
433 : 0 : goto err_free_inst;
434 : :
435 : 0 : if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
436 : 0 : "authencesn(%s,%s)", auth_base->cra_driver_name,
437 [ # # ]: 0 : enc->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
438 : 0 : goto err_free_inst;
439 : :
440 : 0 : inst->alg.base.cra_flags = (auth_base->cra_flags |
441 : 0 : enc->base.cra_flags) & CRYPTO_ALG_ASYNC;
442 : 0 : inst->alg.base.cra_priority = enc->base.cra_priority * 10 +
443 : 0 : auth_base->cra_priority;
444 : 0 : inst->alg.base.cra_blocksize = enc->base.cra_blocksize;
445 : 0 : inst->alg.base.cra_alignmask = auth_base->cra_alignmask |
446 : 0 : enc->base.cra_alignmask;
447 : 0 : inst->alg.base.cra_ctxsize = sizeof(struct crypto_authenc_esn_ctx);
448 : :
449 : 0 : inst->alg.ivsize = crypto_skcipher_alg_ivsize(enc);
450 : 0 : inst->alg.chunksize = crypto_skcipher_alg_chunksize(enc);
451 : 0 : inst->alg.maxauthsize = auth->digestsize;
452 : :
453 : 0 : inst->alg.init = crypto_authenc_esn_init_tfm;
454 : 0 : inst->alg.exit = crypto_authenc_esn_exit_tfm;
455 : :
456 : 0 : inst->alg.setkey = crypto_authenc_esn_setkey;
457 : 0 : inst->alg.setauthsize = crypto_authenc_esn_setauthsize;
458 : 0 : inst->alg.encrypt = crypto_authenc_esn_encrypt;
459 : 0 : inst->alg.decrypt = crypto_authenc_esn_decrypt;
460 : :
461 : 0 : inst->free = crypto_authenc_esn_free,
462 : :
463 : 0 : err = aead_register_instance(tmpl, inst);
464 [ # # ]: 0 : if (err) {
465 : 0 : err_free_inst:
466 : 0 : crypto_authenc_esn_free(inst);
467 : : }
468 : : return err;
469 : : }
470 : :
471 : : static struct crypto_template crypto_authenc_esn_tmpl = {
472 : : .name = "authencesn",
473 : : .create = crypto_authenc_esn_create,
474 : : .module = THIS_MODULE,
475 : : };
476 : :
477 : 30 : static int __init crypto_authenc_esn_module_init(void)
478 : : {
479 : 30 : return crypto_register_template(&crypto_authenc_esn_tmpl);
480 : : }
481 : :
482 : 0 : static void __exit crypto_authenc_esn_module_exit(void)
483 : : {
484 : 0 : crypto_unregister_template(&crypto_authenc_esn_tmpl);
485 : 0 : }
486 : :
487 : : subsys_initcall(crypto_authenc_esn_module_init);
488 : : module_exit(crypto_authenc_esn_module_exit);
489 : :
490 : : MODULE_LICENSE("GPL");
491 : : MODULE_AUTHOR("Steffen Klassert <steffen.klassert@secunet.com>");
492 : : MODULE_DESCRIPTION("AEAD wrapper for IPsec with extended sequence numbers");
493 : : MODULE_ALIAS_CRYPTO("authencesn");
|