diff --git a/libdevcrypto/AES.cpp b/libdevcrypto/AES.cpp index c3ea0393691..0af9da94d90 100644 --- a/libdevcrypto/AES.cpp +++ b/libdevcrypto/AES.cpp @@ -28,101 +28,85 @@ using namespace std; using namespace dev; -using namespace dev::crypto; using namespace CryptoPP; -// The number of columns comprising a state in AES. This is a constant in AES. Value=4 -#define Nb 4 -// The number of 32 bit words in a key. -#define Nk 4 -// Key length in bytes [128 bit] -#define KEYLEN 16 -// The number of rounds in AES Cipher. -#define Nr 10 - - -/*****************************************************************************/ -/* Private variables: */ -/*****************************************************************************/ -// state - array holding the intermediate results during decryption. -typedef uint8_t state_t[4][4]; - -// The array that stores the round keys. -static uint8_t RoundKey[176]; - -// The Key input to the AES Program -static const uint8_t* Key; - -// The lookup-tables are marked const so they can be placed in read-only storage instead of RAM -// The numbers below can be computed dynamically trading ROM for RAM - -// This can be useful in (embedded) bootloader applications, where ROM is often limited. -static const uint8_t sbox[256] = { - //0 1 2 3 4 5 6 7 8 9 A B C D E F - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; +namespace +{ + +// This code is modified version of https://github.com/kokke/tiny-AES128-C. + +constexpr int Nb = 4; ///< Number of columns in a AES state. +constexpr int Nk = 4; ///< The number of 32 bit words in a key. +constexpr int c_keySize = 16; ///< Key length in bytes (128 bit). +constexpr int Nr = 10; ///< The number of rounds in AES Cipher. + +using state_t = byte[4][4]; + +/// The lookup-tables. +const byte sbox[256] = { + //0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 +}; // The round constant word array, Rcon[i], contains the values given by // x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8) // Note that i starts at 1, not 0). -static const uint8_t Rcon[255] = { - 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, - 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, - 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, - 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, - 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, - 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, - 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, - 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, - 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, - 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, - 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, - 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, - 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, - 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, - 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, - 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb }; - - -static uint8_t getSBoxValue(uint8_t num) -{ - return sbox[num]; -} - -// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states. -static void KeyExpansion(void) +const byte Rcon[255] = { + 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, + 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, + 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, + 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, + 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, + 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, + 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, + 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, + 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, + 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, + 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, + 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, + 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, + 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, + 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, + 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb +}; + +/// Produces Nb(Nr+1) round keys. The round keys are used in each round +/// to decrypt the states. +void keyExpansion(byte* roundKeys, byte const* key) { - uint32_t i, j, k; - uint8_t tempa[4]; // Used for the column/row operations + int i; + byte tempa[4]; // Used for the column/row operations // The first round key is the key itself. - for(i = 0; i < Nk; ++i) + for (i = 0; i < Nk; ++i) { - RoundKey[(i * 4) + 0] = Key[(i * 4) + 0]; - RoundKey[(i * 4) + 1] = Key[(i * 4) + 1]; - RoundKey[(i * 4) + 2] = Key[(i * 4) + 2]; - RoundKey[(i * 4) + 3] = Key[(i * 4) + 3]; + roundKeys[(i * 4) + 0] = key[(i * 4) + 0]; + roundKeys[(i * 4) + 1] = key[(i * 4) + 1]; + roundKeys[(i * 4) + 2] = key[(i * 4) + 2]; + roundKeys[(i * 4) + 3] = key[(i * 4) + 3]; } // All other round keys are found from the previous round keys. for(; (i < (Nb * (Nr + 1))); ++i) { - for(j = 0; j < 4; ++j) + for (int j = 0; j < 4; ++j) { - tempa[j]=RoundKey[(i-1) * 4 + j]; + tempa[j] = roundKeys[(i-1) * 4 + j]; } if (i % Nk == 0) { @@ -131,7 +115,7 @@ static void KeyExpansion(void) // Function RotWord() { - k = tempa[0]; + auto k = tempa[0]; tempa[0] = tempa[1]; tempa[1] = tempa[2]; tempa[2] = tempa[3]; @@ -143,55 +127,45 @@ static void KeyExpansion(void) // Function Subword() { - tempa[0] = getSBoxValue(tempa[0]); - tempa[1] = getSBoxValue(tempa[1]); - tempa[2] = getSBoxValue(tempa[2]); - tempa[3] = getSBoxValue(tempa[3]); + tempa[0] = sbox[tempa[0]]; + tempa[1] = sbox[tempa[1]]; + tempa[2] = sbox[tempa[2]]; + tempa[3] = sbox[tempa[3]]; } tempa[0] = tempa[0] ^ Rcon[i/Nk]; } - RoundKey[i * 4 + 0] = RoundKey[(i - Nk) * 4 + 0] ^ tempa[0]; - RoundKey[i * 4 + 1] = RoundKey[(i - Nk) * 4 + 1] ^ tempa[1]; - RoundKey[i * 4 + 2] = RoundKey[(i - Nk) * 4 + 2] ^ tempa[2]; - RoundKey[i * 4 + 3] = RoundKey[(i - Nk) * 4 + 3] ^ tempa[3]; + roundKeys[i * 4 + 0] = roundKeys[(i - Nk) * 4 + 0] ^ tempa[0]; + roundKeys[i * 4 + 1] = roundKeys[(i - Nk) * 4 + 1] ^ tempa[1]; + roundKeys[i * 4 + 2] = roundKeys[(i - Nk) * 4 + 2] ^ tempa[2]; + roundKeys[i * 4 + 3] = roundKeys[(i - Nk) * 4 + 3] ^ tempa[3]; } } -// This function adds the round key to state. -// The round key is added to the state by an XOR function. -static void AddRoundKey(state_t* state, uint8_t round) +/// Adds the round key to state. +/// The round key is added to the state by an XOR function. +void addRoundKey(state_t* state, byte const* roundKeys, int round) { - uint8_t i,j; - for(i=0;i<4;++i) - { - for(j = 0; j < 4; ++j) - { - (*state)[i][j] ^= RoundKey[round * Nb * 4 + i * Nb + j]; - } - } + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 4; ++j) + (*state)[i][j] ^= roundKeys[round * Nb * 4 + i * Nb + j]; } -// The SubBytes Function Substitutes the values in the -// state matrix with values in an S-box. -static void SubBytes(state_t* state) +/// Substitutes the values in the +/// state matrix with values in an S-box. +void subBytes(state_t* state) { - uint8_t i, j; - for(i = 0; i < 4; ++i) - { - for(j = 0; j < 4; ++j) - { - (*state)[j][i] = getSBoxValue((*state)[j][i]); - } - } + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 4; ++j) + (*state)[j][i] = sbox[(*state)[j][i]]; } -// The ShiftRows() function shifts the rows in the state to the left. -// Each row is shifted with different offset. -// Offset = Row number. So the first row is not shifted. -static void ShiftRows(state_t* state) +/// Shifts the rows in the state to the left. +/// Each row is shifted with different offset. +/// Offset = Row number. So the first row is not shifted. +void shiftRows(state_t* state) { - uint8_t temp; + byte temp; // Rotate first row 1 columns to left temp = (*state)[0][1]; @@ -205,108 +179,112 @@ static void ShiftRows(state_t* state) (*state)[0][2] = (*state)[2][2]; (*state)[2][2] = temp; - temp = (*state)[1][2]; + temp = (*state)[1][2]; (*state)[1][2] = (*state)[3][2]; (*state)[3][2] = temp; // Rotate third row 3 columns to left - temp = (*state)[0][3]; + temp = (*state)[0][3]; (*state)[0][3] = (*state)[3][3]; (*state)[3][3] = (*state)[2][3]; (*state)[2][3] = (*state)[1][3]; (*state)[1][3] = temp; } -static uint8_t xtime(uint8_t x) +inline byte xtime(byte x) { - return ((x<<1) ^ (((x>>7) & 1) * 0x1b)); + return static_cast(x<<1) ^ (((x>>7) & 1) * 0x1b); } // MixColumns function mixes the columns of the state matrix -static void MixColumns(state_t* state) +void mixColumns(state_t* state) { - uint8_t i; - uint8_t Tmp,Tm,t; - for(i = 0; i < 4; ++i) + byte Tmp,Tm,t; + for(auto i = 0; i < 4; ++i) { t = (*state)[i][0]; Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ; Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ; Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ; Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ; - Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ; + Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ; } } - // Cipher is the main function that encrypts the PlainText. -static void Cipher(state_t* state) +void cipher(state_t* state, byte const* roundKeys) { - uint8_t round = 0; - // Add the First round key to the state before starting the rounds. - AddRoundKey(state, 0); + addRoundKey(state, roundKeys, 0); // There will be Nr rounds. // The first Nr-1 rounds are identical. // These Nr-1 rounds are executed in the loop below. - for(round = 1; round < Nr; ++round) + for (int round = 1; round < Nr; ++round) { - SubBytes(state); - ShiftRows(state); - MixColumns(state); - AddRoundKey(state, round); + subBytes(state); + shiftRows(state); + mixColumns(state); + addRoundKey(state, roundKeys, round); } // The last round is given below. // The MixColumns function is not here in the last round. - SubBytes(state); - ShiftRows(state); - AddRoundKey(state, Nr); + subBytes(state); + shiftRows(state); + addRoundKey(state, roundKeys, Nr); } -static void BlockCopy(uint8_t* output, const uint8_t* input) +void AES128_CTR_process_buffer(byte* output, const byte* input, size_t length, const byte* key, const byte* iv) { - uint8_t i; - for (i=0;i= 0; --j) + { + ++(ctr[j]); + + if (ctr[j]) + break; + } + } + + output[i] = (input[i]) ^ ((&state[0][0])[i & 0x0000000F]); } } +} -void dev::AES128_CTR_process_buffer(uint8_t* output, const uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv) +bytes dev::encryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _plain) { - state_t state; - uint32_t i = 0; - uint8_t ctr[KEYLEN]; - - BlockCopy(ctr, iv); - Key = key; - KeyExpansion(); - - while (i < length) - { - if ((i & 0x0000000F) == 0) - { - BlockCopy(&state[0][0], ctr); - Cipher(&state); - - for (int j = KEYLEN - 1; j >= 0; --j) - { - ++(ctr[j]); - - if (ctr[j]) - break; - } - } + if (_k.size() != 16) + return {}; - output[i] = (input[i]) ^ (((uint8_t*)state)[i & 0x0000000F]); - ++i; - } + bytes ret(_plain.size()); + AES128_CTR_process_buffer(ret.data(), _plain.data(), _plain.size(), _k.data(), _iv.data()); + return ret; } +bytesSec dev::decryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _cipher) +{ + if (_k.size() != 16) + return {}; + bytesSec ret(_cipher.size()); + AES128_CTR_process_buffer(ret.writable().data(), _cipher.data(), _cipher.size(), _k.data(), _iv.data()); + return ret; +} bytes dev::aesDecrypt(bytesConstRef _ivCipher, std::string const& _password, unsigned _rounds, bytesConstRef _salt) { diff --git a/libdevcrypto/AES.h b/libdevcrypto/AES.h index 33139d62c89..498e60cbf8c 100644 --- a/libdevcrypto/AES.h +++ b/libdevcrypto/AES.h @@ -24,12 +24,24 @@ #pragma once -#include "Common.h" +#include namespace dev { -void AES128_CTR_process_buffer(uint8_t* output, const uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv); +/// Encrypts payload with specified IV/ctr using AES128-CTR. +bytes encryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _plain); + +/// Decrypts payload with specified IV/ctr using AES128-CTR. +bytesSec decryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _cipher); + +/// Encrypts payload with specified IV/ctr using AES128-CTR. +inline bytes encryptSymNoAuth(SecureFixedHash<16> const& _k, h128 const& _iv, bytesConstRef _plain) { return encryptAES128CTR(_k.ref(), _iv, _plain); } +inline bytes encryptSymNoAuth(SecureFixedHash<32> const& _k, h128 const& _iv, bytesConstRef _plain) { return encryptAES128CTR(_k.ref(), _iv, _plain); } + +/// Decrypts payload with specified IV/ctr using AES128-CTR. +inline bytesSec decryptSymNoAuth(SecureFixedHash<16> const& _k, h128 const& _iv, bytesConstRef _cipher) { return decryptAES128CTR(_k.ref(), _iv, _cipher); } +inline bytesSec decryptSymNoAuth(SecureFixedHash<32> const& _k, h128 const& _iv, bytesConstRef _cipher) { return decryptAES128CTR(_k.ref(), _iv, _cipher); } bytes aesDecrypt(bytesConstRef _cipher, std::string const& _password, unsigned _rounds = 2000, bytesConstRef _salt = bytesConstRef()); diff --git a/libdevcrypto/Common.cpp b/libdevcrypto/Common.cpp index a95dcdce612..5d3c0734bf9 100644 --- a/libdevcrypto/Common.cpp +++ b/libdevcrypto/Common.cpp @@ -161,26 +161,6 @@ std::pair dev::encryptSymNoAuth(SecureFixedHash<16> const& _k, byte return make_pair(encryptSymNoAuth(_k, iv, _plain), iv); } -bytes dev::encryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _plain) -{ - if (_k.size() != 16) - return {}; - - bytes ret(_plain.size()); - AES128_CTR_process_buffer(ret.data(), _plain.data(), _plain.size(), _k.data(), _iv.data()); - return ret; -} - -bytesSec dev::decryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _cipher) -{ - if (_k.size() != 16) - return {}; - - bytesSec ret(_cipher.size()); - AES128_CTR_process_buffer(ret.writable().data(), _cipher.data(), _cipher.size(), _k.data(), _iv.data()); - return ret; -} - Public dev::recover(Signature const& _sig, h256 const& _message) { int v = _sig[64]; diff --git a/libdevcrypto/Common.h b/libdevcrypto/Common.h index ad95bcbada0..a67b6f0c1dc 100644 --- a/libdevcrypto/Common.h +++ b/libdevcrypto/Common.h @@ -115,26 +115,12 @@ bool decryptECIES(Secret const& _k, bytesConstRef _sharedMacData, bytesConstRef /// Encrypts payload with random IV/ctr using AES128-CTR. std::pair encryptSymNoAuth(SecureFixedHash<16> const& _k, bytesConstRef _plain); -/// Encrypts payload with specified IV/ctr using AES128-CTR. -bytes encryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _plain); - -/// Decrypts payload with specified IV/ctr using AES128-CTR. -bytesSec decryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _cipher); - -/// Encrypts payload with specified IV/ctr using AES128-CTR. -inline bytes encryptSymNoAuth(SecureFixedHash<16> const& _k, h128 const& _iv, bytesConstRef _plain) { return encryptAES128CTR(_k.ref(), _iv, _plain); } -inline bytes encryptSymNoAuth(SecureFixedHash<32> const& _k, h128 const& _iv, bytesConstRef _plain) { return encryptAES128CTR(_k.ref(), _iv, _plain); } - -/// Decrypts payload with specified IV/ctr using AES128-CTR. -inline bytesSec decryptSymNoAuth(SecureFixedHash<16> const& _k, h128 const& _iv, bytesConstRef _cipher) { return decryptAES128CTR(_k.ref(), _iv, _cipher); } -inline bytesSec decryptSymNoAuth(SecureFixedHash<32> const& _k, h128 const& _iv, bytesConstRef _cipher) { return decryptAES128CTR(_k.ref(), _iv, _cipher); } - /// Recovers Public key from signed message hash. Public recover(Signature const& _sig, h256 const& _hash); - + /// Returns siganture of message hash. Signature sign(Secret const& _k, h256 const& _hash); - + /// Verify signature. bool verify(Public const& _k, Signature const& _s, h256 const& _hash); diff --git a/libdevcrypto/CryptoPP.cpp b/libdevcrypto/CryptoPP.cpp index 66aaf93ffdc..55b529b241a 100644 --- a/libdevcrypto/CryptoPP.cpp +++ b/libdevcrypto/CryptoPP.cpp @@ -27,6 +27,7 @@ #include #include #include "ECDHE.h" +#include "AES.h" static_assert(CRYPTOPP_VERSION == 570, "Wrong Crypto++ version"); diff --git a/libdevcrypto/SecretStore.cpp b/libdevcrypto/SecretStore.cpp index 0b792f117cb..e508c434fa0 100644 --- a/libdevcrypto/SecretStore.cpp +++ b/libdevcrypto/SecretStore.cpp @@ -30,6 +30,8 @@ #include #include #include +#include "AES.h" + using namespace std; using namespace dev; namespace js = json_spirit; diff --git a/test/libdevcrypto/crypto.cpp b/test/libdevcrypto/crypto.cpp index 875db598ba7..5b69703023c 100644 --- a/test/libdevcrypto/crypto.cpp +++ b/test/libdevcrypto/crypto.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include using namespace std;