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