1 /* 2 * AES (Rijndael) cipher - encrypt 3 * 4 * Modifications to public domain implementation: 5 * - support only 128-bit keys 6 * - cleanup 7 * - use C pre-processor to make it easier to change S table access 8 * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at 9 * cost of reduced throughput (quite small difference on Pentium 4, 10 * 10-25% when using -O1 or -O2 optimization) 11 * 12 * Copyright (c) 2003-2005, Jouni Malinen <j (at) w1.fi> 13 * 14 * This program is free software; you can redistribute it and/or modify 15 * it under the terms of the GNU General Public License version 2 as 16 * published by the Free Software Foundation. 17 * 18 * Alternatively, this software may be distributed under the terms of BSD 19 * license. 20 * 21 * See README and COPYING for more details. 22 */ 23 24 #include "includes.h" 25 26 #include "common.h" 27 #include "crypto.h" 28 #include "aes_i.h" 29 30 void rijndaelEncrypt(const u32 rk[/*44*/], const u8 pt[16], u8 ct[16]) 31 { 32 u32 s0, s1, s2, s3, t0, t1, t2, t3; 33 const int Nr = 10; 34 #ifndef FULL_UNROLL 35 int r; 36 #endif /* ?FULL_UNROLL */ 37 38 /* 39 * map byte array block to cipher state 40 * and add initial round key: 41 */ 42 s0 = GETU32(pt ) ^ rk[0]; 43 s1 = GETU32(pt + 4) ^ rk[1]; 44 s2 = GETU32(pt + 8) ^ rk[2]; 45 s3 = GETU32(pt + 12) ^ rk[3]; 46 47 #define ROUND(i,d,s) \ 48 d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \ 49 d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \ 50 d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \ 51 d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3] 52 53 #ifdef FULL_UNROLL 54 55 ROUND(1,t,s); 56 ROUND(2,s,t); 57 ROUND(3,t,s); 58 ROUND(4,s,t); 59 ROUND(5,t,s); 60 ROUND(6,s,t); 61 ROUND(7,t,s); 62 ROUND(8,s,t); 63 ROUND(9,t,s); 64 65 rk += Nr << 2; 66 67 #else /* !FULL_UNROLL */ 68 69 /* Nr - 1 full rounds: */ 70 r = Nr >> 1; 71 for (;;) { 72 ROUND(1,t,s); 73 rk += 8; 74 if (--r == 0) 75 break; 76 ROUND(0,s,t); 77 } 78 79 #endif /* ?FULL_UNROLL */ 80 81 #undef ROUND 82 83 /* 84 * apply last round and 85 * map cipher state to byte array block: 86 */ 87 s0 = TE41(t0) ^ TE42(t1) ^ TE43(t2) ^ TE44(t3) ^ rk[0]; 88 PUTU32(ct , s0); 89 s1 = TE41(t1) ^ TE42(t2) ^ TE43(t3) ^ TE44(t0) ^ rk[1]; 90 PUTU32(ct + 4, s1); 91 s2 = TE41(t2) ^ TE42(t3) ^ TE43(t0) ^ TE44(t1) ^ rk[2]; 92 PUTU32(ct + 8, s2); 93 s3 = TE41(t3) ^ TE42(t0) ^ TE43(t1) ^ TE44(t2) ^ rk[3]; 94 PUTU32(ct + 12, s3); 95 } 96 97 98 void * aes_encrypt_init(const u8 *key, size_t len) 99 { 100 u32 *rk; 101 if (len != 16) 102 return NULL; 103 rk = os_malloc(AES_PRIV_SIZE); 104 if (rk == NULL) 105 return NULL; 106 rijndaelKeySetupEnc(rk, key); 107 return rk; 108 } 109 110 111 void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) 112 { 113 rijndaelEncrypt(ctx, plain, crypt); 114 } 115 116 117 void aes_encrypt_deinit(void *ctx) 118 { 119 os_memset(ctx, 0, AES_PRIV_SIZE); 120 os_free(ctx); 121 } 122