gcm.c 32.1 KB
Newer Older
M
Mikko Herranen 已提交
1 2 3 4 5 6 7 8 9 10 11
/*
 * GCM: Galois/Counter Mode.
 *
 * Copyright (c) 2007 Nokia Siemens Networks - Mikko Herranen <mh1@iki.fi>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 */

#include <crypto/gf128mul.h>
H
Herbert Xu 已提交
12
#include <crypto/internal/aead.h>
13
#include <crypto/internal/skcipher.h>
14
#include <crypto/internal/hash.h>
15
#include <crypto/null.h>
16
#include <crypto/scatterwalk.h>
17 18
#include <crypto/hash.h>
#include "internal.h"
19
#include <linux/completion.h>
M
Mikko Herranen 已提交
20 21 22 23 24 25 26
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>

struct gcm_instance_ctx {
27
	struct crypto_skcipher_spawn ctr;
28
	struct crypto_ahash_spawn ghash;
M
Mikko Herranen 已提交
29 30 31 32
};

struct crypto_gcm_ctx {
	struct crypto_ablkcipher *ctr;
33
	struct crypto_ahash *ghash;
M
Mikko Herranen 已提交
34 35
};

H
Herbert Xu 已提交
36 37 38 39 40
struct crypto_rfc4106_ctx {
	struct crypto_aead *child;
	u8 nonce[4];
};

41 42 43 44
struct crypto_rfc4543_instance_ctx {
	struct crypto_aead_spawn aead;
};

45 46
struct crypto_rfc4543_ctx {
	struct crypto_aead *child;
47
	struct crypto_blkcipher *null;
48 49 50 51 52 53 54
	u8 nonce[4];
};

struct crypto_rfc4543_req_ctx {
	struct aead_request subreq;
};

M
Mikko Herranen 已提交
55
struct crypto_gcm_ghash_ctx {
56 57
	unsigned int cryptlen;
	struct scatterlist *src;
58
	int (*complete)(struct aead_request *req, u32 flags);
M
Mikko Herranen 已提交
59 60 61
};

struct crypto_gcm_req_priv_ctx {
62
	u8 iv[16];
M
Mikko Herranen 已提交
63
	u8 auth_tag[16];
H
Herbert Xu 已提交
64
	u8 iauth_tag[16];
65 66 67
	struct scatterlist src[3];
	struct scatterlist dst[3];
	struct scatterlist sg;
68 69 70 71 72
	struct crypto_gcm_ghash_ctx ghash_ctx;
	union {
		struct ahash_request ahreq;
		struct ablkcipher_request abreq;
	} u;
M
Mikko Herranen 已提交
73 74
};

75 76 77 78 79
struct crypto_gcm_setkey_result {
	int err;
	struct completion completion;
};

80 81 82 83 84 85
static struct {
	u8 buf[16];
	struct scatterlist sg;
} *gcm_zeroes;

static int crypto_rfc4543_copy_src_to_dst(struct aead_request *req, bool enc);
86

87 88 89 90 91 92 93 94
static inline struct crypto_gcm_req_priv_ctx *crypto_gcm_reqctx(
	struct aead_request *req)
{
	unsigned long align = crypto_aead_alignmask(crypto_aead_reqtfm(req));

	return (void *)PTR_ALIGN((u8 *)aead_request_ctx(req), align + 1);
}

95
static void crypto_gcm_setkey_done(struct crypto_async_request *req, int err)
M
Mikko Herranen 已提交
96
{
97
	struct crypto_gcm_setkey_result *result = req->data;
M
Mikko Herranen 已提交
98

99 100 101 102 103
	if (err == -EINPROGRESS)
		return;

	result->err = err;
	complete(&result->completion);
M
Mikko Herranen 已提交
104 105 106 107 108 109
}

