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