Fork of François Berder Crypto, fixed AES CBC and small rework
Dependents: AES_example shaun_larada Smartage
Fork of Crypto by
Revision 0:7a1237bd2d13, committed 2013-09-07
- Comitter:
- feb11
- Date:
- Sat Sep 07 23:47:28 2013 +0000
- Child:
- 1:14a7cea431aa
- Commit message:
- initial import
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AES.cpp Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,294 @@ +#include "AES.h" +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +static const uint8_t sbox[] = +{ + 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 +}; + +static const uint8_t inv_s[] = +{ + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, + 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, + 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, + 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, + 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, + 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, + 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, + 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, + 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, + 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, + 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D +}; + + +static const uint32_t rcon[10]= +{ + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000 +}; + +AES::AES(const AES_TYPE t, uint8_t *key): +state() +{ + switch(t) + { + case AES_128: + nr = 10; + nk = 4; + break; + + case AES_192: + nr = 12; + nk = 6; + break; + + case AES_256: + nr = 14; + nk = 8; + break; + } + + keyExpansion(key); +} + +void AES::keyExpansion(uint8_t *key) +{ + uint32_t temp; + int i = 0; + + while(i < nk) + { + w[i] = (key[4*i] << 24) + (key[4*i+1] << 16) + (key[4*i+2] << 8) + key[4*i+3]; + i++; + } + i = nk; + while(i < 4*(nr+1)) + { + temp = w[i-1]; + if(i % nk == 0) + { + temp = rotWord(temp); + temp = subWord(temp); + temp ^= rcon[i/nk-1]; + } + else if(nk > 6 && i % nk == 4) + temp = subWord(temp); + w[i] = w[i-nk] ^ temp; + i++; + } +} + +uint32_t AES::rotWord(uint32_t w) +{ + return (w << 8) + (w >> 24); +} + +uint32_t AES::invRotWord(uint32_t w) +{ + return (w >> 8) + (w << 24); +} + +uint32_t AES::subWord(uint32_t w) +{ + uint32_t out = 0; + for(int i = 0; i < 4; ++i) + { + uint8_t temp = (w & 0xFF); + out |= (sbox[temp] << (8*i)); + w = (w >> 8); + } + return out; +} + +void AES::subBytes() +{ + for(int i = 0; i < 16; ++i) + state[i] = sbox[state[i]]; +} + +void AES::invSubBytes() +{ + for(int i = 0; i < 16; ++i) + state[i] = inv_s[state[i]]; +} + +void AES::shiftRows() +{ + for(int r = 0; r < 4; ++r) + { + uint32_t temp = (state[r] << 24) + (state[r+4] << 16) + (state[r+8] << 8) + state[r+12]; + int i = r; + while(i > 0) + { + temp = rotWord(temp); + --i; + } + state[r] = temp >> 24; + state[r+4] = (temp & 0x00FF0000) >> 16; + state[r+8] = (temp & 0x0000FF00) >> 8; + state[r+12] = temp & 0xFF; + } +} + +void AES::invShiftRows() +{ + for(int r = 0; r < 4; ++r) + { + uint32_t temp = (state[r] << 24) + (state[r+4] << 16) + (state[r+8] << 8) + state[r+12]; + int i = r; + while(i > 0) + { + temp = invRotWord(temp); + --i; + } + state[r] = temp >> 24; + state[r+4] = (temp & 0x00FF0000) >> 16; + state[r+8] = (temp & 0x0000FF00) >> 8; + state[r+12] = temp & 0xFF; + } +} + +/* Multiply two numbers in the GF(2^8) finite field defined + * by the polynomial x^8 + x^4 + x^3 + x + 1 */ +uint8_t gmul(uint8_t a, uint8_t b) +{ + uint8_t p = 0; + uint8_t counter; + uint8_t carry; + for (counter = 0; counter < 8; counter++) { + if (b & 1) + p ^= a; + carry = (a & 0x80); + a <<= 1; + if (carry) + a ^= 0x001B; /* what x^8 is modulo x^8 + x^4 + x^3 + x^2 + 1 */ + b >>= 1; + } + return p; +} + +void AES::mul(uint8_t *r) +{ + uint8_t tmp[4]; + memcpy(tmp, r, 4); + r[0] = gmul(tmp[0],2) ^ gmul(tmp[1],3) ^ tmp[2] ^ tmp[3]; + r[1] = tmp[0] ^ gmul(tmp[1],2) ^ gmul(tmp[2],3) ^ tmp[3]; + r[2] = tmp[0] ^ tmp[1] ^ gmul(tmp[2],2) ^ gmul(tmp[3],3); + r[3] = gmul(tmp[0],3) ^ tmp[1] ^ tmp[2] ^ gmul(tmp[3],2); +} + +void AES::invMul(uint8_t *r) +{ + uint8_t tmp[4]; + memcpy(tmp, r, 4); + r[0] = gmul(tmp[0],0x0e) ^ gmul(tmp[1],0x0b) ^ gmul(tmp[2],0x0d) ^ gmul(tmp[3],9); + r[1] = gmul(tmp[0],9) ^ gmul(tmp[1],0x0e) ^ gmul(tmp[2],0x0b) ^ gmul(tmp[3],0x0d); + r[2] = gmul(tmp[0],0x0d) ^ gmul(tmp[1],9) ^ gmul(tmp[2],0x0e) ^ gmul(tmp[3],0x0b); + r[3] = gmul(tmp[0],0x0b) ^ gmul(tmp[1],0x0d) ^ gmul(tmp[2],9) ^ gmul(tmp[3],0x0e); +} + +void AES::mixColumns() +{ + for(int c = 0; c < 4; ++c) + mul(&state[4*c]); +} + +void AES::invMixColumns() +{ + for(int c = 0; c < 4; ++c) + invMul(&state[4*c]); +} + +void AES::addRoundKey(int round) +{ + for(int c = 0; c < 4; ++c) + { + uint32_t temp = (state[4*c] << 24) + (state[4*c+1] << 16) + (state[4*c+2] << 8) + state[4*c+3]; + temp ^= w[round*4+c]; + state[4*c] = (temp >> 24); + state[4*c+1] = ((temp & 0x00FF0000) >> 16); + state[4*c+2] = ((temp & 0x0000FF00) >> 8); + state[4*c+3] = temp & 0xFF; + } +} + +void AES::decryptBlock(uint8_t *out, uint8_t *in) +{ + memcpy(state,in,16); + + addRoundKey(nr); + + for(int round = nr-1; round > 0; --round) + { + invShiftRows(); + invSubBytes(); + addRoundKey(round); + invMixColumns(); + } + invShiftRows(); + invSubBytes(); + addRoundKey(0); + + memcpy(out, state, 16); +} + +void AES::encryptBlock(uint8_t *out, uint8_t *in) +{ + memcpy(state,in,16); + + addRoundKey(0); + + for(int round = 1; round < nr; ++round) + { + subBytes(); + shiftRows(); + mixColumns(); + addRoundKey(round); + } + subBytes(); + shiftRows(); + addRoundKey(nr); + + memcpy(out, state, 16); +} + +void AES::encrypt(uint8_t *out, uint8_t *in, uint32_t length) +{ + for(uint32_t i = 0; i < length; i+=16) + encryptBlock(&out[i], &in[i]); +} + +void AES::decrypt(uint8_t *out, uint8_t *in, uint32_t length) +{ + for(uint32_t i = 0; i < length; i+=16) + decryptBlock(&out[i], &in[i]); +} + +uint32_t AES::getBlockSize() const +{ + return 16; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AES.h Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,47 @@ +#ifndef AES_H +#define AES_H + +#include "Cipher.h" + +enum AES_TYPE +{ + AES_128 = 4, + AES_192 = 6, + AES_256 = 8 +}; + +class AES : public Cipher +{ + public : + + AES(const AES_TYPE type, uint8_t *key); + + virtual void encrypt(uint8_t *out, uint8_t *in, uint32_t length); + virtual void decrypt(uint8_t *out, uint8_t *in, uint32_t length); + virtual uint32_t getBlockSize() const; + + private : + + void encryptBlock(uint8_t *out, uint8_t *in); + void decryptBlock(uint8_t *out, uint8_t *in); + + void keyExpansion(uint8_t *key); + uint32_t rotWord(uint32_t w); + uint32_t invRotWord(uint32_t w); + uint32_t subWord(uint32_t w); + void subBytes(); + void invSubBytes(); + void shiftRows(); + void invShiftRows(); + void mul(uint8_t *r); + void invMul(uint8_t *r); + void mixColumns(); + void invMixColumns(); + void addRoundKey(int round); + + uint8_t state[16]; + uint32_t w[60]; + uint8_t nr,nk; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Cipher.cpp Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,12 @@ +#include "Cipher.h" + +Cipher::~Cipher() +{ +} + + +CIPHER_TYPE Cipher::getType() const +{ + return getBlockSize() <= 1 ? STREAM_CIPHER : BLOCK_CIPHER; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Cipher.h Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,27 @@ +#ifndef CIPHER_H +#define CIPHER_H + +#include <stdint.h> + +enum CIPHER_TYPE +{ + STREAM_CIPHER, + BLOCK_CIPHER +}; + +class Cipher +{ + public : + + virtual ~Cipher(); + + virtual void encrypt(uint8_t *out, uint8_t *in, uint32_t length) = 0; + virtual void decrypt(uint8_t *out, uint8_t *in, uint32_t length) = 0; + virtual uint32_t getBlockSize() const = 0; + + CIPHER_TYPE getType() const; + +}; + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Crypto.h Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,12 @@ +#ifndef CRYPTO_H +#define CRYPTO_H + +#include "AES.h" +#include "RC4.h" + +#include "MD2.h" +#include "MD5.h" +#include "SHA1.h" +#include "SHA2.h" + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HashAlgorithm.cpp Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,5 @@ +#include "HashAlgorithm.h" + +HashAlgorithm::~HashAlgorithm() +{ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HashAlgorithm.h Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,16 @@ +#ifndef HASH_ALGORITHM_H +#define HASH_ALGORITHM_H + +#include <stdint.h> + +class HashAlgorithm +{ + public : + + virtual ~HashAlgorithm(); + virtual void add(uint8_t *in, uint32_t length) = 0; + virtual void computeDigest(uint8_t *out) = 0; + virtual uint8_t outputSize() const = 0; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MD2.cpp Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,170 @@ +#include "MD2.h" +#include <string.h> + +static const uint8_t s[] = +{ + 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, + 0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA, + 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, + 0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A, + 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21, + 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, + 0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6, + 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, + 0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02, + 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F, + 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, + 0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52, + 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, + 0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39, + 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, + 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14 +}; + + +MD2::MD2(): +HashAlgorithm(), +bufferLength(0), +l(0) +{ + memset(checksum, 0, 16); + memset(x, 0, 48); +} + +void MD2::computeBuffer() +{ + for(int j = 0; j < 16; ++j) + { + uint8_t c = buffer[j]; + checksum[j] ^= s[c^l]; + l = checksum[j]; + } + + + for(int j = 0; j < 16; ++j) + { + x[16+j] = buffer[j]; + x[32+j] = x[16+j] ^ x[j]; + } + + uint8_t t = 0; + + for(int j = 0; j < 18; ++j) + { + for(int k = 0; k < 48; ++k) + { + x[k] = x[k] ^ s[t]; + t = x[k]; + } + t += j; + } +} + +void MD2::add(uint8_t *in, uint32_t length) +{ + if(length < 16-bufferLength) + { + memcpy(&buffer[bufferLength], in, length); + bufferLength += length; + return; + } + int offset = 16-bufferLength; + memcpy(&buffer[bufferLength], in, offset); + computeBuffer(); + while(length-offset > 16) + { + memcpy(buffer, &in[offset], 16); + computeBuffer(); + offset += 16; + } + if(offset > length) + offset -= 16; + bufferLength = length - offset; + memcpy(buffer, &in[offset], bufferLength); +} + +void MD2::computeDigest(uint8_t *digest) +{ + // compute what's left in the buffer + int padding = 16 - bufferLength; + memset(&buffer[bufferLength], padding, padding); + computeBuffer(); + + for(int j = 0; j < 16; ++j) + { + x[16+j] = checksum[j]; + x[32+j] = x[16+j] ^ x[j]; + } + + uint8_t t = 0; + + for(int j = 0; j < 18; ++j) + { + for(int k = 0; k < 48; ++k) + { + x[k] = x[k] ^ s[t]; + t = x[k]; + } + t += j; + } + + // reset state + bufferLength = 0; + l = 0; + memset(checksum, 0, 16); + memcpy(digest, x, 16); + memset(x,0,48); +} + +uint8_t MD2::outputSize() const +{ + return 16; +} + +void MD2::computeDigest(uint8_t *digest, uint8_t *in, uint32_t length) +{ + uint8_t padding = 16 - (length % 16); + int totalLength = length + 16 + padding; + uint8_t *buffer = new uint8_t[totalLength]; + memcpy(buffer, in, length); + memset(&buffer[length], padding, padding); + uint8_t checksum[16]; + memset(checksum, 0, 16); + uint8_t l = 0; + + for(int i = 0; i < ((totalLength-16)/16); ++i) + { + for(int j = 0; j < 16; ++j) + { + uint8_t c = buffer[i*16+j]; + checksum[j] ^= s[c^l]; + l = checksum[j]; + } + } + memcpy(&buffer[totalLength-16], checksum, 16); + + uint8_t x[48]; + memset(x,0,48); + + for(int i = 0; i < (totalLength/16); ++i) + { + for(int j = 0; j < 16; ++j) + { + x[16+j] = buffer[i*16+j]; + x[32+j] = x[16+j] ^ x[j]; + } + + uint8_t t = 0; + + for(int j = 0; j < 18; ++j) + { + for(int k = 0; k < 48; ++k) + { + t = x[k] = x[k] ^ s[t]; + } + t += j; + } + } + delete[] buffer; + memcpy(digest, x, 16); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MD2.h Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,30 @@ +#ifndef MD2_H +#define MD2_H + +#include "HashAlgorithm.h" + +class MD2 : public HashAlgorithm +{ + public : + + MD2(); + + virtual void add(uint8_t *in, uint32_t length); + virtual void computeDigest(uint8_t *out); + virtual uint8_t outputSize() const; + + static void computeDigest(uint8_t *digest, uint8_t *in, uint32_t length); + + private : + + void computeBuffer(); + + uint8_t bufferLength; + uint8_t l; + uint8_t buffer[16]; + uint8_t checksum[16]; + uint8_t x[48]; +}; + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MD5.cpp Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,231 @@ +#include "MD5.h" +#include <string.h> + +static const uint32_t T[] = +{ + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 +}; + +static const uint32_t A = 0x67452301; +static const uint32_t B = 0xefcdab89; +static const uint32_t C = 0x98badcfe; +static const uint32_t D = 0x10325476; + +static uint32_t F(uint32_t x, uint32_t y, uint32_t z) +{ + return (x & y) | ((~x) & z); +} + +static uint32_t G(uint32_t x, uint32_t y, uint32_t z) +{ + return (x & z) | (y & (~z)); +} + +static uint32_t H(uint32_t x, uint32_t y, uint32_t z) +{ + return x ^ y ^ z; +} + +static uint32_t I(uint32_t x, uint32_t y, uint32_t z) +{ + return y ^ (x | (~z)); +} + +static uint32_t rotLeft(uint32_t w, uint8_t s) +{ + return (w << s) | (w >> (32-s)); +} + +#define ROUND1(a,b,c,d,k,s,i) \ + a += F(b,c,d) + x[k] + T[i-1]; \ + a = rotLeft(a,s);\ + a += b; +#define ROUND2(a,b,c,d,k,s,i) \ + a += G(b,c,d) + x[k] + T[i-1]; \ + a = rotLeft(a,s);\ + a += b; +#define ROUND3(a,b,c,d,k,s,i) \ + a += H(b,c,d) + x[k] + T[i-1]; \ + a = rotLeft(a,s);\ + a += b; +#define ROUND4(a,b,c,d,k,s,i) \ + a += I(b,c,d) + x[k] + T[i-1]; \ + a = rotLeft(a,s);\ + a += b; + + +MD5::MD5(): +HashAlgorithm(), +a(A), +b(B), +c(C), +d(D), +totalBufferLength(0), +buffer(), +bufferLength(0) +{ +} + +uint8_t MD5::outputSize() const +{ + return 16; +} + +void MD5::add(uint8_t *in, uint32_t length) +{ + if(length < 64-bufferLength) + { + memcpy(&buffer[bufferLength], in, length); + bufferLength += length; + totalBufferLength += length; + return; + } + int offset = 64-bufferLength; + memcpy(&buffer[bufferLength], in, offset); + uint32_t tmpA = a, tmpB = b, tmpC = c, tmpD = d; + computeRounds(&a, &b, &c, &d, buffer); + a += tmpA; + b += tmpB; + c += tmpC; + d += tmpD; + while(length-offset > 64) + { + memcpy(buffer, &in[offset], 64); + tmpA = a; + tmpB = b; + tmpC = c; + tmpD = d; + computeRounds(&a, &b, &c, &d, buffer); + a += tmpA; + b += tmpB; + c += tmpC; + d += tmpD; + offset += 64; + } + if(offset > length) + offset -= 64; + bufferLength = length - offset; + memcpy(buffer, &in[offset], bufferLength); + totalBufferLength += length; +} + +void MD5::computeDigest(uint8_t *digest) +{ + uint16_t padding; + if(totalBufferLength % 64 < 56) + padding = 56 - (totalBufferLength % 64); + else + padding = 56 + (64 - (totalBufferLength % 64)); + uint8_t val = 0x80; + add(&val, 1); + val = 0; + for(int i = 0; i < padding-1; ++i) + add(&val,1); + totalBufferLength -= padding; + uint64_t lengthBit = totalBufferLength * 8; + uint32_t lengthBitLow = lengthBit; + uint32_t lengthBitHigh = lengthBit >> 32; + add((uint8_t*)&lengthBitLow,4); + add((uint8_t*)&lengthBitHigh,4); + + memcpy(digest, &a, 4); + memcpy(&digest[4], &b, 4); + memcpy(&digest[8], &c, 4); + memcpy(&digest[12], &d, 4); + // reset state + a = A; + b = B; + c = C; + d = D; + totalBufferLength = 0; + bufferLength = 0; +} + +void MD5::computeRounds(uint32_t *a2, uint32_t *b2, uint32_t *c2, uint32_t *d2, uint8_t *buffer) +{ + uint32_t a = *a2, b = *b2, c = *c2, d = *d2; + uint32_t x[16]; + for(int j = 0; j < 16; ++j) + memcpy(&x[j], &buffer[j*4], 4); + + // Round 1 + ROUND1(a,b,c,d,0,7,1); ROUND1(d,a,b,c,1,12,2); ROUND1(c,d,a,b,2,17,3); ROUND1(b,c,d,a,3,22,4); + ROUND1(a,b,c,d,4,7,5); ROUND1(d,a,b,c,5,12,6); ROUND1(c,d,a,b,6,17,7); ROUND1(b,c,d,a,7,22,8); + ROUND1(a,b,c,d,8,7,9); ROUND1(d,a,b,c,9,12,10); ROUND1(c,d,a,b,10,17,11); ROUND1(b,c,d,a,11,22,12); + ROUND1(a,b,c,d,12,7,13); ROUND1(d,a,b,c,13,12,14); ROUND1(c,d,a,b,14,17,15); ROUND1(b,c,d,a,15,22,16); + + // Round 2 + ROUND2(a,b,c,d,1,5,17); ROUND2(d,a,b,c,6,9,18); ROUND2(c,d,a,b,11,14,19); ROUND2(b,c,d,a,0,20,20); + ROUND2(a,b,c,d,5,5,21); ROUND2(d,a,b,c,10,9,22); ROUND2(c,d,a,b,15,14,23); ROUND2(b,c,d,a,4,20,24); + ROUND2(a,b,c,d,9,5,25); ROUND2(d,a,b,c,14,9,26); ROUND2(c,d,a,b,3,14,27); ROUND2(b,c,d,a,8,20,28); + ROUND2(a,b,c,d,13,5,29); ROUND2(d,a,b,c,2,9,30); ROUND2(c,d,a,b,7,14,31); ROUND2(b,c,d,a,12,20,32); + + // Round 3 + ROUND3(a,b,c,d,5,4,33); ROUND3(d,a,b,c,8,11,34); ROUND3(c,d,a,b,11,16,35); ROUND3(b,c,d,a,14,23,36); + ROUND3(a,b,c,d,1,4,37); ROUND3(d,a,b,c,4,11,38); ROUND3(c,d,a,b,7,16,39); ROUND3(b,c,d,a,10,23,40); + ROUND3(a,b,c,d,13,4,41); ROUND3(d,a,b,c,0,11,42); ROUND3(c,d,a,b,3,16,43); ROUND3(b,c,d,a,6,23,44); + ROUND3(a,b,c,d,9,4,45); ROUND3(d,a,b,c,12,11,46); ROUND3(c,d,a,b,15,16,47); ROUND3(b,c,d,a,2,23,48); + + // Round 4 + ROUND4(a,b,c,d,0,6,49); ROUND4(d,a,b,c,7,10,50); ROUND4(c,d,a,b,14,15,51); ROUND4(b,c,d,a,5,21,52); + ROUND4(a,b,c,d,12,6,53); ROUND4(d,a,b,c,3,10,54); ROUND4(c,d,a,b,10,15,55); ROUND4(b,c,d,a,1,21,56); + ROUND4(a,b,c,d,8,6,57); ROUND4(d,a,b,c,15,10,58); ROUND4(c,d,a,b,6,15,59); ROUND4(b,c,d,a,13,21,60); + ROUND4(a,b,c,d,4,6,61); ROUND4(d,a,b,c,11,10,62); ROUND4(c,d,a,b,2,15,63); ROUND4(b,c,d,a,9,21,64); + + *a2 = a; + *b2 = b; + *c2 = c; + *d2 = d; +} + +void MD5::computeDigest(uint8_t *digest, uint8_t *msg, uint32_t length) +{ + uint16_t padding; + if(length % 64 < 56) + padding = 56 - (length % 64); + else + padding = 56 + (64 - (length % 64)); + uint32_t totalLength = length + padding + 8; + uint8_t *buffer = new uint8_t[totalLength]; + memcpy(buffer, msg, length); + buffer[length] = 0x80; + memset(&buffer[length+1], 0, padding-1); + uint64_t lengthBit = length * 8; + uint32_t lengthBitLow = lengthBit; + uint32_t lengthBitHigh = lengthBit >> 32; + memcpy(&buffer[length+padding], &lengthBitLow, 4); + memcpy(&buffer[length+padding+4], &lengthBitHigh, 4); + + uint32_t a = A, b = B, c = C, d = D; + for(int i = 0; i < totalLength/64; ++i) + { + uint32_t tmpA = a, tmpB = b, tmpC = c, tmpD = d; + computeRounds(&a, &b, &c, &d, &buffer[64*i]); + + a += tmpA; + b += tmpB; + c += tmpC; + d += tmpD; + } + delete[] buffer; + + memcpy(digest, &a, 4); + memcpy(&digest[4], &b, 4); + memcpy(&digest[8], &c, 4); + memcpy(&digest[12], &d, 4); +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MD5.h Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,29 @@ +#ifndef MD5_H +#define MD5_H + +#include "HashAlgorithm.h" + + +class MD5 : public HashAlgorithm +{ + public : + + MD5(); + + virtual void add(uint8_t *in, uint32_t length); + virtual void computeDigest(uint8_t *out); + virtual uint8_t outputSize() const; + + static void computeDigest(uint8_t *digest, uint8_t *in, uint32_t length); + + private : + + static void computeRounds(uint32_t *a2, uint32_t *b2, uint32_t *c2, uint32_t *d2, uint8_t *buffer); + + uint32_t a,b,c,d; + uint32_t totalBufferLength; + uint8_t buffer[64]; + uint8_t bufferLength; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RC4.cpp Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,46 @@ +#include "RC4.h" + +RC4::RC4(uint8_t *key, uint8_t keyLength): +Cipher(), +s(), +i(0), +j(0) +{ + for(int k = 0; k < 256; ++k) + s[k] = k; + int l = 0; + for(int k = 0; k < 256; ++k) + { + l = (l + s[k] + key[k % keyLength]) % 256; + uint8_t tmp = s[l]; + s[l] = s[k]; + s[k] = tmp; + } +} + +uint8_t RC4::encyptByte(uint8_t in) +{ + ++i; + j += s[i]; + uint8_t tmp = s[i]; + s[i] = s[j]; + s[j] = tmp; + uint8_t c = s[(s[i]+s[j])%256]; + return in^c; +} + +void RC4::encrypt(uint8_t *out, uint8_t *in, uint32_t length) +{ + for(uint32_t l = 0; l < length; ++l) + out[l] = encyptByte(in[l]); +} + +void RC4::decrypt(uint8_t *out, uint8_t *in, uint32_t length) +{ + encrypt(out, in, length); +} + +uint32_t RC4::getBlockSize() const +{ + return 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RC4.h Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,25 @@ +#ifndef RC4_H +#define RC4_H + +#include "Cipher.h" + +class RC4 : public Cipher +{ + public : + + RC4(uint8_t *key, uint8_t keyLength); + + virtual void encrypt(uint8_t *out, uint8_t *in, uint32_t length); + virtual void decrypt(uint8_t *out, uint8_t *in, uint32_t length); + virtual uint32_t getBlockSize() const; + + private : + + uint8_t encyptByte(uint8_t in); + + uint8_t s[256]; + uint8_t i,j; + +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SHA1.cpp Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,235 @@ +#include "SHA1.h" +#include <string.h> + +static uint32_t f(uint8_t t, uint32_t B, uint32_t C, uint32_t D) +{ + if(t <= 19) + return (B & C) | ((~B) & D); + else if(t <= 39) + return B ^ C ^ D; + else if(t <= 59) + return (B & C) | (B & D) | (C & D); + else if(t <= 79) + return B ^ C ^ D; + + return 0; +} + +static uint32_t K(uint8_t t) +{ + if(t <= 19) + return 0x5A827999; + else if(t <= 39) + return 0x6ED9EBA1; + else if(t <= 59) + return 0x8F1BBCDC; + else if(t <= 79) + return 0xCA62C1D6; + + return 0; +} + +static uint32_t rotLeft(uint32_t w, uint8_t n) +{ + return (w << n) | (w >> (32-n)); +} + +static const uint32_t H0 = 0x67452301; +static const uint32_t H1 = 0xEFCDAB89; +static const uint32_t H2 = 0x98BADCFE; +static const uint32_t H3 = 0x10325476; +static const uint32_t H4 = 0xC3D2E1F0; +static const uint32_t MASK = 0x0000000F; + + +SHA1::SHA1(): +HashAlgorithm(), +h0(H0), +h1(H1), +h2(H2), +h3(H3), +h4(H4), +totalBufferLength(0), +buffer(), +bufferLength(0) +{ +} + +uint8_t SHA1::outputSize() const +{ + return 20; +} + +void SHA1::add(uint8_t *in, uint32_t length) +{ + if(length < 64-bufferLength) + { + memcpy(&buffer[bufferLength], in, length); + bufferLength += length; + totalBufferLength += length; + return; + } + int offset = 64-bufferLength; + memcpy(&buffer[bufferLength], in, offset); + computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); + while(length-offset > 64) + { + memcpy(buffer, &in[offset], 64); + computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); + offset += 64; + } + if(offset > length) + offset -= 64; + bufferLength = length - offset; + memcpy(buffer, &in[offset], bufferLength); + totalBufferLength += length; +} + +void SHA1::computeDigest(uint8_t *digest) +{ + uint16_t padding; + if(totalBufferLength % 64 < 56) + padding = 56 - (totalBufferLength % 64); + else + padding = 56 + (64 - (totalBufferLength % 64)); + uint8_t val = 0x80; + add(&val, 1); + val = 0; + for(int i = 0; i < padding-1; ++i) + add(&val,1); + totalBufferLength -= padding; + uint64_t lengthBit = totalBufferLength * 8; + uint32_t lengthBitLow = lengthBit; + uint32_t lengthBitHigh = lengthBit >> 32; + uint8_t l[4]; + + l[0] = lengthBitHigh >> 24; + l[1] = lengthBitHigh >> 16; + l[2] = lengthBitHigh >> 8; + l[3] = lengthBitHigh; + add(l, 4); + l[0] = lengthBitLow >> 24; + l[1] = lengthBitLow >> 16; + l[2] = lengthBitLow >> 8; + l[3] = lengthBitLow; + add(l, 4); + + digest[0] = h0 >> 24; + digest[1] = h0 >> 16; + digest[2] = h0 >> 8; + digest[3] = h0; + digest[4] = h1 >> 24; + digest[5] = h1 >> 16; + digest[6] = h1 >> 8; + digest[7] = h1; + digest[8] = h2 >> 24; + digest[9] = h2 >> 16; + digest[10] = h2 >> 8; + digest[11] = h2; + digest[12] = h3 >> 24; + digest[13] = h3 >> 16; + digest[14] = h3 >> 8; + digest[15] = h3; + digest[16] = h4 >> 24; + digest[17] = h4 >> 16; + digest[18] = h4 >> 8; + digest[19] = h4; + + // reset state + h0 = H0; + h1 = H1; + h2 = H2; + h3 = H3; + h4 = H4; + totalBufferLength = 0; + bufferLength = 0; +} + +void SHA1::computeBlock(uint32_t *h02, uint32_t *h12, uint32_t *h22, uint32_t *h32, uint32_t *h42, uint8_t *buffer) +{ + uint32_t w[16]; + for(int j = 0; j < 16; ++j) + w[j] = (buffer[j*4] << 24) | (buffer[j*4+1] << 16) | (buffer[j*4+2] << 8) | buffer[j*4+3]; + + uint32_t a = *h02, b = *h12, c = *h22, d = *h32, e = *h42; + for(uint8_t t = 0; t < 80; ++t) + { + uint32_t s = t & MASK; + if(t >= 16) + { + w[s%16] = w[((s + 13) & MASK)%16] ^ w[((s + 8) & MASK)%16] ^ w[((s + 2) & MASK)%16] ^ w[s%16]; + w[s%16] = rotLeft(w[s%16], 1); + } + + uint32_t temp = rotLeft(a, 5) + f(t, b, c, d) + e + w[s%16] + K(t); + e = d; + d = c; + c = rotLeft(b,30); + b = a; + a = temp; + } + *h02 += a; + *h12 += b; + *h22 += c; + *h32 += d; + *h42 += e; +} + + + +/* method 2 */ +void SHA1::computeDigest(uint8_t *digest, uint8_t *in, uint32_t length) +{ + uint16_t padding; + if(length % 64 < 56) + padding = 56 - (length % 64); + else + padding = 56 + (64 - (length % 64)); + uint32_t totalLength = length + padding + 8; + uint8_t *buffer = new uint8_t[totalLength]; + memcpy(buffer, in, length); + buffer[length] = 0x80; + memset(&buffer[length+1], 0, padding-1); + uint64_t lengthBit = length * 8; + uint32_t lengthBitLow = lengthBit; + uint32_t lengthBitHigh = lengthBit >> 32; + uint8_t l[4]; + l[0] = lengthBitLow >> 24; + l[1] = lengthBitLow >> 16; + l[2] = lengthBitLow >> 8; + l[3] = lengthBitLow; + memcpy(&buffer[length+padding+4], l, 4); + l[0] = lengthBitHigh >> 24; + l[1] = lengthBitHigh >> 16; + l[2] = lengthBitHigh >> 8; + l[3] = lengthBitHigh; + memcpy(&buffer[length+padding], l, 4); + + uint32_t h0 = H0, h1 = H1, h2 = H2, h3 = H3, h4 = H4; + for(int i = 0; i < totalLength/64; ++i) + computeBlock(&h0,&h1,&h2,&h3,&h4, &buffer[64*i]); + + delete[] buffer; + + digest[0] = h0 >> 24; + digest[1] = h0 >> 16; + digest[2] = h0 >> 8; + digest[3] = h0; + digest[4] = h1 >> 24; + digest[5] = h1 >> 16; + digest[6] = h1 >> 8; + digest[7] = h1; + digest[8] = h2 >> 24; + digest[9] = h2 >> 16; + digest[10] = h2 >> 8; + digest[11] = h2; + digest[12] = h3 >> 24; + digest[13] = h3 >> 16; + digest[14] = h3 >> 8; + digest[15] = h3; + digest[16] = h4 >> 24; + digest[17] = h4 >> 16; + digest[18] = h4 >> 8; + digest[19] = h4; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SHA1.h Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,28 @@ +#ifndef SHA1_H +#define SHA1_H + +#include "HashAlgorithm.h" + + +class SHA1 : public HashAlgorithm +{ + public : + + SHA1(); + + virtual void add(uint8_t *in, uint32_t length); + virtual void computeDigest(uint8_t *out); + virtual uint8_t outputSize() const; + + static void computeDigest(uint8_t *digest, uint8_t *in, uint32_t length); + + private : + static void computeBlock(uint32_t *h02, uint32_t *h12, uint32_t *h22, uint32_t *h32, uint32_t *h42, uint8_t *buffer); + + uint32_t h0, h1, h2, h3, h4; + uint32_t totalBufferLength; + uint8_t buffer[64]; + uint8_t bufferLength; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SHA2.h Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,9 @@ +#ifndef SHA2_H +#define SHA2_H + +#include "SHA224.h" +#include "SHA256.h" +#include "SHA384.h" +#include "SHA512.h" + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SHA224.cpp Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,28 @@ +#include "SHA224.h" + + +SHA224::SHA224(): +HashAlgorithm(), +algo(SHA_224) +{ +} + +void SHA224::add(uint8_t *in, uint32_t length) +{ + algo.add(in, length); +} + +void SHA224::computeDigest(uint8_t *out) +{ + algo.computeDigest(out); +} + +uint8_t SHA224::outputSize() const +{ + return 28; +} + +void SHA224::computeDigest(uint8_t *digest, uint8_t *in, uint32_t length) +{ + SHA2_32::computeDigest(SHA_224, digest, in, length); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SHA224.h Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,23 @@ +#ifndef SHA2_224_H +#define SHA2_224_H + +#include "HashAlgorithm.h" +#include "SHA2_32.h" + +class SHA224 : public HashAlgorithm +{ + public : + + SHA224(); + virtual void add(uint8_t *in, uint32_t length); + virtual void computeDigest(uint8_t *out); + virtual uint8_t outputSize() const; + + static void computeDigest(uint8_t *digest, uint8_t *in, uint32_t length); + + private : + + SHA2_32 algo; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SHA256.cpp Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,28 @@ +#include "SHA256.h" + + +SHA256::SHA256(): +HashAlgorithm(), +algo(SHA_256) +{ +} + +void SHA256::add(uint8_t *in, uint32_t length) +{ + algo.add(in, length); +} + +void SHA256::computeDigest(uint8_t *out) +{ + algo.computeDigest(out); +} + +uint8_t SHA256::outputSize() const +{ + return 32; +} + +void SHA256::computeDigest(uint8_t *digest, uint8_t *in, uint32_t length) +{ + SHA2_32::computeDigest(SHA_256, digest, in, length); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SHA256.h Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,24 @@ +#ifndef SHA2_256_H +#define SHA2_256_H + +#include "HashAlgorithm.h" +#include "SHA2_32.h" + + +class SHA256 : public HashAlgorithm +{ + public : + + SHA256(); + virtual void add(uint8_t *in, uint32_t length); + virtual void computeDigest(uint8_t *out); + virtual uint8_t outputSize() const; + + static void computeDigest(uint8_t *digest, uint8_t *in, uint32_t length); + + private : + + SHA2_32 algo; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SHA2_32.cpp Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,353 @@ +#include "SHA2_32.h" +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +static const uint32_t K[] = +{ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +static uint32_t rotLeft(uint32_t w, uint8_t n) +{ + return (w << n) | (w >> (32-n)); +} + +static uint32_t rotRight(uint32_t w, uint8_t n) +{ + return rotLeft(w,32-n); +} + +static uint32_t CH(uint32_t x, uint32_t y, uint32_t z) +{ + return (x & y) ^ ((~x) & z); +} + +static uint32_t MAJ(uint32_t x, uint32_t y, uint32_t z) +{ + return (x & y) ^ (x & z) ^ (y & z); +} + +static uint32_t BSIG0(uint32_t x) +{ + return rotRight(x,2) ^ rotRight(x,13) ^ rotRight(x,22); +} + +static uint32_t BSIG1(uint32_t x) +{ + return rotRight(x,6) ^ rotRight(x,11) ^ rotRight(x,25); +} + +static uint32_t SSIG0(uint32_t x) +{ + return rotRight(x,7) ^ rotRight(x,18) ^ (x >> 3); +} + +static uint32_t SSIG1(uint32_t x) +{ + return rotRight(x,17) ^ rotRight(x,19) ^ (x >> 10); +} + + +static const uint32_t H[] = +{ + // SHA-224 + 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, + 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4, + + // SHA-256 + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 +}; + +SHA2_32::SHA2_32(SHA_32_TYPE t): +type(t), +totalBufferLength(0), +bufferLength(0) +{ + switch(type) + { + case SHA_224: + h0 = H[0]; + h1 = H[1]; + h2 = H[2]; + h3 = H[3]; + h4 = H[4]; + h5 = H[5]; + h6 = H[6]; + h7 = H[7]; + break; + + case SHA_256: + h0 = H[8]; + h1 = H[9]; + h2 = H[10]; + h3 = H[11]; + h4 = H[12]; + h5 = H[13]; + h6 = H[14]; + h7 = H[15]; + break; + } +} + +void SHA2_32::add(uint8_t *in, uint32_t length) +{ + if(length < 64-bufferLength) + { + memcpy(&buffer[bufferLength], in, length); + bufferLength += length; + totalBufferLength += length; + return; + } + int offset = 64-bufferLength; + memcpy(&buffer[bufferLength], in, offset); + computeBlock(&h0,&h1,&h2,&h3,&h4,&h5,&h6,&h7,buffer); + while(length-offset > 64) + { + memcpy(buffer, &in[offset], 64); + computeBlock(&h0,&h1,&h2,&h3,&h4,&h5,&h6,&h7,buffer); + offset += 64; + } + if(offset > length) + offset -= 64; + bufferLength = length - offset; + memcpy(buffer, &in[offset], bufferLength); + totalBufferLength += length; +} + +void SHA2_32::computeDigest(uint8_t *digest) +{ + uint16_t padding; + if(totalBufferLength % 64 < 56) + padding = 56 - (totalBufferLength % 64); + else + padding = 56 + (64 - (totalBufferLength % 64)); + uint8_t val = 0x80; + add(&val, 1); + val = 0; + for(int i = 0; i < padding-1; ++i) + add(&val,1); + totalBufferLength -= padding; + uint64_t lengthBit = totalBufferLength * 8; + uint32_t lengthBitLow = lengthBit; + uint32_t lengthBitHigh = lengthBit >> 32; + uint8_t tmp[4]; + tmp[0] = lengthBitHigh >> 24; + tmp[1] = lengthBitHigh >> 16; + tmp[2] = lengthBitHigh >> 8; + tmp[3] = lengthBitHigh; + add(tmp, 4); + tmp[0] = lengthBitLow >> 24; + tmp[1] = lengthBitLow >> 16; + tmp[2] = lengthBitLow >> 8; + tmp[3] = lengthBitLow; + add(tmp, 4); + + digest[0] = h0 >> 24; + digest[1] = h0 >> 16; + digest[2] = h0 >> 8; + digest[3] = h0; + digest[4] = h1 >> 24; + digest[5] = h1 >> 16; + digest[6] = h1 >> 8; + digest[7] = h1; + digest[8] = h2 >> 24; + digest[9] = h2 >> 16; + digest[10] = h2 >> 8; + digest[11] = h2; + digest[12] = h3 >> 24; + digest[13] = h3 >> 16; + digest[14] = h3 >> 8; + digest[15] = h3; + digest[16] = h4 >> 24; + digest[17] = h4 >> 16; + digest[18] = h4 >> 8; + digest[19] = h4; + digest[20] = h5 >> 24; + digest[21] = h5 >> 16; + digest[22] = h5 >> 8; + digest[23] = h5; + digest[24] = h6 >> 24; + digest[25] = h6 >> 16; + digest[26] = h6 >> 8; + digest[27] = h6; + + if(type == SHA_256) + { + digest[28] = h7 >> 24; + digest[29] = h7 >> 16; + digest[30] = h7 >> 8; + digest[31] = h7; + } + + // reset state + switch(type) + { + case SHA_224: + h0 = H[0]; + h1 = H[1]; + h2 = H[2]; + h3 = H[3]; + h4 = H[4]; + h5 = H[5]; + h6 = H[6]; + h7 = H[7]; + break; + + case SHA_256: + h0 = H[8]; + h1 = H[9]; + h2 = H[10]; + h3 = H[11]; + h4 = H[12]; + h5 = H[13]; + h6 = H[14]; + h7 = H[15]; + break; + } + totalBufferLength = 0; + bufferLength = 0; +} + +void SHA2_32::computeBlock(uint32_t *h02, + uint32_t *h12, + uint32_t *h22, + uint32_t *h32, + uint32_t *h42, + uint32_t *h52, + uint32_t *h62, + uint32_t *h72, + uint8_t *buffer) +{ + uint32_t w[64]; + for(int t = 0; t < 16; ++t) + w[t] = (buffer[t*4] << 24) | (buffer[t*4+1] << 16) | (buffer[t*4+2] << 8) | buffer[t*4+3]; + for(int t = 16; t < 64; ++t) + w[t] = SSIG1(w[t-2]) + w[t-7] + SSIG0(w[t-15]) + w[t-16]; + + uint32_t a = *h02, b = *h12, c = *h22, d = *h32, e = *h42, f = *h52, g = *h62, h = *h72; + for(int t = 0; t < 64; ++t) + { + uint32_t T1 = h + BSIG1(e) + CH(e,f,g) + K[t] + w[t]; + uint32_t T2 = BSIG0(a) + MAJ(a,b,c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } + + *h02 += a; + *h12 += b; + *h22 += c; + *h32 += d; + *h42 += e; + *h52 += f; + *h62 += g; + *h72 += h; +} + +void SHA2_32::computeDigest(SHA_32_TYPE type, uint8_t *digest, uint8_t *in, uint32_t length) +{ + uint32_t h0 = H[type*8], h1 = H[type*8+1], h2 = H[type*8+2], h3 = H[type*8+3]; + uint32_t h4 = H[type*8+4], h5 = H[type*8+5], h6 = H[type*8+6], h7 = H[type*8+7]; + int offset = 0; + while(length - offset >= 64) + { + computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, &in[offset]); + offset += 64; + } + uint8_t bufferLength = length-offset; + uint8_t buffer[64]; + memcpy(buffer, &in[offset],bufferLength); + uint16_t padding; + if(length % 64 < 56) + padding = 56 - (length % 64); + else + padding = 56 + (64 - (length % 64)); + buffer[bufferLength] = 0x80; + bufferLength++; + padding--; + while(padding > 0) + { + if(bufferLength == 64) + { + computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, buffer); + bufferLength = 0; + } + buffer[bufferLength] = 0; + bufferLength++; + padding--; + } + uint64_t lengthBit = length * 8; + uint32_t lengthBitLow = lengthBit; + uint32_t lengthBitHigh = lengthBit >> 32; + uint8_t tmp[4]; + tmp[0] = lengthBitLow >> 24; + tmp[1] = lengthBitLow >> 16; + tmp[2] = lengthBitLow >> 8; + tmp[3] = lengthBitLow; + memcpy(&buffer[60], tmp, 4); + tmp[0] = lengthBitHigh >> 24; + tmp[1] = lengthBitHigh >> 16; + tmp[2] = lengthBitHigh >> 8; + tmp[3] = lengthBitHigh; + memcpy(&buffer[56], tmp, 4); + computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, buffer); + + digest[0] = h0 >> 24; + digest[1] = h0 >> 16; + digest[2] = h0 >> 8; + digest[3] = h0; + digest[4] = h1 >> 24; + digest[5] = h1 >> 16; + digest[6] = h1 >> 8; + digest[7] = h1; + digest[8] = h2 >> 24; + digest[9] = h2 >> 16; + digest[10] = h2 >> 8; + digest[11] = h2; + digest[12] = h3 >> 24; + digest[13] = h3 >> 16; + digest[14] = h3 >> 8; + digest[15] = h3; + digest[16] = h4 >> 24; + digest[17] = h4 >> 16; + digest[18] = h4 >> 8; + digest[19] = h4; + digest[20] = h5 >> 24; + digest[21] = h5 >> 16; + digest[22] = h5 >> 8; + digest[23] = h5; + digest[24] = h6 >> 24; + digest[25] = h6 >> 16; + digest[26] = h6 >> 8; + digest[27] = h6; + + if(type == SHA_256) + { + digest[28] = h7 >> 24; + digest[29] = h7 >> 16; + digest[30] = h7 >> 8; + digest[31] = h7; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SHA2_32.h Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,40 @@ +#ifndef SHA2_32_H +#define SHA2_32_H + +#include <stdint.h> + +enum SHA_32_TYPE +{ + SHA_224, + SHA_256 +}; + +class SHA2_32 +{ + public : + + SHA2_32(SHA_32_TYPE type); + void add(uint8_t *in, uint32_t length); + void computeDigest(uint8_t *digest); + static void computeDigest(SHA_32_TYPE type, uint8_t *digest, uint8_t *in, uint32_t length); + + private : + + static void computeBlock(uint32_t *h02, + uint32_t *h12, + uint32_t *h22, + uint32_t *h32, + uint32_t *h42, + uint32_t *h52, + uint32_t *h62, + uint32_t *h72, + uint8_t *buffer); + + SHA_32_TYPE type; + uint32_t h0, h1, h2, h3, h4, h5, h6, h7; + uint32_t totalBufferLength; + uint8_t buffer[64]; + uint8_t bufferLength; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SHA2_64.cpp Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,342 @@ +#include "SHA2_64.h" +#include <string.h> + + +static const uint64_t K[] = +{ + 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, + 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, + 0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, + 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694, + 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, + 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, + 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, + 0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70, + 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df, + 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b, + 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, + 0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, + 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, + 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, + 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, + 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, + 0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, + 0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b, + 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c, + 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817 +}; + +static const uint64_t H[] = +{ + // SHA-384 + 0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939, + 0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4, + + // SHA-512 + 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179 +}; + +static uint64_t revWord(uint64_t w) +{ + uint8_t buffer[8]; + buffer[0] = w >> 56; + buffer[1] = w >> 48; + buffer[2] = w >> 40; + buffer[3] = w >> 32; + buffer[4] = w >> 24; + buffer[5] = w >> 16; + buffer[6] = w >> 8; + buffer[7] = w; + + uint64_t res = buffer[7]; + res <<= 8; + res |= buffer[6]; + res <<= 8; + res |= buffer[5]; + res <<= 8; + res |= buffer[4]; + res <<= 8; + res |= buffer[3]; + res <<= 8; + res |= buffer[2]; + res <<= 8; + res |= buffer[1]; + res <<= 8; + res |= buffer[0]; + + return res; +} + +static uint64_t rotLeft(uint64_t w, uint8_t n) +{ + return (w << n) | (w >> (64-n)); +} + +static uint64_t rotRight(uint64_t w, uint8_t n) +{ + return rotLeft(w,64-n); +} + +static uint64_t CH(uint64_t x, uint64_t y, uint64_t z) +{ + return (x & y) ^ ((~x) & z); +} + +static uint64_t MAJ(uint64_t x, uint64_t y, uint64_t z) +{ + return (x & y) ^ (x & z) ^ (y & z); +} + +static uint64_t BSIG0(uint64_t x) +{ + return rotRight(x,28) ^ rotRight(x,34) ^ rotRight(x,39); +} + +static uint64_t BSIG1(uint64_t x) +{ + return rotRight(x,14) ^ rotRight(x,18) ^ rotRight(x,41); +} + +static uint64_t SSIG0(uint64_t x) +{ + return rotRight(x,1) ^ rotRight(x,8) ^ (x >> 7); +} + +static uint64_t SSIG1(uint64_t x) +{ + return rotRight(x,19) ^ rotRight(x,61) ^ (x>>6); +} + +SHA2_64::SHA2_64(SHA2_64_TYPE t): +type(t), +totalBufferLength(0), +bufferLength(0) +{ + switch(type) + { + case SHA_384: + h0 = H[0]; + h1 = H[1]; + h2 = H[2]; + h3 = H[3]; + h4 = H[4]; + h5 = H[5]; + h6 = H[6]; + h7 = H[7]; + break; + + case SHA_512: + h0 = H[8]; + h1 = H[9]; + h2 = H[10]; + h3 = H[11]; + h4 = H[12]; + h5 = H[13]; + h6 = H[14]; + h7 = H[15]; + break; + } +} + +void SHA2_64::add(uint8_t *in, uint32_t length) +{ + if(length < 128-bufferLength) + { + memcpy(&buffer[bufferLength], in, length); + bufferLength += length; + totalBufferLength += length; + return; + } + int offset = 128-bufferLength; + memcpy(&buffer[bufferLength], in, offset); + computeBlock(&h0,&h1,&h2,&h3,&h4,&h5,&h6,&h7,buffer); + while(length-offset > 128) + { + memcpy(buffer, &in[offset], 128); + computeBlock(&h0,&h1,&h2,&h3,&h4,&h5,&h6,&h7,buffer); + offset += 128; + } + if(offset > length) + offset -= 128; + bufferLength = length - offset; + memcpy(buffer, &in[offset], bufferLength); + totalBufferLength += length; +} + +void SHA2_64::computeDigest(uint8_t *digest) +{ + uint16_t padding; + if(totalBufferLength % 128 < 112) + padding = 112 - (totalBufferLength % 128); + else + padding = 112 + (128 - (totalBufferLength % 128)); + uint8_t val = 0x80; + add(&val, 1); + val = 0; + for(int i = 0; i < padding-1; ++i) + add(&val,1); + totalBufferLength -= padding; + uint64_t lengthBit = 0; + add((uint8_t*)&lengthBit, 8); + lengthBit = (totalBufferLength - 8) * 8; + lengthBit = revWord(lengthBit); + add((uint8_t*)&lengthBit, 8); + + h0 = revWord(h0); + h1 = revWord(h1); + h2 = revWord(h2); + h3 = revWord(h3); + h4 = revWord(h4); + h5 = revWord(h5); + + + memcpy(digest, &h0, 8); + memcpy(&digest[8], &h1, 8); + memcpy(&digest[16], &h2, 8); + memcpy(&digest[24], &h3, 8); + memcpy(&digest[32], &h4, 8); + memcpy(&digest[40], &h5, 8); + + if(type == SHA_512) + { + h6 = revWord(h6); + h7 = revWord(h7); + memcpy(&digest[48], &h6, 8); + memcpy(&digest[56], &h7, 8); + } + + // reset state + switch(type) + { + case SHA_384: + h0 = H[0]; + h1 = H[1]; + h2 = H[2]; + h3 = H[3]; + h4 = H[4]; + h5 = H[5]; + h6 = H[6]; + h7 = H[7]; + break; + + case SHA_512: + h0 = H[8]; + h1 = H[9]; + h2 = H[10]; + h3 = H[11]; + h4 = H[12]; + h5 = H[13]; + h6 = H[14]; + h7 = H[15]; + break; + } + totalBufferLength = 0; + bufferLength = 0; +} + +void SHA2_64::computeBlock(uint64_t *h02, + uint64_t *h12, + uint64_t *h22, + uint64_t *h32, + uint64_t *h42, + uint64_t *h52, + uint64_t *h62, + uint64_t *h72, + uint8_t *buffer) +{ + uint64_t w[80]; + for(int t = 0; t < 16; ++t) + { + memcpy(&w[t], &buffer[t*8], 8); + w[t] = revWord(w[t]); + } + for(int t = 16; t < 80; ++t) + w[t] = SSIG1(w[t-2]) + w[t-7] + SSIG0(w[t-15]) + w[t-16]; + + uint64_t a = *h02, b = *h12, c = *h22, d = *h32, e = *h42, f = *h52, g = *h62, h = *h72; + for(int t = 0; t < 80; ++t) + { + uint64_t T1 = h + BSIG1(e) + CH(e,f,g) + K[t] + w[t]; + uint64_t T2 = BSIG0(a) + MAJ(a,b,c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } + *h02 += a; + *h12 += b; + *h22 += c; + *h32 += d; + *h42 += e; + *h52 += f; + *h62 += g; + *h72 += h; +} + +void SHA2_64::computeDigest(SHA2_64_TYPE type, uint8_t *digest, uint8_t *in, uint32_t length) +{ + uint64_t h0 = H[type*8], h1 = H[type*8+1], h2 = H[type*8+2], h3 = H[type*8+3]; + uint64_t h4 = H[type*8+4], h5 = H[type*8+5], h6 = H[type*8+6], h7 = H[type*8+7]; + int offset = 0; + while(length - offset >= 128) + { + computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, &in[offset]); + offset += 128; + } + uint8_t bufferLength = length-offset; + uint8_t buffer[128]; + memcpy(buffer, &in[offset],bufferLength); + uint16_t padding; + if(length % 128 < 112) + padding = 112 - (length % 128); + else + padding = 112 + (128 - (length % 128)); + buffer[bufferLength] = 0x80; + bufferLength++; + padding--; + while(padding > 0) + { + if(bufferLength == 128) + { + computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, buffer); + bufferLength = 0; + } + buffer[bufferLength] = 0; + bufferLength++; + padding--; + } + uint64_t lengthBit = length * 8; + lengthBit = revWord(lengthBit); + memset(&buffer[112], 0, 8); + memcpy(&buffer[120], &lengthBit, 8); + computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, buffer); + + h0 = revWord(h0); + h1 = revWord(h1); + h2 = revWord(h2); + h3 = revWord(h3); + h4 = revWord(h4); + h5 = revWord(h5); + + + memcpy(digest, &h0, 8); + memcpy(&digest[8], &h1, 8); + memcpy(&digest[16], &h2, 8); + memcpy(&digest[24], &h3, 8); + memcpy(&digest[32], &h4, 8); + memcpy(&digest[40], &h5, 8); + + if(type == SHA_512) + { + h6 = revWord(h6); + h7 = revWord(h7); + memcpy(&digest[48], &h6, 8); + memcpy(&digest[56], &h7, 8); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SHA2_64.h Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,40 @@ +#ifndef SHA2_64_H +#define SHA2_64_H + +#include <stdint.h> + +enum SHA2_64_TYPE +{ + SHA_384, + SHA_512 +}; + +class SHA2_64 +{ + public : + + SHA2_64(SHA2_64_TYPE type); + void add(uint8_t *in, uint32_t length); + void computeDigest(uint8_t *digest); + static void computeDigest(SHA2_64_TYPE type, uint8_t *digest, uint8_t *in, uint32_t length); + + private : + + static void computeBlock(uint64_t *h02, + uint64_t *h12, + uint64_t *h22, + uint64_t *h32, + uint64_t *h42, + uint64_t *h52, + uint64_t *h62, + uint64_t *h72, + uint8_t *buffer); + + SHA2_64_TYPE type; + uint64_t h0, h1, h2, h3, h4, h5, h6, h7; + uint32_t totalBufferLength; + uint8_t buffer[128]; + uint8_t bufferLength; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SHA384.cpp Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,28 @@ +#include "SHA384.h" + + +SHA384::SHA384(): +HashAlgorithm(), +algo(SHA_384) +{ +} + +void SHA384::add(uint8_t *in, uint32_t length) +{ + algo.add(in, length); +} + +void SHA384::computeDigest(uint8_t *out) +{ + algo.computeDigest(out); +} + +uint8_t SHA384::outputSize() const +{ + return 48; +} + +void SHA384::computeDigest(uint8_t *digest, uint8_t *in, uint32_t length) +{ + SHA2_64::computeDigest(SHA_384, digest, in, length); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SHA384.h Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,24 @@ +#ifndef SHA2_384_H +#define SHA2_384_H + +#include "HashAlgorithm.h" +#include "SHA2_64.h" + + +class SHA384 : public HashAlgorithm +{ + public : + + SHA384(); + virtual void add(uint8_t *in, uint32_t length); + virtual void computeDigest(uint8_t *out); + virtual uint8_t outputSize() const; + + static void computeDigest(uint8_t *digest, uint8_t *in, uint32_t length); + + private : + + SHA2_64 algo; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SHA512.cpp Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,28 @@ +#include "SHA512.h" + + +SHA512::SHA512(): +HashAlgorithm(), +algo(SHA_512) +{ +} + +void SHA512::add(uint8_t *in, uint32_t length) +{ + algo.add(in, length); +} + +void SHA512::computeDigest(uint8_t *out) +{ + algo.computeDigest(out); +} + +uint8_t SHA512::outputSize() const +{ + return 64; +} + +void SHA512::computeDigest(uint8_t *digest, uint8_t *in, uint32_t length) +{ + SHA2_64::computeDigest(SHA_512, digest, in, length); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SHA512.h Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,24 @@ +#ifndef SHA2_512_H +#define SHA2_512_H + +#include "HashAlgorithm.h" +#include "SHA2_64.h" + + +class SHA512 : public HashAlgorithm +{ + public : + + SHA512(); + virtual void add(uint8_t *in, uint32_t length); + virtual void computeDigest(uint8_t *out); + virtual uint8_t outputSize() const; + + static void computeDigest(uint8_t *digest, uint8_t *in, uint32_t length); + + private : + + SHA2_64 algo; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/9c8f0e3462fb \ No newline at end of file