chiark / gitweb /
73b22bb6aa0e030bba812e30e50b86732f69bb8c
[catacomb] / symm / square.c
1 /* -*-c-*-
2  *
3  * The Square block cipher
4  *
5  * (c) 2000 Straylight/Edgeware
6  */
7
8 /*----- Licensing notice --------------------------------------------------*
9  *
10  * This file is part of Catacomb.
11  *
12  * Catacomb is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU Library General Public License as
14  * published by the Free Software Foundation; either version 2 of the
15  * License, or (at your option) any later version.
16  *
17  * Catacomb is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU Library General Public License for more details.
21  *
22  * You should have received a copy of the GNU Library General Public
23  * License along with Catacomb; if not, write to the Free
24  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25  * MA 02111-1307, USA.
26  */
27
28 /*----- Header files ------------------------------------------------------*/
29
30 #include <assert.h>
31 #include <stdio.h>
32
33 #include <mLib/bits.h>
34
35 #include "blkc.h"
36 #include "gcipher.h"
37 #include "paranoia.h"
38 #include "square.h"
39
40 /*----- Global variables --------------------------------------------------*/
41
42 const octet square_keysz[] = { KSZ_RANGE, SQUARE_KEYSZ, 4, 16, 4 };
43
44 /*----- Constant tables ---------------------------------------------------*/
45
46 extern const octet square_s[256], square_si[256];
47 extern const uint32 square_t[4][256], square_ti[4][256];
48 extern const uint32 square_u[4][256];
49 extern const octet square_rcon[32];
50
51 #define S square_s
52 #define SI square_si
53 #define T square_t
54 #define TI square_ti
55 #define U square_u
56 #define RCON square_rcon
57
58 /*----- Main code ---------------------------------------------------------*/
59
60 /* --- @square_init@ --- *
61  *
62  * Arguments:   @square_ctx *k@ = pointer to context to initialize
63  *              @const void *buf@ = pointer to buffer of key material
64  *              @size_t sz@ = size of the key material
65  *
66  * Returns:     ---
67  *
68  * Use:         Initializes a Square context with a particular key.  Square
69  *              keys must be a multiple of 32 bits long, and may be at most
70  *              128 bits.
71  */
72
73 void square_init(square_ctx *k, const void *buf, size_t sz)
74 {
75   unsigned nk, nr, nw;
76   unsigned i, j, jj;
77   const octet *p;
78   uint32 ww;
79   uint32 kk[SQUARE_KWORDS];
80
81   /* --- Sort out the key size --- */
82
83   KSZ_ASSERT(square, sz);
84   nk = sz / 4;
85
86   /* --- Fetch the first key words out --- */
87
88   p = buf;
89   for (i = 0; i < nk; i++) {
90     kk[i] = LOAD32_L(p);
91     p += 4;
92   }
93   nr = 8;
94
95   /* --- GCC complains about an out-of-bounds subscript here --- *
96    *
97    * This is impossible.  Thanks to @KSZ_ASSERT@, we know that @sz <= 16@ and
98    * hence @i <= nk <= 4@; but @SQUARE_KWORDS == 36@.
99    */
100
101 #if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
102 #  pragma GCC diagnostic push
103 #  pragma GCC diagnostic ignored "-Warray-bounds"
104 #endif
105
106   ww = kk[i - 1];
107
108 #if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
109 #  pragma GCC diagnostic pop
110 #endif
111
112   /* --- Expand this material to fill the rest of the table --- */
113
114   nw = (nr + 1) * 4;
115   p = RCON;
116   for (; i < nw; i++) {
117     uint32 w = kk[i - nk];
118     if (i % nk == 0) {
119       ww = ROR32(ww, 8);
120       w ^= ww ^ *p++;
121     } else
122       w ^= ww;
123     kk[i] = ww = w;
124   }
125
126   /* --- Make the encryption and decryption keys --- */
127
128   for (i = 0; i < nr * 4; i++) {
129     uint32 w = kk[i];
130     k->w[i] = (U[0][U8(w >>  0)] ^ U[1][U8(w >>  8)] ^
131                U[2][U8(w >> 16)] ^ U[3][U8(w >> 24)]);
132   }
133   for (; i < nw; i++)
134     k->w[i] = kk[i];
135
136   jj = nw;
137   for (i = 0; i < nr * 4; i += 4) {
138     jj -= 4;
139     for (j = 0; j < 4; j++)
140       k->wi[i + j] = kk[jj + j];
141   }
142   for (j = 0; j < 4; j++)
143     k->wi[i + j] = k->w[j];
144
145   BURN(kk);
146 }
147
148 /* --- @square_eblk@, @square_dblk@ --- *
149  *
150  * Arguments:   @const square_ctx *k@ = pointer to Square context
151  *              @const uint32 s[4]@ = pointer to source block
152  *              @uint32 d[4]@ = pointer to destination block
153  *
154  * Returns:     ---
155  *
156  * Use:         Low-level block encryption and decryption.
157  */
158
159 #define SUB(s, sh, a, b, c, d)                                          \
160   (s[U8((a) >> sh)] <<  0 | s[U8((b) >> sh)] <<  8 |                    \
161    s[U8((c) >> sh)] << 16 | s[U8((d) >> sh)] << 24)
162
163 #define MIX(t, sh, a, b, c, d)                                          \
164   (t[0][U8((a) >> sh)] ^ t[1][U8((b) >> sh)] ^                          \
165    t[2][U8((c) >> sh)] ^ t[3][U8((d) >> sh)])
166
167 #define DO(what, t, aa, bb, cc, dd, a, b, c, d, w) do {                 \
168   aa = what(t,  0, a, b, c, d) ^ *w++;                                  \
169   bb = what(t,  8, a, b, c, d) ^ *w++;                                  \
170   cc = what(t, 16, a, b, c, d) ^ *w++;                                  \
171   dd = what(t, 24, a, b, c, d) ^ *w++;                                  \
172 } while (0)
173
174 void square_eblk(const square_ctx *k, const uint32 *s, uint32 *dst)
175 {
176   uint32 a = s[0], b = s[1], c = s[2], d = s[3];
177   uint32 aa, bb, cc, dd;
178   const uint32 *w = k->w;
179
180   a ^= *w++; b ^= *w++; c ^= *w++; d ^= *w++;
181
182   DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
183   DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
184   DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
185   DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
186   DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
187   DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
188   DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
189   DO(SUB, S, a, b, c, d, aa, bb, cc, dd, w);
190
191   dst[0] = a; dst[1] = b; dst[2] = c; dst[3] = d;
192 }
193
194 void square_dblk(const square_ctx *k, const uint32 *s, uint32 *dst)
195 {
196   uint32 a = s[0], b = s[1], c = s[2], d = s[3];
197   uint32 aa, bb, cc, dd;
198   const uint32 *w = k->wi;
199
200   a ^= *w++; b ^= *w++; c ^= *w++; d ^= *w++;
201
202   DO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
203   DO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
204   DO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
205   DO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
206   DO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
207   DO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
208   DO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
209   DO(SUB, SI, a, b, c, d, aa, bb, cc, dd, w);
210
211   dst[0] = a; dst[1] = b; dst[2] = c; dst[3] = d;
212 }
213
214 BLKC_TEST(SQUARE, square)
215
216 /*----- That's all, folks -------------------------------------------------*/