1ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/*
2ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta ---------------------------------------------------------------------------
3ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
4ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
5ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta LICENSE TERMS
6ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
7ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta The redistribution and use of this software (with or without changes)
8ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta is allowed without the payment of fees or royalties provided that:
9ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
10ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta  1. source code distributions include the above copyright notice, this
11ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta     list of conditions and the following disclaimer;
12ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
13ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta  2. binary distributions include the above copyright notice, this list
14ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta     of conditions and the following disclaimer in their documentation;
15ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
16ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta  3. the name of the copyright holder is not used to endorse products
17ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta     built using this software without specific written permission.
18ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
19ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta DISCLAIMER
20ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
21ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta This software is provided 'as is' with no explicit or implied warranties
22ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta in respect of its properties, including, but not limited to, correctness
23ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta and/or fitness for purpose.
24ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta ---------------------------------------------------------------------------
25ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta Issue 09/09/2006
26ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
27ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta This is an AES implementation that uses only 8-bit byte operations on the
28ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta cipher state (there are options to use 32-bit types if available).
29ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
30ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta The combination of mix columns and byte substitution used here is based on
31ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta that developed by Karl Malbrain. His contribution is acknowledged.
32ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta */
33ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
34ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/* define if you have a fast memcpy function on your system */
35ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if 1
36ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#  define HAVE_MEMCPY
37ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#  include <string.h>
38ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if 0
39ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#  if defined( _MSC_VER )
40ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#    include <intrin.h>
41ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#    pragma intrinsic( memcpy )
42ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#  endif
43ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
44ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
45ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
46ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#include <stdlib.h>
47ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
48ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/* define if you have fast 32-bit types on your system */
49ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if 1
50ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#  define HAVE_UINT_32T
51ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
52ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
53ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/* define if you don't want any tables */
54ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if 1
55ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#  define USE_TABLES
56ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
57ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
58ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/*  On Intel Core 2 duo VERSION_1 is faster */
59ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
60ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/* alternative versions (test for performance on your system) */
61ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if 1
62ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#  define VERSION_1
63ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
64ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
65ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#include "aes.h"
66ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
67ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( HAVE_UINT_32T )
68ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta  typedef unsigned long uint_32t;
69ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
70ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
71ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/* functions for finite field multiplication in the AES Galois field    */
72ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
73ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define WPOLY   0x011b
74ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define BPOLY     0x1b
75ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define DPOLY   0x008d
76ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
77ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define f1(x)   (x)
78ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define f2(x)   ((x << 1) ^ (((x >> 7) & 1) * WPOLY))
79ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define f4(x)   ((x << 2) ^ (((x >> 6) & 1) * WPOLY) ^ (((x >> 6) & 2) * WPOLY))
80ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define f8(x)   ((x << 3) ^ (((x >> 5) & 1) * WPOLY) ^ (((x >> 5) & 2) * WPOLY) \
81ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                          ^ (((x >> 5) & 4) * WPOLY))
82ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define d2(x)   (((x) >> 1) ^ ((x) & 1 ? DPOLY : 0))
83ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
84ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define f3(x)   (f2(x) ^ x)
85ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define f9(x)   (f8(x) ^ x)
86ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define fb(x)   (f8(x) ^ f2(x) ^ x)
87ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define fd(x)   (f8(x) ^ f4(x) ^ x)
88ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define fe(x)   (f8(x) ^ f4(x) ^ f2(x))
89ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
90ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( USE_TABLES )
91ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
92ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define sb_data(w) {    /* S Box data values */                            \
93ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
94ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
95ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
96ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
97ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
98ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
99ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
100ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
101ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
102ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
103ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
104ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
105ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
106ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
107ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
108ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
109ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
110ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
111ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
112ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
113ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
114ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
115ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
116ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
117ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
118ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
119ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
120ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
121ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
122ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
123ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
124ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) }
125ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
126ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define isb_data(w) {   /* inverse S Box data values */                    \
127ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
128ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
129ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
130ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\
131ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\
132ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\
133ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\
134ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\
135ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\
136ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\
137ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\
138ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\
139ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\
140ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\
141ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\
142ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\
143ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\
144ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\
145ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\
146ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\
147ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\
148ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\
149ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\
150ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\
151ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\
152ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\
153ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\
154ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\
155ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
156ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
157ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
158ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d) }
159ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
160ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define mm_data(w) {    /* basic data for forming finite field tables */   \
161ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
162ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
163ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
164ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\
165ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\
166ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\
167ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\
168ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\
169ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\
170ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\
171ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\
172ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\
173ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\
174ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\
175ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\
176ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\
177ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\
178ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\
179ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\
180ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\
181ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\
182ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\
183ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\
184ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\
185ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\
186ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\
187ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\
188ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\
189ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
190ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
191ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
192ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) }
193ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
194ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic const uint_8t sbox[256]  =  sb_data(f1);
195ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic const uint_8t isbox[256] = isb_data(f1);
196ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
197ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic const uint_8t gfm2_sbox[256] = sb_data(f2);
198ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic const uint_8t gfm3_sbox[256] = sb_data(f3);
199ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
200ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic const uint_8t gfmul_9[256] = mm_data(f9);
201ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic const uint_8t gfmul_b[256] = mm_data(fb);
202ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic const uint_8t gfmul_d[256] = mm_data(fd);
203ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic const uint_8t gfmul_e[256] = mm_data(fe);
204ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
205ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define s_box(x)     sbox[(x)]
206ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define is_box(x)    isbox[(x)]
207ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define gfm2_sb(x)   gfm2_sbox[(x)]
208ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define gfm3_sb(x)   gfm3_sbox[(x)]
209ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define gfm_9(x)     gfmul_9[(x)]
210ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define gfm_b(x)     gfmul_b[(x)]
211ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define gfm_d(x)     gfmul_d[(x)]
212ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define gfm_e(x)     gfmul_e[(x)]
213ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
214ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#else
215ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
216ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/* this is the high bit of x right shifted by 1 */
217ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/* position. Since the starting polynomial has  */
218ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/* 9 bits (0x11b), this right shift keeps the   */
219ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/* values of all top bits within a byte         */
220ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
221ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic uint_8t hibit(const uint_8t x)
222ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{   uint_8t r = (uint_8t)((x >> 1) | (x >> 2));
223ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
224ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    r |= (r >> 2);
225ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    r |= (r >> 4);
226ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    return (r + 1) >> 1;
227ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
228ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
229ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/* return the inverse of the finite field element x */
230ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
231ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic uint_8t gf_inv(const uint_8t x)
232ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{   uint_8t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
233ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
234ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    if(x < 2)
235ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        return x;
236ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
237ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    for( ; ; )
238ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {
239ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        if(n1)
240ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            while(n2 >= n1)             /* divide polynomial p2 by p1    */
241ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            {
242ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                n2 /= n1;               /* shift smaller polynomial left */
243ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                p2 ^= (p1 * n2) & 0xff; /* and remove from larger one    */
244ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                v2 ^= (v1 * n2);        /* shift accumulated value and   */
245ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                n2 = hibit(p2);         /* add into result               */
246ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            }
247ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        else
248ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            return v1;
249ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
250ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        if(n2)                          /* repeat with values swapped    */
251ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            while(n1 >= n2)
252ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            {
253ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                n1 /= n2;
254ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                p1 ^= p2 * n1;
255ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                v1 ^= v2 * n1;
256ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                n1 = hibit(p1);
257ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            }
258ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        else
259ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            return v2;
260ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
261ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
262ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
263ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/* The forward and inverse affine transformations used in the S-box */
264ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battauint_8t fwd_affine(const uint_8t x)
265ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{
266ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( HAVE_UINT_32T )
267ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    uint_32t w = x;
268ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4);
269ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    return 0x63 ^ ((w ^ (w >> 8)) & 0xff);
270ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#else
271ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    return 0x63 ^ x ^ (x << 1) ^ (x << 2) ^ (x << 3) ^ (x << 4)
272ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    ^ (x >> 7) ^ (x >> 6) ^ (x >> 5) ^ (x >> 4);
273ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
274ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
275ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
276ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battauint_8t inv_affine(const uint_8t x)
277ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{
278ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( HAVE_UINT_32T )
279ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    uint_32t w = x;
280ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    w = (w << 1) ^ (w << 3) ^ (w << 6);
281ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    return 0x05 ^ ((w ^ (w >> 8)) & 0xff);
282ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#else
283ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    return 0x05 ^ (x << 1) ^ (x << 3) ^ (x << 6)
284ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                ^ (x >> 7) ^ (x >> 5) ^ (x >> 2);
285ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
286ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
287ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
288ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define s_box(x)   fwd_affine(gf_inv(x))
289ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define is_box(x)  gf_inv(inv_affine(x))
290ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define gfm2_sb(x) f2(s_box(x))
291ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define gfm3_sb(x) f3(s_box(x))
292ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define gfm_9(x)   f9(x)
293ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define gfm_b(x)   fb(x)
294ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define gfm_d(x)   fd(x)
295ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#define gfm_e(x)   fe(x)
296ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
297ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
298ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
299ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( HAVE_MEMCPY )
300ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#  define block_copy_nn(d, s, l)    memcpy(d, s, l)
301ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#  define block_copy(d, s)          memcpy(d, s, N_BLOCK)
302ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#else
303ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#  define block_copy_nn(d, s, l)    copy_block_nn(d, s, l)
304ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#  define block_copy(d, s)          copy_block(d, s)
305ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
306ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
307ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if !defined( HAVE_MEMCPY )
308ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic void copy_block( void *d, const void *s )
309ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{
310ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( HAVE_UINT_32T )
311ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_32t*)d)[ 0] = ((uint_32t*)s)[ 0];
312ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_32t*)d)[ 1] = ((uint_32t*)s)[ 1];
313ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_32t*)d)[ 2] = ((uint_32t*)s)[ 2];
314ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_32t*)d)[ 3] = ((uint_32t*)s)[ 3];
315ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#else
316ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 0] = ((uint_8t*)s)[ 0];
317ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 1] = ((uint_8t*)s)[ 1];
318ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 2] = ((uint_8t*)s)[ 2];
319ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 3] = ((uint_8t*)s)[ 3];
320ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 4] = ((uint_8t*)s)[ 4];
321ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 5] = ((uint_8t*)s)[ 5];
322ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 6] = ((uint_8t*)s)[ 6];
323ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 7] = ((uint_8t*)s)[ 7];
324ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 8] = ((uint_8t*)s)[ 8];
325ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 9] = ((uint_8t*)s)[ 9];
326ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[10] = ((uint_8t*)s)[10];
327ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[11] = ((uint_8t*)s)[11];
328ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[12] = ((uint_8t*)s)[12];
329ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[13] = ((uint_8t*)s)[13];
330ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[14] = ((uint_8t*)s)[14];
331ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[15] = ((uint_8t*)s)[15];
332ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
333ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
334ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
335ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic void copy_block_nn( void * d, const void *s, uint_8t nn )
336ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{
337ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    while( nn-- )
338ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        *((uint_8t*)d)++ = *((uint_8t*)s)++;
339ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
340ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
341ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
342ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic void xor_block( void *d, const void *s )
343ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{
344ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( HAVE_UINT_32T )
345ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_32t*)d)[ 0] ^= ((uint_32t*)s)[ 0];
346ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_32t*)d)[ 1] ^= ((uint_32t*)s)[ 1];
347ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_32t*)d)[ 2] ^= ((uint_32t*)s)[ 2];
348ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_32t*)d)[ 3] ^= ((uint_32t*)s)[ 3];
349ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#else
350ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 0] ^= ((uint_8t*)s)[ 0];
351ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 1] ^= ((uint_8t*)s)[ 1];
352ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 2] ^= ((uint_8t*)s)[ 2];
353ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 3] ^= ((uint_8t*)s)[ 3];
354ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 4] ^= ((uint_8t*)s)[ 4];
355ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 5] ^= ((uint_8t*)s)[ 5];
356ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 6] ^= ((uint_8t*)s)[ 6];
357ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 7] ^= ((uint_8t*)s)[ 7];
358ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 8] ^= ((uint_8t*)s)[ 8];
359ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 9] ^= ((uint_8t*)s)[ 9];
360ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[10] ^= ((uint_8t*)s)[10];
361ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[11] ^= ((uint_8t*)s)[11];
362ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[12] ^= ((uint_8t*)s)[12];
363ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[13] ^= ((uint_8t*)s)[13];
364ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[14] ^= ((uint_8t*)s)[14];
365ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[15] ^= ((uint_8t*)s)[15];
366ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
367ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
368ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
369ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic void copy_and_key( void *d, const void *s, const void *k )
370ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{
371ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( HAVE_UINT_32T )
372ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_32t*)d)[ 0] = ((uint_32t*)s)[ 0] ^ ((uint_32t*)k)[ 0];
373ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_32t*)d)[ 1] = ((uint_32t*)s)[ 1] ^ ((uint_32t*)k)[ 1];
374ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_32t*)d)[ 2] = ((uint_32t*)s)[ 2] ^ ((uint_32t*)k)[ 2];
375ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_32t*)d)[ 3] = ((uint_32t*)s)[ 3] ^ ((uint_32t*)k)[ 3];
376ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#elif 1
377ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 0] = ((uint_8t*)s)[ 0] ^ ((uint_8t*)k)[ 0];
378ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 1] = ((uint_8t*)s)[ 1] ^ ((uint_8t*)k)[ 1];
379ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 2] = ((uint_8t*)s)[ 2] ^ ((uint_8t*)k)[ 2];
380ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 3] = ((uint_8t*)s)[ 3] ^ ((uint_8t*)k)[ 3];
381ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 4] = ((uint_8t*)s)[ 4] ^ ((uint_8t*)k)[ 4];
382ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 5] = ((uint_8t*)s)[ 5] ^ ((uint_8t*)k)[ 5];
383ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 6] = ((uint_8t*)s)[ 6] ^ ((uint_8t*)k)[ 6];
384ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 7] = ((uint_8t*)s)[ 7] ^ ((uint_8t*)k)[ 7];
385ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 8] = ((uint_8t*)s)[ 8] ^ ((uint_8t*)k)[ 8];
386ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[ 9] = ((uint_8t*)s)[ 9] ^ ((uint_8t*)k)[ 9];
387ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[10] = ((uint_8t*)s)[10] ^ ((uint_8t*)k)[10];
388ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[11] = ((uint_8t*)s)[11] ^ ((uint_8t*)k)[11];
389ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[12] = ((uint_8t*)s)[12] ^ ((uint_8t*)k)[12];
390ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[13] = ((uint_8t*)s)[13] ^ ((uint_8t*)k)[13];
391ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[14] = ((uint_8t*)s)[14] ^ ((uint_8t*)k)[14];
392ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ((uint_8t*)d)[15] = ((uint_8t*)s)[15] ^ ((uint_8t*)k)[15];
393ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#else
394ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    block_copy(d, s);
395ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    xor_block(d, k);
396ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
397ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
398ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
399ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic void add_round_key( uint_8t d[N_BLOCK], const uint_8t k[N_BLOCK] )
400ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{
401ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    xor_block(d, k);
402ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
403ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
404ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic void shift_sub_rows( uint_8t st[N_BLOCK] )
405ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{   uint_8t tt;
406ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
407ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    st[ 0] = s_box(st[ 0]); st[ 4] = s_box(st[ 4]);
408ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    st[ 8] = s_box(st[ 8]); st[12] = s_box(st[12]);
409ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
410ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    tt = st[1]; st[ 1] = s_box(st[ 5]); st[ 5] = s_box(st[ 9]);
411ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    st[ 9] = s_box(st[13]); st[13] = s_box( tt );
412ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
413ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    tt = st[2]; st[ 2] = s_box(st[10]); st[10] = s_box( tt );
414ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    tt = st[6]; st[ 6] = s_box(st[14]); st[14] = s_box( tt );
415ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
416ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    tt = st[15]; st[15] = s_box(st[11]); st[11] = s_box(st[ 7]);
417ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    st[ 7] = s_box(st[ 3]); st[ 3] = s_box( tt );
418ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
419ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
420ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic void inv_shift_sub_rows( uint_8t st[N_BLOCK] )
421ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{   uint_8t tt;
422ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
423ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    st[ 0] = is_box(st[ 0]); st[ 4] = is_box(st[ 4]);
424ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    st[ 8] = is_box(st[ 8]); st[12] = is_box(st[12]);
425ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
426ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    tt = st[13]; st[13] = is_box(st[9]); st[ 9] = is_box(st[5]);
427ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    st[ 5] = is_box(st[1]); st[ 1] = is_box( tt );
428ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
429ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    tt = st[2]; st[ 2] = is_box(st[10]); st[10] = is_box( tt );
430ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    tt = st[6]; st[ 6] = is_box(st[14]); st[14] = is_box( tt );
431ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
432ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    tt = st[3]; st[ 3] = is_box(st[ 7]); st[ 7] = is_box(st[11]);
433ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    st[11] = is_box(st[15]); st[15] = is_box( tt );
434ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
435ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
436ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( VERSION_1 )
437ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta  static void mix_sub_columns( uint_8t dt[N_BLOCK] )
438ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta  { uint_8t st[N_BLOCK];
439ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    block_copy(st, dt);
440ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#else
441ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta  static void mix_sub_columns( uint_8t dt[N_BLOCK], uint_8t st[N_BLOCK] )
442ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta  {
443ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
444ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[ 0] = gfm2_sb(st[0]) ^ gfm3_sb(st[5]) ^ s_box(st[10]) ^ s_box(st[15]);
445ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[ 1] = s_box(st[0]) ^ gfm2_sb(st[5]) ^ gfm3_sb(st[10]) ^ s_box(st[15]);
446ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[ 2] = s_box(st[0]) ^ s_box(st[5]) ^ gfm2_sb(st[10]) ^ gfm3_sb(st[15]);
447ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[ 3] = gfm3_sb(st[0]) ^ s_box(st[5]) ^ s_box(st[10]) ^ gfm2_sb(st[15]);
448ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
449ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[ 4] = gfm2_sb(st[4]) ^ gfm3_sb(st[9]) ^ s_box(st[14]) ^ s_box(st[3]);
450ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[ 5] = s_box(st[4]) ^ gfm2_sb(st[9]) ^ gfm3_sb(st[14]) ^ s_box(st[3]);
451ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[ 6] = s_box(st[4]) ^ s_box(st[9]) ^ gfm2_sb(st[14]) ^ gfm3_sb(st[3]);
452ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[ 7] = gfm3_sb(st[4]) ^ s_box(st[9]) ^ s_box(st[14]) ^ gfm2_sb(st[3]);
453ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
454ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[ 8] = gfm2_sb(st[8]) ^ gfm3_sb(st[13]) ^ s_box(st[2]) ^ s_box(st[7]);
455ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[ 9] = s_box(st[8]) ^ gfm2_sb(st[13]) ^ gfm3_sb(st[2]) ^ s_box(st[7]);
456ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[10] = s_box(st[8]) ^ s_box(st[13]) ^ gfm2_sb(st[2]) ^ gfm3_sb(st[7]);
457ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[11] = gfm3_sb(st[8]) ^ s_box(st[13]) ^ s_box(st[2]) ^ gfm2_sb(st[7]);
458ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
459ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[12] = gfm2_sb(st[12]) ^ gfm3_sb(st[1]) ^ s_box(st[6]) ^ s_box(st[11]);
460ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[13] = s_box(st[12]) ^ gfm2_sb(st[1]) ^ gfm3_sb(st[6]) ^ s_box(st[11]);
461ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[14] = s_box(st[12]) ^ s_box(st[1]) ^ gfm2_sb(st[6]) ^ gfm3_sb(st[11]);
462ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[15] = gfm3_sb(st[12]) ^ s_box(st[1]) ^ s_box(st[6]) ^ gfm2_sb(st[11]);
463ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta  }
464ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
465ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( VERSION_1 )
466ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta  static void inv_mix_sub_columns( uint_8t dt[N_BLOCK] )
467ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta  { uint_8t st[N_BLOCK];
468ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    block_copy(st, dt);
469ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#else
470ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta  static void inv_mix_sub_columns( uint_8t dt[N_BLOCK], uint_8t st[N_BLOCK] )
471ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta  {
472ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
473ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[ 0] = is_box(gfm_e(st[ 0]) ^ gfm_b(st[ 1]) ^ gfm_d(st[ 2]) ^ gfm_9(st[ 3]));
474ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[ 5] = is_box(gfm_9(st[ 0]) ^ gfm_e(st[ 1]) ^ gfm_b(st[ 2]) ^ gfm_d(st[ 3]));
475ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[10] = is_box(gfm_d(st[ 0]) ^ gfm_9(st[ 1]) ^ gfm_e(st[ 2]) ^ gfm_b(st[ 3]));
476ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[15] = is_box(gfm_b(st[ 0]) ^ gfm_d(st[ 1]) ^ gfm_9(st[ 2]) ^ gfm_e(st[ 3]));
477ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
478ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[ 4] = is_box(gfm_e(st[ 4]) ^ gfm_b(st[ 5]) ^ gfm_d(st[ 6]) ^ gfm_9(st[ 7]));
479ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[ 9] = is_box(gfm_9(st[ 4]) ^ gfm_e(st[ 5]) ^ gfm_b(st[ 6]) ^ gfm_d(st[ 7]));
480ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[14] = is_box(gfm_d(st[ 4]) ^ gfm_9(st[ 5]) ^ gfm_e(st[ 6]) ^ gfm_b(st[ 7]));
481ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[ 3] = is_box(gfm_b(st[ 4]) ^ gfm_d(st[ 5]) ^ gfm_9(st[ 6]) ^ gfm_e(st[ 7]));
482ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
483ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[ 8] = is_box(gfm_e(st[ 8]) ^ gfm_b(st[ 9]) ^ gfm_d(st[10]) ^ gfm_9(st[11]));
484ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[13] = is_box(gfm_9(st[ 8]) ^ gfm_e(st[ 9]) ^ gfm_b(st[10]) ^ gfm_d(st[11]));
485ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[ 2] = is_box(gfm_d(st[ 8]) ^ gfm_9(st[ 9]) ^ gfm_e(st[10]) ^ gfm_b(st[11]));
486ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[ 7] = is_box(gfm_b(st[ 8]) ^ gfm_d(st[ 9]) ^ gfm_9(st[10]) ^ gfm_e(st[11]));
487ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
488ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[12] = is_box(gfm_e(st[12]) ^ gfm_b(st[13]) ^ gfm_d(st[14]) ^ gfm_9(st[15]));
489ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[ 1] = is_box(gfm_9(st[12]) ^ gfm_e(st[13]) ^ gfm_b(st[14]) ^ gfm_d(st[15]));
490ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[ 6] = is_box(gfm_d(st[12]) ^ gfm_9(st[13]) ^ gfm_e(st[14]) ^ gfm_b(st[15]));
491ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    dt[11] = is_box(gfm_b(st[12]) ^ gfm_d(st[13]) ^ gfm_9(st[14]) ^ gfm_e(st[15]));
492ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta  }
493ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
494ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( AES_ENC_PREKEYED ) || defined( AES_DEC_PREKEYED )
495ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
496ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/*  Set the cipher key for the pre-keyed version */
497ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
498ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battareturn_type aes_set_key( const unsigned char key[], length_type keylen, aes_context ctx[1] )
499ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{
500ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    uint_8t cc, rc, hi;
501ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
502ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    switch( keylen )
503ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {
504ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    case 16:
505ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    case 128:
506ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        keylen = 16;
507ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        break;
508ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    case 24:
509ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    case 192:
510ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        keylen = 24;
511ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        break;
512ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    case 32:
51316fe0822ccd3eb6f66d3afd9965d25a0a0cb4c30Prerepa Viswanadham    /*    case 256:           length in bits (256 = 8*32) */
514ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        keylen = 32;
515ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        break;
516ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    default:
517ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        ctx->rnd = 0;
518ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        return (return_type)-1;
519ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
520ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    block_copy_nn(ctx->ksch, key, keylen);
521ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    hi = (keylen + 28) << 2;
522ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    ctx->rnd = (hi >> 4) - 1;
523ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    for( cc = keylen, rc = 1; cc < hi; cc += 4 )
524ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {   uint_8t tt, t0, t1, t2, t3;
525ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
526ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        t0 = ctx->ksch[cc - 4];
527ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        t1 = ctx->ksch[cc - 3];
528ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        t2 = ctx->ksch[cc - 2];
529ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        t3 = ctx->ksch[cc - 1];
530ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        if( cc % keylen == 0 )
531ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        {
532ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            tt = t0;
533ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            t0 = s_box(t1) ^ rc;
534ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            t1 = s_box(t2);
535ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            t2 = s_box(t3);
536ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            t3 = s_box(tt);
537ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            rc = f2(rc);
538ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        }
539ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        else if( keylen > 24 && cc % keylen == 16 )
540ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        {
541ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            t0 = s_box(t0);
542ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            t1 = s_box(t1);
543ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            t2 = s_box(t2);
544ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            t3 = s_box(t3);
545ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        }
546ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        tt = cc - keylen;
547ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        ctx->ksch[cc + 0] = ctx->ksch[tt + 0] ^ t0;
548ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        ctx->ksch[cc + 1] = ctx->ksch[tt + 1] ^ t1;
549ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        ctx->ksch[cc + 2] = ctx->ksch[tt + 2] ^ t2;
550ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        ctx->ksch[cc + 3] = ctx->ksch[tt + 3] ^ t3;
551ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
552ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    return 0;
553ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
554ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
555ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
556ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
557ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( AES_ENC_PREKEYED )
558ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
559ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/*  Encrypt a single block of 16 bytes */
560ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
561ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battareturn_type aes_encrypt( const unsigned char in[N_BLOCK], unsigned char  out[N_BLOCK], const aes_context ctx[1] )
562ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{
563ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    if( ctx->rnd )
564ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {
565ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        uint_8t s1[N_BLOCK], r;
566ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        copy_and_key( s1, in, ctx->ksch );
567ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
568ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        for( r = 1 ; r < ctx->rnd ; ++r )
569ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( VERSION_1 )
570ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        {
571ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            mix_sub_columns( s1 );
572ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            add_round_key( s1, ctx->ksch + r * N_BLOCK);
573ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        }
574ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#else
575ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        {   uint_8t s2[N_BLOCK];
576ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            mix_sub_columns( s2, s1 );
577ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            copy_and_key( s1, s2, ctx->ksch + r * N_BLOCK);
578ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        }
579ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
580ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        shift_sub_rows( s1 );
581ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        copy_and_key( out, s1, ctx->ksch + r * N_BLOCK );
582ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
583ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    else
584ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        return (return_type)-1;
585ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    return 0;
586ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
587ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
588ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/* CBC encrypt a number of blocks (input and return an IV) */
589ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
590ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battareturn_type aes_cbc_encrypt( const unsigned char *in, unsigned char *out,
591ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                         int n_block, unsigned char iv[N_BLOCK], const aes_context ctx[1] )
592ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{
593ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
594ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    while(n_block--)
595ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {
596ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        xor_block(iv, in);
597ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
598ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta			return EXIT_FAILURE;
599ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        memcpy(out, iv, N_BLOCK);
600ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        in += N_BLOCK;
601ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        out += N_BLOCK;
602ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
603ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    return EXIT_SUCCESS;
604ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
605ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
606ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
607ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
608ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( AES_DEC_PREKEYED )
609ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
610ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/*  Decrypt a single block of 16 bytes */
611ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
612ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battareturn_type aes_decrypt( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK], const aes_context ctx[1] )
613ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{
614ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    if( ctx->rnd )
615ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {
616ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        uint_8t s1[N_BLOCK], r;
617ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        copy_and_key( s1, in, ctx->ksch + ctx->rnd * N_BLOCK );
618ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        inv_shift_sub_rows( s1 );
619ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
620ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        for( r = ctx->rnd ; --r ; )
621ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( VERSION_1 )
622ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        {
623ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            add_round_key( s1, ctx->ksch + r * N_BLOCK );
624ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            inv_mix_sub_columns( s1 );
625ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        }
626ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#else
627ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        {   uint_8t s2[N_BLOCK];
628ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            copy_and_key( s2, s1, ctx->ksch + r * N_BLOCK );
629ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            inv_mix_sub_columns( s1, s2 );
630ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        }
631ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
632ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        copy_and_key( out, s1, ctx->ksch );
633ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
634ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    else
635ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        return (return_type)-1;
636ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    return 0;
637ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
638ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
639ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/* CBC decrypt a number of blocks (input and return an IV) */
640ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
641ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battareturn_type aes_cbc_decrypt( const unsigned char *in, unsigned char *out,
642ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                         int n_block, unsigned char iv[N_BLOCK], const aes_context ctx[1] )
643ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{
644ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    while(n_block--)
645ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {   uint_8t tmp[N_BLOCK];
646ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
647ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        memcpy(tmp, in, N_BLOCK);
648ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        if(aes_decrypt(in, out, ctx) != EXIT_SUCCESS)
649ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta			return EXIT_FAILURE;
650ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        xor_block(out, iv);
651ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        memcpy(iv, tmp, N_BLOCK);
652ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        in += N_BLOCK;
653ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        out += N_BLOCK;
654ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
655ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    return EXIT_SUCCESS;
656ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
657ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
658ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
659ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
660ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( AES_ENC_128_OTFK )
661ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
662ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/*  The 'on the fly' encryption key update for for 128 bit keys */
663ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
664ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic void update_encrypt_key_128( uint_8t k[N_BLOCK], uint_8t *rc )
665ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{   uint_8t cc;
666ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
667ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[0] ^= s_box(k[13]) ^ *rc;
668ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[1] ^= s_box(k[14]);
669ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[2] ^= s_box(k[15]);
670ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[3] ^= s_box(k[12]);
671ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    *rc = f2( *rc );
672ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
673ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    for(cc = 4; cc < 16; cc += 4 )
674ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {
675ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 0] ^= k[cc - 4];
676ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 1] ^= k[cc - 3];
677ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 2] ^= k[cc - 2];
678ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 3] ^= k[cc - 1];
679ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
680ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
681ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
682ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/*  Encrypt a single block of 16 bytes with 'on the fly' 128 bit keying */
683ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
684ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battavoid aes_encrypt_128( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK],
685ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                     const unsigned char key[N_BLOCK], unsigned char o_key[N_BLOCK] )
686ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{   uint_8t s1[N_BLOCK], r, rc = 1;
687ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
688ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    if(o_key != key)
689ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        block_copy( o_key, key );
690ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    copy_and_key( s1, in, o_key );
691ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
692ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    for( r = 1 ; r < 10 ; ++r )
693ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( VERSION_1 )
694ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {
695ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        mix_sub_columns( s1 );
696ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        update_encrypt_key_128( o_key, &rc );
697ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        add_round_key( s1, o_key );
698ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
699ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#else
700ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {   uint_8t s2[N_BLOCK];
701ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        mix_sub_columns( s2, s1 );
702ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        update_encrypt_key_128( o_key, &rc );
703ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        copy_and_key( s1, s2, o_key );
704ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
705ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
706ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
707ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    shift_sub_rows( s1 );
708ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    update_encrypt_key_128( o_key, &rc );
709ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    copy_and_key( out, s1, o_key );
710ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
711ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
712ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
713ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
714ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( AES_DEC_128_OTFK )
715ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
716ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/*  The 'on the fly' decryption key update for for 128 bit keys */
717ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
718ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic void update_decrypt_key_128( uint_8t k[N_BLOCK], uint_8t *rc )
719ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{   uint_8t cc;
720ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
721ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    for( cc = 12; cc > 0; cc -= 4 )
722ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {
723ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 0] ^= k[cc - 4];
724ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 1] ^= k[cc - 3];
725ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 2] ^= k[cc - 2];
726ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 3] ^= k[cc - 1];
727ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
728ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    *rc = d2(*rc);
729ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[0] ^= s_box(k[13]) ^ *rc;
730ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[1] ^= s_box(k[14]);
731ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[2] ^= s_box(k[15]);
732ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[3] ^= s_box(k[12]);
733ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
734ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
735ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/*  Decrypt a single block of 16 bytes with 'on the fly' 128 bit keying */
736ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
737ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battavoid aes_decrypt_128( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK],
738ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                      const unsigned char key[N_BLOCK], unsigned char o_key[N_BLOCK] )
739ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{
740ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    uint_8t s1[N_BLOCK], r, rc = 0x6c;
741ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    if(o_key != key)
742ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        block_copy( o_key, key );
743ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
744ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    copy_and_key( s1, in, o_key );
745ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    inv_shift_sub_rows( s1 );
746ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
747ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    for( r = 10 ; --r ; )
748ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( VERSION_1 )
749ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {
750ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        update_decrypt_key_128( o_key, &rc );
751ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        add_round_key( s1, o_key );
752ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        inv_mix_sub_columns( s1 );
753ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
754ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#else
755ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {   uint_8t s2[N_BLOCK];
756ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        update_decrypt_key_128( o_key, &rc );
757ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        copy_and_key( s2, s1, o_key );
758ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        inv_mix_sub_columns( s1, s2 );
759ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
760ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
761ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    update_decrypt_key_128( o_key, &rc );
762ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    copy_and_key( out, s1, o_key );
763ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
764ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
765ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
766ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
767ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( AES_ENC_256_OTFK )
768ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
769ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/*  The 'on the fly' encryption key update for for 256 bit keys */
770ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
771ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic void update_encrypt_key_256( uint_8t k[2 * N_BLOCK], uint_8t *rc )
772ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{   uint_8t cc;
773ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
774ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[0] ^= s_box(k[29]) ^ *rc;
775ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[1] ^= s_box(k[30]);
776ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[2] ^= s_box(k[31]);
777ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[3] ^= s_box(k[28]);
778ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    *rc = f2( *rc );
779ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
780ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    for(cc = 4; cc < 16; cc += 4)
781ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {
782ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 0] ^= k[cc - 4];
783ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 1] ^= k[cc - 3];
784ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 2] ^= k[cc - 2];
785ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 3] ^= k[cc - 1];
786ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
787ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
788ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[16] ^= s_box(k[12]);
789ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[17] ^= s_box(k[13]);
790ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[18] ^= s_box(k[14]);
791ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[19] ^= s_box(k[15]);
792ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
793ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    for( cc = 20; cc < 32; cc += 4 )
794ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {
795ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 0] ^= k[cc - 4];
796ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 1] ^= k[cc - 3];
797ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 2] ^= k[cc - 2];
798ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 3] ^= k[cc - 1];
799ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
800ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
801ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
802ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/*  Encrypt a single block of 16 bytes with 'on the fly' 256 bit keying */
803ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
804ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battavoid aes_encrypt_256( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK],
805ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                      const unsigned char key[2 * N_BLOCK], unsigned char o_key[2 * N_BLOCK] )
806ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{
807ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    uint_8t s1[N_BLOCK], r, rc = 1;
808ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    if(o_key != key)
809ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {
810ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        block_copy( o_key, key );
811ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        block_copy( o_key + 16, key + 16 );
812ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
813ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    copy_and_key( s1, in, o_key );
814ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
815ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    for( r = 1 ; r < 14 ; ++r )
816ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( VERSION_1 )
817ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {
818ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        mix_sub_columns(s1);
819ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        if( r & 1 )
820ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            add_round_key( s1, o_key + 16 );
821ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        else
822ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        {
823ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            update_encrypt_key_256( o_key, &rc );
824ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            add_round_key( s1, o_key );
825ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        }
826ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
827ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#else
828ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {   uint_8t s2[N_BLOCK];
829ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        mix_sub_columns( s2, s1 );
830ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        if( r & 1 )
831ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            copy_and_key( s1, s2, o_key + 16 );
832ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        else
833ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        {
834ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            update_encrypt_key_256( o_key, &rc );
835ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            copy_and_key( s1, s2, o_key );
836ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        }
837ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
838ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
839ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
840ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    shift_sub_rows( s1 );
841ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    update_encrypt_key_256( o_key, &rc );
842ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    copy_and_key( out, s1, o_key );
843ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
844ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
845ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
846ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
847ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( AES_DEC_256_OTFK )
848ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
849ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/*  The 'on the fly' encryption key update for for 256 bit keys */
850ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
851ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battastatic void update_decrypt_key_256( uint_8t k[2 * N_BLOCK], uint_8t *rc )
852ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{   uint_8t cc;
853ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
854ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    for(cc = 28; cc > 16; cc -= 4)
855ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {
856ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 0] ^= k[cc - 4];
857ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 1] ^= k[cc - 3];
858ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 2] ^= k[cc - 2];
859ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 3] ^= k[cc - 1];
860ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
861ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
862ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[16] ^= s_box(k[12]);
863ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[17] ^= s_box(k[13]);
864ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[18] ^= s_box(k[14]);
865ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[19] ^= s_box(k[15]);
866ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
867ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    for(cc = 12; cc > 0; cc -= 4)
868ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {
869ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 0] ^= k[cc - 4];
870ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 1] ^= k[cc - 3];
871ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 2] ^= k[cc - 2];
872ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        k[cc + 3] ^= k[cc - 1];
873ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
874ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
875ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    *rc = d2(*rc);
876ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[0] ^= s_box(k[29]) ^ *rc;
877ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[1] ^= s_box(k[30]);
878ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[2] ^= s_box(k[31]);
879ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    k[3] ^= s_box(k[28]);
880ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
881ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
882ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/*  Decrypt a single block of 16 bytes with 'on the fly'
883ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    256 bit keying
884ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta*/
885ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battavoid aes_decrypt_256( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK],
886ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                      const unsigned char key[2 * N_BLOCK], unsigned char o_key[2 * N_BLOCK] )
887ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{
888ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    uint_8t s1[N_BLOCK], r, rc = 0x80;
889ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
890ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    if(o_key != key)
891ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {
892ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        block_copy( o_key, key );
893ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        block_copy( o_key + 16, key + 16 );
894ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
895ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
896ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    copy_and_key( s1, in, o_key );
897ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    inv_shift_sub_rows( s1 );
898ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
899ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    for( r = 14 ; --r ; )
900ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if defined( VERSION_1 )
901ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {
902ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        if( ( r & 1 ) )
903ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        {
904ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            update_decrypt_key_256( o_key, &rc );
905ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            add_round_key( s1, o_key + 16 );
906ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        }
907ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        else
908ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            add_round_key( s1, o_key );
909ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        inv_mix_sub_columns( s1 );
910ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
911ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#else
912ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {   uint_8t s2[N_BLOCK];
913ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        if( ( r & 1 ) )
914ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        {
915ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            update_decrypt_key_256( o_key, &rc );
916ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            copy_and_key( s2, s1, o_key + 16 );
917ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        }
918ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        else
919ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            copy_and_key( s2, s1, o_key );
920ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        inv_mix_sub_columns( s1, s2 );
921ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
922ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
923ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    copy_and_key( out, s1, o_key );
924ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
925ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
926ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
927