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