]> git.cryptolib.org Git - avr-crypto-lib.git/blob - norx/norx32.c
c43d792b333bb5f43ef2d7a9f4f22549a9ffad65
[avr-crypto-lib.git] / norx / norx32.c
1 /* norx32.c */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2006-2014 Daniel Otte (daniel.otte@rub.de)
5
6     This program is free software: you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation, either version 3 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20
21 #include <inttypes.h>
22 #include <avr/pgmspace.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <memxor.h>
26 #include <norx32.h>
27
28 #include <stdio.h>
29 #include "cli.h"
30
31 #define R0  8
32 #define R1 11
33 #define R2 16
34 #define R3 31
35
36 #define U0 0x243f6a88l
37 #define U1 0x85a308d3l
38 #define U2 0x13198a2el
39 #define U3 0x03707344l
40 #define U4 0x254f537al
41 #define U5 0x38531d48l
42 #define U6 0x839c6E83l
43 #define U7 0xf97a3ae5l
44 #define U8 0x8c91d88cl
45 #define U9 0x11eafb59l
46
47 #if 0
48
49
50 #define U0 0x886a3f24l
51 #define U1 0xd308a385l
52 #define U2 0x2e8a1913l
53 #define U3 0x44737003l
54 #define U4 0x7a534f25l
55 #define U5 0x481d5338l
56 #define U6 0x836e9c83l
57 #define U7 0xe53a7af9l
58 #define U8 0xxxxxxxxxx
59 #define U9 0x59fbea11l
60
61 #endif
62
63 #define WORD_SIZE 32
64
65 #define RATE_WORDS 10
66 #define CAPACITY_WORDS 6
67
68 #define RATE_BITS (RATE_WORDS * WORD_SIZE)
69 #define CAPACITY_BITS (CAPACITY_WORDS * WORD_SIZE)
70
71 #define RATE_BYTES (RATE_BITS / 8)
72 #define CAPACITY_BYTES (CAPACITY_BITS / 8)
73
74 #define TAG_HEADER    0x01
75 #define TAG_PAYLOAD   0x02
76 #define TAG_TRAILER   0x04
77 #define TAG_TAG       0x08
78 #define TAG_BRANCHING 0x10
79 #define TAG_MERGING   0x20
80
81
82 #define SET_TAG(ctx,t) do { ((uint8_t*)&(ctx)->s[15])[0] ^= (t); } while (0)
83
84
85 void norx32_dump(const norx32_ctx_t *ctx)
86 {
87     printf("\n--- DUMP STATE ---");
88     printf("\n\t%08lX %08lX %08lX %08lX", ctx->s[ 0], ctx->s[ 1], ctx->s[ 2], ctx->s[ 3]);
89     printf("\n\t%08lX %08lX %08lX %08lX", ctx->s[ 4], ctx->s[ 5], ctx->s[ 6], ctx->s[ 7]);
90     printf("\n\t%08lX %08lX %08lX %08lX", ctx->s[ 8], ctx->s[ 9], ctx->s[10], ctx->s[11]);
91     printf("\n\t%08lX %08lX %08lX %08lX", ctx->s[12], ctx->s[13], ctx->s[14], ctx->s[15]);
92     printf("\n--- END ---\n");
93 }
94
95 static void phi(uint32_t *(a[2]))
96 {
97     uint32_t x;
98     x = (*(a[0]) & *(a[1])) << 1;
99     *(a[0]) ^= *(a[1]) ^ x;
100 }
101
102 static void xrot(uint32_t *a, const uint32_t *b, uint8_t r)
103 {
104     uint32_t x;
105     x = *a ^ *b;
106     *a = (x << (32 - r)) | (x >> r);
107 }
108
109 #define A (a[0])
110 #define B (a[1])
111 #define C (a[2])
112 #define D (a[3])
113
114 void g32(uint32_t *(a[4]))
115 {
116     phi(&A);
117     xrot(D, A, R0);
118     phi(&C);
119     xrot(B, C, R1);
120     phi(&A);
121     xrot(D, A, R2);
122     phi(&C);
123     xrot(B, C, R3);
124 }
125
126 static uint8_t g2_table[4][4] = {
127         {0, 5, 10, 15},
128         {1, 6, 11, 12},
129         {2, 7,  8, 13},
130         {3, 4,  9, 14},
131 };
132
133 void f32(norx32_ctx_t *ctx)
134 {
135     uint32_t *(a[4]);
136     uint8_t i, rounds;
137     rounds = ctx->r;
138     do {
139         a[0] = &ctx->s[0];
140         a[1] = &ctx->s[4];
141         a[2] = &ctx->s[8];
142         a[3] = &ctx->s[12];
143         g32(a);
144         i = 3;
145         do {
146             a[0]++;
147             a[1]++;
148             a[2]++;
149             a[3]++;
150             g32(a);
151         } while (--i);
152         i = 4;
153         do {
154             --i;
155             a[0] = &ctx->s[g2_table[i][0]];
156             a[1] = &ctx->s[g2_table[i][1]];
157             a[2] = &ctx->s[g2_table[i][2]];
158             a[3] = &ctx->s[g2_table[i][3]];
159             g32(a);
160         } while (i);
161     } while (--rounds);
162 }
163
164 static const uint32_t init_state[] PROGMEM = {
165         U0,  0,  0, U1,
166          0,  0,  0,  0,
167         U2, U3, U4, U5,
168         U6, U7, U8 ^ (1l << 15), U9
169 };
170
171 static void norx32_process_block(
172     norx32_ctx_t *ctx,
173     const void *block,
174     uint8_t tag )
175 {
176     SET_TAG(ctx, tag);
177     f32(ctx);
178     memxor(ctx->s, block, RATE_BYTES);
179 }
180
181 static void norx32_process_last_block(
182     norx32_ctx_t *ctx,
183     void *out_block,
184     const void *block,
185     uint16_t length_b,
186     uint8_t tag )
187 {
188     while (length_b >= RATE_BITS) {
189         norx32_process_block(ctx, block, tag);
190         block = (uint8_t*)block + RATE_BYTES;
191         length_b -= RATE_BITS;
192         if (out_block) {
193             memcpy(out_block, ctx->s, RATE_BYTES);
194             out_block = (uint8_t*)out_block + RATE_BYTES;
195         }
196     }
197     SET_TAG(ctx, tag);
198     f32(ctx);
199     memxor(ctx->s, block, (length_b + 7) / 8);
200     if (out_block) {
201         memcpy(out_block, ctx->s, (length_b + 7) / 8);
202         out_block = (uint8_t*)out_block + (length_b + 7) / 8;
203         if ((length_b & 7) != 0) {
204             ((uint8_t*)out_block)[length_b / 8 + 1] &= 0xff << (7 - (length_b & 7));
205         }
206     }
207     ((uint8_t*)ctx->s)[length_b / 8] ^= 1 << (length_b & 7);
208     if (length_b == RATE_BITS - 1) {
209         SET_TAG(ctx, tag);
210         f32(ctx);
211     }
212     ((uint8_t*)ctx->s)[RATE_BYTES - 1] ^= 0x80;
213
214 }
215
216 /******************************************************************************/
217
218 int8_t norx32_init (
219     norx32_ctx_t *ctx,
220     const void* nonce,
221     const void* key,
222     uint16_t tag_size_b,
223     uint8_t rounds,
224     uint8_t parallel )
225 {
226     uint32_t v;
227     if (ctx == NULL || nonce == NULL || key == NULL) {
228         return -1;
229     }
230     if (tag_size_b > 320) {
231         return -1;
232     }
233     if (rounds < 1 || rounds > 63) {
234         return -1;
235     }
236     if (parallel != 1) {
237         return -2;
238     }
239     memcpy_P(ctx->s, init_state, sizeof(ctx->s));
240     memcpy(&ctx->s[1], nonce, 2 * sizeof(ctx->s[1]));
241     memcpy(&ctx->s[4], key, 4 * sizeof(ctx->s[4]));
242     v  = ((uint32_t)rounds)   << 26;
243     v ^= ((uint32_t)parallel) << 18;
244     v ^= tag_size_b;
245     ctx->s[14] ^= v;
246     ctx->d = parallel;
247     ctx->a = tag_size_b;
248     ctx->r = rounds;
249     f32(ctx);
250     return 0;
251 }
252
253 void norx32_finalize(norx32_ctx_t *ctx, void *tag)
254 {
255     SET_TAG(ctx, TAG_TAG);
256     f32(ctx);
257     f32(ctx);
258     if (tag) {
259         memcpy(tag, ctx->s, (ctx->a + 7) / 8);
260     }
261 }
262
263 void norx32_add_header_block(norx32_ctx_t *ctx, const void *block)
264 {
265     norx32_process_block(ctx, block, TAG_HEADER);
266 }
267
268 void norx32_add_header_last_block(
269     norx32_ctx_t *ctx,
270     const void *block,
271     uint16_t length_b )
272 {
273     norx32_process_last_block(ctx, NULL, block, length_b, TAG_HEADER);
274 }
275
276 void norx32_encrypt_block(norx32_ctx_t *ctx, void *dest, const void *src)
277 {
278     norx32_process_block(ctx, src, TAG_PAYLOAD);
279     if (dest) {
280         memcpy(dest, ctx->s, RATE_BYTES);
281     }
282 }
283
284 void norx32_encrypt_last_block(
285     norx32_ctx_t *ctx,
286     void *dest,
287     const void *src,
288     uint16_t length_b )
289 {
290     norx32_process_last_block(ctx, dest, src, length_b, TAG_PAYLOAD);
291 }
292
293 void norx32_add_trailer_block(norx32_ctx_t *ctx, const void *block)
294 {
295     norx32_process_block(ctx, block, TAG_TRAILER);
296 }
297
298 void norx32_add_trailer_last_block(
299     norx32_ctx_t *ctx,
300     const void *block,
301     uint16_t length_b )
302 {
303     norx32_process_last_block(ctx, NULL, block, length_b, TAG_TRAILER);
304 }
305
306 /******************************************************************************/
307
308 void norx32_default_simple (
309     void *data_dest,
310     void *tag_dest,
311     const void *key,
312     const void *nonce,
313     const void *header,
314     size_t header_length_B,
315     const void *data_src,
316     size_t data_length_B,
317     const void *trailer,
318     size_t trailer_length_B )
319 {
320     norx32_ctx_t ctx;
321     norx32_init(&ctx, nonce, key, 4 * WORD_SIZE, 4, 1);
322     if (header && header_length_B) {
323         norx32_add_header_last_block(&ctx, header, header_length_B * 8);
324     }
325     if (data_src && data_length_B) {
326         norx32_encrypt_last_block(&ctx, data_dest, data_src, data_length_B * 8);
327     }
328     if (trailer && trailer_length_B) {
329         norx32_add_trailer_last_block(&ctx, trailer, trailer_length_B * 8);
330     }
331     norx32_finalize(&ctx, tag_dest);
332 }