00001
00002
00003 #include "pch.h"
00004 #include "wake.h"
00005
00006 NAMESPACE_BEGIN(CryptoPP)
00007
00008 inline word32 WAKE::M(word32 x, word32 y)
00009 {
00010 word32 w = x+y;
00011 return (w>>8) ^ t[(byte)w];
00012 }
00013
00014 inline word32 WAKE::enc(word32 V)
00015 {
00016 V = V^r6;
00017 r3 = M(r3, V);
00018 r4 = M(r4, r3);
00019 r5 = M(r5, r4);
00020 r6 = M(r6, r5);
00021 return V;
00022 }
00023
00024 inline word32 WAKE::dec(word32 V)
00025 {
00026 r3 = M(r3, V);
00027 V = V^r6;
00028 r4 = M(r4, r3);
00029 r5 = M(r5, r4);
00030 r6 = M(r6, r5);
00031 return V;
00032 }
00033
00034 void WAKE::genkey(word32 k0, word32 k1, word32 k2, word32 k3)
00035 {
00036 long x, z;
00037 int p ;
00038 static long tt[10]= {
00039 0x726a8f3bL,
00040 0xe69a3b5cL,
00041 0xd3c71fe5L,
00042 0xab3c73d2L,
00043 0x4d3a8eb3L,
00044 0x0396d6e8L,
00045 0x3d4c2f7aL,
00046 0x9ee27cf3L, } ;
00047 t[0] = k0;
00048 t[1] = k1;
00049 t[2] = k2;
00050 t[3] = k3;
00051 for (p=4 ; p<256 ; p++)
00052 {
00053 x=t[p-4]+t[p-1] ;
00054 t[p]= (x>>3) ^ tt[byte(x&7)] ;
00055 }
00056
00057 for (p=0 ; p<23 ; p++)
00058 t[p]+=t[p+89] ;
00059 x=t[33] ; z=t[59] | 0x01000001L ;
00060 z=z&0xff7fffffL ;
00061 for (p=0 ; p<256 ; p++) {
00062 x=(x&0xff7fffffL)+z ;
00063 t[p]=(t[p] & 0x00ffffffL) ^ x ; }
00064
00065 t[256]=t[0] ;
00066 byte y=byte(x);
00067 for (p=0 ; p<256 ; p++) {
00068 t[p]=t[y=byte(t[p^y]^y)] ;
00069 t[y]=t[p+1] ; }
00070 }
00071
00072 WAKEEncryption::WAKEEncryption(const byte *key, BufferedTransformation *outQueue)
00073 : Filter(outQueue), inbuf(INBUFMAX), inbufSize(0)
00074 {
00075 r3 = ((word32)key[0] << 24) | ((word32)key[1] << 16) | ((word32)key[2] << 8) | (word32)key[3];
00076 r4 = ((word32)key[4] << 24) | ((word32)key[5] << 16) | ((word32)key[6] << 8) | (word32)key[7];
00077 r5 = ((word32)key[8] << 24) | ((word32)key[9] << 16) | ((word32)key[10] << 8) | (word32)key[11];
00078 r6 = ((word32)key[12] << 24) | ((word32)key[13] << 16) | ((word32)key[14] << 8) | (word32)key[15];
00079
00080 word32 k0 = ((word32)key[16] << 24) | ((word32)key[17] << 16) | ((word32)key[18] << 8) | (word32)key[19];
00081 word32 k1 = ((word32)key[20] << 24) | ((word32)key[21] << 16) | ((word32)key[22] << 8) | (word32)key[23];
00082 word32 k2 = ((word32)key[24] << 24) | ((word32)key[25] << 16) | ((word32)key[26] << 8) | (word32)key[27];
00083 word32 k3 = ((word32)key[28] << 24) | ((word32)key[29] << 16) | ((word32)key[30] << 8) | (word32)key[31];
00084 genkey(k0, k1, k2, k3);
00085 }
00086
00087 void WAKEEncryption::ProcessInbuf()
00088 {
00089 assert((inbufSize % 4) == 0);
00090
00091 word32 *ptr = (word32 *)inbuf.ptr;
00092 byte *const end = (byte *)inbuf+inbufSize;
00093
00094 while (ptr!=(word32 *)end)
00095 {
00096 #ifdef IS_LITTLE_ENDIAN
00097 *ptr = byteReverse(enc(byteReverse(*ptr)));
00098 #else
00099 *ptr = enc(*ptr);
00100 #endif
00101 ptr++;
00102 }
00103
00104 AttachedTransformation()->Put(inbuf, inbufSize);
00105 inbufSize=0;
00106 }
00107
00108 void WAKEEncryption::Put(const byte *inString, unsigned int length)
00109 {
00110 while (length)
00111 {
00112 if (inbufSize==INBUFMAX)
00113 ProcessInbuf();
00114 unsigned int l = STDMIN(length, INBUFMAX-inbufSize);
00115 memcpy(inbuf+inbufSize, inString, l);
00116 inString+=l;
00117 length-=l;
00118 inbufSize+=l;
00119 }
00120 }
00121
00122 void WAKEEncryption::MessageEnd(int propagation)
00123 {
00124 if (inbufSize == INBUFMAX)
00125 ProcessInbuf();
00126
00127 memset(inbuf+inbufSize, 4-(inbufSize%4), 4-(inbufSize%4));
00128 inbufSize += 4-(inbufSize%4);
00129 ProcessInbuf();
00130 Filter::MessageEnd(propagation);
00131 }
00132
00133 void WAKEDecryption::ProcessInbuf()
00134 {
00135 assert((inbufSize % 4) == 0);
00136
00137 word32 *ptr = (word32 *)inbuf.ptr;
00138 byte *const end = (byte *)inbuf+inbufSize;
00139
00140 while (ptr!=(word32 *)end)
00141 {
00142 #ifdef IS_LITTLE_ENDIAN
00143 *ptr = byteReverse(dec(byteReverse(*ptr)));
00144 #else
00145 *ptr = dec(*ptr);
00146 #endif
00147 ptr++;
00148 }
00149
00150 if (lastBlock)
00151 {
00152 if (inbuf[inbufSize-1] > 4) inbuf[inbufSize-1]=0;
00153 AttachedTransformation()->Put(inbuf, inbufSize-inbuf[inbufSize-1]);
00154 }
00155 else
00156 AttachedTransformation()->Put(inbuf, inbufSize);
00157
00158 inbufSize=0;
00159 }
00160
00161 void WAKEDecryption::MessageEnd(int propagation)
00162 {
00163 lastBlock = true;
00164 ProcessInbuf();
00165 Filter::MessageEnd(propagation);
00166 }
00167
00168 NAMESPACE_END