chiark / gitweb /
math/gfx-sqr.c: Use bithacking rather than a table for squaring.
[catacomb] / symm / cbc-def.h
1 /* -*-c-*-
2  *
3  * Definitions for cipher block chaining 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_CBC_DEF_H
29 #define CATACOMB_CBC_DEF_H
30
31 #ifdef __cplusplus
32   extern "C" {
33 #endif
34
35 /*----- Header files ------------------------------------------------------*/
36
37 #include <string.h>
38
39 #include <mLib/bits.h>
40 #include <mLib/sub.h>
41
42 #ifndef CATACOMB_ARENA_H
43 #  include "arena.h"
44 #endif
45
46 #ifndef CATACOMB_BLKC_H
47 #  include "blkc.h"
48 #endif
49
50 #ifndef CATACOMB_GCIPHER_H
51 #  include "gcipher.h"
52 #endif
53
54 #ifndef CATACOMB_PARANOIA_H
55 #  include "paranoia.h"
56 #endif
57
58 /*----- Macros ------------------------------------------------------------*/
59
60 /* --- @CBC_DEF@ --- *
61  *
62  * Arguments:   @PRE@, @pre@ = prefixes for the underlying block cipher
63  *
64  * Use:         Creates an implementation for CBC stealing mode.
65  */
66
67 #define CBC_DEF(PRE, pre) CBC_DEFX(PRE, pre, #pre, #pre)
68
69 #define CBC_DEFX(PRE, pre, name, fname)                                 \
70                                                                         \
71 /* --- @pre_cbcgetiv@ --- *                                             \
72  *                                                                      \
73  * Arguments:   @const pre_cbcctx *ctx@ = pointer to CBC context block  \
74  *              @void *iv@ = pointer to output data block               \
75  *                                                                      \
76  * Returns:     ---                                                     \
77  *                                                                      \
78  * Use:         Reads the currently set IV.  Reading and setting an IV  \
79  *              is transparent to the CBC encryption or decryption      \
80  *              process.                                                \
81  */                                                                     \
82                                                                         \
83 void pre##_cbcgetiv(const pre##_cbcctx *ctx, void *iv)                  \
84   { BLKC_STORE(PRE, iv, ctx->a); }                                      \
85                                                                         \
86 /* --- @pre_cbcsetiv@ --- *                                             \
87  *                                                                      \
88  * Arguments:   @pre_cbcctx *ctx@ = pointer to CBC context block        \
89  *              @cnost void *iv@ = pointer to IV to set                 \
90  *                                                                      \
91  * Returns:     ---                                                     \
92  *                                                                      \
93  * Use:         Sets the IV to use for subsequent encryption.           \
94  */                                                                     \
95                                                                         \
96 void pre##_cbcsetiv(pre##_cbcctx *ctx, const void *iv)                  \
97   { BLKC_LOAD(PRE, ctx->a, iv); }                                       \
98                                                                         \
99 /* --- @pre_cbcsetkey@ --- *                                            \
100  *                                                                      \
101  * Arguments:   @pre_cbcctx *ctx@ = pointer to CBC context block        \
102  *              @const pre_ctx *k@ = pointer to cipher context          \
103  *                                                                      \
104  * Returns:     ---                                                     \
105  *                                                                      \
106  * Use:         Sets the CBC context to use a different cipher key.     \
107  */                                                                     \
108                                                                         \
109 void pre##_cbcsetkey(pre##_cbcctx *ctx, const pre##_ctx *k)             \
110   { ctx->ctx = *k; }                                                    \
111                                                                         \
112 /* --- @pre_cbcinit@ --- *                                              \
113  *                                                                      \
114  * Arguments:   @pre_cbcctx *ctx@ = pointer to cipher context           \
115  *              @const void *key@ = pointer to the key buffer           \
116  *              @size_t sz@ = size of the key                           \
117  *              @const void *iv@ = pointer to initialization vector     \
118  *                                                                      \
119  * Returns:     ---                                                     \
120  *                                                                      \
121  * Use:         Initializes a CBC context ready for use.  The @iv@      \
122  *              argument may be passed as a null pointer to set a zero  \
123  *              IV.  Apart from that, this call is equivalent to calls  \
124  *              to @pre_init@, @pre_cbcsetkey@ and @pre_cbcsetiv@.      \
125  */                                                                     \
126                                                                         \
127 void pre##_cbcinit(pre##_cbcctx *ctx,                                   \
128                    const void *key, size_t sz,                          \
129                    const void *iv)                                      \
130 {                                                                       \
131   static const octet zero[PRE##_BLKSZ] = { 0 };                         \
132                                                                         \
133   pre##_init(&ctx->ctx, key, sz);                                       \
134   BLKC_LOAD(PRE, ctx->a, iv ? iv : zero);                               \
135 }                                                                       \
136                                                                         \
137 /* --- @pre_cbcencrypt@ --- *                                           \
138  *                                                                      \
139  * Arguments:   @pre_cbcctx *ctx@ = pointer to CBC context block        \
140  *              @const void *src@ = pointer to source data              \
141  *              @void *dest@ = pointer to destination data              \
142  *              @size_t sz@ = size of block to be encrypted             \
143  *                                                                      \
144  * Returns:     ---                                                     \
145  *                                                                      \
146  * Use:         Encrypts a block with a block cipher in CBC mode, with  \
147  *              ciphertext stealing and other clever tricks.            \
148  *              Essentially, data can be encrypted in arbitrary sized   \
149  *              chunks, although decryption must use the same chunks.   \
150  */                                                                     \
151                                                                         \
152 void pre##_cbcencrypt(pre##_cbcctx *ctx,                                \
153                       const void *src, void *dest,                      \
154                       size_t sz)                                        \
155 {                                                                       \
156   const octet *s = src;                                                 \
157   octet *d = dest;                                                      \
158   octet b[PRE##_BLKSZ], bb[PRE##_BLKSZ];                                \
159   octet y;                                                              \
160   unsigned i;                                                           \
161                                                                         \
162   /* --- Empty blocks are trivial --- */                                \
163                                                                         \
164   if (!sz) return;                                                      \
165                                                                         \
166   /* --- Extra magical case for a short block --- *                     \
167    *                                                                    \
168    * Encrypt the IV, then exclusive-or the plaintext with the octets    \
169    * of the encrypted IV, shifting ciphertext octets in instead.  This  \
170    * basically switches over to CFB.                                    \
171    */                                                                   \
172                                                                         \
173   if (sz < PRE##_BLKSZ) {                                               \
174     pre##_eblk(&ctx->ctx, ctx->a, ctx->a);                              \
175     BLKC_STORE(PRE, b, ctx->a);                                         \
176     if (!d) d = bb;                                                     \
177     for (i = 0; i < sz; i++) d[i] = b[i] ^ (s ? s[i] : 0);              \
178     memmove(b, b + sz, PRE##_BLKSZ - sz);                               \
179     memcpy(b + PRE##_BLKSZ - sz, d, sz);                                \
180     BLKC_LOAD(PRE, ctx->a, b);                                          \
181     return;                                                             \
182   }                                                                     \
183                                                                         \
184   /* --- Do the main chunk of encryption --- *                          \
185    *                                                                    \
186    * This will do the whole lot if it's a whole number of blocks.  For  \
187    * each block, XOR it with the previous ciphertext in @iv@, encrypt,  \
188    * and keep a copy of the ciphertext for the next block.              \
189    */                                                                   \
190                                                                         \
191   while (sz >= 2*PRE##_BLKSZ || sz == PRE##_BLKSZ) {                    \
192     if (s) { BLKC_XLOAD(PRE, ctx->a, s); s += PRE##_BLKSZ; }            \
193     pre##_eblk(&ctx->ctx, ctx->a, ctx->a);                              \
194     if (d) { BLKC_STORE(PRE, d, ctx->a); d += PRE##_BLKSZ; }            \
195     sz -= PRE##_BLKSZ;                                                  \
196   }                                                                     \
197                                                                         \
198   /* --- Do the tail-end block and bit-left-over --- *                  \
199    *                                                                    \
200    * This isn't very efficient.  That shouldn't matter much.            \
201    */                                                                   \
202                                                                         \
203   if (sz) {                                                             \
204                                                                         \
205     /* --- Let @sz@ be the size of the partial block --- */             \
206                                                                         \
207     sz -= PRE##_BLKSZ;                                                  \
208                                                                         \
209     /* --- First stage --- *                                            \
210      *                                                                  \
211      * XOR the complete block with the current IV, and encrypt it.  The \
212      * first part of the result is the partial ciphertext block.  Don't \
213      * write that out yet, because I've not read the partial plaintext  \
214      * block.                                                           \
215      */                                                                 \
216                                                                         \
217     if (s) BLKC_XLOAD(PRE, ctx->a, s);                                  \
218     pre##_eblk(&ctx->ctx, ctx->a, ctx->a);                              \
219     BLKC_STORE(PRE, b, ctx->a);                                         \
220                                                                         \
221     /* --- Second stage --- *                                           \
222      *                                                                  \
223      * Now XOR in the partial plaintext block, writing out the          \
224      * ciphertext as I go.  Then encrypt, and write the complete        \
225      * ciphertext block.                                                \
226      */                                                                 \
227                                                                         \
228     if (s) s += PRE##_BLKSZ;                                            \
229     if (d) d += PRE##_BLKSZ;                                            \
230     for (i = 0; i < sz; i++) {                                          \
231       y = b[i];                                                         \
232       if (s) b[i] ^= s[i];                                              \
233       if (d) d[i] = y;                                                  \
234     }                                                                   \
235     BLKC_LOAD(PRE, ctx->a, b);                                          \
236     pre##_eblk(&ctx->ctx, ctx->a, ctx->a);                              \
237     if (d) BLKC_STORE(PRE, d - PRE##_BLKSZ, ctx->a);                    \
238   }                                                                     \
239                                                                         \
240   /* --- Done --- */                                                    \
241                                                                         \
242   return;                                                               \
243 }                                                                       \
244                                                                         \
245 /* --- @pre_cbcdecrypt@ --- *                                           \
246  *                                                                      \
247  * Arguments:   @pre_cbcctx *ctx@ = pointer to CBC context block        \
248  *              @const void *src@ = pointer to source data              \
249  *              @void *dest@ = pointer to destination data              \
250  *              @size_t sz@ = size of block to be encrypted             \
251  *                                                                      \
252  * Returns:     ---                                                     \
253  *                                                                      \
254  * Use:         Decrypts a block with a block cipher in CBC mode, with  \
255  *              ciphertext stealing and other clever tricks.            \
256  *              Essentially, data can be encrypted in arbitrary sized   \
257  *              chunks, although decryption must use the same chunks.   \
258  */                                                                     \
259                                                                         \
260 void pre##_cbcdecrypt(pre##_cbcctx *ctx,                                \
261                       const void *src, void *dest,                      \
262                       size_t sz)                                        \
263 {                                                                       \
264   const octet *s = src;                                                 \
265   octet *d = dest;                                                      \
266   uint32 t[PRE##_BLKSZ/4], u[PRE##_BLKSZ/4];                            \
267   octet b[PRE##_BLKSZ], c[PRE##_BLKSZ];                                 \
268   octet y;                                                              \
269   unsigned i;                                                           \
270                                                                         \
271   /* --- Empty blocks are trivial --- */                                \
272                                                                         \
273   if (!sz) return;                                                      \
274                                                                         \
275   /* --- Extra magical case for a short block --- *                     \
276    *                                                                    \
277    * Encrypt the IV, then exclusive-or the ciphertext with the octets   \
278    * of the encrypted IV, shifting ciphertext octets in instead.  This  \
279    * basically switches over to CFB.                                    \
280    */                                                                   \
281                                                                         \
282   if (sz < PRE##_BLKSZ) {                                               \
283     pre##_eblk(&ctx->ctx, ctx->a, ctx->a);                              \
284     BLKC_STORE(PRE, b, ctx->a);                                         \
285     for (i = 0; i < sz; i++) { y = s[i]; d[i] = b[i] ^ y; c[i] = y; }   \
286     memmove(b, b + sz, PRE##_BLKSZ - sz);                               \
287     memcpy(b + PRE##_BLKSZ - sz, c, sz);                                \
288     BLKC_LOAD(PRE, ctx->a, b);                                          \
289     return;                                                             \
290   }                                                                     \
291                                                                         \
292   /* --- Do the main chunk of decryption --- *                          \
293    *                                                                    \
294    * This will do the whole lot if it's a whole number of blocks.  For  \
295    * each block, decrypt, XOR it with the previous ciphertext in @iv@,  \
296    * and keep a copy of the ciphertext for the next block.              \
297    */                                                                   \
298                                                                         \
299   while (sz >= 2*PRE##_BLKSZ || sz == PRE##_BLKSZ) {                    \
300     BLKC_LOAD(PRE, t, s); s += PRE##_BLKSZ;                             \
301     pre##_dblk(&ctx->ctx, t, u);                                        \
302     BLKC_XSTORE(PRE, d, u, ctx->a); d += PRE##_BLKSZ;                   \
303     BLKC_MOVE(PRE, ctx->a, t);                                          \
304     sz -= PRE##_BLKSZ;                                                  \
305   }                                                                     \
306                                                                         \
307   /* --- Do the tail-end block and bit-left-over --- *                  \
308    *                                                                    \
309    * This isn't very efficient.  That shouldn't matter much.            \
310    */                                                                   \
311                                                                         \
312   if (sz) {                                                             \
313                                                                         \
314     /* --- Let @sz@ be the size of the partial block --- */             \
315                                                                         \
316     sz -= PRE##_BLKSZ;                                                  \
317                                                                         \
318     /* --- First stage --- *                                            \
319      *                                                                  \
320      * Take the complete ciphertext block, and decrypt it.  This block  \
321      * is carried over for the next encryption operation.               \
322      */                                                                 \
323                                                                         \
324     BLKC_LOAD(PRE, t, s);                                               \
325     pre##_dblk(&ctx->ctx, t, u);                                        \
326                                                                         \
327     /* --- Second stage --- *                                           \
328      *                                                                  \
329      * XORing the first few bytes of this with the partial ciphertext   \
330      * block recovers the partial plaintext block.  At the same time,   \
331      * write the partial ciphertext block's contents in ready for stage \
332      * three.                                                           \
333      */                                                                 \
334                                                                         \
335     BLKC_STORE(PRE, b, u);                                              \
336     s += PRE##_BLKSZ;                                                   \
337     d += PRE##_BLKSZ;                                                   \
338     for (i = 0; i < sz; i++) { y = s[i]; d[i] = b[i] ^ y; b[i] = y; }   \
339                                                                         \
340     /* --- Third stage --- *                                            \
341      *                                                                  \
342      * Decrypt the block we've got left, and XOR with the initial IV to \
343      * recover the complete plaintext block.                            \
344      */                                                                 \
345                                                                         \
346     BLKC_LOAD(PRE, u, b);                                               \
347     pre##_dblk(&ctx->ctx, u, u);                                        \
348     BLKC_XSTORE(PRE, d - PRE##_BLKSZ, u, ctx->a);                       \
349     BLKC_MOVE(PRE, ctx->a, t);                                          \
350   }                                                                     \
351                                                                         \
352   /* --- Done --- */                                                    \
353                                                                         \
354   return;                                                               \
355 }                                                                       \
356                                                                         \
357 /* --- Generic cipher interface --- */                                  \
358                                                                         \
359 static const gcipher_ops gops;                                          \
360                                                                         \
361 typedef struct gctx {                                                   \
362   gcipher c;                                                            \
363   pre##_cbcctx k;                                                       \
364 } gctx;                                                                 \
365                                                                         \
366 static gcipher *ginit(const void *k, size_t sz)                         \
367 {                                                                       \
368   gctx *g = S_CREATE(gctx);                                             \
369   g->c.ops = &gops;                                                     \
370   pre##_cbcinit(&g->k, k, sz, 0);                                       \
371   return (&g->c);                                                       \
372 }                                                                       \
373                                                                         \
374 static void gencrypt(gcipher *c, const void *s, void *t, size_t sz)     \
375   { gctx *g = (gctx *)c; pre##_cbcencrypt(&g->k, s, t, sz); }           \
376                                                                         \
377 static void gdecrypt(gcipher *c, const void *s, void *t, size_t sz)     \
378   { gctx *g = (gctx *)c; pre##_cbcdecrypt(&g->k, s, t, sz); }           \
379                                                                         \
380 static void gdestroy(gcipher *c)                                        \
381   { gctx *g = (gctx *)c; BURN(*g); S_DESTROY(g); }                      \
382                                                                         \
383 static void gsetiv(gcipher *c, const void *iv)                          \
384   { gctx *g = (gctx *)c; pre##_cbcsetiv(&g->k, iv); }                   \
385                                                                         \
386 static const gcipher_ops gops = {                                       \
387   &pre##_cbc,                                                           \
388   gencrypt, gdecrypt, gdestroy, gsetiv, 0                               \
389 };                                                                      \
390                                                                         \
391 const gccipher pre##_cbc = {                                            \
392   name "-cbc", pre##_keysz, PRE##_BLKSZ,                                \
393   ginit                                                                 \
394 };                                                                      \
395                                                                         \
396 CBC_TESTX(PRE, pre, name, fname)
397
398 /*----- Test rig ----------------------------------------------------------*/
399
400 #define CBC_TEST(PRE, pre) CBC_TESTX(PRE, pre, #pre, #pre)
401
402 #ifdef TEST_RIG
403
404 #include "modes-test.h"
405
406 /* --- @CBC_TEST@ --- *
407  *
408  * Arguments:   @PRE@, @pre@ = prefixes for block cipher definitions
409  *
410  * Use:         Standard test rig for CBC functions.
411  */
412
413 #define CBC_TESTX(PRE, pre, name, fname)                                \
414                                                                         \
415 static pre##_ctx key;                                                   \
416 static pre##_cbcctx ctx;                                                \
417                                                                         \
418 static void pre##_cbc_test_setup(const octet *k, size_t ksz)            \
419   { pre##_init(&key, k, ksz); pre##_cbcsetkey(&ctx, &key); }            \
420                                                                         \
421 static void pre##_cbc_test_reset(const octet *iv)                       \
422   { pre##_cbcsetiv(&ctx, iv); }                                         \
423                                                                         \
424 static void pre##_cbc_test_enc(const octet *s, octet *d, size_t sz)     \
425   { pre##_cbcencrypt(&ctx, s, d, sz); }                                 \
426                                                                         \
427 static void pre##_cbc_test_dec(const octet *s, octet *d, size_t sz)     \
428   { pre##_cbcdecrypt(&ctx, s, d, sz); }                                 \
429                                                                         \
430 int main(int argc, char *argv[])                                        \
431 {                                                                       \
432   return test_encmode(fname "-cbc", PRE##_KEYSZ, PRE##_BLKSZ,           \
433                       1, TEMF_REFALIGN,                                 \
434                       pre##_cbc_test_setup, pre##_cbc_test_reset,       \
435                       pre##_cbc_test_enc, pre##_cbc_test_dec,           \
436                       argc, argv);                                      \
437 }
438
439 #else
440 #  define CBC_TESTX(PRE, pre, name, fname)
441 #endif
442
443 /*----- That's all, folks -------------------------------------------------*/
444
445 #ifdef __cplusplus
446   }
447 #endif
448
449 #endif