static int crypto_gcm_setkey(struct crypto_aead *aead, const u8 *key,
			     unsigned int keylen)
{
	struct crypto_gcm_ctx *ctx = crypto_aead_ctx(aead);
110
	struct crypto_ahash *ghash = ctx->ghash;
M
Mikko Herranen 已提交
111
	struct crypto_ablkcipher *ctr = ctx->ctr;
112 113 114 115 116 117 118 119 120 121
	struct {
		be128 hash;
		u8 iv[8];

		struct crypto_gcm_setkey_result result;

		struct scatterlist sg[1];
		struct ablkcipher_request req;
	} *data;
	int err;
M
Mikko Herranen 已提交
122 123 124

	crypto_ablkcipher_clear_flags(ctr, CRYPTO_TFM_REQ_MASK);
	crypto_ablkcipher_set_flags(ctr, crypto_aead_get_flags(aead) &
125
					 CRYPTO_TFM_REQ_MASK);
M
Mikko Herranen 已提交
126
	err = crypto_ablkcipher_setkey(ctr, key, keylen);
127 128
	crypto_aead_set_flags(aead, crypto_ablkcipher_get_flags(ctr) &
				    CRYPTO_TFM_RES_MASK);
M
Mikko Herranen 已提交
129
	if (err)
130
		return err;
M
Mikko Herranen 已提交
131

132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
	data = kzalloc(sizeof(*data) + crypto_ablkcipher_reqsize(ctr),
		       GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	init_completion(&data->result.completion);
	sg_init_one(data->sg, &data->hash, sizeof(data->hash));
	ablkcipher_request_set_tfm(&data->req, ctr);
	ablkcipher_request_set_callback(&data->req, CRYPTO_TFM_REQ_MAY_SLEEP |
						    CRYPTO_TFM_REQ_MAY_BACKLOG,
					crypto_gcm_setkey_done,
					&data->result);
	ablkcipher_request_set_crypt(&data->req, data->sg, data->sg,
				     sizeof(data->hash), data->iv);

	err = crypto_ablkcipher_encrypt(&data->req);
	if (err == -EINPROGRESS || err == -EBUSY) {
		err = wait_for_completion_interruptible(
			&data->result.completion);
		if (!err)
			err = data->result.err;
	}

M
Mikko Herranen 已提交
155 156 157
	if (err)
		goto out;

158 159 160 161 162 163
	crypto_ahash_clear_flags(ghash, CRYPTO_TFM_REQ_MASK);
	crypto_ahash_set_flags(ghash, crypto_aead_get_flags(aead) &
			       CRYPTO_TFM_REQ_MASK);
	err = crypto_ahash_setkey(ghash, (u8 *)&data->hash, sizeof(be128));
	crypto_aead_set_flags(aead, crypto_ahash_get_flags(ghash) &
			      CRYPTO_TFM_RES_MASK);
M
Mikko Herranen 已提交
164

165
out:
166
	kzfree(data);
M
Mikko Herranen 已提交
167 168 169
	return err;
}

H
Herbert Xu 已提交
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
static int crypto_gcm_setauthsize(struct crypto_aead *tfm,
				  unsigned int authsize)
{
	switch (authsize) {
	case 4:
	case 8:
	case 12:
	case 13:
	case 14:
	case 15:
	case 16:
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

189
static void crypto_gcm_init_common(struct aead_request *req)
M
Mikko Herranen 已提交
190
{
191
	struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
192
	__be32 counter = cpu_to_be32(1);
193
	struct scatterlist *sg;
194 195

	memset(pctx->auth_tag, 0, sizeof(pctx->auth_tag));
196 197
	memcpy(pctx->iv, req->iv, 12);
	memcpy(pctx->iv + 12, &counter, 4);
198

199
	sg_init_table(pctx->src, 3);
200
	sg_set_buf(pctx->src, pctx->auth_tag, sizeof(pctx->auth_tag));
201 202 203
	sg = scatterwalk_ffwd(pctx->src + 1, req->src, req->assoclen);
	if (sg != pctx->src + 1)
		scatterwalk_sg_chain(pctx->src, 2, sg);
204 205

	if (req->src != req->dst) {
206
		sg_init_table(pctx->dst, 3);
207
		sg_set_buf(pctx->dst, pctx->auth_tag, sizeof(pctx->auth_tag));
208 209 210
		sg = scatterwalk_ffwd(pctx->dst + 1, req->dst, req->assoclen);
		if (sg != pctx->dst + 1)
			scatterwalk_sg_chain(pctx->dst, 2, sg);
211
	}
212 213 214 215 216 217 218 219 220 221 222 223
}

static void crypto_gcm_init_crypt(struct aead_request *req,
				  unsigned int cryptlen)
{
	struct crypto_aead *aead = crypto_aead_reqtfm(req);
	struct crypto_gcm_ctx *ctx = crypto_aead_ctx(aead);
	struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
	struct ablkcipher_request *ablk_req = &pctx->u.abreq;
	struct scatterlist *dst;

	dst = req->src == req->dst ? pctx->src : pctx->dst;
M
Mikko Herranen 已提交
224 225

	ablkcipher_request_set_tfm(ablk_req, ctx->ctr);
226 227
	ablkcipher_request_set_crypt(ablk_req, pctx->src, dst,
				     cryptlen + sizeof(pctx->auth_tag),
228
				     pctx->iv);
229 230 231 232 233 234 235 236 237
}

static inline unsigned int gcm_remain(unsigned int len)
{
	len &= 0xfU;
	return len ? 16 - len : 0;
}

static void gcm_hash_len_done(struct crypto_async_request *areq, int err);
M
Mikko Herranen 已提交
238

239
static int gcm_hash_update(struct aead_request *req,
M
Mark Rustad 已提交
240
			   crypto_completion_t compl,
241
			   struct scatterlist *src,
242
			   unsigned int len, u32 flags)
243
{
244
	struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
245
	struct ahash_request *ahreq = &pctx->u.ahreq;
M
Mikko Herranen 已提交
246

247
	ahash_request_set_callback(ahreq, flags, compl, req);
248 249 250
	ahash_request_set_crypt(ahreq, src, NULL, len);

	return crypto_ahash_update(ahreq);
M
Mikko Herranen 已提交
251 252
}

253 254
static int gcm_hash_remain(struct aead_request *req,
			   unsigned int remain,
255
			   crypto_completion_t compl, u32 flags)
M
Mikko Herranen 已提交
256
{
257
	return gcm_hash_update(req, compl, &gcm_zeroes->sg, remain, flags);
258 259
}

260
static int gcm_hash_len(struct aead_request *req, u32 flags)
261
{
262
	struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
263 264 265 266 267 268 269
	struct ahash_request *ahreq = &pctx->u.ahreq;
	struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;
	u128 lengths;

	lengths.a = cpu_to_be64(req->assoclen * 8);
	lengths.b = cpu_to_be64(gctx->cryptlen * 8);
	memcpy(pctx->iauth_tag, &lengths, 16);
270 271 272 273
	sg_init_one(&pctx->sg, pctx->iauth_tag, 16);
	ahash_request_set_callback(ahreq, flags, gcm_hash_len_done, req);
	ahash_request_set_crypt(ahreq, &pctx->sg,
				pctx->iauth_tag, sizeof(lengths));
274

275
	return crypto_ahash_finup(ahreq);
276 277
}

278
static int gcm_hash_len_continue(struct aead_request *req, u32 flags)
279
{
280
	struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
281 282
	struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;

283
	return gctx->complete(req, flags);
284 285
}

286
static void gcm_hash_len_done(struct crypto_async_request *areq, int err)
287 288
{
	struct aead_request *req = areq->data;
289

290 291
	if (err)
		goto out;
292

293 294 295
	err = gcm_hash_len_continue(req, 0);
	if (err == -EINPROGRESS)
		return;
296

297 298
out:
	aead_request_complete(req, err);
299 300
}

301
static int gcm_hash_crypt_remain_continue(struct aead_request *req, u32 flags)
302
{
303 304
	return gcm_hash_len(req, flags) ?:
	       gcm_hash_len_continue(req, flags);
305 306
}

307 308
static void gcm_hash_crypt_remain_done(struct crypto_async_request *areq,
				       int err)
309 310
{
	struct aead_request *req = areq->data;
311

312 313 314 315 316 317 318 319 320
	if (err)
		goto out;

	err = gcm_hash_crypt_remain_continue(req, 0);
	if (err == -EINPROGRESS)
		return;

out:
	aead_request_complete(req, err);
321 322
}

323
static int gcm_hash_crypt_continue(struct aead_request *req, u32 flags)
324
{
325 326 327 328
	struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
	struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;
	unsigned int remain;

329 330 331 332 333
	remain = gcm_remain(gctx->cryptlen);
	if (remain)
		return gcm_hash_remain(req, remain,
				       gcm_hash_crypt_remain_done, flags) ?:
		       gcm_hash_crypt_remain_continue(req, flags);
334

335
	return gcm_hash_crypt_remain_continue(req, flags);
336 337
}

338
static void gcm_hash_crypt_done(struct crypto_async_request *areq, int err)
339 340
{
	struct aead_request *req = areq->data;
341

342 343 344 345 346 347 348 349 350
	if (err)
		goto out;

	err = gcm_hash_crypt_continue(req, 0);
	if (err == -EINPROGRESS)
		return;

out:
	aead_request_complete(req, err);
351 352
}

353
static int gcm_hash_assoc_remain_continue(struct aead_request *req, u32 flags)
354
{
355 356 357
	struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
	struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;

358 359 360 361 362 363
	if (gctx->cryptlen)
		return gcm_hash_update(req, gcm_hash_crypt_done,
				       gctx->src, gctx->cryptlen, flags) ?:
		       gcm_hash_crypt_continue(req, flags);

	return gcm_hash_crypt_remain_continue(req, flags);
364 365
}

366 367
static void gcm_hash_assoc_remain_done(struct crypto_async_request *areq,
				       int err)
368 369
{
	struct aead_request *req = areq->data;
370

371 372 373 374 375 376 377 378 379
	if (err)
		goto out;

	err = gcm_hash_assoc_remain_continue(req, 0);
	if (err == -EINPROGRESS)
		return;

out:
	aead_request_complete(req, err);
380 381
}

382
static int gcm_hash_assoc_continue(struct aead_request *req, u32 flags)
383
{
384 385
	unsigned int remain;

386 387 388 389 390
	remain = gcm_remain(req->assoclen);
	if (remain)
		return gcm_hash_remain(req, remain,
				       gcm_hash_assoc_remain_done, flags) ?:
		       gcm_hash_assoc_remain_continue(req, flags);
391

392
	return gcm_hash_assoc_remain_continue(req, flags);
393 394
}

395
static void gcm_hash_assoc_done(struct crypto_async_request *areq, int err)
396 397
{
	struct aead_request *req = areq->data;
398

399 400 401 402 403 404 405 406 407
	if (err)
		goto out;

	err = gcm_hash_assoc_continue(req, 0);
	if (err == -EINPROGRESS)
		return;

out:
	aead_request_complete(req, err);
408 409
}

410
static int gcm_hash_init_continue(struct aead_request *req, u32 flags)
411
{
412 413 414 415
	if (req->assoclen)
		return gcm_hash_update(req, gcm_hash_assoc_done,
				       req->src, req->assoclen, flags) ?:
		       gcm_hash_assoc_continue(req, flags);
416

417
	return gcm_hash_assoc_remain_continue(req, flags);
418 419 420 421 422 423
}

static void gcm_hash_init_done(struct crypto_async_request *areq, int err)
{
	struct aead_request *req = areq->data;

424 425 426 427 428 429 430 431 432
	if (err)
		goto out;

	err = gcm_hash_init_continue(req, 0);
	if (err == -EINPROGRESS)
		return;

out:
	aead_request_complete(req, err);
433 434
}

435
static int gcm_hash(struct aead_request *req, u32 flags)
436
{
437
	struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
438
	struct ahash_request *ahreq = &pctx->u.ahreq;
439
	struct crypto_gcm_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
440 441 442

	ahash_request_set_tfm(ahreq, ctx->ghash);

443 444 445
	ahash_request_set_callback(ahreq, flags, gcm_hash_init_done, req);
	return crypto_ahash_init(ahreq) ?:
	       gcm_hash_init_continue(req, flags);
446 447
}

448
static int gcm_enc_copy_hash(struct aead_request *req, u32 flags)
449
{
450
	struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
451 452
	struct crypto_aead *aead = crypto_aead_reqtfm(req);
	u8 *auth_tag = pctx->auth_tag;
M
Mikko Herranen 已提交
453

454 455 456
	crypto_xor(auth_tag, pctx->iauth_tag, 16);
	scatterwalk_map_and_copy(auth_tag, req->dst,
				 req->assoclen + req->cryptlen,
H
Herbert Xu 已提交
457
				 crypto_aead_authsize(aead), 1);
458
	return 0;
H
Herbert Xu 已提交
459 460
}

461
static int gcm_encrypt_continue(struct aead_request *req, u32 flags)
H
Herbert Xu 已提交
462
{
463
	struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
464
	struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;
H
Herbert Xu 已提交
465

466 467 468
	gctx->src = sg_next(req->src == req->dst ? pctx->src : pctx->dst);
	gctx->cryptlen = req->cryptlen;
	gctx->complete = gcm_enc_copy_hash;
H
Herbert Xu 已提交
469

470
	return gcm_hash(req, flags);
M
Mikko Herranen 已提交
471 472
}

473
static void gcm_encrypt_done(struct crypto_async_request *areq, int err)
474 475 476
{
	struct aead_request *req = areq->data;

477 478 479 480 481 482
	if (err)
		goto out;

	err = gcm_encrypt_continue(req, 0);
	if (err == -EINPROGRESS)
		return;
483

484
out:
485
	aead_request_complete(req, err);
486 487
}

M
Mikko Herranen 已提交
488 489
static int crypto_gcm_encrypt(struct aead_request *req)
{
490
	struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
491
	struct ablkcipher_request *abreq = &pctx->u.abreq;
492
	u32 flags = aead_request_flags(req);
493

494 495 496
	crypto_gcm_init_common(req);
	crypto_gcm_init_crypt(req, req->cryptlen);
	ablkcipher_request_set_callback(abreq, flags, gcm_encrypt_done, req);
497

498 499
	return crypto_ablkcipher_encrypt(abreq) ?:
	       gcm_encrypt_continue(req, flags);
M
Mikko Herranen 已提交
500 501
}

502
static int crypto_gcm_verify(struct aead_request *req)
503
{
504
	struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
505 506 507 508 509 510
	struct crypto_aead *aead = crypto_aead_reqtfm(req);
	u8 *auth_tag = pctx->auth_tag;
	u8 *iauth_tag = pctx->iauth_tag;
	unsigned int authsize = crypto_aead_authsize(aead);
	unsigned int cryptlen = req->cryptlen - authsize;

511
	crypto_xor(auth_tag, iauth_tag, 16);
512 513
	scatterwalk_map_and_copy(iauth_tag, req->src,
				 req->assoclen + cryptlen, authsize, 0);
514
	return crypto_memneq(iauth_tag, auth_tag, authsize) ? -EBADMSG : 0;
515 516
}

517
static void gcm_decrypt_done(struct crypto_async_request *areq, int err)
M
Mikko Herranen 已提交
518
{
519 520 521
	struct aead_request *req = areq->data;

	if (!err)
522
		err = crypto_gcm_verify(req);
523 524

	aead_request_complete(req, err);
M
Mikko Herranen 已提交
525 526
}

527
static int gcm_dec_hash_continue(struct aead_request *req, u32 flags)
528 529 530 531 532
{
	struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
	struct ablkcipher_request *abreq = &pctx->u.abreq;
	struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;

533 534 535
	crypto_gcm_init_crypt(req, gctx->cryptlen);
	ablkcipher_request_set_callback(abreq, flags, gcm_decrypt_done, req);
	return crypto_ablkcipher_decrypt(abreq) ?: crypto_gcm_verify(req);
536 537
}

M
Mikko Herranen 已提交
538 539
static int crypto_gcm_decrypt(struct aead_request *req)
{
H
Herbert Xu 已提交
540
	struct crypto_aead *aead = crypto_aead_reqtfm(req);
541
	struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
542
	struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;
H
Herbert Xu 已提交
543
	unsigned int authsize = crypto_aead_authsize(aead);
544
	unsigned int cryptlen = req->cryptlen;
545
	u32 flags = aead_request_flags(req);
M
Mikko Herranen 已提交
546

H
Herbert Xu 已提交
547
	cryptlen -= authsize;
M
Mikko Herranen 已提交
548

549
	crypto_gcm_init_common(req);
M
Mikko Herranen 已提交
550

551 552 553
	gctx->src = sg_next(pctx->src);
	gctx->cryptlen = cryptlen;
	gctx->complete = gcm_dec_hash_continue;
M
Mikko Herranen 已提交
554

555
	return gcm_hash(req, flags);
M
Mikko Herranen 已提交
556 557
}

558
static int crypto_gcm_init_tfm(struct crypto_aead *tfm)
M
Mikko Herranen 已提交
559
{
560 561 562
	struct aead_instance *inst = aead_alg_instance(tfm);
	struct gcm_instance_ctx *ictx = aead_instance_ctx(inst);
	struct crypto_gcm_ctx *ctx = crypto_aead_ctx(tfm);
M
Mikko Herranen 已提交
563
	struct crypto_ablkcipher *ctr;
564
	struct crypto_ahash *ghash;
M
Mikko Herranen 已提交
565 566 567
	unsigned long align;
	int err;

568 569 570 571
	ghash = crypto_spawn_ahash(&ictx->ghash);
	if (IS_ERR(ghash))
		return PTR_ERR(ghash);

572
	ctr = crypto_spawn_skcipher(&ictx->ctr);
M
Mikko Herranen 已提交
573 574
	err = PTR_ERR(ctr);
	if (IS_ERR(ctr))
575
		goto err_free_hash;
M
Mikko Herranen 已提交
576 577

	ctx->ctr = ctr;
578
	ctx->ghash = ghash;
M
Mikko Herranen 已提交
579

580
	align = crypto_aead_alignmask(tfm);
M
Mikko Herranen 已提交
581
	align &= ~(crypto_tfm_ctx_alignment() - 1);
582
	crypto_aead_set_reqsize(tfm,
583
		align + offsetof(struct crypto_gcm_req_priv_ctx, u) +
584 585 586
		max(sizeof(struct ablkcipher_request) +
		    crypto_ablkcipher_reqsize(ctr),
		    sizeof(struct ahash_request) +
587
		    crypto_ahash_reqsize(ghash)));
M
Mikko Herranen 已提交
588 589

	return 0;
590 591 592 593

err_free_hash:
	crypto_free_ahash(ghash);
	return err;
M
Mikko Herranen 已提交
594 595
}

596
static void crypto_gcm_exit_tfm(struct crypto_aead *tfm)
M
Mikko Herranen 已提交
597
{
598
	struct crypto_gcm_ctx *ctx = crypto_aead_ctx(tfm);
M
Mikko Herranen 已提交
599

600
	crypto_free_ahash(ctx->ghash);
M
Mikko Herranen 已提交
601 602 603
	crypto_free_ablkcipher(ctx->ctr);
}

604 605 606 607 608
static int crypto_gcm_create_common(struct crypto_template *tmpl,
				    struct rtattr **tb,
				    const char *full_name,
				    const char *ctr_name,
				    const char *ghash_name)
M
Mikko Herranen 已提交
609
{
610
	struct crypto_attr_type *algt;
611
	struct aead_instance *inst;
M
Mikko Herranen 已提交
612
	struct crypto_alg *ctr;
613
	struct crypto_alg *ghash_alg;
614
	struct hash_alg_common *ghash;
M
Mikko Herranen 已提交
615 616 617
	struct gcm_instance_ctx *ctx;
	int err;

618 619
	algt = crypto_get_attr_type(tb);
	if (IS_ERR(algt))
620
		return PTR_ERR(algt);
M
Mikko Herranen 已提交
621

622
	if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
623
		return -EINVAL;
M
Mikko Herranen 已提交
624

625 626 627 628
	ghash_alg = crypto_find_alg(ghash_name, &crypto_ahash_type,
				    CRYPTO_ALG_TYPE_HASH,
				    CRYPTO_ALG_TYPE_AHASH_MASK);
	if (IS_ERR(ghash_alg))
629 630 631
		return PTR_ERR(ghash_alg);

	ghash = __crypto_hash_alg_common(ghash_alg);
632 633

	err = -ENOMEM;
634 635
	inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
	if (!inst)
636
		goto out_put_ghash;
M
Mikko Herranen 已提交
637

638 639 640
	ctx = aead_instance_ctx(inst);
	err = crypto_init_ahash_spawn(&ctx->ghash, ghash,
				      aead_crypto_instance(inst));
641 642 643
	if (err)
		goto err_free_inst;

644 645 646 647 648
	err = -EINVAL;
	if (ghash->digestsize != 16)
		goto err_drop_ghash;

	crypto_set_skcipher_spawn(&ctx->ctr, aead_crypto_instance(inst));
649 650 651 652
	err = crypto_grab_skcipher(&ctx->ctr, ctr_name, 0,
				   crypto_requires_sync(algt->type,
							algt->mask));
	if (err)
653
		goto err_drop_ghash;
654 655

	ctr = crypto_skcipher_spawn_alg(&ctx->ctr);
M
Mikko Herranen 已提交
656

657
	/* We only support 16-byte blocks. */
658
	if (ctr->cra_ablkcipher.ivsize != 16)
659 660 661 662 663
		goto out_put_ctr;

	/* Not a stream cipher? */
	err = -EINVAL;
	if (ctr->cra_blocksize != 1)
M
Mikko Herranen 已提交
664 665 666
		goto out_put_ctr;

	err = -ENAMETOOLONG;
667
	if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
668 669
		     "gcm_base(%s,%s)", ctr->cra_driver_name,
		     ghash_alg->cra_driver_name) >=
670
	    CRYPTO_MAX_ALG_NAME)
671
		goto out_put_ctr;
M
Mikko Herranen 已提交
672

673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694
	memcpy(inst->alg.base.cra_name, full_name, CRYPTO_MAX_ALG_NAME);

	inst->alg.base.cra_flags = (ghash->base.cra_flags | ctr->cra_flags) &
				   CRYPTO_ALG_ASYNC;
	inst->alg.base.cra_priority = (ghash->base.cra_priority +
				       ctr->cra_priority) / 2;
	inst->alg.base.cra_blocksize = 1;
	inst->alg.base.cra_alignmask = ghash->base.cra_alignmask |
				       ctr->cra_alignmask;
	inst->alg.base.cra_ctxsize = sizeof(struct crypto_gcm_ctx);
	inst->alg.ivsize = 12;
	inst->alg.maxauthsize = 16;
	inst->alg.init = crypto_gcm_init_tfm;
	inst->alg.exit = crypto_gcm_exit_tfm;
	inst->alg.setkey = crypto_gcm_setkey;
	inst->alg.setauthsize = crypto_gcm_setauthsize;
	inst->alg.encrypt = crypto_gcm_encrypt;
	inst->alg.decrypt = crypto_gcm_decrypt;

	err = aead_register_instance(tmpl, inst);
	if (err)
		goto out_put_ctr;
M
Mikko Herranen 已提交
695

696
out_put_ghash:
697
	crypto_mod_put(ghash_alg);
698
	return err;
699 700 701

out_put_ctr:
	crypto_drop_skcipher(&ctx->ctr);
702 703
err_drop_ghash:
	crypto_drop_ahash(&ctx->ghash);
M
Mikko Herranen 已提交
704 705
err_free_inst:
	kfree(inst);
706
	goto out_put_ghash;
M
Mikko Herranen 已提交
707 708
}

709
static int crypto_gcm_create(struct crypto_template *tmpl, struct rtattr **tb)
710 711 712 713 714 715 716
{
	const char *cipher_name;
	char ctr_name[CRYPTO_MAX_ALG_NAME];
	char full_name[CRYPTO_MAX_ALG_NAME];

	cipher_name = crypto_attr_alg_name(tb[1]);
	if (IS_ERR(cipher_name))
717
		return PTR_ERR(cipher_name);
718 719 720

	if (snprintf(ctr_name, CRYPTO_MAX_ALG_NAME, "ctr(%s)", cipher_name) >=
	    CRYPTO_MAX_ALG_NAME)
721
		return -ENAMETOOLONG;
722 723 724

	if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "gcm(%s)", cipher_name) >=
	    CRYPTO_MAX_ALG_NAME)
