Skip to content

Commit

Permalink
Add XTS block cipher mode of operation (GH #891, PR #892)
Browse files Browse the repository at this point in the history
  • Loading branch information
noloader committed Oct 12, 2019
1 parent 85ecff4 commit 76c29ea
Show file tree
Hide file tree
Showing 17 changed files with 8,772 additions and 21 deletions.
3 changes: 3 additions & 0 deletions Filelist.txt
Expand Up @@ -410,6 +410,8 @@ xtr.cpp
xtr.h
xtrcrypt.cpp
xtrcrypt.h
xts.cpp
xts.h
zdeflate.cpp
zdeflate.h
zinflate.cpp
Expand Down Expand Up @@ -576,6 +578,7 @@ TestVectors/vmac.txt
TestVectors/wake.txt
TestVectors/whrlpool.txt
TestVectors/xchacha.txt
TestVectors/xts.txt
TestPrograms/test_32bit.cxx
TestPrograms/test_64bit.cxx
TestPrograms/test_arm_acle.cxx
Expand Down
8,204 changes: 8,204 additions & 0 deletions TestVectors/xts.txt

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions bench2.cpp
Expand Up @@ -167,6 +167,9 @@ void Benchmark2(double t, double hertz)
BenchMarkByName<SymmetricCipher>("AES/CBC", 16);
BenchMarkByName<SymmetricCipher>("AES/CBC", 24);
BenchMarkByName<SymmetricCipher>("AES/CBC", 32);
BenchMarkByName<SymmetricCipher>("AES/XTS", 32);
BenchMarkByName<SymmetricCipher>("AES/XTS", 48);
BenchMarkByName<SymmetricCipher>("AES/XTS", 64);
BenchMarkByName<SymmetricCipher>("AES/OFB", 16);
BenchMarkByName<SymmetricCipher>("AES/CFB", 16);
BenchMarkByName<SymmetricCipher>("AES/ECB", 16);
Expand Down
33 changes: 27 additions & 6 deletions cmac.cpp
Expand Up @@ -5,24 +5,40 @@
#ifndef CRYPTOPP_IMPORTS

#include "cmac.h"
#include "misc.h"

NAMESPACE_BEGIN(CryptoPP)
ANONYMOUS_NAMESPACE_BEGIN

using CryptoPP::byte;
using CryptoPP::IsPowerOf2;

static void MulU(byte *k, unsigned int length)
void MulU(byte *k, unsigned int len)
{
byte carry = 0;

for (int i=length-1; i>=1; i-=2)
for (int i=len-1; i>=1; i-=2)
{
byte carry2 = k[i] >> 7;
k[i] += k[i] + carry;
carry = k[i-1] >> 7;
k[i-1] += k[i-1] + carry2;
}

#ifndef CRYPTOPP_CMAC_WIDE_BLOCK_CIPHERS
CRYPTOPP_ASSERT(len == 16);

if (carry)
{
k[15] ^= 0x87;
return;
}
#else
CRYPTOPP_ASSERT(IsPowerOf2(len));
CRYPTOPP_ASSERT(len >= 8);
CRYPTOPP_ASSERT(len <= 128);

if (carry)
{
switch (length)
switch (len)
{
case 8:
k[7] ^= 0x1b;
Expand Down Expand Up @@ -50,11 +66,16 @@ static void MulU(byte *k, unsigned int length)
k[127] ^= 0x43;
break;
default:
throw InvalidArgument("CMAC: " + IntToString(length) + " is not a supported cipher block size");
CRYPTOPP_ASSERT(0);
}
}
#endif // CRYPTOPP_CMAC_WIDE_BLOCK_CIPHERS
}

ANONYMOUS_NAMESPACE_END

NAMESPACE_BEGIN(CryptoPP)

void CMAC_Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
{
BlockCipher &cipher = AccessCipher();
Expand Down
8 changes: 7 additions & 1 deletion cmac.h
Expand Up @@ -10,6 +10,13 @@
#include "seckey.h"
#include "secblock.h"

/// \brief Enable CMAC and wide block ciphers
/// \details CMAC is only defined for AES. The library can support wide
/// block ciphers like Kaylna and Threefish since we know the polynomials.
#ifndef CRYPTOPP_CMAC_WIDE_BLOCK_CIPHERS
# define CRYPTOPP_CMAC_WIDE_BLOCK_CIPHERS 1
#endif // CRYPTOPP_CMAC_WIDE_BLOCK_CIPHERS

NAMESPACE_BEGIN(CryptoPP)

/// \brief CMAC base implementation
Expand All @@ -19,7 +26,6 @@ class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CMAC_Base : public MessageAuthenticationCo
public:

virtual ~CMAC_Base() {}

CMAC_Base() : m_counter(0) {}

void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
Expand Down
4 changes: 2 additions & 2 deletions cryptest.nmake
Expand Up @@ -83,7 +83,7 @@ LIB_SRCS = \
sm4_simd.cpp sosemanuk.cpp speck.cpp speck128_simd.cpp speck64_simd.cpp \
square.cpp squaretb.cpp sse_simd.cpp strciphr.cpp tea.cpp tftables.cpp \
threefish.cpp tiger.cpp tigertab.cpp ttmac.cpp tweetnacl.cpp twofish.cpp \
vmac.cpp wake.cpp whrlpool.cpp xed25519.cpp xtr.cpp xtrcrypt.cpp \
vmac.cpp wake.cpp whrlpool.cpp xed25519.cpp xtr.cpp xtrcrypt.cpp xts.cpp \
zdeflate.cpp zinflate.cpp zlib.cpp

LIB_OBJS = \
Expand Down Expand Up @@ -114,7 +114,7 @@ LIB_OBJS = \
sm4_simd.obj sosemanuk.obj speck.obj speck128_simd.obj speck64_simd.obj \
square.obj squaretb.obj sse_simd.obj strciphr.obj tea.obj tftables.obj \
threefish.obj tiger.obj tigertab.obj ttmac.obj tweetnacl.obj twofish.obj \
vmac.obj wake.obj whrlpool.obj xed25519.obj xtr.obj xtrcrypt.obj \
vmac.obj wake.obj whrlpool.obj xed25519.obj xtr.obj xtrcrypt.obj xts.obj \
zdeflate.obj zinflate.obj zlib.obj

ASM_OBJS = \
Expand Down
2 changes: 2 additions & 0 deletions cryptlib.vcxproj
Expand Up @@ -346,6 +346,7 @@
<ClCompile Include="xed25519.cpp" />
<ClCompile Include="xtr.cpp" />
<ClCompile Include="xtrcrypt.cpp" />
<ClCompile Include="xts.cpp" />
<ClCompile Include="zdeflate.cpp" />
<ClCompile Include="zinflate.cpp" />
<ClCompile Include="zlib.cpp" />
Expand Down Expand Up @@ -568,6 +569,7 @@
<ClInclude Include="xed25519.h" />
<ClInclude Include="xtr.h" />
<ClInclude Include="xtrcrypt.h" />
<ClInclude Include="xts.h" />
<ClInclude Include="zdeflate.h" />
<ClInclude Include="zinflate.h" />
<ClInclude Include="zlib.h" />
Expand Down
6 changes: 6 additions & 0 deletions cryptlib.vcxproj.filters
Expand Up @@ -518,6 +518,9 @@
<ClCompile Include="xtrcrypt.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="xts.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="zdeflate.cpp">
<Filter>Source Files</Filter>
</ClCompile>
Expand Down Expand Up @@ -1053,6 +1056,9 @@
<ClInclude Include="xtrcrypt.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="xts.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="zdeflate.h">
<Filter>Header Files</Filter>
</ClInclude>
Expand Down
2 changes: 1 addition & 1 deletion modes.cpp
Expand Up @@ -213,7 +213,7 @@ size_t CBC_CTS_Encryption::ProcessLastBlock(byte *outString, size_t outLength, c
const size_t used = inLength;
const unsigned int blockSize = BlockSize();

if (inLength <= BlockSize())
if (inLength <= blockSize)
{
if (!m_stolenIV)
throw InvalidArgument("CBC_Encryption: message is too short for ciphertext stealing");
Expand Down
6 changes: 4 additions & 2 deletions modes.h
Expand Up @@ -255,8 +255,10 @@ class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockOrientedCipherModeBase : public Ciphe
unsigned int MandatoryBlockSize() const {return BlockSize();}
bool IsRandomAccess() const {return false;}
bool IsSelfInverting() const {return false;}
bool IsForwardTransformation() const {return m_cipher->IsForwardTransformation();}
void Resynchronize(const byte *iv, int length=-1) {memcpy_s(m_register, m_register.size(), iv, ThrowIfInvalidIVLength(length));}
bool IsForwardTransformation() const
{return m_cipher->IsForwardTransformation();}
void Resynchronize(const byte *iv, int length=-1)
{memcpy_s(m_register, m_register.size(), iv, ThrowIfInvalidIVLength(length));}

protected:
bool RequireAlignedInput() const {return true;}
Expand Down
2 changes: 2 additions & 0 deletions regtest3.cpp
Expand Up @@ -21,6 +21,7 @@
#include "ccm.h"
#include "gcm.h"
#include "eax.h"
#include "xts.h"
#include "twofish.h"
#include "serpent.h"
#include "cast.h"
Expand Down Expand Up @@ -67,6 +68,7 @@ void RegisterFactories4()
RegisterSymmetricCipherDefaultFactories<CFB_Mode<AES> >();
RegisterSymmetricCipherDefaultFactories<OFB_Mode<AES> >();
RegisterSymmetricCipherDefaultFactories<CTR_Mode<AES> >();
RegisterSymmetricCipherDefaultFactories<XTS_Mode<AES> >("AES/XTS");

RegisterAuthenticatedSymmetricCipherDefaultFactories<CCM<AES> >();
RegisterAuthenticatedSymmetricCipherDefaultFactories<GCM<AES> >();
Expand Down
20 changes: 11 additions & 9 deletions test.cpp
Expand Up @@ -1010,15 +1010,17 @@ bool Validate(int alg, bool thorough)
case 80: result = ValidateVMAC(); break;
case 81: result = ValidateCCM(); break;
case 82: result = ValidateGCM(); break;
case 83: result = ValidateCMAC(); break;
case 84: result = ValidateSM3(); break;
case 85: result = ValidateBLAKE2s(); break;
case 86: result = ValidateBLAKE2b(); break;
case 87: result = ValidatePoly1305(); break;
case 88: result = ValidateSipHash(); break;
case 89: result = ValidateHashDRBG(); break;
case 90: result = ValidateHmacDRBG(); break;
case 91: result = ValidateNaCl(); break;
case 83: result = ValidateXTS(); break;
case 84: result = ValidateCMAC(); break;
case 85: result = ValidateSM3(); break;
case 86: result = ValidateBLAKE2s(); break;
case 87: result = ValidateBLAKE2b(); break;
case 88: result = ValidatePoly1305(); break;
case 89: result = ValidateSipHash(); break;
case 90: result = ValidateHashDRBG(); break;
case 91: result = ValidateHmacDRBG(); break;
case 92: result = ValidateNaCl(); break;

case 100: result = ValidateCHAM(); break;
case 101: result = ValidateSIMECK(); break;
case 102: result = ValidateSIMON(); break;
Expand Down
1 change: 1 addition & 0 deletions validat3.cpp
Expand Up @@ -171,6 +171,7 @@ bool ValidateAll(bool thorough)
pass=ValidateVMAC() && pass;
pass=ValidateCCM() && pass;
pass=ValidateGCM() && pass;
pass=ValidateXTS() && pass;
pass=ValidateCMAC() && pass;
pass=RunTestDataFile("TestVectors/eax.txt") && pass;

Expand Down
6 changes: 6 additions & 0 deletions validat4.cpp
Expand Up @@ -1860,6 +1860,12 @@ bool ValidateGCM()
return RunTestDataFile("TestVectors/gcm.txt", MakeParameters(Name::TableSize(), (int)64*1024)) && pass;
}

bool ValidateXTS()
{
std::cout << "\nAES/XTS validation suite running...\n";
return RunTestDataFile("TestVectors/xts.txt");
}

bool ValidateCMAC()
{
std::cout << "\nCMAC validation suite running...\n";
Expand Down
1 change: 1 addition & 0 deletions validate.h
Expand Up @@ -117,6 +117,7 @@ bool ValidateSosemanuk();
bool ValidateVMAC();
bool ValidateCCM();
bool ValidateGCM();
bool ValidateXTS();
bool ValidateCMAC();

bool ValidateBBS();
Expand Down

0 comments on commit 76c29ea

Please sign in to comment.