sl@0: /* sl@0: * Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * sl@0: */ sl@0: sl@0: sl@0: #include "rijndaelimpl.h" sl@0: #include "keys.h" sl@0: sl@0: #include "rijndaeltables.h" sl@0: #include "common/inlines.h" sl@0: #include "pluginconfig.h" sl@0: #include "symmetriccipherimpl.h" sl@0: #include sl@0: sl@0: using namespace SoftwareCrypto; sl@0: sl@0: const TUint KAESKeyBytes128 = 16; sl@0: const TUint KAESKeyBytes192 = 24; sl@0: const TUint KAESKeyBytes256 = 32; sl@0: const TUint KAESBlockBytes = 16; sl@0: sl@0: /* CRijndaelmpl*/ sl@0: CRijndaelImpl::CRijndaelImpl( sl@0: TUid aCryptoMode, sl@0: TUid aOperationMode, sl@0: TUid aPadding) : sl@0: CSymmetricBlockCipherImpl(KAESBlockBytes, aCryptoMode, aOperationMode, aPadding) sl@0: { sl@0: } sl@0: sl@0: CRijndaelImpl* CRijndaelImpl::NewL(const CKey& aKey, TUid aCryptoMode, TUid aOperationMode, TUid aPadding) sl@0: { sl@0: CRijndaelImpl* self = CRijndaelImpl::NewLC(aKey, aCryptoMode, aOperationMode, aPadding); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: CRijndaelImpl* CRijndaelImpl::NewLC(const CKey& aKey, TUid aCryptoMode, TUid aOperationMode, TUid aPadding) sl@0: { sl@0: CRijndaelImpl* self = new(ELeave) CRijndaelImpl(aCryptoMode, aOperationMode, aPadding); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aKey); sl@0: sl@0: const TDesC8& keyContent = aKey.GetTDesC8L(KSymmetricKeyParameterUid); sl@0: TCrypto::IsSymmetricWeakEnoughL(BytesToBits(keyContent.Size()) - keyContent.Size()); sl@0: return self; sl@0: } sl@0: sl@0: CRijndaelImpl::~CRijndaelImpl() sl@0: { sl@0: // make sure key information isn't visible to other processes if the sl@0: // page is reused. sl@0: Mem::FillZ(&iK, sizeof(iK)); sl@0: } sl@0: sl@0: void CRijndaelImpl::ConstructL(const CKey& aKey) sl@0: { sl@0: CSymmetricBlockCipherImpl::ConstructL(aKey); sl@0: SetKeySchedule(); sl@0: } sl@0: sl@0: CExtendedCharacteristics* CRijndaelImpl::CreateExtendedCharacteristicsL() sl@0: { sl@0: // All Symbian software plug-ins have unlimited concurrency, cannot be reserved sl@0: // for exclusive use and are not CERTIFIED to be standards compliant. sl@0: return CExtendedCharacteristics::NewL(KMaxTInt, EFalse); sl@0: } sl@0: sl@0: const CExtendedCharacteristics* CRijndaelImpl::GetExtendedCharacteristicsL() sl@0: { sl@0: return CRijndaelImpl::CreateExtendedCharacteristicsL(); sl@0: } sl@0: sl@0: TUid CRijndaelImpl::ImplementationUid() const sl@0: { sl@0: return KCryptoPluginAesUid; sl@0: } sl@0: sl@0: TBool CRijndaelImpl::IsValidKeyLength(TInt aKeyBytes) const sl@0: { sl@0: switch(aKeyBytes) sl@0: { sl@0: case KAESKeyBytes128: sl@0: case KAESKeyBytes192: sl@0: case KAESKeyBytes256: sl@0: return ETrue; sl@0: default: sl@0: return EFalse; sl@0: } sl@0: } sl@0: sl@0: void CRijndaelImpl::SetKeySchedule() sl@0: { sl@0: iRounds = iKeyBytes/4 + 6; sl@0: if (iCryptoMode.iUid == KCryptoModeEncrypt) sl@0: { sl@0: SetEncryptKeySchedule(*iKey, &iK[0]); sl@0: } sl@0: else sl@0: { sl@0: ASSERT(iCryptoMode.iUid == KCryptoModeDecrypt); sl@0: SetDecryptKeySchedule(*iKey, &iK[0]); sl@0: } sl@0: } sl@0: sl@0: void CRijndaelImpl::TransformEncrypt( sl@0: TUint8* aBuffer, sl@0: TUint aNumBlocks) sl@0: { sl@0: for (TInt i = 0; i < aNumBlocks; ++i) sl@0: { sl@0: ModeEncryptStart(aBuffer); sl@0: sl@0: TUint32 s0, s1, s2, s3, t0, t1, t2, t3; sl@0: const TUint32* rk = &iK[0]; sl@0: sl@0: /* sl@0: * map byte array block to cipher state sl@0: * and add initial round key: sl@0: */ sl@0: GetBlockBigEndian(aBuffer, s0, s1, s2, s3); sl@0: s0 ^= rk[0]; sl@0: s1 ^= rk[1]; sl@0: s2 ^= rk[2]; sl@0: s3 ^= rk[3]; sl@0: /* sl@0: * Nr - 1 full rounds: sl@0: */ sl@0: TUint r = iRounds >> 1; sl@0: FOREVER sl@0: { sl@0: t0 = sl@0: RIJNDAEL_TABLE::Te0[GETBYTE(s0, 3)] ^ sl@0: RIJNDAEL_TABLE::Te1[GETBYTE(s1, 2)] ^ sl@0: RIJNDAEL_TABLE::Te2[GETBYTE(s2, 1)] ^ sl@0: RIJNDAEL_TABLE::Te3[GETBYTE(s3, 0)] ^ sl@0: rk[4]; sl@0: t1 = sl@0: RIJNDAEL_TABLE::Te0[GETBYTE(s1, 3)] ^ sl@0: RIJNDAEL_TABLE::Te1[GETBYTE(s2, 2)] ^ sl@0: RIJNDAEL_TABLE::Te2[GETBYTE(s3, 1)] ^ sl@0: RIJNDAEL_TABLE::Te3[GETBYTE(s0, 0)] ^ sl@0: rk[5]; sl@0: t2 = sl@0: RIJNDAEL_TABLE::Te0[GETBYTE(s2, 3)] ^ sl@0: RIJNDAEL_TABLE::Te1[GETBYTE(s3, 2)] ^ sl@0: RIJNDAEL_TABLE::Te2[GETBYTE(s0, 1)] ^ sl@0: RIJNDAEL_TABLE::Te3[GETBYTE(s1, 0)] ^ sl@0: rk[6]; sl@0: t3 = sl@0: RIJNDAEL_TABLE::Te0[GETBYTE(s3, 3)] ^ sl@0: RIJNDAEL_TABLE::Te1[GETBYTE(s0, 2)] ^ sl@0: RIJNDAEL_TABLE::Te2[GETBYTE(s1, 1)] ^ sl@0: RIJNDAEL_TABLE::Te3[GETBYTE(s2, 0)] ^ sl@0: rk[7]; sl@0: sl@0: rk += 8; sl@0: if (--r == 0) sl@0: break; sl@0: sl@0: s0 = sl@0: RIJNDAEL_TABLE::Te0[GETBYTE(t0, 3)] ^ sl@0: RIJNDAEL_TABLE::Te1[GETBYTE(t1, 2)] ^ sl@0: RIJNDAEL_TABLE::Te2[GETBYTE(t2, 1)] ^ sl@0: RIJNDAEL_TABLE::Te3[GETBYTE(t3, 0)] ^ sl@0: rk[0]; sl@0: s1 = sl@0: RIJNDAEL_TABLE::Te0[GETBYTE(t1, 3)] ^ sl@0: RIJNDAEL_TABLE::Te1[GETBYTE(t2, 2)] ^ sl@0: RIJNDAEL_TABLE::Te2[GETBYTE(t3, 1)] ^ sl@0: RIJNDAEL_TABLE::Te3[GETBYTE(t0, 0)] ^ sl@0: rk[1]; sl@0: s2 = sl@0: RIJNDAEL_TABLE::Te0[GETBYTE(t2, 3)] ^ sl@0: RIJNDAEL_TABLE::Te1[GETBYTE(t3, 2)] ^ sl@0: RIJNDAEL_TABLE::Te2[GETBYTE(t0, 1)] ^ sl@0: RIJNDAEL_TABLE::Te3[GETBYTE(t1, 0)] ^ sl@0: rk[2]; sl@0: s3 = sl@0: RIJNDAEL_TABLE::Te0[GETBYTE(t3, 3)] ^ sl@0: RIJNDAEL_TABLE::Te1[GETBYTE(t0, 2)] ^ sl@0: RIJNDAEL_TABLE::Te2[GETBYTE(t1, 1)] ^ sl@0: RIJNDAEL_TABLE::Te3[GETBYTE(t2, 0)] ^ sl@0: rk[3]; sl@0: } sl@0: /* sl@0: * apply last round and sl@0: * map cipher state to byte array block: sl@0: */ sl@0: sl@0: s0 = sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(t0, 3)] & 0xff000000) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(t1, 2)] & 0x00ff0000) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(t2, 1)] & 0x0000ff00) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(t3, 0)] & 0x000000ff) ^ sl@0: rk[0]; sl@0: s1 = sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(t1, 3)] & 0xff000000) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(t2, 2)] & 0x00ff0000) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(t3, 1)] & 0x0000ff00) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(t0, 0)] & 0x000000ff) ^ sl@0: rk[1]; sl@0: s2 = sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(t2, 3)] & 0xff000000) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(t3, 2)] & 0x00ff0000) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(t0, 1)] & 0x0000ff00) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(t1, 0)] & 0x000000ff) ^ sl@0: rk[2]; sl@0: s3 = sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(t3, 3)] & 0xff000000) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(t0, 2)] & 0x00ff0000) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(t1, 1)] & 0x0000ff00) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(t2, 0)] & 0x000000ff) ^ sl@0: rk[3]; sl@0: sl@0: PutBlockBigEndian(aBuffer, s0, s1, s2, s3); sl@0: ModeEncryptEnd(aBuffer); sl@0: aBuffer += KAESBlockBytes; sl@0: } sl@0: } sl@0: sl@0: void CRijndaelImpl::TransformDecrypt( sl@0: TUint8* aBuffer, sl@0: TUint aNumBlocks) sl@0: { sl@0: for (TInt i = 0; i < aNumBlocks; ++i) sl@0: { sl@0: ModeDecryptStart(aBuffer); sl@0: sl@0: TUint32 s0, s1, s2, s3, t0, t1, t2, t3; sl@0: const TUint32* rk = &iK[0]; sl@0: sl@0: /* sl@0: * map byte array block to cipher state sl@0: * and add initial round key: sl@0: */ sl@0: GetBlockBigEndian(aBuffer, s0, s1, s2, s3); sl@0: sl@0: s0 ^= rk[0]; sl@0: s1 ^= rk[1]; sl@0: s2 ^= rk[2]; sl@0: s3 ^= rk[3]; sl@0: /* sl@0: * Nr - 1 full rounds: sl@0: */ sl@0: TUint r = iRounds >> 1; sl@0: FOREVER sl@0: { sl@0: t0 = sl@0: RIJNDAEL_TABLE::Td0[GETBYTE(s0, 3)] ^ sl@0: RIJNDAEL_TABLE::Td1[GETBYTE(s3, 2)] ^ sl@0: RIJNDAEL_TABLE::Td2[GETBYTE(s2, 1)] ^ sl@0: RIJNDAEL_TABLE::Td3[GETBYTE(s1, 0)] ^ sl@0: rk[4]; sl@0: t1 = sl@0: RIJNDAEL_TABLE::Td0[GETBYTE(s1, 3)] ^ sl@0: RIJNDAEL_TABLE::Td1[GETBYTE(s0, 2)] ^ sl@0: RIJNDAEL_TABLE::Td2[GETBYTE(s3, 1)] ^ sl@0: RIJNDAEL_TABLE::Td3[GETBYTE(s2, 0)] ^ sl@0: rk[5]; sl@0: t2 = sl@0: RIJNDAEL_TABLE::Td0[GETBYTE(s2, 3)] ^ sl@0: RIJNDAEL_TABLE::Td1[GETBYTE(s1, 2)] ^ sl@0: RIJNDAEL_TABLE::Td2[GETBYTE(s0, 1)] ^ sl@0: RIJNDAEL_TABLE::Td3[GETBYTE(s3, 0)] ^ sl@0: rk[6]; sl@0: t3 = sl@0: RIJNDAEL_TABLE::Td0[GETBYTE(s3, 3)] ^ sl@0: RIJNDAEL_TABLE::Td1[GETBYTE(s2, 2)] ^ sl@0: RIJNDAEL_TABLE::Td2[GETBYTE(s1, 1)] ^ sl@0: RIJNDAEL_TABLE::Td3[GETBYTE(s0, 0)] ^ sl@0: rk[7]; sl@0: sl@0: rk += 8; sl@0: if (--r == 0) sl@0: break; sl@0: sl@0: s0 = sl@0: RIJNDAEL_TABLE::Td0[GETBYTE(t0, 3)] ^ sl@0: RIJNDAEL_TABLE::Td1[GETBYTE(t3, 2)] ^ sl@0: RIJNDAEL_TABLE::Td2[GETBYTE(t2, 1)] ^ sl@0: RIJNDAEL_TABLE::Td3[GETBYTE(t1, 0)] ^ sl@0: rk[0]; sl@0: s1 = sl@0: RIJNDAEL_TABLE::Td0[GETBYTE(t1, 3)] ^ sl@0: RIJNDAEL_TABLE::Td1[GETBYTE(t0, 2)] ^ sl@0: RIJNDAEL_TABLE::Td2[GETBYTE(t3, 1)] ^ sl@0: RIJNDAEL_TABLE::Td3[GETBYTE(t2, 0)] ^ sl@0: rk[1]; sl@0: s2 = sl@0: RIJNDAEL_TABLE::Td0[GETBYTE(t2, 3)] ^ sl@0: RIJNDAEL_TABLE::Td1[GETBYTE(t1, 2)] ^ sl@0: RIJNDAEL_TABLE::Td2[GETBYTE(t0, 1)] ^ sl@0: RIJNDAEL_TABLE::Td3[GETBYTE(t3, 0)] ^ sl@0: rk[2]; sl@0: s3 = sl@0: RIJNDAEL_TABLE::Td0[GETBYTE(t3, 3)] ^ sl@0: RIJNDAEL_TABLE::Td1[GETBYTE(t2, 2)] ^ sl@0: RIJNDAEL_TABLE::Td2[GETBYTE(t1, 1)] ^ sl@0: RIJNDAEL_TABLE::Td3[GETBYTE(t0, 0)] ^ sl@0: rk[3]; sl@0: } sl@0: /* sl@0: * apply last round and sl@0: * map cipher state to byte array block: sl@0: */ sl@0: s0 = sl@0: (RIJNDAEL_TABLE::Td4[GETBYTE(t0, 3)] & 0xff000000) ^ sl@0: (RIJNDAEL_TABLE::Td4[GETBYTE(t3, 2)] & 0x00ff0000) ^ sl@0: (RIJNDAEL_TABLE::Td4[GETBYTE(t2, 1)] & 0x0000ff00) ^ sl@0: (RIJNDAEL_TABLE::Td4[GETBYTE(t1, 0)] & 0x000000ff) ^ sl@0: rk[0]; sl@0: s1 = sl@0: (RIJNDAEL_TABLE::Td4[GETBYTE(t1, 3)] & 0xff000000) ^ sl@0: (RIJNDAEL_TABLE::Td4[GETBYTE(t0, 2)] & 0x00ff0000) ^ sl@0: (RIJNDAEL_TABLE::Td4[GETBYTE(t3, 1)] & 0x0000ff00) ^ sl@0: (RIJNDAEL_TABLE::Td4[GETBYTE(t2, 0)] & 0x000000ff) ^ sl@0: rk[1]; sl@0: s2 = sl@0: (RIJNDAEL_TABLE::Td4[GETBYTE(t2, 3)] & 0xff000000) ^ sl@0: (RIJNDAEL_TABLE::Td4[GETBYTE(t1, 2)] & 0x00ff0000) ^ sl@0: (RIJNDAEL_TABLE::Td4[GETBYTE(t0, 1)] & 0x0000ff00) ^ sl@0: (RIJNDAEL_TABLE::Td4[GETBYTE(t3, 0)] & 0x000000ff) ^ sl@0: rk[2]; sl@0: s3 = sl@0: (RIJNDAEL_TABLE::Td4[GETBYTE(t3, 3)] & 0xff000000) ^ sl@0: (RIJNDAEL_TABLE::Td4[GETBYTE(t2, 2)] & 0x00ff0000) ^ sl@0: (RIJNDAEL_TABLE::Td4[GETBYTE(t1, 1)] & 0x0000ff00) ^ sl@0: (RIJNDAEL_TABLE::Td4[GETBYTE(t0, 0)] & 0x000000ff) ^ sl@0: rk[3]; sl@0: PutBlockBigEndian(aBuffer, s0, s1, s2, s3); sl@0: ModeDecryptEnd(aBuffer); sl@0: aBuffer += KAESBlockBytes; sl@0: } sl@0: } sl@0: sl@0: void CRijndaelImpl::SetEncryptKeySchedule(const TDesC8& aKey, TUint32* aKeySchedule) sl@0: { sl@0: TUint keySize = aKey.Length(); sl@0: TUint32 temp; sl@0: TUint32* rk = aKeySchedule; sl@0: sl@0: TUint i = 0; sl@0: sl@0: GetUserKeyBigEndian(rk, keySize/4, &aKey[0], keySize); sl@0: sl@0: switch(keySize) sl@0: { sl@0: case (KAESKeyBytes128): sl@0: { sl@0: FOREVER sl@0: { sl@0: temp = rk[3]; sl@0: rk[4] = rk[0] ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 2)] & 0xff000000) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 3)] & 0x000000ff) ^ sl@0: RIJNDAEL_TABLE::rcon[i]; sl@0: rk[5] = rk[1] ^ rk[4]; sl@0: rk[6] = rk[2] ^ rk[5]; sl@0: rk[7] = rk[3] ^ rk[6]; sl@0: if (++i == 10) sl@0: break; sl@0: rk += 4; sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case (KAESKeyBytes192): sl@0: { sl@0: FOREVER sl@0: { sl@0: temp = rk[ 5]; sl@0: rk[ 6] = rk[ 0] ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 2)] & 0xff000000) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 3)] & 0x000000ff) ^ sl@0: RIJNDAEL_TABLE::rcon[i]; sl@0: rk[ 7] = rk[ 1] ^ rk[ 6]; sl@0: rk[ 8] = rk[ 2] ^ rk[ 7]; sl@0: rk[ 9] = rk[ 3] ^ rk[ 8]; sl@0: if (++i == 8) sl@0: break; sl@0: rk[10] = rk[ 4] ^ rk[ 9]; sl@0: rk[11] = rk[ 5] ^ rk[10]; sl@0: rk += 6; sl@0: } sl@0: } sl@0: break; sl@0: sl@0: case (KAESKeyBytes256): sl@0: { sl@0: FOREVER sl@0: { sl@0: temp = rk[ 7]; sl@0: rk[ 8] = rk[ 0] ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 2)] & 0xff000000) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 3)] & 0x000000ff) ^ sl@0: RIJNDAEL_TABLE::rcon[i]; sl@0: rk[ 9] = rk[ 1] ^ rk[ 8]; sl@0: rk[10] = rk[ 2] ^ rk[ 9]; sl@0: rk[11] = rk[ 3] ^ rk[10]; sl@0: if (++i == 7) sl@0: break; sl@0: temp = rk[11]; sl@0: rk[12] = rk[ 4] ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 3)] & 0xff000000) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 2)] & 0x00ff0000) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 1)] & 0x0000ff00) ^ sl@0: (RIJNDAEL_TABLE::Te4[GETBYTE(temp, 0)] & 0x000000ff); sl@0: rk[13] = rk[ 5] ^ rk[12]; sl@0: rk[14] = rk[ 6] ^ rk[13]; sl@0: rk[15] = rk[ 7] ^ rk[14]; sl@0: sl@0: rk += 8; sl@0: } sl@0: } sl@0: break; sl@0: sl@0: default: sl@0: assert(0); // Shouldn't get here, keeps compiler happy sl@0: } sl@0: } sl@0: sl@0: void CRijndaelImpl::SetDecryptKeySchedule(const TDesC8& aKey, TUint32* aKeySchedule) sl@0: { sl@0: SetEncryptKeySchedule(aKey, aKeySchedule); sl@0: sl@0: TUint i, j; sl@0: TUint32* rk = aKeySchedule; sl@0: TUint32 temp; sl@0: sl@0: // invert the order of the round keys sl@0: for (i = 0, j = 4*iRounds; i < j; i += 4, j -= 4) sl@0: { sl@0: temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; sl@0: temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; sl@0: temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; sl@0: temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; sl@0: } sl@0: sl@0: // apply the inverse MixColumn transform to all round keys but the first and the last sl@0: for (i = 1; i < iRounds; i++) sl@0: { sl@0: rk += 4; sl@0: rk[0] = sl@0: RIJNDAEL_TABLE::Td0[RIJNDAEL_TABLE::Te4[GETBYTE(rk[0], 3)] & 0xff] ^ sl@0: RIJNDAEL_TABLE::Td1[RIJNDAEL_TABLE::Te4[GETBYTE(rk[0], 2)] & 0xff] ^ sl@0: RIJNDAEL_TABLE::Td2[RIJNDAEL_TABLE::Te4[GETBYTE(rk[0], 1)] & 0xff] ^ sl@0: RIJNDAEL_TABLE::Td3[RIJNDAEL_TABLE::Te4[GETBYTE(rk[0], 0)] & 0xff]; sl@0: rk[1] = sl@0: RIJNDAEL_TABLE::Td0[RIJNDAEL_TABLE::Te4[GETBYTE(rk[1], 3)] & 0xff] ^ sl@0: RIJNDAEL_TABLE::Td1[RIJNDAEL_TABLE::Te4[GETBYTE(rk[1], 2)] & 0xff] ^ sl@0: RIJNDAEL_TABLE::Td2[RIJNDAEL_TABLE::Te4[GETBYTE(rk[1], 1)] & 0xff] ^ sl@0: RIJNDAEL_TABLE::Td3[RIJNDAEL_TABLE::Te4[GETBYTE(rk[1], 0)] & 0xff]; sl@0: rk[2] = sl@0: RIJNDAEL_TABLE::Td0[RIJNDAEL_TABLE::Te4[GETBYTE(rk[2], 3)] & 0xff] ^ sl@0: RIJNDAEL_TABLE::Td1[RIJNDAEL_TABLE::Te4[GETBYTE(rk[2], 2)] & 0xff] ^ sl@0: RIJNDAEL_TABLE::Td2[RIJNDAEL_TABLE::Te4[GETBYTE(rk[2], 1)] & 0xff] ^ sl@0: RIJNDAEL_TABLE::Td3[RIJNDAEL_TABLE::Te4[GETBYTE(rk[2], 0)] & 0xff]; sl@0: rk[3] = sl@0: RIJNDAEL_TABLE::Td0[RIJNDAEL_TABLE::Te4[GETBYTE(rk[3], 3)] & 0xff] ^ sl@0: RIJNDAEL_TABLE::Td1[RIJNDAEL_TABLE::Te4[GETBYTE(rk[3], 2)] & 0xff] ^ sl@0: RIJNDAEL_TABLE::Td2[RIJNDAEL_TABLE::Te4[GETBYTE(rk[3], 1)] & 0xff] ^ sl@0: RIJNDAEL_TABLE::Td3[RIJNDAEL_TABLE::Te4[GETBYTE(rk[3], 0)] & 0xff]; sl@0: } sl@0: }