summaryrefslogtreecommitdiff
path: root/rijndael.cpp
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2017-09-12 05:53:17 -0400
committerJeffrey Walton <noloader@gmail.com>2017-09-12 05:53:17 -0400
commitb090e5f69fe761b08b6fd1bfc51cb16d6d363cb7 (patch)
tree3ae3bdefc185f92f2149445008adf3cf4f2b9c84 /rijndael.cpp
parentcfb63decec771d660394d7fbf8b5c7b566a09232 (diff)
downloadcryptopp-git-b090e5f69fe761b08b6fd1bfc51cb16d6d363cb7.tar.gz
Add Power8 AES decryption
Diffstat (limited to 'rijndael.cpp')
-rw-r--r--rijndael.cpp54
1 files changed, 35 insertions, 19 deletions
diff --git a/rijndael.cpp b/rijndael.cpp
index e5079d9b..3e016d6f 100644
--- a/rijndael.cpp
+++ b/rijndael.cpp
@@ -113,6 +113,19 @@ CRYPTOPP_ALIGN_DATA(16) static word32 Td[256*4];
static volatile bool s_TeFilled = false, s_TdFilled = false;
+ANONYMOUS_NAMESPACE_BEGIN
+
+CRYPTOPP_ALIGN_DATA(16)
+const word32 s_one[] = {0, 0, 0, 1<<24};
+
+/* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+CRYPTOPP_ALIGN_DATA(16)
+const word32 s_rconLE[] = {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36
+};
+
+ANONYMOUS_NAMESPACE_END
+
// ************************* Portable Code ************************************
#define QUARTER_ROUND(L, T, t, a, b, c, d) \
@@ -221,7 +234,7 @@ void Rijndael::Base::FillDecTable()
}
#if (CRYPTOPP_AESNI_AVAILABLE)
-extern void Rijndael_UncheckedSetKey_SSE4_AESNI(const byte *userKey, size_t keyLen, word32* rk);
+extern void Rijndael_UncheckedSetKey_SSE4_AESNI(const byte *userKey, size_t keyLen, word32* rk, unsigned int rounds);
extern void Rijndael_UncheckedSetKeyRev_AESNI(word32 *key, unsigned int rounds);
extern size_t Rijndael_Enc_AdvancedProcessBlocks_AESNI(const word32 *subkeys, size_t rounds,
@@ -240,8 +253,6 @@ extern size_t Rijndael_Dec_AdvancedProcessBlocks_ARMV8(const word32 *subkeys, si
#if (CRYPTOPP_POWER8_AES_AVAILABLE)
extern void ByteReverseArrayLE(byte src[16]);
-extern void Rijndael_UncheckedSetKey_POWER8(const byte *userKey, size_t keyLen, word32 *rk, CipherDir dir);
-
extern void Rijndael_Enc_ProcessAndXorBlock_POWER8(const word32 *subkeys, size_t rounds,
const byte *inBlock, const byte *xorBlock, byte *outBlock);
extern void Rijndael_Dec_ProcessAndXorBlock_POWER8(const word32 *subkeys, size_t rounds,
@@ -263,7 +274,7 @@ void Rijndael::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLen, c
{
// TODO: Add non-SSE4.1 variant for low-end Atoms. The low-end
// Atoms have SSE2-SSSE3 and AES-NI, but not SSE4.1 or SSE4.2.
- Rijndael_UncheckedSetKey_SSE4_AESNI(userKey, keyLen, rk);
+ Rijndael_UncheckedSetKey_SSE4_AESNI(userKey, keyLen, rk, m_rounds);
if (!IsForwardTransformation())
Rijndael_UncheckedSetKeyRev_AESNI(m_key, m_rounds);
@@ -306,6 +317,25 @@ void Rijndael::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLen, c
rk = m_key;
+#if CRYPTOPP_POWER8_AES_AVAILABLE
+ if (HasAES())
+ {
+ ConditionalByteReverse(BIG_ENDIAN_ORDER, rk, rk, 16);
+ ConditionalByteReverse(BIG_ENDIAN_ORDER, rk + m_rounds*4, rk + m_rounds*4, 16);
+ ConditionalByteReverse(BIG_ENDIAN_ORDER, rk+4, rk+4, (m_rounds-1)*16);
+
+#if defined(IS_LITTLE_ENDIAN)
+ // VSX registers are big-endian. The entire subkey table must be byte
+ // reversed on little-endian systems to ensure it loads properly.
+ byte * ptr = reinterpret_cast<byte*>(rk);
+ for (unsigned int i=0; i<=m_rounds; i++)
+ ByteReverseArrayLE(ptr+i*16);
+#endif // IS_LITTLE_ENDIAN
+
+ return;
+ }
+#endif // CRYPTOPP_POWER8_AES_AVAILABLE
+
if (IsForwardTransformation())
{
if (!s_TeFilled)
@@ -351,20 +381,6 @@ void Rijndael::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLen, c
if (HasAES())
ConditionalByteReverse(BIG_ENDIAN_ORDER, rk+4, rk+4, (m_rounds-1)*16);
#endif
-#if CRYPTOPP_POWER8_AES_AVAILABLE
- if (IsForwardTransformation() && HasAES())
- {
- ConditionalByteReverse(BIG_ENDIAN_ORDER, rk+4, rk+4, (m_rounds-1)*16);
-
-#if defined(IS_LITTLE_ENDIAN)
- // VSX registers are big-endian. The entire subkey table must be byte
- // reversed on little-endian systems to ensure it loads properly.
- byte * ptr = reinterpret_cast<byte*>(rk);
- for (unsigned int i=0; i<=m_rounds; i++)
- ByteReverseArrayLE(ptr+i*16);
-#endif // IS_LITTLE_ENDIAN
- }
-#endif // CRYPTOPP_POWER8_AES_AVAILABLE
}
void Rijndael::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
@@ -483,7 +499,7 @@ void Rijndael::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock
}
#endif
-#if (CRYPTOPP_POWER8_AES_AVAILABLE) && 0
+#if (CRYPTOPP_POWER8_AES_AVAILABLE)
if (HasAES())
{
(void)Rijndael_Dec_ProcessAndXorBlock_POWER8(m_key, m_rounds, inBlock, xorBlock, outBlock);