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