725
		return -ENAMETOOLONG;
726

727 728
	return crypto_gcm_create_common(tmpl, tb, full_name,
					ctr_name, "ghash");
729 730
}

M
Mikko Herranen 已提交
731 732 733 734
static void crypto_gcm_free(struct crypto_instance *inst)
{
	struct gcm_instance_ctx *ctx = crypto_instance_ctx(inst);

735
	crypto_drop_skcipher(&ctx->ctr);
736
	crypto_drop_ahash(&ctx->ghash);
737
	kfree(aead_instance(inst));
M
Mikko Herranen 已提交
738 739 740 741
}

static struct crypto_template crypto_gcm_tmpl = {
	.name = "gcm",
742
	.create = crypto_gcm_create,
M
Mikko Herranen 已提交
743 744 745 746
	.free = crypto_gcm_free,
	.module = THIS_MODULE,
};

747 748
static int crypto_gcm_base_create(struct crypto_template *tmpl,
				  struct rtattr **tb)
749 750
{
	const char *ctr_name;
751
	const char *ghash_name;
752 753 754 755
	char full_name[CRYPTO_MAX_ALG_NAME];

	ctr_name = crypto_attr_alg_name(tb[1]);
	if (IS_ERR(ctr_name))
756
		return PTR_ERR(ctr_name);
757

758 759
	ghash_name = crypto_attr_alg_name(tb[2]);
	if (IS_ERR(ghash_name))
760
		return PTR_ERR(ghash_name);
761 762 763

	if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "gcm_base(%s,%s)",
		     ctr_name, ghash_name) >= CRYPTO_MAX_ALG_NAME)
