00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
#include "pch.h"
00032
#include "rijndael.h"
00033
#include "misc.h"
00034
00035 NAMESPACE_BEGIN(CryptoPP)
00036
00037 void
Rijndael::Base::UncheckedSetKey(CipherDir dir, const byte *userKey,
unsigned int keylen)
00038 {
00039 AssertValidKeyLength(keylen);
00040
00041 m_rounds = keylen/4 + 6;
00042 m_key.New(4*(m_rounds+1));
00043
00044 word32 temp, *rk = m_key;
00045
unsigned int i=0;
00046
00047 GetUserKey(BIG_ENDIAN_ORDER, rk, keylen/4, userKey, keylen);
00048
00049
switch(keylen)
00050 {
00051
case 16:
00052
while (
true)
00053 {
00054 temp = rk[3];
00055 rk[4] = rk[0] ^
00056 (Te4[GETBYTE(temp, 2)] & 0xff000000) ^
00057 (Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^
00058 (Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^
00059 (Te4[GETBYTE(temp, 3)] & 0x000000ff) ^
00060 rcon[i];
00061 rk[5] = rk[1] ^ rk[4];
00062 rk[6] = rk[2] ^ rk[5];
00063 rk[7] = rk[3] ^ rk[6];
00064
if (++i == 10)
00065
break;
00066 rk += 4;
00067 }
00068
break;
00069
00070
case 24:
00071
while (
true)
00072 {
00073 temp = rk[ 5];
00074 rk[ 6] = rk[ 0] ^
00075 (Te4[GETBYTE(temp, 2)] & 0xff000000) ^
00076 (Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^
00077 (Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^
00078 (Te4[GETBYTE(temp, 3)] & 0x000000ff) ^
00079 rcon[i];
00080 rk[ 7] = rk[ 1] ^ rk[ 6];
00081 rk[ 8] = rk[ 2] ^ rk[ 7];
00082 rk[ 9] = rk[ 3] ^ rk[ 8];
00083
if (++i == 8)
00084
break;
00085 rk[10] = rk[ 4] ^ rk[ 9];
00086 rk[11] = rk[ 5] ^ rk[10];
00087 rk += 6;
00088 }
00089
break;
00090
00091
case 32:
00092
while (
true)
00093 {
00094 temp = rk[ 7];
00095 rk[ 8] = rk[ 0] ^
00096 (Te4[GETBYTE(temp, 2)] & 0xff000000) ^
00097 (Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^
00098 (Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^
00099 (Te4[GETBYTE(temp, 3)] & 0x000000ff) ^
00100 rcon[i];
00101 rk[ 9] = rk[ 1] ^ rk[ 8];
00102 rk[10] = rk[ 2] ^ rk[ 9];
00103 rk[11] = rk[ 3] ^ rk[10];
00104
if (++i == 7)
00105
break;
00106 temp = rk[11];
00107 rk[12] = rk[ 4] ^
00108 (Te4[GETBYTE(temp, 3)] & 0xff000000) ^
00109 (Te4[GETBYTE(temp, 2)] & 0x00ff0000) ^
00110 (Te4[GETBYTE(temp, 1)] & 0x0000ff00) ^
00111 (Te4[GETBYTE(temp, 0)] & 0x000000ff);
00112 rk[13] = rk[ 5] ^ rk[12];
00113 rk[14] = rk[ 6] ^ rk[13];
00114 rk[15] = rk[ 7] ^ rk[14];
00115
00116 rk += 8;
00117 }
00118
break;
00119 }
00120
00121
if (dir == DECRYPTION)
00122 {
00123
unsigned int i, j;
00124 rk = m_key;
00125
00126
00127
for (i = 0, j = 4*m_rounds; i < j; i += 4, j -= 4) {
00128 temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
00129 temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
00130 temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
00131 temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
00132 }
00133
00134
for (i = 1; i < m_rounds; i++) {
00135 rk += 4;
00136 rk[0] =
00137 Td0[Te4[GETBYTE(rk[0], 3)] & 0xff] ^
00138 Td1[Te4[GETBYTE(rk[0], 2)] & 0xff] ^
00139 Td2[Te4[GETBYTE(rk[0], 1)] & 0xff] ^
00140 Td3[Te4[GETBYTE(rk[0], 0)] & 0xff];
00141 rk[1] =
00142 Td0[Te4[GETBYTE(rk[1], 3)] & 0xff] ^
00143 Td1[Te4[GETBYTE(rk[1], 2)] & 0xff] ^
00144 Td2[Te4[GETBYTE(rk[1], 1)] & 0xff] ^
00145 Td3[Te4[GETBYTE(rk[1], 0)] & 0xff];
00146 rk[2] =
00147 Td0[Te4[GETBYTE(rk[2], 3)] & 0xff] ^
00148 Td1[Te4[GETBYTE(rk[2], 2)] & 0xff] ^
00149 Td2[Te4[GETBYTE(rk[2], 1)] & 0xff] ^
00150 Td3[Te4[GETBYTE(rk[2], 0)] & 0xff];
00151 rk[3] =
00152 Td0[Te4[GETBYTE(rk[3], 3)] & 0xff] ^
00153 Td1[Te4[GETBYTE(rk[3], 2)] & 0xff] ^
00154 Td2[Te4[GETBYTE(rk[3], 1)] & 0xff] ^
00155 Td3[Te4[GETBYTE(rk[3], 0)] & 0xff];
00156 }
00157 }
00158 }
00159
00160
typedef BlockGetAndPut<word32, BigEndian> Block;
00161
00162
void Rijndael::Enc::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock, byte *outBlock)
const
00163
{
00164 word32 s0, s1, s2, s3, t0, t1, t2, t3;
00165
const word32 *rk = m_key;
00166
00167
00168
00169
00170
00171 Block::Get(inBlock)(s0)(s1)(s2)(s3);
00172 s0 ^= rk[0];
00173 s1 ^= rk[1];
00174 s2 ^= rk[2];
00175 s3 ^= rk[3];
00176
00177
00178
00179
unsigned int r = m_rounds >> 1;
00180
for (;;) {
00181 t0 =
00182 Te0[GETBYTE(s0, 3)] ^
00183 Te1[GETBYTE(s1, 2)] ^
00184 Te2[GETBYTE(s2, 1)] ^
00185 Te3[GETBYTE(s3, 0)] ^
00186 rk[4];
00187 t1 =
00188 Te0[GETBYTE(s1, 3)] ^
00189 Te1[GETBYTE(s2, 2)] ^
00190 Te2[GETBYTE(s3, 1)] ^
00191 Te3[GETBYTE(s0, 0)] ^
00192 rk[5];
00193 t2 =
00194 Te0[GETBYTE(s2, 3)] ^
00195 Te1[GETBYTE(s3, 2)] ^
00196 Te2[GETBYTE(s0, 1)] ^
00197 Te3[GETBYTE(s1, 0)] ^
00198 rk[6];
00199 t3 =
00200 Te0[GETBYTE(s3, 3)] ^
00201 Te1[GETBYTE(s0, 2)] ^
00202 Te2[GETBYTE(s1, 1)] ^
00203 Te3[GETBYTE(s2, 0)] ^
00204 rk[7];
00205
00206 rk += 8;
00207
if (--r == 0) {
00208
break;
00209 }
00210
00211 s0 =
00212 Te0[GETBYTE(t0, 3)] ^
00213 Te1[GETBYTE(t1, 2)] ^
00214 Te2[GETBYTE(t2, 1)] ^
00215 Te3[GETBYTE(t3, 0)] ^
00216 rk[0];
00217 s1 =
00218 Te0[GETBYTE(t1, 3)] ^
00219 Te1[GETBYTE(t2, 2)] ^
00220 Te2[GETBYTE(t3, 1)] ^
00221 Te3[GETBYTE(t0, 0)] ^
00222 rk[1];
00223 s2 =
00224 Te0[GETBYTE(t2, 3)] ^
00225 Te1[GETBYTE(t3, 2)] ^
00226 Te2[GETBYTE(t0, 1)] ^
00227 Te3[GETBYTE(t1, 0)] ^
00228 rk[2];
00229 s3 =
00230 Te0[GETBYTE(t3, 3)] ^
00231 Te1[GETBYTE(t0, 2)] ^
00232 Te2[GETBYTE(t1, 1)] ^
00233 Te3[GETBYTE(t2, 0)] ^
00234 rk[3];
00235 }
00236
00237
00238
00239
00240
00241 s0 =
00242 (Te4[GETBYTE(t0, 3)] & 0xff000000) ^
00243 (Te4[GETBYTE(t1, 2)] & 0x00ff0000) ^
00244 (Te4[GETBYTE(t2, 1)] & 0x0000ff00) ^
00245 (Te4[GETBYTE(t3, 0)] & 0x000000ff) ^
00246 rk[0];
00247 s1 =
00248 (Te4[GETBYTE(t1, 3)] & 0xff000000) ^
00249 (Te4[GETBYTE(t2, 2)] & 0x00ff0000) ^
00250 (Te4[GETBYTE(t3, 1)] & 0x0000ff00) ^
00251 (Te4[GETBYTE(t0, 0)] & 0x000000ff) ^
00252 rk[1];
00253 s2 =
00254 (Te4[GETBYTE(t2, 3)] & 0xff000000) ^
00255 (Te4[GETBYTE(t3, 2)] & 0x00ff0000) ^
00256 (Te4[GETBYTE(t0, 1)] & 0x0000ff00) ^
00257 (Te4[GETBYTE(t1, 0)] & 0x000000ff) ^
00258 rk[2];
00259 s3 =
00260 (Te4[GETBYTE(t3, 3)] & 0xff000000) ^
00261 (Te4[GETBYTE(t0, 2)] & 0x00ff0000) ^
00262 (Te4[GETBYTE(t1, 1)] & 0x0000ff00) ^
00263 (Te4[GETBYTE(t2, 0)] & 0x000000ff) ^
00264 rk[3];
00265
00266 Block::Put(xorBlock, outBlock)(s0)(s1)(s2)(s3);
00267 }
00268
00269
void Rijndael::Dec::ProcessAndXorBlock(
const byte *inBlock,
const byte *xorBlock, byte *outBlock)
const
00270
{
00271 word32 s0, s1, s2, s3, t0, t1, t2, t3;
00272
const word32 *rk = m_key;
00273
00274
00275
00276
00277
00278 Block::Get(inBlock)(s0)(s1)(s2)(s3);
00279 s0 ^= rk[0];
00280 s1 ^= rk[1];
00281 s2 ^= rk[2];
00282 s3 ^= rk[3];
00283
00284
00285
00286
unsigned int r = m_rounds >> 1;
00287
for (;;) {
00288 t0 =
00289 Td0[GETBYTE(s0, 3)] ^
00290 Td1[GETBYTE(s3, 2)] ^
00291 Td2[GETBYTE(s2, 1)] ^
00292 Td3[GETBYTE(s1, 0)] ^
00293 rk[4];
00294 t1 =
00295 Td0[GETBYTE(s1, 3)] ^
00296 Td1[GETBYTE(s0, 2)] ^
00297 Td2[GETBYTE(s3, 1)] ^
00298 Td3[GETBYTE(s2, 0)] ^
00299 rk[5];
00300 t2 =
00301 Td0[GETBYTE(s2, 3)] ^
00302 Td1[GETBYTE(s1, 2)] ^
00303 Td2[GETBYTE(s0, 1)] ^
00304 Td3[GETBYTE(s3, 0)] ^
00305 rk[6];
00306 t3 =
00307 Td0[GETBYTE(s3, 3)] ^
00308 Td1[GETBYTE(s2, 2)] ^
00309 Td2[GETBYTE(s1, 1)] ^
00310 Td3[GETBYTE(s0, 0)] ^
00311 rk[7];
00312
00313 rk += 8;
00314
if (--r == 0) {
00315
break;
00316 }
00317
00318 s0 =
00319 Td0[GETBYTE(t0, 3)] ^
00320 Td1[GETBYTE(t3, 2)] ^
00321 Td2[GETBYTE(t2, 1)] ^
00322 Td3[GETBYTE(t1, 0)] ^
00323 rk[0];
00324 s1 =
00325 Td0[GETBYTE(t1, 3)] ^
00326 Td1[GETBYTE(t0, 2)] ^
00327 Td2[GETBYTE(t3, 1)] ^
00328 Td3[GETBYTE(t2, 0)] ^
00329 rk[1];
00330 s2 =
00331 Td0[GETBYTE(t2, 3)] ^
00332 Td1[GETBYTE(t1, 2)] ^
00333 Td2[GETBYTE(t0, 1)] ^
00334 Td3[GETBYTE(t3, 0)] ^
00335 rk[2];
00336 s3 =
00337 Td0[GETBYTE(t3, 3)] ^
00338 Td1[GETBYTE(t2, 2)] ^
00339 Td2[GETBYTE(t1, 1)] ^
00340 Td3[GETBYTE(t0, 0)] ^
00341 rk[3];
00342 }
00343
00344
00345
00346
00347 s0 =
00348 (Td4[GETBYTE(t0, 3)] & 0xff000000) ^
00349 (Td4[GETBYTE(t3, 2)] & 0x00ff0000) ^
00350 (Td4[GETBYTE(t2, 1)] & 0x0000ff00) ^
00351 (Td4[GETBYTE(t1, 0)] & 0x000000ff) ^
00352 rk[0];
00353 s1 =
00354 (Td4[GETBYTE(t1, 3)] & 0xff000000) ^
00355 (Td4[GETBYTE(t0, 2)] & 0x00ff0000) ^
00356 (Td4[GETBYTE(t3, 1)] & 0x0000ff00) ^
00357 (Td4[GETBYTE(t2, 0)] & 0x000000ff) ^
00358 rk[1];
00359 s2 =
00360 (Td4[GETBYTE(t2, 3)] & 0xff000000) ^
00361 (Td4[GETBYTE(t1, 2)] & 0x00ff0000) ^
00362 (Td4[GETBYTE(t0, 1)] & 0x0000ff00) ^
00363 (Td4[GETBYTE(t3, 0)] & 0x000000ff) ^
00364 rk[2];
00365 s3 =
00366 (Td4[GETBYTE(t3, 3)] & 0xff000000) ^
00367 (Td4[GETBYTE(t2, 2)] & 0x00ff0000) ^
00368 (Td4[GETBYTE(t1, 1)] & 0x0000ff00) ^
00369 (Td4[GETBYTE(t0, 0)] & 0x000000ff) ^
00370 rk[3];
00371
00372 Block::Put(xorBlock, outBlock)(s0)(s1)(s2)(s3);
00373 }
00374
00375 NAMESPACE_END