aes_generic.c 12.1 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
/* 
 * Cryptographic API.
 *
 * AES Cipher Algorithm.
 *
 * Based on Brian Gladman's code.
 *
 * Linux developers:
 *  Alexander Kjeldaas <astor@fast.no>
 *  Herbert Valerio Riedel <hvr@hvrlab.org>
 *  Kyle McMartin <kyle@debian.org>
 *  Adam J. Richter <adam@yggdrasil.com> (conversion to 2.5 API).
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * ---------------------------------------------------------------------------
 * Copyright (c) 2002, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
 * All rights reserved.
 *
 * LICENSE TERMS
 *
 * The free distribution and use of this software in both source and binary
 * form is allowed (with or without changes) provided that:
 *
 *   1. distributions of this source code include the above copyright
 *      notice, this list of conditions and the following disclaimer;
 *
 *   2. distributions in binary form include the above copyright
 *      notice, this list of conditions and the following disclaimer
 *      in the documentation and/or other associated materials;
 *
 *   3. the copyright holder's name is not used to endorse products
 *      built using this software without specific written permission.
 *
 * ALTERNATIVELY, provided that this notice is retained in full, this product
 * may be distributed under the terms of the GNU General Public License (GPL),
 * in which case the provisions of the GPL apply INSTEAD OF those given above.
 *
 * DISCLAIMER
 *
 * This software is provided 'as is' with no explicit or implied warranties
 * in respect of its properties, including, but not limited to, correctness
 * and/or fitness for purpose.
 * ---------------------------------------------------------------------------
 */

50
#include <crypto/aes.h>
L
Linus Torvalds 已提交
51 52 53 54 55 56 57
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/crypto.h>
#include <asm/byteorder.h>

58
static inline u8 byte(const u32 x, const unsigned n)
L
Linus Torvalds 已提交
59 60 61 62 63 64 65 66 67 68
{
	return x >> (n << 3);
}

static u8 pow_tab[256] __initdata;
static u8 log_tab[256] __initdata;
static u8 sbx_tab[256] __initdata;
static u8 isb_tab[256] __initdata;
static u32 rco_tab[10];

69 70 71 72 73 74 75 76 77
u32 crypto_ft_tab[4][256];
u32 crypto_fl_tab[4][256];
u32 crypto_it_tab[4][256];
u32 crypto_il_tab[4][256];

EXPORT_SYMBOL_GPL(crypto_ft_tab);
EXPORT_SYMBOL_GPL(crypto_fl_tab);
EXPORT_SYMBOL_GPL(crypto_it_tab);
EXPORT_SYMBOL_GPL(crypto_il_tab);
L
Linus Torvalds 已提交
78

79
static inline u8 __init f_mult(u8 a, u8 b)
L
Linus Torvalds 已提交
80 81 82 83 84 85
{
	u8 aa = log_tab[a], cc = aa + log_tab[b];

	return pow_tab[cc + (cc < aa ? 1 : 0)];
}

86 87 88
#define ff_mult(a, b)	(a && b ? f_mult(a, b) : 0)

