1f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* LibTomCrypt, modular cryptographic library -- Tom St Denis
2f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
3f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * LibTomCrypt is a library that provides various cryptographic
4f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * algorithms in a highly modular and flexible manner.
5f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
6f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * The library is free for all purposes without any express
7f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * guarantee it works.
8f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
9f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
10f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */
11f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
12f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* AES implementation by Tom St Denis
13f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
14f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Derived from the Public Domain source code by
15f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
16f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project---
17f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  * rijndael-alg-fst.c
18f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  *
19f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  * @version 3.0 (December 2000)
20f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  *
21f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  * Optimised ANSI C code for the Rijndael cipher (now AES)
22f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  *
23f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
24f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
25f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  * @author Paulo Barreto <paulo.barreto@terra.com.br>
26f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project---
27f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */
28f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
29f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @file aes.c
30f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  Implementation of AES
31f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
32f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
33f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "tomcrypt.h"
34f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
35f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef RIJNDAEL
36f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
37f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifndef ENCRYPT_ONLY
38f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
39f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define SETUP    rijndael_setup
40f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define ECB_ENC  rijndael_ecb_encrypt
41f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define ECB_DEC  rijndael_ecb_decrypt
42f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define ECB_DONE rijndael_done
43f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define ECB_TEST rijndael_test
44f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define ECB_KS   rijndael_keysize
45f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
46f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#if 0
47f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectconst struct ltc_cipher_descriptor rijndael_desc =
48f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
49f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    "rijndael",
50f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    6,
51f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    16, 32, 16, 10,
52f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS,
53f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
54f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project};
55f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
56f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
57f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectconst struct ltc_cipher_descriptor aes_desc =
58f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
59f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    "aes",
60f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    6,
61f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    16, 32, 16, 10,
62f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS,
63f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
64f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project};
65f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
66f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#else
67f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
68f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define SETUP    rijndael_enc_setup
69f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define ECB_ENC  rijndael_enc_ecb_encrypt
70f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define ECB_KS   rijndael_enc_keysize
71f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define ECB_DONE rijndael_enc_done
72f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
73f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectconst struct ltc_cipher_descriptor rijndael_enc_desc =
74f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
75f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    "rijndael",
76f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    6,
77f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    16, 32, 16, 10,
78f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS,
79f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
80f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project};
81f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
82f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectconst struct ltc_cipher_descriptor aes_enc_desc =
83f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
84f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    "aes",
85f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    6,
86f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    16, 32, 16, 10,
87f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS,
88f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
89f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project};
90f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
91f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
92f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
93f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "aes_tab.c"
94f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
95f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic ulong32 setup_mix(ulong32 temp)
96f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
97f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   return (Te4_3[byte(temp, 2)]) ^
98f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          (Te4_2[byte(temp, 1)]) ^
99f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          (Te4_1[byte(temp, 0)]) ^
100f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          (Te4_0[byte(temp, 3)]);
101f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
102f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
103f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifndef ENCRYPT_ONLY
104f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_SMALL_CODE
105f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic ulong32 setup_mix2(ulong32 temp)
106f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
107f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   return Td0(255 & Te4[byte(temp, 3)]) ^
108f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          Td1(255 & Te4[byte(temp, 2)]) ^
109f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          Td2(255 & Te4[byte(temp, 1)]) ^
110f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          Td3(255 & Te4[byte(temp, 0)]);
111f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
112f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
113f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
114f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
115f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /**
116f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    Initialize the AES (Rijndael) block cipher
117f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    @param key The symmetric key you wish to pass
118f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    @param keylen The key length in bytes
119f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    @param num_rounds The number of rounds desired (0 for default)
120f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    @param skey The key in as scheduled by this function.
121f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    @return CRYPT_OK if successful
122f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */
123f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
124f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
125f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    int i, j;
126f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    ulong32 temp, *rk;
127f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifndef ENCRYPT_ONLY
128f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    ulong32 *rrk;
129f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
130f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LTC_ARGCHK(key  != NULL);
131f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LTC_ARGCHK(skey != NULL);
132f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
133f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    if (keylen != 16 && keylen != 24 && keylen != 32) {
134f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       return CRYPT_INVALID_KEYSIZE;
135f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
136f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
137f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    if (num_rounds != 0 && num_rounds != (10 + ((keylen/8)-2)*2)) {
138f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       return CRYPT_INVALID_ROUNDS;
139f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
140f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
141f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    skey->rijndael.Nr = 10 + ((keylen/8)-2)*2;
142f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
143f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* setup the forward key */
144f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    i                 = 0;
145f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    rk                = skey->rijndael.eK;
146f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LOAD32H(rk[0], key     );
147f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LOAD32H(rk[1], key +  4);
148f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LOAD32H(rk[2], key +  8);
149f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LOAD32H(rk[3], key + 12);
150f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    if (keylen == 16) {
151f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        j = 44;
152f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        for (;;) {
153f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            temp  = rk[3];
154f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[4] = rk[0] ^ setup_mix(temp) ^ rcon[i];
155f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[5] = rk[1] ^ rk[4];
156f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[6] = rk[2] ^ rk[5];
157f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[7] = rk[3] ^ rk[6];
158f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            if (++i == 10) {
159f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project               break;
160f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            }
161f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk += 4;
162f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        }
163f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    } else if (keylen == 24) {
164f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        j = 52;
165f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        LOAD32H(rk[4], key + 16);
166f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        LOAD32H(rk[5], key + 20);
167f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        for (;;) {
168f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        #ifdef _MSC_VER
169f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5];
170f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        #else
171f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            temp = rk[5];
172f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        #endif
173f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[ 6] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
174f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[ 7] = rk[ 1] ^ rk[ 6];
175f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[ 8] = rk[ 2] ^ rk[ 7];
176f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[ 9] = rk[ 3] ^ rk[ 8];
177f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            if (++i == 8) {
178f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project                break;
179f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            }
180f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[10] = rk[ 4] ^ rk[ 9];
181f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[11] = rk[ 5] ^ rk[10];
182f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk += 6;
183f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        }
184f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    } else if (keylen == 32) {
185f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        j = 60;
186f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        LOAD32H(rk[4], key + 16);
187f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        LOAD32H(rk[5], key + 20);
188f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        LOAD32H(rk[6], key + 24);
189f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        LOAD32H(rk[7], key + 28);
190f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        for (;;) {
191f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        #ifdef _MSC_VER
192f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7];
193f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        #else
194f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            temp = rk[7];
195f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        #endif
196f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[ 8] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
197f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[ 9] = rk[ 1] ^ rk[ 8];
198f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[10] = rk[ 2] ^ rk[ 9];
199f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[11] = rk[ 3] ^ rk[10];
200f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            if (++i == 7) {
201f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project                break;
202f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            }
203f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            temp = rk[11];
204f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[12] = rk[ 4] ^ setup_mix(RORc(temp, 8));
205f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[13] = rk[ 5] ^ rk[12];
206f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[14] = rk[ 6] ^ rk[13];
207f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[15] = rk[ 7] ^ rk[14];
208f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk += 8;
209f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        }
210f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    } else {
211f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       /* this can't happen */
212f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       return CRYPT_ERROR;
213f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
214f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
215f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifndef ENCRYPT_ONLY
216f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* setup the inverse key now */
217f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    rk   = skey->rijndael.dK;
218f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    rrk  = skey->rijndael.eK + j - 4;
219f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
220f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* apply the inverse MixColumn transform to all round keys but the first and the last: */
221f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* copy first */
222f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    *rk++ = *rrk++;
223f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    *rk++ = *rrk++;
224f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    *rk++ = *rrk++;
225f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    *rk   = *rrk;
226f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    rk -= 3; rrk -= 3;
227f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
228f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (i = 1; i < skey->rijndael.Nr; i++) {
229f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rrk -= 4;
230f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk  += 4;
231f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    #ifdef LTC_SMALL_CODE
232f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        temp = rrk[0];
233f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk[0] = setup_mix2(temp);
234f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        temp = rrk[1];
235f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk[1] = setup_mix2(temp);
236f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        temp = rrk[2];
237f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk[2] = setup_mix2(temp);
238f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        temp = rrk[3];
239f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk[3] = setup_mix2(temp);
240f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     #else
241f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        temp = rrk[0];
242f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk[0] =
243f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Tks0[byte(temp, 3)] ^
244f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Tks1[byte(temp, 2)] ^
245f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Tks2[byte(temp, 1)] ^
246f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Tks3[byte(temp, 0)];
247f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        temp = rrk[1];
248f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk[1] =
249f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Tks0[byte(temp, 3)] ^
250f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Tks1[byte(temp, 2)] ^
251f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Tks2[byte(temp, 1)] ^
252f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Tks3[byte(temp, 0)];
253f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        temp = rrk[2];
254f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk[2] =
255f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Tks0[byte(temp, 3)] ^
256f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Tks1[byte(temp, 2)] ^
257f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Tks2[byte(temp, 1)] ^
258f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Tks3[byte(temp, 0)];
259f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        temp = rrk[3];
260f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk[3] =
261f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Tks0[byte(temp, 3)] ^
262f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Tks1[byte(temp, 2)] ^
263f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Tks2[byte(temp, 1)] ^
264f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Tks3[byte(temp, 0)];
265f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      #endif
266f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
267f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
268f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
269f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* copy last */
270f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    rrk -= 4;
271f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    rk  += 4;
272f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    *rk++ = *rrk++;
273f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    *rk++ = *rrk++;
274f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    *rk++ = *rrk++;
275f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    *rk   = *rrk;
276f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif /* ENCRYPT_ONLY */
277f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
278f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    return CRYPT_OK;
279f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
280f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
281f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
282f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  Encrypts a block of text with AES
283f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @param pt The input plaintext (16 bytes)
284f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @param ct The output ciphertext (16 bytes)
285f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @param skey The key as scheduled
286f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @return CRYPT_OK if successful
287f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
288f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_CLEAN_STACK
289f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic int _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
290f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#else
291f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
292f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
293f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
294f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
295f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    int Nr, r;
296f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
297f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LTC_ARGCHK(pt != NULL);
298f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LTC_ARGCHK(ct != NULL);
299f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LTC_ARGCHK(skey != NULL);
300f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
301f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    Nr = skey->rijndael.Nr;
302f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    rk = skey->rijndael.eK;
303f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
304f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /*
305f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     * map byte array block to cipher state
306f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     * and add initial round key:
307f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     */
308f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LOAD32H(s0, pt      ); s0 ^= rk[0];
309f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LOAD32H(s1, pt  +  4); s1 ^= rk[1];
310f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LOAD32H(s2, pt  +  8); s2 ^= rk[2];
311f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LOAD32H(s3, pt  + 12); s3 ^= rk[3];
312f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
313f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_SMALL_CODE
314f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
315f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (r = 0; ; r++) {
316f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk += 4;
317f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        t0 =
318f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te0(byte(s0, 3)) ^
319f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te1(byte(s1, 2)) ^
320f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te2(byte(s2, 1)) ^
321f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te3(byte(s3, 0)) ^
322f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[0];
323f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        t1 =
324f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te0(byte(s1, 3)) ^
325f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te1(byte(s2, 2)) ^
326f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te2(byte(s3, 1)) ^
327f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te3(byte(s0, 0)) ^
328f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[1];
329f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        t2 =
330f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te0(byte(s2, 3)) ^
331f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te1(byte(s3, 2)) ^
332f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te2(byte(s0, 1)) ^
333f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te3(byte(s1, 0)) ^
334f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[2];
335f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        t3 =
336f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te0(byte(s3, 3)) ^
337f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te1(byte(s0, 2)) ^
338f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te2(byte(s1, 1)) ^
339f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te3(byte(s2, 0)) ^
340f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[3];
341f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        if (r == Nr-2) {
342f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project           break;
343f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        }
344f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        s0 = t0; s1 = t1; s2 = t2; s3 = t3;
345f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
346f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    rk += 4;
347f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
348f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#else
349f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
350f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /*
351f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     * Nr - 1 full rounds:
352f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     */
353f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    r = Nr >> 1;
354f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (;;) {
355f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        t0 =
356f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te0(byte(s0, 3)) ^
357f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te1(byte(s1, 2)) ^
358f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te2(byte(s2, 1)) ^
359f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te3(byte(s3, 0)) ^
360f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[4];
361f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        t1 =
362f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te0(byte(s1, 3)) ^
363f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te1(byte(s2, 2)) ^
364f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te2(byte(s3, 1)) ^
365f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te3(byte(s0, 0)) ^
366f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[5];
367f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        t2 =
368f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te0(byte(s2, 3)) ^
369f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te1(byte(s3, 2)) ^
370f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te2(byte(s0, 1)) ^
371f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te3(byte(s1, 0)) ^
372f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[6];
373f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        t3 =
374f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te0(byte(s3, 3)) ^
375f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te1(byte(s0, 2)) ^
376f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te2(byte(s1, 1)) ^
377f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te3(byte(s2, 0)) ^
378f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[7];
379f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
380f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk += 8;
381f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        if (--r == 0) {
382f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            break;
383f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        }
384f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
385f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        s0 =
386f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te0(byte(t0, 3)) ^
387f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te1(byte(t1, 2)) ^
388f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te2(byte(t2, 1)) ^
389f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te3(byte(t3, 0)) ^
390f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[0];
391f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        s1 =
392f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te0(byte(t1, 3)) ^
393f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te1(byte(t2, 2)) ^
394f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te2(byte(t3, 1)) ^
395f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te3(byte(t0, 0)) ^
396f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[1];
397f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        s2 =
398f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te0(byte(t2, 3)) ^
399f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te1(byte(t3, 2)) ^
400f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te2(byte(t0, 1)) ^
401f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te3(byte(t1, 0)) ^
402f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[2];
403f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        s3 =
404f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te0(byte(t3, 3)) ^
405f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te1(byte(t0, 2)) ^
406f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te2(byte(t1, 1)) ^
407f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Te3(byte(t2, 0)) ^
408f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[3];
409f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
410f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
411f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
412f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
413f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /*
414f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     * apply last round and
415f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     * map cipher state to byte array block:
416f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     */
417f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    s0 =
418f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Te4_3[byte(t0, 3)]) ^
419f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Te4_2[byte(t1, 2)]) ^
420f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Te4_1[byte(t2, 1)]) ^
421f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Te4_0[byte(t3, 0)]) ^
422f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk[0];
423f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    STORE32H(s0, ct);
424f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    s1 =
425f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Te4_3[byte(t1, 3)]) ^
426f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Te4_2[byte(t2, 2)]) ^
427f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Te4_1[byte(t3, 1)]) ^
428f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Te4_0[byte(t0, 0)]) ^
429f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk[1];
430f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    STORE32H(s1, ct+4);
431f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    s2 =
432f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Te4_3[byte(t2, 3)]) ^
433f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Te4_2[byte(t3, 2)]) ^
434f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Te4_1[byte(t0, 1)]) ^
435f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Te4_0[byte(t1, 0)]) ^
436f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk[2];
437f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    STORE32H(s2, ct+8);
438f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    s3 =
439f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Te4_3[byte(t3, 3)]) ^
440f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Te4_2[byte(t0, 2)]) ^
441f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Te4_1[byte(t1, 1)]) ^
442f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Te4_0[byte(t2, 0)]) ^
443f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk[3];
444f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    STORE32H(s3, ct+12);
445f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
446f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    return CRYPT_OK;
447f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
448f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
449f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_CLEAN_STACK
450f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
451f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
452f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   int err = _rijndael_ecb_encrypt(pt, ct, skey);
453f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
454f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   return err;
455f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
456f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
457f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
458f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifndef ENCRYPT_ONLY
459f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
460f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
461f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  Decrypts a block of text with AES
462f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @param ct The input ciphertext (16 bytes)
463f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @param pt The output plaintext (16 bytes)
464f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @param skey The key as scheduled
465f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @return CRYPT_OK if successful
466f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
467f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_CLEAN_STACK
468f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic int _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
469f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#else
470f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
471f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
472f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
473f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
474f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    int Nr, r;
475f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
476f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LTC_ARGCHK(pt != NULL);
477f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LTC_ARGCHK(ct != NULL);
478f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LTC_ARGCHK(skey != NULL);
479f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
480f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    Nr = skey->rijndael.Nr;
481f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    rk = skey->rijndael.dK;
482f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
483f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /*
484f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     * map byte array block to cipher state
485f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     * and add initial round key:
486f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     */
487f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LOAD32H(s0, ct      ); s0 ^= rk[0];
488f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LOAD32H(s1, ct  +  4); s1 ^= rk[1];
489f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LOAD32H(s2, ct  +  8); s2 ^= rk[2];
490f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    LOAD32H(s3, ct  + 12); s3 ^= rk[3];
491f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
492f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_SMALL_CODE
493f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (r = 0; ; r++) {
494f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk += 4;
495f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        t0 =
496f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td0(byte(s0, 3)) ^
497f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td1(byte(s3, 2)) ^
498f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td2(byte(s2, 1)) ^
499f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td3(byte(s1, 0)) ^
500f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[0];
501f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        t1 =
502f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td0(byte(s1, 3)) ^
503f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td1(byte(s0, 2)) ^
504f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td2(byte(s3, 1)) ^
505f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td3(byte(s2, 0)) ^
506f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[1];
507f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        t2 =
508f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td0(byte(s2, 3)) ^
509f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td1(byte(s1, 2)) ^
510f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td2(byte(s0, 1)) ^
511f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td3(byte(s3, 0)) ^
512f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[2];
513f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        t3 =
514f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td0(byte(s3, 3)) ^
515f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td1(byte(s2, 2)) ^
516f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td2(byte(s1, 1)) ^
517f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td3(byte(s0, 0)) ^
518f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[3];
519f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        if (r == Nr-2) {
520f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project           break;
521f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        }
522f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        s0 = t0; s1 = t1; s2 = t2; s3 = t3;
523f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
524f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    rk += 4;
525f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
526f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#else
527f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
528f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /*
529f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     * Nr - 1 full rounds:
530f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     */
531f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    r = Nr >> 1;
532f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (;;) {
533f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
534f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        t0 =
535f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td0(byte(s0, 3)) ^
536f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td1(byte(s3, 2)) ^
537f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td2(byte(s2, 1)) ^
538f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td3(byte(s1, 0)) ^
539f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[4];
540f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        t1 =
541f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td0(byte(s1, 3)) ^
542f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td1(byte(s0, 2)) ^
543f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td2(byte(s3, 1)) ^
544f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td3(byte(s2, 0)) ^
545f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[5];
546f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        t2 =
547f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td0(byte(s2, 3)) ^
548f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td1(byte(s1, 2)) ^
549f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td2(byte(s0, 1)) ^
550f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td3(byte(s3, 0)) ^
551f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[6];
552f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        t3 =
553f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td0(byte(s3, 3)) ^
554f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td1(byte(s2, 2)) ^
555f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td2(byte(s1, 1)) ^
556f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td3(byte(s0, 0)) ^
557f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[7];
558f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
559f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk += 8;
560f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        if (--r == 0) {
561f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            break;
562f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        }
563f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
564f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
565f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        s0 =
566f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td0(byte(t0, 3)) ^
567f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td1(byte(t3, 2)) ^
568f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td2(byte(t2, 1)) ^
569f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td3(byte(t1, 0)) ^
570f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[0];
571f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        s1 =
572f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td0(byte(t1, 3)) ^
573f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td1(byte(t0, 2)) ^
574f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td2(byte(t3, 1)) ^
575f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td3(byte(t2, 0)) ^
576f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[1];
577f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        s2 =
578f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td0(byte(t2, 3)) ^
579f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td1(byte(t1, 2)) ^
580f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td2(byte(t0, 1)) ^
581f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td3(byte(t3, 0)) ^
582f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[2];
583f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        s3 =
584f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td0(byte(t3, 3)) ^
585f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td1(byte(t2, 2)) ^
586f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td2(byte(t1, 1)) ^
587f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            Td3(byte(t0, 0)) ^
588f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project            rk[3];
589f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
590f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
591f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
592f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /*
593f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     * apply last round and
594f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     * map cipher state to byte array block:
595f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     */
596f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    s0 =
597f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Td4[byte(t0, 3)] & 0xff000000) ^
598f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Td4[byte(t3, 2)] & 0x00ff0000) ^
599f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Td4[byte(t2, 1)] & 0x0000ff00) ^
600f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Td4[byte(t1, 0)] & 0x000000ff) ^
601f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk[0];
602f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    STORE32H(s0, pt);
603f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    s1 =
604f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Td4[byte(t1, 3)] & 0xff000000) ^
605f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Td4[byte(t0, 2)] & 0x00ff0000) ^
606f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Td4[byte(t3, 1)] & 0x0000ff00) ^
607f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Td4[byte(t2, 0)] & 0x000000ff) ^
608f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk[1];
609f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    STORE32H(s1, pt+4);
610f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    s2 =
611f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Td4[byte(t2, 3)] & 0xff000000) ^
612f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Td4[byte(t1, 2)] & 0x00ff0000) ^
613f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Td4[byte(t0, 1)] & 0x0000ff00) ^
614f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Td4[byte(t3, 0)] & 0x000000ff) ^
615f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk[2];
616f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    STORE32H(s2, pt+8);
617f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    s3 =
618f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Td4[byte(t3, 3)] & 0xff000000) ^
619f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Td4[byte(t2, 2)] & 0x00ff0000) ^
620f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Td4[byte(t1, 1)] & 0x0000ff00) ^
621f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        (Td4[byte(t0, 0)] & 0x000000ff) ^
622f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        rk[3];
623f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    STORE32H(s3, pt+12);
624f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
625f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    return CRYPT_OK;
626f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
627f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
628f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
629f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_CLEAN_STACK
630f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
631f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
632f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   int err = _rijndael_ecb_decrypt(ct, pt, skey);
633f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
634f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   return err;
635f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
636f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
637f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
638f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
639f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  Performs a self-test of the AES block cipher
640f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
641f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
642f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint ECB_TEST(void)
643f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
644f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project #ifndef LTC_TEST
645f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    return CRYPT_NOP;
646f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project #else
647f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int err;
648f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project static const struct {
649f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     int keylen;
650f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     unsigned char key[32], pt[16], ct[16];
651f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } tests[] = {
652f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    { 16,
653f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
654f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
655f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
656f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
657f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
658f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }
659f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }, {
660f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      24,
661f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
662f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
663f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
664f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
665f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
666f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
667f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }
668f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }, {
669f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      32,
670f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
671f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
672f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
673f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
674f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
675f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
676f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
677f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }
678f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
679f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project };
680f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
681f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project symmetric_key key;
682f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned char tmp[2][16];
683f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int i, y;
684f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
685f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
686f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    zeromem(&key, sizeof(key));
687f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
688f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       return err;
689f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
690f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
691f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key);
692f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    rijndael_ecb_decrypt(tmp[0], tmp[1], &key);
693f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) {
694f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#if 0
695f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       printf("\n\nTest %d failed\n", i);
696f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       if (XMEMCMP(tmp[0], tests[i].ct, 16)) {
697f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          printf("CT: ");
698f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          for (i = 0; i < 16; i++) {
699f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project             printf("%02x ", tmp[0][i]);
700f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          }
701f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          printf("\n");
702f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       } else {
703f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          printf("PT: ");
704f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          for (i = 0; i < 16; i++) {
705f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project             printf("%02x ", tmp[1][i]);
706f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          }
707f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          printf("\n");
708f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       }
709f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
710f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        return CRYPT_FAIL_TESTVECTOR;
711f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
712f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
713f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
714f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      for (y = 0; y < 16; y++) tmp[0][y] = 0;
715f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      for (y = 0; y < 1000; y++) rijndael_ecb_encrypt(tmp[0], tmp[0], &key);
716f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      for (y = 0; y < 1000; y++) rijndael_ecb_decrypt(tmp[0], tmp[0], &key);
717f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
718f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project }
719f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_OK;
720f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project #endif
721f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
722f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
723f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif /* ENCRYPT_ONLY */
724f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
725f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
726f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/** Terminate the context
727f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @param skey    The scheduled key
728f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
729f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid ECB_DONE(symmetric_key *skey)
730f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
731f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
732f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
733f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
734f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
735f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  Gets suitable key size
736f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @param keysize [in/out] The length of the recommended key (in bytes).  This function will store the suitable size back in this variable.
737f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @return CRYPT_OK if the input key size is acceptable.
738f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
739f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint ECB_KS(int *keysize)
740f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
741f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LTC_ARGCHK(keysize != NULL);
742f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
743f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   if (*keysize < 16)
744f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      return CRYPT_INVALID_KEYSIZE;
745f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   if (*keysize < 24) {
746f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      *keysize = 16;
747f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      return CRYPT_OK;
748f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   } else if (*keysize < 32) {
749f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      *keysize = 24;
750f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      return CRYPT_OK;
751f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   } else {
752f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      *keysize = 32;
753f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      return CRYPT_OK;
754f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   }
755f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
756f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
757f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
758f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
759f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
760f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/aes/aes.c,v $ */
761f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Revision: 1.14 $ */
762f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Date: 2006/11/08 23:01:06 $ */
763