Home | History | Annotate | Download | only in nanohub
      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