764
		return -ENAMETOOLONG;
765

766 767
	return crypto_gcm_create_common(tmpl, tb, full_name,
					ctr_name, ghash_name);
768 769 770 771
}

static struct crypto_template crypto_gcm_base_tmpl = {
	.name = "gcm_base",
772
	.create = crypto_gcm_base_create,
773 774 775 776
	.free = crypto_gcm_free,
	.module = THIS_MODULE,
};

H
Herbert Xu 已提交
777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832
static int crypto_rfc4106_setkey(struct crypto_aead *parent, const u8 *key,
				 unsigned int keylen)
{
	struct crypto_rfc4106_ctx *ctx = crypto_aead_ctx(parent);
	struct crypto_aead *child = ctx->child;
	int err;

	if (keylen < 4)
		return -EINVAL;

	keylen -= 4;
	memcpy(ctx->nonce, key + keylen, 4);

	crypto_aead_clear_flags(child, CRYPTO_TFM_REQ_MASK);
	crypto_aead_set_flags(child, crypto_aead_get_flags(parent) &
				     CRYPTO_TFM_REQ_MASK);
	err = crypto_aead_setkey(child, key, keylen);
	crypto_aead_set_flags(parent, crypto_aead_get_flags(child) &
				      CRYPTO_TFM_RES_MASK);

	return err;
}

