chiark / gitweb /
debian/control: Don't require `valgrind' on `armel'.
[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 {                                                                       \
85   BLKC_STORE(PRE, iv, ctx->iv);                                         \
86 }                                                                       \
87                                                                         \
88 /* --- @pre_cbcsetiv@ --- *                                             \
89  *                                                                      \
90  * Arguments:   @pre_cbcctx *ctx@ = pointer to CBC context block        \
91  *              @cnost void *iv@ = pointer to IV to set                 \
92  *                                                                      \
93  * Returns:     ---                                                     \
94  *                                                                      \
95  * Use:         Sets the IV to use for subsequent encryption.           \
96  */                                                                     \
97                                                                         \
98 void pre##_cbcsetiv(pre##_cbcctx *ctx, const void *iv)                  \
99 {                                                                       \
100   BLKC_LOAD(PRE, ctx->iv, iv);                                          \
101 }                                                                       \
102                                                                         \
103 /* --- @pre_cbcsetkey@ --- *                                            \
104  *                                                                      \
105  * Arguments:   @pre_cbcctx *ctx@ = pointer to CBC context block        \
106  *              @const pre_ctx *k@ = pointer to cipher context          \
107  *                                                                      \
108  * Returns:     ---                                                     \
109  *                                                                      \
110  * Use:         Sets the CBC context to use a different cipher key.     \
111  */                                                                     \
112                                                                         \
113 void pre##_cbcsetkey(pre##_cbcctx *ctx, const pre##_ctx *k)             \
114 {                                                                       \
115   ctx->ctx = *k;                                                        \
116 }                                                                       \
117                                                                         \
118 /* --- @pre_cbcinit@ --- *                                              \
119  *                                                                      \
120  * Arguments:   @pre_cbcctx *ctx@ = pointer to cipher context           \
121  *              @const void *key@ = pointer to the key buffer           \
122  *              @size_t sz@ = size of the key                           \
123  *              @const void *iv@ = pointer to initialization vector     \
124  *                                                                      \
125  * Returns:     ---                                                     \
126  *                                                                      \
127  * Use:         Initializes a CBC context ready for use.  The @iv@      \
128  *              argument may be passed as a null pointer to set a zero  \
129  *              IV.  Apart from that, this call is equivalent to calls  \
130  *              to @pre_init@, @pre_cbcsetkey@ and @pre_cbcsetiv@.      \
131  */                                                                     \
132                                                                         \
133 void pre##_cbcinit(pre##_cbcctx *ctx,                                   \
134                      const void *key, size_t sz,                        \
135                      const void *iv)                                    \
136 {                                                                       \
137   static const octet zero[PRE##_BLKSZ] = { 0 };                         \
138   pre##_init(&ctx->ctx, key, sz);                                       \
139   BLKC_LOAD(PRE, ctx->iv, iv ? iv : zero);                              \
140 }                                                                       \
141                                                                         \
142 /* --- @pre_cbcencrypt@ --- *                                           \
143  *                                                                      \
144  * Arguments:   @pre_cbcctx *ctx@ = pointer to CBC context block        \
145  *              @const void *src@ = pointer to source data              \
146  *              @void *dest@ = pointer to destination data              \
147  *              @size_t sz@ = size of block to be encrypted             \
148  *                                                                      \
149  * Returns:     ---                                                     \
150  *                                                                      \
151  * Use:         Encrypts a block with a block cipher in CBC mode, with  \
152  *              ciphertext stealing and other clever tricks.            \
153  *              Essentially, data can be encrypted in arbitrary sized   \
154  *              chunks, although decryption must use the same chunks.   \
155  */                                                                     \
156                                                                         \
157 void pre##_cbcencrypt(pre##_cbcctx *ctx,                                \
158                         const void *src, void *dest,                    \
159                         size_t sz)                                      \
160 {                                                                       \
161   const octet *s = src;                                                 \
162   octet *d = dest;                                                      \
163                                                                         \
164   /* --- Empty blocks are trivial --- */                                \
165                                                                         \
166   if (!sz)                                                              \
167     return;                                                             \
168                                                                         \
169   /* --- Extra magical case for a short block --- *                     \
170    *                                                                    \
171    * Encrypt the IV, then exclusive-or the plaintext with the octets    \
172    * of the encrypted IV, shifting ciphertext octets in instead.  This  \
173    * basically switches over to CFB.                                    \
174    */                                                                   \
175                                                                         \
176   if (sz < PRE##_BLKSZ) {                                               \
177     octet b[PRE##_BLKSZ];                                               \
178     unsigned i;                                                         \
179                                                                         \
180     pre##_eblk(&ctx->ctx, ctx->iv, ctx->iv);                            \
181     BLKC_STORE(PRE, b, ctx->iv);                                        \
182     if (d) {                                                            \
183       for (i = 0; i < sz; i++)                                          \
184         d[i] = b[i] ^ (s ? s[i] : 0);                                   \
185     }                                                                   \
186     memmove(b, b + sz, PRE##_BLKSZ - sz);                               \
187     memcpy(b + PRE##_BLKSZ - sz, d, sz);                                \
188     BLKC_LOAD(PRE, ctx->iv, b);                                         \
189     return;                                                             \
190   }                                                                     \
191                                                                         \
192   /* --- Do the main chunk of encryption --- *                          \
193    *                                                                    \
194    * This will do the whole lot if it's a whole number of blocks.  For  \
195    * each block, XOR it with the previous ciphertext in @iv@, encrypt,  \
196    * and keep a copy of the ciphertext for the next block.              \
197    */                                                                   \
198                                                                         \
199   while (sz >= 2 * PRE##_BLKSZ || sz == PRE##_BLKSZ) {                  \
200     if (s) {                                                            \
201       BLKC_XLOAD(PRE, ctx->iv, s);                                      \
202       s += PRE##_BLKSZ;                                                 \
203     }                                                                   \
204     pre##_eblk(&ctx->ctx, ctx->iv, ctx->iv);                            \
205     if (d) {                                                            \
206       BLKC_STORE(PRE, d, ctx->iv);                                      \
207       d += PRE##_BLKSZ;                                                 \
208     }                                                                   \
209     sz -= PRE##_BLKSZ;                                                  \
210   }                                                                     \
211                                                                         \
212   /* --- Do the tail-end block and bit-left-over --- *                  \
213    *                                                                    \
214    * This isn't very efficient.  That shouldn't matter much.            \
215    */                                                                   \
216                                                                         \
217   if (sz) {                                                             \
218     octet b[PRE##_BLKSZ];                                               \
219     unsigned i;                                                         \
220                                                                         \
221     /* --- Let @sz@ be the size of the partial block --- */             \
222                                                                         \
223     sz -= PRE##_BLKSZ;                                                  \
224                                                                         \
225     /* --- First stage --- *                                            \
226      *                                                                  \
227      * XOR the complete block with the current IV, and encrypt it.  The \
228      * first part of the result is the partial ciphertext block.  Don't \
229      * write that out yet, because I've not read the partial plaintext  \
230      * block.                                                           \
231      */                                                                 \
232                                                                         \
233     if (s) BLKC_XLOAD(PRE, ctx->iv, s);                                 \
234     pre##_eblk(&ctx->ctx, ctx->iv, ctx->iv);                            \
235     BLKC_STORE(PRE, b, ctx->iv);                                        \
236                                                                         \
237     /* --- Second stage --- *                                           \
238      *                                                                  \
239      * Now XOR in the partial plaintext block, writing out the          \
240      * ciphertext as I go.  Then encrypt, and write the complete        \
241      * ciphertext block.                                                \
242      */                                                                 \
243                                                                         \
244     if (s) s += PRE##_BLKSZ;                                            \
245     if (d) d += PRE##_BLKSZ;                                            \
246     for (i = 0; i < sz; i++) {                                          \
247       register octet x = b[i];                                          \
248       if (s) b[i] ^= s[i];                                              \
249       if (d) d[i] = x;                                                  \
250     }                                                                   \
251     BLKC_LOAD(PRE, ctx->iv, b);                                         \
252     pre##_eblk(&ctx->ctx, ctx->iv, ctx->iv);                            \
253     if (d) BLKC_STORE(PRE, d - PRE##_BLKSZ, ctx->iv);                   \
254   }                                                                     \
255                                                                         \
256   /* --- Done --- */                                                    \
257                                                                         \
258   return;                                                               \
259 }                                                                       \
260                                                                         \
261 /* --- @pre_cbcdecrypt@ --- *                                           \
262  *                                                                      \
263  * Arguments:   @pre_cbcctx *ctx@ = pointer to CBC context block        \
264  *              @const void *src@ = pointer to source data              \
265  *              @void *dest@ = pointer to destination data              \
266  *              @size_t sz@ = size of block to be encrypted             \
267  *                                                                      \
268  * Returns:     ---                                                     \
269  *                                                                      \
270  * Use:         Decrypts a block with a block cipher in CBC mode, with  \
271  *              ciphertext stealing and other clever tricks.            \
272  *              Essentially, data can be encrypted in arbitrary sized   \
273  *              chunks, although decryption must use the same chunks.   \
274  */                                                                     \
275                                                                         \
276 void pre##_cbcdecrypt(pre##_cbcctx *ctx,                                \
277                         const void *src, void *dest,                    \
278                         size_t sz)                                      \
279 {                                                                       \
280   const octet *s = src;                                                 \
281   octet *d = dest;                                                      \
282                                                                         \
283   /* --- Empty blocks are trivial --- */                                \
284                                                                         \
285   if (!sz)                                                              \
286     return;                                                             \
287                                                                         \
288   /* --- Extra magical case for a short block --- *                     \
289    *                                                                    \
290    * Encrypt the IV, then exclusive-or the ciphertext with the octets   \
291    * of the encrypted IV, shifting ciphertext octets in instead.  This  \
292    * basically switches over to CFB.                                    \
293    */                                                                   \
294                                                                         \
295   if (sz < PRE##_BLKSZ) {                                               \
296     octet b[PRE##_BLKSZ], c[PRE##_BLKSZ];                               \
297     unsigned i;                                                         \
298                                                                         \
299     pre##_eblk(&ctx->ctx, ctx->iv, ctx->iv);                            \
300     BLKC_STORE(PRE, b, ctx->iv);                                        \
301     for (i = 0; i < sz; i++) {                                          \
302       register octet x = s[i];                                          \
303       d[i] = b[i] ^ x;                                                  \
304       c[i] = x;                                                         \
305     }                                                                   \
306     memmove(b, b + sz, PRE##_BLKSZ - sz);                               \
307     memcpy(b + PRE##_BLKSZ - sz, c, sz);                                \
308     BLKC_LOAD(PRE, ctx->iv, b);                                         \
309     return;                                                             \
310   }                                                                     \
311                                                                         \
312   /* --- Do the main chunk of decryption --- *                          \
313    *                                                                    \
314    * This will do the whole lot if it's a whole number of blocks.  For  \
315    * each block, decrypt, XOR it with the previous ciphertext in @iv@,  \
316    * and keep a copy of the ciphertext for the next block.              \
317    */                                                                   \
318                                                                         \
319   while (sz >= 2 * PRE##_BLKSZ || sz == PRE##_BLKSZ) {                  \
320     uint32 b[PRE##_BLKSZ / 4], niv[PRE##_BLKSZ / 4];                    \
321     BLKC_LOAD(PRE, niv, s);                                             \
322     pre##_dblk(&ctx->ctx, niv, b);                                      \
323     BLKC_XSTORE(PRE, d, b, ctx->iv);                                    \
324     BLKC_MOVE(PRE, ctx->iv, niv);                                       \
325     s += PRE##_BLKSZ;                                                   \
326     d += PRE##_BLKSZ;                                                   \
327     sz -= PRE##_BLKSZ;                                                  \
328   }                                                                     \
329                                                                         \
330   /* --- Do the tail-end block and bit-left-over --- *                  \
331    *                                                                    \
332    * This isn't very efficient.  That shouldn't matter much.            \
333    */                                                                   \
334                                                                         \
335   if (sz) {                                                             \
336     octet b[PRE##_BLKSZ];                                               \
337     uint32 bk[PRE##_BLKSZ / 4], niv[PRE##_BLKSZ / 4];                   \
338     unsigned i;                                                         \
339                                                                         \
340     /* --- Let @sz@ be the size of the partial block --- */             \
341                                                                         \
342     sz -= PRE##_BLKSZ;                                                  \
343                                                                         \
344     /* --- First stage --- *                                            \
345      *                                                                  \
346      * Take the complete ciphertext block, and decrypt it.  This block  \
347      * is carried over for the next encryption operation.               \
348      */                                                                 \
349                                                                         \
350     BLKC_LOAD(PRE, niv, s);                                             \
351     pre##_dblk(&ctx->ctx, niv, bk);                                     \
352                                                                         \
353     /* --- Second stage --- *                                           \
354      *                                                                  \
355      * XORing the first few bytes of this with the partial ciphertext   \
356      * block recovers the partial plaintext block.  At the same time,   \
357      * write the partial ciphertext block's contents in ready for stage \
358      * three.                                                           \
359      */                                                                 \
360                                                                         \
361     BLKC_STORE(PRE, b, bk);                                             \
362     s += PRE##_BLKSZ;                                                   \
363     d += PRE##_BLKSZ;                                                   \
364     for (i = 0; i < sz; i++) {                                          \
365       register octet x = s[i];                                          \
366       d[i] = b[i] ^ x;                                                  \
367       b[i] = x;                                                         \
368     }                                                                   \
369                                                                         \
370     /* --- Third stage --- *                                            \
371      *                                                                  \
372      * Decrypt the block we've got left, and XOR with the initial IV to \
373      * recover the complete plaintext block.                            \
374      */                                                                 \
375                                                                         \
376     BLKC_LOAD(PRE, bk, b);                                              \
377     pre##_dblk(&ctx->ctx, bk, bk);                                      \
378     BLKC_XSTORE(PRE, d - PRE##_BLKSZ, bk, ctx->iv);                     \
379     BLKC_MOVE(PRE, ctx->iv, niv);                                       \
380   }                                                                     \
381                                                                         \
382   /* --- Done --- */                                                    \
383                                                                         \
384   return;                                                               \
385 }                                                                       \
386                                                                         \
387 /* --- Generic cipher interface --- */                                  \
388                                                                         \
389 static const gcipher_ops gops;                                          \
390                                                                         \
391 typedef struct gctx {                                                   \
392   gcipher c;                                                            \
393   pre##_cbcctx k;                                                       \
394 } gctx;                                                                 \
395                                                                         \
396 static gcipher *ginit(const void *k, size_t sz)                         \
397 {                                                                       \
398   gctx *g = S_CREATE(gctx);                                             \
399   g->c.ops = &gops;                                                     \
400   pre##_cbcinit(&g->k, k, sz, 0);                                       \
401   return (&g->c);                                                       \
402 }                                                                       \
403                                                                         \
404 static void gencrypt(gcipher *c, const void *s, void *t, size_t sz)     \
405 {                                                                       \
406   gctx *g = (gctx *)c;                                                  \
407   pre##_cbcencrypt(&g->k, s, t, sz);                                    \
408 }                                                                       \
409                                                                         \
410 static void gdecrypt(gcipher *c, const void *s, void *t, size_t sz)     \
411 {                                                                       \
412   gctx *g = (gctx *)c;                                                  \
413   pre##_cbcdecrypt(&g->k, s, t, sz);                                    \
414 }                                                                       \
415                                                                         \
416 static void gdestroy(gcipher *c)                                        \
417 {                                                                       \
418   gctx *g = (gctx *)c;                                                  \
419   BURN(*g);                                                             \
420   S_DESTROY(g);                                                         \
421 }                                                                       \
422                                                                         \
423 static void gsetiv(gcipher *c, const void *iv)                          \
424 {                                                                       \
425   gctx *g = (gctx *)c;                                                  \
426   pre##_cbcsetiv(&g->k, iv);                                            \
427 }                                                                       \
428                                                                         \
429 static const gcipher_ops gops = {                                       \
430   &pre##_cbc,                                                           \
431   gencrypt, gdecrypt, gdestroy, gsetiv, 0                               \
432 };                                                                      \
433                                                                         \
434 const gccipher pre##_cbc = {                                            \
435   name "-cbc", pre##_keysz, PRE##_BLKSZ,                                \
436   ginit                                                                 \
437 };                                                                      \
438                                                                         \
439 CBC_TESTX(PRE, pre, name, fname)
440
441 /*----- Test rig ----------------------------------------------------------*/
442
443 #define CBC_TEST(PRE, pre) CBC_TESTX(PRE, pre, #pre, #pre)
444
445 #ifdef TEST_RIG
446
447 #include <stdio.h>
448
449 #include "daftstory.h"
450
451 /* --- @CBC_TEST@ --- *
452  *
453  * Arguments:   @PRE@, @pre@ = prefixes for block cipher definitions
454  *
455  * Use:         Standard test rig for CBC functions.
456  */
457
458 #define CBC_TESTX(PRE, pre, name, fname)                                \
459                                                                         \
460 /* --- Initial plaintext for the test --- */                            \
461                                                                         \
462 static const octet text[] = TEXT;                                       \
463                                                                         \
464 /* --- Key and IV to use --- */                                         \
465                                                                         \
466 static const octet key[] = KEY;                                         \
467 static const octet iv[] = IV;                                           \
468                                                                         \
469 /* --- Buffers for encryption and decryption output --- */              \
470                                                                         \
471 static octet ct[sizeof(text)];                                          \
472 static octet pt[sizeof(text)];                                          \
473                                                                         \
474 static void hexdump(const octet *p, size_t sz, size_t off)              \
475 {                                                                       \
476   const octet *q = p + sz;                                              \
477   for (sz = 0; p < q; p++, sz++) {                                      \
478     printf("%02x", *p);                                                 \
479     if ((off + sz + 1) % PRE##_BLKSZ == 0)                              \
480       putchar(':');                                                     \
481   }                                                                     \
482 }                                                                       \
483                                                                         \
484 int main(void)                                                          \
485 {                                                                       \
486   size_t sz = 0, rest;                                                  \
487   pre##_cbcctx ctx;                                                     \
488   pre##_ctx k;                                                          \
489   int status = 0;                                                       \
490   int done = 0;                                                         \
491                                                                         \
492   size_t keysz = PRE##_KEYSZ ?                                          \
493     PRE##_KEYSZ : strlen((const char *)key);                            \
494                                                                         \
495   fputs(name "-cbc: ", stdout);                                         \
496                                                                         \
497   pre##_init(&k, key, keysz);                                           \
498   pre##_cbcsetkey(&ctx, &k);                                            \
499                                                                         \
500   while (sz <= sizeof(text)) {                                          \
501     rest = sizeof(text) - sz;                                           \
502     memcpy(ct, text, sizeof(text));                                     \
503     pre##_cbcsetiv(&ctx, iv);                                           \
504     pre##_cbcencrypt(&ctx, ct, ct, sz);                                 \
505     pre##_cbcencrypt(&ctx, ct + sz, ct + sz, rest);                     \
506     memcpy(pt, ct, sizeof(text));                                       \
507     pre##_cbcsetiv(&ctx, iv);                                           \
508     pre##_cbcdecrypt(&ctx, pt, pt, sz);                                 \
509     pre##_cbcdecrypt(&ctx, pt + sz, pt + sz, rest);                     \
510     if (memcmp(pt, text, sizeof(text)) == 0) {                          \
511       done++;                                                           \
512       if (sizeof(text) < 40 || done % 8 == 0)                           \
513         fputc('.', stdout);                                             \
514       if (done % 480 == 0)                                              \
515         fputs("\n\t", stdout);                                          \
516       fflush(stdout);                                                   \
517     } else {                                                            \
518       printf("\nError (sz = %lu)\n", (unsigned long)sz);                \
519       status = 1;                                                       \
520       printf("\tplaintext      = "); hexdump(text, sz, 0);              \
521         printf(", "); hexdump(text + sz, rest, sz);                     \
522         fputc('\n', stdout);                                            \
523       printf("\tciphertext     = "); hexdump(ct, sz, 0);                \
524         printf(", "); hexdump(ct + sz, rest, sz);                       \
525         fputc('\n', stdout);                                            \
526       printf("\trecovered text = "); hexdump(pt, sz, 0);                \
527         printf(", "); hexdump(pt + sz, rest, sz);                       \
528         fputc('\n', stdout);                                            \
529       fputc('\n', stdout);                                              \
530     }                                                                   \
531     if (sz < 63)                                                        \
532       sz++;                                                             \
533     else                                                                \
534       sz += 9;                                                          \
535   }                                                                     \
536                                                                         \
537   fputs(status ? " failed\n" : " ok\n", stdout);                        \
538   return (status);                                                      \
539 }
540
541 #else
542 #  define CBC_TESTX(PRE, pre, name, fname)
543 #endif
544
545 /*----- That's all, folks -------------------------------------------------*/
546
547 #ifdef __cplusplus
548   }
549 #endif
550
551 #endif