remove HAVAL, MD5-MAC, XMAC

pull/2/head
weidai 2007-04-15 23:01:58 +00:00
parent 643b302227
commit 0014078939
5 changed files with 0 additions and 722 deletions

276
haval.cpp
View File

@ -1,276 +0,0 @@
// haval.cpp - written and placed in the public domain by Wei Dai
#include "pch.h"
#include "haval.h"
#include "misc.h"
NAMESPACE_BEGIN(CryptoPP)
HAVAL::HAVAL(unsigned int digestSize, unsigned int pass)
: digestSize(digestSize), pass(pass)
{
SetStateSize(DIGESTSIZE);
if (!(digestSize >= 16 && digestSize <= 32 && digestSize%4==0))
throw InvalidArgument("HAVAL: invalid digest size");
if (!(pass >= 3 && pass <= 5))
throw InvalidArgument("HAVAL: invalid number of passes");
Init();
}
void HAVAL::Init()
{
m_digest[0] = 0x243F6A88;
m_digest[1] = 0x85A308D3;
m_digest[2] = 0x13198A2E;
m_digest[3] = 0x03707344;
m_digest[4] = 0xA4093822;
m_digest[5] = 0x299F31D0;
m_digest[6] = 0x082EFA98;
m_digest[7] = 0xEC4E6C89;
}
void HAVAL::HashEndianCorrectedBlock(const word32 *in)
{
if (pass==3)
HAVAL3::Transform(m_digest, in);
else if (pass==4)
HAVAL4::Transform(m_digest, in);
else
HAVAL5::Transform(m_digest, in);
}
void HAVAL::TruncatedFinal(byte *hash, size_t size)
{
ThrowIfInvalidTruncatedSize(size);
PadLastBlock(118, 1); // first byte of padding for HAVAL is 1 instead of 0x80
CorrectEndianess(m_data, m_data, 120);
m_data[29] &= 0xffff;
m_data[29] |= ((word32)digestSize<<25) | ((word32)pass<<19) | ((word32)HAVAL_VERSION<<16);
m_data[30] = GetBitCountLo();
m_data[31] = GetBitCountHi();
HashEndianCorrectedBlock(m_data);
Tailor(digestSize*8);
CorrectEndianess(m_digest, m_digest, digestSize);
memcpy(hash, m_digest, size);
Restart(); // reinit for next use
}
#define ROTR(x, y) rotrFixed(x, y##u)
// fold digest down to desired size
void HAVAL::Tailor(unsigned int bitlen)
{
#define EB(a, b, c) (m_digest[a] & (((~(word32)0) << b) & ((~(word32)0) >> (8*sizeof(word32)-b-c))))
#define S(a, b) (a > b ? a - b : 32 + a - b)
#define T128(a, b, c, d, e) ROTR(EB(7, b, S(a,b)) | EB(6, c, S(b,c)) | EB(5, d, S(c,d)) | EB(4, e, S(d,e)), e)
#define T160(a, b, c, d) ROTR(EB(7, b, S(a,b)) | EB(6, c, S(b,c)) | EB(5, d, S(c,d)), d)
#define T192(a, b, c) ROTR(EB(7, b, S(a,b)) | EB(6, c, S(b,c)), c)
#define T224(a, b) ROTR(EB(7, b, S(a,b)), b)
switch (bitlen)
{
case 128:
m_digest[0] += T128(8, 0, 24, 16, 8);
m_digest[1] += T128(16, 8, 0, 24, 16);
m_digest[2] += T128(24, 16, 8, 0, 24);
m_digest[3] += T128(0, 24, 16, 8, 0);
break;
case 160:
m_digest[0] += T160(6, 0, 25, 19);
m_digest[1] += T160(12, 6, 0, 25);
m_digest[2] += T160(19, 12, 6, 0);
m_digest[3] += T160(25, 19, 12, 6);
m_digest[4] += T160(0, 25, 19, 12);
break;
case 192:
m_digest[0] += T192(5, 0, 26);
m_digest[1] += T192(10, 5, 0);
m_digest[2] += T192(16, 10, 5);
m_digest[3] += T192(21, 16, 10);
m_digest[4] += T192(26, 21, 16);
m_digest[5] += T192(0, 26, 21);
break;
case 224:
m_digest[0] += T224(0, 27);
m_digest[1] += T224(27, 22);
m_digest[2] += T224(22, 18);
m_digest[3] += T224(18, 13);
m_digest[4] += T224(13, 9);
m_digest[5] += T224(9, 4);
m_digest[6] += T224(4, 0);
break;
case 256:
break;
default:
assert(false);
}
}
/* Nonlinear F functions */
/* #define F1(X6, X5, X4, X3, X2, X1, X0) \
((X1) & (X4) ^ (X2) & (X5) ^ (X3) & (X6) ^ (X0) & (X1) ^ (X0))*/
#define F1(X6, X5, X4, X3, X2, X1, X0) \
(((X1) & ((X4) ^ (X0))) ^ ((X2) & (X5)) ^ ((X3) & (X6)) ^ (X0))
/* #define F2(X6, X5, X4, X3, X2, X1, X0) \
((X1) & (X2) & (X3) ^ (X2) & (X4) & (X5) ^ \
(X1) & (X2) ^ (X1) & (X4) ^ (X2) & (X6) ^ (X3) & (X5) ^ \
(X4) & (X5) ^ (X0) & (X2) ^ (X0))*/
#define F2(X6, X5, X4, X3, X2, X1, X0) \
(((X2) & (((X1) & (~(X3))) ^ ((X4) & (X5)) ^ (X6) ^ (X0))) ^ \
(((X4) & ((X1) ^ (X5))) ^ ((X3) & (X5)) ^ (X0)))
/* #define F3(X6, X5, X4, X3, X2, X1, X0) \
((X1) & (X2) & (X3) ^ (X1) & (X4) ^ (X2) & (X5) ^ (X3) & (X6) ^ (X0) &
(X3) ^ (X0))*/
#define F3(X6, X5, X4, X3, X2, X1, X0) \
(((X3) & (((X1) & (X2)) ^ (X6) ^ (X0))) ^ ((X1) & (X4)) ^ \
((X2) & (X5)) ^ (X0))
/* #define F4(X6, X5, X4, X3, X2, X1, X0) \
((X1) & (X2) & (X3) ^ (X2) & (X4) & (X5) ^ (X3) & (X4) & (X6) ^ \
(X1) & (X4) ^ (X2) & (X6) ^ (X3) & (X4) ^ (X3) & (X5) ^ \
(X3) & (X6) ^ (X4) & (X5) ^ (X4) & (X6) ^ (X0) & (X4) ^(X0))*/
#define F4(X6, X5, X4, X3, X2, X1, X0) \
(((X4) & (((~(X2)) & (X5)) ^ ((X3) | (X6)) ^ (X1) ^ (X0))) ^ \
((X3) & (((X1) & (X2)) ^ (X5) ^ (X6))) ^ ((X2) & (X6)) ^ (X0))
/* #define F5(X6, X5, X4, X3, X2, X1, X0) \
((X1) & (X4) ^ (X2) & (X5) ^ (X3) & (X6) ^ \
(X0) & (X1) & (X2) & (X3) ^ (X0) & (X5) ^ (X0))*/
#define F5(X6, X5, X4, X3, X2, X1, X0) \
(((X1) & ((X4) ^ ((X0) & (X2) & (X3)))) ^ \
(((X2) ^ (X0)) & (X5)) ^ ((X3) & (X6)) ^ (X0))
#define p31(x) (x==0 ? 1 : (x==1 ? 0 : (x==2 ? 3 : (x==3 ? 5 : (x==4 ? 6 : (x==5 ? 2 : (x==6 ? 4 : 7)))))))
#define p41(x) (x==0 ? 2 : (x==1 ? 6 : (x==2 ? 1 : (x==3 ? 4 : (x==4 ? 5 : (x==5 ? 3 : (x==6 ? 0 : 7)))))))
#define p51(x) (x==0 ? 3 : (x==1 ? 4 : (x==2 ? 1 : (x==3 ? 0 : (x==4 ? 5 : (x==5 ? 2 : (x==6 ? 6 : 7)))))))
#define p32(x) (x==0 ? 4 : (x==1 ? 2 : (x==2 ? 1 : (x==3 ? 0 : (x==4 ? 5 : (x==5 ? 3 : (x==6 ? 6 : 7)))))))
#define p42(x) (x==0 ? 3 : (x==1 ? 5 : (x==2 ? 2 : (x==3 ? 0 : (x==4 ? 1 : (x==5 ? 6 : (x==6 ? 4 : 7)))))))
#define p52(x) (x==0 ? 6 : (x==1 ? 2 : (x==2 ? 1 : (x==3 ? 0 : (x==4 ? 3 : (x==5 ? 4 : (x==6 ? 5 : 7)))))))
#define p33(x) (x==0 ? 6 : (x==1 ? 1 : (x==2 ? 2 : (x==3 ? 3 : (x==4 ? 4 : (x==5 ? 5 : (x==6 ? 0 : 7)))))))
#define p43(x) (x==0 ? 1 : (x==1 ? 4 : (x==2 ? 3 : (x==3 ? 6 : (x==4 ? 0 : (x==5 ? 2 : (x==6 ? 5 : 7)))))))
#define p53(x) (x==0 ? 2 : (x==1 ? 6 : (x==2 ? 0 : (x==3 ? 4 : (x==4 ? 3 : (x==5 ? 1 : (x==6 ? 5 : 7)))))))
#define p44(x) (x==0 ? 6 : (x==1 ? 4 : (x==2 ? 0 : (x==3 ? 5 : (x==4 ? 2 : (x==5 ? 1 : (x==6 ? 3 : 7)))))))
#define p54(x) (x==0 ? 1 : (x==1 ? 5 : (x==2 ? 3 : (x==3 ? 2 : (x==4 ? 0 : (x==5 ? 4 : (x==6 ? 6 : 7)))))))
#define p55(x) (x==0 ? 2 : (x==1 ? 5 : (x==2 ? 0 : (x==3 ? 6 : (x==4 ? 4 : (x==5 ? 3 : (x==6 ? 1 : 7)))))))
#define t(b,p,x,j) ((b&&((p(x)+8-j)%8<(8-j)))?E:T)[(p(x)+8-j)%8]
#define FF(b, e, F, p, j, w, c) \
T[7-j] = rotrFixed(F(t(b,p,0,j), t(b,p,1,j), t(b,p,2,j), t(b,p,3,j), t(b,p,4,j), t(b,p,5,j), t(b,p,6,j)), 7U) + rotrFixed(t(b,p,7,j), 11U) + w + c; \
if (e) E[7-j] += T[7-j];
#ifdef CRYPTOPP_DOXYGEN_PROCESSING
// Doxygen can't handle these macros
#define Round1(t)
#define Round(t, n)
#else
#define Round1(t) \
for (i=0; i<4; i++) \
{ \
FF(i==0, 0, F1, p##t##1, 0, W[8*i+0], 0); \
FF(i==0, 0, F1, p##t##1, 1, W[8*i+1], 0); \
FF(i==0, 0, F1, p##t##1, 2, W[8*i+2], 0); \
FF(i==0, 0, F1, p##t##1, 3, W[8*i+3], 0); \
FF(i==0, 0, F1, p##t##1, 4, W[8*i+4], 0); \
FF(i==0, 0, F1, p##t##1, 5, W[8*i+5], 0); \
FF(i==0, 0, F1, p##t##1, 6, W[8*i+6], 0); \
FF(i==0, 0, F1, p##t##1, 7, W[8*i+7], 0); \
}
#define Round(t, n) \
for (i=0; i<4; i++) \
{ \
FF(0, t==n && i==3, F##n, p##t##n, 0, W[wi##n[8*i+0]], mc##n[8*i+0]); \
FF(0, t==n && i==3, F##n, p##t##n, 1, W[wi##n[8*i+1]], mc##n[8*i+1]); \
FF(0, t==n && i==3, F##n, p##t##n, 2, W[wi##n[8*i+2]], mc##n[8*i+2]); \
FF(0, t==n && i==3, F##n, p##t##n, 3, W[wi##n[8*i+3]], mc##n[8*i+3]); \
FF(0, t==n && i==3, F##n, p##t##n, 4, W[wi##n[8*i+4]], mc##n[8*i+4]); \
FF(0, t==n && i==3, F##n, p##t##n, 5, W[wi##n[8*i+5]], mc##n[8*i+5]); \
FF(0, t==n && i==3, F##n, p##t##n, 6, W[wi##n[8*i+6]], mc##n[8*i+6]); \
FF(0, t==n && i==3, F##n, p##t##n, 7, W[wi##n[8*i+7]], mc##n[8*i+7]); \
}
#endif
const unsigned int HAVAL::wi2[32] = { 5,14,26,18,11,28, 7,16, 0,23,20,22, 1,10, 4, 8,30, 3,21, 9,17,24,29, 6,19,12,15,13, 2,25,31,27};
const unsigned int HAVAL::wi3[32] = {19, 9, 4,20,28,17, 8,22,29,14,25,12,24,30,16,26,31,15, 7, 3, 1, 0,18,27,13, 6,21,10,23,11, 5, 2};
const unsigned int HAVAL::wi4[32] = {24, 4, 0,14, 2, 7,28,23,26, 6,30,20,18,25,19, 3,22,11,31,21, 8,27,12, 9, 1,29, 5,15,17,10,16,13};
const unsigned int HAVAL::wi5[32] = {27, 3,21,26,17,11,20,29,19, 0,12, 7,13, 8,31,10, 5, 9,14,30,18, 6,28,24, 2,23,16,22, 4, 1,25,15};
const word32 HAVAL::mc2[32] = {
0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917
, 0x9216D5D9, 0x8979FB1B, 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96
, 0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, 0x636920D8, 0x71574E69
, 0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5};
const word32 HAVAL::mc3[32] = {
0x9C30D539,0x2AF26013,0xC5D1B023,0x286085F0,0xCA417918,0xB8DB38EF,0x8E79DCB0,0x603A180E,
0x6C9E0E8B,0xB01E8A3E,0xD71577C1,0xBD314B27,0x78AF2FDA,0x55605C60,0xE65525F3,0xAA55AB94,
0x57489862,0x63E81440,0x55CA396A,0x2AAB10B6,0xB4CC5C34,0x1141E8CE,0xA15486AF,0x7C72E993,
0xB3EE1411,0x636FBC2A,0x2BA9C55D,0x741831F6,0xCE5C3E16,0x9B87931E,0xAFD6BA33,0x6C24CF5C};
const word32 HAVAL::mc4[32] = {
0x7A325381,0x28958677,0x3B8F4898,0x6B4BB9AF,0xC4BFE81B,0x66282193,0x61D809CC,0xFB21A991,
0x487CAC60,0x5DEC8032,0xEF845D5D,0xE98575B1,0xDC262302,0xEB651B88,0x23893E81,0xD396ACC5,
0x0F6D6FF3,0x83F44239,0x2E0B4482,0xA4842004,0x69C8F04A,0x9E1F9B5E,0x21C66842,0xF6E96C9A,
0x670C9C61,0xABD388F0,0x6A51A0D2,0xD8542F68,0x960FA728,0xAB5133A3,0x6EEF0B6C,0x137A3BE4};
const word32 HAVAL::mc5[32] = {
0xBA3BF050,0x7EFB2A98,0xA1F1651D,0x39AF0176,0x66CA593E,0x82430E88,0x8CEE8619,0x456F9FB4,
0x7D84A5C3,0x3B8B5EBE,0xE06F75D8,0x85C12073,0x401A449F,0x56C16AA6,0x4ED3AA62,0x363F7706,
0x1BFEDF72,0x429B023D,0x37D0D724,0xD00A1248,0xDB0FEAD3,0x49F1C09B,0x075372C9,0x80991B7B,
0x25D479D8,0xF6E8DEF7,0xE3FE501A,0xB6794C3B,0x976CE0BD,0x04C006BA,0xC1A94FB6,0x409F60C4};
void HAVAL3::Transform(word32 *E, const word32 *W)
{
word32 T[8];
unsigned int i;
Round1(3);
Round(3, 2);
Round(3, 3);
memset(T, 0, sizeof(T));
}
void HAVAL4::Transform(word32 *E, const word32 *W)
{
word32 T[8];
unsigned int i;
Round1(4);
Round(4, 2);
Round(4, 3);
Round(4, 4);
memset(T, 0, sizeof(T));
}
void HAVAL5::Transform(word32 *E, const word32 *W)
{
word32 T[8];
unsigned int i;
Round1(5);
Round(5, 2);
Round(5, 3);
Round(5, 4);
Round(5, 5);
memset(T, 0, sizeof(T));
}
NAMESPACE_END

63
haval.h
View File

@ -1,63 +0,0 @@
#ifndef CRYPTOPP_HAVAL_H
#define CRYPTOPP_HAVAL_H
#include "iterhash.h"
NAMESPACE_BEGIN(CryptoPP)
/// <a href="http://www.weidai.com/scan-mirror/md.html#HAVAL">HAVAL</a>
/*! \warning HAVAL with 128-bit or 160-bit output is considered insecure, and should not be used
unless you absolutely need it for compatibility. */
class HAVAL : public IteratedHash<word32, LittleEndian, 128>
{
public:
enum {HAVAL_VERSION = 1};
CRYPTOPP_CONSTANT(DIGESTSIZE = 32)
/// digestSize can be 16, 20, 24, 28, or 32 (Default=32)<br>
/// pass can be 3, 4 or 5 (Default=3)
HAVAL(unsigned int digestSize=DIGESTSIZE, unsigned int passes=3);
void TruncatedFinal(byte *hash, size_t size);
unsigned int DigestSize() const {return digestSize;}
static const char * StaticAlgorithmName() {return "HAVAL";}
std::string AlgorithmName() const {return std::string("HAVAL(") + IntToString(digestSize) + "," + IntToString(pass) + ")";}
protected:
static const unsigned int wi2[32], wi3[32], wi4[32], wi5[32];
static const word32 mc2[32], mc3[32], mc4[32], mc5[32];
void Init();
void Tailor(unsigned int FPTLEN);
void HashEndianCorrectedBlock(const word32 *in);
const unsigned int digestSize, pass;
};
/// <a href="http://www.weidai.com/scan-mirror/md.html#HAVAL">HAVAL</a> with 3 passes
class HAVAL3 : public HAVAL
{
public:
HAVAL3(unsigned int digestSize=DIGESTSIZE) : HAVAL(digestSize, 3) {}
static void Transform(word32 *buf, const word32 *in);
};
/// <a href="http://www.weidai.com/scan-mirror/md.html#HAVAL">HAVAL</a> with 4 passes
class HAVAL4 : public HAVAL
{
public:
HAVAL4(unsigned int digestSize=DIGESTSIZE) : HAVAL(digestSize, 4) {}
static void Transform(word32 *buf, const word32 *in);
};
/// <a href="http://www.weidai.com/scan-mirror/md.html#HAVAL">HAVAL</a> with 5 passes
class HAVAL5 : public HAVAL
{
public:
HAVAL5(unsigned int digestSize=DIGESTSIZE) : HAVAL(digestSize, 5) {}
static void Transform(word32 *buf, const word32 *in);
};
NAMESPACE_END
#endif

View File

@ -1,166 +0,0 @@
// md5mac.cpp - modified by Wei Dai from Colin Plumb's public domain md5.c
// any modifications are placed in the public domain
#include "pch.h"
#include "md5mac.h"
#include "misc.h"
NAMESPACE_BEGIN(CryptoPP)
const word32 MD5MAC_Base::T[12] =
{ 0xac45ef97,0xcd430f29,0x551b7e45,0x3411801c,
0x96ce77b1,0x7c8e722e,0x0aab5a5f,0x18be4336,
0x21b4219d,0x4db987bc,0xbd279da2,0xc3d75bc7 };
void MD5MAC_Base::UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs &)
{
const word32 zeros[4] = {0,0,0,0};
for (unsigned i=0, j; i<3; i++)
{
m_key[4*i+0] = 0x67452301L;
m_key[4*i+1] = 0xefcdab89L;
m_key[4*i+2] = 0x98badcfeL;
m_key[4*i+3] = 0x10325476L;
memcpy(m_data, userKey, KEYLENGTH);
CorrectEndianess(m_data, m_data, KEYLENGTH);
for (j=0; j<3; j++)
memcpy(m_data+4+4*j, T+((i+j)%3)*4, 16);
Transform(m_key+4*i, m_data, zeros);
for (j=0; j<3; j++)
memcpy(m_data+4*j, T+((i+j)%3)*4, 16);
memcpy(m_data+12, userKey, KEYLENGTH);
CorrectEndianess(m_data+12, m_data+12, KEYLENGTH);
Transform(m_key+4*i, m_data, zeros);
}
Init();
}
void MD5MAC_Base::Init()
{
m_digest[0] = m_key[0];
m_digest[1] = m_key[1];
m_digest[2] = m_key[2];
m_digest[3] = m_key[3];
}
void MD5MAC_Base::TruncatedFinal(byte *hash, size_t size)
{
ThrowIfInvalidTruncatedSize(size);
PadLastBlock(56);
CorrectEndianess(m_data, m_data, 56);
m_data[14] = GetBitCountLo();
m_data[15] = GetBitCountHi();
Transform(m_digest, m_data, m_key+4);
unsigned i;
for (i=0; i<4; i++)
m_data[i] = m_key[8+i];
for (i=0; i<12; i++)
m_data[i+4] = T[i] ^ m_key[8+i%4];
Transform(m_digest, m_data, m_key+4);
CorrectEndianess(m_digest, m_digest, DIGESTSIZE);
memcpy(hash, m_digest, size);
Restart(); // reinit for next use
}
void MD5MAC_Base::Transform(word32 *digest, const word32 *in, const word32 *key)
{
#define F1(x, y, z) ((z ^ (x & (y ^ z))) + key[0])
#define F2(x, y, z) ((y ^ (z & (x ^ y))) + key[1])
#define F3(x, y, z) ((x ^ y ^ z) + key[2])
#define F4(x, y, z) ((y ^ (x | ~z)) + key[3])
#define MD5STEP(f, w, x, y, z, data, s) \
w = rotlFixed(w + f(x, y, z) + data, s) + x
word32 a, b, c, d;
a=digest[0];
b=digest[1];
c=digest[2];
d=digest[3];
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
digest[0]+=a;
digest[1]+=b;
digest[2]+=c;
digest[3]+=d;
}
NAMESPACE_END

View File

@ -1,38 +0,0 @@
#ifndef CRYPTOPP_MD5MAC_H
#define CRYPTOPP_MD5MAC_H
/** \file
*/
#include "seckey.h"
#include "iterhash.h"
NAMESPACE_BEGIN(CryptoPP)
class CRYPTOPP_NO_VTABLE MD5MAC_Base : public FixedKeyLength<16>, public IteratedHash<word32, LittleEndian, 64, MessageAuthenticationCode>
{
public:
static std::string StaticAlgorithmName() {return "MD5-MAC";}
CRYPTOPP_CONSTANT(DIGESTSIZE = 16)
MD5MAC_Base() {SetStateSize(DIGESTSIZE);}
void UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs &params);
void TruncatedFinal(byte *mac, size_t size);
unsigned int DigestSize() const {return DIGESTSIZE;}
protected:
static void Transform (word32 *buf, const word32 *in, const word32 *key);
void HashEndianCorrectedBlock(const word32 *data) {Transform(m_digest, data, m_key+4);}
void Init();
static const word32 T[12];
FixedSizeSecBlock<word32, 12> m_key;
};
//! <a href="http://www.weidai.com/scan-mirror/mac.html#MD5-MAC">MD5-MAC</a>
DOCUMENTED_TYPEDEF(MessageAuthenticationCodeFinal<MD5MAC_Base>, MD5MAC)
NAMESPACE_END
#endif

179
xormac.h
View File

@ -1,179 +0,0 @@
// xormac.h - written and placed in the public domain by Wei Dai
#ifndef CRYPTOPP_XORMAC_H
#define CRYPTOPP_XORMAC_H
#include "seckey.h"
#include "iterhash.h"
#include "argnames.h"
#include "algparam.h"
NAMESPACE_BEGIN(CryptoPP)
template <class T> struct DigestSizeSubtract4Workaround // VC60 workaround
{
CRYPTOPP_CONSTANT(RESULT = T::DIGESTSIZE-4)
};
template <class T>
class CRYPTOPP_NO_VTABLE XMACC_Base : public FixedKeyLength<DigestSizeSubtract4Workaround<T>::RESULT, SimpleKeyingInterface::INTERNALLY_GENERATED_IV>,
public IteratedHash<typename T::HashWordType, typename T::ByteOrderClass, T::BLOCKSIZE, MessageAuthenticationCode>
{
public:
static std::string StaticAlgorithmName() {return std::string("XMAC(") + T::StaticAlgorithmName() + ")";}
CRYPTOPP_CONSTANT(DIGESTSIZE = 4+T::DIGESTSIZE)
typedef typename T::HashWordType HashWordType;
XMACC_Base() {SetStateSize(T::DIGESTSIZE);}
void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
void Resynchronize(const byte *IV)
{
GetWord(false, BIG_ENDIAN_ORDER, m_counter, IV);
this->Restart();
}
unsigned int IVSize() const
{return 4;}
void GetNextIV(byte *IV)
{
if (m_counter == 0xffffffff)
throw NotImplemented("XMACC: must have a valid counter to get next IV");
PutWord(false, BIG_ENDIAN_ORDER, IV, m_counter+1);
}
word32 CurrentCounter() const {return m_counter;}
void TruncatedFinal(byte *mac, size_t size);
bool TruncatedVerify(const byte *mac, size_t length);
unsigned int DigestSize() const {return DIGESTSIZE;} // need to override this
private:
void Init();
static void WriteWord32(byte *output, word32 value);
static void XorDigest(HashWordType *digest, const HashWordType *buffer);
void HashEndianCorrectedBlock(const HashWordType *data);
FixedSizeSecBlock<byte, DigestSizeSubtract4Workaround<T>::RESULT> m_key;
CRYPTOPP_CONSTANT(BUFFER_SIZE = (T::DIGESTSIZE / sizeof(HashWordType))) // VC60 workaround
#ifdef __BORLANDC__
FixedSizeSecBlock<HashWordType, T::DIGESTSIZE / sizeof(HashWordType)> m_buffer;
#else
FixedSizeSecBlock<HashWordType, BUFFER_SIZE> m_buffer;
#endif
word32 m_counter, m_index;
};
//! <a href="http://www.weidai.com/scan-mirror/mac.html#XMAC">XMAC</a>
/*! If you need to generate MACs with XMACC (instead of just verifying them),
you must save the counter before destroying an XMACC object
and reinitialize it the next time you create an XMACC with the same key.
Start counter at 0 when using a key for the first time. */
template <class T>
class XMACC : public ClonableImpl<XMACC<T>, MessageAuthenticationCodeImpl<XMACC_Base<T> > >
{
public:
XMACC() {}
XMACC(const byte *key, word32 counter = 0xffffffff)
{this->SetKey(key, this->KEYLENGTH, MakeParameters(Name::XMACC_Counter(), counter));}
};
template <class T> void XMACC_Base<T>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
{
this->AssertValidKeyLength(length);
m_counter = 0xffffffff;
const byte *iv = NULL;
if (params.GetValue(Name::IV(), iv))
GetWord(false, BIG_ENDIAN_ORDER, m_counter, iv);
else
params.GetValue(Name::XMACC_Counter(), m_counter);
memcpy_s(m_key, m_key.SizeInBytes(), key, this->KEYLENGTH);
Init();
}
template <class T> void XMACC_Base<T>::Init()
{
m_index = 0x80000000;
memset(this->m_digest, 0, T::DIGESTSIZE);
}
template <class T> inline void XMACC_Base<T>::WriteWord32(byte *output, word32 value)
{
output[0] = byte(value >> 24);
output[1] = byte(value >> 16);
output[2] = byte(value >> 8);
output[3] = byte(value);
}
template <class T> inline void XMACC_Base<T>::XorDigest(HashWordType *digest, const HashWordType *buffer)
{
for (unsigned i=0; i<(T::DIGESTSIZE/sizeof(HashWordType)); i++)
digest[i] ^= buffer[i];
}
template <class T> void XMACC_Base<T>::HashEndianCorrectedBlock(const HashWordType *input)
{
memcpy_s(m_buffer, m_buffer.SizeInBytes(), m_key, this->KEYLENGTH);
WriteWord32((byte *)m_buffer.begin()+this->KEYLENGTH, ++m_index);
T::CorrectEndianess(m_buffer, m_buffer, T::DIGESTSIZE);
T::Transform(m_buffer, input);
XorDigest(this->m_digest, m_buffer);
}
template <class T> void XMACC_Base<T>::TruncatedFinal(byte *mac, size_t size)
{
this->ThrowIfInvalidTruncatedSize(size);
if (size < 4)
throw InvalidArgument("XMACC: truncating the MAC to less than 4 bytes will cause it to be unverifiable");
if (m_counter == 0xffffffff)
throw InvalidArgument("XMACC: the counter must be initialized to a valid value for MAC generation");
PadLastBlock(this->BLOCKSIZE - 2*sizeof(HashWordType));
CorrectEndianess(this->m_data, this->m_data, this->BLOCKSIZE - 2*sizeof(HashWordType));
this->m_data[this->m_data.size()-2] = ByteReverse(this->GetBitCountHi()); // ByteReverse for backwards compatibility
this->m_data[this->m_data.size()-1] = ByteReverse(this->GetBitCountLo());
HashEndianCorrectedBlock(this->m_data);
memcpy_s(m_buffer, m_buffer.SizeInBytes(), m_key, this->KEYLENGTH);
WriteWord32((byte *)m_buffer.begin()+this->KEYLENGTH, 0);
memset(this->m_data, 0, this->BLOCKSIZE-4);
WriteWord32((byte *)this->m_data.begin()+this->BLOCKSIZE-4, ++m_counter);
T::CorrectEndianess(m_buffer, m_buffer, T::DIGESTSIZE);
T::CorrectEndianess(this->m_data, this->m_data, this->BLOCKSIZE);
T::Transform(m_buffer, this->m_data);
XorDigest(this->m_digest, m_buffer);
WriteWord32(mac, m_counter);
T::CorrectEndianess(this->m_digest, this->m_digest, T::DIGESTSIZE);
memcpy_s(mac+4, size-4, this->m_digest, size-4);
this->Restart(); // reinit for next use
}
template <class T> bool XMACC_Base<T>::TruncatedVerify(const byte *mac, size_t size)
{
assert(4 <= size && size <= DIGESTSIZE);
PadLastBlock(this->BLOCKSIZE - 2*sizeof(HashWordType));
CorrectEndianess(this->m_data, this->m_data, this->BLOCKSIZE - 2*sizeof(HashWordType));
this->m_data[this->m_data.size()-2] = ByteReverse(this->GetBitCountHi()); // ByteReverse for backwards compatibility
this->m_data[this->m_data.size()-1] = ByteReverse(this->GetBitCountLo());
HashEndianCorrectedBlock(this->m_data);
memcpy_s(m_buffer, m_buffer.SizeInBytes(), m_key, this->KEYLENGTH);
WriteWord32((byte *)m_buffer.begin()+this->KEYLENGTH, 0);
memset(this->m_data, 0, this->BLOCKSIZE-4);
memcpy_s((byte *)this->m_data.begin()+this->BLOCKSIZE-4, 4, mac, 4);
T::CorrectEndianess(m_buffer, m_buffer, T::DIGESTSIZE);
T::CorrectEndianess(this->m_data, this->m_data, this->BLOCKSIZE);
T::Transform(m_buffer, this->m_data);
XorDigest(this->m_digest, m_buffer);
T::CorrectEndianess(this->m_digest, this->m_digest, T::DIGESTSIZE);
bool macValid = (memcmp(mac+4, this->m_digest, size-4) == 0);
this->Restart(); // reinit for next use
return macValid;
}
NAMESPACE_END
#endif