/* -*-c-*-
*
- * $Id: blkc.h,v 1.1 1999/09/03 08:41:11 mdw Exp $
+ * $Id: blkc.h,v 1.3 2000/06/17 10:47:06 mdw Exp $
*
* Common definitions for block ciphers
*
/*----- Revision history --------------------------------------------------*
*
* $Log: blkc.h,v $
+ * Revision 1.3 2000/06/17 10:47:06 mdw
+ * Slight support for 96-bit ciphers. Support for counter-mode ciphers.
+ *
+ * Revision 1.2 1999/12/10 23:29:48 mdw
+ * Change header file guard names.
+ *
* Revision 1.1 1999/09/03 08:41:11 mdw
* Initial import.
*
*/
-#ifndef BLKC_H
-#define BLKC_H
+#ifndef CATACOMB_BLKC_H
+#define CATACOMB_BLKC_H
#ifdef __cplusplus
extern "C" {
/*----- Header files ------------------------------------------------------*/
+#include <assert.h>
+
#include <mLib/bits.h>
/*----- Theory of operation -----------------------------------------------*
#define BLKC_FIRST(x, y, z) x
#define BLKC_SECOND(x, y, z) y
#define BLKC_THIRD(x, y, z) z
-#define BLKC_TYPE(PRE) BLKC_APPLY(BLKC_FIRST, PRE ## _CLASS)
-#define BLKC_ENDIAN(PRE) BLKC_APPLY(BLKC_SECOND, PRE ## _CLASS)
-#define BLKC_BITS(PRE) BLKC_APPLY(BLKC_THIRD, PRE ## _CLASS)
+#define BLKC_TYPE(PRE) BLKC_APPLY(BLKC_FIRST, PRE##_CLASS)
+#define BLKC_ENDIAN(PRE) BLKC_APPLY(BLKC_SECOND, PRE##_CLASS)
+#define BLKC_BITS(PRE) BLKC_APPLY(BLKC_THIRD, PRE##_CLASS)
#define BLKC_STORE_E(PRE) BLKC_GLUE(STORE32_, BLKC_ENDIAN(PRE))
#define BLKC_LOAD_E(PRE) BLKC_GLUE(LOAD32_, BLKC_ENDIAN(PRE))
BLKC_GLUE(BLKC_XMOVE_, BLKC_TYPE(PRE)) \
(PRE, w, wx, BLKC_BITS(PRE))
+#define BLKC_STEP(PRE, w) \
+ BLKC_GLUE(BLKC_STEP_X_, BLKC_ENDIAN(PRE)) \
+ (PRE, w)
+
+#define BLKC_SET(PRE, w, x) \
+ BLKC_GLUE(BLKC_SET_X_, BLKC_ENDIAN(PRE)) \
+ (PRE, w, x)
+
+#define BLKC_SHOW(PRE, tag, w) do { \
+ fputs(tag ": ", stdout); \
+ BLKC_SKEL_X(PRE, BLKC_W(w);, printf("%08x ", *_w++);); \
+ fputc('\n', stdout); \
+} while (0)
+
/* --- General implementation skeleton --- */
#define BLKC_SKEL(PRE, decl, guts) do { \
#define BLKC_P(p) register octet *_p = (octet *)(p)
#define BLKC_W(w) register uint32 *_w = (w)
-#define BLKC_WX(wx) register uint32 *_wx = (wx);
+#define BLKC_WX(wx) register uint32 *_wx = (wx)
/* --- Implementation for unusual block sizes --- */
#define BLKC_SKEL_X(PRE, decl, guts) \
- BLKC_SKEL(PRE, int _i; decl, \
- for (_i = 0; _i < PRE ## _BLKSZ / 4; _i++) { \
+ BLKC_SKEL(PRE, unsigned _i; decl, \
+ for (_i = 0; _i < PRE##_BLKSZ / 4; _i++) { \
guts \
})
BLKC_SKEL_X(PRE, BLKC_W(w); const BLKC_WX(wx);, \
*_w ^= *_wx; _w++; _wx++; ) \
+#define BLKC_STEP_X_B(PRE, w) do { \
+ unsigned _i = PRE##_BLKSZ / 4; BLKC_W(w); uint32 _x = 0; \
+ while (_i && !_x) { _i--; _w[_i] = _x = U32(_w[_i] + 1); } \
+} while (0)
+
+#define BLKC_STEP_X_L(PRE, w) do { \
+ unsigned _i = 0; BLKC_W(w); uint32 _x = 0; \
+ while (_i < PRE##_BLKSZ / 4 && !_x) \
+ { _w[_i] = _x = U32(_w[_i] + 1); _i++; } \
+} while (0)
+
+#define BLKC_SET_X_B(PRE, w, x) do { \
+ unsigned _i; BLKC_W(w); unsigned long _x = x; \
+ for (_i = 0; _i < PRE##_BLKSZ / 4; _i++) { \
+ *_w++ = U32(_x); \
+ _x = ((_x & ~MASK32) >> 16) >> 16; \
+ } \
+} while (0)
+
+#define BLKC_SET_X_L(PRE, w, x) do { \
+ unsigned _i; BLKC_W(w); unsigned long _x = x; _w += PRE##_BLKSZ / 4; \
+ for (_i = 0; _i < PRE##_BLKSZ / 4; _i++) { \
+ *--_w = U32(_x); \
+ _x = ((_x & ~MASK32) >> 16) >> 16; \
+ } \
+} while (0)
+
/* --- Implementation for known block sizes --- */
#define BLKC_SKEL_64(PRE, decl, op, guts) \
BLKC_SKEL(PRE, decl, guts(op, 0); guts(op, 1);)
+#define BLKC_SKEL_96(PRE, decl, op, guts) \
+ BLKC_SKEL(PRE, decl, guts(op, 0); guts(op, 1); guts(op, 2);)
+
#define BLKC_SKEL_128(PRE, decl, op, guts) \
BLKC_SKEL(PRE, decl, guts(op, 0); guts(op, 1); guts(op, 2); guts(op, 3);)
\
static int verify(dstr *v) \
{ \
- pre ## _ctx k; \
- uint32 p[PRE ## _BLKSZ / 4]; \
- uint32 c[PRE ## _BLKSZ / 4]; \
- uint32 d[PRE ## _BLKSZ / 4]; \
+ pre##_ctx k; \
+ uint32 p[PRE##_BLKSZ / 4]; \
+ uint32 c[PRE##_BLKSZ / 4]; \
+ uint32 d[PRE##_BLKSZ / 4]; \
dstr b = DSTR_INIT; \
int ok = 1; \
\
/* --- Initialize the key buffer --- */ \
\
- dstr_ensure(&b, PRE ## _BLKSZ); \
- b.len = PRE ## _BLKSZ; \
- pre ## _init(&k, v[0].buf, v[0].len); \
+ dstr_ensure(&b, PRE##_BLKSZ); \
+ b.len = PRE##_BLKSZ; \
+ pre##_init(&k, v[0].buf, v[0].len); \
BLKC_LOAD(PRE, p, v[1].buf); \
BLKC_LOAD(PRE, c, v[2].buf); \
\
/* --- Test encryption --- */ \
\
BLKC_MOVE(PRE, d, p); \
- pre ## _eblk(&k, d, d); \
+ pre##_eblk(&k, d, d); \
BLKC_STORE(PRE, b.buf, d); \
- if (memcmp(b.buf, v[2].buf, PRE ## _BLKSZ)) { \
+ if (memcmp(b.buf, v[2].buf, PRE##_BLKSZ)) { \
ok = 0; \
printf("\nfail encryption:" \
"\n\tkey = "); \
/* --- Test decryption --- */ \
\
BLKC_MOVE(PRE, d, c); \
- pre ## _dblk(&k, d, d); \
+ pre##_dblk(&k, d, d); \
BLKC_STORE(PRE, b.buf, d); \
- if (memcmp(b.buf, v[1].buf, PRE ## _BLKSZ)) { \
+ if (memcmp(b.buf, v[1].buf, PRE##_BLKSZ)) { \
ok = 0; \
printf("\nfail decryption:" \
"\n\tkey = "); \