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   @file noekeon.c
13f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   Implementation of the Noekeon block cipher by Tom St Denis
14f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
15f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "tomcrypt.h"
16f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
17f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef NOEKEON
18f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
19f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectconst struct ltc_cipher_descriptor noekeon_desc =
20f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
21f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    "noekeon",
22f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    16,
23f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    16, 16, 16, 16,
24f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    &noekeon_setup,
25f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    &noekeon_ecb_encrypt,
26f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    &noekeon_ecb_decrypt,
27f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    &noekeon_test,
28f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    &noekeon_done,
29f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    &noekeon_keysize,
30f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
31f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project};
32f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
33f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic const ulong32 RC[] = {
34f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   0x00000080UL, 0x0000001bUL, 0x00000036UL, 0x0000006cUL,
35f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   0x000000d8UL, 0x000000abUL, 0x0000004dUL, 0x0000009aUL,
36f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   0x0000002fUL, 0x0000005eUL, 0x000000bcUL, 0x00000063UL,
37f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   0x000000c6UL, 0x00000097UL, 0x00000035UL, 0x0000006aUL,
38f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   0x000000d4UL
39f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project};
40f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
41f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define kTHETA(a, b, c, d)                                 \
42f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    temp = a^c; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \
43f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    b ^= temp; d ^= temp;                                  \
44f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    temp = b^d; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \
45f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    a ^= temp; c ^= temp;
46f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
47f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define THETA(k, a, b, c, d)                               \
48f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    temp = a^c; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \
49f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    b ^= temp ^ k[1]; d ^= temp ^ k[3];                    \
50f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    temp = b^d; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \
51f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    a ^= temp ^ k[0]; c ^= temp ^ k[2];
52f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
53f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define GAMMA(a, b, c, d)     \
54f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    b ^= ~(d|c);              \
55f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    a ^= c&b;                 \
56f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    temp = d; d = a; a = temp;\
57f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    c ^= a ^ b ^ d;           \
58f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    b ^= ~(d|c);              \
59f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    a ^= c&b;
60f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
61f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define PI1(a, b, c, d) \
62f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    a = ROLc(a, 1); c = ROLc(c, 5); d = ROLc(d, 2);
63f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
64f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define PI2(a, b, c, d) \
65f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    a = RORc(a, 1); c = RORc(c, 5); d = RORc(d, 2);
66f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
67f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /**
68f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    Initialize the Noekeon block cipher
69f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    @param key The symmetric key you wish to pass
70f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    @param keylen The key length in bytes
71f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    @param num_rounds The number of rounds desired (0 for default)
72f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    @param skey The key in as scheduled by this function.
73f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    @return CRYPT_OK if successful
74f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */
75f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
76f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
77f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   ulong32 temp;
78f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
79f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LTC_ARGCHK(key != NULL);
80f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LTC_ARGCHK(skey != NULL);
81f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
82f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   if (keylen != 16) {
83f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      return CRYPT_INVALID_KEYSIZE;
84f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   }
85f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
86f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   if (num_rounds != 16 && num_rounds != 0) {
87f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      return CRYPT_INVALID_ROUNDS;
88f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   }
89f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
90f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LOAD32H(skey->noekeon.K[0],&key[0]);
91f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LOAD32H(skey->noekeon.K[1],&key[4]);
92f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LOAD32H(skey->noekeon.K[2],&key[8]);
93f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LOAD32H(skey->noekeon.K[3],&key[12]);
94f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
95f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LOAD32H(skey->noekeon.dK[0],&key[0]);
96f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LOAD32H(skey->noekeon.dK[1],&key[4]);
97f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LOAD32H(skey->noekeon.dK[2],&key[8]);
98f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LOAD32H(skey->noekeon.dK[3],&key[12]);
99f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
100f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   kTHETA(skey->noekeon.dK[0], skey->noekeon.dK[1], skey->noekeon.dK[2], skey->noekeon.dK[3]);
101f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
102f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   return CRYPT_OK;
103f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
104f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
105f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
106f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  Encrypts a block of text with Noekeon
107f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @param pt The input plaintext (16 bytes)
108f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @param ct The output ciphertext (16 bytes)
109f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @param skey The key as scheduled
110f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @return CRYPT_OK if successful
111f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
112f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_CLEAN_STACK
113f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic int _noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
114f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#else
115f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
116f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
117f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
118f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   ulong32 a,b,c,d,temp;
119f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   int r;
120f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
121f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LTC_ARGCHK(skey != NULL);
122f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LTC_ARGCHK(pt   != NULL);
123f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LTC_ARGCHK(ct   != NULL);
124f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
125f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LOAD32H(a,&pt[0]); LOAD32H(b,&pt[4]);
126f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LOAD32H(c,&pt[8]); LOAD32H(d,&pt[12]);
127f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
128f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define ROUND(i) \
129f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       a ^= RC[i]; \
130f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       THETA(skey->noekeon.K, a,b,c,d); \
131f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       PI1(a,b,c,d); \
132f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       GAMMA(a,b,c,d); \
133f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       PI2(a,b,c,d);
134f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
135f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   for (r = 0; r < 16; ++r) {
136f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       ROUND(r);
137f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   }
138f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
139f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#undef ROUND
140f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
141f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   a ^= RC[16];
142f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   THETA(skey->noekeon.K, a, b, c, d);
143f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
144f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   STORE32H(a,&ct[0]); STORE32H(b,&ct[4]);
145f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   STORE32H(c,&ct[8]); STORE32H(d,&ct[12]);
146f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
147f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   return CRYPT_OK;
148f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
149f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
150f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_CLEAN_STACK
151f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
152f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
153f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   int err = _noekeon_ecb_encrypt(pt, ct, skey);
154f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   burn_stack(sizeof(ulong32) * 5 + sizeof(int));
155f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   return CRYPT_OK;
156f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
157f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
158f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
159f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
160f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  Decrypts a block of text with Noekeon
161f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @param ct The input ciphertext (16 bytes)
162f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @param pt The output plaintext (16 bytes)
163f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @param skey The key as scheduled
164f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @return CRYPT_OK if successful
165f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
166f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_CLEAN_STACK
167f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic int _noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
168f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#else
169f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
170f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
171f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
172f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   ulong32 a,b,c,d, temp;
173f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   int r;
174f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
175f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LTC_ARGCHK(skey != NULL);
176f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LTC_ARGCHK(pt   != NULL);
177f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LTC_ARGCHK(ct   != NULL);
178f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
179f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LOAD32H(a,&ct[0]); LOAD32H(b,&ct[4]);
180f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LOAD32H(c,&ct[8]); LOAD32H(d,&ct[12]);
181f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
182f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
183f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define ROUND(i) \
184f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       THETA(skey->noekeon.dK, a,b,c,d); \
185f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       a ^= RC[i]; \
186f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       PI1(a,b,c,d); \
187f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       GAMMA(a,b,c,d); \
188f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       PI2(a,b,c,d);
189f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
190f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   for (r = 16; r > 0; --r) {
191f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       ROUND(r);
192f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   }
193f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
194f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#undef ROUND
195f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
196f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   THETA(skey->noekeon.dK, a,b,c,d);
197f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   a ^= RC[0];
198f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   STORE32H(a,&pt[0]); STORE32H(b, &pt[4]);
199f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   STORE32H(c,&pt[8]); STORE32H(d, &pt[12]);
200f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   return CRYPT_OK;
201f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
202f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
203f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_CLEAN_STACK
204f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
205f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
206f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   int err = _noekeon_ecb_decrypt(ct, pt, skey);
207f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   burn_stack(sizeof(ulong32) * 5 + sizeof(int));
208f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   return err;
209f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
210f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
211f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
212f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
213f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  Performs a self-test of the Noekeon block cipher
214f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
215f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
216f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint noekeon_test(void)
217f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
218f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project #ifndef LTC_TEST
219f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    return CRYPT_NOP;
220f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project #else
221f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project static const struct {
222f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     int keylen;
223f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project     unsigned char key[16], pt[16], ct[16];
224f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } tests[] = {
225f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   {
226f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      16,
227f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
228f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
229f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      { 0x18, 0xa6, 0xec, 0xe5, 0x28, 0xaa, 0x79, 0x73,
230f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        0x28, 0xb2, 0xc0, 0x91, 0xa0, 0x2f, 0x54, 0xc5}
231f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   }
232f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project };
233f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project symmetric_key key;
234f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned char tmp[2][16];
235f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int err, i, y;
236f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
237f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
238f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    zeromem(&key, sizeof(key));
239f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    if ((err = noekeon_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
240f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       return err;
241f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
242f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
243f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    noekeon_ecb_encrypt(tests[i].pt, tmp[0], &key);
244f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    noekeon_ecb_decrypt(tmp[0], tmp[1], &key);
245f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) {
246f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#if 0
247f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       printf("\n\nTest %d failed\n", i);
248f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       if (XMEMCMP(tmp[0], tests[i].ct, 16)) {
249f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          printf("CT: ");
250f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          for (i = 0; i < 16; i++) {
251f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project             printf("%02x ", tmp[0][i]);
252f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          }
253f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          printf("\n");
254f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       } else {
255f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          printf("PT: ");
256f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          for (i = 0; i < 16; i++) {
257f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project             printf("%02x ", tmp[1][i]);
258f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          }
259f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project          printf("\n");
260f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       }
261f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
262f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        return CRYPT_FAIL_TESTVECTOR;
263f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
264f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
265f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
266f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      for (y = 0; y < 16; y++) tmp[0][y] = 0;
267f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      for (y = 0; y < 1000; y++) noekeon_ecb_encrypt(tmp[0], tmp[0], &key);
268f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      for (y = 0; y < 1000; y++) noekeon_ecb_decrypt(tmp[0], tmp[0], &key);
269f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
270f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project }
271f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_OK;
272f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project #endif
273f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
274f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
275f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/** Terminate the context
276f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   @param skey    The scheduled key
277f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
278f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid noekeon_done(symmetric_key *skey)
279f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
280f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
281f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
282f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/**
283f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  Gets suitable key size
284f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The 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.
285f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  @return CRYPT_OK if the input key size is acceptable.
286f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/
287f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint noekeon_keysize(int *keysize)
288f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
289f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   LTC_ARGCHK(keysize != NULL);
290f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   if (*keysize < 16) {
291f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      return CRYPT_INVALID_KEYSIZE;
292f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   } else {
293f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      *keysize = 16;
294f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      return CRYPT_OK;
295f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project   }
296f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
297f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
298f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
299f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
300f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
301f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/noekeon.c,v $ */
302f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Revision: 1.12 $ */
303f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Date: 2006/11/08 23:01:06 $ */
304