static int crypto_rfc4106_setauthsize(struct crypto_aead *parent,
				      unsigned int authsize)
{
	struct crypto_rfc4106_ctx *ctx = crypto_aead_ctx(parent);

	switch (authsize) {
	case 8:
	case 12:
	case 16:
		break;
	default:
		return -EINVAL;
	}

	return crypto_aead_setauthsize(ctx->child, authsize);
}

static struct aead_request *crypto_rfc4106_crypt(struct aead_request *req)
{
	struct aead_request *subreq = aead_request_ctx(req);
	struct crypto_aead *aead = crypto_aead_reqtfm(req);
	struct crypto_rfc4106_ctx *ctx = crypto_aead_ctx(aead);
	struct crypto_aead *child = ctx->child;
	u8 *iv = PTR_ALIGN((u8 *)(subreq + 1) + crypto_aead_reqsize(child),
			   crypto_aead_alignmask(child) + 1);

	memcpy(iv, ctx->nonce, 4);
	memcpy(iv + 4, req->iv, 8);

	aead_request_set_tfm(subreq, child);
	aead_request_set_callback(subreq, req->base.flags, req->base.complete,
				  req->base.data);
	aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, iv);
833
	aead_request_set_ad(subreq, req->assoclen);
H
Herbert Xu 已提交
834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851

	return subreq;
}

