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