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