1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <string.h>
18 #include <stdint.h>
19 #include <nanohub/aes.h>
20
21
22 #define AES_NUM_ROUNDS 14
23
24
25
26 static const uint8_t FwdSbox[] = {
27 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
28 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
29 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
30 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
31 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
32 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
33 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
34 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
35 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
36 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
37 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
38 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
39 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
40 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
41 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
42 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16,
43 };
44
45 static const uint8_t RevSbox[] = {
46 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
47 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
48 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
49 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
50 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
51 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
52 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
53 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
54 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
55 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
56 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
57 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
58 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
59 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
60 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
61 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D,
62 };
63
64 static const uint32_t FwdTab0[] = { //other 3 tables are this same table, RORed 8, 16, and 24 bits respectively.
65 0xC66363A5, 0xF87C7C84, 0xEE777799, 0xF67B7B8D, 0xFFF2F20D, 0xD66B6BBD, 0xDE6F6FB1, 0x91C5C554,
66 0x60303050, 0x02010103, 0xCE6767A9, 0x562B2B7D, 0xE7FEFE19, 0xB5D7D762, 0x4DABABE6, 0xEC76769A,
67 0x8FCACA45, 0x1F82829D, 0x89C9C940, 0xFA7D7D87, 0xEFFAFA15, 0xB25959EB, 0x8E4747C9, 0xFBF0F00B,
68 0x41ADADEC, 0xB3D4D467, 0x5FA2A2FD, 0x45AFAFEA, 0x239C9CBF, 0x53A4A4F7, 0xE4727296, 0x9BC0C05B,
69 0x75B7B7C2, 0xE1FDFD1C, 0x3D9393AE, 0x4C26266A, 0x6C36365A, 0x7E3F3F41, 0xF5F7F702, 0x83CCCC4F,
70 0x6834345C, 0x51A5A5F4, 0xD1E5E534, 0xF9F1F108, 0xE2717193, 0xABD8D873, 0x62313153, 0x2A15153F,
71 0x0804040C, 0x95C7C752, 0x46232365, 0x9DC3C35E, 0x30181828, 0x379696A1, 0x0A05050F, 0x2F9A9AB5,
72 0x0E070709, 0x24121236, 0x1B80809B, 0xDFE2E23D, 0xCDEBEB26, 0x4E272769, 0x7FB2B2CD, 0xEA75759F,
73 0x1209091B, 0x1D83839E, 0x582C2C74, 0x341A1A2E, 0x361B1B2D, 0xDC6E6EB2, 0xB45A5AEE, 0x5BA0A0FB,
74 0xA45252F6, 0x763B3B4D, 0xB7D6D661, 0x7DB3B3CE, 0x5229297B, 0xDDE3E33E, 0x5E2F2F71, 0x13848497,
75 0xA65353F5, 0xB9D1D168, 0x00000000, 0xC1EDED2C, 0x40202060, 0xE3FCFC1F, 0x79B1B1C8, 0xB65B5BED,
76 0xD46A6ABE, 0x8DCBCB46, 0x67BEBED9, 0x7239394B, 0x944A4ADE, 0x984C4CD4, 0xB05858E8, 0x85CFCF4A,
77 0xBBD0D06B, 0xC5EFEF2A, 0x4FAAAAE5, 0xEDFBFB16, 0x864343C5, 0x9A4D4DD7, 0x66333355, 0x11858594,
78 0x8A4545CF, 0xE9F9F910, 0x04020206, 0xFE7F7F81, 0xA05050F0, 0x783C3C44, 0x259F9FBA, 0x4BA8A8E3,
79 0xA25151F3, 0x5DA3A3FE, 0x804040C0, 0x058F8F8A, 0x3F9292AD, 0x219D9DBC, 0x70383848, 0xF1F5F504,
80 0x63BCBCDF, 0x77B6B6C1, 0xAFDADA75, 0x42212163, 0x20101030, 0xE5FFFF1A, 0xFDF3F30E, 0xBFD2D26D,
81 0x81CDCD4C, 0x180C0C14, 0x26131335, 0xC3ECEC2F, 0xBE5F5FE1, 0x359797A2, 0x884444CC, 0x2E171739,
82 0x93C4C457, 0x55A7A7F2, 0xFC7E7E82, 0x7A3D3D47, 0xC86464AC, 0xBA5D5DE7, 0x3219192B, 0xE6737395,
83 0xC06060A0, 0x19818198, 0x9E4F4FD1, 0xA3DCDC7F, 0x44222266, 0x542A2A7E, 0x3B9090AB, 0x0B888883,
84 0x8C4646CA, 0xC7EEEE29, 0x6BB8B8D3, 0x2814143C, 0xA7DEDE79, 0xBC5E5EE2, 0x160B0B1D, 0xADDBDB76,
85 0xDBE0E03B, 0x64323256, 0x743A3A4E, 0x140A0A1E, 0x924949DB, 0x0C06060A, 0x4824246C, 0xB85C5CE4,
86 0x9FC2C25D, 0xBDD3D36E, 0x43ACACEF, 0xC46262A6, 0x399191A8, 0x319595A4, 0xD3E4E437, 0xF279798B,
87 0xD5E7E732, 0x8BC8C843, 0x6E373759, 0xDA6D6DB7, 0x018D8D8C, 0xB1D5D564, 0x9C4E4ED2, 0x49A9A9E0,
88 0xD86C6CB4, 0xAC5656FA, 0xF3F4F407, 0xCFEAEA25, 0xCA6565AF, 0xF47A7A8E, 0x47AEAEE9, 0x10080818,
89 0x6FBABAD5, 0xF0787888, 0x4A25256F, 0x5C2E2E72, 0x381C1C24, 0x57A6A6F1, 0x73B4B4C7, 0x97C6C651,
90 0xCBE8E823, 0xA1DDDD7C, 0xE874749C, 0x3E1F1F21, 0x964B4BDD, 0x61BDBDDC, 0x0D8B8B86, 0x0F8A8A85,
91 0xE0707090, 0x7C3E3E42, 0x71B5B5C4, 0xCC6666AA, 0x904848D8, 0x06030305, 0xF7F6F601, 0x1C0E0E12,
92 0xC26161A3, 0x6A35355F, 0xAE5757F9, 0x69B9B9D0, 0x17868691, 0x99C1C158, 0x3A1D1D27, 0x279E9EB9,
93 0xD9E1E138, 0xEBF8F813, 0x2B9898B3, 0x22111133, 0xD26969BB, 0xA9D9D970, 0x078E8E89, 0x339494A7,
94 0x2D9B9BB6, 0x3C1E1E22, 0x15878792, 0xC9E9E920, 0x87CECE49, 0xAA5555FF, 0x50282878, 0xA5DFDF7A,
95 0x038C8C8F, 0x59A1A1F8, 0x09898980, 0x1A0D0D17, 0x65BFBFDA, 0xD7E6E631, 0x844242C6, 0xD06868B8,
96 0x824141C3, 0x299999B0, 0x5A2D2D77, 0x1E0F0F11, 0x7BB0B0CB, 0xA85454FC, 0x6DBBBBD6, 0x2C16163A,
97 };
98
99 static const uint32_t RevTab0[] = { //other 3 tables are this same table, RORed 8, 16, and 24 bits respectively.
100 0x51F4A750, 0x7E416553, 0x1A17A4C3, 0x3A275E96, 0x3BAB6BCB, 0x1F9D45F1, 0xACFA58AB, 0x4BE30393,
101 0x2030FA55, 0xAD766DF6, 0x88CC7691, 0xF5024C25, 0x4FE5D7FC, 0xC52ACBD7, 0x26354480, 0xB562A38F,
102 0xDEB15A49, 0x25BA1B67, 0x45EA0E98, 0x5DFEC0E1, 0xC32F7502, 0x814CF012, 0x8D4697A3, 0x6BD3F9C6,
103 0x038F5FE7, 0x15929C95, 0xBF6D7AEB, 0x955259DA, 0xD4BE832D, 0x587421D3, 0x49E06929, 0x8EC9C844,
104 0x75C2896A, 0xF48E7978, 0x99583E6B, 0x27B971DD, 0xBEE14FB6, 0xF088AD17, 0xC920AC66, 0x7DCE3AB4,
105 0x63DF4A18, 0xE51A3182, 0x97513360, 0x62537F45, 0xB16477E0, 0xBB6BAE84, 0xFE81A01C, 0xF9082B94,
106 0x70486858, 0x8F45FD19, 0x94DE6C87, 0x527BF8B7, 0xAB73D323, 0x724B02E2, 0xE31F8F57, 0x6655AB2A,
107 0xB2EB2807, 0x2FB5C203, 0x86C57B9A, 0xD33708A5, 0x302887F2, 0x23BFA5B2, 0x02036ABA, 0xED16825C,
108 0x8ACF1C2B, 0xA779B492, 0xF307F2F0, 0x4E69E2A1, 0x65DAF4CD, 0x0605BED5, 0xD134621F, 0xC4A6FE8A,
109 0x342E539D, 0xA2F355A0, 0x058AE132, 0xA4F6EB75, 0x0B83EC39, 0x4060EFAA, 0x5E719F06, 0xBD6E1051,
110 0x3E218AF9, 0x96DD063D, 0xDD3E05AE, 0x4DE6BD46, 0x91548DB5, 0x71C45D05, 0x0406D46F, 0x605015FF,
111 0x1998FB24, 0xD6BDE997, 0x894043CC, 0x67D99E77, 0xB0E842BD, 0x07898B88, 0xE7195B38, 0x79C8EEDB,
112 0xA17C0A47, 0x7C420FE9, 0xF8841EC9, 0x00000000, 0x09808683, 0x322BED48, 0x1E1170AC, 0x6C5A724E,
113 0xFD0EFFFB, 0x0F853856, 0x3DAED51E, 0x362D3927, 0x0A0FD964, 0x685CA621, 0x9B5B54D1, 0x24362E3A,
114 0x0C0A67B1, 0x9357E70F, 0xB4EE96D2, 0x1B9B919E, 0x80C0C54F, 0x61DC20A2, 0x5A774B69, 0x1C121A16,
115 0xE293BA0A, 0xC0A02AE5, 0x3C22E043, 0x121B171D, 0x0E090D0B, 0xF28BC7AD, 0x2DB6A8B9, 0x141EA9C8,
116 0x57F11985, 0xAF75074C, 0xEE99DDBB, 0xA37F60FD, 0xF701269F, 0x5C72F5BC, 0x44663BC5, 0x5BFB7E34,
117 0x8B432976, 0xCB23C6DC, 0xB6EDFC68, 0xB8E4F163, 0xD731DCCA, 0x42638510, 0x13972240, 0x84C61120,
118 0x854A247D, 0xD2BB3DF8, 0xAEF93211, 0xC729A16D, 0x1D9E2F4B, 0xDCB230F3, 0x0D8652EC, 0x77C1E3D0,
119 0x2BB3166C, 0xA970B999, 0x119448FA, 0x47E96422, 0xA8FC8CC4, 0xA0F03F1A, 0x567D2CD8, 0x223390EF,
120 0x87494EC7, 0xD938D1C1, 0x8CCAA2FE, 0x98D40B36, 0xA6F581CF, 0xA57ADE28, 0xDAB78E26, 0x3FADBFA4,
121 0x2C3A9DE4, 0x5078920D, 0x6A5FCC9B, 0x547E4662, 0xF68D13C2, 0x90D8B8E8, 0x2E39F75E, 0x82C3AFF5,
122 0x9F5D80BE, 0x69D0937C, 0x6FD52DA9, 0xCF2512B3, 0xC8AC993B, 0x10187DA7, 0xE89C636E, 0xDB3BBB7B,
123 0xCD267809, 0x6E5918F4, 0xEC9AB701, 0x834F9AA8, 0xE6956E65, 0xAAFFE67E, 0x21BCCF08, 0xEF15E8E6,
124 0xBAE79BD9, 0x4A6F36CE, 0xEA9F09D4, 0x29B07CD6, 0x31A4B2AF, 0x2A3F2331, 0xC6A59430, 0x35A266C0,
125 0x744EBC37, 0xFC82CAA6, 0xE090D0B0, 0x33A7D815, 0xF104984A, 0x41ECDAF7, 0x7FCD500E, 0x1791F62F,
126 0x764DD68D, 0x43EFB04D, 0xCCAA4D54, 0xE49604DF, 0x9ED1B5E3, 0x4C6A881B, 0xC12C1FB8, 0x4665517F,
127 0x9D5EEA04, 0x018C355D, 0xFA877473, 0xFB0B412E, 0xB3671D5A, 0x92DBD252, 0xE9105633, 0x6DD64713,
128 0x9AD7618C, 0x37A10C7A, 0x59F8148E, 0xEB133C89, 0xCEA927EE, 0xB761C935, 0xE11CE5ED, 0x7A47B13C,
129 0x9CD2DF59, 0x55F2733F, 0x1814CE79, 0x73C737BF, 0x53F7CDEA, 0x5FFDAA5B, 0xDF3D6F14, 0x7844DB86,
130 0xCAAFF381, 0xB968C43E, 0x3824342C, 0xC2A3405F, 0x161DC372, 0xBCE2250C, 0x283C498B, 0xFF0D9541,
131 0x39A80171, 0x080CB3DE, 0xD8B4E49C, 0x6456C190, 0x7BCB8461, 0xD532B670, 0x486C5C74, 0xD0B85742,
132 };
133
134 #ifdef ARM
135
136 #define STRINFIGY2(b) #b
137 #define STRINGIFY(b) STRINFIGY2(b)
138 #define ror(v, b) ({uint32_t ret; if (b) asm("ror %0, #" STRINGIFY(b) :"=r"(ret):"0"(v)); else ret = v; ret;})
139
140 #else
141
ror(uint32_t val,uint32_t by)142 inline static uint32_t ror(uint32_t val, uint32_t by)
143 {
144 if (!by)
145 return val;
146
147 val = (val >> by) | (val << (32 - by));
148
149 return val;
150 }
151
152 #endif
153
154
aesInitForEncr(struct AesContext * ctx,const uint32_t * k)155 void aesInitForEncr(struct AesContext *ctx, const uint32_t *k)
156 {
157 uint32_t i, *ks = ctx->K, roundConstant = 0x01000000;
158
159 //first 8 words are just the key itself
160 memcpy(ctx->K, k, sizeof(uint32_t[AES_KEY_WORDS]));
161
162 //create round keys for encryption
163 for (i = 0; i < 7; i++, ks += 8, roundConstant <<= 1) {
164 ks[8] = ks[0] ^ roundConstant
165 ^ (((uint32_t)FwdSbox[(ks[ 7] >> 16) & 0xff]) << 24)
166 ^ (((uint32_t)FwdSbox[(ks[ 7] >> 8) & 0xff]) << 16)
167 ^ (((uint32_t)FwdSbox[(ks[ 7] >> 0) & 0xff]) << 8)
168 ^ (((uint32_t)FwdSbox[(ks[ 7] >> 24) & 0xff]) << 0);
169 ks[9] = ks[1] ^ ks[8];
170 ks[10] = ks[2] ^ ks[9];
171 ks[11] = ks[3] ^ ks[10];
172 ks[12] = ks[4]
173 ^ (((uint32_t)FwdSbox[(ks[11] >> 24) & 0xff]) << 24)
174 ^ (((uint32_t)FwdSbox[(ks[11] >> 16) & 0xff]) << 16)
175 ^ (((uint32_t)FwdSbox[(ks[11] >> 8) & 0xff]) << 8)
176 ^ (((uint32_t)FwdSbox[(ks[11] >> 0) & 0xff]) << 0);
177 ks[13] = ks[5] ^ ks[12];
178 ks[14] = ks[6] ^ ks[13];
179 ks[15] = ks[7] ^ ks[14];
180 }
181 }
182
aesInitForDecr(struct AesContext * ctx,struct AesSetupTempWorksSpace * tmpSpace,const uint32_t * k)183 void aesInitForDecr(struct AesContext *ctx, struct AesSetupTempWorksSpace *tmpSpace, const uint32_t *k)
184 {
185 uint32_t i, j, *ks = ctx->K + 4, *encrK = tmpSpace->tmpCtx.K + 52;
186
187 //we need encryption keys to calculate decryption keys
188 aesInitForEncr(&tmpSpace->tmpCtx, k);
189
190 //now we can calculate round keys for decryption
191 memcpy(ctx->K, tmpSpace->tmpCtx.K + 56, sizeof(uint32_t[4]));
192 for (i = 0; i < AES_NUM_ROUNDS - 1; i++, encrK -= 4, ks += 4) { //num_rounds-1 seems to be concensus, but num_rounds make more sense...
193 for (j = 0; j < 4; j++) {
194 ks[j] =
195 ror(RevTab0[FwdSbox[(encrK[j] >> 24) & 0xff]], 0) ^
196 ror(RevTab0[FwdSbox[(encrK[j] >> 16) & 0xff]], 8) ^
197 ror(RevTab0[FwdSbox[(encrK[j] >> 8) & 0xff]], 16) ^
198 ror(RevTab0[FwdSbox[(encrK[j] >> 0) & 0xff]], 24);
199 }
200 }
201 memcpy(ks, encrK, sizeof(uint32_t[4]));
202 }
203
aesEncr(struct AesContext * ctx,const uint32_t * src,uint32_t * dst)204 void aesEncr(struct AesContext *ctx, const uint32_t *src, uint32_t *dst)
205 {
206 uint32_t x0, x1, x2, x3; //we CAN use an array, but then GCC will not use registers. so we use separate vars. sigh...
207 uint32_t *k = ctx->K, i;
208
209 //setup
210 x0 = *src++ ^ *k++;
211 x1 = *src++ ^ *k++;
212 x2 = *src++ ^ *k++;
213 x3 = *src++ ^ *k++;
214
215 //all-but-last round
216 for (i = 0; i < AES_NUM_ROUNDS - 1; i++) {
217 uint32_t t0, t1, t2;
218
219 t0 = *k++ ^
220 ror(FwdTab0[(x0 >> 24) & 0xff], 0) ^
221 ror(FwdTab0[(x1 >> 16) & 0xff], 8) ^
222 ror(FwdTab0[(x2 >> 8) & 0xff], 16) ^
223 ror(FwdTab0[(x3 >> 0) & 0xff], 24);
224
225 t1 = *k++ ^
226 ror(FwdTab0[(x1 >> 24) & 0xff], 0) ^
227 ror(FwdTab0[(x2 >> 16) & 0xff], 8) ^
228 ror(FwdTab0[(x3 >> 8) & 0xff], 16) ^
229 ror(FwdTab0[(x0 >> 0) & 0xff], 24);
230
231 t2 = *k++ ^
232 ror(FwdTab0[(x2 >> 24) & 0xff], 0) ^
233 ror(FwdTab0[(x3 >> 16) & 0xff], 8) ^
234 ror(FwdTab0[(x0 >> 8) & 0xff], 16) ^
235 ror(FwdTab0[(x1 >> 0) & 0xff], 24);
236
237 x3 = *k++ ^
238 ror(FwdTab0[(x3 >> 24) & 0xff], 0) ^
239 ror(FwdTab0[(x0 >> 16) & 0xff], 8) ^
240 ror(FwdTab0[(x1 >> 8) & 0xff], 16) ^
241 ror(FwdTab0[(x2 >> 0) & 0xff], 24);
242
243 x0 = t0;
244 x1 = t1;
245 x2 = t2;
246 }
247
248 //last round
249 *dst++ = *k++ ^
250 (((uint32_t)(FwdSbox[(x0 >> 24) & 0xff])) << 24) ^
251 (((uint32_t)(FwdSbox[(x1 >> 16) & 0xff])) << 16) ^
252 (((uint32_t)(FwdSbox[(x2 >> 8) & 0xff])) << 8) ^
253 (((uint32_t)(FwdSbox[(x3 >> 0) & 0xff])) << 0);
254
255 *dst++ = *k++ ^
256 (((uint32_t)(FwdSbox[(x1 >> 24) & 0xff])) << 24) ^
257 (((uint32_t)(FwdSbox[(x2 >> 16) & 0xff])) << 16) ^
258 (((uint32_t)(FwdSbox[(x3 >> 8) & 0xff])) << 8) ^
259 (((uint32_t)(FwdSbox[(x0 >> 0) & 0xff])) << 0);
260
261 *dst++ = *k++ ^
262 (((uint32_t)(FwdSbox[(x2 >> 24) & 0xff])) << 24) ^
263 (((uint32_t)(FwdSbox[(x3 >> 16) & 0xff])) << 16) ^
264 (((uint32_t)(FwdSbox[(x0 >> 8) & 0xff])) << 8) ^
265 (((uint32_t)(FwdSbox[(x1 >> 0) & 0xff])) << 0);
266
267 *dst++ = *k++ ^
268 (((uint32_t)(FwdSbox[(x3 >> 24) & 0xff])) << 24) ^
269 (((uint32_t)(FwdSbox[(x0 >> 16) & 0xff])) << 16) ^
270 (((uint32_t)(FwdSbox[(x1 >> 8) & 0xff])) << 8) ^
271 (((uint32_t)(FwdSbox[(x2 >> 0) & 0xff])) << 0);
272 }
273
aesDecr(struct AesContext * ctx,const uint32_t * src,uint32_t * dst)274 void aesDecr(struct AesContext *ctx, const uint32_t *src, uint32_t *dst)
275 {
276 uint32_t x0, x1, x2, x3;
277 uint32_t *k = ctx->K, i;
278
279 //setup
280 x0 = *src++ ^ *k++;
281 x1 = *src++ ^ *k++;
282 x2 = *src++ ^ *k++;
283 x3 = *src++ ^ *k++;
284
285 //all-but-last round
286 for (i = 0; i < AES_NUM_ROUNDS - 1; i++) {
287 uint32_t t0, t1, t2;
288
289 t0 = *k++ ^
290 ror(RevTab0[(x0 >> 24) & 0xff], 0) ^
291 ror(RevTab0[(x3 >> 16) & 0xff], 8) ^
292 ror(RevTab0[(x2 >> 8) & 0xff], 16) ^
293 ror(RevTab0[(x1 >> 0) & 0xff], 24);
294
295 t1 = *k++ ^
296 ror(RevTab0[(x1 >> 24) & 0xff], 0) ^
297 ror(RevTab0[(x0 >> 16) & 0xff], 8) ^
298 ror(RevTab0[(x3 >> 8) & 0xff], 16) ^
299 ror(RevTab0[(x2 >> 0) & 0xff], 24);
300
301 t2 = *k++ ^
302 ror(RevTab0[(x2 >> 24) & 0xff], 0) ^
303 ror(RevTab0[(x1 >> 16) & 0xff], 8) ^
304 ror(RevTab0[(x0 >> 8) & 0xff], 16) ^
305 ror(RevTab0[(x3 >> 0) & 0xff], 24);
306
307 x3 = *k++ ^
308 ror(RevTab0[(x3 >> 24) & 0xff], 0) ^
309 ror(RevTab0[(x2 >> 16) & 0xff], 8) ^
310 ror(RevTab0[(x1 >> 8) & 0xff], 16) ^
311 ror(RevTab0[(x0 >> 0) & 0xff], 24);
312
313 x0 = t0;
314 x1 = t1;
315 x2 = t2;
316 }
317
318 //last round
319 *dst++ = *k++ ^
320 (((uint32_t)(RevSbox[(x0 >> 24) & 0xff])) << 24) ^
321 (((uint32_t)(RevSbox[(x3 >> 16) & 0xff])) << 16) ^
322 (((uint32_t)(RevSbox[(x2 >> 8) & 0xff])) << 8) ^
323 (((uint32_t)(RevSbox[(x1 >> 0) & 0xff])) << 0);
324
325 *dst++ = *k++ ^
326 (((uint32_t)(RevSbox[(x1 >> 24) & 0xff])) << 24) ^
327 (((uint32_t)(RevSbox[(x0 >> 16) & 0xff])) << 16) ^
328 (((uint32_t)(RevSbox[(x3 >> 8) & 0xff])) << 8) ^
329 (((uint32_t)(RevSbox[(x2 >> 0) & 0xff])) << 0);
330
331 *dst++ = *k++ ^
332 (((uint32_t)(RevSbox[(x2 >> 24) & 0xff])) << 24) ^
333 (((uint32_t)(RevSbox[(x1 >> 16) & 0xff])) << 16) ^
334 (((uint32_t)(RevSbox[(x0 >> 8) & 0xff])) << 8) ^
335 (((uint32_t)(RevSbox[(x3 >> 0) & 0xff])) << 0);
336
337 *dst++ = *k++ ^
338 (((uint32_t)(RevSbox[(x3 >> 24) & 0xff])) << 24) ^
339 (((uint32_t)(RevSbox[(x2 >> 16) & 0xff])) << 16) ^
340 (((uint32_t)(RevSbox[(x1 >> 8) & 0xff])) << 8) ^
341 (((uint32_t)(RevSbox[(x0 >> 0) & 0xff])) << 0);
342 }
343
aesCbcInitForEncr(struct AesCbcContext * ctx,const uint32_t * k,const uint32_t * iv)344 void aesCbcInitForEncr(struct AesCbcContext *ctx, const uint32_t *k, const uint32_t *iv)
345 {
346 aesInitForEncr(&ctx->aes, k);
347 memcpy(ctx->iv, iv, sizeof(uint32_t[AES_BLOCK_WORDS]));
348 }
349
aesCbcInitForDecr(struct AesCbcContext * ctx,const uint32_t * k,const uint32_t * iv)350 void aesCbcInitForDecr(struct AesCbcContext *ctx, const uint32_t *k, const uint32_t *iv)
351 {
352 struct AesSetupTempWorksSpace tmp;
353
354 aesInitForDecr(&ctx->aes, &tmp, k);
355 memcpy(ctx->iv, iv, sizeof(uint32_t[AES_BLOCK_WORDS]));
356 }
357
aesCbcEncr(struct AesCbcContext * ctx,const uint32_t * src,uint32_t * dst)358 void aesCbcEncr(struct AesCbcContext *ctx, const uint32_t *src, uint32_t *dst)
359 {
360 uint32_t i;
361
362 for (i = 0; i < AES_BLOCK_WORDS; i++)
363 ctx->iv[i] ^= *src++;
364
365 aesEncr(&ctx->aes, ctx->iv, dst);
366 memcpy(ctx->iv, dst, sizeof(uint32_t[AES_BLOCK_WORDS]));
367 }
368
aesCbcDecr(struct AesCbcContext * ctx,const uint32_t * src,uint32_t * dst)369 void aesCbcDecr(struct AesCbcContext *ctx, const uint32_t *src, uint32_t *dst)
370 {
371 uint32_t i, tmp[AES_BLOCK_WORDS];
372
373 aesDecr(&ctx->aes, src, tmp);
374 for (i = 0; i < AES_BLOCK_WORDS; i++)
375 tmp[i] ^= ctx->iv[i];
376
377 memcpy(ctx->iv, src, sizeof(uint32_t[AES_BLOCK_WORDS]));
378 memcpy(dst, tmp, sizeof(uint32_t[AES_BLOCK_WORDS]));
379 }
380
381
382
383
384
385