pare down ltc

This commit is contained in:
Thomas Fussell 2017-04-11 13:35:50 -04:00
parent cc165dbb67
commit 36dc88cf24

View File

@ -32,13 +32,6 @@
#include "aes.hpp" #include "aes.hpp"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wold-style-cast"
#pragma clang diagnostic ignored "-Wdocumentation"
#pragma clang diagnostic ignored "-Wwritable-strings"
#pragma clang diagnostic ignored "-Wsign-conversion"
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
namespace { namespace {
static const std::uint32_t TE0[256] = { static const std::uint32_t TE0[256] = {
@ -948,38 +941,26 @@ static const std::uint32_t rcon[] = {
static std::uint32_t setup_mix(std::uint32_t temp) static std::uint32_t setup_mix(std::uint32_t temp)
{ {
return (Te4_3[byte(temp, 2)]) ^ return (Te4_3[byte(temp, 2)])
(Te4_2[byte(temp, 1)]) ^ ^ (Te4_2[byte(temp, 1)])
(Te4_1[byte(temp, 0)]) ^ ^ (Te4_1[byte(temp, 0)])
(Te4_0[byte(temp, 3)]); ^ (Te4_0[byte(temp, 3)]);
} }
#define STORE32H(x, y) \
do { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
(y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } while(0)
#define LOAD32H(x, y) \ #define LOAD32H(x, y) \
do { x = ((std::uint32_t)((y)[0] & 255)<<24) | \ do { x = (static_cast<std::uint32_t>((y)[0] & 255)<<24) | \
((std::uint32_t)((y)[1] & 255)<<16) | \ (static_cast<std::uint32_t>((y)[1] & 255)<<16) | \
((std::uint32_t)((y)[2] & 255)<<8) | \ (static_cast<std::uint32_t>((y)[2] & 255)<<8) | \
((std::uint32_t)((y)[3] & 255)); } while(0) (static_cast<std::uint32_t>((y)[3] & 255)); } while(0)
#define RORc(x, y) ( ((((std::uint32_t)(x)&0xFFFFFFFFUL)>>(std::uint32_t)((y)&31)) | ((std::uint32_t)(x)<<(std::uint32_t)((32-((y)&31))&31))) & 0xFFFFFFFFUL) #define RORc(x, y) ( (((static_cast<std::uint32_t>(x)&0xFFFFFFFFUL)>>static_cast<std::uint32_t>((y)&31)) | (static_cast<std::uint32_t>(x)<<static_cast<std::uint32_t>((32-((y)&31))&31))) & 0xFFFFFFFFUL)
struct rijndael_key { struct rijndael_key {
std::uint32_t eK[60], dK[60]; std::uint32_t eK[60], dK[60];
int Nr; int Nr;
}; };
/** rijndael_key rijndael_setup(const std::vector<std::uint8_t> &key)
Initialize the AES (Rijndael) block cipher
@param key The symmetric key you wish to pass
@param keylen The key length in bytes
@param num_rounds The number of rounds desired (0 for default)
@param skey The key in as scheduled by this function.
@return CRYPT_OK if successful
*/
rijndael_key rijndael_setup(const unsigned char *key, int keylen, int num_rounds)
{ {
rijndael_key skey; rijndael_key skey;
@ -987,15 +968,12 @@ rijndael_key rijndael_setup(const unsigned char *key, int keylen, int num_rounds
std::uint32_t temp, *rk; std::uint32_t temp, *rk;
std::uint32_t *rrk; std::uint32_t *rrk;
if (keylen != 16 && keylen != 24 && keylen != 32) { if (key.size() != 16 && key.size() != 24 && key.size() != 32)
{
throw std::runtime_error(""); throw std::runtime_error("");
} }
if (num_rounds != 0 && num_rounds != (10 + ((keylen/8)-2)*2)) { skey.Nr = 10 + ((key.size()/8)-2)*2;
throw std::runtime_error("");
}
skey.Nr = 10 + ((keylen/8)-2)*2;
/* setup the forward key */ /* setup the forward key */
i = 0; i = 0;
@ -1118,13 +1096,10 @@ rijndael_key rijndael_setup(const unsigned char *key, int keylen, int num_rounds
return skey; return skey;
} }
/** #define STORE32H(x, y) \
Encrypts a block of text with AES do { (y)[0] = static_cast<std::uint8_t>(((x)>>24)&255); (y)[1] = static_cast<std::uint8_t>(((x)>>16)&255); \
@param pt The input plaintext (16 bytes) (y)[2] = static_cast<std::uint8_t>(((x)>>8)&255); (y)[3] = static_cast<std::uint8_t>((x)&255); } while(0)
@param ct The output ciphertext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, rijndael_key &skey) void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, rijndael_key &skey)
{ {
std::uint32_t s0, s1, s2, s3, t0, t1, t2, t3, *rk; std::uint32_t s0, s1, s2, s3, t0, t1, t2, t3, *rk;
@ -1237,20 +1212,12 @@ void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, rijndael_k
STORE32H(s3, ct+12); STORE32H(s3, ct+12);
} }
/**
Decrypts a block of text with AES
@param ct The input ciphertext (16 bytes)
@param pt The output plaintext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, rijndael_key &skey) void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, rijndael_key &skey)
{ {
std::uint32_t s0, s1, s2, s3, t0, t1, t2, t3, *rk; std::uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
int Nr, r;
Nr = skey.Nr; auto Nr = skey.Nr;
rk = skey.dK; auto rk = skey.dK;
/* /*
* map byte array block to cipher state * map byte array block to cipher state
@ -1264,7 +1231,8 @@ void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, rijndael_k
/* /*
* Nr - 1 full rounds: * Nr - 1 full rounds:
*/ */
r = Nr >> 1; auto r = Nr >> 1;
for (;;) { for (;;) {
t0 = t0 =
@ -1358,6 +1326,11 @@ void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, rijndael_k
STORE32H(s3, pt+12); STORE32H(s3, pt+12);
} }
#undef byte
#undef LOAD32H
#undef STORE32H
#undef RORc
} // namespace } // namespace
namespace xlnt { namespace xlnt {
@ -1369,15 +1342,19 @@ std::vector<std::uint8_t> aes_ecb_encrypt(
{ {
if (plaintext.empty()) return {}; if (plaintext.empty()) return {};
auto expanded_key = rijndael_setup(key.data(), key.size(), 0); if (plaintext.size() % 16 != 0)
{
std::vector<std::uint8_t> ciphertext(plaintext.size()); throw std::runtime_error("");
}
auto ciphertext = std::vector<std::uint8_t>(plaintext.size());
auto expanded_key = rijndael_setup(key.data(), key.size());
auto len = plaintext.size(); auto len = plaintext.size();
auto pt = plaintext.data(); auto pt = plaintext.data();
auto ct = ciphertext.data(); auto ct = ciphertext.data();
while (len) { while (len)
{
rijndael_ecb_encrypt(pt, ct, expanded_key); rijndael_ecb_encrypt(pt, ct, expanded_key);
pt += 16; pt += 16;
@ -1394,15 +1371,19 @@ std::vector<std::uint8_t> aes_ecb_decrypt(
{ {
if (ciphertext.empty()) return {}; if (ciphertext.empty()) return {};
auto expanded_key = rijndael_setup(key.data(), key.size(), 0); if (ciphertext.size() % 16 != 0)
{
std::vector<std::uint8_t> plaintext(ciphertext.size()); throw std::runtime_error("");
}
auto plaintext = std::vector<std::uint8_t>(ciphertext.size());
auto expanded_key = rijndael_setup(key.data(), key.size());
auto len = ciphertext.size(); auto len = ciphertext.size();
auto ct = ciphertext.data(); auto ct = ciphertext.data();
auto pt = plaintext.data(); auto pt = plaintext.data();
while (len) { while (len)
{
rijndael_ecb_decrypt(ct, pt, expanded_key); rijndael_ecb_decrypt(ct, pt, expanded_key);
pt += 16; pt += 16;
@ -1420,51 +1401,32 @@ std::vector<std::uint8_t> aes_cbc_encrypt(
{ {
if (plaintext.empty()) return {}; if (plaintext.empty()) return {};
auto expanded_key = rijndael_setup(key.data(), key.size(), 0); if (plaintext.size() % 16 != 0)
{
std::vector<std::uint8_t> ciphertext(plaintext.size()); throw std::runtime_error("");
}
auto ciphertext = std::vector<std::uint8_t>(plaintext.size());
auto expanded_key = rijndael_setup(key.data(), key.size());
auto len = plaintext.size(); auto len = plaintext.size();
auto ct = ciphertext.data(); auto ct = ciphertext.data();
auto pt = plaintext.data(); auto pt = plaintext.data();
auto iv_vec = original_iv; auto iv_vec = original_iv;
auto iv = iv_vec.data(); auto iv = iv_vec.data();
if (len % 16) { while (len)
throw std::runtime_error(""); {
} for (auto x = 0; x < 16; x++)
{
#ifdef LTC_FAST
if (16 % sizeof(LTC_FAST_TYPE)) {
throw std::runtime_error("");
}
#endif
while (len) {
// xor IV against plaintext
#if defined(LTC_FAST)
for (auto x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) {
*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)iv + x)) ^= *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x));
}
#else
for (auto x = 0; x < 16; x++) {
iv[x] ^= pt[x]; iv[x] ^= pt[x];
} }
#endif
// encrypt
rijndael_ecb_encrypt(iv, ct, expanded_key); rijndael_ecb_encrypt(iv, ct, expanded_key);
// store IV [ciphertext] for a future block for (auto x = 0; x < 16; x++)
#if defined(LTC_FAST) {
for (auto x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) {
*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)iv + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x));
}
#else
for (auto x = 0; x < 16; x++) {
iv[x] = ct[x]; iv[x] = ct[x];
} }
#endif
pt += 16; pt += 16;
ct += 16; ct += 16;
@ -1481,51 +1443,31 @@ std::vector<std::uint8_t> aes_cbc_decrypt(
{ {
if (ciphertext.empty()) return {}; if (ciphertext.empty()) return {};
auto expanded_key = rijndael_setup(key.data(), key.size(), 0); if (ciphertext.size() % 16 != 0)
{
throw std::runtime_error("");
}
std::vector<std::uint8_t> plaintext(ciphertext.size()); std::array<std::uint8_t, 16> temporary{{0}};
auto plaintext = std::vector<std::uint8_t>(ciphertext.size());
auto expanded_key = rijndael_setup(key.data(), key.size());
auto len = ciphertext.size(); auto len = ciphertext.size();
auto ct = ciphertext.data(); auto ct = ciphertext.data();
auto pt = plaintext.data(); auto pt = plaintext.data();
auto iv_vec = original_iv; auto iv_vec = original_iv;
auto iv = iv_vec.data(); auto iv = iv_vec.data();
unsigned char tmp[16]; while (len)
#ifdef LTC_FAST {
LTC_FAST_TYPE tmpy; rijndael_ecb_decrypt(ct, temporary.data(), expanded_key);
#else
unsigned char tmpy;
#endif
if (len % 16 != 0) { for (auto x = 0; x < 16; x++)
throw std::runtime_error(""); {
} auto tmpy = temporary[x] ^ iv[x];
#ifdef LTC_FAST
if (16 % sizeof(LTC_FAST_TYPE)) {
throw std::runtime_error("");
}
#endif
while (len) {
/* decrypt */
rijndael_ecb_decrypt(ct, tmp, expanded_key);
/* xor IV against plaintext */
#if defined(LTC_FAST)
for (auto x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) {
tmpy = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)iv + x)) ^ *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)tmp + x));
*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)iv + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x));
*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) = tmpy;
}
#else
for (auto x = 0; x < 16; x++) {
tmpy = tmp[x] ^ iv[x];
iv[x] = ct[x]; iv[x] = ct[x];
pt[x] = tmpy; pt[x] = tmpy;
} }
#endif
pt += 16; pt += 16;
ct += 16; ct += 16;
@ -1537,5 +1479,3 @@ std::vector<std::uint8_t> aes_cbc_decrypt(
} // namespace detail } // namespace detail
} // namespace xlnt } // namespace xlnt
#pragma clang diagnostic pop