/* -*-c-*-
*
- * $Id: rijndael.c,v 1.2 2000/12/06 20:32:59 mdw Exp $
+ * $Id: rijndael.c,v 1.3 2001/05/07 15:44:46 mdw Exp $
*
* The Rijndael block cipher
*
/*----- Revision history --------------------------------------------------*
*
* $Log: rijndael.c,v $
+ * Revision 1.3 2001/05/07 15:44:46 mdw
+ * Fix unusual numbers of rounds. Simplify implementation.
+ *
* Revision 1.2 2000/12/06 20:32:59 mdw
* Fix round count for weird key sizes.
*
/*----- Main code ---------------------------------------------------------*/
-#define BYTESUB(x, s) \
- (s[U8((x) >> 24)] << 24 | s[U8((x) >> 16)] << 16 | \
- s[U8((x) >> 8)] << 8 | s[U8((x) >> 0)] << 0)
+#define SUB(s, a, b, c, d) \
+ (s[U8((a) >> 0)] << 0 | s[U8((b) >> 8)] << 8 | \
+ s[U8((c) >> 16)] << 16 | s[U8((d) >> 24)] << 24)
+
+#define MIX(t, a, b, c, d) \
+ (t[0][U8((a) >> 0)] ^ t[1][U8((b) >> 8)] ^ \
+ t[2][U8((c) >> 16)] ^ t[3][U8((d) >> 24)])
/* --- @rijndael_init@ --- *
*
uint32 w = k->w[i - nk];
if (i % nk == 0) {
ww = ROR32(ww, 8);
- w ^= BYTESUB(ww, S) ^ *p++;
+ w ^= SUB(S, ww, ww, ww, ww) ^ *p++;
} else if (nk > 6 && i % nk == 4)
- w ^= BYTESUB(ww, S);
+ w ^= SUB(S, ww, ww, ww, ww);
else
w ^= ww;
k->w[i] = ww = w;
j -= RIJNDAEL_BLKSZ / 4;
for (jj = 0; jj < RIJNDAEL_BLKSZ / 4; jj++) {
uint32 w = k->w[j + jj];
- k->wi[i + jj] = (U[0][U8(w >> 0)] ^ U[1][U8(w >> 8)] ^
- U[2][U8(w >> 16)] ^ U[3][U8(w >> 24)]);
+ k->wi[i + jj] = MIX(U, w, w, w, w);
}
}
* Use: Low-level block encryption and decryption.
*/
-#define EROUND(aa, bb, cc, dd, a, b, c, d, w) do { \
- aa = (T[0][U8(a >> 0)] ^ T[1][U8(b >> 8)] ^ \
- T[2][U8(c >> 16)] ^ T[3][U8(d >> 24)]) ^ *w++; \
- bb = (T[0][U8(b >> 0)] ^ T[1][U8(c >> 8)] ^ \
- T[2][U8(d >> 16)] ^ T[3][U8(a >> 24)]) ^ *w++; \
- cc = (T[0][U8(c >> 0)] ^ T[1][U8(d >> 8)] ^ \
- T[2][U8(a >> 16)] ^ T[3][U8(b >> 24)]) ^ *w++; \
- dd = (T[0][U8(d >> 0)] ^ T[1][U8(a >> 8)] ^ \
- T[2][U8(b >> 16)] ^ T[3][U8(c >> 24)]) ^ *w++; \
+#define DO(what, t, aa, bb, cc, dd, a, b, c, d, w) do { \
+ aa = what(t, a, b, c, d) ^ *w++; \
+ bb = what(t, b, c, d, a) ^ *w++; \
+ cc = what(t, c, d, a, b) ^ *w++; \
+ dd = what(t, d, a, b, c) ^ *w++; \
} while (0)
-#define DROUND(aa, bb, cc, dd, a, b, c, d, w) do { \
- aa = (TI[0][U8(a >> 0)] ^ TI[1][U8(d >> 8)] ^ \
- TI[2][U8(c >> 16)] ^ TI[3][U8(b >> 24)]) ^ *w++; \
- bb = (TI[0][U8(b >> 0)] ^ TI[1][U8(a >> 8)] ^ \
- TI[2][U8(d >> 16)] ^ TI[3][U8(c >> 24)]) ^ *w++; \
- cc = (TI[0][U8(c >> 0)] ^ TI[1][U8(b >> 8)] ^ \
- TI[2][U8(a >> 16)] ^ TI[3][U8(d >> 24)]) ^ *w++; \
- dd = (TI[0][U8(d >> 0)] ^ TI[1][U8(c >> 8)] ^ \
- TI[2][U8(b >> 16)] ^ TI[3][U8(a >> 24)]) ^ *w++; \
+#define UNDO(what, t, aa, bb, cc, dd, a, b, c, d, w) do { \
+ aa = what(t, a, d, c, b) ^ *w++; \
+ bb = what(t, b, a, d, c) ^ *w++; \
+ cc = what(t, c, b, a, d) ^ *w++; \
+ dd = what(t, d, c, b, a) ^ *w++; \
} while (0)
void rijndael_eblk(const rijndael_ctx *k, const uint32 *s, uint32 *dst)
uint32 *w = k->w;
a ^= *w++; b ^= *w++; c ^= *w++; d ^= *w++;
+ aa = a; bb = b; cc = c; dd = d;
switch (k->nr) {
case 14:
- EROUND(aa, bb, cc, dd, a, b, c, d, w);
- EROUND(a, b, c, d, aa, bb, cc, dd, w);
+ DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
+ case 13:
+ DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
case 12:
- EROUND(aa, bb, cc, dd, a, b, c, d, w);
- EROUND(a, b, c, d, aa, bb, cc, dd, w);
+ DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
+ case 11:
+ DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
case 10:
default:
- EROUND(aa, bb, cc, dd, a, b, c, d, w);
- EROUND(a, b, c, d, aa, bb, cc, dd, w);
- EROUND(aa, bb, cc, dd, a, b, c, d, w);
- EROUND(a, b, c, d, aa, bb, cc, dd, w);
- EROUND(aa, bb, cc, dd, a, b, c, d, w);
- EROUND(a, b, c, d, aa, bb, cc, dd, w);
- EROUND(aa, bb, cc, dd, a, b, c, d, w);
- EROUND(a, b, c, d, aa, bb, cc, dd, w);
- EROUND(aa, bb, cc, dd, a, b, c, d, w);
+ DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
+ DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
+ DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
+ DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
+ DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
+ DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
+ DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
+ DO(MIX, T, a, b, c, d, aa, bb, cc, dd, w);
+ DO(MIX, T, aa, bb, cc, dd, a, b, c, d, w);
}
-
- a = ((S[U8(aa >> 0)] << 0) ^ (S[U8(bb >> 8)] << 8) ^
- (S[U8(cc >> 16)] << 16) ^ (S[U8(dd >> 24)] << 24)) ^ *w++;
- b = ((S[U8(bb >> 0)] << 0) ^ (S[U8(cc >> 8)] << 8) ^
- (S[U8(dd >> 16)] << 16) ^ (S[U8(aa >> 24)] << 24)) ^ *w++;
- c = ((S[U8(cc >> 0)] << 0) ^ (S[U8(dd >> 8)] << 8) ^
- (S[U8(aa >> 16)] << 16) ^ (S[U8(bb >> 24)] << 24)) ^ *w++;
- d = ((S[U8(dd >> 0)] << 0) ^ (S[U8(aa >> 8)] << 8) ^
- (S[U8(bb >> 16)] << 16) ^ (S[U8(cc >> 24)] << 24)) ^ *w++;
+ DO(SUB, S, a, b, c, d, aa, bb, cc, dd, w);
dst[0] = a; dst[1] = b; dst[2] = c; dst[3] = d;
}
uint32 *w = k->wi;
a ^= *w++; b ^= *w++; c ^= *w++; d ^= *w++;
+ aa = a; bb = b; cc = c; dd = d;
switch (k->nr) {
case 14:
- DROUND(aa, bb, cc, dd, a, b, c, d, w);
- DROUND(a, b, c, d, aa, bb, cc, dd, w);
+ UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
+ case 13:
+ UNDO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
case 12:
- DROUND(aa, bb, cc, dd, a, b, c, d, w);
- DROUND(a, b, c, d, aa, bb, cc, dd, w);
+ UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
+ case 11:
+ UNDO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
case 10:
default:
- DROUND(aa, bb, cc, dd, a, b, c, d, w);
- DROUND(a, b, c, d, aa, bb, cc, dd, w);
- DROUND(aa, bb, cc, dd, a, b, c, d, w);
- DROUND(a, b, c, d, aa, bb, cc, dd, w);
- DROUND(aa, bb, cc, dd, a, b, c, d, w);
- DROUND(a, b, c, d, aa, bb, cc, dd, w);
- DROUND(aa, bb, cc, dd, a, b, c, d, w);
- DROUND(a, b, c, d, aa, bb, cc, dd, w);
- DROUND(aa, bb, cc, dd, a, b, c, d, w);
+ UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
+ UNDO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
+ UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
+ UNDO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
+ UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
+ UNDO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
+ UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
+ UNDO(MIX, TI, a, b, c, d, aa, bb, cc, dd, w);
+ UNDO(MIX, TI, aa, bb, cc, dd, a, b, c, d, w);
}
-
- a = ((SI[U8(aa >> 0)] << 0) ^ (SI[U8(dd >> 8)] << 8) ^
- (SI[U8(cc >> 16)] << 16) ^ (SI[U8(bb >> 24)] << 24)) ^ *w++;
- b = ((SI[U8(bb >> 0)] << 0) ^ (SI[U8(aa >> 8)] << 8) ^
- (SI[U8(dd >> 16)] << 16) ^ (SI[U8(cc >> 24)] << 24)) ^ *w++;
- c = ((SI[U8(cc >> 0)] << 0) ^ (SI[U8(bb >> 8)] << 8) ^
- (SI[U8(aa >> 16)] << 16) ^ (SI[U8(dd >> 24)] << 24)) ^ *w++;
- d = ((SI[U8(dd >> 0)] << 0) ^ (SI[U8(cc >> 8)] << 8) ^
- (SI[U8(bb >> 16)] << 16) ^ (SI[U8(aa >> 24)] << 24)) ^ *w++;
+ UNDO(SUB, SI, a, b, c, d, aa, bb, cc, dd, w);
dst[0] = a; dst[1] = b; dst[2] = c; dst[3] = d;
}