Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

rijndael, optimized version 2.4

  • Loading branch information...
commit d1bf839b84e18cd5a7dc5670657979a8946c2173 1 parent c43b1a7
itojun authored
View
43 kame/sys/crypto/rijndael/boxes-fst.dat
@@ -1,41 +1,3 @@
-word8 Logtable[256] = {
- 0, 0, 25, 1, 50, 2, 26, 198, 75, 199, 27, 104, 51, 238, 223, 3,
-100, 4, 224, 14, 52, 141, 129, 239, 76, 113, 8, 200, 248, 105, 28, 193,
-125, 194, 29, 181, 249, 185, 39, 106, 77, 228, 166, 114, 154, 201, 9, 120,
-101, 47, 138, 5, 33, 15, 225, 36, 18, 240, 130, 69, 53, 147, 218, 142,
-150, 143, 219, 189, 54, 208, 206, 148, 19, 92, 210, 241, 64, 70, 131, 56,
-102, 221, 253, 48, 191, 6, 139, 98, 179, 37, 226, 152, 34, 136, 145, 16,
-126, 110, 72, 195, 163, 182, 30, 66, 58, 107, 40, 84, 250, 133, 61, 186,
- 43, 121, 10, 21, 155, 159, 94, 202, 78, 212, 172, 229, 243, 115, 167, 87,
-175, 88, 168, 80, 244, 234, 214, 116, 79, 174, 233, 213, 231, 230, 173, 232,
- 44, 215, 117, 122, 235, 22, 11, 245, 89, 203, 95, 176, 156, 169, 81, 160,
-127, 12, 246, 111, 23, 196, 73, 236, 216, 67, 31, 45, 164, 118, 123, 183,
-204, 187, 62, 90, 251, 96, 177, 134, 59, 82, 161, 108, 170, 85, 41, 157,
-151, 178, 135, 144, 97, 190, 220, 252, 188, 149, 207, 205, 55, 63, 91, 209,
- 83, 57, 132, 60, 65, 162, 109, 71, 20, 42, 158, 93, 86, 242, 211, 171,
- 68, 17, 146, 217, 35, 32, 46, 137, 180, 124, 184, 38, 119, 153, 227, 165,
-103, 74, 237, 222, 197, 49, 254, 24, 13, 99, 140, 128, 192, 247, 112, 7
-};
-
-word8 Alogtable[256] = {
- 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53,
- 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170,
-229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49,
- 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205,
- 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136,
-131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154,
-181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
-254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160,
-251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65,
-195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117,
-159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128,
-155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84,
-252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202,
- 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
- 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23,
- 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1
-};
-
word8 S[256] = {
99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118,
202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192,
@@ -55,6 +17,7 @@ word8 S[256] = {
140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22
};
+#ifdef INTERMEDIATE_VALUE_KAT
word8 Si[256] = {
82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251,
124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203,
@@ -73,6 +36,7 @@ word8 Si[256] = {
160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97,
23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125
};
+#endif /* INTERMEDIATE_VALUE_KAT */
word8 T1[256][4] = {
0xc6,0x63,0x63,0xa5, 0xf8,0x7c,0x7c,0x84, 0xee,0x77,0x77,0x99, 0xf6,0x7b,0x7b,0x8d,
@@ -946,4 +910,5 @@ word8 U4[256][4] = {
};
word32 rcon[30] = {
- 0x01,0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 };
+ 0x01,0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
+};
View
563 kame/sys/crypto/rijndael/rijndael-alg-fst.c
@@ -1,7 +1,13 @@
-/* rijndael-alg-fst.c v2.0 August '99
+/*
+ * rijndael-alg-fst.c v2.3 April '2000
+ *
* Optimised ANSI C code
+ *
* authors: v1.0: Antoon Bosselaers
* v2.0: Vincent Rijmen
+ * v2.3: Paulo Barreto
+ *
+ * This code is placed in the public domain.
*/
#include <stdio.h>
@@ -9,130 +15,33 @@
#include "rijndael-alg-fst.h"
-#define SC ((BC - 4) >> 1)
-
#include "boxes-fst.dat"
-static word8 shifts[3][4][2] = {
- 0, 0,
- 1, 3,
- 2, 2,
- 3, 1,
-
- 0, 0,
- 1, 5,
- 2, 4,
- 3, 3,
-
- 0, 0,
- 1, 7,
- 3, 5,
- 4, 4
-};
-
-
-word8 mul(word8 a, word8 b) {
- /* multiply two elements of GF(2^m)
- * needed for MixColumn and InvMixColumn
- */
- if (a && b)
- return Alogtable[(Logtable[a] + Logtable[b])%255];
- else
- return 0;
-}
-
-void KeyAddition(word8 a[4][4], word8 rk[4][4], word8 BC) {
- /* Exor corresponding text input and round key input bytes
- */
- int i, j;
-
- for(i = 0; i < BC; i++)
- for(j = 0; j < 4; j++)
- a[i][j] ^= rk[i][j];
-}
-
-void ShiftRow(word8 a[4][4], word8 d, word8 BC) {
- /* Row 0 remains unchanged
- * The other three rows are shifted a variable amount
- */
- word8 tmp[4];
- int i, j;
-
- for(i = 1; i < 4; i++) {
- for(j = 0; j < BC; j++)
- tmp[j] = a[(j + shifts[SC][i][d]) % BC][i];
- for(j = 0; j < BC; j++)
- a[j][i] = tmp[j];
- }
-}
-
-void Substitution(word8 a[4][4], word8 box[256], word8 BC) {
- /* Replace every byte of the input by the byte at that place
- * in the nonlinear S-box
- */
- int i, j;
-
- for(i = 0; i < BC; i++)
- for(j = 0; j < 4; j++)
- a[i][j] = box[a[i][j]] ;
-}
-
-void MixColumn(word8 a[4][4], word8 BC) {
- /* Mix the four bytes of every column in a linear way
- */
- word8 b[4][4];
- int i, j;
-
- for(j = 0; j < BC; j++)
- for(i = 0; i < 4; i++)
- b[j][i] = mul(2,a[j][i])
- ^ mul(3,a[j][(i + 1) % 4])
- ^ a[j][(i + 2) % 4]
- ^ a[j][(i + 3) % 4];
- for(i = 0; i < 4; i++)
- for(j = 0; j < BC; j++)
- a[j][i] = b[j][i];
-}
-
-void InvMixColumn(word8 a[4][4], word8 BC) {
- /* Mix the four bytes of every column in a linear way
- * This is the opposite operation of Mixcolumn
- */
- int j;
-
- for(j = 0; j < BC; j++)
- *((word32*)a[j]) = *((word32*)U1[a[j][0]])
- ^ *((word32*)U2[a[j][1]])
- ^ *((word32*)U3[a[j][2]])
- ^ *((word32*)U4[a[j][3]]);
-
-
-}
-
-int rijndaelKeySched (word8 k[MAXKC][4], int keyBits, word8 W[MAXROUNDS+1][4][4])
-{
+int rijndaelKeySched(word8 k[MAXKC][4], word8 W[MAXROUNDS+1][4][4], int ROUNDS) {
/* Calculate the necessary round keys
* The number of calculations depends on keyBits and blockBits
*/
int j, r, t, rconpointer = 0;
word8 tk[MAXKC][4];
int KC = ROUNDS - 6;
-
- for(j = KC-1; j >= 0; j--)
+
+ for (j = KC-1; j >= 0; j--) {
*((word32*)tk[j]) = *((word32*)k[j]);
+ }
r = 0;
t = 0;
/* copy values into round key array */
- for(j = 0; (j < KC) && (r < (ROUNDS+1)); ) {
- for (; (j < KC) && (t < 4); j++, t++)
+ for (j = 0; (j < KC) && (r < ROUNDS + 1); ) {
+ for (; (j < KC) && (t < 4); j++, t++) {
*((word32*)W[r][t]) = *((word32*)tk[j]);
+ }
if (t == 4) {
r++;
t = 0;
}
}
- while (r < (ROUNDS+1)) { /* while not enough round key material calculated */
+ while (r < ROUNDS + 1) { /* while not enough round key material calculated */
/* calculate new values */
tk[0][0] ^= S[tk[KC-1][1]];
tk[0][1] ^= S[tk[KC-1][2]];
@@ -140,140 +49,171 @@ int rijndaelKeySched (word8 k[MAXKC][4], int keyBits, word8 W[MAXROUNDS+1][4][4]
tk[0][3] ^= S[tk[KC-1][0]];
tk[0][0] ^= rcon[rconpointer++];
- if (KC != 8)
- for(j = 1; j < KC; j++)
+ if (KC != 8) {
+ for (j = 1; j < KC; j++) {
*((word32*)tk[j]) ^= *((word32*)tk[j-1]);
- else {
- for(j = 1; j < KC/2; j++)
+ }
+ } else {
+ for (j = 1; j < KC/2; j++) {
*((word32*)tk[j]) ^= *((word32*)tk[j-1]);
+ }
tk[KC/2][0] ^= S[tk[KC/2 - 1][0]];
tk[KC/2][1] ^= S[tk[KC/2 - 1][1]];
tk[KC/2][2] ^= S[tk[KC/2 - 1][2]];
tk[KC/2][3] ^= S[tk[KC/2 - 1][3]];
- for(j = KC/2 + 1; j < KC; j++)
+ for (j = KC/2 + 1; j < KC; j++) {
*((word32*)tk[j]) ^= *((word32*)tk[j-1]);
+ }
}
/* copy values into round key array */
- for(j = 0; (j < KC) && (r < (ROUNDS+1)); ) {
- for (; (j < KC) && (t < 4); j++, t++)
+ for (j = 0; (j < KC) && (r < ROUNDS + 1); ) {
+ for (; (j < KC) && (t < 4); j++, t++) {
*((word32*)W[r][t]) = *((word32*)tk[j]);
+ }
if (t == 4) {
r++;
t = 0;
}
}
}
-
return 0;
}
-int rijndaelKeyEnctoDec (int keyBits, word8 W[MAXROUNDS+1][4][4])
-{
+int rijndaelKeyEncToDec(word8 W[MAXROUNDS+1][4][4], int ROUNDS) {
int r;
+ word8 *w;
for (r = 1; r < ROUNDS; r++) {
- InvMixColumn(W[r], 4);
+ w = W[r][0];
+ *((word32*)w) =
+ *((word32*)U1[w[0]])
+ ^ *((word32*)U2[w[1]])
+ ^ *((word32*)U3[w[2]])
+ ^ *((word32*)U4[w[3]]);
+
+ w = W[r][1];
+ *((word32*)w) =
+ *((word32*)U1[w[0]])
+ ^ *((word32*)U2[w[1]])
+ ^ *((word32*)U3[w[2]])
+ ^ *((word32*)U4[w[3]]);
+
+ w = W[r][2];
+ *((word32*)w) =
+ *((word32*)U1[w[0]])
+ ^ *((word32*)U2[w[1]])
+ ^ *((word32*)U3[w[2]])
+ ^ *((word32*)U4[w[3]]);
+
+ w = W[r][3];
+ *((word32*)w) =
+ *((word32*)U1[w[0]])
+ ^ *((word32*)U2[w[1]])
+ ^ *((word32*)U3[w[2]])
+ ^ *((word32*)U4[w[3]]);
}
return 0;
}
-int rijndaelEncrypt (word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4])
-{
- /* Encryption of one block.
- */
+/**
+ * Encrypt a single block.
+ */
+int rijndaelEncrypt(word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4], int ROUNDS) {
int r;
- word8 temp[4][4];
+ word8 temp[4][4];
- *((word32*)temp[0]) = *((word32*)a) ^ *((word32*)rk[0][0]);
- *((word32*)temp[1]) = *((word32*)(a+4)) ^ *((word32*)rk[0][1]);
- *((word32*)temp[2]) = *((word32*)(a+8)) ^ *((word32*)rk[0][2]);
+ *((word32*)temp[0]) = *((word32*)(a )) ^ *((word32*)rk[0][0]);
+ *((word32*)temp[1]) = *((word32*)(a+ 4)) ^ *((word32*)rk[0][1]);
+ *((word32*)temp[2]) = *((word32*)(a+ 8)) ^ *((word32*)rk[0][2]);
*((word32*)temp[3]) = *((word32*)(a+12)) ^ *((word32*)rk[0][3]);
- *((word32*)b) = *((word32*)T1[temp[0][0]])
- ^ *((word32*)T2[temp[1][1]])
- ^ *((word32*)T3[temp[2][2]])
- ^ *((word32*)T4[temp[3][3]]);
- *((word32*)(b+4)) = *((word32*)T1[temp[1][0]])
- ^ *((word32*)T2[temp[2][1]])
- ^ *((word32*)T3[temp[3][2]])
- ^ *((word32*)T4[temp[0][3]]);
- *((word32*)(b+8)) = *((word32*)T1[temp[2][0]])
- ^ *((word32*)T2[temp[3][1]])
- ^ *((word32*)T3[temp[0][2]])
- ^ *((word32*)T4[temp[1][3]]);
- *((word32*)(b+12)) = *((word32*)T1[temp[3][0]])
- ^ *((word32*)T2[temp[0][1]])
- ^ *((word32*)T3[temp[1][2]])
- ^ *((word32*)T4[temp[2][3]]);
- for(r = 1; r < ROUNDS-1; r++) {
- *((word32*)temp[0]) = *((word32*)b) ^ *((word32*)rk[r][0]);
- *((word32*)temp[1]) = *((word32*)(b+4)) ^ *((word32*)rk[r][1]);
- *((word32*)temp[2]) = *((word32*)(b+8)) ^ *((word32*)rk[r][2]);
+ *((word32*)(b )) = *((word32*)T1[temp[0][0]])
+ ^ *((word32*)T2[temp[1][1]])
+ ^ *((word32*)T3[temp[2][2]])
+ ^ *((word32*)T4[temp[3][3]]);
+ *((word32*)(b + 4)) = *((word32*)T1[temp[1][0]])
+ ^ *((word32*)T2[temp[2][1]])
+ ^ *((word32*)T3[temp[3][2]])
+ ^ *((word32*)T4[temp[0][3]]);
+ *((word32*)(b + 8)) = *((word32*)T1[temp[2][0]])
+ ^ *((word32*)T2[temp[3][1]])
+ ^ *((word32*)T3[temp[0][2]])
+ ^ *((word32*)T4[temp[1][3]]);
+ *((word32*)(b +12)) = *((word32*)T1[temp[3][0]])
+ ^ *((word32*)T2[temp[0][1]])
+ ^ *((word32*)T3[temp[1][2]])
+ ^ *((word32*)T4[temp[2][3]]);
+ for (r = 1; r < ROUNDS-1; r++) {
+ *((word32*)temp[0]) = *((word32*)(b )) ^ *((word32*)rk[r][0]);
+ *((word32*)temp[1]) = *((word32*)(b+ 4)) ^ *((word32*)rk[r][1]);
+ *((word32*)temp[2]) = *((word32*)(b+ 8)) ^ *((word32*)rk[r][2]);
*((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[r][3]);
- *((word32*)b) = *((word32*)T1[temp[0][0]])
- ^ *((word32*)T2[temp[1][1]])
- ^ *((word32*)T3[temp[2][2]])
- ^ *((word32*)T4[temp[3][3]]);
- *((word32*)(b+4)) = *((word32*)T1[temp[1][0]])
- ^ *((word32*)T2[temp[2][1]])
- ^ *((word32*)T3[temp[3][2]])
- ^ *((word32*)T4[temp[0][3]]);
- *((word32*)(b+8)) = *((word32*)T1[temp[2][0]])
- ^ *((word32*)T2[temp[3][1]])
- ^ *((word32*)T3[temp[0][2]])
- ^ *((word32*)T4[temp[1][3]]);
- *((word32*)(b+12)) = *((word32*)T1[temp[3][0]])
- ^ *((word32*)T2[temp[0][1]])
- ^ *((word32*)T3[temp[1][2]])
- ^ *((word32*)T4[temp[2][3]]);
- }
- /* last round is special */
- *((word32*)temp[0]) = *((word32*)b) ^ *((word32*)rk[ROUNDS-1][0]);
- *((word32*)temp[1]) = *((word32*)(b+4)) ^ *((word32*)rk[ROUNDS-1][1]);
- *((word32*)temp[2]) = *((word32*)(b+8)) ^ *((word32*)rk[ROUNDS-1][2]);
+
+ *((word32*)(b )) = *((word32*)T1[temp[0][0]])
+ ^ *((word32*)T2[temp[1][1]])
+ ^ *((word32*)T3[temp[2][2]])
+ ^ *((word32*)T4[temp[3][3]]);
+ *((word32*)(b + 4)) = *((word32*)T1[temp[1][0]])
+ ^ *((word32*)T2[temp[2][1]])
+ ^ *((word32*)T3[temp[3][2]])
+ ^ *((word32*)T4[temp[0][3]]);
+ *((word32*)(b + 8)) = *((word32*)T1[temp[2][0]])
+ ^ *((word32*)T2[temp[3][1]])
+ ^ *((word32*)T3[temp[0][2]])
+ ^ *((word32*)T4[temp[1][3]]);
+ *((word32*)(b +12)) = *((word32*)T1[temp[3][0]])
+ ^ *((word32*)T2[temp[0][1]])
+ ^ *((word32*)T3[temp[1][2]])
+ ^ *((word32*)T4[temp[2][3]]);
+ }
+ /* last round is special */
+ *((word32*)temp[0]) = *((word32*)(b )) ^ *((word32*)rk[ROUNDS-1][0]);
+ *((word32*)temp[1]) = *((word32*)(b+ 4)) ^ *((word32*)rk[ROUNDS-1][1]);
+ *((word32*)temp[2]) = *((word32*)(b+ 8)) ^ *((word32*)rk[ROUNDS-1][2]);
*((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[ROUNDS-1][3]);
- b[0] = T1[temp[0][0]][1];
- b[1] = T1[temp[1][1]][1];
- b[2] = T1[temp[2][2]][1];
- b[3] = T1[temp[3][3]][1];
- b[4] = T1[temp[1][0]][1];
- b[5] = T1[temp[2][1]][1];
- b[6] = T1[temp[3][2]][1];
- b[7] = T1[temp[0][3]][1];
- b[8] = T1[temp[2][0]][1];
- b[9] = T1[temp[3][1]][1];
- b[10] = T1[temp[0][2]][1];
- b[11] = T1[temp[1][3]][1];
- b[12] = T1[temp[3][0]][1];
- b[13] = T1[temp[0][1]][1];
- b[14] = T1[temp[1][2]][1];
- b[15] = T1[temp[2][3]][1];
- *((word32*)b) ^= *((word32*)rk[ROUNDS][0]);
- *((word32*)(b+4)) ^= *((word32*)rk[ROUNDS][1]);
- *((word32*)(b+8)) ^= *((word32*)rk[ROUNDS][2]);
+ b[ 0] = T1[temp[0][0]][1];
+ b[ 1] = T1[temp[1][1]][1];
+ b[ 2] = T1[temp[2][2]][1];
+ b[ 3] = T1[temp[3][3]][1];
+ b[ 4] = T1[temp[1][0]][1];
+ b[ 5] = T1[temp[2][1]][1];
+ b[ 6] = T1[temp[3][2]][1];
+ b[ 7] = T1[temp[0][3]][1];
+ b[ 8] = T1[temp[2][0]][1];
+ b[ 9] = T1[temp[3][1]][1];
+ b[10] = T1[temp[0][2]][1];
+ b[11] = T1[temp[1][3]][1];
+ b[12] = T1[temp[3][0]][1];
+ b[13] = T1[temp[0][1]][1];
+ b[14] = T1[temp[1][2]][1];
+ b[15] = T1[temp[2][3]][1];
+ *((word32*)(b )) ^= *((word32*)rk[ROUNDS][0]);
+ *((word32*)(b+ 4)) ^= *((word32*)rk[ROUNDS][1]);
+ *((word32*)(b+ 8)) ^= *((word32*)rk[ROUNDS][2]);
*((word32*)(b+12)) ^= *((word32*)rk[ROUNDS][3]);
return 0;
}
-int rijndaelEncryptRound (word8 a[4][4],
- word8 rk[MAXROUNDS+1][4][4], int rounds)
-/* Encrypt only a certain number of rounds.
+#ifdef INTERMEDIATE_VALUE_KAT
+/**
+ * Encrypt only a certain number of rounds.
* Only used in the Intermediate Value Known Answer Test.
*/
-{
+int rijndaelEncryptRound(word8 a[4][4], word8 rk[MAXROUNDS+1][4][4], int ROUNDS, int rounds) {
int r;
- word8 temp[4][4];
-
+ word8 temp[4][4];
/* make number of rounds sane */
- if (rounds > ROUNDS) rounds = ROUNDS;
+ if (rounds > ROUNDS) {
+ rounds = ROUNDS;
+ }
*((word32*)a[0]) = *((word32*)a[0]) ^ *((word32*)rk[0][0]);
*((word32*)a[1]) = *((word32*)a[1]) ^ *((word32*)rk[0][1]);
*((word32*)a[2]) = *((word32*)a[2]) ^ *((word32*)rk[0][2]);
*((word32*)a[3]) = *((word32*)a[3]) ^ *((word32*)rk[0][3]);
- for(r = 1; (r <= rounds) && (r < ROUNDS); r++) {
+ for (r = 1; (r <= rounds) && (r < ROUNDS); r++) {
*((word32*)temp[0]) = *((word32*)T1[a[0][0]])
^ *((word32*)T2[a[1][1]])
^ *((word32*)T3[a[2][2]])
@@ -294,25 +234,25 @@ int rijndaelEncryptRound (word8 a[4][4],
*((word32*)a[1]) = *((word32*)temp[1]) ^ *((word32*)rk[r][1]);
*((word32*)a[2]) = *((word32*)temp[2]) ^ *((word32*)rk[r][2]);
*((word32*)a[3]) = *((word32*)temp[3]) ^ *((word32*)rk[r][3]);
- }
+ }
if (rounds == ROUNDS) {
- /* last round is special */
- temp[0][0] = T1[a[0][0]][1];
- temp[0][1] = T1[a[1][1]][1];
- temp[0][2] = T1[a[2][2]][1];
- temp[0][3] = T1[a[3][3]][1];
- temp[1][0] = T1[a[1][0]][1];
- temp[1][1] = T1[a[2][1]][1];
- temp[1][2] = T1[a[3][2]][1];
- temp[1][3] = T1[a[0][3]][1];
- temp[2][0] = T1[a[2][0]][1];
- temp[2][1] = T1[a[3][1]][1];
- temp[2][2] = T1[a[0][2]][1];
- temp[2][3] = T1[a[1][3]][1];
- temp[3][0] = T1[a[3][0]][1];
- temp[3][1] = T1[a[0][1]][1];
- temp[3][2] = T1[a[1][2]][1];
- temp[3][3] = T1[a[2][3]][1];
+ /* last round is special */
+ temp[0][0] = T1[a[0][0]][1];
+ temp[0][1] = T1[a[1][1]][1];
+ temp[0][2] = T1[a[2][2]][1];
+ temp[0][3] = T1[a[3][3]][1];
+ temp[1][0] = T1[a[1][0]][1];
+ temp[1][1] = T1[a[2][1]][1];
+ temp[1][2] = T1[a[3][2]][1];
+ temp[1][3] = T1[a[0][3]][1];
+ temp[2][0] = T1[a[2][0]][1];
+ temp[2][1] = T1[a[3][1]][1];
+ temp[2][2] = T1[a[0][2]][1];
+ temp[2][3] = T1[a[1][3]][1];
+ temp[3][0] = T1[a[3][0]][1];
+ temp[3][1] = T1[a[0][1]][1];
+ temp[3][2] = T1[a[1][2]][1];
+ temp[3][3] = T1[a[2][3]][1];
*((word32*)a[0]) = *((word32*)temp[0]) ^ *((word32*)rk[ROUNDS][0]);
*((word32*)a[1]) = *((word32*)temp[1]) ^ *((word32*)rk[ROUNDS][1]);
*((word32*)a[2]) = *((word32*)temp[2]) ^ *((word32*)rk[ROUNDS][2]);
@@ -321,48 +261,50 @@ int rijndaelEncryptRound (word8 a[4][4],
return 0;
}
+#endif /* INTERMEDIATE_VALUE_KAT */
-
-int rijndaelDecrypt (word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4])
-{
+/**
+ * Decrypt a single block.
+ */
+int rijndaelDecrypt(word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4], int ROUNDS) {
int r;
- word8 temp[4][4];
+ word8 temp[4][4];
-
- *((word32*)temp[0]) = *((word32*)a) ^ *((word32*)rk[ROUNDS][0]);
- *((word32*)temp[1]) = *((word32*)(a+4)) ^ *((word32*)rk[ROUNDS][1]);
- *((word32*)temp[2]) = *((word32*)(a+8)) ^ *((word32*)rk[ROUNDS][2]);
+ *((word32*)temp[0]) = *((word32*)(a )) ^ *((word32*)rk[ROUNDS][0]);
+ *((word32*)temp[1]) = *((word32*)(a+ 4)) ^ *((word32*)rk[ROUNDS][1]);
+ *((word32*)temp[2]) = *((word32*)(a+ 8)) ^ *((word32*)rk[ROUNDS][2]);
*((word32*)temp[3]) = *((word32*)(a+12)) ^ *((word32*)rk[ROUNDS][3]);
- *((word32*)b) = *((word32*)T5[temp[0][0]])
+
+ *((word32*)(b )) = *((word32*)T5[temp[0][0]])
^ *((word32*)T6[temp[3][1]])
^ *((word32*)T7[temp[2][2]])
^ *((word32*)T8[temp[1][3]]);
- *((word32*)(b+4)) = *((word32*)T5[temp[1][0]])
+ *((word32*)(b+ 4)) = *((word32*)T5[temp[1][0]])
^ *((word32*)T6[temp[0][1]])
^ *((word32*)T7[temp[3][2]])
^ *((word32*)T8[temp[2][3]]);
- *((word32*)(b+8)) = *((word32*)T5[temp[2][0]])
+ *((word32*)(b+ 8)) = *((word32*)T5[temp[2][0]])
^ *((word32*)T6[temp[1][1]])
^ *((word32*)T7[temp[0][2]])
^ *((word32*)T8[temp[3][3]]);
- *((word32*)(b+12)) = *((word32*)T5[temp[3][0]])
+ *((word32*)(b+12)) = *((word32*)T5[temp[3][0]])
^ *((word32*)T6[temp[2][1]])
^ *((word32*)T7[temp[1][2]])
^ *((word32*)T8[temp[0][3]]);
- for(r = ROUNDS-1; r > 1; r--) {
- *((word32*)temp[0]) = *((word32*)b) ^ *((word32*)rk[r][0]);
- *((word32*)temp[1]) = *((word32*)(b+4)) ^ *((word32*)rk[r][1]);
- *((word32*)temp[2]) = *((word32*)(b+8)) ^ *((word32*)rk[r][2]);
+ for (r = ROUNDS-1; r > 1; r--) {
+ *((word32*)temp[0]) = *((word32*)(b )) ^ *((word32*)rk[r][0]);
+ *((word32*)temp[1]) = *((word32*)(b+ 4)) ^ *((word32*)rk[r][1]);
+ *((word32*)temp[2]) = *((word32*)(b+ 8)) ^ *((word32*)rk[r][2]);
*((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[r][3]);
- *((word32*)b) = *((word32*)T5[temp[0][0]])
+ *((word32*)(b )) = *((word32*)T5[temp[0][0]])
^ *((word32*)T6[temp[3][1]])
^ *((word32*)T7[temp[2][2]])
^ *((word32*)T8[temp[1][3]]);
- *((word32*)(b+4)) = *((word32*)T5[temp[1][0]])
+ *((word32*)(b+ 4)) = *((word32*)T5[temp[1][0]])
^ *((word32*)T6[temp[0][1]])
^ *((word32*)T7[temp[3][2]])
^ *((word32*)T8[temp[2][3]]);
- *((word32*)(b+8)) = *((word32*)T5[temp[2][0]])
+ *((word32*)(b+ 8)) = *((word32*)T5[temp[2][0]])
^ *((word32*)T6[temp[1][1]])
^ *((word32*)T7[temp[0][2]])
^ *((word32*)T8[temp[3][3]]);
@@ -370,74 +312,129 @@ int rijndaelDecrypt (word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4])
^ *((word32*)T6[temp[2][1]])
^ *((word32*)T7[temp[1][2]])
^ *((word32*)T8[temp[0][3]]);
- }
- /* last round is special */
- *((word32*)temp[0]) = *((word32*)b) ^ *((word32*)rk[1][0]);
- *((word32*)temp[1]) = *((word32*)(b+4)) ^ *((word32*)rk[1][1]);
- *((word32*)temp[2]) = *((word32*)(b+8)) ^ *((word32*)rk[1][2]);
+ }
+ /* last round is special */
+ *((word32*)temp[0]) = *((word32*)(b )) ^ *((word32*)rk[1][0]);
+ *((word32*)temp[1]) = *((word32*)(b+ 4)) ^ *((word32*)rk[1][1]);
+ *((word32*)temp[2]) = *((word32*)(b+ 8)) ^ *((word32*)rk[1][2]);
*((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[1][3]);
- b[0] = S5[temp[0][0]];
- b[1] = S5[temp[3][1]];
- b[2] = S5[temp[2][2]];
- b[3] = S5[temp[1][3]];
- b[4] = S5[temp[1][0]];
- b[5] = S5[temp[0][1]];
- b[6] = S5[temp[3][2]];
- b[7] = S5[temp[2][3]];
- b[8] = S5[temp[2][0]];
- b[9] = S5[temp[1][1]];
- b[10] = S5[temp[0][2]];
- b[11] = S5[temp[3][3]];
- b[12] = S5[temp[3][0]];
- b[13] = S5[temp[2][1]];
- b[14] = S5[temp[1][2]];
- b[15] = S5[temp[0][3]];
- *((word32*)b) ^= *((word32*)rk[0][0]);
- *((word32*)(b+4)) ^= *((word32*)rk[0][1]);
- *((word32*)(b+8)) ^= *((word32*)rk[0][2]);
+ b[ 0] = S5[temp[0][0]];
+ b[ 1] = S5[temp[3][1]];
+ b[ 2] = S5[temp[2][2]];
+ b[ 3] = S5[temp[1][3]];
+ b[ 4] = S5[temp[1][0]];
+ b[ 5] = S5[temp[0][1]];
+ b[ 6] = S5[temp[3][2]];
+ b[ 7] = S5[temp[2][3]];
+ b[ 8] = S5[temp[2][0]];
+ b[ 9] = S5[temp[1][1]];
+ b[10] = S5[temp[0][2]];
+ b[11] = S5[temp[3][3]];
+ b[12] = S5[temp[3][0]];
+ b[13] = S5[temp[2][1]];
+ b[14] = S5[temp[1][2]];
+ b[15] = S5[temp[0][3]];
+ *((word32*)(b )) ^= *((word32*)rk[0][0]);
+ *((word32*)(b+ 4)) ^= *((word32*)rk[0][1]);
+ *((word32*)(b+ 8)) ^= *((word32*)rk[0][2]);
*((word32*)(b+12)) ^= *((word32*)rk[0][3]);
return 0;
}
-
-int rijndaelDecryptRound (word8 a[4][4],
- word8 rk[MAXROUNDS+1][4][4], int rounds)
-/* Decrypt only a certain number of rounds.
+#ifdef INTERMEDIATE_VALUE_KAT
+/**
+ * Decrypt only a certain number of rounds.
* Only used in the Intermediate Value Known Answer Test.
* Operations rearranged such that the intermediate values
* of decryption correspond with the intermediate values
* of encryption.
*/
-{
- int r;
-
+int rijndaelDecryptRound(word8 a[4][4], word8 rk[MAXROUNDS+1][4][4], int ROUNDS, int rounds) {
+ int r, i;
+ word8 temp[4], shift;
/* make number of rounds sane */
- if (rounds > ROUNDS) rounds = ROUNDS;
-
- /* First the special round:
- * without InvMixColumn
- * with extra KeyAddition
- */
- KeyAddition(a,rk[ROUNDS],4);
- Substitution(a,Si,4);
- ShiftRow(a,1,4);
-
- /* ROUNDS-1 ordinary rounds
- */
- for(r = ROUNDS-1; r > rounds; r--) {
- KeyAddition(a,rk[r],4);
- InvMixColumn(a,4);
- Substitution(a,Si,4);
- ShiftRow(a,1,4);
+ if (rounds > ROUNDS) {
+ rounds = ROUNDS;
+ }
+ /* first round is special: */
+ *(word32 *)a[0] ^= *(word32 *)rk[ROUNDS][0];
+ *(word32 *)a[1] ^= *(word32 *)rk[ROUNDS][1];
+ *(word32 *)a[2] ^= *(word32 *)rk[ROUNDS][2];
+ *(word32 *)a[3] ^= *(word32 *)rk[ROUNDS][3];
+ for (i = 0; i < 4; i++) {
+ a[i][0] = Si[a[i][0]];
+ a[i][1] = Si[a[i][1]];
+ a[i][2] = Si[a[i][2]];
+ a[i][3] = Si[a[i][3]];
+ }
+ for (i = 1; i < 4; i++) {
+ shift = (4 - i) & 3;
+ temp[0] = a[(0 + shift) & 3][i];
+ temp[1] = a[(1 + shift) & 3][i];
+ temp[2] = a[(2 + shift) & 3][i];
+ temp[3] = a[(3 + shift) & 3][i];
+ a[0][i] = temp[0];
+ a[1][i] = temp[1];
+ a[2][i] = temp[2];
+ a[3][i] = temp[3];
+ }
+ /* ROUNDS-1 ordinary rounds */
+ for (r = ROUNDS-1; r > rounds; r--) {
+ *(word32 *)a[0] ^= *(word32 *)rk[r][0];
+ *(word32 *)a[1] ^= *(word32 *)rk[r][1];
+ *(word32 *)a[2] ^= *(word32 *)rk[r][2];
+ *(word32 *)a[3] ^= *(word32 *)rk[r][3];
+
+ *((word32*)a[0]) =
+ *((word32*)U1[a[0][0]])
+ ^ *((word32*)U2[a[0][1]])
+ ^ *((word32*)U3[a[0][2]])
+ ^ *((word32*)U4[a[0][3]]);
+
+ *((word32*)a[1]) =
+ *((word32*)U1[a[1][0]])
+ ^ *((word32*)U2[a[1][1]])
+ ^ *((word32*)U3[a[1][2]])
+ ^ *((word32*)U4[a[1][3]]);
+
+ *((word32*)a[2]) =
+ *((word32*)U1[a[2][0]])
+ ^ *((word32*)U2[a[2][1]])
+ ^ *((word32*)U3[a[2][2]])
+ ^ *((word32*)U4[a[2][3]]);
+
+ *((word32*)a[3]) =
+ *((word32*)U1[a[3][0]])
+ ^ *((word32*)U2[a[3][1]])
+ ^ *((word32*)U3[a[3][2]])
+ ^ *((word32*)U4[a[3][3]]);
+ for (i = 0; i < 4; i++) {
+ a[i][0] = Si[a[i][0]];
+ a[i][1] = Si[a[i][1]];
+ a[i][2] = Si[a[i][2]];
+ a[i][3] = Si[a[i][3]];
+ }
+ for (i = 1; i < 4; i++) {
+ shift = (4 - i) & 3;
+ temp[0] = a[(0 + shift) & 3][i];
+ temp[1] = a[(1 + shift) & 3][i];
+ temp[2] = a[(2 + shift) & 3][i];
+ temp[3] = a[(3 + shift) & 3][i];
+ a[0][i] = temp[0];
+ a[1][i] = temp[1];
+ a[2][i] = temp[2];
+ a[3][i] = temp[3];
+ }
}
-
if (rounds == 0) {
- /* End with the extra key addition
- */
- KeyAddition(a,rk[0],4);
+ /* End with the extra key addition */
+ *(word32 *)a[0] ^= *(word32 *)rk[0][0];
+ *(word32 *)a[1] ^= *(word32 *)rk[0][1];
+ *(word32 *)a[2] ^= *(word32 *)rk[0][2];
+ *(word32 *)a[3] ^= *(word32 *)rk[0][3];
}
-
return 0;
}
+#endif /* INTERMEDIATE_VALUE_KAT */
View
63 kame/sys/crypto/rijndael/rijndael-alg-fst.h
@@ -1,28 +1,39 @@
-/* rijndael-alg-fst.h v2.0 August '99
+/*
+ * rijndael-alg-fst.h v2.3 April '2000
+ *
* Optimised ANSI C code
+ *
+ * #define INTERMEDIATE_VALUE_KAT to generate the Intermediate Value Known Answer Test.
*/
-#ifndef __RIJNDAEL_ALG_H
-#define __RIJNDAEL_ALG_H
-
-#define MAXKC (256/32)
-#define MAXROUNDS 14
-
-typedef unsigned char word8;
-typedef unsigned short word16;
-typedef unsigned int word32;
-
-int ROUNDS;
-
-int rijndaelKeySched (word8 k[MAXKC][4], int keyBits,
- word8 rk[MAXROUNDS+1][4][4]);
-int rijndaelKeyEnctoDec (int keyBits, word8 W[MAXROUNDS+1][4][4]);
-int rijndaelEncrypt (word8 a[16], word8 b[16],
- word8 rk[MAXROUNDS+1][4][4]);
-int rijndaelEncryptRound (word8 a[4][4],
- word8 rk[MAXROUNDS+1][4][4], int rounds);
-int rijndaelDecrypt (word8 a[16], word8 b[16],
- word8 rk[MAXROUNDS+1][4][4]);
-int rijndaelDecryptRound (word8 a[4][4],
- word8 rk[MAXROUNDS+1][4][4], int rounds);
-
-#endif /* __RIJNDAEL_ALG_H */
+
+#ifndef __RIJNDAEL_ALG_FST_H
+#define __RIJNDAEL_ALG_FST_H
+
+#define MAXKC (256/32)
+#define MAXROUNDS 14
+
+#ifndef USUAL_TYPES
+#define USUAL_TYPES
+typedef unsigned char byte;
+typedef unsigned char word8;
+typedef unsigned short word16;
+typedef unsigned int word32;
+#endif /* USUAL_TYPES */
+
+int rijndaelKeySched(word8 k[MAXKC][4], word8 rk[MAXROUNDS+1][4][4], int ROUNDS);
+
+int rijndaelKeyEncToDec(word8 W[MAXROUNDS+1][4][4], int ROUNDS);
+
+int rijndaelEncrypt(word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4], int ROUNDS);
+
+#ifdef INTERMEDIATE_VALUE_KAT
+int rijndaelEncryptRound(word8 a[4][4], word8 rk[MAXROUNDS+1][4][4], int ROUNDS, int rounds);
+#endif /* INTERMEDIATE_VALUE_KAT */
+
+int rijndaelDecrypt(word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4], int ROUNDS);
+
+#ifdef INTERMEDIATE_VALUE_KAT
+int rijndaelDecryptRound(word8 a[4][4], word8 rk[MAXROUNDS+1][4][4], int ROUNDS, int rounds);
+#endif /* INTERMEDIATE_VALUE_KAT */
+
+#endif /* __RIJNDAEL_ALG_FST_H */
View
387 kame/sys/crypto/rijndael/rijndael-api-fst.c
@@ -1,19 +1,29 @@
-/* rijndael-api-fst.c v2.0 August '99
+/*
+ * rijndael-api-fst.c v2.3 April '2000
+ *
* Optimised ANSI C code
+ *
* authors: v1.0: Antoon Bosselaers
* v2.0: Vincent Rijmen
+ * v2.1: Vincent Rijmen
+ * v2.2: Vincent Rijmen
+ * v2.3: Paulo Barreto
+ * v2.4: Vincent Rijmen
+ *
+ * This code is placed in the public domain.
*/
+#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "rijndael-alg-fst.h"
#include "rijndael-api-fst.h"
-int makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial)
-{
+int makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial) {
word8 k[MAXKC][4];
- int i, j, t;
+ int i;
+ char *keyMat;
if (key == NULL) {
return BAD_KEY_INSTANCE;
@@ -31,48 +41,57 @@ int makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial)
return BAD_KEY_MAT;
}
- if ( keyMaterial ) {
+ if (keyMaterial != NULL) {
strncpy(key->keyMaterial, keyMaterial, keyLen/4);
}
- ROUNDS = keyLen/32 + 6;
+ key->ROUNDS = keyLen/32 + 6;
/* initialize key schedule: */
- for(i = 0; i < key->keyLen/8; i++) {
- t = key->keyMaterial[2*i];
+ keyMat = key->keyMaterial;
+#ifndef BINARY_KEY_MATERIAL
+ for (i = 0; i < key->keyLen/8; i++) {
+ int t, j;
+
+ t = *keyMat++;
if ((t >= '0') && (t <= '9')) j = (t - '0') << 4;
else if ((t >= 'a') && (t <= 'f')) j = (t - 'a' + 10) << 4;
else if ((t >= 'A') && (t <= 'F')) j = (t - 'A' + 10) << 4;
else return BAD_KEY_MAT;
- t = key->keyMaterial[2*i+1];
+ t = *keyMat++;
if ((t >= '0') && (t <= '9')) j ^= (t - '0');
else if ((t >= 'a') && (t <= 'f')) j ^= (t - 'a' + 10);
else if ((t >= 'A') && (t <= 'F')) j ^= (t - 'A' + 10);
else return BAD_KEY_MAT;
- k[i / 4][i % 4] = (word8) j;
+ k[i >> 2][i & 3] = (word8)j;
+ }
+#else
+ for (i = 0; i < key->keyLen/8; i++) {
+ k[i >> 2][i & 3] = (word8)keyMat[i];
+ }
+#endif /* ?BINARY_KEY_MATERIAL */
+ rijndaelKeySched(k, key->keySched, key->ROUNDS);
+ if (direction == DIR_DECRYPT) {
+ rijndaelKeyEncToDec(key->keySched, key->ROUNDS);
}
- rijndaelKeySched (k, key->keyLen, key->keySched);
- if (direction == DIR_DECRYPT)
- rijndaelKeyEnctoDec (key->keyLen, key->keySched);
return TRUE;
}
-int cipherInit(cipherInstance *cipher, BYTE mode, char *IV)
-{
- int i, j, t;
-
+int cipherInit(cipherInstance *cipher, BYTE mode, char *IV) {
if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
cipher->mode = mode;
} else {
return BAD_CIPHER_MODE;
}
-
-
if (IV != NULL) {
- for(i = 0; i < 16; i++) {
+#ifndef BINARY_KEY_MATERIAL
+ int i;
+ for (i = 0; i < MAX_IV_SIZE; i++) {
+ int t, j;
+
t = IV[2*i];
if ((t >= '0') && (t <= '9')) j = (t - '0') << 4;
else if ((t >= 'a') && (t <= 'f')) j = (t - 'a' + 10) << 4;
@@ -85,17 +104,19 @@ int cipherInit(cipherInstance *cipher, BYTE mode, char *IV)
else if ((t >= 'A') && (t <= 'F')) j ^= (t - 'A' + 10);
else return BAD_CIPHER_INSTANCE;
- cipher->IV[i] = (word8) j;
- }
+ cipher->IV[i] = (word8)j;
+ }
+#else
+ memcpy(cipher->IV, IV, MAX_IV_SIZE);
+#endif /* ?BINARY_KEY_MATERIAL */
+ } else {
+ memset(cipher->IV, 0, MAX_IV_SIZE);
}
-
return TRUE;
}
-
-int blockEncrypt(cipherInstance *cipher,
- keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer)
-{
+int blockEncrypt(cipherInstance *cipher, keyInstance *key,
+ BYTE *input, int inputLen, BYTE *outBuffer) {
int i, k, numBlocks;
word8 block[16], iv[4][4];
@@ -104,61 +125,55 @@ int blockEncrypt(cipherInstance *cipher,
key->direction == DIR_DECRYPT) {
return BAD_CIPHER_STATE;
}
-
+ if (input == NULL || inputLen <= 0) {
+ return 0; /* nothing to do */
+ }
numBlocks = inputLen/128;
switch (cipher->mode) {
case MODE_ECB:
for (i = numBlocks; i > 0; i--) {
-
- rijndaelEncrypt (input, outBuffer, key->keySched);
-
+ rijndaelEncrypt(input, outBuffer, key->keySched, key->ROUNDS);
input += 16;
outBuffer += 16;
}
break;
case MODE_CBC:
-#if STRICT_ALIGN
- memcpy(block,cipher->IV,16);
-#else
- *((word32*)block) = *((word32*)(cipher->IV));
- *((word32*)(block+4)) = *((word32*)(cipher->IV+4));
- *((word32*)(block+8)) = *((word32*)(cipher->IV+8));
- *((word32*)(block+12)) = *((word32*)(cipher->IV+12));
-#endif
-
- for (i = numBlocks; i > 0; i--) {
- *((word32*)block) ^= *((word32*)(input));
- *((word32*)(block+4)) ^= *((word32*)(input+4));
- *((word32*)(block+8)) ^= *((word32*)(input+8));
- *((word32*)(block+12)) ^= *((word32*)(input+12));
-
- rijndaelEncrypt (block, outBuffer, key->keySched);
-
- input += 16;
+ ((word32*)block)[0] = ((word32*)cipher->IV)[0] ^ ((word32*)input)[0];
+ ((word32*)block)[1] = ((word32*)cipher->IV)[1] ^ ((word32*)input)[1];
+ ((word32*)block)[2] = ((word32*)cipher->IV)[2] ^ ((word32*)input)[2];
+ ((word32*)block)[3] = ((word32*)cipher->IV)[3] ^ ((word32*)input)[3];
+ rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS);
+ input += 16;
+ for (i = numBlocks - 1; i > 0; i--) {
+ ((word32*)block)[0] = ((word32*)outBuffer)[0] ^ ((word32*)input)[0];
+ ((word32*)block)[1] = ((word32*)outBuffer)[1] ^ ((word32*)input)[1];
+ ((word32*)block)[2] = ((word32*)outBuffer)[2] ^ ((word32*)input)[2];
+ ((word32*)block)[3] = ((word32*)outBuffer)[3] ^ ((word32*)input)[3];
outBuffer += 16;
+ rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS);
+ input += 16;
}
break;
case MODE_CFB1:
#if STRICT_ALIGN
- memcpy(iv,cipher->IV,16);
-#else
- *((word32*)iv[0]) = *((word32*)(cipher->IV));
- *((word32*)iv[1]) = *((word32*)(cipher->IV+4));
- *((word32*)iv[2]) = *((word32*)(cipher->IV+8));
+ memcpy(iv, cipher->IV, 16);
+#else /* !STRICT_ALIGN */
+ *((word32*)iv[0]) = *((word32*)(cipher->IV ));
+ *((word32*)iv[1]) = *((word32*)(cipher->IV+ 4));
+ *((word32*)iv[2]) = *((word32*)(cipher->IV+ 8));
*((word32*)iv[3]) = *((word32*)(cipher->IV+12));
-#endif
+#endif /* ?STRICT_ALIGN */
for (i = numBlocks; i > 0; i--) {
for (k = 0; k < 128; k++) {
- *((word32*)block) = *((word32*)iv[0]);
- *((word32*)(block+4)) = *((word32*)iv[1]);
- *((word32*)(block+8)) = *((word32*)iv[2]);
+ *((word32*) block ) = *((word32*)iv[0]);
+ *((word32*)(block+ 4)) = *((word32*)iv[1]);
+ *((word32*)(block+ 8)) = *((word32*)iv[2]);
*((word32*)(block+12)) = *((word32*)iv[3]);
-
- rijndaelEncrypt (block, block, key->keySched);
+ rijndaelEncrypt(block, block, key->keySched, key->ROUNDS);
outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
@@ -184,12 +199,80 @@ int blockEncrypt(cipherInstance *cipher,
return BAD_CIPHER_STATE;
}
- return numBlocks*128;
+ return 128*numBlocks;
+}
+
+/**
+ * Encrypt data partitioned in octets, using RFC 2040-like padding.
+ *
+ * @param input data to be encrypted (octet sequence)
+ * @param inputOctets input length in octets (not bits)
+ * @param outBuffer encrypted output data
+ *
+ * @return length in octets (not bits) of the encrypted output buffer.
+ */
+int padEncrypt(cipherInstance *cipher, keyInstance *key,
+ BYTE *input, int inputOctets, BYTE *outBuffer) {
+ int i, numBlocks, padLen;
+ word8 block[16], *iv;
+
+ if (cipher == NULL ||
+ key == NULL ||
+ key->direction == DIR_DECRYPT) {
+ return BAD_CIPHER_STATE;
+ }
+ if (input == NULL || inputOctets <= 0) {
+ return 0; /* nothing to do */
+ }
+
+ numBlocks = inputOctets/16;
+
+ switch (cipher->mode) {
+ case MODE_ECB:
+ for (i = numBlocks; i > 0; i--) {
+ rijndaelEncrypt(input, outBuffer, key->keySched, key->ROUNDS);
+ input += 16;
+ outBuffer += 16;
+ }
+ padLen = 16 - (inputOctets - 16*numBlocks);
+ assert(padLen > 0 && padLen <= 16);
+ memcpy(block, input, 16 - padLen);
+ memset(block + 16 - padLen, padLen, padLen);
+ rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS);
+ break;
+
+ case MODE_CBC:
+ iv = cipher->IV;
+ for (i = numBlocks; i > 0; i--) {
+ ((word32*)block)[0] = ((word32*)input)[0] ^ ((word32*)iv)[0];
+ ((word32*)block)[1] = ((word32*)input)[1] ^ ((word32*)iv)[1];
+ ((word32*)block)[2] = ((word32*)input)[2] ^ ((word32*)iv)[2];
+ ((word32*)block)[3] = ((word32*)input)[3] ^ ((word32*)iv)[3];
+ rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS);
+ iv = outBuffer;
+ input += 16;
+ outBuffer += 16;
+ }
+ padLen = 16 - (inputOctets - 16*numBlocks);
+ assert(padLen > 0 && padLen <= 16);
+ for (i = 0; i < 16 - padLen; i++) {
+ block[i] = input[i] ^ iv[i];
+ }
+ for (i = 16 - padLen; i < 16; i++) {
+ block[i] = (BYTE)padLen ^ iv[i];
+ }
+ rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS);
+ break;
+
+ default:
+ return BAD_CIPHER_STATE;
+ }
+
+ return 16*(numBlocks + 1);
}
-int blockDecrypt(cipherInstance *cipher,
- keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer)
-{
+int blockDecrypt(cipherInstance *cipher, keyInstance *key,
+ BYTE *input, int inputLen, BYTE *outBuffer) {
int i, k, numBlocks;
word8 block[16], iv[4][4];
@@ -198,53 +281,45 @@ int blockDecrypt(cipherInstance *cipher,
cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT) {
return BAD_CIPHER_STATE;
}
-
+ if (input == NULL || inputLen <= 0) {
+ return 0; /* nothing to do */
+ }
numBlocks = inputLen/128;
-
+
switch (cipher->mode) {
case MODE_ECB:
for (i = numBlocks; i > 0; i--) {
-
- rijndaelDecrypt (input, outBuffer, key->keySched);
-
+ rijndaelDecrypt(input, outBuffer, key->keySched, key->ROUNDS);
input += 16;
outBuffer += 16;
-
}
break;
case MODE_CBC:
- /* first block */
-
- rijndaelDecrypt (input, block, key->keySched);
+#if STRICT_ALIGN
+ memcpy(iv, cipher->IV, 16);
+#else
+ *((word32*)iv[0]) = *((word32*)(cipher->IV ));
+ *((word32*)iv[1]) = *((word32*)(cipher->IV+ 4));
+ *((word32*)iv[2]) = *((word32*)(cipher->IV+ 8));
+ *((word32*)iv[3]) = *((word32*)(cipher->IV+12));
+#endif
+ for (i = numBlocks; i > 0; i--) {
+ rijndaelDecrypt(input, block, key->keySched, key->ROUNDS);
+ ((word32*)block)[0] ^= *((word32*)iv[0]);
+ ((word32*)block)[1] ^= *((word32*)iv[1]);
+ ((word32*)block)[2] ^= *((word32*)iv[2]);
+ ((word32*)block)[3] ^= *((word32*)iv[3]);
#if STRICT_ALIGN
- memcpy(outBuffer,cipher->IV,16);
- *((word32*)(outBuffer)) ^= *((word32*)block);
- *((word32*)(outBuffer+4)) ^= *((word32*)(block+4));
- *((word32*)(outBuffer+8)) ^= *((word32*)(block+8));
- *((word32*)(outBuffer+12)) ^= *((word32*)(block+12));
+ memcpy(iv, input, 16);
+ memcpy(outBuf, block, 16);
#else
- *((word32*)(outBuffer)) = *((word32*)block) ^ *((word32*)(cipher->IV));
- *((word32*)(outBuffer+4)) = *((word32*)(block+4)) ^ *((word32*)(cipher->IV+4));
- *((word32*)(outBuffer+8)) = *((word32*)(block+8)) ^ *((word32*)(cipher->IV+8));
- *((word32*)(outBuffer+12)) = *((word32*)(block+12)) ^ *((word32*)(cipher->IV+12));
+ *((word32*)iv[0]) = ((word32*)input)[0]; ((word32*)outBuffer)[0] = ((word32*)block)[0];
+ *((word32*)iv[1]) = ((word32*)input)[1]; ((word32*)outBuffer)[1] = ((word32*)block)[1];
+ *((word32*)iv[2]) = ((word32*)input)[2]; ((word32*)outBuffer)[2] = ((word32*)block)[2];
+ *((word32*)iv[3]) = ((word32*)input)[3]; ((word32*)outBuffer)[3] = ((word32*)block)[3];
#endif
-
- /* next blocks */
- for (i = numBlocks-1; i > 0; i--) {
-
- rijndaelDecrypt (input, block, key->keySched);
-
- *((word32*)(outBuffer+16)) = *((word32*)block) ^
- *((word32*)(input-16));
- *((word32*)(outBuffer+20)) = *((word32*)(block+4)) ^
- *((word32*)(input-12));
- *((word32*)(outBuffer+24)) = *((word32*)(block+8)) ^
- *((word32*)(input-8));
- *((word32*)(outBuffer+28)) = *((word32*)(block+12)) ^
- *((word32*)(input-4));
-
input += 16;
outBuffer += 16;
}
@@ -252,21 +327,20 @@ int blockDecrypt(cipherInstance *cipher,
case MODE_CFB1:
#if STRICT_ALIGN
- memcpy(iv,cipher->IV,16);
+ memcpy(iv, cipher->IV, 16);
#else
*((word32*)iv[0]) = *((word32*)(cipher->IV));
- *((word32*)iv[1]) = *((word32*)(cipher->IV+4));
- *((word32*)iv[2]) = *((word32*)(cipher->IV+8));
+ *((word32*)iv[1]) = *((word32*)(cipher->IV+ 4));
+ *((word32*)iv[2]) = *((word32*)(cipher->IV+ 8));
*((word32*)iv[3]) = *((word32*)(cipher->IV+12));
#endif
for (i = numBlocks; i > 0; i--) {
for (k = 0; k < 128; k++) {
- *((word32*)block) = *((word32*)iv[0]);
- *((word32*)(block+4)) = *((word32*)iv[1]);
- *((word32*)(block+8)) = *((word32*)iv[2]);
+ *((word32*) block ) = *((word32*)iv[0]);
+ *((word32*)(block+ 4)) = *((word32*)iv[1]);
+ *((word32*)(block+ 8)) = *((word32*)iv[2]);
*((word32*)(block+12)) = *((word32*)iv[3]);
-
- rijndaelEncrypt (block, block, key->keySched);
+ rijndaelEncrypt(block, block, key->keySched, key->ROUNDS);
iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
@@ -292,10 +366,91 @@ int blockDecrypt(cipherInstance *cipher,
return BAD_CIPHER_STATE;
}
- return numBlocks*128;
+ return 128*numBlocks;
}
+int padDecrypt(cipherInstance *cipher, keyInstance *key,
+ BYTE *input, int inputOctets, BYTE *outBuffer) {
+ int i, numBlocks, padLen;
+ word8 block[16];
+ word32 iv[4];
+
+ if (cipher == NULL ||
+ key == NULL ||
+ key->direction == DIR_ENCRYPT) {
+ return BAD_CIPHER_STATE;
+ }
+ if (input == NULL || inputOctets <= 0) {
+ return 0; /* nothing to do */
+ }
+ if (inputOctets % 16 != 0) {
+ return BAD_DATA;
+ }
+
+ numBlocks = inputOctets/16;
+ switch (cipher->mode) {
+ case MODE_ECB:
+ /* all blocks but last */
+ for (i = numBlocks - 1; i > 0; i--) {
+ rijndaelDecrypt(input, outBuffer, key->keySched, key->ROUNDS);
+ input += 16;
+ outBuffer += 16;
+ }
+ /* last block */
+ rijndaelDecrypt(input, block, key->keySched, key->ROUNDS);
+ padLen = block[15];
+ if (padLen >= 16) {
+ return BAD_DATA;
+ }
+ for (i = 16 - padLen; i < 16; i++) {
+ if (block[i] != padLen) {
+ return BAD_DATA;
+ }
+ }
+ memcpy(outBuffer, block, 16 - padLen);
+ break;
+
+ case MODE_CBC:
+ memcpy(iv, cipher->IV, 16);
+ /* all blocks but last */
+ for (i = numBlocks - 1; i > 0; i--) {
+ rijndaelDecrypt(input, block, key->keySched, key->ROUNDS);
+ ((word32*)block)[0] ^= iv[0];
+ ((word32*)block)[1] ^= iv[1];
+ ((word32*)block)[2] ^= iv[2];
+ ((word32*)block)[3] ^= iv[3];
+ memcpy(iv, input, 16);
+ memcpy(outBuffer, block, 16);
+ input += 16;
+ outBuffer += 16;
+ }
+ /* last block */
+ rijndaelDecrypt(input, block, key->keySched, key->ROUNDS);
+ ((word32*)block)[0] ^= iv[0];
+ ((word32*)block)[1] ^= iv[1];
+ ((word32*)block)[2] ^= iv[2];
+ ((word32*)block)[3] ^= iv[3];
+ padLen = block[15];
+ if (padLen <= 0 || padLen > 16) {
+ return BAD_DATA;
+ }
+ for (i = 16 - padLen; i < 16; i++) {
+ if (block[i] != padLen) {
+ return BAD_DATA;
+ }
+ }
+ memcpy(outBuffer, block, 16 - padLen);
+ break;
+
+ default:
+ return BAD_CIPHER_STATE;
+ }
+
+ return 16*numBlocks - padLen;
+}
+
+#ifdef INTERMEDIATE_VALUE_KAT
/**
* cipherUpdateRounds:
*
@@ -306,14 +461,12 @@ int blockDecrypt(cipherInstance *cipher,
* TRUE - on success
* BAD_CIPHER_STATE - cipher in bad state (e.g., not initialized)
*/
-int cipherUpdateRounds(cipherInstance *cipher,
- keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer, int rounds)
-{
+int cipherUpdateRounds(cipherInstance *cipher, keyInstance *key,
+ BYTE *input, int inputLen, BYTE *outBuffer, int rounds) {
int j;
word8 block[4][4];
- if (cipher == NULL ||
- key == NULL) {
+ if (cipher == NULL || key == NULL) {
return BAD_CIPHER_STATE;
}
@@ -324,14 +477,15 @@ int cipherUpdateRounds(cipherInstance *cipher,
switch (key->direction) {
case DIR_ENCRYPT:
- rijndaelEncryptRound (block, key->keySched, rounds);
- break;
+ rijndaelEncryptRound(block, key->keySched, key->ROUNDS, rounds);
+ break;
case DIR_DECRYPT:
- rijndaelDecryptRound (block, key->keySched, rounds);
- break;
+ rijndaelDecryptRound(block, key->keySched, key->ROUNDS, rounds);
+ break;
- default: return BAD_KEY_DIR;
+ default:
+ return BAD_KEY_DIR;
}
for (j = 3; j >= 0; j--) {
@@ -341,3 +495,4 @@ int cipherUpdateRounds(cipherInstance *cipher,
return TRUE;
}
+#endif /* INTERMEDIATE_VALUE_KAT */
View
123 kame/sys/crypto/rijndael/rijndael-api-fst.h
@@ -1,7 +1,13 @@
-/* rijndael-api-fst.h v2.0 August '99
+/*
+ * rijndael-api-fst.h v2.3 April '2000
+ *
* Optimised ANSI C code
+ *
+ * #define INTERMEDIATE_VALUE_KAT to generate the Intermediate Value Known Answer Test.
*/
+#ifndef __RIJNDAEL_API_FST_H
+#define __RIJNDAEL_API_FST_H
#include <stdio.h>
#include "rijndael-alg-fst.h"
@@ -10,34 +16,29 @@
Add any additional defines you need
*/
-#define DIR_ENCRYPT 0 /* Are we encrpyting? */
-#define DIR_DECRYPT 1 /* Are we decrpyting? */
-#define MODE_ECB 1 /* Are we ciphering in ECB mode? */
-#define MODE_CBC 2 /* Are we ciphering in CBC mode? */
-#define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */
-#define TRUE 1
-#define FALSE 0
-#define BITSPERBLOCK 128 /* Default number of bits in a cipher block */
+#define DIR_ENCRYPT 0 /* Are we encrpyting? */
+#define DIR_DECRYPT 1 /* Are we decrpyting? */
+#define MODE_ECB 1 /* Are we ciphering in ECB mode? */
+#define MODE_CBC 2 /* Are we ciphering in CBC mode? */
+#define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */
+#define TRUE 1
+#define FALSE 0
+#define BITSPERBLOCK 128 /* Default number of bits in a cipher block */
/* Error Codes - CHANGE POSSIBLE: inclusion of additional error codes */
-#define BAD_KEY_DIR -1 /* Key direction is invalid, e.g.,
- unknown value */
-#define BAD_KEY_MAT -2 /* Key material not of correct
- length */
-#define BAD_KEY_INSTANCE -3 /* Key passed is not valid */
-#define BAD_CIPHER_MODE -4 /* Params struct passed to
- cipherInit invalid */
-#define BAD_CIPHER_STATE -5 /* Cipher in wrong state (e.g., not
- initialized) */
-#define BAD_BLOCK_LENGTH -6
-#define BAD_CIPHER_INSTANCE -7
-
+#define BAD_KEY_DIR -1 /* Key direction is invalid, e.g., unknown value */
+#define BAD_KEY_MAT -2 /* Key material not of correct length */
+#define BAD_KEY_INSTANCE -3 /* Key passed is not valid */
+#define BAD_CIPHER_MODE -4 /* Params struct passed to cipherInit invalid */
+#define BAD_CIPHER_STATE -5 /* Cipher in wrong state (e.g., not initialized) */
+#define BAD_BLOCK_LENGTH -6
+#define BAD_CIPHER_INSTANCE -7
+#define BAD_DATA -8 /* Data contents are invalid, e.g., invalid padding */
+#define BAD_OTHER -9 /* Unknown error */
/* CHANGE POSSIBLE: inclusion of algorithm specific defines */
-#define MAX_KEY_SIZE 64 /* # of ASCII char's needed to
- represent a key */
-#define MAX_IV_SIZE 32 /* # bytes needed to
- represent an IV */
+#define MAX_KEY_SIZE 64 /* # of ASCII char's needed to represent a key */
+#define MAX_IV_SIZE 16 /* # bytes needed to represent an IV */
/* Typedefs:
@@ -45,45 +46,55 @@
parameters at the bottom of the structs as appropriate.
*/
-typedef unsigned char BYTE;
+typedef unsigned char BYTE;
/* The structure for key information */
typedef struct {
- BYTE direction; /* Key used for encrypting or decrypting? */
- int keyLen; /* Length of the key */
- char keyMaterial[MAX_KEY_SIZE+1]; /* Raw key data in ASCII,
- e.g., user input or KAT values */
- /* The following parameters are algorithm dependent, replace or
- add as necessary */
- int blockLen; /* block length */
- word8 keySched[MAXROUNDS+1][4][4]; /* key schedule */
- } keyInstance;
+ BYTE direction; /* Key used for encrypting or decrypting? */
+ int keyLen; /* Length of the key */
+ char keyMaterial[MAX_KEY_SIZE+1]; /* Raw key data in ASCII, e.g., user input or KAT values */
+ /* The following parameters are algorithm dependent, replace or add as necessary */
+ int ROUNDS; /* key-length-dependent number of rounds */
+ int blockLen; /* block length */
+ word8 keySched[MAXROUNDS+1][4][4]; /* key schedule */
+} keyInstance;
/* The structure for cipher information */
-typedef struct { /* changed order of the components */
- BYTE mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */
- BYTE IV[MAX_IV_SIZE]; /* A possible Initialization Vector for
- ciphering */
- /* Add any algorithm specific parameters needed here */
- int blockLen; /* Sample: Handles non-128 bit block sizes
- (if available) */
- } cipherInstance;
-
-
-/* Function protoypes */
-/* CHANGED: makeKey(): parameter blockLen added
- this parameter is absolutely necessary if you want to
- setup the round keys in a variable block length setting
- cipherInit(): parameter blockLen added (for obvious reasons)
+typedef struct { /* changed order of the components */
+ BYTE mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */
+ BYTE IV[MAX_IV_SIZE]; /* A possible Initialization Vector for ciphering */
+ /* Add any algorithm specific parameters needed here */
+ int blockLen; /* Sample: Handles non-128 bit block sizes (if available) */
+} cipherInstance;
+
+/* Function prototypes */
+/* CHANGED: nothing
+ TODO: implement the following extensions to setup 192-bit and 256-bit block lengths:
+ makeKeyEx(): parameter blockLen added
+ -- this parameter is absolutely necessary if you want to
+ setup the round keys in a variable block length setting
+ cipherInitEx(): parameter blockLen added (for obvious reasons)
*/
+
int makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial);
int cipherInit(cipherInstance *cipher, BYTE mode, char *IV);
-int blockEncrypt(cipherInstance *cipher, keyInstance *key, BYTE *input,
- int inputLen, BYTE *outBuffer);
+int blockEncrypt(cipherInstance *cipher, keyInstance *key,
+ BYTE *input, int inputLen, BYTE *outBuffer);
+
+int padEncrypt(cipherInstance *cipher, keyInstance *key,
+ BYTE *input, int inputOctets, BYTE *outBuffer);
+
+int blockDecrypt(cipherInstance *cipher, keyInstance *key,
+ BYTE *input, int inputLen, BYTE *outBuffer);
+
+int padDecrypt(cipherInstance *cipher, keyInstance *key,
+ BYTE *input, int inputOctets, BYTE *outBuffer);
+
+#ifdef INTERMEDIATE_VALUE_KAT
+int cipherUpdateRounds(cipherInstance *cipher, keyInstance *key,
+ BYTE *input, int inputLen, BYTE *outBuffer, int Rounds);
+#endif /* INTERMEDIATE_VALUE_KAT */
-int blockDecrypt(cipherInstance *cipher, keyInstance *key, BYTE *input,
- int inputLen, BYTE *outBuffer);
-int cipherUpdateRounds(cipherInstance *cipher, keyInstance *key, BYTE *input,
- int inputLen, BYTE *outBuffer, int Rounds);
+#endif /* __RIJNDAEL_API_FST_H */
Please sign in to comment.
Something went wrong with that request. Please try again.