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 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 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 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 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 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 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 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 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 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