static void __init gen_tabs(void)
L
Linus Torvalds 已提交
89 90 91 92
{
	u32 i, t;
	u8 p, q;

93 94 95 96 97
	/*
	 * log and power tables for GF(2**8) finite field with
	 * 0x011b as modular polynomial - the simplest primitive
	 * root is 0x03, used here to generate the tables
	 */
L
Linus Torvalds 已提交
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125

	for (i = 0, p = 1; i < 256; ++i) {
		pow_tab[i] = (u8) p;
		log_tab[p] = (u8) i;

		p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0);
	}

	log_tab[1] = 0;

	for (i = 0, p = 1; i < 10; ++i) {
		rco_tab[i] = p;

		p = (p << 1) ^ (p & 0x80 ? 0x01b : 0);
	}

	for (i = 0; i < 256; ++i) {
		p = (i ? pow_tab[255 - log_tab[i]] : 0);
		q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2));
		p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2));
		sbx_tab[i] = p;
		isb_tab[p] = (u8) i;
	}

	for (i = 0; i < 256; ++i) {
		p = sbx_tab[i];

		t = p;
126 127 128 129
		crypto_fl_tab[0][i] = t;
		crypto_fl_tab[1][i] = rol32(t, 8);
		crypto_fl_tab[2][i] = rol32(t, 16);
		crypto_fl_tab[3][i] = rol32(t, 24);
L
Linus Torvalds 已提交
130

131
		t = ((u32) ff_mult(2, p)) |
L
Linus Torvalds 已提交
132
		    ((u32) p << 8) |
133
		    ((u32) p << 16) | ((u32) ff_mult(3, p) << 24);
L
Linus Torvalds 已提交
134

135 136 137 138
		crypto_ft_tab[0][i] = t;
		crypto_ft_tab[1][i] = rol32(t, 8);
		crypto_ft_tab[2][i] = rol32(t, 16);
		crypto_ft_tab[3][i] = rol32(t, 24);
L
Linus Torvalds 已提交
139 140 141 142

		p = isb_tab[i];

		t = p;
143 144 145 146
		crypto_il_tab[0][i] = t;
		crypto_il_tab[1][i] = rol32(t, 8);
		crypto_il_tab[2][i] = rol32(t, 16);
		crypto_il_tab[3][i] = rol32(t, 24);
L
Linus Torvalds 已提交
147

148 149 150 151
		t = ((u32) ff_mult(14, p)) |
		    ((u32) ff_mult(9, p) << 8) |
		    ((u32) ff_mult(13, p) << 16) |
		    ((u32) ff_mult(11, p) << 24);
L
Linus Torvalds 已提交
152

153 154 155 156
		crypto_it_tab[0][i] = t;
		crypto_it_tab[1][i] = rol32(t, 8);
		crypto_it_tab[2][i] = rol32(t, 16);
		crypto_it_tab[3][i] = rol32(t, 24);
L
Linus Torvalds 已提交
157 158 159 160 161
	}
}

/* initialise the key schedule from the user supplied key */

162
#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
L
Linus Torvalds 已提交
163

164 165 166 167 168 169 170 171 172 173 174 175
#define imix_col(y,x)	do {		\
	u	= star_x(x);		\
	v	= star_x(u);		\
	w	= star_x(v);		\
	t	= w ^ (x);		\
	(y)	= u ^ v ^ w;		\
	(y)	^= ror32(u ^ t, 8) ^	\
		ror32(v ^ t, 16) ^	\
		ror32(t, 24);		\
} while (0)

#define ls_box(x)		\
176 177 178 179
	crypto_fl_tab[0][byte(x, 0)] ^	\
	crypto_fl_tab[1][byte(x, 1)] ^	\
	crypto_fl_tab[2][byte(x, 2)] ^	\
	crypto_fl_tab[3][byte(x, 3)]
180 181 182 183

#define loop4(i)	do {		\
	t = ror32(t, 8);		\
	t = ls_box(t) ^ rco_tab[i];	\
184 185 186 187 188 189 190 191
	t ^= ctx->key_enc[4 * i];		\
	ctx->key_enc[4 * i + 4] = t;		\
	t ^= ctx->key_enc[4 * i + 1];		\
	ctx->key_enc[4 * i + 5] = t;		\
	t ^= ctx->key_enc[4 * i + 2];		\
	ctx->key_enc[4 * i + 6] = t;		\
	t ^= ctx->key_enc[4 * i + 3];		\
	ctx->key_enc[4 * i + 7] = t;		\
192 193 194 195 196
} while (0)

#define loop6(i)	do {		\
	t = ror32(t, 8);		\
	t = ls_box(t) ^ rco_tab[i];	\
197 198 199 200 201 202 203 204 205 206 207 208
	t ^= ctx->key_enc[6 * i];		\
	ctx->key_enc[6 * i + 6] = t;		\
	t ^= ctx->key_enc[6 * i + 1];		\
	ctx->key_enc[6 * i + 7] = t;		\
	t ^= ctx->key_enc[6 * i + 2];		\
	ctx->key_enc[6 * i + 8] = t;		\
	t ^= ctx->key_enc[6 * i + 3];		\
	ctx->key_enc[6 * i + 9] = t;		\
	t ^= ctx->key_enc[6 * i + 4];		\
	ctx->key_enc[6 * i + 10] = t;		\
	t ^= ctx->key_enc[6 * i + 5];		\
	ctx->key_enc[6 * i + 11] = t;		\
209 210 211 212 213
} while (0)

