chiark / gitweb /
configure.ac: Replace with a new version.
[catacomb] / rijndael.c
1 /* -*-c-*-
2  *
3  * $Id: rijndael.c,v 1.5 2004/04/08 01:36:15 mdw Exp $
4  *
5  * The Rijndael block cipher
6  *
7  * (c) 2000 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------*
11  *
12  * This file is part of Catacomb.
13  *
14  * Catacomb is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU Library General Public License as
16  * published by the Free Software Foundation; either version 2 of the
17  * License, or (at your option) any later version.
18  *
19  * Catacomb is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU Library General Public License for more details.
23  *
24  * You should have received a copy of the GNU Library General Public
25  * License along with Catacomb; if not, write to the Free
26  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27  * MA 02111-1307, USA.
28  */
29
30 /*----- Header files ------------------------------------------------------*/
31
32 #include <assert.h>
33 #include <stdio.h>
34
35 #include <mLib/bits.h>
36
37 #include "blkc.h"
38 #include "gcipher.h"
39 #include "rijndael.h"
40 #include "rijndael-base.h"
41
42 /*----- Main code ---------------------------------------------------------*/
43
44 /* --- @rijndael_init@ --- *
45  *
46  * Arguments:   @rijndael_ctx *k@ = pointer to context to initialize
47  *              @const void *buf@ = pointer to buffer of key material
48  *              @size_t sz@ = size of the key material
49  *
50  * Returns:     ---
51  *
52  * Use:         Initializes a Rijndael context with a particular key.  This
53  *              implementation of Rijndael doesn't impose any particular
54  *              limits on the key size except that it must be multiple of 4
55  *              bytes long.  256 bits seems sensible, though.
56  */
57
58 void rijndael_init(rijndael_ctx *k, const void *buf, size_t sz)
59 {
60   rijndael_setup(k, RIJNDAEL_BLKSZ / 4, buf, sz);
61 }
62
63 /* --- @rijndael_eblk@, @rijndael_dblk@ --- *
64  *
65  * Arguments:   @const rijndael_ctx *k@ = pointer to Rijndael context
66  *              @const uint32 s[4]@ = pointer to source block
67  *              @uint32 d[4]@ = pointer to destination block
68  *
69  * Returns:     ---
70  *
71  * Use:         Low-level block encryption and decryption.
72  */
73
74 #define DO(what, t, aa, bb, cc, dd, a, b, c, d, w) do {                 \
75   aa = what(t, a, b, c, d) ^ *w++;                                      \
76   bb = what(t, b, c, d, a) ^ *w++;                                      \
77   cc = what(t, c, d, a, b) ^ *w++;                                      \
78   dd = what(t, d, a, b, c) ^ *w++;                                      \
79 } while (0)
80
81 #define UNDO(what, t, aa, bb, cc, dd, a, b, c, d, w) do {               \
82   aa = what(t, a, d, c, b) ^ *w++;                                      \
83   bb = what(t, b, a, d, c) ^ *w++;                                      \
84   cc = what(t, c, b, a, d) ^ *w++;                                      \
85   dd = what(t, d, c, b, a) ^ *w++;                                      \
86 } while (0)
87
88 void rijndael_eblk(const rijndael_ctx *k, const uint32 *s, uint32 *dst)
89 {
90   uint32 a = s[0], b = s[1], c = s[2], d = s[3];
91   uint32 aa, bb, cc, dd;
92   const uint32 *w = k->w;
93
94   a ^= *w++; b ^= *w++; c ^= *w++; d ^= *w++;
95   aa = a; bb = b; cc = c; dd = d;
96
97   switch (k->nr) {
98     case 14:
99       DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
100     case 13:
101       DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
102     case 12:
103       DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
104     case 11:
105       DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
106     case 10:
107     default:
108       DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
109       DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
110       DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
111       DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
112       DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
113       DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
114       DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
115       DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
116       DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
117   }
118   DO(SUB, S, a, b, c, d, aa, bb, cc, dd, w);
119
120   dst[0] = a; dst[1] = b; dst[2] = c; dst[3] = d;
121 }
122
123 void rijndael_dblk(const rijndael_ctx *k, const uint32 *s, uint32 *dst)
124 {
125   uint32 a = s[0], b = s[1], c = s[2], d = s[3];
126   uint32 aa, bb, cc, dd;
127   const uint32 *w = k->wi;
128
129   a ^= *w++; b ^= *w++; c ^= *w++; d ^= *w++;
130   aa = a; bb = b; cc = c; dd = d;
131
132   switch (k->nr) {
133     case 14:
134       UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
135     case 13:
136       UNDO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
137     case 12:
138       UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
139     case 11:
140       UNDO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
141     case 10:
142     default:
143       UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
144       UNDO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
145       UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
146       UNDO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
147       UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
148       UNDO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
149       UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
150       UNDO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
151       UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
152   }
153   UNDO(SUB, SI, a, b, c, d, aa, bb, cc, dd, w);
154
155   dst[0] = a; dst[1] = b; dst[2] = c; dst[3] = d;
156 }
157
158 BLKC_TEST(RIJNDAEL, rijndael)
159
160 /*----- That's all, folks -------------------------------------------------*/