static int crypto_rfc4106_encrypt(struct aead_request *req)
{
	req = crypto_rfc4106_crypt(req);

	return crypto_aead_encrypt(req);
}

static int crypto_rfc4106_decrypt(struct aead_request *req)
{
	req = crypto_rfc4106_crypt(req);

	return crypto_aead_decrypt(req);
}

852
static int crypto_rfc4106_init_tfm(struct crypto_aead *tfm)
H
Herbert Xu 已提交
853
{
854 855 856
	struct aead_instance *inst = aead_alg_instance(tfm);
	struct crypto_aead_spawn *spawn = aead_instance_ctx(inst);
	struct crypto_rfc4106_ctx *ctx = crypto_aead_ctx(tfm);
H
Herbert Xu 已提交
857 858 859 860 861 862 863 864 865 866 867
	struct crypto_aead *aead;
	unsigned long align;

	aead = crypto_spawn_aead(spawn);
	if (IS_ERR(aead))
		return PTR_ERR(aead);

	ctx->child = aead;

	align = crypto_aead_alignmask(aead);
	align &= ~(crypto_tfm_ctx_alignment() - 1);
868 869
	crypto_aead_set_reqsize(
		tfm,
870 871
		sizeof(struct aead_request) +
		ALIGN(crypto_aead_reqsize(aead), crypto_tfm_ctx_alignment()) +
872
		align + 12);
H
Herbert Xu 已提交
873 874 875 876

	return 0;
}

877
static void crypto_rfc4106_exit_tfm(struct crypto_aead *tfm)
H
Herbert Xu 已提交
878
{
879
	struct crypto_rfc4106_ctx *ctx = crypto_aead_ctx(tfm);
H
Herbert Xu 已提交
880 881 882 883

	crypto_free_aead(ctx->child);
}

884 885
static int crypto_rfc4106_create(struct crypto_template *tmpl,
				 struct rtattr **tb)
H
Herbert Xu 已提交
886 887
{
	struct crypto_attr_type *algt;
888
	struct aead_instance *inst;
H
Herbert Xu 已提交
889
	struct crypto_aead_spawn *spawn;
890
	struct aead_alg *alg;
H
Herbert Xu 已提交
891 892 893 894 895
	const char *ccm_name;
	int err;

	algt = crypto_get_attr_type(tb);
	if (IS_ERR(algt))
896
		return PTR_ERR(algt);
H
Herbert Xu 已提交
897 898

	if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
899
		return -EINVAL;
H
Herbert Xu 已提交
900 901 902

	ccm_name = crypto_attr_alg_name(tb[1]);
	if (IS_ERR(ccm_name))
903
		return PTR_ERR(ccm_name);
H
Herbert Xu 已提交
904 905 906

	inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
	if (!inst)
907
		return -ENOMEM;
H
Herbert Xu 已提交
908

909 910
	spawn = aead_instance_ctx(inst);
	crypto_set_aead_spawn(spawn, aead_crypto_instance(inst));
H
Herbert Xu 已提交
911 912 913 914 915
	err = crypto_grab_aead(spawn, ccm_name, 0,
			       crypto_requires_sync(algt->type, algt->mask));
	if (err)
		goto out_free_inst;

916
	alg = crypto_spawn_aead_alg(spawn);
H
Herbert Xu 已提交
917 918 919

	err = -EINVAL;

920 921
	/* Underlying IV size must be 12. */
	if (crypto_aead_alg_ivsize(alg) != 12)
H
Herbert Xu 已提交
922 923 924
		goto out_drop_alg;

	/* Not a stream cipher? */
925
	if (alg->base.cra_blocksize != 1)
H
Herbert Xu 已提交
926 927 928
		goto out_drop_alg;

	err = -ENAMETOOLONG;
929 930 931 932 933
	if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
		     "rfc4106(%s)", alg->base.cra_name) >=
	    CRYPTO_MAX_ALG_NAME ||
	    snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
		     "rfc4106(%s)", alg->base.cra_driver_name) >=
H
Herbert Xu 已提交
934 935 936
	    CRYPTO_MAX_ALG_NAME)
		goto out_drop_alg;

937 938 939 940
	inst->alg.base.cra_flags |= alg->base.cra_flags & CRYPTO_ALG_ASYNC;
	inst->alg.base.cra_priority = alg->base.cra_priority;
	inst->alg.base.cra_blocksize = 1;
	inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
H
Herbert Xu 已提交
941

942
	inst->alg.base.cra_ctxsize = sizeof(struct crypto_rfc4106_ctx);
H
Herbert Xu 已提交
943

944 945
	inst->alg.ivsize = 8;
	inst->alg.maxauthsize = crypto_aead_alg_maxauthsize(alg);
H
Herbert Xu 已提交
946

947 948
	inst->alg.init = crypto_rfc4106_init_tfm;
	inst->alg.exit = crypto_rfc4106_exit_tfm;
H
Herbert Xu 已提交
949

950 951 952 953
	inst->alg.setkey = crypto_rfc4106_setkey;
	inst->alg.setauthsize = crypto_rfc4106_setauthsize;
	inst->alg.encrypt = crypto_rfc4106_encrypt;
	inst->alg.decrypt = crypto_rfc4106_decrypt;
H
Herbert Xu 已提交
954

955 956 957
	err = aead_register_instance(tmpl, inst);
	if (err)
		goto out_drop_alg;
H
Herbert Xu 已提交
958 959