#define loop8(i)	do {			\
	t = ror32(t, 8);			\
	t = ls_box(t) ^ rco_tab[i];		\
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
	t ^= ctx->key_enc[8 * i];			\
	ctx->key_enc[8 * i + 8] = t;			\
	t ^= ctx->key_enc[8 * i + 1];			\
	ctx->key_enc[8 * i + 9] = t;			\
	t ^= ctx->key_enc[8 * i + 2];			\
	ctx->key_enc[8 * i + 10] = t;			\
	t ^= ctx->key_enc[8 * i + 3];			\
	ctx->key_enc[8 * i + 11] = t;			\
	t  = ctx->key_enc[8 * i + 4] ^ ls_box(t);	\
	ctx->key_enc[8 * i + 12] = t;			\
	t ^= ctx->key_enc[8 * i + 5];			\
	ctx->key_enc[8 * i + 13] = t;			\
	t ^= ctx->key_enc[8 * i + 6];			\
	ctx->key_enc[8 * i + 14] = t;			\
	t ^= ctx->key_enc[8 * i + 7];			\
	ctx->key_enc[8 * i + 15] = t;			\
230
} while (0)
L
Linus Torvalds 已提交
231

232
int crypto_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
233
		unsigned int key_len)
L
Linus Torvalds 已提交
234
{
235
	struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
236
	const __le32 *key = (const __le32 *)in_key;
237
	u32 *flags = &tfm->crt_flags;
238
	u32 i, t, u, v, w, j;
L
Linus Torvalds 已提交
239

240
	if (key_len % 8) {
L
Linus Torvalds 已提交
241 242 243 244 245 246
		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
		return -EINVAL;
	}

	ctx->key_length = key_len;

247 248 249 250
	ctx->key_dec[key_len + 24] = ctx->key_enc[0] = le32_to_cpu(key[0]);
	ctx->key_dec[key_len + 25] = ctx->key_enc[1] = le32_to_cpu(key[1]);
	ctx->key_dec[key_len + 26] = ctx->key_enc[2] = le32_to_cpu(key[2]);
	ctx->key_dec[key_len + 27] = ctx->key_enc[3] = le32_to_cpu(key[3]);
L
Linus Torvalds 已提交
251 252 253

	switch (key_len) {
	case 16:
254
		t = ctx->key_enc[3];
L
Linus Torvalds 已提交
255
		for (i = 0; i < 10; ++i)
256
			loop4(i);
L
Linus Torvalds 已提交
257 258 259
		break;

	case 24:
260 261
		ctx->key_enc[4] = le32_to_cpu(key[4]);
		t = ctx->key_enc[5] = le32_to_cpu(key[5]);
L
Linus Torvalds 已提交
262
		for (i = 0; i < 8; ++i)
263
			loop6(i);
L
Linus Torvalds 已提交
264 265 266
		break;

	case 32:
267 268 269 270
		ctx->key_enc[4] = le32_to_cpu(key[4]);
		ctx->key_enc[5] = le32_to_cpu(key[5]);
		ctx->key_enc[6] = le32_to_cpu(key[6]);
		t = ctx->key_enc[7] = le32_to_cpu(key[7]);
L
Linus Torvalds 已提交
271
		for (i = 0; i < 7; ++i)
272
			loop8(i);
L
Linus Torvalds 已提交
273 274 275
		break;
	}

276 277 278 279
	ctx->key_dec[0] = ctx->key_enc[key_len + 24];
	ctx->key_dec[1] = ctx->key_enc[key_len + 25];
	ctx->key_dec[2] = ctx->key_enc[key_len + 26];
	ctx->key_dec[3] = ctx->key_enc[key_len + 27];
L
Linus Torvalds 已提交
280 281

	for (i = 4; i < key_len + 24; ++i) {
282 283
		j = key_len + 24 - (i & ~3) + (i & 3);
		imix_col(ctx->key_dec[j], ctx->key_enc[i]);
L
Linus Torvalds 已提交
284 285 286
	}
	return 0;
}
287
EXPORT_SYMBOL_GPL(crypto_aes_set_key);
L
Linus Torvalds 已提交
288 289 290

/* encrypt a block of text */

