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@w1.fi> 13 * 14 * This software may be distributed under the terms of the BSD license. 15 * See README for more details. 16 */ 17 18#include "includes.h" 19 20#include "common.h" 21#include "crypto.h" 22#include "aes_i.h" 23 24static void rijndaelEncrypt(const u32 rk[/*44*/], const u8 pt[16], u8 ct[16]) 25{ 26 u32 s0, s1, s2, s3, t0, t1, t2, t3; 27 const int Nr = 10; 28#ifndef FULL_UNROLL 29 int r; 30#endif /* ?FULL_UNROLL */ 31 32 /* 33 * map byte array block to cipher state 34 * and add initial round key: 35 */ 36 s0 = GETU32(pt ) ^ rk[0]; 37 s1 = GETU32(pt + 4) ^ rk[1]; 38 s2 = GETU32(pt + 8) ^ rk[2]; 39 s3 = GETU32(pt + 12) ^ rk[3]; 40 41#define ROUND(i,d,s) \ 42d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \ 43d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \ 44d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \ 45d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3] 46 47#ifdef FULL_UNROLL 48 49 ROUND(1,t,s); 50 ROUND(2,s,t); 51 ROUND(3,t,s); 52 ROUND(4,s,t); 53 ROUND(5,t,s); 54 ROUND(6,s,t); 55 ROUND(7,t,s); 56 ROUND(8,s,t); 57 ROUND(9,t,s); 58 59 rk += Nr << 2; 60 61#else /* !FULL_UNROLL */ 62 63 /* Nr - 1 full rounds: */ 64 r = Nr >> 1; 65 for (;;) { 66 ROUND(1,t,s); 67 rk += 8; 68 if (--r == 0) 69 break; 70 ROUND(0,s,t); 71 } 72 73#endif /* ?FULL_UNROLL */ 74 75#undef ROUND 76 77 /* 78 * apply last round and 79 * map cipher state to byte array block: 80 */ 81 s0 = TE41(t0) ^ TE42(t1) ^ TE43(t2) ^ TE44(t3) ^ rk[0]; 82 PUTU32(ct , s0); 83 s1 = TE41(t1) ^ TE42(t2) ^ TE43(t3) ^ TE44(t0) ^ rk[1]; 84 PUTU32(ct + 4, s1); 85 s2 = TE41(t2) ^ TE42(t3) ^ TE43(t0) ^ TE44(t1) ^ rk[2]; 86 PUTU32(ct + 8, s2); 87 s3 = TE41(t3) ^ TE42(t0) ^ TE43(t1) ^ TE44(t2) ^ rk[3]; 88 PUTU32(ct + 12, s3); 89} 90 91 92void * aes_encrypt_init(const u8 *key, size_t len) 93{ 94 u32 *rk; 95 if (len != 16) 96 return NULL; 97 rk = os_malloc(AES_PRIV_SIZE); 98 if (rk == NULL) 99 return NULL; 100 rijndaelKeySetupEnc(rk, key); 101 return rk; 102} 103 104 105void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) 106{ 107 rijndaelEncrypt(ctx, plain, crypt); 108} 109 110 111void aes_encrypt_deinit(void *ctx) 112{ 113 os_memset(ctx, 0, AES_PRIV_SIZE); 114 os_free(ctx); 115} 116