Line | Count | Source (jump to first uncovered line) |
1 | 0 | #define NROUNDS 32 |
2 | | |
3 | 0 | #define substLong(t) ( (uint)SubstTable20[(uint)t&255] | \ |
4 | 0 | ((uint)SubstTable20[(int)(t>> 8)&255]<< 8) | \ |
5 | 0 | ((uint)SubstTable20[(int)(t>>16)&255]<<16) | \ |
6 | 0 | ((uint)SubstTable20[(int)(t>>24)&255]<<24) ) |
7 | | |
8 | | |
9 | | static byte InitSubstTable20[256]={ |
10 | | 215, 19,149, 35, 73,197,192,205,249, 28, 16,119, 48,221, 2, 42, |
11 | | 232, 1,177,233, 14, 88,219, 25,223,195,244, 90, 87,239,153,137, |
12 | | 255,199,147, 70, 92, 66,246, 13,216, 40, 62, 29,217,230, 86, 6, |
13 | | 71, 24,171,196,101,113,218,123, 93, 91,163,178,202, 67, 44,235, |
14 | | 107,250, 75,234, 49,167,125,211, 83,114,157,144, 32,193,143, 36, |
15 | | 158,124,247,187, 89,214,141, 47,121,228, 61,130,213,194,174,251, |
16 | | 97,110, 54,229,115, 57,152, 94,105,243,212, 55,209,245, 63, 11, |
17 | | 164,200, 31,156, 81,176,227, 21, 76, 99,139,188,127, 17,248, 51, |
18 | | 207,120,189,210, 8,226, 41, 72,183,203,135,165,166, 60, 98, 7, |
19 | | 122, 38,155,170, 69,172,252,238, 39,134, 59,128,236, 27,240, 80, |
20 | | 131, 3, 85,206,145, 79,154,142,159,220,201,133, 74, 64, 20,129, |
21 | | 224,185,138,103,173,182, 43, 34,254, 82,198,151,231,180, 58, 10, |
22 | | 118, 26,102, 12, 50,132, 22,191,136,111,162,179, 45, 4,148,108, |
23 | | 161, 56, 78,126,242,222, 15,175,146, 23, 33,241,181,190, 77,225, |
24 | | 0, 46,169,186, 68, 95,237, 65, 53,208,253,168, 9, 18,100, 52, |
25 | | 116,184,160, 96,109, 37, 30,106,140,104,150, 5,204,117,112, 84 |
26 | | }; |
27 | | |
28 | | |
29 | | void CryptData::SetKey20(const char *Password) |
30 | 0 | { |
31 | 0 | InitCRC32(CRCTab); |
32 | |
|
33 | 0 | char Psw[MAXPASSWORD]; |
34 | 0 | strncpyz(Psw,Password,ASIZE(Psw)); // We'll need to modify it below. |
35 | 0 | size_t PswLength=strlen(Psw); |
36 | |
|
37 | 0 | Key20[0]=0xD3A3B879L; |
38 | 0 | Key20[1]=0x3F6D12F7L; |
39 | 0 | Key20[2]=0x7515A235L; |
40 | 0 | Key20[3]=0xA4E7F123L; |
41 | |
|
42 | 0 | memcpy(SubstTable20,InitSubstTable20,sizeof(SubstTable20)); |
43 | 0 | for (uint J=0;J<256;J++) |
44 | 0 | for (size_t I=0;I<PswLength;I+=2) |
45 | 0 | { |
46 | 0 | uint N1=(byte)CRCTab [ (byte(Password[I]) - J) &0xff]; |
47 | 0 | uint N2=(byte)CRCTab [ (byte(Password[I+1]) + J) &0xff]; |
48 | 0 | for (int K=1;N1!=N2;N1=(N1+1)&0xff,K++) |
49 | 0 | Swap20(&SubstTable20[N1],&SubstTable20[(N1+I+K)&0xff]); |
50 | 0 | } |
51 | | |
52 | | // Incomplete last block of password must be zero padded. |
53 | 0 | if ((PswLength & CRYPT_BLOCK_MASK)!=0) |
54 | 0 | for (size_t I=PswLength;I<=(PswLength|CRYPT_BLOCK_MASK);I++) |
55 | 0 | Psw[I]=0; |
56 | |
|
57 | 0 | for (size_t I=0;I<PswLength;I+=CRYPT_BLOCK_SIZE) |
58 | 0 | EncryptBlock20((byte *)Psw+I); |
59 | 0 | } |
60 | | |
61 | | |
62 | | void CryptData::EncryptBlock20(byte *Buf) |
63 | 0 | { |
64 | 0 | uint A,B,C,D,T,TA,TB; |
65 | 0 | A=RawGet4(Buf+0)^Key20[0]; |
66 | 0 | B=RawGet4(Buf+4)^Key20[1]; |
67 | 0 | C=RawGet4(Buf+8)^Key20[2]; |
68 | 0 | D=RawGet4(Buf+12)^Key20[3]; |
69 | 0 | for(int I=0;I<NROUNDS;I++) |
70 | 0 | { |
71 | 0 | T=((C+rotls(D,11,32))^Key20[I&3]); |
72 | 0 | TA=A^substLong(T); |
73 | 0 | T=((D^rotls(C,17,32))+Key20[I&3]); |
74 | 0 | TB=B^substLong(T); |
75 | 0 | A=C; |
76 | 0 | B=D; |
77 | 0 | C=TA; |
78 | 0 | D=TB; |
79 | 0 | } |
80 | 0 | RawPut4(C^Key20[0],Buf+0); |
81 | 0 | RawPut4(D^Key20[1],Buf+4); |
82 | 0 | RawPut4(A^Key20[2],Buf+8); |
83 | 0 | RawPut4(B^Key20[3],Buf+12); |
84 | 0 | UpdKeys20(Buf); |
85 | 0 | } |
86 | | |
87 | | |
88 | | void CryptData::DecryptBlock20(byte *Buf) |
89 | 0 | { |
90 | 0 | byte InBuf[16]; |
91 | 0 | uint A,B,C,D,T,TA,TB; |
92 | 0 | A=RawGet4(Buf+0)^Key20[0]; |
93 | 0 | B=RawGet4(Buf+4)^Key20[1]; |
94 | 0 | C=RawGet4(Buf+8)^Key20[2]; |
95 | 0 | D=RawGet4(Buf+12)^Key20[3]; |
96 | 0 | memcpy(InBuf,Buf,sizeof(InBuf)); |
97 | 0 | for(int I=NROUNDS-1;I>=0;I--) |
98 | 0 | { |
99 | 0 | T=((C+rotls(D,11,32))^Key20[I&3]); |
100 | 0 | TA=A^substLong(T); |
101 | 0 | T=((D^rotls(C,17,32))+Key20[I&3]); |
102 | 0 | TB=B^substLong(T); |
103 | 0 | A=C; |
104 | 0 | B=D; |
105 | 0 | C=TA; |
106 | 0 | D=TB; |
107 | 0 | } |
108 | 0 | RawPut4(C^Key20[0],Buf+0); |
109 | 0 | RawPut4(D^Key20[1],Buf+4); |
110 | 0 | RawPut4(A^Key20[2],Buf+8); |
111 | 0 | RawPut4(B^Key20[3],Buf+12); |
112 | 0 | UpdKeys20(InBuf); |
113 | 0 | } |
114 | | |
115 | | |
116 | | void CryptData::UpdKeys20(byte *Buf) |
117 | 0 | { |
118 | 0 | for (int I=0;I<16;I+=4) |
119 | 0 | { |
120 | 0 | Key20[0]^=CRCTab[Buf[I]]; |
121 | 0 | Key20[1]^=CRCTab[Buf[I+1]]; |
122 | 0 | Key20[2]^=CRCTab[Buf[I+2]]; |
123 | 0 | Key20[3]^=CRCTab[Buf[I+3]]; |
124 | 0 | } |
125 | 0 | } |
126 | | |
127 | | |
128 | | void CryptData::Swap20(byte *Ch1,byte *Ch2) |
129 | 0 | { |
130 | 0 | byte Ch=*Ch1; |
131 | 0 | *Ch1=*Ch2; |
132 | 0 | *Ch2=Ch; |
133 | 0 | } |