291
#define f_rn(bo, bi, n, k)	do {				\
292 293 294 295
	bo[n] = crypto_ft_tab[0][byte(bi[n], 0)] ^			\
		crypto_ft_tab[1][byte(bi[(n + 1) & 3], 1)] ^		\
		crypto_ft_tab[2][byte(bi[(n + 2) & 3], 2)] ^		\
		crypto_ft_tab[3][byte(bi[(n + 3) & 3], 3)] ^ *(k + n);	\
296 297 298 299 300 301 302 303 304 305 306
} while (0)

#define f_nround(bo, bi, k)	do {\
	f_rn(bo, bi, 0, k);	\
	f_rn(bo, bi, 1, k);	\
	f_rn(bo, bi, 2, k);	\
	f_rn(bo, bi, 3, k);	\
	k += 4;			\
} while (0)

#define f_rl(bo, bi, n, k)	do {				\
307 308 309 310
	bo[n] = crypto_fl_tab[0][byte(bi[n], 0)] ^			\
		crypto_fl_tab[1][byte(bi[(n + 1) & 3], 1)] ^		\
		crypto_fl_tab[2][byte(bi[(n + 2) & 3], 2)] ^		\
		crypto_fl_tab[3][byte(bi[(n + 3) & 3], 3)] ^ *(k + n);	\
311 312 313 314 315 316 317 318
} while (0)

#define f_lround(bo, bi, k)	do {\
	f_rl(bo, bi, 0, k);	\
	f_rl(bo, bi, 1, k);	\
	f_rl(bo, bi, 2, k);	\
	f_rl(bo, bi, 3, k);	\
} while (0)
L
Linus Torvalds 已提交
319

320
static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
L
Linus Torvalds 已提交
321
{
322
	const struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
323 324
	const __le32 *src = (const __le32 *)in;
	__le32 *dst = (__le32 *)out;
L
Linus Torvalds 已提交
325
	u32 b0[4], b1[4];
326 327
	const u32 *kp = ctx->key_enc + 4;
	const int key_len = ctx->key_length;
L
Linus Torvalds 已提交
328

329 330 331 332
	b0[0] = le32_to_cpu(src[0]) ^ ctx->key_enc[0];
	b0[1] = le32_to_cpu(src[1]) ^ ctx->key_enc[1];
	b0[2] = le32_to_cpu(src[2]) ^ ctx->key_enc[2];
	b0[3] = le32_to_cpu(src[3]) ^ ctx->key_enc[3];
L
Linus Torvalds 已提交
333

334
	if (key_len > 24) {
335 336
		f_nround(b1, b0, kp);
		f_nround(b0, b1, kp);
L
Linus Torvalds 已提交
337 338
	}

339
	if (key_len > 16) {
340 341
		f_nround(b1, b0, kp);
		f_nround(b0, b1, kp);
L
Linus Torvalds 已提交
342 343
	}

344 345 346 347 348 349 350 351 352 353
	f_nround(b1, b0, kp);
	f_nround(b0, b1, kp);
	f_nround(b1, b0, kp);
	f_nround(b0, b1, kp);
	f_nround(b1, b0, kp);
	f_nround(b0, b1, kp);
	f_nround(b1, b0, kp);
	f_nround(b0, b1, kp);
	f_nround(b1, b0, kp);
	f_lround(b0, b1, kp);
L
Linus Torvalds 已提交
354

355 356 357 358
	dst[0] = cpu_to_le32(b0[0]);
	dst[1] = cpu_to_le32(b0[1]);
	dst[2] = cpu_to_le32(b0[2]);
	dst[3] = cpu_to_le32(b0[3]);
L
Linus Torvalds 已提交
359 360 361 362
}

/* decrypt a block of text */

363
#define i_rn(bo, bi, n, k)	do {				\
364 365 366 367
	bo[n] = crypto_it_tab[0][byte(bi[n], 0)] ^			\
		crypto_it_tab[1][byte(bi[(n + 3) & 3], 1)] ^		\
		crypto_it_tab[2][byte(bi[(n + 2) & 3], 2)] ^		\
		crypto_it_tab[3][byte(bi[(n + 1) & 3], 3)] ^ *(k + n);	\
368 369 370 371 372 373 374
} while (0)

#define i_nround(bo, bi, k)	do {\
	i_rn(bo, bi, 0, k);	\
	i_rn(bo, bi, 1, k);	\
	i_rn(bo, bi, 2, k);	\
	i_rn(bo, bi, 3, k);	\
375
	k += 4;			\
