os/security/cryptoplugins/cryptospiplugins/source/softwarecrypto/rijndaelimpl.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/cryptoplugins/cryptospiplugins/source/softwarecrypto/rijndaelimpl.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,484 @@
1.4 +/*
1.5 +* Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of the License "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +*
1.19 +*/
1.20 +
1.21 +
1.22 +#include "rijndaelimpl.h"
1.23 +#include "keys.h"
1.24 +
1.25 +#include "rijndaeltables.h"
1.26 +#include "common/inlines.h"
1.27 +#include "pluginconfig.h"
1.28 +#include "symmetriccipherimpl.h"
1.29 +#include <cryptostrength.h>
1.30 +
1.31 +using namespace SoftwareCrypto;
1.32 +
1.33 +const TUint KAESKeyBytes128 = 16;
1.34 +const TUint KAESKeyBytes192 = 24;
1.35 +const TUint KAESKeyBytes256 = 32;
1.36 +const TUint KAESBlockBytes = 16;
1.37 +
1.38 +/* CRijndaelmpl*/
1.39 +CRijndaelImpl::CRijndaelImpl(
1.40 + TUid aCryptoMode,
1.41 + TUid aOperationMode,
1.42 + TUid aPadding) :
1.43 + CSymmetricBlockCipherImpl(KAESBlockBytes, aCryptoMode, aOperationMode, aPadding)
1.44 + {
1.45 + }
1.46 +
1.47 +CRijndaelImpl* CRijndaelImpl::NewL(const CKey& aKey, TUid aCryptoMode, TUid aOperationMode, TUid aPadding)
1.48 + {
1.49 + CRijndaelImpl* self = CRijndaelImpl::NewLC(aKey, aCryptoMode, aOperationMode, aPadding);
1.50 + CleanupStack::Pop(self);
1.51 + return self;
1.52 + }
1.53 +
1.54 +CRijndaelImpl* CRijndaelImpl::NewLC(const CKey& aKey, TUid aCryptoMode, TUid aOperationMode, TUid aPadding)
1.55 + {
1.56 + CRijndaelImpl* self = new(ELeave) CRijndaelImpl(aCryptoMode, aOperationMode, aPadding);
1.57 + CleanupStack::PushL(self);
1.58 + self->ConstructL(aKey);
1.59 +
1.60 + const TDesC8& keyContent = aKey.GetTDesC8L(KSymmetricKeyParameterUid);
1.61 + TCrypto::IsSymmetricWeakEnoughL(BytesToBits(keyContent.Size()) - keyContent.Size());
1.62 + return self;
1.63 + }
1.64 +
1.65 +CRijndaelImpl::~CRijndaelImpl()
1.66 + {
1.67 + // make sure key information isn't visible to other processes if the
1.68 + // page is reused.
1.69 + Mem::FillZ(&iK, sizeof(iK));
1.70 + }
1.71 +
1.72 +void CRijndaelImpl::ConstructL(const CKey& aKey)
1.73 + {
1.74 + CSymmetricBlockCipherImpl::ConstructL(aKey);
1.75 + SetKeySchedule();
1.76 + }
1.77 +
1.78 +CExtendedCharacteristics* CRijndaelImpl::CreateExtendedCharacteristicsL()
1.79 + {
1.80 + // All Symbian software plug-ins have unlimited concurrency, cannot be reserved
1.81 + // for exclusive use and are not CERTIFIED to be standards compliant.
1.82 + return CExtendedCharacteristics::NewL(KMaxTInt, EFalse);
1.83 + }
1.84 +
1.85 +const CExtendedCharacteristics* CRijndaelImpl::GetExtendedCharacteristicsL()
1.86 + {
1.87 + return CRijndaelImpl::CreateExtendedCharacteristicsL();
1.88 + }
1.89 +
1.90 +TUid CRijndaelImpl::ImplementationUid() const
1.91 + {
1.92 + return KCryptoPluginAesUid;
1.93 + }
1.94 +
1.95 +TBool CRijndaelImpl::IsValidKeyLength(TInt aKeyBytes) const
1.96 + {
1.97 + switch(aKeyBytes)
1.98 + {
1.99 + case KAESKeyBytes128:
1.100 + case KAESKeyBytes192:
1.101 + case KAESKeyBytes256:
1.102 + return ETrue;
1.103 + default:
1.104 + return EFalse;
1.105 + }
1.106 + }
1.107 +
1.108 +void CRijndaelImpl::SetKeySchedule()
1.109 + {
1.110 + iRounds = iKeyBytes/4 + 6;
1.111 + if (iCryptoMode.iUid == KCryptoModeEncrypt)
1.112 + {
1.113 + SetEncryptKeySchedule(*iKey, &iK[0]);
1.114 + }
1.115 + else
1.116 + {
1.117 + ASSERT(iCryptoMode.iUid == KCryptoModeDecrypt);
1.118 + SetDecryptKeySchedule(*iKey, &iK[0]);
1.119 + }
1.120 + }
1.121 +
1.122 +void CRijndaelImpl::TransformEncrypt(
1.123 + TUint8* aBuffer,
1.124 + TUint aNumBlocks)
1.125 + {
1.126 + for (TInt i = 0; i < aNumBlocks; ++i)
1.127 + {
1.128 + ModeEncryptStart(aBuffer);
1.129 +
1.130 + TUint32 s0, s1, s2, s3, t0, t1, t2, t3;
1.131 + const TUint32* rk = &iK[0];
1.132 +
1.133 + /*
1.134 + * map byte array block to cipher state
1.135 + * and add initial round key:
1.136 + */
1.137 + GetBlockBigEndian(aBuffer, s0, s1, s2, s3);
1.138 + s0 ^= rk[0];
1.139 + s1 ^= rk[1];
1.140 + s2 ^= rk[2];
1.141 + s3 ^= rk[3];
1.142 + /*
1.143 + * Nr - 1 full rounds:
1.144 + */
1.145 + TUint r = iRounds >> 1;
1.146 + FOREVER
1.147 + {
1.148 + t0 =
1.149 + RIJNDAEL_TABLE::Te0[GETBYTE(s0, 3)] ^
1.150 + RIJNDAEL_TABLE::Te1[GETBYTE(s1, 2)] ^
1.151 + RIJNDAEL_TABLE::Te2[GETBYTE(s2, 1)] ^
1.152 + RIJNDAEL_TABLE::Te3[GETBYTE(s3, 0)] ^
1.153 + rk[4];
1.154 + t1 =
1.155 + RIJNDAEL_TABLE::Te0[GETBYTE(s1, 3)] ^
1.156 + RIJNDAEL_TABLE::Te1[GETBYTE(s2, 2)] ^
1.157 + RIJNDAEL_TABLE::Te2[GETBYTE(s3, 1)] ^
1.158 + RIJNDAEL_TABLE::Te3[GETBYTE(s0, 0)] ^
1.159 + rk[5];
1.160 + t2 =
1.161 + RIJNDAEL_TABLE::Te0[GETBYTE(s2, 3)] ^
1.162 + RIJNDAEL_TABLE::Te1[GETBYTE(s3, 2)] ^
1.163 + RIJNDAEL_TABLE::Te2[GETBYTE(s0, 1)] ^
1.164 + RIJNDAEL_TABLE::Te3[GETBYTE(s1, 0)] ^
1.165 + rk[6];
1.166 + t3 =
1.167 + RIJNDAEL_TABLE::Te0[GETBYTE(s3, 3)] ^
1.168 + RIJNDAEL_TABLE::Te1[GETBYTE(s0, 2)] ^
1.169 + RIJNDAEL_TABLE::Te2[GETBYTE(s1, 1)] ^
1.170 + RIJNDAEL_TABLE::Te3[GETBYTE(s2, 0)] ^
1.171 + rk[7];
1.172 +
1.173 + rk += 8;
1.174 + if (--r == 0)
1.175 + break;
1.176 +
1.177 + s0 =
1.178 + RIJNDAEL_TABLE::Te0[GETBYTE(t0, 3)] ^
1.179 + RIJNDAEL_TABLE::Te1[GETBYTE(t1, 2)] ^
1.180 + RIJNDAEL_TABLE::Te2[GETBYTE(t2, 1)] ^
1.181 + RIJNDAEL_TABLE::Te3[GETBYTE(t3, 0)] ^
1.182 + rk[0];
1.183 + s1 =
1.184 + RIJNDAEL_TABLE::Te0[GETBYTE(t1, 3)] ^
1.185 + RIJNDAEL_TABLE::Te1[GETBYTE(t2, 2)] ^
1.186 + RIJNDAEL_TABLE::Te2[GETBYTE(t3, 1)] ^
1.187 + RIJNDAEL_TABLE::Te3[GETBYTE(t0, 0)] ^
1.188 + rk[1];
1.189 + s2 =
1.190 + RIJNDAEL_TABLE::Te0[GETBYTE(t2, 3)] ^
1.191 + RIJNDAEL_TABLE::Te1[GETBYTE(t3, 2)] ^
1.192 + RIJNDAEL_TABLE::Te2[GETBYTE(t0, 1)] ^
1.193 + RIJNDAEL_TABLE::Te3[GETBYTE(t1, 0)] ^
1.194 + rk[2];
1.195 + s3 =
1.196 + RIJNDAEL_TABLE::Te0[GETBYTE(t3, 3)] ^
1.197 + RIJNDAEL_TABLE::Te1[GETBYTE(t0, 2)] ^
1.198 + RIJNDAEL_TABLE::Te2[GETBYTE(t1, 1)] ^
1.199 + RIJNDAEL_TABLE::Te3[GETBYTE(t2, 0)] ^
1.200 + rk[3];
1.201 + }
1.202 + /*
1.203 + * apply last round and
1.204 + * map cipher state to byte array block:
1.205 + */
1.206 +
1.207 + s0 =
1.208 + (RIJNDAEL_TABLE::Te4[GETBYTE(t0, 3)] & 0xff000000) ^
1.209 + (RIJNDAEL_TABLE::Te4[GETBYTE(t1, 2)] & 0x00ff0000) ^
1.210 + (RIJNDAEL_TABLE::Te4[GETBYTE(t2, 1)] & 0x0000ff00) ^
1.211 + (RIJNDAEL_TABLE::Te4[GETBYTE(t3, 0)] & 0x000000ff) ^
1.212 + rk[0];
1.213 + s1 =
1.214 + (RIJNDAEL_TABLE::Te4[GETBYTE(t1, 3)] & 0xff000000) ^
1.215 + (RIJNDAEL_TABLE::Te4[GETBYTE(t2, 2)] & 0x00ff0000) ^
1.216 + (RIJNDAEL_TABLE::Te4[GETBYTE(t3, 1)] & 0x0000ff00) ^
1.217 + (RIJNDAEL_TABLE::Te4[GETBYTE(t0, 0)] & 0x000000ff) ^
1.218 + rk[1];
1.219 + s2 =
1.220 + (RIJNDAEL_TABLE::Te4[GETBYTE(t2, 3)] & 0xff000000) ^
1.221 + (RIJNDAEL_TABLE::Te4[GETBYTE(t3, 2)] & 0x00ff0000) ^
1.222 + (RIJNDAEL_TABLE::Te4[GETBYTE(t0, 1)] & 0x0000ff00) ^
1.223 + (RIJNDAEL_TABLE::Te4[GETBYTE(t1, 0)] & 0x000000ff) ^
1.224 + rk[2];
1.225 + s3 =
1.226 + (RIJNDAEL_TABLE::Te4[GETBYTE(t3, 3)] & 0xff000000) ^
1.227 + (RIJNDAEL_TABLE::Te4[GETBYTE(t0, 2)] & 0x00ff0000) ^
1.228 + (RIJNDAEL_TABLE::Te4[GETBYTE(t1, 1)] & 0x0000ff00) ^
1.229 + (RIJNDAEL_TABLE::Te4[GETBYTE(t2, 0)] & 0x000000ff) ^
1.230 + rk[3];
1.231 +
1.232 + PutBlockBigEndian(aBuffer, s0, s1, s2, s3);
1.233 + ModeEncryptEnd(aBuffer);
1.234 + aBuffer += KAESBlockBytes;
1.235 + }
1.236 + }
1.237 +
1.238 +void CRijndaelImpl::TransformDecrypt(
1.239 + TUint8* aBuffer,
1.240 + TUint aNumBlocks)
1.241 + {
1.242 + for (TInt i = 0; i < aNumBlocks; ++i)
1.243 + {
1.244 + ModeDecryptStart(aBuffer);
1.245 +
1.246 + TUint32 s0, s1, s2, s3, t0, t1, t2, t3;
1.247 + const TUint32* rk = &iK[0];
1.248 +
1.249 + /*
1.250 + * map byte array block to cipher state
1.251 + * and add initial round key:
1.252 + */
1.253 + GetBlockBigEndian(aBuffer, s0, s1, s2, s3);
1.254 +
1.255 + s0 ^= rk[0];
1.256 + s1 ^= rk[1];
1.257 + s2 ^= rk[2];
1.258 + s3 ^= rk[3];
1.259 + /*
1.260 + * Nr - 1 full rounds:
1.261 + */
1.262 + TUint r = iRounds >> 1;
1.263 + FOREVER
1.264 + {
1.265 + t0 =
1.266 + RIJNDAEL_TABLE::Td0[GETBYTE(s0, 3)] ^
1.267 + RIJNDAEL_TABLE::Td1[GETBYTE(s3, 2)] ^
1.268 + RIJNDAEL_TABLE::Td2[GETBYTE(s2, 1)] ^
1.269 + RIJNDAEL_TABLE::Td3[GETBYTE(s1, 0)] ^
1.270 + rk[4];
1.271 + t1 =
1.272 + RIJNDAEL_TABLE::Td0[GETBYTE(s1, 3)] ^
1.273 + RIJNDAEL_TABLE::Td1[GETBYTE(s0, 2)] ^
1.274 + RIJNDAEL_TABLE::Td2[GETBYTE(s3, 1)] ^
1.275 + RIJNDAEL_TABLE::Td3[GETBYTE(s2, 0)] ^
1.276 + rk[5];
1.277 + t2 =
1.278 + RIJNDAEL_TABLE::Td0[GETBYTE(s2, 3)] ^
1.279 + RIJNDAEL_TABLE::Td1[GETBYTE(s1, 2)] ^
1.280 + RIJNDAEL_TABLE::Td2[GETBYTE(s0, 1)] ^
1.281 + RIJNDAEL_TABLE::Td3[GETBYTE(s3, 0)] ^
1.282 + rk[6];
1.283 + t3 =
1.284 + RIJNDAEL_TABLE::Td0[GETBYTE(s3, 3)] ^
1.285 + RIJNDAEL_TABLE::Td1[GETBYTE(s2, 2)] ^
1.286 + RIJNDAEL_TABLE::Td2[GETBYTE(s1, 1)] ^
1.287 + RIJNDAEL_TABLE::Td3[GETBYTE(s0, 0)] ^
1.288 + rk[7];
1.289 +
1.290 + rk += 8;
1.291 + if (--r == 0)
1.292 + break;
1.293 +
1.294 + s0 =
1.295 + RIJNDAEL_TABLE::Td0[GETBYTE(t0, 3)] ^
1.296 + RIJNDAEL_TABLE::Td1[GETBYTE(t3, 2)] ^
1.297 + RIJNDAEL_TABLE::Td2[GETBYTE(t2, 1)] ^
1.298 + RIJNDAEL_TABLE::Td3[GETBYTE(t1, 0)] ^
1.299 + rk[0];
1.300 + s1 =
1.301 + RIJNDAEL_TABLE::Td0[GETBYTE(t1, 3)] ^
1.302 + RIJNDAEL_TABLE::Td1[GETBYTE(t0, 2)] ^
1.303 + RIJNDAEL_TABLE::Td2[GETBYTE(t3, 1)] ^
1.304 + RIJNDAEL_TABLE::Td3[GETBYTE(t2, 0)] ^
1.305 + rk[1];
1.306 + s2 =
1.307 + RIJNDAEL_TABLE::Td0[GETBYTE(t2, 3)] ^
1.308 + RIJNDAEL_TABLE::Td1[GETBYTE(t1, 2)] ^
1.309 + RIJNDAEL_TABLE::Td2[GETBYTE(t0, 1)] ^
1.310 + RIJNDAEL_TABLE::Td3[GETBYTE(t3, 0)] ^
1.311 + rk[2];
1.312 + s3 =
1.313 + RIJNDAEL_TABLE::Td0[GETBYTE(t3, 3)] ^
1.314 + RIJNDAEL_TABLE::Td1[GETBYTE(t2, 2)] ^
1.315 + RIJNDAEL_TABLE::Td2[GETBYTE(t1, 1)] ^
1.316 + RIJNDAEL_TABLE::Td3[GETBYTE(t0, 0)] ^
1.317 + rk[3];
1.318 + }
1.319 + /*
1.320 + * apply last round and
1.321 + * map cipher state to byte array block:
1.322 + */
1.323 + s0 =
1.324 + (RIJNDAEL_TABLE::Td4[GETBYTE(t0, 3)] & 0xff000000) ^
1.325 + (RIJNDAEL_TABLE::Td4[GETBYTE(t3, 2)] & 0x00ff0000) ^
1.326 + (RIJNDAEL_TABLE::Td4[GETBYTE(t2, 1)] & 0x0000ff00) ^
1.327 + (RIJNDAEL_TABLE::Td4[GETBYTE(t1, 0)] & 0x000000ff) ^
1.328 + rk[0];
1.329 + s1 =
1.330 + (RIJNDAEL_TABLE::Td4[GETBYTE(t1, 3)] & 0xff000000) ^
1.331 + (RIJNDAEL_TABLE::Td4[GETBYTE(t0, 2)] & 0x00ff0000) ^
1.332 + (RIJNDAEL_TABLE::Td4[GETBYTE(t3, 1)] & 0x0000ff00) ^
1.333 + (RIJNDAEL_TABLE::Td4[GETBYTE(t2, 0)] & 0x000000ff) ^
1.334 + rk[1];
1.335 + s2 =
1.336 + (RIJNDAEL_TABLE::Td4[GETBYTE(t2, 3)] & 0xff000000) ^
1.337 + (RIJNDAEL_TABLE::Td4[GETBYTE(t1, 2)] & 0x00ff0000) ^
1.338 + (RIJNDAEL_TABLE::Td4[GETBYTE(t0, 1)] & 0x0000ff00) ^
1.339 + (RIJNDAEL_TABLE::Td4[GETBYTE(t3, 0)] & 0x000000ff) ^
1.340 + rk[2];
1.341 + s3 =
1.342 + (RIJNDAEL_TABLE::Td4[GETBYTE(t3, 3)] & 0xff000000) ^
1.343 + (RIJNDAEL_TABLE::Td4[GETBYTE(t2, 2)] & 0x00ff0000) ^
1.344 + (RIJNDAEL_TABLE::Td4[GETBYTE(t1, 1)] & 0x0000ff00) ^
1.345 + (RIJNDAEL_TABLE::Td4[GETBYTE(t0, 0)] & 0x000000ff) ^
1.346 + rk[3];
1.347 + PutBlockBigEndian(aBuffer, s0, s1, s2, s3);
1.348 + ModeDecryptEnd(aBuffer);
1.349 + aBuffer += KAESBlockBytes;
1.350 + }
1.351 + }
1.352 +
1.353 +void CRijndaelImpl::SetEncryptKeySchedule(const TDesC8& aKey, TUint32* aKeySchedule)
1.354 + {
1.355 + TUint keySize = aKey.Length();
1.356 + TUint32 temp;
1.357 + TUint32* rk = aKeySchedule;
1.358 +
1.359 + TUint i = 0;
1.360 +
1.361 + GetUserKeyBigEndian(rk, keySize/4, &aKey[0], keySize);
1.362 +
1.363 + switch(keySize)
1.364 + {
1.365 + case (KAESKeyBytes128):
1.366 + {
1.367 + FOREVER
1.368 + {
1.369 + temp = rk[3];
1.370 + rk[4] = rk[0] ^
1.371 + (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 2)] & 0xff000000) ^
1.372 + (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^
1.373 + (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^
1.374 + (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 3)] & 0x000000ff) ^
1.375 + RIJNDAEL_TABLE::rcon[i];
1.376 + rk[5] = rk[1] ^ rk[4];
1.377 + rk[6] = rk[2] ^ rk[5];
1.378 + rk[7] = rk[3] ^ rk[6];
1.379 + if (++i == 10)
1.380 + break;
1.381 + rk += 4;
1.382 + }
1.383 + }
1.384 + break;
1.385 +
1.386 + case (KAESKeyBytes192):
1.387 + {
1.388 + FOREVER
1.389 + {
1.390 + temp = rk[ 5];
1.391 + rk[ 6] = rk[ 0] ^
1.392 + (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 2)] & 0xff000000) ^
1.393 + (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^
1.394 + (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^
1.395 + (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 3)] & 0x000000ff) ^
1.396 + RIJNDAEL_TABLE::rcon[i];
1.397 + rk[ 7] = rk[ 1] ^ rk[ 6];
1.398 + rk[ 8] = rk[ 2] ^ rk[ 7];
1.399 + rk[ 9] = rk[ 3] ^ rk[ 8];
1.400 + if (++i == 8)
1.401 + break;
1.402 + rk[10] = rk[ 4] ^ rk[ 9];
1.403 + rk[11] = rk[ 5] ^ rk[10];
1.404 + rk += 6;
1.405 + }
1.406 + }
1.407 + break;
1.408 +
1.409 + case (KAESKeyBytes256):
1.410 + {
1.411 + FOREVER
1.412 + {
1.413 + temp = rk[ 7];
1.414 + rk[ 8] = rk[ 0] ^
1.415 + (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 2)] & 0xff000000) ^
1.416 + (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^
1.417 + (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^
1.418 + (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 3)] & 0x000000ff) ^
1.419 + RIJNDAEL_TABLE::rcon[i];
1.420 + rk[ 9] = rk[ 1] ^ rk[ 8];
1.421 + rk[10] = rk[ 2] ^ rk[ 9];
1.422 + rk[11] = rk[ 3] ^ rk[10];
1.423 + if (++i == 7)
1.424 + break;
1.425 + temp = rk[11];
1.426 + rk[12] = rk[ 4] ^
1.427 + (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 3)] & 0xff000000) ^
1.428 + (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 2)] & 0x00ff0000) ^
1.429 + (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 1)] & 0x0000ff00) ^
1.430 + (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 0)] & 0x000000ff);
1.431 + rk[13] = rk[ 5] ^ rk[12];
1.432 + rk[14] = rk[ 6] ^ rk[13];
1.433 + rk[15] = rk[ 7] ^ rk[14];
1.434 +
1.435 + rk += 8;
1.436 + }
1.437 + }
1.438 + break;
1.439 +
1.440 + default:
1.441 + assert(0); // Shouldn't get here, keeps compiler happy
1.442 + }
1.443 + }
1.444 +
1.445 +void CRijndaelImpl::SetDecryptKeySchedule(const TDesC8& aKey, TUint32* aKeySchedule)
1.446 + {
1.447 + SetEncryptKeySchedule(aKey, aKeySchedule);
1.448 +
1.449 + TUint i, j;
1.450 + TUint32* rk = aKeySchedule;
1.451 + TUint32 temp;
1.452 +
1.453 + // invert the order of the round keys
1.454 + for (i = 0, j = 4*iRounds; i < j; i += 4, j -= 4)
1.455 + {
1.456 + temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
1.457 + temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
1.458 + temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
1.459 + temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
1.460 + }
1.461 +
1.462 + // apply the inverse MixColumn transform to all round keys but the first and the last
1.463 + for (i = 1; i < iRounds; i++)
1.464 + {
1.465 + rk += 4;
1.466 + rk[0] =
1.467 + RIJNDAEL_TABLE::Td0[RIJNDAEL_TABLE::Te4[GETBYTE(rk[0], 3)] & 0xff] ^
1.468 + RIJNDAEL_TABLE::Td1[RIJNDAEL_TABLE::Te4[GETBYTE(rk[0], 2)] & 0xff] ^
1.469 + RIJNDAEL_TABLE::Td2[RIJNDAEL_TABLE::Te4[GETBYTE(rk[0], 1)] & 0xff] ^
1.470 + RIJNDAEL_TABLE::Td3[RIJNDAEL_TABLE::Te4[GETBYTE(rk[0], 0)] & 0xff];
1.471 + rk[1] =
1.472 + RIJNDAEL_TABLE::Td0[RIJNDAEL_TABLE::Te4[GETBYTE(rk[1], 3)] & 0xff] ^
1.473 + RIJNDAEL_TABLE::Td1[RIJNDAEL_TABLE::Te4[GETBYTE(rk[1], 2)] & 0xff] ^
1.474 + RIJNDAEL_TABLE::Td2[RIJNDAEL_TABLE::Te4[GETBYTE(rk[1], 1)] & 0xff] ^
1.475 + RIJNDAEL_TABLE::Td3[RIJNDAEL_TABLE::Te4[GETBYTE(rk[1], 0)] & 0xff];
1.476 + rk[2] =
1.477 + RIJNDAEL_TABLE::Td0[RIJNDAEL_TABLE::Te4[GETBYTE(rk[2], 3)] & 0xff] ^
1.478 + RIJNDAEL_TABLE::Td1[RIJNDAEL_TABLE::Te4[GETBYTE(rk[2], 2)] & 0xff] ^
1.479 + RIJNDAEL_TABLE::Td2[RIJNDAEL_TABLE::Te4[GETBYTE(rk[2], 1)] & 0xff] ^
1.480 + RIJNDAEL_TABLE::Td3[RIJNDAEL_TABLE::Te4[GETBYTE(rk[2], 0)] & 0xff];
1.481 + rk[3] =
1.482 + RIJNDAEL_TABLE::Td0[RIJNDAEL_TABLE::Te4[GETBYTE(rk[3], 3)] & 0xff] ^
1.483 + RIJNDAEL_TABLE::Td1[RIJNDAEL_TABLE::Te4[GETBYTE(rk[3], 2)] & 0xff] ^
1.484 + RIJNDAEL_TABLE::Td2[RIJNDAEL_TABLE::Te4[GETBYTE(rk[3], 1)] & 0xff] ^
1.485 + RIJNDAEL_TABLE::Td3[RIJNDAEL_TABLE::Te4[GETBYTE(rk[3], 0)] & 0xff];
1.486 + }
1.487 + }