1/* 2 * Cryptographic API. 3 * 4 * AES Cipher Algorithm. 5 * 6 * Based on Brian Gladman's code. 7 * 8 * Linux developers: 9 * Alexander Kjeldaas <astor@fast.no> 10 * Herbert Valerio Riedel <hvr@hvrlab.org> 11 * Kyle McMartin <kyle@debian.org> 12 * Adam J. Richter <adam@yggdrasil.com> (conversion to 2.5 API). 13 * Andreas Steinmetz <ast@domdv.de> (adapted to x86_64 assembler) 14 * 15 * This program is free software; you can redistribute it and/or modify 16 * it under the terms of the GNU General Public License as published by 17 * the Free Software Foundation; either version 2 of the License, or 18 * (at your option) any later version. 19 * 20 * --------------------------------------------------------------------------- 21 * Copyright (c) 2002, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK. 22 * All rights reserved. 23 * 24 * LICENSE TERMS 25 * 26 * The free distribution and use of this software in both source and binary 27 * form is allowed (with or without changes) provided that: 28 * 29 * 1. distributions of this source code include the above copyright 30 * notice, this list of conditions and the following disclaimer; 31 * 32 * 2. distributions in binary form include the above copyright 33 * notice, this list of conditions and the following disclaimer 34 * in the documentation and/or other associated materials; 35 * 36 * 3. the copyright holder's name is not used to endorse products 37 * built using this software without specific written permission. 38 * 39 * ALTERNATIVELY, provided that this notice is retained in full, this product 40 * may be distributed under the terms of the GNU General Public License (GPL), 41 * in which case the provisions of the GPL apply INSTEAD OF those given above. 42 * 43 * DISCLAIMER 44 * 45 * This software is provided 'as is' with no explicit or implied warranties 46 * in respect of its properties, including, but not limited to, correctness 47 * and/or fitness for purpose. 48 * --------------------------------------------------------------------------- 49 */ 50 51/* Some changes from the Gladman version: 52 s/RIJNDAEL(e_key)/E_KEY/g 53 s/RIJNDAEL(d_key)/D_KEY/g 54*/ 55 56#include <asm/byteorder.h> 57#include <linux/bitops.h> 58#include <linux/crypto.h> 59#include <linux/errno.h> 60#include <linux/init.h> 61#include <linux/module.h> 62#include <linux/types.h> 63 64#define AES_MIN_KEY_SIZE 16 65#define AES_MAX_KEY_SIZE 32 66 67#define AES_BLOCK_SIZE 16 68 69/* 70 * #define byte(x, nr) ((unsigned char)((x) >> (nr*8))) 71 */ 72static inline u8 byte(const u32 x, const unsigned n) 73{ 74 return x >> (n << 3); 75} 76 77struct aes_ctx 78{ 79 u32 key_length; 80 u32 buf[120]; 81}; 82 83#define E_KEY (&ctx->buf[0]) 84#define D_KEY (&ctx->buf[60]) 85 86static u8 pow_tab[256] __initdata; 87static u8 log_tab[256] __initdata; 88static u8 sbx_tab[256] __initdata; 89static u8 isb_tab[256] __initdata; 90static u32 rco_tab[10]; 91u32 aes_ft_tab[4][256]; 92u32 aes_it_tab[4][256]; 93 94u32 aes_fl_tab[4][256]; 95u32 aes_il_tab[4][256]; 96 97static inline u8 f_mult(u8 a, u8 b) 98{ 99 u8 aa = log_tab[a], cc = aa + log_tab[b]; 100 101 return pow_tab[cc + (cc < aa ? 1 : 0)]; 102} 103 104#define ff_mult(a, b) (a && b ? f_mult(a, b) : 0) 105 106#define ls_box(x) \ 107 (aes_fl_tab[0][byte(x, 0)] ^ \ 108 aes_fl_tab[1][byte(x, 1)] ^ \ 109 aes_fl_tab[2][byte(x, 2)] ^ \ 110 aes_fl_tab[3][byte(x, 3)]) 111 112static void __init gen_tabs(void) 113{ 114 u32 i, t; 115 u8 p, q; 116 117 /* log and power tables for GF(2**8) finite field with 118 0x011b as modular polynomial - the simplest primitive 119 root is 0x03, used here to generate the tables */ 120 121 for (i = 0, p = 1; i < 256; ++i) { 122 pow_tab[i] = (u8)p; 123 log_tab[p] = (u8)i; 124 125 p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0); 126 } 127 128 log_tab[1] = 0; 129 130 for (i = 0, p = 1; i < 10; ++i) { 131 rco_tab[i] = p; 132 133 p = (p << 1) ^ (p & 0x80 ? 0x01b : 0); 134 } 135 136 for (i = 0; i < 256; ++i) { 137 p = (i ? pow_tab[255 - log_tab[i]] : 0); 138 q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2)); 139 p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2)); 140 sbx_tab[i] = p; 141 isb_tab[p] = (u8)i; 142 } 143 144 for (i = 0; i < 256; ++i) { 145 p = sbx_tab[i]; 146 147 t = p; 148 aes_fl_tab[0][i] = t; 149 aes_fl_tab[1][i] = rol32(t, 8); 150 aes_fl_tab[2][i] = rol32(t, 16); 151 aes_fl_tab[3][i] = rol32(t, 24); 152 153 t = ((u32)ff_mult(2, p)) | 154 ((u32)p << 8) | 155 ((u32)p << 16) | ((u32)ff_mult(3, p) << 24); 156 157 aes_ft_tab[0][i] = t; 158 aes_ft_tab[1][i] = rol32(t, 8); 159 aes_ft_tab[2][i] = rol32(t, 16); 160 aes_ft_tab[3][i] = rol32(t, 24); 161 162 p = isb_tab[i]; 163 164 t = p; 165 aes_il_tab[0][i] = t; 166 aes_il_tab[1][i] = rol32(t, 8); 167 aes_il_tab[2][i] = rol32(t, 16); 168 aes_il_tab[3][i] = rol32(t, 24); 169 170 t = ((u32)ff_mult(14, p)) | 171 ((u32)ff_mult(9, p) << 8) | 172 ((u32)ff_mult(13, p) << 16) | 173 ((u32)ff_mult(11, p) << 24); 174 175 aes_it_tab[0][i] = t; 176 aes_it_tab[1][i] = rol32(t, 8); 177 aes_it_tab[2][i] = rol32(t, 16); 178 aes_it_tab[3][i] = rol32(t, 24); 179 } 180} 181 182#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b) 183 184#define imix_col(y, x) \ 185 u = star_x(x); \ 186 v = star_x(u); \ 187 w = star_x(v); \ 188 t = w ^ (x); \ 189 (y) = u ^ v ^ w; \ 190 (y) ^= ror32(u ^ t, 8) ^ \ 191 ror32(v ^ t, 16) ^ \ 192 ror32(t, 24) 193 194/* initialise the key schedule from the user supplied key */ 195 196#define loop4(i) \ 197{ \ 198 t = ror32(t, 8); t = ls_box(t) ^ rco_tab[i]; \ 199 t ^= E_KEY[4 * i]; E_KEY[4 * i + 4] = t; \ 200 t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t; \ 201 t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t; \ 202 t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t; \ 203} 204 205#define loop6(i) \ 206{ \ 207 t = ror32(t, 8); t = ls_box(t) ^ rco_tab[i]; \ 208 t ^= E_KEY[6 * i]; E_KEY[6 * i + 6] = t; \ 209 t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t; \ 210 t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t; \ 211 t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t; \ 212 t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t; \ 213 t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t; \ 214} 215 216#define loop8(i) \ 217{ \ 218 t = ror32(t, 8); ; t = ls_box(t) ^ rco_tab[i]; \ 219 t ^= E_KEY[8 * i]; E_KEY[8 * i + 8] = t; \ 220 t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t; \ 221 t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t; \ 222 t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t; \ 223 t = E_KEY[8 * i + 4] ^ ls_box(t); \ 224 E_KEY[8 * i + 12] = t; \ 225 t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t; \ 226 t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t; \ 227 t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t; \ 228} 229 230static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, 231 unsigned int key_len) 232{ 233 struct aes_ctx *ctx = crypto_tfm_ctx(tfm); 234 const __le32 *key = (const __le32 *)in_key; 235 u32 *flags = &tfm->crt_flags; 236 u32 i, j, t, u, v, w; 237 238 if (key_len % 8) { 239 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; 240 return -EINVAL; 241 } 242 243 ctx->key_length = key_len; 244 245 D_KEY[key_len + 24] = E_KEY[0] = le32_to_cpu(key[0]); 246 D_KEY[key_len + 25] = E_KEY[1] = le32_to_cpu(key[1]); 247 D_KEY[key_len + 26] = E_KEY[2] = le32_to_cpu(key[2]); 248 D_KEY[key_len + 27] = E_KEY[3] = le32_to_cpu(key[3]); 249 250 switch (key_len) { 251 case 16: 252 t = E_KEY[3]; 253 for (i = 0; i < 10; ++i) 254 loop4(i); 255 break; 256 257 case 24: 258 E_KEY[4] = le32_to_cpu(key[4]); 259 t = E_KEY[5] = le32_to_cpu(key[5]); 260 for (i = 0; i < 8; ++i) 261 loop6 (i); 262 break; 263 264 case 32: 265 E_KEY[4] = le32_to_cpu(key[4]); 266 E_KEY[5] = le32_to_cpu(key[5]); 267 E_KEY[6] = le32_to_cpu(key[6]); 268 t = E_KEY[7] = le32_to_cpu(key[7]); 269 for (i = 0; i < 7; ++i) 270 loop8(i); 271 break; 272 } 273 274 D_KEY[0] = E_KEY[key_len + 24]; 275 D_KEY[1] = E_KEY[key_len + 25]; 276 D_KEY[2] = E_KEY[key_len + 26]; 277 D_KEY[3] = E_KEY[key_len + 27]; 278 279 for (i = 4; i < key_len + 24; ++i) { 280 j = key_len + 24 - (i & ~3) + (i & 3); 281 imix_col(D_KEY[j], E_KEY[i]); 282 } 283 284 return 0; 285} 286 287asmlinkage void aes_enc_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in); 288asmlinkage void aes_dec_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in); 289 290static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) 291{ 292 aes_enc_blk(tfm, dst, src); 293} 294 295static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) 296{ 297 aes_dec_blk(tfm, dst, src); 298} 299 300static struct crypto_alg aes_alg = { 301 .cra_name = "aes", 302 .cra_driver_name = "aes-x86_64", 303 .cra_priority = 200, 304 .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 305 .cra_blocksize = AES_BLOCK_SIZE, 306 .cra_ctxsize = sizeof(struct aes_ctx), 307 .cra_module = THIS_MODULE, 308 .cra_list = LIST_HEAD_INIT(aes_alg.cra_list), 309 .cra_u = { 310 .cipher = { 311 .cia_min_keysize = AES_MIN_KEY_SIZE, 312 .cia_max_keysize = AES_MAX_KEY_SIZE, 313 .cia_setkey = aes_set_key, 314 .cia_encrypt = aes_encrypt, 315 .cia_decrypt = aes_decrypt 316 } 317 } 318}; 319 320static int __init aes_init(void) 321{ 322 gen_tabs(); 323 return crypto_register_alg(&aes_alg); 324} 325 326static void __exit aes_fini(void) 327{ 328 crypto_unregister_alg(&aes_alg); 329} 330 331module_init(aes_init); 332module_exit(aes_fini); 333 334MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm"); 335MODULE_LICENSE("GPL"); 336MODULE_ALIAS("aes"); 337