376 377 378
} while (0)

#define i_rl(bo, bi, n, k)	do {			\
379 380 381 382
	bo[n] = crypto_il_tab[0][byte(bi[n], 0)] ^		\
	crypto_il_tab[1][byte(bi[(n + 3) & 3], 1)] ^		\
	crypto_il_tab[2][byte(bi[(n + 2) & 3], 2)] ^		\
	crypto_il_tab[3][byte(bi[(n + 1) & 3], 3)] ^ *(k + n);	\
383 384 385 386 387 388 389 390
} while (0)

#define i_lround(bo, bi, k)	do {\
	i_rl(bo, bi, 0, k);	\
	i_rl(bo, bi, 1, k);	\
	i_rl(bo, bi, 2, k);	\
	i_rl(bo, bi, 3, k);	\
} while (0)
L
Linus Torvalds 已提交
391

392
static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
L
Linus Torvalds 已提交
393
{
394
	const struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
395 396
	const __le32 *src = (const __le32 *)in;
	__le32 *dst = (__le32 *)out;
L
Linus Torvalds 已提交
397 398
	u32 b0[4], b1[4];
	const int key_len = ctx->key_length;
399
	const u32 *kp = ctx->key_dec + 4;
L
Linus Torvalds 已提交
400

401 402 403 404
	b0[0] = le32_to_cpu(src[0]) ^  ctx->key_dec[0];
	b0[1] = le32_to_cpu(src[1]) ^  ctx->key_dec[1];
	b0[2] = le32_to_cpu(src[2]) ^  ctx->key_dec[2];
	b0[3] = le32_to_cpu(src[3]) ^  ctx->key_dec[3];
L
Linus Torvalds 已提交
405 406

	if (key_len > 24) {
407 408
		i_nround(b1, b0, kp);
		i_nround(b0, b1, kp);
L
Linus Torvalds 已提交
409 410 411
	}

	if (key_len > 16) {
412 413
		i_nround(b1, b0, kp);
		i_nround(b0, b1, kp);
L
Linus Torvalds 已提交
414 415
	}

416 417 418 419 420 421 422 423 424 425
	i_nround(b1, b0, kp);
	i_nround(b0, b1, kp);
	i_nround(b1, b0, kp);
	i_nround(b0, b1, kp);
	i_nround(b1, b0, kp);
	i_nround(b0, b1, kp);
	i_nround(b1, b0, kp);
	i_nround(b0, b1, kp);
	i_nround(b1, b0, kp);
	i_lround(b0, b1, kp);
L
Linus Torvalds 已提交
426

427 428 429 430
	dst[0] = cpu_to_le32(b0[0]);
	dst[1] = cpu_to_le32(b0[1]);
	dst[2] = cpu_to_le32(b0[2]);
	dst[3] = cpu_to_le32(b0[3]);
L
Linus Torvalds 已提交
431 432 433 434
}

static struct crypto_alg aes_alg = {
	.cra_name		=	"aes",
435 436
	.cra_driver_name	=	"aes-generic",
	.cra_priority		=	100,
L
Linus Torvalds 已提交
437 438
	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
	.cra_blocksize		=	AES_BLOCK_SIZE,
439
	.cra_ctxsize		=	sizeof(struct crypto_aes_ctx),
440
	.cra_alignmask		=	3,
L
Linus Torvalds 已提交
441 442 443 444 445 446
	.cra_module		=	THIS_MODULE,
	.cra_list		=	LIST_HEAD_INIT(aes_alg.cra_list),
	.cra_u			=	{
		.cipher = {
			.cia_min_keysize	=	AES_MIN_KEY_SIZE,
			.cia_max_keysize	=	AES_MAX_KEY_SIZE,
447
			.cia_setkey		=	crypto_aes_set_key,
448 449
			.cia_encrypt		=	aes_encrypt,
			.cia_decrypt		=	aes_decrypt
L
Linus Torvalds 已提交
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469
		}
	}
};

static int __init aes_init(void)
{
	gen_tabs();
	return crypto_register_alg(&aes_alg);
}

static void __exit aes_fini(void)
{
	crypto_unregister_alg(&aes_alg);
}

module_init(aes_init);
module_exit(aes_fini);

MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
MODULE_LICENSE("Dual BSD/GPL");
470
MODULE_ALIAS("aes");