better standard compliance
[rofl0r-kripto.git] / lib / block / noekeon.c
blob13add59ee33bbaf2cd60885c6113d57af160527a
1 /*
2 * Copyright (C) 2011 Gregor Pintar <grpintar@gmail.com>
4 * Permission is granted to deal in this work without any restriction,
5 * including unlimited rights to use, publicly perform, publish,
6 * reproduce, relicence, modify, merge, and/or distribute in any form,
7 * for any purpose, with or without fee, and by any means.
9 * This work is provided "AS IS" and WITHOUT WARRANTY of any kind,
10 * to the utmost extent permitted by applicable law. In no event
11 * shall a licensor, author or contributor be held liable for any
12 * issues arising in any way out of dealing in the work.
15 #include <stdint.h>
16 #include <stdlib.h>
17 #include <limits.h>
19 #include <kripto/cast.h>
20 #include <kripto/loadstore.h>
21 #include <kripto/rotate.h>
22 #include <kripto/memwipe.h>
23 #include <kripto/block.h>
24 #include <kripto/desc/block.h>
25 #include <kripto/object/block.h>
27 #include <kripto/block/noekeon.h>
29 struct kripto_block
31 struct kripto_block_object obj;
32 unsigned int rounds;
33 uint32_t k[4];
34 uint32_t dk[4];
37 static const uint8_t rc[34] =
39 0x80, 0x1B, 0x36, 0x6C, 0xD8, 0xAB, 0x4D, 0x9A,
40 0x2F, 0x5E, 0xBC, 0x63, 0xC6, 0x97, 0x35, 0x6A,
41 0xD4, 0xB3, 0x7D, 0xFA, 0xEF, 0xC5, 0x91, 0x39,
42 0x72, 0xE4, 0xD3, 0xBD, 0x61, 0xC2, 0x9F, 0x25,
43 0x4A, 0x94
46 #define THETA(X0, X1, X2, X3, K0, K1, K2, K3) \
47 { \
48 T = X0 ^ X2; \
49 T ^= ROL32(T, 8) ^ ROR32(T, 8); \
50 X1 ^= T; \
51 X3 ^= T; \
52 X0 ^= K0; X1 ^= K1; X2 ^= K2; X3 ^= K3; \
53 T = X1 ^ X3; \
54 T ^= ROL32(T, 8) ^ ROR32(T, 8); \
55 X0 ^= T; \
56 X2 ^= T; \
59 #define GAMMA(X0, X1, X2, X3) \
60 { \
61 X1 ^= ~(X3 | X2); \
62 X0 ^= X2 & X1; \
63 T = X3; X3 = X0; X0 = T; \
64 X2 ^= X0 ^ X1 ^ X3; \
65 X1 ^= ~(X3 | X2); \
66 X0 ^= X2 & X1; \
69 #define PI1(X1, X2, X3) \
70 { \
71 X1 = ROL32(X1, 1); \
72 X2 = ROL32(X2, 5); \
73 X3 = ROL32(X3, 2); \
76 #define PI2(X1, X2, X3) \
77 { \
78 X1 = ROR32(X1, 1); \
79 X2 = ROR32(X2, 5); \
80 X3 = ROR32(X3, 2); \
83 static void noekeon_encrypt
85 const kripto_block *s,
86 const void *pt,
87 void *ct
90 uint32_t x0;
91 uint32_t x1;
92 uint32_t x2;
93 uint32_t x3;
94 uint32_t T;
95 unsigned int r;
97 x0 = LOAD32B(CU8(pt));
98 x1 = LOAD32B(CU8(pt) + 4);
99 x2 = LOAD32B(CU8(pt) + 8);
100 x3 = LOAD32B(CU8(pt) + 12);
102 for(r = 0; r < s->rounds; r++)
104 x0 ^= rc[r];
105 THETA(x0, x1, x2, x3, s->k[0], s->k[1], s->k[2], s->k[3]);
106 PI1(x1, x2, x3);
107 GAMMA(x0, x1, x2, x3);
108 PI2(x1, x2, x3);
110 x0 ^= rc[r];
111 THETA(x0, x1, x2, x3, s->k[0], s->k[1], s->k[2], s->k[3]);
113 STORE32B(x0, U8(ct));
114 STORE32B(x1, U8(ct) + 4);
115 STORE32B(x2, U8(ct) + 8);
116 STORE32B(x3, U8(ct) + 12);
119 static void noekeon_decrypt
121 const kripto_block *s,
122 const void *ct,
123 void *pt
126 uint32_t x0;
127 uint32_t x1;
128 uint32_t x2;
129 uint32_t x3;
130 uint32_t T;
131 unsigned int r;
133 x0 = LOAD32B(CU8(ct));
134 x1 = LOAD32B(CU8(ct) + 4);
135 x2 = LOAD32B(CU8(ct) + 8);
136 x3 = LOAD32B(CU8(ct) + 12);
138 for(r = s->rounds; r; r--)
140 THETA(x0, x1, x2, x3, s->dk[0], s->dk[1], s->dk[2], s->dk[3]);
141 x0 ^= rc[r];
142 PI1(x1, x2, x3);
143 GAMMA(x0, x1, x2, x3);
144 PI2(x1, x2, x3);
146 THETA(x0, x1, x2, x3, s->dk[0], s->dk[1], s->dk[2], s->dk[3]);
147 x0 ^= rc[r];
149 STORE32B(x0, U8(pt));
150 STORE32B(x1, U8(pt) + 4);
151 STORE32B(x2, U8(pt) + 8);
152 STORE32B(x3, U8(pt) + 12);
155 static void noekeon_setup
157 kripto_block *s,
158 const uint8_t *key,
159 unsigned int key_len
162 unsigned int i;
163 uint32_t T;
165 if(!s->rounds) s->rounds = 16;
167 /* direct mode */
168 s->k[0] = s->k[1] = s->k[2] = s->k[3] = 0;
170 for(i = 0; i < key_len; i++)
171 s->k[i >> 2] |= key[i] << (24 - ((i & 3) << 3));
173 /* decryption key */
174 s->dk[0] = s->k[0];
175 s->dk[1] = s->k[1];
176 s->dk[2] = s->k[2];
177 s->dk[3] = s->k[3];
178 THETA(s->dk[0], s->dk[1], s->dk[2], s->dk[3], 0, 0, 0, 0);
181 static kripto_block *noekeon_create
183 unsigned int r,
184 const void *key,
185 unsigned int key_len
188 kripto_block *s;
190 s = malloc(sizeof(kripto_block));
191 if(!s) return 0;
193 s->obj.desc = kripto_block_noekeon;
194 s->rounds = r;
196 noekeon_setup(s, key, key_len);
198 return s;
201 static kripto_block *noekeon_recreate
203 kripto_block *s,
204 unsigned int r,
205 const void *key,
206 unsigned int key_len
209 s->rounds = r;
210 noekeon_setup(s, key, key_len);
212 return s;
215 static void noekeon_destroy(kripto_block *s)
217 kripto_memwipe(s, sizeof(kripto_block));
218 free(s);
221 static const kripto_block_desc noekeon =
223 &noekeon_create,
224 &noekeon_recreate,
226 &noekeon_encrypt,
227 &noekeon_decrypt,
228 &noekeon_destroy,
229 16, /* block size */
230 16 /* max key */
233 const kripto_block_desc *const kripto_block_noekeon = &noekeon;