xref: /openbmc/u-boot/lib/aes.c (revision d330e04d9d427a26381b59f40875af17f4c288a2)
1  /*
2   * Copyright (c) 2011 The Chromium OS Authors.
3   * (C) Copyright 2011 NVIDIA Corporation www.nvidia.com
4   *
5   * SPDX-License-Identifier:	GPL-2.0+
6   */
7  
8  /*
9   * advanced encryption standard
10   * author: karl malbrain, malbrain@yahoo.com
11   *
12   * This work, including the source code, documentation
13   * and related data, is placed into the public domain.
14   *
15   * The orginal author is Karl Malbrain.
16   *
17   * THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY
18   * OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF
19   * MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE,
20   * ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE
21   * RESULTING FROM THE USE, MODIFICATION, OR
22   * REDISTRIBUTION OF THIS SOFTWARE.
23  */
24  
25  #ifndef USE_HOSTCC
26  #include <common.h>
27  #else
28  #include <string.h>
29  #endif
30  #include "uboot_aes.h"
31  
32  /* forward s-box */
33  static const u8 sbox[256] = {
34  	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
35  	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
36  	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
37  	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
38  	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
39  	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
40  	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
41  	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
42  	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
43  	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
44  	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
45  	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
46  	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
47  	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
48  	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
49  	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
50  	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
51  	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
52  	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
53  	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
54  	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
55  	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
56  	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
57  	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
58  	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
59  	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
60  	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
61  	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
62  	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
63  	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
64  	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
65  	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
66  };
67  
68  /* inverse s-box */
69  static const u8 inv_sbox[256] = {
70  	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
71  	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
72  	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
73  	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
74  	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
75  	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
76  	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
77  	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
78  	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
79  	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
80  	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
81  	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
82  	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
83  	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
84  	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
85  	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
86  	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
87  	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
88  	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
89  	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
90  	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
91  	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
92  	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
93  	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
94  	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
95  	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
96  	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
97  	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
98  	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
99  	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
100  	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
101  	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
102  };
103  
104  /* combined Xtimes2[Sbox[]] */
105  static const u8 x2_sbox[256] = {
106  	0xc6, 0xf8, 0xee, 0xf6, 0xff, 0xd6, 0xde, 0x91,
107  	0x60, 0x02, 0xce, 0x56, 0xe7, 0xb5, 0x4d, 0xec,
108  	0x8f, 0x1f, 0x89, 0xfa, 0xef, 0xb2, 0x8e, 0xfb,
109  	0x41, 0xb3, 0x5f, 0x45, 0x23, 0x53, 0xe4, 0x9b,
110  	0x75, 0xe1, 0x3d, 0x4c, 0x6c, 0x7e, 0xf5, 0x83,
111  	0x68, 0x51, 0xd1, 0xf9, 0xe2, 0xab, 0x62, 0x2a,
112  	0x08, 0x95, 0x46, 0x9d, 0x30, 0x37, 0x0a, 0x2f,
113  	0x0e, 0x24, 0x1b, 0xdf, 0xcd, 0x4e, 0x7f, 0xea,
114  	0x12, 0x1d, 0x58, 0x34, 0x36, 0xdc, 0xb4, 0x5b,
115  	0xa4, 0x76, 0xb7, 0x7d, 0x52, 0xdd, 0x5e, 0x13,
116  	0xa6, 0xb9, 0x00, 0xc1, 0x40, 0xe3, 0x79, 0xb6,
117  	0xd4, 0x8d, 0x67, 0x72, 0x94, 0x98, 0xb0, 0x85,
118  	0xbb, 0xc5, 0x4f, 0xed, 0x86, 0x9a, 0x66, 0x11,
119  	0x8a, 0xe9, 0x04, 0xfe, 0xa0, 0x78, 0x25, 0x4b,
120  	0xa2, 0x5d, 0x80, 0x05, 0x3f, 0x21, 0x70, 0xf1,
121  	0x63, 0x77, 0xaf, 0x42, 0x20, 0xe5, 0xfd, 0xbf,
122  	0x81, 0x18, 0x26, 0xc3, 0xbe, 0x35, 0x88, 0x2e,
123  	0x93, 0x55, 0xfc, 0x7a, 0xc8, 0xba, 0x32, 0xe6,
124  	0xc0, 0x19, 0x9e, 0xa3, 0x44, 0x54, 0x3b, 0x0b,
125  	0x8c, 0xc7, 0x6b, 0x28, 0xa7, 0xbc, 0x16, 0xad,
126  	0xdb, 0x64, 0x74, 0x14, 0x92, 0x0c, 0x48, 0xb8,
127  	0x9f, 0xbd, 0x43, 0xc4, 0x39, 0x31, 0xd3, 0xf2,
128  	0xd5, 0x8b, 0x6e, 0xda, 0x01, 0xb1, 0x9c, 0x49,
129  	0xd8, 0xac, 0xf3, 0xcf, 0xca, 0xf4, 0x47, 0x10,
130  	0x6f, 0xf0, 0x4a, 0x5c, 0x38, 0x57, 0x73, 0x97,
131  	0xcb, 0xa1, 0xe8, 0x3e, 0x96, 0x61, 0x0d, 0x0f,
132  	0xe0, 0x7c, 0x71, 0xcc, 0x90, 0x06, 0xf7, 0x1c,
133  	0xc2, 0x6a, 0xae, 0x69, 0x17, 0x99, 0x3a, 0x27,
134  	0xd9, 0xeb, 0x2b, 0x22, 0xd2, 0xa9, 0x07, 0x33,
135  	0x2d, 0x3c, 0x15, 0xc9, 0x87, 0xaa, 0x50, 0xa5,
136  	0x03, 0x59, 0x09, 0x1a, 0x65, 0xd7, 0x84, 0xd0,
137  	0x82, 0x29, 0x5a, 0x1e, 0x7b, 0xa8, 0x6d, 0x2c
138  };
139  
140  /* combined Xtimes3[Sbox[]] */
141  static const u8 x3_sbox[256] = {
142  	0xa5, 0x84, 0x99, 0x8d, 0x0d, 0xbd, 0xb1, 0x54,
143  	0x50, 0x03, 0xa9, 0x7d, 0x19, 0x62, 0xe6, 0x9a,
144  	0x45, 0x9d, 0x40, 0x87, 0x15, 0xeb, 0xc9, 0x0b,
145  	0xec, 0x67, 0xfd, 0xea, 0xbf, 0xf7, 0x96, 0x5b,
146  	0xc2, 0x1c, 0xae, 0x6a, 0x5a, 0x41, 0x02, 0x4f,
147  	0x5c, 0xf4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3f,
148  	0x0c, 0x52, 0x65, 0x5e, 0x28, 0xa1, 0x0f, 0xb5,
149  	0x09, 0x36, 0x9b, 0x3d, 0x26, 0x69, 0xcd, 0x9f,
150  	0x1b, 0x9e, 0x74, 0x2e, 0x2d, 0xb2, 0xee, 0xfb,
151  	0xf6, 0x4d, 0x61, 0xce, 0x7b, 0x3e, 0x71, 0x97,
152  	0xf5, 0x68, 0x00, 0x2c, 0x60, 0x1f, 0xc8, 0xed,
153  	0xbe, 0x46, 0xd9, 0x4b, 0xde, 0xd4, 0xe8, 0x4a,
154  	0x6b, 0x2a, 0xe5, 0x16, 0xc5, 0xd7, 0x55, 0x94,
155  	0xcf, 0x10, 0x06, 0x81, 0xf0, 0x44, 0xba, 0xe3,
156  	0xf3, 0xfe, 0xc0, 0x8a, 0xad, 0xbc, 0x48, 0x04,
157  	0xdf, 0xc1, 0x75, 0x63, 0x30, 0x1a, 0x0e, 0x6d,
158  	0x4c, 0x14, 0x35, 0x2f, 0xe1, 0xa2, 0xcc, 0x39,
159  	0x57, 0xf2, 0x82, 0x47, 0xac, 0xe7, 0x2b, 0x95,
160  	0xa0, 0x98, 0xd1, 0x7f, 0x66, 0x7e, 0xab, 0x83,
161  	0xca, 0x29, 0xd3, 0x3c, 0x79, 0xe2, 0x1d, 0x76,
162  	0x3b, 0x56, 0x4e, 0x1e, 0xdb, 0x0a, 0x6c, 0xe4,
163  	0x5d, 0x6e, 0xef, 0xa6, 0xa8, 0xa4, 0x37, 0x8b,
164  	0x32, 0x43, 0x59, 0xb7, 0x8c, 0x64, 0xd2, 0xe0,
165  	0xb4, 0xfa, 0x07, 0x25, 0xaf, 0x8e, 0xe9, 0x18,
166  	0xd5, 0x88, 0x6f, 0x72, 0x24, 0xf1, 0xc7, 0x51,
167  	0x23, 0x7c, 0x9c, 0x21, 0xdd, 0xdc, 0x86, 0x85,
168  	0x90, 0x42, 0xc4, 0xaa, 0xd8, 0x05, 0x01, 0x12,
169  	0xa3, 0x5f, 0xf9, 0xd0, 0x91, 0x58, 0x27, 0xb9,
170  	0x38, 0x13, 0xb3, 0x33, 0xbb, 0x70, 0x89, 0xa7,
171  	0xb6, 0x22, 0x92, 0x20, 0x49, 0xff, 0x78, 0x7a,
172  	0x8f, 0xf8, 0x80, 0x17, 0xda, 0x31, 0xc6, 0xb8,
173  	0xc3, 0xb0, 0x77, 0x11, 0xcb, 0xfc, 0xd6, 0x3a
174  };
175  
176  /*
177   * modular multiplication tables based on:
178   *
179   * Xtime2[x] = (x & 0x80 ? 0x1b : 0) ^ (x + x)
180   * Xtime3[x] = x^Xtime2[x];
181   */
182  static const u8 x_time_9[256] = {
183  	0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
184  	0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
185  	0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf,
186  	0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
187  	0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
188  	0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
189  	0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94,
190  	0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc,
191  	0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49,
192  	0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01,
193  	0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9,
194  	0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
195  	0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72,
196  	0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a,
197  	0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2,
198  	0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa,
199  	0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3,
200  	0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
201  	0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43,
202  	0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b,
203  	0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8,
204  	0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0,
205  	0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78,
206  	0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
207  	0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5,
208  	0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed,
209  	0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35,
210  	0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d,
211  	0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e,
212  	0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
213  	0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e,
214  	0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46
215  };
216  
217  static const u8 x_time_b[256] = {
218  	0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31,
219  	0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
220  	0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81,
221  	0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
222  	0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a,
223  	0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
224  	0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa,
225  	0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2,
226  	0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7,
227  	0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f,
228  	0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77,
229  	0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
230  	0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc,
231  	0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4,
232  	0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c,
233  	0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54,
234  	0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6,
235  	0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
236  	0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76,
237  	0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e,
238  	0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd,
239  	0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5,
240  	0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d,
241  	0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
242  	0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30,
243  	0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68,
244  	0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80,
245  	0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8,
246  	0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b,
247  	0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
248  	0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb,
249  	0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3
250  };
251  
252  static const u8 x_time_d[256] = {
253  	0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23,
254  	0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
255  	0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3,
256  	0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
257  	0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98,
258  	0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
259  	0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48,
260  	0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20,
261  	0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e,
262  	0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26,
263  	0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e,
264  	0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
265  	0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5,
266  	0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d,
267  	0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25,
268  	0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d,
269  	0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9,
270  	0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
271  	0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29,
272  	0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41,
273  	0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42,
274  	0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a,
275  	0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92,
276  	0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
277  	0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94,
278  	0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc,
279  	0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44,
280  	0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c,
281  	0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f,
282  	0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
283  	0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff,
284  	0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97
285  };
286  
287  static const u8 x_time_e[256] = {
288  	0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a,
289  	0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
290  	0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca,
291  	0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
292  	0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1,
293  	0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
294  	0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11,
295  	0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61,
296  	0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87,
297  	0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7,
298  	0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67,
299  	0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
300  	0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c,
301  	0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c,
302  	0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc,
303  	0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc,
304  	0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b,
305  	0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
306  	0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b,
307  	0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb,
308  	0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0,
309  	0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0,
310  	0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50,
311  	0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
312  	0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6,
313  	0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
314  	0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26,
315  	0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
316  	0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d,
317  	0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
318  	0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd,
319  	0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d
320  };
321  
322  /*
323   * Exchanges columns in each of 4 rows
324   * row0 - unchanged, row1- shifted left 1,
325   * row2 - shifted left 2 and row3 - shifted left 3
326   */
327  static void shift_rows(u8 *state)
328  {
329  	u8 tmp;
330  
331  	/* just substitute row 0 */
332  	state[0] = sbox[state[0]];
333  	state[4] = sbox[state[4]];
334  	state[8] = sbox[state[8]];
335  	state[12] = sbox[state[12]];
336  
337  	/* rotate row 1 */
338  	tmp = sbox[state[1]];
339  	state[1] = sbox[state[5]];
340  	state[5] = sbox[state[9]];
341  	state[9] = sbox[state[13]];
342  	state[13] = tmp;
343  
344  	/* rotate row 2 */
345  	tmp = sbox[state[2]];
346  	state[2] = sbox[state[10]];
347  	state[10] = tmp;
348  	tmp = sbox[state[6]];
349  	state[6] = sbox[state[14]];
350  	state[14] = tmp;
351  
352  	/* rotate row 3 */
353  	tmp = sbox[state[15]];
354  	state[15] = sbox[state[11]];
355  	state[11] = sbox[state[7]];
356  	state[7] = sbox[state[3]];
357  	state[3] = tmp;
358  }
359  
360  /*
361   * restores columns in each of 4 rows
362   * row0 - unchanged, row1- shifted right 1,
363   * row2 - shifted right 2 and row3 - shifted right 3
364   */
365  static void inv_shift_rows(u8 *state)
366  {
367  	u8 tmp;
368  
369  	/* restore row 0 */
370  	state[0] = inv_sbox[state[0]];
371  	state[4] = inv_sbox[state[4]];
372  	state[8] = inv_sbox[state[8]];
373  	state[12] = inv_sbox[state[12]];
374  
375  	/* restore row 1 */
376  	tmp = inv_sbox[state[13]];
377  	state[13] = inv_sbox[state[9]];
378  	state[9] = inv_sbox[state[5]];
379  	state[5] = inv_sbox[state[1]];
380  	state[1] = tmp;
381  
382  	/* restore row 2 */
383  	tmp = inv_sbox[state[2]];
384  	state[2] = inv_sbox[state[10]];
385  	state[10] = tmp;
386  	tmp = inv_sbox[state[6]];
387  	state[6] = inv_sbox[state[14]];
388  	state[14] = tmp;
389  
390  	/* restore row 3 */
391  	tmp = inv_sbox[state[3]];
392  	state[3] = inv_sbox[state[7]];
393  	state[7] = inv_sbox[state[11]];
394  	state[11] = inv_sbox[state[15]];
395  	state[15] = tmp;
396  }
397  
398  /* recombine and mix each row in a column */
399  static void mix_sub_columns(u8 *state)
400  {
401  	u8 tmp[4 * AES_STATECOLS];
402  
403  	/* mixing column 0 */
404  	tmp[0] = x2_sbox[state[0]] ^ x3_sbox[state[5]] ^
405  		 sbox[state[10]] ^ sbox[state[15]];
406  	tmp[1] = sbox[state[0]] ^ x2_sbox[state[5]] ^
407  		 x3_sbox[state[10]] ^ sbox[state[15]];
408  	tmp[2] = sbox[state[0]] ^ sbox[state[5]] ^
409  		 x2_sbox[state[10]] ^ x3_sbox[state[15]];
410  	tmp[3] = x3_sbox[state[0]] ^ sbox[state[5]] ^
411  		 sbox[state[10]] ^ x2_sbox[state[15]];
412  
413  	/* mixing column 1 */
414  	tmp[4] = x2_sbox[state[4]] ^ x3_sbox[state[9]] ^
415  		 sbox[state[14]] ^ sbox[state[3]];
416  	tmp[5] = sbox[state[4]] ^ x2_sbox[state[9]] ^
417  		 x3_sbox[state[14]] ^ sbox[state[3]];
418  	tmp[6] = sbox[state[4]] ^ sbox[state[9]] ^
419  		 x2_sbox[state[14]] ^ x3_sbox[state[3]];
420  	tmp[7] = x3_sbox[state[4]] ^ sbox[state[9]] ^
421  		 sbox[state[14]] ^ x2_sbox[state[3]];
422  
423  	/* mixing column 2 */
424  	tmp[8] = x2_sbox[state[8]] ^ x3_sbox[state[13]] ^
425  		 sbox[state[2]] ^ sbox[state[7]];
426  	tmp[9] = sbox[state[8]] ^ x2_sbox[state[13]] ^
427  		 x3_sbox[state[2]] ^ sbox[state[7]];
428  	tmp[10] = sbox[state[8]] ^ sbox[state[13]] ^
429  		  x2_sbox[state[2]] ^ x3_sbox[state[7]];
430  	tmp[11] = x3_sbox[state[8]] ^ sbox[state[13]] ^
431  		  sbox[state[2]] ^ x2_sbox[state[7]];
432  
433  	/* mixing column 3 */
434  	tmp[12] = x2_sbox[state[12]] ^ x3_sbox[state[1]] ^
435  		  sbox[state[6]] ^ sbox[state[11]];
436  	tmp[13] = sbox[state[12]] ^ x2_sbox[state[1]] ^
437  		  x3_sbox[state[6]] ^ sbox[state[11]];
438  	tmp[14] = sbox[state[12]] ^ sbox[state[1]] ^
439  		  x2_sbox[state[6]] ^ x3_sbox[state[11]];
440  	tmp[15] = x3_sbox[state[12]] ^ sbox[state[1]] ^
441  		  sbox[state[6]] ^ x2_sbox[state[11]];
442  
443  	memcpy(state, tmp, sizeof(tmp));
444  }
445  
446  /* restore and un-mix each row in a column */
447  static void inv_mix_sub_columns(u8 *state)
448  {
449  	u8 tmp[4 * AES_STATECOLS];
450  	int  i;
451  
452  	/* restore column 0 */
453  	tmp[0] = x_time_e[state[0]] ^ x_time_b[state[1]] ^
454  		 x_time_d[state[2]] ^ x_time_9[state[3]];
455  	tmp[5] = x_time_9[state[0]] ^ x_time_e[state[1]] ^
456  		 x_time_b[state[2]] ^ x_time_d[state[3]];
457  	tmp[10] = x_time_d[state[0]] ^ x_time_9[state[1]] ^
458  		  x_time_e[state[2]] ^ x_time_b[state[3]];
459  	tmp[15] = x_time_b[state[0]] ^ x_time_d[state[1]] ^
460  		  x_time_9[state[2]] ^ x_time_e[state[3]];
461  
462  	/* restore column 1 */
463  	tmp[4] = x_time_e[state[4]] ^ x_time_b[state[5]] ^
464  		 x_time_d[state[6]] ^ x_time_9[state[7]];
465  	tmp[9] = x_time_9[state[4]] ^ x_time_e[state[5]] ^
466  		 x_time_b[state[6]] ^ x_time_d[state[7]];
467  	tmp[14] = x_time_d[state[4]] ^ x_time_9[state[5]] ^
468  		  x_time_e[state[6]] ^ x_time_b[state[7]];
469  	tmp[3] = x_time_b[state[4]] ^ x_time_d[state[5]] ^
470  		 x_time_9[state[6]] ^ x_time_e[state[7]];
471  
472  	/* restore column 2 */
473  	tmp[8] = x_time_e[state[8]] ^ x_time_b[state[9]] ^
474  		 x_time_d[state[10]] ^ x_time_9[state[11]];
475  	tmp[13] = x_time_9[state[8]] ^ x_time_e[state[9]] ^
476  		  x_time_b[state[10]] ^ x_time_d[state[11]];
477  	tmp[2] = x_time_d[state[8]] ^ x_time_9[state[9]] ^
478  		 x_time_e[state[10]] ^ x_time_b[state[11]];
479  	tmp[7] = x_time_b[state[8]] ^ x_time_d[state[9]] ^
480  		 x_time_9[state[10]] ^ x_time_e[state[11]];
481  
482  	/* restore column 3 */
483  	tmp[12] = x_time_e[state[12]] ^ x_time_b[state[13]] ^
484  		  x_time_d[state[14]] ^ x_time_9[state[15]];
485  	tmp[1] = x_time_9[state[12]] ^ x_time_e[state[13]] ^
486  		 x_time_b[state[14]] ^ x_time_d[state[15]];
487  	tmp[6] = x_time_d[state[12]] ^ x_time_9[state[13]] ^
488  		 x_time_e[state[14]] ^ x_time_b[state[15]];
489  	tmp[11] = x_time_b[state[12]] ^ x_time_d[state[13]] ^
490  		  x_time_9[state[14]] ^ x_time_e[state[15]];
491  
492  	for (i = 0; i < 4 * AES_STATECOLS; i++)
493  		state[i] = inv_sbox[tmp[i]];
494  }
495  
496  /*
497   * encrypt/decrypt columns of the key
498   * n.b. you can replace this with byte-wise xor if you wish.
499   */
500  static void add_round_key(u32 *state, u32 *key)
501  {
502  	int idx;
503  
504  	for (idx = 0; idx < 4; idx++)
505  		state[idx] ^= key[idx];
506  }
507  
508  static u8 rcon[11] = {
509  	0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
510  };
511  
512  /* produce AES_STATECOLS bytes for each round */
513  void aes_expand_key(u8 *key, u8 *expkey)
514  {
515  	u8 tmp0, tmp1, tmp2, tmp3, tmp4;
516  	u32 idx;
517  
518  	memcpy(expkey, key, AES_KEYCOLS * 4);
519  
520  	for (idx = AES_KEYCOLS; idx < AES_STATECOLS * (AES_ROUNDS + 1); idx++) {
521  		tmp0 = expkey[4*idx - 4];
522  		tmp1 = expkey[4*idx - 3];
523  		tmp2 = expkey[4*idx - 2];
524  		tmp3 = expkey[4*idx - 1];
525  		if (!(idx % AES_KEYCOLS)) {
526  			tmp4 = tmp3;
527  			tmp3 = sbox[tmp0];
528  			tmp0 = sbox[tmp1] ^ rcon[idx / AES_KEYCOLS];
529  			tmp1 = sbox[tmp2];
530  			tmp2 = sbox[tmp4];
531  		} else if ((AES_KEYCOLS > 6) && (idx % AES_KEYCOLS == 4)) {
532  			tmp0 = sbox[tmp0];
533  			tmp1 = sbox[tmp1];
534  			tmp2 = sbox[tmp2];
535  			tmp3 = sbox[tmp3];
536  		}
537  
538  		expkey[4*idx+0] = expkey[4*idx - 4*AES_KEYCOLS + 0] ^ tmp0;
539  		expkey[4*idx+1] = expkey[4*idx - 4*AES_KEYCOLS + 1] ^ tmp1;
540  		expkey[4*idx+2] = expkey[4*idx - 4*AES_KEYCOLS + 2] ^ tmp2;
541  		expkey[4*idx+3] = expkey[4*idx - 4*AES_KEYCOLS + 3] ^ tmp3;
542  	}
543  }
544  
545  /* encrypt one 128 bit block */
546  void aes_encrypt(u8 *in, u8 *expkey, u8 *out)
547  {
548  	u8 state[AES_STATECOLS * 4];
549  	u32 round;
550  
551  	memcpy(state, in, AES_STATECOLS * 4);
552  	add_round_key((u32 *)state, (u32 *)expkey);
553  
554  	for (round = 1; round < AES_ROUNDS + 1; round++) {
555  		if (round < AES_ROUNDS)
556  			mix_sub_columns(state);
557  		else
558  			shift_rows(state);
559  
560  		add_round_key((u32 *)state,
561  			      (u32 *)expkey + round * AES_STATECOLS);
562  	}
563  
564  	memcpy(out, state, sizeof(state));
565  }
566  
567  void aes_decrypt(u8 *in, u8 *expkey, u8 *out)
568  {
569  	u8 state[AES_STATECOLS * 4];
570  	int round;
571  
572  	memcpy(state, in, sizeof(state));
573  
574  	add_round_key((u32 *)state,
575  		      (u32 *)expkey + AES_ROUNDS * AES_STATECOLS);
576  	inv_shift_rows(state);
577  
578  	for (round = AES_ROUNDS; round--; ) {
579  		add_round_key((u32 *)state,
580  			      (u32 *)expkey + round * AES_STATECOLS);
581  		if (round)
582  			inv_mix_sub_columns(state);
583  	}
584  
585  	memcpy(out, state, sizeof(state));
586  }
587  
588  static void debug_print_vector(char *name, u32 num_bytes, u8 *data)
589  {
590  #ifdef DEBUG
591  	printf("%s [%d] @0x%08x", name, num_bytes, (u32)data);
592  	print_buffer(0, data, 1, num_bytes, 16);
593  #endif
594  }
595  
596  void aes_apply_cbc_chain_data(u8 *cbc_chain_data, u8 *src, u8 *dst)
597  {
598  	int i;
599  
600  	for (i = 0; i < AES_KEY_LENGTH; i++)
601  		*dst++ = *src++ ^ *cbc_chain_data++;
602  }
603  
604  void aes_cbc_encrypt_blocks(u8 *key_exp, u8 *src, u8 *dst, u32 num_aes_blocks)
605  {
606  	u8 zero_key[AES_KEY_LENGTH] = { 0 };
607  	u8 tmp_data[AES_KEY_LENGTH];
608  	/* Convenient array of 0's for IV */
609  	u8 *cbc_chain_data = zero_key;
610  	u32 i;
611  
612  	for (i = 0; i < num_aes_blocks; i++) {
613  		debug("encrypt_object: block %d of %d\n", i, num_aes_blocks);
614  		debug_print_vector("AES Src", AES_KEY_LENGTH, src);
615  
616  		/* Apply the chain data */
617  		aes_apply_cbc_chain_data(cbc_chain_data, src, tmp_data);
618  		debug_print_vector("AES Xor", AES_KEY_LENGTH, tmp_data);
619  
620  		/* Encrypt the AES block */
621  		aes_encrypt(tmp_data, key_exp, dst);
622  		debug_print_vector("AES Dst", AES_KEY_LENGTH, dst);
623  
624  		/* Update pointers for next loop. */
625  		cbc_chain_data = dst;
626  		src += AES_KEY_LENGTH;
627  		dst += AES_KEY_LENGTH;
628  	}
629  }
630  
631  void aes_cbc_decrypt_blocks(u8 *key_exp, u8 *src, u8 *dst, u32 num_aes_blocks)
632  {
633  	u8 tmp_data[AES_KEY_LENGTH], tmp_block[AES_KEY_LENGTH];
634  	/* Convenient array of 0's for IV */
635  	u8 cbc_chain_data[AES_KEY_LENGTH] = { 0 };
636  	u32 i;
637  
638  	for (i = 0; i < num_aes_blocks; i++) {
639  		debug("encrypt_object: block %d of %d\n", i, num_aes_blocks);
640  		debug_print_vector("AES Src", AES_KEY_LENGTH, src);
641  
642  		memcpy(tmp_block, src, AES_KEY_LENGTH);
643  
644  		/* Decrypt the AES block */
645  		aes_decrypt(src, key_exp, tmp_data);
646  		debug_print_vector("AES Xor", AES_KEY_LENGTH, tmp_data);
647  
648  		/* Apply the chain data */
649  		aes_apply_cbc_chain_data(cbc_chain_data, tmp_data, dst);
650  		debug_print_vector("AES Dst", AES_KEY_LENGTH, dst);
651  
652  		/* Update pointers for next loop. */
653  		memcpy(cbc_chain_data, tmp_block, AES_KEY_LENGTH);
654  		src += AES_KEY_LENGTH;
655  		dst += AES_KEY_LENGTH;
656  	}
657  }
658