out:
960
	return err;
H
Herbert Xu 已提交
961 962 963 964 965 966 967 968 969 970

out_drop_alg:
	crypto_drop_aead(spawn);
out_free_inst:
	kfree(inst);
	goto out;
}

static void crypto_rfc4106_free(struct crypto_instance *inst)
{
971 972
	crypto_drop_aead(crypto_instance_ctx(inst));
	kfree(aead_instance(inst));
H
Herbert Xu 已提交
973 974 975 976
}

static struct crypto_template crypto_rfc4106_tmpl = {
	.name = "rfc4106",
977
	.create = crypto_rfc4106_create,
H
Herbert Xu 已提交
978 979 980 981
	.free = crypto_rfc4106_free,
	.module = THIS_MODULE,
};

982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015
static int crypto_rfc4543_setkey(struct crypto_aead *parent, const u8 *key,
				 unsigned int keylen)
{
	struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(parent);
	struct crypto_aead *child = ctx->child;
	int err;

	if (keylen < 4)
		return -EINVAL;

	keylen -= 4;
	memcpy(ctx->nonce, key + keylen, 4);

	crypto_aead_clear_flags(child, CRYPTO_TFM_REQ_MASK);
	crypto_aead_set_flags(child, crypto_aead_get_flags(parent) &
				     CRYPTO_TFM_REQ_MASK);
	err = crypto_aead_setkey(child, key, keylen);
	crypto_aead_set_flags(parent, crypto_aead_get_flags(child) &
				      CRYPTO_TFM_RES_MASK);

	return err;
}

static int crypto_rfc4543_setauthsize(struct crypto_aead *parent,
				      unsigned int authsize)
{
	struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(parent);

	if (authsize != 16)
		return -EINVAL;

	return crypto_aead_setauthsize(ctx->child, authsize);
}

1016
static int crypto_rfc4543_crypt(struct aead_request *req, bool enc)
1017 1018 1019
{
	struct crypto_aead *aead = crypto_aead_reqtfm(req);
	struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(aead);
1020
	struct crypto_rfc4543_req_ctx *rctx = aead_request_ctx(req);
1021 1022 1023 1024
	struct aead_request *subreq = &rctx->subreq;
	unsigned int authsize = crypto_aead_authsize(aead);
	u8 *iv = PTR_ALIGN((u8 *)(rctx + 1) + crypto_aead_reqsize(ctx->child),
			   crypto_aead_alignmask(ctx->child) + 1);
1025 1026 1027 1028 1029 1030 1031
	int err;

	if (req->src != req->dst) {
		err = crypto_rfc4543_copy_src_to_dst(req, enc);
		if (err)
			return err;
	}
1032 1033 1034 1035 1036

	memcpy(iv, ctx->nonce, 4);
	memcpy(iv + 4, req->iv, 8);

	aead_request_set_tfm(subreq, ctx->child);
1037 1038 1039 1040 1041 1042 1043 1044
	aead_request_set_callback(subreq, req->base.flags,
				  req->base.complete, req->base.data);
	aead_request_set_crypt(subreq, req->src, req->dst,
			       enc ? 0 : authsize, iv);
	aead_request_set_ad(subreq, req->assoclen + req->cryptlen -
				    subreq->cryptlen);

	return enc ? crypto_aead_encrypt(subreq) : crypto_aead_decrypt(subreq);
1045 1046
}

1047 1048 1049 1050 1051
static int crypto_rfc4543_copy_src_to_dst(struct aead_request *req, bool enc)
{
	struct crypto_aead *aead = crypto_aead_reqtfm(req);
	struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(aead);
	unsigned int authsize = crypto_aead_authsize(aead);
1052 1053
	unsigned int nbytes = req->assoclen + req->cryptlen -
			      (enc ? 0 : authsize);
1054 1055 1056 1057 1058 1059 1060
	struct blkcipher_desc desc = {
		.tfm = ctx->null,
	};

	return crypto_blkcipher_encrypt(&desc, req->dst, req->src, nbytes);
}

1061 1062
static int crypto_rfc4543_encrypt(struct aead_request *req)
{
1063
	return crypto_rfc4543_crypt(req, true);
1064 1065 1066 1067
}

static int crypto_rfc4543_decrypt(struct aead_request *req)
{
1068
	return crypto_rfc4543_crypt(req, false);
1069 1070
}

1071
static int crypto_rfc4543_init_tfm(struct crypto_aead *tfm)
1072
{
1073 1074
	struct aead_instance *inst = aead_alg_instance(tfm);
	struct crypto_rfc4543_instance_ctx *ictx = aead_instance_ctx(inst);
1075
	struct crypto_aead_spawn *spawn = &ictx->aead;
1076
	struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(tfm);
1077
	struct crypto_aead *aead;
1078
	struct crypto_blkcipher *null;
1079
	unsigned long align;
1080
	int err = 0;
1081 1082 1083 1084 1085

	aead = crypto_spawn_aead(spawn);
	if (IS_ERR(aead))
		return PTR_ERR(aead);

1086
	null = crypto_get_default_null_skcipher();
1087 1088 1089 1090
	err = PTR_ERR(null);
	if (IS_ERR(null))
		goto err_free_aead;

1091
	ctx->child = aead;
1092
	ctx->null = null;
1093 1094 1095

	align = crypto_aead_alignmask(aead);
	align &= ~(crypto_tfm_ctx_alignment() - 1);
1096 1097
	crypto_aead_set_reqsize(
		tfm,
1098 1099
		sizeof(struct crypto_rfc4543_req_ctx) +
		ALIGN(crypto_aead_reqsize(aead), crypto_tfm_ctx_alignment()) +
1100
		align + 12);
1101 1102

	return 0;
1103 1104 1105 1106

err_free_aead:
	crypto_free_aead(aead);
	return err;
1107 1108
}

1109
static void crypto_rfc4543_exit_tfm(struct crypto_aead *tfm)
1110
{
1111
	struct crypto_rfc4543_ctx *ctx = crypto_aead_ctx(tfm);
1112 1113

	crypto_free_aead(ctx->child);
1114
	crypto_put_default_null_skcipher();
1115 1116
}

1117 1118
static int crypto_rfc4543_create(struct crypto_template *tmpl,
				struct rtattr **tb)
