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 *iv, u8 *src, u8 *dst, 605 u32 num_aes_blocks) 606 { 607 u8 tmp_data[AES_KEY_LENGTH]; 608 u8 *cbc_chain_data = iv; 609 u32 i; 610 611 for (i = 0; i < num_aes_blocks; i++) { 612 debug("encrypt_object: block %d of %d\n", i, num_aes_blocks); 613 debug_print_vector("AES Src", AES_KEY_LENGTH, src); 614 615 /* Apply the chain data */ 616 aes_apply_cbc_chain_data(cbc_chain_data, src, tmp_data); 617 debug_print_vector("AES Xor", AES_KEY_LENGTH, tmp_data); 618 619 /* Encrypt the AES block */ 620 aes_encrypt(tmp_data, key_exp, dst); 621 debug_print_vector("AES Dst", AES_KEY_LENGTH, dst); 622 623 /* Update pointers for next loop. */ 624 cbc_chain_data = dst; 625 src += AES_KEY_LENGTH; 626 dst += AES_KEY_LENGTH; 627 } 628 } 629 630 void aes_cbc_decrypt_blocks(u8 *key_exp, u8 *iv, u8 *src, u8 *dst, 631 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]; 636 u32 i; 637 638 memcpy(cbc_chain_data, iv, AES_KEY_LENGTH); 639 for (i = 0; i < num_aes_blocks; i++) { 640 debug("encrypt_object: block %d of %d\n", i, num_aes_blocks); 641 debug_print_vector("AES Src", AES_KEY_LENGTH, src); 642 643 memcpy(tmp_block, src, AES_KEY_LENGTH); 644 645 /* Decrypt the AES block */ 646 aes_decrypt(src, key_exp, tmp_data); 647 debug_print_vector("AES Xor", AES_KEY_LENGTH, tmp_data); 648 649 /* Apply the chain data */ 650 aes_apply_cbc_chain_data(cbc_chain_data, tmp_data, dst); 651 debug_print_vector("AES Dst", AES_KEY_LENGTH, dst); 652 653 /* Update pointers for next loop. */ 654 memcpy(cbc_chain_data, tmp_block, AES_KEY_LENGTH); 655 src += AES_KEY_LENGTH; 656 dst += AES_KEY_LENGTH; 657 } 658 } 659