chiark / gitweb /
math/gfx-sqr.c: Use bithacking rather than a table for squaring.
[catacomb] / symm / ecb-def.h
1 /* -*-c-*-
2  *
3  * Definitions electronic code book mode
4  *
5  * (c) 1999 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 #ifndef CATACOMB_ECB_DEF_H
29 #define CATACOMB_ECB_DEF_H
30
31 #ifdef __cplusplus
32   extern "C" {
33 #endif
34
35 /*----- Header files ------------------------------------------------------*/
36
37 #include <assert.h>
38 #include <string.h>
39
40 #include <mLib/bits.h>
41 #include <mLib/sub.h>
42
43 #ifndef CATACOMB_ARENA_H
44 #  include "arena.h"
45 #endif
46
47 #ifndef CATACOMB_BLKC_H
48 #  include "blkc.h"
49 #endif
50
51 #ifndef CATACOMB_GCIPHER_H
52 #  include "gcipher.h"
53 #endif
54
55 #ifndef CATACOMB_PARANOIA_H
56 #  include "paranoia.h"
57 #endif
58
59 /*----- Macros ------------------------------------------------------------*/
60
61 /* --- @ECB_DEF@ --- *
62  *
63  * Arguments:   @PRE@, @pre@ = prefixes for the underlying block cipher
64  *
65  * Use:         Creates an implementation for ECB stealing mode.
66  */
67
68 #define ECB_DEF(PRE, pre) ECB_DEFX(PRE, pre, #pre, #pre)
69
70 #define ECB_DEFX(PRE, pre, name, fname)                                 \
71                                                                         \
72 /* --- @pre_ecbsetkey@ --- *                                            \
73  *                                                                      \
74  * Arguments:   @pre_ecbctx *ctx@ = pointer to ECB context block        \
75  *              @const pre_ctx *k@ = pointer to cipher context          \
76  *                                                                      \
77  * Returns:     ---                                                     \
78  *                                                                      \
79  * Use:         Sets the ECB context to use a different cipher key.     \
80  */                                                                     \
81                                                                         \
82 void pre##_ecbsetkey(pre##_ecbctx *ctx, const pre##_ctx *k)             \
83   { ctx->ctx = *k; }                                                    \
84                                                                         \
85 /* --- @pre_ecbinit@ --- *                                              \
86  *                                                                      \
87  * Arguments:   @pre_ecbctx *ctx@ = pointer to cipher context           \
88  *              @const void *key@ = pointer to the key buffer           \
89  *              @size_t sz@ = size of the key                           \
90  *              @const void *iv@ = pointer to initialization vector     \
91  *                                                                      \
92  * Returns:     ---                                                     \
93  *                                                                      \
94  * Use:         Initializes an ECB context ready for use.  This is      \
95  *              equivalent to calls to @pre_init@ and @pre_setkey@.     \
96  */                                                                     \
97                                                                         \
98 void pre##_ecbinit(pre##_ecbctx *ctx,                                   \
99                    const void *key, size_t sz,                          \
100                    const void *iv)                                      \
101   { pre##_init(&ctx->ctx, key, sz); }                                   \
102                                                                         \
103 /* --- @pre_ecbencrypt@ --- *                                           \
104  *                                                                      \
105  * Arguments:   @pre_ecbctx *ctx@ = pointer to ECB context block        \
106  *              @const void *src@ = pointer to source data              \
107  *              @void *dest@ = pointer to destination data              \
108  *              @size_t sz@ = size of block to be encrypted             \
109  *                                                                      \
110  * Returns:     ---                                                     \
111  *                                                                      \
112  * Use:         Encrypts a block with a block cipher in ECB mode, with  \
113  *              ciphertext stealing and other clever tricks.            \
114  *              Essentially, data can be encrypted in arbitrary sized   \
115  *              chunks, although decryption must use the same chunks.   \
116  */                                                                     \
117                                                                         \
118 void pre##_ecbencrypt(pre##_ecbctx *ctx,                                \
119                       const void *src, void *dest,                      \
120                       size_t sz)                                        \
121 {                                                                       \
122   const octet *s = src;                                                 \
123   octet *d = dest;                                                      \
124   uint32 t[PRE##_BLKSZ/4];                                              \
125   octet b[PRE##_BLKSZ];                                                 \
126   octet y;                                                              \
127   unsigned i;                                                           \
128                                                                         \
129   /* --- Empty blocks are trivial, and ECB is stateless --- */          \
130                                                                         \
131   if (!sz || !d) return;                                                \
132                                                                         \
133   /* --- Short blocks aren't allowed in ECB --- *                       \
134    *                                                                    \
135    * There's absolutely nothing secure I can do with them.              \
136    */                                                                   \
137                                                                         \
138   assert(((void)"ECB must have at least one whole block to work with",  \
139           sz >= PRE##_BLKSZ));                                          \
140                                                                         \
141   /* --- Do the main chunk of encryption --- *                          \
142    *                                                                    \
143    * This will do the whole lot if it's a whole number of blocks.  Just \
144    * give each block to the cipher in turn.  This is trivial.           \
145    * Hopefully...                                                       \
146    */                                                                   \
147                                                                         \
148   while (sz >= 2*PRE##_BLKSZ || sz == PRE##_BLKSZ) {                    \
149     if (!s) BLKC_ZERO(PRE, t);                                          \
150     else { BLKC_LOAD(PRE, t, s); s += PRE##_BLKSZ; }                    \
151     pre##_eblk(&ctx->ctx, t, t);                                        \
152     BLKC_STORE(PRE, d, t); d += PRE##_BLKSZ;                            \
153     sz -= PRE##_BLKSZ;                                                  \
154   }                                                                     \
155                                                                         \
156   /* --- Do the tail-end block and bit-left-over --- *                  \
157    *                                                                    \
158    * This isn't very efficient.  That shouldn't matter much.            \
159    */                                                                   \
160                                                                         \
161   if (sz) {                                                             \
162                                                                         \
163     /* --- Let @sz@ be the size of the partial block --- */             \
164                                                                         \
165     sz -= PRE##_BLKSZ;                                                  \
166                                                                         \
167     /* --- First stage --- *                                            \
168      *                                                                  \
169      * Read in the current block, and encrypt it.  The first part of    \
170      * the result is the partial ciphertext block.  Don't write that    \
171      * out yet, because I've not read the partial plaintext block.      \
172      */                                                                 \
173                                                                         \
174     if (!s) BLKC_ZERO(PRE, t);                                          \
175     else { BLKC_LOAD(PRE, t, s); s += PRE##_BLKSZ; }                    \
176     pre##_eblk(&ctx->ctx, t, t);                                        \
177     BLKC_STORE(PRE, b, t);                                              \
178                                                                         \
179     /* --- Second stage --- *                                           \
180      *                                                                  \
181      * Now move in the partial plaintext block, writing out the         \
182      * ciphertext as I go.  Then encrypt, and write the complete        \
183      * ciphertext block.                                                \
184      */                                                                 \
185                                                                         \
186     d += PRE##_BLKSZ;                                                   \
187     for (i = 0; i < sz; i++) { y = b[i]; b[i] = s[i]; d[i] = y; }       \
188     BLKC_LOAD(PRE, t, b);                                               \
189     pre##_eblk(&ctx->ctx, t, t);                                        \
190     BLKC_STORE(PRE, d - PRE##_BLKSZ, t);                                \
191   }                                                                     \
192                                                                         \
193   /* --- Done --- */                                                    \
194                                                                         \
195   return;                                                               \
196 }                                                                       \
197                                                                         \
198 /* --- @pre_ecbdecrypt@ --- *                                           \
199  *                                                                      \
200  * Arguments:   @pre_ecbctx *ctx@ = pointer to ECB context block        \
201  *              @const void *src@ = pointer to source data              \
202  *              @void *dest@ = pointer to destination data              \
203  *              @size_t sz@ = size of block to be encrypted             \
204  *                                                                      \
205  * Returns:     ---                                                     \
206  *                                                                      \
207  * Use:         Decrypts a block with a block cipher in ECB mode, with  \
208  *              ciphertext stealing and other clever tricks.            \
209  *              Essentially, data can be encrypted in arbitrary sized   \
210  *              chunks, although decryption must use the same chunks.   \
211  */                                                                     \
212                                                                         \
213 void pre##_ecbdecrypt(pre##_ecbctx *ctx,                                \
214                         const void *src, void *dest,                    \
215                         size_t sz)                                      \
216 {                                                                       \
217   const octet *s = src;                                                 \
218   octet *d = dest;                                                      \
219   uint32 t[PRE##_BLKSZ/4];                                              \
220   octet b[PRE##_BLKSZ];                                                 \
221   octet y;                                                              \
222   unsigned i;                                                           \
223                                                                         \
224   /* --- Empty blocks are trivial --- */                                \
225                                                                         \
226   if (!sz) return;                                                      \
227                                                                         \
228   /* --- Short blocks aren't allowed in ECB --- *                       \
229    *                                                                    \
230    * There's absolutely nothing secure I can do with them.              \
231    */                                                                   \
232                                                                         \
233   assert(((void)"ECB must have at least one whole block to work with",  \
234           sz >= PRE##_BLKSZ));                                          \
235                                                                         \
236   /* --- Do the main chunk of decryption --- *                          \
237    *                                                                    \
238    * This will do the whole lot if it's a whole number of blocks.       \
239    * Each block is just handed to the block cipher in turn.             \
240    */                                                                   \
241                                                                         \
242   while (sz >= 2*PRE##_BLKSZ || sz == PRE##_BLKSZ) {                    \
243     BLKC_LOAD(PRE, t, s); s += PRE##_BLKSZ;                             \
244     pre##_dblk(&ctx->ctx, t, t);                                        \
245     BLKC_STORE(PRE, d, t); d += PRE##_BLKSZ;                            \
246     sz -= PRE##_BLKSZ;                                                  \
247   }                                                                     \
248                                                                         \
249   /* --- Do the tail-end block and bit-left-over --- *                  \
250    *                                                                    \
251    * This isn't very efficient.  That shouldn't matter much.            \
252    */                                                                   \
253                                                                         \
254   if (sz) {                                                             \
255                                                                         \
256     /* --- Let @sz@ be the size of the partial block --- */             \
257                                                                         \
258     sz -= PRE##_BLKSZ;                                                  \
259                                                                         \
260     /* --- First stage --- *                                            \
261      *                                                                  \
262      * Take the complete ciphertext block, and decrypt it.  This block  \
263      * is carried over for the next encryption operation.               \
264      */                                                                 \
265                                                                         \
266     BLKC_LOAD(PRE, t, s);                                               \
267     pre##_dblk(&ctx->ctx, t, t);                                        \
268     BLKC_STORE(PRE, b, t);                                              \
269                                                                         \
270     /* --- Second stage --- *                                           \
271      *                                                                  \
272      * The first few bytes are the partial plaintext block.  Write that \
273      * and replace with the partial ciphertext block.  Then decrypt     \
274      * what's left as the complete plaintext.                           \
275      */                                                                 \
276                                                                         \
277     s += PRE##_BLKSZ;                                                   \
278     d += PRE##_BLKSZ;                                                   \
279     for (i = 0; i < sz; i++) { y = s[i]; d[i] = b[i]; b[i] = y; }       \
280     BLKC_LOAD(PRE, t, b);                                               \
281     pre##_dblk(&ctx->ctx, t, t);                                        \
282     BLKC_STORE(PRE, d - PRE##_BLKSZ, t);                                \
283   }                                                                     \
284                                                                         \
285   /* --- Done --- */                                                    \
286                                                                         \
287   return;                                                               \
288 }                                                                       \
289                                                                         \
290 /* --- Generic cipher interface --- */                                  \
291                                                                         \
292 static const gcipher_ops gops;                                          \
293                                                                         \
294 typedef struct gctx {                                                   \
295   gcipher c;                                                            \
296   pre##_ecbctx k;                                                       \
297 } gctx;                                                                 \
298                                                                         \
299 static gcipher *ginit(const void *k, size_t sz)                         \
300 {                                                                       \
301   gctx *g = S_CREATE(gctx);                                             \
302   g->c.ops = &gops;                                                     \
303   pre##_ecbinit(&g->k, k, sz, 0);                                       \
304   return (&g->c);                                                       \
305 }                                                                       \
306                                                                         \
307 static void gencrypt(gcipher *c, const void *s, void *t, size_t sz)     \
308   { gctx *g = (gctx *)c; pre##_ecbencrypt(&g->k, s, t, sz); }           \
309                                                                         \
310 static void gdecrypt(gcipher *c, const void *s, void *t, size_t sz)     \
311   { gctx *g = (gctx *)c; pre##_ecbdecrypt(&g->k, s, t, sz); }           \
312                                                                         \
313 static void gdestroy(gcipher *c)                                        \
314   { gctx *g = (gctx *)c; BURN(*g); S_DESTROY(g); }                      \
315                                                                         \
316 static const gcipher_ops gops = {                                       \
317   &pre##_ecb,                                                           \
318   gencrypt, gdecrypt, gdestroy, 0, 0                                    \
319 };                                                                      \
320                                                                         \
321 const gccipher pre##_ecb = {                                            \
322   name "-ecb", pre##_keysz, PRE##_BLKSZ,                                \
323   ginit                                                                 \
324 };                                                                      \
325                                                                         \
326 ECB_TESTX(PRE, pre, name, fname)
327
328 /*----- Test rig ----------------------------------------------------------*/
329
330 #define ECB_TEST(PRE, pre) ECB_TESTX(PRE, pre, #pre, #pre)
331
332 #ifdef TEST_RIG
333
334 #include "modes-test.h"
335
336 /* --- @ECB_TEST@ --- *
337  *
338  * Arguments:   @PRE@, @pre@ = prefixes for block cipher definitions
339  *
340  * Use:         Standard test rig for ECB functions.
341  */
342
343 #define ECB_TESTX(PRE, pre, name, fname)                                \
344                                                                         \
345 static pre##_ctx key;                                                   \
346 static pre##_ecbctx ctx;                                                \
347                                                                         \
348 static void pre##_ecb_test_setup(const octet *k, size_t ksz)            \
349   { pre##_init(&key, k, ksz); pre##_ecbsetkey(&ctx, &key); }            \
350                                                                         \
351 static void pre##_ecb_test_reset(const octet *iv)                       \
352   { ; }                                                                 \
353                                                                         \
354 static void pre##_ecb_test_enc(const octet *s, octet *d, size_t sz)     \
355   { pre##_ecbencrypt(&ctx, s, d, sz); }                                 \
356                                                                         \
357 static void pre##_ecb_test_dec(const octet *s, octet *d, size_t sz)     \
358   { pre##_ecbdecrypt(&ctx, s, d, sz); }                                 \
359                                                                         \
360 int main(int argc, char *argv[])                                        \
361 {                                                                       \
362   return test_encmode(fname "-ecb", PRE##_KEYSZ, PRE##_BLKSZ,           \
363                       PRE##_BLKSZ, TEMF_REFALIGN,                       \
364                       pre##_ecb_test_setup, pre##_ecb_test_reset,       \
365                       pre##_ecb_test_enc, pre##_ecb_test_dec,           \
366                       argc, argv);                                      \
367 }
368
369 #else
370 #  define ECB_TESTX(PRE, pre, name, fname)
371 #endif
372
373 /*----- That's all, folks -------------------------------------------------*/
374
375 #ifdef __cplusplus
376   }
377 #endif
378
379 #endif