1119 1120
{
	struct crypto_attr_type *algt;
1121
	struct aead_instance *inst;
1122
	struct crypto_aead_spawn *spawn;
1123
	struct aead_alg *alg;
1124
	struct crypto_rfc4543_instance_ctx *ctx;
1125 1126 1127 1128 1129
	const char *ccm_name;
	int err;

	algt = crypto_get_attr_type(tb);
	if (IS_ERR(algt))
1130
		return PTR_ERR(algt);
1131 1132

	if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
1133
		return -EINVAL;
1134 1135 1136

	ccm_name = crypto_attr_alg_name(tb[1]);
	if (IS_ERR(ccm_name))
1137
		return PTR_ERR(ccm_name);
1138

1139
	inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
1140
	if (!inst)
1141
		return -ENOMEM;
1142

1143
	ctx = aead_instance_ctx(inst);
1144
	spawn = &ctx->aead;
1145
	crypto_set_aead_spawn(spawn, aead_crypto_instance(inst));
1146 1147 1148 1149 1150
	err = crypto_grab_aead(spawn, ccm_name, 0,
			       crypto_requires_sync(algt->type, algt->mask));
	if (err)
		goto out_free_inst;

1151
	alg = crypto_spawn_aead_alg(spawn);
1152 1153 1154

	err = -EINVAL;

1155 1156
	/* Underlying IV size must be 12. */
	if (crypto_aead_alg_ivsize(alg) != 12)
1157
		goto out_drop_alg;
1158 1159

	/* Not a stream cipher? */
1160
	if (alg->base.cra_blocksize != 1)
1161
		goto out_drop_alg;
1162 1163

	err = -ENAMETOOLONG;
1164 1165 1166 1167 1168
	if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
		     "rfc4543(%s)", alg->base.cra_name) >=
	    CRYPTO_MAX_ALG_NAME ||
	    snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
		     "rfc4543(%s)", alg->base.cra_driver_name) >=
1169
	    CRYPTO_MAX_ALG_NAME)
1170
		goto out_drop_alg;
1171

1172 1173 1174 1175
	inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC;
	inst->alg.base.cra_priority = alg->base.cra_priority;
	inst->alg.base.cra_blocksize = 1;
	inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
1176

1177
	inst->alg.base.cra_ctxsize = sizeof(struct crypto_rfc4543_ctx);
1178

1179 1180
	inst->alg.ivsize = 8;
	inst->alg.maxauthsize = crypto_aead_alg_maxauthsize(alg);
1181

1182 1183
	inst->alg.init = crypto_rfc4543_init_tfm;
	inst->alg.exit = crypto_rfc4543_exit_tfm;
1184

1185 1186 1187 1188
	inst->alg.setkey = crypto_rfc4543_setkey;
	inst->alg.setauthsize = crypto_rfc4543_setauthsize;
	inst->alg.encrypt = crypto_rfc4543_encrypt;
	inst->alg.decrypt = crypto_rfc4543_decrypt;
1189

1190 1191 1192
	err = aead_register_instance(tmpl, inst);
	if (err)
		goto out_drop_alg;
1193 1194

out:
1195
	return err;
1196 1197 1198 1199 1200 1201 1202 1203 1204 1205

out_drop_alg:
	crypto_drop_aead(spawn);
out_free_inst:
	kfree(inst);
	goto out;
}

static void crypto_rfc4543_free(struct crypto_instance *inst)
{
1206 1207 1208 1209
	struct crypto_rfc4543_instance_ctx *ctx = crypto_instance_ctx(inst);

	crypto_drop_aead(&ctx->aead);

1210
	kfree(aead_instance(inst));
1211 1212 1213 1214
}

static struct crypto_template crypto_rfc4543_tmpl = {
	.name = "rfc4543",
1215
	.create = crypto_rfc4543_create,
1216 1217 1218 1219
	.free = crypto_rfc4543_free,
	.module = THIS_MODULE,
};

M
Mikko Herranen 已提交
1220 1221
static int __init crypto_gcm_module_init(void)
{
1222 1223
	int err;

1224
	gcm_zeroes = kzalloc(sizeof(*gcm_zeroes), GFP_KERNEL);
1225 1226 1227
	if (!gcm_zeroes)
		return -ENOMEM;

1228 1229
	sg_init_one(&gcm_zeroes->sg, gcm_zeroes->buf, sizeof(gcm_zeroes->buf));

1230 1231 1232 1233 1234 1235 1236 1237
	err = crypto_register_template(&crypto_gcm_base_tmpl);
	if (err)
		goto out;

	err = crypto_register_template(&crypto_gcm_tmpl);
	if (err)
		goto out_undo_base;

H
Herbert Xu 已提交
1238 1239 1240 1241
	err = crypto_register_template(&crypto_rfc4106_tmpl);
	if (err)
		goto out_undo_gcm;

1242 1243 1244 1245
	err = crypto_register_template(&crypto_rfc4543_tmpl);
	if (err)
		goto out_undo_rfc4106;

1246
	return 0;
1247

1248 1249
out_undo_rfc4106:
	crypto_unregister_template(&crypto_rfc4106_tmpl);
H
Herbert Xu 已提交
1250 1251
out_undo_gcm:
	crypto_unregister_template(&crypto_gcm_tmpl);
1252 1253
out_undo_base:
	crypto_unregister_template(&crypto_gcm_base_tmpl);
1254 1255 1256
out:
	kfree(gcm_zeroes);
	return err;
M
Mikko Herranen 已提交
1257 1258 1259 1260
}

static void __exit crypto_gcm_module_exit(void)
{
1261
	kfree(gcm_zeroes);
1262
	crypto_unregister_template(&crypto_rfc4543_tmpl);
H
Herbert Xu 已提交
1263
	crypto_unregister_template(&crypto_rfc4106_tmpl);
M
Mikko Herranen 已提交
1264
	crypto_unregister_template(&crypto_gcm_tmpl);
1265
	crypto_unregister_template(&crypto_gcm_base_tmpl);
M
Mikko Herranen 已提交
1266 1267 1268 1269 1270 1271 1272 1273
}

module_init(crypto_gcm_module_init);
module_exit(crypto_gcm_module_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Galois/Counter Mode");
MODULE_AUTHOR("Mikko Herranen <mh1@iki.fi>");
1274 1275 1276
MODULE_ALIAS_CRYPTO("gcm_base");
MODULE_ALIAS_CRYPTO("rfc4106");
MODULE_ALIAS_CRYPTO("rfc4543");
1277
MODULE_ALIAS_CRYPTO("gcm");