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