xref: /rk3399_rockchip-uboot/lib/aes.c (revision b80c0b99347c52884cccc7c09775942acbcc0739)
15b1a5451SYen Lin /*
25b1a5451SYen Lin  * Copyright (c) 2011 The Chromium OS Authors.
35b1a5451SYen Lin  * (C) Copyright 2011 NVIDIA Corporation www.nvidia.com
45b1a5451SYen Lin  *
51a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
65b1a5451SYen Lin  */
75b1a5451SYen Lin 
85b1a5451SYen Lin /*
95b1a5451SYen Lin  * advanced encryption standard
105b1a5451SYen Lin  * author: karl malbrain, malbrain@yahoo.com
115b1a5451SYen Lin  *
125b1a5451SYen Lin  * This work, including the source code, documentation
135b1a5451SYen Lin  * and related data, is placed into the public domain.
145b1a5451SYen Lin  *
155b1a5451SYen Lin  * The orginal author is Karl Malbrain.
165b1a5451SYen Lin  *
175b1a5451SYen Lin  * THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY
185b1a5451SYen Lin  * OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF
195b1a5451SYen Lin  * MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE,
205b1a5451SYen Lin  * ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE
215b1a5451SYen Lin  * RESULTING FROM THE USE, MODIFICATION, OR
225b1a5451SYen Lin  * REDISTRIBUTION OF THIS SOFTWARE.
235b1a5451SYen Lin */
245b1a5451SYen Lin 
25a8a752c0SMarek Vasut #ifndef USE_HOSTCC
265b1a5451SYen Lin #include <common.h>
27a8a752c0SMarek Vasut #else
28a8a752c0SMarek Vasut #include <string.h>
29a8a752c0SMarek Vasut #endif
30*b80c0b99SStefano Babic #include "uboot_aes.h"
315b1a5451SYen Lin 
325b1a5451SYen Lin /* forward s-box */
335b1a5451SYen Lin static const u8 sbox[256] = {
345b1a5451SYen Lin 	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
355b1a5451SYen Lin 	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
365b1a5451SYen Lin 	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
375b1a5451SYen Lin 	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
385b1a5451SYen Lin 	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
395b1a5451SYen Lin 	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
405b1a5451SYen Lin 	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
415b1a5451SYen Lin 	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
425b1a5451SYen Lin 	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
435b1a5451SYen Lin 	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
445b1a5451SYen Lin 	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
455b1a5451SYen Lin 	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
465b1a5451SYen Lin 	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
475b1a5451SYen Lin 	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
485b1a5451SYen Lin 	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
495b1a5451SYen Lin 	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
505b1a5451SYen Lin 	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
515b1a5451SYen Lin 	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
525b1a5451SYen Lin 	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
535b1a5451SYen Lin 	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
545b1a5451SYen Lin 	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
555b1a5451SYen Lin 	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
565b1a5451SYen Lin 	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
575b1a5451SYen Lin 	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
585b1a5451SYen Lin 	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
595b1a5451SYen Lin 	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
605b1a5451SYen Lin 	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
615b1a5451SYen Lin 	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
625b1a5451SYen Lin 	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
635b1a5451SYen Lin 	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
645b1a5451SYen Lin 	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
655b1a5451SYen Lin 	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
665b1a5451SYen Lin };
675b1a5451SYen Lin 
685b1a5451SYen Lin /* inverse s-box */
695b1a5451SYen Lin static const u8 inv_sbox[256] = {
705b1a5451SYen Lin 	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
715b1a5451SYen Lin 	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
725b1a5451SYen Lin 	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
735b1a5451SYen Lin 	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
745b1a5451SYen Lin 	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
755b1a5451SYen Lin 	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
765b1a5451SYen Lin 	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
775b1a5451SYen Lin 	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
785b1a5451SYen Lin 	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
795b1a5451SYen Lin 	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
805b1a5451SYen Lin 	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
815b1a5451SYen Lin 	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
825b1a5451SYen Lin 	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
835b1a5451SYen Lin 	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
845b1a5451SYen Lin 	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
855b1a5451SYen Lin 	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
865b1a5451SYen Lin 	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
875b1a5451SYen Lin 	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
885b1a5451SYen Lin 	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
895b1a5451SYen Lin 	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
905b1a5451SYen Lin 	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
915b1a5451SYen Lin 	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
925b1a5451SYen Lin 	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
935b1a5451SYen Lin 	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
945b1a5451SYen Lin 	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
955b1a5451SYen Lin 	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
965b1a5451SYen Lin 	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
975b1a5451SYen Lin 	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
985b1a5451SYen Lin 	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
995b1a5451SYen Lin 	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
1005b1a5451SYen Lin 	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
1015b1a5451SYen Lin 	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
1025b1a5451SYen Lin };
1035b1a5451SYen Lin 
1045b1a5451SYen Lin /* combined Xtimes2[Sbox[]] */
1055b1a5451SYen Lin static const u8 x2_sbox[256] = {
1065b1a5451SYen Lin 	0xc6, 0xf8, 0xee, 0xf6, 0xff, 0xd6, 0xde, 0x91,
1075b1a5451SYen Lin 	0x60, 0x02, 0xce, 0x56, 0xe7, 0xb5, 0x4d, 0xec,
1085b1a5451SYen Lin 	0x8f, 0x1f, 0x89, 0xfa, 0xef, 0xb2, 0x8e, 0xfb,
1095b1a5451SYen Lin 	0x41, 0xb3, 0x5f, 0x45, 0x23, 0x53, 0xe4, 0x9b,
1105b1a5451SYen Lin 	0x75, 0xe1, 0x3d, 0x4c, 0x6c, 0x7e, 0xf5, 0x83,
1115b1a5451SYen Lin 	0x68, 0x51, 0xd1, 0xf9, 0xe2, 0xab, 0x62, 0x2a,
1125b1a5451SYen Lin 	0x08, 0x95, 0x46, 0x9d, 0x30, 0x37, 0x0a, 0x2f,
1135b1a5451SYen Lin 	0x0e, 0x24, 0x1b, 0xdf, 0xcd, 0x4e, 0x7f, 0xea,
1145b1a5451SYen Lin 	0x12, 0x1d, 0x58, 0x34, 0x36, 0xdc, 0xb4, 0x5b,
1155b1a5451SYen Lin 	0xa4, 0x76, 0xb7, 0x7d, 0x52, 0xdd, 0x5e, 0x13,
1165b1a5451SYen Lin 	0xa6, 0xb9, 0x00, 0xc1, 0x40, 0xe3, 0x79, 0xb6,
1175b1a5451SYen Lin 	0xd4, 0x8d, 0x67, 0x72, 0x94, 0x98, 0xb0, 0x85,
1185b1a5451SYen Lin 	0xbb, 0xc5, 0x4f, 0xed, 0x86, 0x9a, 0x66, 0x11,
1195b1a5451SYen Lin 	0x8a, 0xe9, 0x04, 0xfe, 0xa0, 0x78, 0x25, 0x4b,
1205b1a5451SYen Lin 	0xa2, 0x5d, 0x80, 0x05, 0x3f, 0x21, 0x70, 0xf1,
1215b1a5451SYen Lin 	0x63, 0x77, 0xaf, 0x42, 0x20, 0xe5, 0xfd, 0xbf,
1225b1a5451SYen Lin 	0x81, 0x18, 0x26, 0xc3, 0xbe, 0x35, 0x88, 0x2e,
1235b1a5451SYen Lin 	0x93, 0x55, 0xfc, 0x7a, 0xc8, 0xba, 0x32, 0xe6,
1245b1a5451SYen Lin 	0xc0, 0x19, 0x9e, 0xa3, 0x44, 0x54, 0x3b, 0x0b,
1255b1a5451SYen Lin 	0x8c, 0xc7, 0x6b, 0x28, 0xa7, 0xbc, 0x16, 0xad,
1265b1a5451SYen Lin 	0xdb, 0x64, 0x74, 0x14, 0x92, 0x0c, 0x48, 0xb8,
1275b1a5451SYen Lin 	0x9f, 0xbd, 0x43, 0xc4, 0x39, 0x31, 0xd3, 0xf2,
1285b1a5451SYen Lin 	0xd5, 0x8b, 0x6e, 0xda, 0x01, 0xb1, 0x9c, 0x49,
1295b1a5451SYen Lin 	0xd8, 0xac, 0xf3, 0xcf, 0xca, 0xf4, 0x47, 0x10,
1305b1a5451SYen Lin 	0x6f, 0xf0, 0x4a, 0x5c, 0x38, 0x57, 0x73, 0x97,
1315b1a5451SYen Lin 	0xcb, 0xa1, 0xe8, 0x3e, 0x96, 0x61, 0x0d, 0x0f,
1325b1a5451SYen Lin 	0xe0, 0x7c, 0x71, 0xcc, 0x90, 0x06, 0xf7, 0x1c,
1335b1a5451SYen Lin 	0xc2, 0x6a, 0xae, 0x69, 0x17, 0x99, 0x3a, 0x27,
1345b1a5451SYen Lin 	0xd9, 0xeb, 0x2b, 0x22, 0xd2, 0xa9, 0x07, 0x33,
1355b1a5451SYen Lin 	0x2d, 0x3c, 0x15, 0xc9, 0x87, 0xaa, 0x50, 0xa5,
1365b1a5451SYen Lin 	0x03, 0x59, 0x09, 0x1a, 0x65, 0xd7, 0x84, 0xd0,
1375b1a5451SYen Lin 	0x82, 0x29, 0x5a, 0x1e, 0x7b, 0xa8, 0x6d, 0x2c
1385b1a5451SYen Lin };
1395b1a5451SYen Lin 
1405b1a5451SYen Lin /* combined Xtimes3[Sbox[]] */
1415b1a5451SYen Lin static const u8 x3_sbox[256] = {
1425b1a5451SYen Lin 	0xa5, 0x84, 0x99, 0x8d, 0x0d, 0xbd, 0xb1, 0x54,
1435b1a5451SYen Lin 	0x50, 0x03, 0xa9, 0x7d, 0x19, 0x62, 0xe6, 0x9a,
1445b1a5451SYen Lin 	0x45, 0x9d, 0x40, 0x87, 0x15, 0xeb, 0xc9, 0x0b,
1455b1a5451SYen Lin 	0xec, 0x67, 0xfd, 0xea, 0xbf, 0xf7, 0x96, 0x5b,
1465b1a5451SYen Lin 	0xc2, 0x1c, 0xae, 0x6a, 0x5a, 0x41, 0x02, 0x4f,
1475b1a5451SYen Lin 	0x5c, 0xf4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3f,
1485b1a5451SYen Lin 	0x0c, 0x52, 0x65, 0x5e, 0x28, 0xa1, 0x0f, 0xb5,
1495b1a5451SYen Lin 	0x09, 0x36, 0x9b, 0x3d, 0x26, 0x69, 0xcd, 0x9f,
1505b1a5451SYen Lin 	0x1b, 0x9e, 0x74, 0x2e, 0x2d, 0xb2, 0xee, 0xfb,
1515b1a5451SYen Lin 	0xf6, 0x4d, 0x61, 0xce, 0x7b, 0x3e, 0x71, 0x97,
1525b1a5451SYen Lin 	0xf5, 0x68, 0x00, 0x2c, 0x60, 0x1f, 0xc8, 0xed,
1535b1a5451SYen Lin 	0xbe, 0x46, 0xd9, 0x4b, 0xde, 0xd4, 0xe8, 0x4a,
1545b1a5451SYen Lin 	0x6b, 0x2a, 0xe5, 0x16, 0xc5, 0xd7, 0x55, 0x94,
1555b1a5451SYen Lin 	0xcf, 0x10, 0x06, 0x81, 0xf0, 0x44, 0xba, 0xe3,
1565b1a5451SYen Lin 	0xf3, 0xfe, 0xc0, 0x8a, 0xad, 0xbc, 0x48, 0x04,
1575b1a5451SYen Lin 	0xdf, 0xc1, 0x75, 0x63, 0x30, 0x1a, 0x0e, 0x6d,
1585b1a5451SYen Lin 	0x4c, 0x14, 0x35, 0x2f, 0xe1, 0xa2, 0xcc, 0x39,
1595b1a5451SYen Lin 	0x57, 0xf2, 0x82, 0x47, 0xac, 0xe7, 0x2b, 0x95,
1605b1a5451SYen Lin 	0xa0, 0x98, 0xd1, 0x7f, 0x66, 0x7e, 0xab, 0x83,
1615b1a5451SYen Lin 	0xca, 0x29, 0xd3, 0x3c, 0x79, 0xe2, 0x1d, 0x76,
1625b1a5451SYen Lin 	0x3b, 0x56, 0x4e, 0x1e, 0xdb, 0x0a, 0x6c, 0xe4,
1635b1a5451SYen Lin 	0x5d, 0x6e, 0xef, 0xa6, 0xa8, 0xa4, 0x37, 0x8b,
1645b1a5451SYen Lin 	0x32, 0x43, 0x59, 0xb7, 0x8c, 0x64, 0xd2, 0xe0,
1655b1a5451SYen Lin 	0xb4, 0xfa, 0x07, 0x25, 0xaf, 0x8e, 0xe9, 0x18,
1665b1a5451SYen Lin 	0xd5, 0x88, 0x6f, 0x72, 0x24, 0xf1, 0xc7, 0x51,
1675b1a5451SYen Lin 	0x23, 0x7c, 0x9c, 0x21, 0xdd, 0xdc, 0x86, 0x85,
1685b1a5451SYen Lin 	0x90, 0x42, 0xc4, 0xaa, 0xd8, 0x05, 0x01, 0x12,
1695b1a5451SYen Lin 	0xa3, 0x5f, 0xf9, 0xd0, 0x91, 0x58, 0x27, 0xb9,
1705b1a5451SYen Lin 	0x38, 0x13, 0xb3, 0x33, 0xbb, 0x70, 0x89, 0xa7,
1715b1a5451SYen Lin 	0xb6, 0x22, 0x92, 0x20, 0x49, 0xff, 0x78, 0x7a,
1725b1a5451SYen Lin 	0x8f, 0xf8, 0x80, 0x17, 0xda, 0x31, 0xc6, 0xb8,
1735b1a5451SYen Lin 	0xc3, 0xb0, 0x77, 0x11, 0xcb, 0xfc, 0xd6, 0x3a
1745b1a5451SYen Lin };
1755b1a5451SYen Lin 
1765b1a5451SYen Lin /*
1775b1a5451SYen Lin  * modular multiplication tables based on:
1785b1a5451SYen Lin  *
1795b1a5451SYen Lin  * Xtime2[x] = (x & 0x80 ? 0x1b : 0) ^ (x + x)
1805b1a5451SYen Lin  * Xtime3[x] = x^Xtime2[x];
1815b1a5451SYen Lin  */
1825b1a5451SYen Lin static const u8 x_time_9[256] = {
1835b1a5451SYen Lin 	0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
1845b1a5451SYen Lin 	0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
1855b1a5451SYen Lin 	0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf,
1865b1a5451SYen Lin 	0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
1875b1a5451SYen Lin 	0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
1885b1a5451SYen Lin 	0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
1895b1a5451SYen Lin 	0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94,
1905b1a5451SYen Lin 	0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc,
1915b1a5451SYen Lin 	0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49,
1925b1a5451SYen Lin 	0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01,
1935b1a5451SYen Lin 	0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9,
1945b1a5451SYen Lin 	0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
1955b1a5451SYen Lin 	0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72,
1965b1a5451SYen Lin 	0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a,
1975b1a5451SYen Lin 	0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2,
1985b1a5451SYen Lin 	0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa,
1995b1a5451SYen Lin 	0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3,
2005b1a5451SYen Lin 	0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
2015b1a5451SYen Lin 	0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43,
2025b1a5451SYen Lin 	0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b,
2035b1a5451SYen Lin 	0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8,
2045b1a5451SYen Lin 	0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0,
2055b1a5451SYen Lin 	0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78,
2065b1a5451SYen Lin 	0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
2075b1a5451SYen Lin 	0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5,
2085b1a5451SYen Lin 	0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed,
2095b1a5451SYen Lin 	0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35,
2105b1a5451SYen Lin 	0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d,
2115b1a5451SYen Lin 	0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e,
2125b1a5451SYen Lin 	0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
2135b1a5451SYen Lin 	0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e,
2145b1a5451SYen Lin 	0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46
2155b1a5451SYen Lin };
2165b1a5451SYen Lin 
2175b1a5451SYen Lin static const u8 x_time_b[256] = {
2185b1a5451SYen Lin 	0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31,
2195b1a5451SYen Lin 	0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
2205b1a5451SYen Lin 	0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81,
2215b1a5451SYen Lin 	0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
2225b1a5451SYen Lin 	0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a,
2235b1a5451SYen Lin 	0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
2245b1a5451SYen Lin 	0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa,
2255b1a5451SYen Lin 	0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2,
2265b1a5451SYen Lin 	0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7,
2275b1a5451SYen Lin 	0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f,
2285b1a5451SYen Lin 	0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77,
2295b1a5451SYen Lin 	0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
2305b1a5451SYen Lin 	0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc,
2315b1a5451SYen Lin 	0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4,
2325b1a5451SYen Lin 	0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c,
2335b1a5451SYen Lin 	0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54,
2345b1a5451SYen Lin 	0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6,
2355b1a5451SYen Lin 	0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
2365b1a5451SYen Lin 	0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76,
2375b1a5451SYen Lin 	0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e,
2385b1a5451SYen Lin 	0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd,
2395b1a5451SYen Lin 	0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5,
2405b1a5451SYen Lin 	0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d,
2415b1a5451SYen Lin 	0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
2425b1a5451SYen Lin 	0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30,
2435b1a5451SYen Lin 	0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68,
2445b1a5451SYen Lin 	0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80,
2455b1a5451SYen Lin 	0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8,
2465b1a5451SYen Lin 	0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b,
2475b1a5451SYen Lin 	0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
2485b1a5451SYen Lin 	0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb,
2495b1a5451SYen Lin 	0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3
2505b1a5451SYen Lin };
2515b1a5451SYen Lin 
2525b1a5451SYen Lin static const u8 x_time_d[256] = {
2535b1a5451SYen Lin 	0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23,
2545b1a5451SYen Lin 	0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
2555b1a5451SYen Lin 	0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3,
2565b1a5451SYen Lin 	0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
2575b1a5451SYen Lin 	0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98,
2585b1a5451SYen Lin 	0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
2595b1a5451SYen Lin 	0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48,
2605b1a5451SYen Lin 	0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20,
2615b1a5451SYen Lin 	0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e,
2625b1a5451SYen Lin 	0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26,
2635b1a5451SYen Lin 	0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e,
2645b1a5451SYen Lin 	0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
2655b1a5451SYen Lin 	0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5,
2665b1a5451SYen Lin 	0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d,
2675b1a5451SYen Lin 	0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25,
2685b1a5451SYen Lin 	0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d,
2695b1a5451SYen Lin 	0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9,
2705b1a5451SYen Lin 	0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
2715b1a5451SYen Lin 	0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29,
2725b1a5451SYen Lin 	0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41,
2735b1a5451SYen Lin 	0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42,
2745b1a5451SYen Lin 	0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a,
2755b1a5451SYen Lin 	0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92,
2765b1a5451SYen Lin 	0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
2775b1a5451SYen Lin 	0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94,
2785b1a5451SYen Lin 	0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc,
2795b1a5451SYen Lin 	0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44,
2805b1a5451SYen Lin 	0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c,
2815b1a5451SYen Lin 	0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f,
2825b1a5451SYen Lin 	0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
2835b1a5451SYen Lin 	0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff,
2845b1a5451SYen Lin 	0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97
2855b1a5451SYen Lin };
2865b1a5451SYen Lin 
2875b1a5451SYen Lin static const u8 x_time_e[256] = {
2885b1a5451SYen Lin 	0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a,
2895b1a5451SYen Lin 	0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
2905b1a5451SYen Lin 	0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca,
2915b1a5451SYen Lin 	0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
2925b1a5451SYen Lin 	0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1,
2935b1a5451SYen Lin 	0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
2945b1a5451SYen Lin 	0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11,
2955b1a5451SYen Lin 	0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61,
2965b1a5451SYen Lin 	0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87,
2975b1a5451SYen Lin 	0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7,
2985b1a5451SYen Lin 	0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67,
2995b1a5451SYen Lin 	0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
3005b1a5451SYen Lin 	0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c,
3015b1a5451SYen Lin 	0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c,
3025b1a5451SYen Lin 	0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc,
3035b1a5451SYen Lin 	0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc,
3045b1a5451SYen Lin 	0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b,
3055b1a5451SYen Lin 	0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
3065b1a5451SYen Lin 	0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b,
3075b1a5451SYen Lin 	0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb,
3085b1a5451SYen Lin 	0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0,
3095b1a5451SYen Lin 	0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0,
3105b1a5451SYen Lin 	0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50,
3115b1a5451SYen Lin 	0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
3125b1a5451SYen Lin 	0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6,
3135b1a5451SYen Lin 	0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
3145b1a5451SYen Lin 	0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26,
3155b1a5451SYen Lin 	0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
3165b1a5451SYen Lin 	0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d,
3175b1a5451SYen Lin 	0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
3185b1a5451SYen Lin 	0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd,
3195b1a5451SYen Lin 	0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d
3205b1a5451SYen Lin };
3215b1a5451SYen Lin 
3225b1a5451SYen Lin /*
3235b1a5451SYen Lin  * Exchanges columns in each of 4 rows
3245b1a5451SYen Lin  * row0 - unchanged, row1- shifted left 1,
3255b1a5451SYen Lin  * row2 - shifted left 2 and row3 - shifted left 3
3265b1a5451SYen Lin  */
shift_rows(u8 * state)3275b1a5451SYen Lin static void shift_rows(u8 *state)
3285b1a5451SYen Lin {
3295b1a5451SYen Lin 	u8 tmp;
3305b1a5451SYen Lin 
3315b1a5451SYen Lin 	/* just substitute row 0 */
3325b1a5451SYen Lin 	state[0] = sbox[state[0]];
3335b1a5451SYen Lin 	state[4] = sbox[state[4]];
3345b1a5451SYen Lin 	state[8] = sbox[state[8]];
3355b1a5451SYen Lin 	state[12] = sbox[state[12]];
3365b1a5451SYen Lin 
3375b1a5451SYen Lin 	/* rotate row 1 */
3385b1a5451SYen Lin 	tmp = sbox[state[1]];
3395b1a5451SYen Lin 	state[1] = sbox[state[5]];
3405b1a5451SYen Lin 	state[5] = sbox[state[9]];
3415b1a5451SYen Lin 	state[9] = sbox[state[13]];
3425b1a5451SYen Lin 	state[13] = tmp;
3435b1a5451SYen Lin 
3445b1a5451SYen Lin 	/* rotate row 2 */
3455b1a5451SYen Lin 	tmp = sbox[state[2]];
3465b1a5451SYen Lin 	state[2] = sbox[state[10]];
3475b1a5451SYen Lin 	state[10] = tmp;
3485b1a5451SYen Lin 	tmp = sbox[state[6]];
3495b1a5451SYen Lin 	state[6] = sbox[state[14]];
3505b1a5451SYen Lin 	state[14] = tmp;
3515b1a5451SYen Lin 
3525b1a5451SYen Lin 	/* rotate row 3 */
3535b1a5451SYen Lin 	tmp = sbox[state[15]];
3545b1a5451SYen Lin 	state[15] = sbox[state[11]];
3555b1a5451SYen Lin 	state[11] = sbox[state[7]];
3565b1a5451SYen Lin 	state[7] = sbox[state[3]];
3575b1a5451SYen Lin 	state[3] = tmp;
3585b1a5451SYen Lin }
3595b1a5451SYen Lin 
3605b1a5451SYen Lin /*
3615b1a5451SYen Lin  * restores columns in each of 4 rows
3625b1a5451SYen Lin  * row0 - unchanged, row1- shifted right 1,
3635b1a5451SYen Lin  * row2 - shifted right 2 and row3 - shifted right 3
3645b1a5451SYen Lin  */
inv_shift_rows(u8 * state)3655b1a5451SYen Lin static void inv_shift_rows(u8 *state)
3665b1a5451SYen Lin {
3675b1a5451SYen Lin 	u8 tmp;
3685b1a5451SYen Lin 
3695b1a5451SYen Lin 	/* restore row 0 */
3705b1a5451SYen Lin 	state[0] = inv_sbox[state[0]];
3715b1a5451SYen Lin 	state[4] = inv_sbox[state[4]];
3725b1a5451SYen Lin 	state[8] = inv_sbox[state[8]];
3735b1a5451SYen Lin 	state[12] = inv_sbox[state[12]];
3745b1a5451SYen Lin 
3755b1a5451SYen Lin 	/* restore row 1 */
3765b1a5451SYen Lin 	tmp = inv_sbox[state[13]];
3775b1a5451SYen Lin 	state[13] = inv_sbox[state[9]];
3785b1a5451SYen Lin 	state[9] = inv_sbox[state[5]];
3795b1a5451SYen Lin 	state[5] = inv_sbox[state[1]];
3805b1a5451SYen Lin 	state[1] = tmp;
3815b1a5451SYen Lin 
3825b1a5451SYen Lin 	/* restore row 2 */
3835b1a5451SYen Lin 	tmp = inv_sbox[state[2]];
3845b1a5451SYen Lin 	state[2] = inv_sbox[state[10]];
3855b1a5451SYen Lin 	state[10] = tmp;
3865b1a5451SYen Lin 	tmp = inv_sbox[state[6]];
3875b1a5451SYen Lin 	state[6] = inv_sbox[state[14]];
3885b1a5451SYen Lin 	state[14] = tmp;
3895b1a5451SYen Lin 
3905b1a5451SYen Lin 	/* restore row 3 */
3915b1a5451SYen Lin 	tmp = inv_sbox[state[3]];
3925b1a5451SYen Lin 	state[3] = inv_sbox[state[7]];
3935b1a5451SYen Lin 	state[7] = inv_sbox[state[11]];
3945b1a5451SYen Lin 	state[11] = inv_sbox[state[15]];
3955b1a5451SYen Lin 	state[15] = tmp;
3965b1a5451SYen Lin }
3975b1a5451SYen Lin 
3985b1a5451SYen Lin /* recombine and mix each row in a column */
mix_sub_columns(u8 * state)3995b1a5451SYen Lin static void mix_sub_columns(u8 *state)
4005b1a5451SYen Lin {
4015b1a5451SYen Lin 	u8 tmp[4 * AES_STATECOLS];
4025b1a5451SYen Lin 
4035b1a5451SYen Lin 	/* mixing column 0 */
4045b1a5451SYen Lin 	tmp[0] = x2_sbox[state[0]] ^ x3_sbox[state[5]] ^
4055b1a5451SYen Lin 		 sbox[state[10]] ^ sbox[state[15]];
4065b1a5451SYen Lin 	tmp[1] = sbox[state[0]] ^ x2_sbox[state[5]] ^
4075b1a5451SYen Lin 		 x3_sbox[state[10]] ^ sbox[state[15]];
4085b1a5451SYen Lin 	tmp[2] = sbox[state[0]] ^ sbox[state[5]] ^
4095b1a5451SYen Lin 		 x2_sbox[state[10]] ^ x3_sbox[state[15]];
4105b1a5451SYen Lin 	tmp[3] = x3_sbox[state[0]] ^ sbox[state[5]] ^
4115b1a5451SYen Lin 		 sbox[state[10]] ^ x2_sbox[state[15]];
4125b1a5451SYen Lin 
4135b1a5451SYen Lin 	/* mixing column 1 */
4145b1a5451SYen Lin 	tmp[4] = x2_sbox[state[4]] ^ x3_sbox[state[9]] ^
4155b1a5451SYen Lin 		 sbox[state[14]] ^ sbox[state[3]];
4165b1a5451SYen Lin 	tmp[5] = sbox[state[4]] ^ x2_sbox[state[9]] ^
4175b1a5451SYen Lin 		 x3_sbox[state[14]] ^ sbox[state[3]];
4185b1a5451SYen Lin 	tmp[6] = sbox[state[4]] ^ sbox[state[9]] ^
4195b1a5451SYen Lin 		 x2_sbox[state[14]] ^ x3_sbox[state[3]];
4205b1a5451SYen Lin 	tmp[7] = x3_sbox[state[4]] ^ sbox[state[9]] ^
4215b1a5451SYen Lin 		 sbox[state[14]] ^ x2_sbox[state[3]];
4225b1a5451SYen Lin 
4235b1a5451SYen Lin 	/* mixing column 2 */
4245b1a5451SYen Lin 	tmp[8] = x2_sbox[state[8]] ^ x3_sbox[state[13]] ^
4255b1a5451SYen Lin 		 sbox[state[2]] ^ sbox[state[7]];
4265b1a5451SYen Lin 	tmp[9] = sbox[state[8]] ^ x2_sbox[state[13]] ^
4275b1a5451SYen Lin 		 x3_sbox[state[2]] ^ sbox[state[7]];
4285b1a5451SYen Lin 	tmp[10] = sbox[state[8]] ^ sbox[state[13]] ^
4295b1a5451SYen Lin 		  x2_sbox[state[2]] ^ x3_sbox[state[7]];
4305b1a5451SYen Lin 	tmp[11] = x3_sbox[state[8]] ^ sbox[state[13]] ^
4315b1a5451SYen Lin 		  sbox[state[2]] ^ x2_sbox[state[7]];
4325b1a5451SYen Lin 
4335b1a5451SYen Lin 	/* mixing column 3 */
4345b1a5451SYen Lin 	tmp[12] = x2_sbox[state[12]] ^ x3_sbox[state[1]] ^
4355b1a5451SYen Lin 		  sbox[state[6]] ^ sbox[state[11]];
4365b1a5451SYen Lin 	tmp[13] = sbox[state[12]] ^ x2_sbox[state[1]] ^
4375b1a5451SYen Lin 		  x3_sbox[state[6]] ^ sbox[state[11]];
4385b1a5451SYen Lin 	tmp[14] = sbox[state[12]] ^ sbox[state[1]] ^
4395b1a5451SYen Lin 		  x2_sbox[state[6]] ^ x3_sbox[state[11]];
4405b1a5451SYen Lin 	tmp[15] = x3_sbox[state[12]] ^ sbox[state[1]] ^
4415b1a5451SYen Lin 		  sbox[state[6]] ^ x2_sbox[state[11]];
4425b1a5451SYen Lin 
4435b1a5451SYen Lin 	memcpy(state, tmp, sizeof(tmp));
4445b1a5451SYen Lin }
4455b1a5451SYen Lin 
4465b1a5451SYen Lin /* restore and un-mix each row in a column */
inv_mix_sub_columns(u8 * state)4475b1a5451SYen Lin static void inv_mix_sub_columns(u8 *state)
4485b1a5451SYen Lin {
4495b1a5451SYen Lin 	u8 tmp[4 * AES_STATECOLS];
4505b1a5451SYen Lin 	int  i;
4515b1a5451SYen Lin 
4525b1a5451SYen Lin 	/* restore column 0 */
4535b1a5451SYen Lin 	tmp[0] = x_time_e[state[0]] ^ x_time_b[state[1]] ^
4545b1a5451SYen Lin 		 x_time_d[state[2]] ^ x_time_9[state[3]];
4555b1a5451SYen Lin 	tmp[5] = x_time_9[state[0]] ^ x_time_e[state[1]] ^
4565b1a5451SYen Lin 		 x_time_b[state[2]] ^ x_time_d[state[3]];
4575b1a5451SYen Lin 	tmp[10] = x_time_d[state[0]] ^ x_time_9[state[1]] ^
4585b1a5451SYen Lin 		  x_time_e[state[2]] ^ x_time_b[state[3]];
4595b1a5451SYen Lin 	tmp[15] = x_time_b[state[0]] ^ x_time_d[state[1]] ^
4605b1a5451SYen Lin 		  x_time_9[state[2]] ^ x_time_e[state[3]];
4615b1a5451SYen Lin 
4625b1a5451SYen Lin 	/* restore column 1 */
4635b1a5451SYen Lin 	tmp[4] = x_time_e[state[4]] ^ x_time_b[state[5]] ^
4645b1a5451SYen Lin 		 x_time_d[state[6]] ^ x_time_9[state[7]];
4655b1a5451SYen Lin 	tmp[9] = x_time_9[state[4]] ^ x_time_e[state[5]] ^
4665b1a5451SYen Lin 		 x_time_b[state[6]] ^ x_time_d[state[7]];
4675b1a5451SYen Lin 	tmp[14] = x_time_d[state[4]] ^ x_time_9[state[5]] ^
4685b1a5451SYen Lin 		  x_time_e[state[6]] ^ x_time_b[state[7]];
4695b1a5451SYen Lin 	tmp[3] = x_time_b[state[4]] ^ x_time_d[state[5]] ^
4705b1a5451SYen Lin 		 x_time_9[state[6]] ^ x_time_e[state[7]];
4715b1a5451SYen Lin 
4725b1a5451SYen Lin 	/* restore column 2 */
4735b1a5451SYen Lin 	tmp[8] = x_time_e[state[8]] ^ x_time_b[state[9]] ^
4745b1a5451SYen Lin 		 x_time_d[state[10]] ^ x_time_9[state[11]];
4755b1a5451SYen Lin 	tmp[13] = x_time_9[state[8]] ^ x_time_e[state[9]] ^
4765b1a5451SYen Lin 		  x_time_b[state[10]] ^ x_time_d[state[11]];
4775b1a5451SYen Lin 	tmp[2] = x_time_d[state[8]] ^ x_time_9[state[9]] ^
4785b1a5451SYen Lin 		 x_time_e[state[10]] ^ x_time_b[state[11]];
4795b1a5451SYen Lin 	tmp[7] = x_time_b[state[8]] ^ x_time_d[state[9]] ^
4805b1a5451SYen Lin 		 x_time_9[state[10]] ^ x_time_e[state[11]];
4815b1a5451SYen Lin 
4825b1a5451SYen Lin 	/* restore column 3 */
4835b1a5451SYen Lin 	tmp[12] = x_time_e[state[12]] ^ x_time_b[state[13]] ^
4845b1a5451SYen Lin 		  x_time_d[state[14]] ^ x_time_9[state[15]];
4855b1a5451SYen Lin 	tmp[1] = x_time_9[state[12]] ^ x_time_e[state[13]] ^
4865b1a5451SYen Lin 		 x_time_b[state[14]] ^ x_time_d[state[15]];
4875b1a5451SYen Lin 	tmp[6] = x_time_d[state[12]] ^ x_time_9[state[13]] ^
4885b1a5451SYen Lin 		 x_time_e[state[14]] ^ x_time_b[state[15]];
4895b1a5451SYen Lin 	tmp[11] = x_time_b[state[12]] ^ x_time_d[state[13]] ^
4905b1a5451SYen Lin 		  x_time_9[state[14]] ^ x_time_e[state[15]];
4915b1a5451SYen Lin 
4925b1a5451SYen Lin 	for (i = 0; i < 4 * AES_STATECOLS; i++)
4935b1a5451SYen Lin 		state[i] = inv_sbox[tmp[i]];
4945b1a5451SYen Lin }
4955b1a5451SYen Lin 
4965b1a5451SYen Lin /*
4975b1a5451SYen Lin  * encrypt/decrypt columns of the key
4985b1a5451SYen Lin  * n.b. you can replace this with byte-wise xor if you wish.
4995b1a5451SYen Lin  */
add_round_key(u32 * state,u32 * key)5005b1a5451SYen Lin static void add_round_key(u32 *state, u32 *key)
5015b1a5451SYen Lin {
5025b1a5451SYen Lin 	int idx;
5035b1a5451SYen Lin 
5045b1a5451SYen Lin 	for (idx = 0; idx < 4; idx++)
5055b1a5451SYen Lin 		state[idx] ^= key[idx];
5065b1a5451SYen Lin }
5075b1a5451SYen Lin 
5085b1a5451SYen Lin static u8 rcon[11] = {
5095b1a5451SYen Lin 	0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
5105b1a5451SYen Lin };
5115b1a5451SYen Lin 
5125b1a5451SYen Lin /* produce AES_STATECOLS bytes for each round */
aes_expand_key(u8 * key,u8 * expkey)5135b1a5451SYen Lin void aes_expand_key(u8 *key, u8 *expkey)
5145b1a5451SYen Lin {
5155b1a5451SYen Lin 	u8 tmp0, tmp1, tmp2, tmp3, tmp4;
5165b1a5451SYen Lin 	u32 idx;
5175b1a5451SYen Lin 
5185b1a5451SYen Lin 	memcpy(expkey, key, AES_KEYCOLS * 4);
5195b1a5451SYen Lin 
5205b1a5451SYen Lin 	for (idx = AES_KEYCOLS; idx < AES_STATECOLS * (AES_ROUNDS + 1); idx++) {
5215b1a5451SYen Lin 		tmp0 = expkey[4*idx - 4];
5225b1a5451SYen Lin 		tmp1 = expkey[4*idx - 3];
5235b1a5451SYen Lin 		tmp2 = expkey[4*idx - 2];
5245b1a5451SYen Lin 		tmp3 = expkey[4*idx - 1];
5255b1a5451SYen Lin 		if (!(idx % AES_KEYCOLS)) {
5265b1a5451SYen Lin 			tmp4 = tmp3;
5275b1a5451SYen Lin 			tmp3 = sbox[tmp0];
5285b1a5451SYen Lin 			tmp0 = sbox[tmp1] ^ rcon[idx / AES_KEYCOLS];
5295b1a5451SYen Lin 			tmp1 = sbox[tmp2];
5305b1a5451SYen Lin 			tmp2 = sbox[tmp4];
5315b1a5451SYen Lin 		} else if ((AES_KEYCOLS > 6) && (idx % AES_KEYCOLS == 4)) {
5325b1a5451SYen Lin 			tmp0 = sbox[tmp0];
5335b1a5451SYen Lin 			tmp1 = sbox[tmp1];
5345b1a5451SYen Lin 			tmp2 = sbox[tmp2];
5355b1a5451SYen Lin 			tmp3 = sbox[tmp3];
5365b1a5451SYen Lin 		}
5375b1a5451SYen Lin 
5385b1a5451SYen Lin 		expkey[4*idx+0] = expkey[4*idx - 4*AES_KEYCOLS + 0] ^ tmp0;
5395b1a5451SYen Lin 		expkey[4*idx+1] = expkey[4*idx - 4*AES_KEYCOLS + 1] ^ tmp1;
5405b1a5451SYen Lin 		expkey[4*idx+2] = expkey[4*idx - 4*AES_KEYCOLS + 2] ^ tmp2;
5415b1a5451SYen Lin 		expkey[4*idx+3] = expkey[4*idx - 4*AES_KEYCOLS + 3] ^ tmp3;
5425b1a5451SYen Lin 	}
5435b1a5451SYen Lin }
5445b1a5451SYen Lin 
5455b1a5451SYen Lin /* encrypt one 128 bit block */
aes_encrypt(u8 * in,u8 * expkey,u8 * out)5465b1a5451SYen Lin void aes_encrypt(u8 *in, u8 *expkey, u8 *out)
5475b1a5451SYen Lin {
5485b1a5451SYen Lin 	u8 state[AES_STATECOLS * 4];
5495b1a5451SYen Lin 	u32 round;
5505b1a5451SYen Lin 
5515b1a5451SYen Lin 	memcpy(state, in, AES_STATECOLS * 4);
5525b1a5451SYen Lin 	add_round_key((u32 *)state, (u32 *)expkey);
5535b1a5451SYen Lin 
5545b1a5451SYen Lin 	for (round = 1; round < AES_ROUNDS + 1; round++) {
5555b1a5451SYen Lin 		if (round < AES_ROUNDS)
5565b1a5451SYen Lin 			mix_sub_columns(state);
5575b1a5451SYen Lin 		else
5585b1a5451SYen Lin 			shift_rows(state);
5595b1a5451SYen Lin 
5605b1a5451SYen Lin 		add_round_key((u32 *)state,
5615b1a5451SYen Lin 			      (u32 *)expkey + round * AES_STATECOLS);
5625b1a5451SYen Lin 	}
5635b1a5451SYen Lin 
5645b1a5451SYen Lin 	memcpy(out, state, sizeof(state));
5655b1a5451SYen Lin }
5665b1a5451SYen Lin 
aes_decrypt(u8 * in,u8 * expkey,u8 * out)5675b1a5451SYen Lin void aes_decrypt(u8 *in, u8 *expkey, u8 *out)
5685b1a5451SYen Lin {
5695b1a5451SYen Lin 	u8 state[AES_STATECOLS * 4];
5705b1a5451SYen Lin 	int round;
5715b1a5451SYen Lin 
5725b1a5451SYen Lin 	memcpy(state, in, sizeof(state));
5735b1a5451SYen Lin 
5745b1a5451SYen Lin 	add_round_key((u32 *)state,
5755b1a5451SYen Lin 		      (u32 *)expkey + AES_ROUNDS * AES_STATECOLS);
5765b1a5451SYen Lin 	inv_shift_rows(state);
5775b1a5451SYen Lin 
5785b1a5451SYen Lin 	for (round = AES_ROUNDS; round--; ) {
5795b1a5451SYen Lin 		add_round_key((u32 *)state,
5805b1a5451SYen Lin 			      (u32 *)expkey + round * AES_STATECOLS);
5815b1a5451SYen Lin 		if (round)
5825b1a5451SYen Lin 			inv_mix_sub_columns(state);
5835b1a5451SYen Lin 	}
5845b1a5451SYen Lin 
5855b1a5451SYen Lin 	memcpy(out, state, sizeof(state));
5865b1a5451SYen Lin }
5876e7b9f4fSMarek Vasut 
debug_print_vector(char * name,u32 num_bytes,u8 * data)5886e7b9f4fSMarek Vasut static void debug_print_vector(char *name, u32 num_bytes, u8 *data)
5896e7b9f4fSMarek Vasut {
5906e7b9f4fSMarek Vasut #ifdef DEBUG
5916e7b9f4fSMarek Vasut 	printf("%s [%d] @0x%08x", name, num_bytes, (u32)data);
5926e7b9f4fSMarek Vasut 	print_buffer(0, data, 1, num_bytes, 16);
5936e7b9f4fSMarek Vasut #endif
5946e7b9f4fSMarek Vasut }
5956e7b9f4fSMarek Vasut 
aes_apply_cbc_chain_data(u8 * cbc_chain_data,u8 * src,u8 * dst)59653eb768dSStephen Warren void aes_apply_cbc_chain_data(u8 *cbc_chain_data, u8 *src, u8 *dst)
5976e7b9f4fSMarek Vasut {
5986e7b9f4fSMarek Vasut 	int i;
5996e7b9f4fSMarek Vasut 
6006e7b9f4fSMarek Vasut 	for (i = 0; i < AES_KEY_LENGTH; i++)
6016e7b9f4fSMarek Vasut 		*dst++ = *src++ ^ *cbc_chain_data++;
6026e7b9f4fSMarek Vasut }
6036e7b9f4fSMarek Vasut 
aes_cbc_encrypt_blocks(u8 * key_exp,u8 * src,u8 * dst,u32 num_aes_blocks)6046e7b9f4fSMarek Vasut void aes_cbc_encrypt_blocks(u8 *key_exp, u8 *src, u8 *dst, u32 num_aes_blocks)
6056e7b9f4fSMarek Vasut {
6066e7b9f4fSMarek Vasut 	u8 zero_key[AES_KEY_LENGTH] = { 0 };
6076e7b9f4fSMarek Vasut 	u8 tmp_data[AES_KEY_LENGTH];
6086e7b9f4fSMarek Vasut 	/* Convenient array of 0's for IV */
6096e7b9f4fSMarek Vasut 	u8 *cbc_chain_data = zero_key;
6106e7b9f4fSMarek Vasut 	u32 i;
6116e7b9f4fSMarek Vasut 
6126e7b9f4fSMarek Vasut 	for (i = 0; i < num_aes_blocks; i++) {
6136e7b9f4fSMarek Vasut 		debug("encrypt_object: block %d of %d\n", i, num_aes_blocks);
6146e7b9f4fSMarek Vasut 		debug_print_vector("AES Src", AES_KEY_LENGTH, src);
6156e7b9f4fSMarek Vasut 
6166e7b9f4fSMarek Vasut 		/* Apply the chain data */
61753eb768dSStephen Warren 		aes_apply_cbc_chain_data(cbc_chain_data, src, tmp_data);
6186e7b9f4fSMarek Vasut 		debug_print_vector("AES Xor", AES_KEY_LENGTH, tmp_data);
6196e7b9f4fSMarek Vasut 
6206e7b9f4fSMarek Vasut 		/* Encrypt the AES block */
6216e7b9f4fSMarek Vasut 		aes_encrypt(tmp_data, key_exp, dst);
6226e7b9f4fSMarek Vasut 		debug_print_vector("AES Dst", AES_KEY_LENGTH, dst);
6236e7b9f4fSMarek Vasut 
6246e7b9f4fSMarek Vasut 		/* Update pointers for next loop. */
6256e7b9f4fSMarek Vasut 		cbc_chain_data = dst;
6266e7b9f4fSMarek Vasut 		src += AES_KEY_LENGTH;
6276e7b9f4fSMarek Vasut 		dst += AES_KEY_LENGTH;
6286e7b9f4fSMarek Vasut 	}
6296e7b9f4fSMarek Vasut }
630dc24bb6dSMarek Vasut 
aes_cbc_decrypt_blocks(u8 * key_exp,u8 * src,u8 * dst,u32 num_aes_blocks)631dc24bb6dSMarek Vasut void aes_cbc_decrypt_blocks(u8 *key_exp, u8 *src, u8 *dst, u32 num_aes_blocks)
632dc24bb6dSMarek Vasut {
633dc24bb6dSMarek Vasut 	u8 tmp_data[AES_KEY_LENGTH], tmp_block[AES_KEY_LENGTH];
634dc24bb6dSMarek Vasut 	/* Convenient array of 0's for IV */
635dc24bb6dSMarek Vasut 	u8 cbc_chain_data[AES_KEY_LENGTH] = { 0 };
636dc24bb6dSMarek Vasut 	u32 i;
637dc24bb6dSMarek Vasut 
638dc24bb6dSMarek Vasut 	for (i = 0; i < num_aes_blocks; i++) {
639dc24bb6dSMarek Vasut 		debug("encrypt_object: block %d of %d\n", i, num_aes_blocks);
640dc24bb6dSMarek Vasut 		debug_print_vector("AES Src", AES_KEY_LENGTH, src);
641dc24bb6dSMarek Vasut 
642dc24bb6dSMarek Vasut 		memcpy(tmp_block, src, AES_KEY_LENGTH);
643dc24bb6dSMarek Vasut 
644dc24bb6dSMarek Vasut 		/* Decrypt the AES block */
645dc24bb6dSMarek Vasut 		aes_decrypt(src, key_exp, tmp_data);
646dc24bb6dSMarek Vasut 		debug_print_vector("AES Xor", AES_KEY_LENGTH, tmp_data);
647dc24bb6dSMarek Vasut 
648dc24bb6dSMarek Vasut 		/* Apply the chain data */
64953eb768dSStephen Warren 		aes_apply_cbc_chain_data(cbc_chain_data, tmp_data, dst);
650dc24bb6dSMarek Vasut 		debug_print_vector("AES Dst", AES_KEY_LENGTH, dst);
651dc24bb6dSMarek Vasut 
652dc24bb6dSMarek Vasut 		/* Update pointers for next loop. */
653dc24bb6dSMarek Vasut 		memcpy(cbc_chain_data, tmp_block, AES_KEY_LENGTH);
654dc24bb6dSMarek Vasut 		src += AES_KEY_LENGTH;
655dc24bb6dSMarek Vasut 		dst += AES_KEY_LENGTH;
656dc24bb6dSMarek Vasut 	}
657dc24bb6dSMarek Vasut }
658