📄 aes.cpp
字号:
/* aes.cpp * * Copyright (C) 2003 Sawtooth Consulting Ltd. * * This file is part of yaSSL. * * yaSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * There are special exceptions to the terms and conditions of the GPL as it * is applied to yaSSL. View the full text of the exception in the file * FLOSS-EXCEPTIONS in the directory of this software distribution. * * yaSSL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *//* C++ based on Wei Dai's aes.cpp from CryptoPP *//* x86 asm original */#if defined(TAOCRYPT_KERNEL_MODE) #define DO_TAOCRYPT_KERNEL_MODE#endif // only some modules now support this#include "runtime.hpp"#include "aes.hpp"namespace TaoCrypt {#if defined(DO_AES_ASM)// ia32 optimized versionvoid AES::Process(byte* out, const byte* in, word32 sz){ if (!isMMX) { Mode_BASE::Process(out, in, sz); return; } word32 blocks = sz / BLOCK_SIZE; if (mode_ == ECB) while (blocks--) { if (dir_ == ENCRYPTION) AsmEncrypt(in, out, (void*)Te0); else AsmDecrypt(in, out, (void*)Td0); out += BLOCK_SIZE; in += BLOCK_SIZE; } else if (mode_ == CBC) if (dir_ == ENCRYPTION) while (blocks--) { r_[0] ^= *(word32*)in; r_[1] ^= *(word32*)(in + 4); r_[2] ^= *(word32*)(in + 8); r_[3] ^= *(word32*)(in + 12); AsmEncrypt((byte*)r_, (byte*)r_, (void*)Te0); memcpy(out, r_, BLOCK_SIZE); out += BLOCK_SIZE; in += BLOCK_SIZE; } else while (blocks--) { AsmDecrypt(in, out, (void*)Td0); *(word32*)out ^= r_[0]; *(word32*)(out + 4) ^= r_[1]; *(word32*)(out + 8) ^= r_[2]; *(word32*)(out + 12) ^= r_[3]; memcpy(r_, in, BLOCK_SIZE); out += BLOCK_SIZE; in += BLOCK_SIZE; }}#endif // DO_AES_ASMvoid AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/){ assert( (keylen == 16) || (keylen == 24) || (keylen == 32) ); rounds_ = keylen/4 + 6; word32 temp, *rk = key_; unsigned int i=0; GetUserKey(BigEndianOrder, rk, keylen/4, userKey, keylen); switch(keylen) { case 16: while (true) { temp = rk[3]; rk[4] = rk[0] ^ (Te4[GETBYTE(temp, 2)] & 0xff000000) ^ (Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^ (Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^ (Te4[GETBYTE(temp, 3)] & 0x000000ff) ^ rcon_[i]; rk[5] = rk[1] ^ rk[4]; rk[6] = rk[2] ^ rk[5]; rk[7] = rk[3] ^ rk[6]; if (++i == 10) break; rk += 4; } break; case 24: while (true) // for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack { temp = rk[ 5]; rk[ 6] = rk[ 0] ^ (Te4[GETBYTE(temp, 2)] & 0xff000000) ^ (Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^ (Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^ (Te4[GETBYTE(temp, 3)] & 0x000000ff) ^ rcon_[i]; rk[ 7] = rk[ 1] ^ rk[ 6]; rk[ 8] = rk[ 2] ^ rk[ 7]; rk[ 9] = rk[ 3] ^ rk[ 8]; if (++i == 8) break; rk[10] = rk[ 4] ^ rk[ 9]; rk[11] = rk[ 5] ^ rk[10]; rk += 6; } break; case 32: while (true) { temp = rk[ 7]; rk[ 8] = rk[ 0] ^ (Te4[GETBYTE(temp, 2)] & 0xff000000) ^ (Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^ (Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^ (Te4[GETBYTE(temp, 3)] & 0x000000ff) ^ rcon_[i]; rk[ 9] = rk[ 1] ^ rk[ 8]; rk[10] = rk[ 2] ^ rk[ 9]; rk[11] = rk[ 3] ^ rk[10]; if (++i == 7) break; temp = rk[11]; rk[12] = rk[ 4] ^ (Te4[GETBYTE(temp, 3)] & 0xff000000) ^ (Te4[GETBYTE(temp, 2)] & 0x00ff0000) ^ (Te4[GETBYTE(temp, 1)] & 0x0000ff00) ^ (Te4[GETBYTE(temp, 0)] & 0x000000ff); rk[13] = rk[ 5] ^ rk[12]; rk[14] = rk[ 6] ^ rk[13]; rk[15] = rk[ 7] ^ rk[14]; rk += 8; } break; } if (dir_ == DECRYPTION) { unsigned int i, j; rk = key_; /* invert the order of the round keys: */ for (i = 0, j = 4*rounds_; i < j; i += 4, j -= 4) { temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; } // apply the inverse MixColumn transform to all round keys but the // first and the last: for (i = 1; i < rounds_; i++) { rk += 4; rk[0] = Td0[Te4[GETBYTE(rk[0], 3)] & 0xff] ^ Td1[Te4[GETBYTE(rk[0], 2)] & 0xff] ^ Td2[Te4[GETBYTE(rk[0], 1)] & 0xff] ^ Td3[Te4[GETBYTE(rk[0], 0)] & 0xff]; rk[1] = Td0[Te4[GETBYTE(rk[1], 3)] & 0xff] ^ Td1[Te4[GETBYTE(rk[1], 2)] & 0xff] ^ Td2[Te4[GETBYTE(rk[1], 1)] & 0xff] ^ Td3[Te4[GETBYTE(rk[1], 0)] & 0xff]; rk[2] = Td0[Te4[GETBYTE(rk[2], 3)] & 0xff] ^ Td1[Te4[GETBYTE(rk[2], 2)] & 0xff] ^ Td2[Te4[GETBYTE(rk[2], 1)] & 0xff] ^ Td3[Te4[GETBYTE(rk[2], 0)] & 0xff]; rk[3] = Td0[Te4[GETBYTE(rk[3], 3)] & 0xff] ^ Td1[Te4[GETBYTE(rk[3], 2)] & 0xff] ^ Td2[Te4[GETBYTE(rk[3], 1)] & 0xff] ^ Td3[Te4[GETBYTE(rk[3], 0)] & 0xff]; } }}void AES::ProcessAndXorBlock(const byte* in, const byte* xOr, byte* out) const{ if (dir_ == ENCRYPTION) encrypt(in, xOr, out); else decrypt(in, xOr, out);}typedef BlockGetAndPut<word32, BigEndian> gpBlock; void AES::encrypt(const byte* inBlock, const byte* xorBlock, byte* outBlock) const{ word32 s0, s1, s2, s3; word32 t0, t1, t2, t3; const word32 *rk = key_; /* * map byte array block to cipher state * and add initial round key: */ gpBlock::Get(inBlock)(s0)(s1)(s2)(s3); s0 ^= rk[0]; s1 ^= rk[1]; s2 ^= rk[2]; s3 ^= rk[3]; /* * Nr - 1 full rounds: */ unsigned int r = rounds_ >> 1; for (;;) { t0 = Te0[GETBYTE(s0, 3)] ^ Te1[GETBYTE(s1, 2)] ^ Te2[GETBYTE(s2, 1)] ^ Te3[GETBYTE(s3, 0)] ^ rk[4]; t1 = Te0[GETBYTE(s1, 3)] ^ Te1[GETBYTE(s2, 2)] ^ Te2[GETBYTE(s3, 1)] ^ Te3[GETBYTE(s0, 0)] ^ rk[5]; t2 = Te0[GETBYTE(s2, 3)] ^ Te1[GETBYTE(s3, 2)] ^ Te2[GETBYTE(s0, 1)] ^ Te3[GETBYTE(s1, 0)] ^ rk[6]; t3 = Te0[GETBYTE(s3, 3)] ^ Te1[GETBYTE(s0, 2)] ^ Te2[GETBYTE(s1, 1)] ^ Te3[GETBYTE(s2, 0)] ^ rk[7]; rk += 8; if (--r == 0) { break; } s0 = Te0[GETBYTE(t0, 3)] ^ Te1[GETBYTE(t1, 2)] ^ Te2[GETBYTE(t2, 1)] ^ Te3[GETBYTE(t3, 0)] ^ rk[0]; s1 = Te0[GETBYTE(t1, 3)] ^ Te1[GETBYTE(t2, 2)] ^ Te2[GETBYTE(t3, 1)] ^ Te3[GETBYTE(t0, 0)] ^ rk[1]; s2 = Te0[GETBYTE(t2, 3)] ^ Te1[GETBYTE(t3, 2)] ^ Te2[GETBYTE(t0, 1)] ^ Te3[GETBYTE(t1, 0)] ^ rk[2]; s3 =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -