1 /*
2 * CAST-256
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7
8 #include <botan/cast256.h>
9 #include <botan/internal/cast_sboxes.h>
10 #include <botan/loadstor.h>
11 #include <botan/rotate.h>
12
13 namespace Botan {
14
15 namespace {
16
17 /*
18 * CAST-256 Round Type 1
19 */
round1(uint32_t & out,uint32_t in,uint32_t MK,uint32_t RK)20 void round1(uint32_t& out, uint32_t in, uint32_t MK, uint32_t RK)
21 {
22 const uint32_t T = rotl_var(MK + in, RK);
23 out ^= (CAST_SBOX1[get_byte(0, T)] ^ CAST_SBOX2[get_byte(1, T)]) -
24 CAST_SBOX3[get_byte(2, T)] + CAST_SBOX4[get_byte(3, T)];
25 }
26
27 /*
28 * CAST-256 Round Type 2
29 */
round2(uint32_t & out,uint32_t in,uint32_t MK,uint32_t RK)30 void round2(uint32_t& out, uint32_t in, uint32_t MK, uint32_t RK)
31 {
32 const uint32_t T = rotl_var(MK ^ in, RK);
33 out ^= (CAST_SBOX1[get_byte(0, T)] - CAST_SBOX2[get_byte(1, T)] +
34 CAST_SBOX3[get_byte(2, T)]) ^ CAST_SBOX4[get_byte(3, T)];
35 }
36
37 /*
38 * CAST-256 Round Type 3
39 */
round3(uint32_t & out,uint32_t in,uint32_t MK,uint32_t RK)40 void round3(uint32_t& out, uint32_t in, uint32_t MK, uint32_t RK)
41 {
42 const uint32_t T = rotl_var(MK - in, RK);
43 out ^= ((CAST_SBOX1[get_byte(0, T)] + CAST_SBOX2[get_byte(1, T)]) ^
44 CAST_SBOX3[get_byte(2, T)]) - CAST_SBOX4[get_byte(3, T)];
45 }
46
47 }
48
49 /*
50 * CAST-256 Encryption
51 */
encrypt_n(const uint8_t in[],uint8_t out[],size_t blocks) const52 void CAST_256::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
53 {
54 verify_key_set(m_RK.empty() == false);
55
56 for(size_t i = 0; i != blocks; ++i)
57 {
58 uint32_t A = load_be<uint32_t>(in, 0);
59 uint32_t B = load_be<uint32_t>(in, 1);
60 uint32_t C = load_be<uint32_t>(in, 2);
61 uint32_t D = load_be<uint32_t>(in, 3);
62
63 round1(C, D, m_MK[ 0], m_RK[ 0]); round2(B, C, m_MK[ 1], m_RK[ 1]);
64 round3(A, B, m_MK[ 2], m_RK[ 2]); round1(D, A, m_MK[ 3], m_RK[ 3]);
65 round1(C, D, m_MK[ 4], m_RK[ 4]); round2(B, C, m_MK[ 5], m_RK[ 5]);
66 round3(A, B, m_MK[ 6], m_RK[ 6]); round1(D, A, m_MK[ 7], m_RK[ 7]);
67 round1(C, D, m_MK[ 8], m_RK[ 8]); round2(B, C, m_MK[ 9], m_RK[ 9]);
68 round3(A, B, m_MK[10], m_RK[10]); round1(D, A, m_MK[11], m_RK[11]);
69 round1(C, D, m_MK[12], m_RK[12]); round2(B, C, m_MK[13], m_RK[13]);
70 round3(A, B, m_MK[14], m_RK[14]); round1(D, A, m_MK[15], m_RK[15]);
71 round1(C, D, m_MK[16], m_RK[16]); round2(B, C, m_MK[17], m_RK[17]);
72 round3(A, B, m_MK[18], m_RK[18]); round1(D, A, m_MK[19], m_RK[19]);
73 round1(C, D, m_MK[20], m_RK[20]); round2(B, C, m_MK[21], m_RK[21]);
74 round3(A, B, m_MK[22], m_RK[22]); round1(D, A, m_MK[23], m_RK[23]);
75 round1(D, A, m_MK[27], m_RK[27]); round3(A, B, m_MK[26], m_RK[26]);
76 round2(B, C, m_MK[25], m_RK[25]); round1(C, D, m_MK[24], m_RK[24]);
77 round1(D, A, m_MK[31], m_RK[31]); round3(A, B, m_MK[30], m_RK[30]);
78 round2(B, C, m_MK[29], m_RK[29]); round1(C, D, m_MK[28], m_RK[28]);
79 round1(D, A, m_MK[35], m_RK[35]); round3(A, B, m_MK[34], m_RK[34]);
80 round2(B, C, m_MK[33], m_RK[33]); round1(C, D, m_MK[32], m_RK[32]);
81 round1(D, A, m_MK[39], m_RK[39]); round3(A, B, m_MK[38], m_RK[38]);
82 round2(B, C, m_MK[37], m_RK[37]); round1(C, D, m_MK[36], m_RK[36]);
83 round1(D, A, m_MK[43], m_RK[43]); round3(A, B, m_MK[42], m_RK[42]);
84 round2(B, C, m_MK[41], m_RK[41]); round1(C, D, m_MK[40], m_RK[40]);
85 round1(D, A, m_MK[47], m_RK[47]); round3(A, B, m_MK[46], m_RK[46]);
86 round2(B, C, m_MK[45], m_RK[45]); round1(C, D, m_MK[44], m_RK[44]);
87
88 store_be(out, A, B, C, D);
89
90 in += BLOCK_SIZE;
91 out += BLOCK_SIZE;
92 }
93 }
94
95 /*
96 * CAST-256 Decryption
97 */
decrypt_n(const uint8_t in[],uint8_t out[],size_t blocks) const98 void CAST_256::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
99 {
100 verify_key_set(m_RK.empty() == false);
101
102 for(size_t i = 0; i != blocks; ++i)
103 {
104 uint32_t A = load_be<uint32_t>(in, 0);
105 uint32_t B = load_be<uint32_t>(in, 1);
106 uint32_t C = load_be<uint32_t>(in, 2);
107 uint32_t D = load_be<uint32_t>(in, 3);
108
109 round1(C, D, m_MK[44], m_RK[44]); round2(B, C, m_MK[45], m_RK[45]);
110 round3(A, B, m_MK[46], m_RK[46]); round1(D, A, m_MK[47], m_RK[47]);
111 round1(C, D, m_MK[40], m_RK[40]); round2(B, C, m_MK[41], m_RK[41]);
112 round3(A, B, m_MK[42], m_RK[42]); round1(D, A, m_MK[43], m_RK[43]);
113 round1(C, D, m_MK[36], m_RK[36]); round2(B, C, m_MK[37], m_RK[37]);
114 round3(A, B, m_MK[38], m_RK[38]); round1(D, A, m_MK[39], m_RK[39]);
115 round1(C, D, m_MK[32], m_RK[32]); round2(B, C, m_MK[33], m_RK[33]);
116 round3(A, B, m_MK[34], m_RK[34]); round1(D, A, m_MK[35], m_RK[35]);
117 round1(C, D, m_MK[28], m_RK[28]); round2(B, C, m_MK[29], m_RK[29]);
118 round3(A, B, m_MK[30], m_RK[30]); round1(D, A, m_MK[31], m_RK[31]);
119 round1(C, D, m_MK[24], m_RK[24]); round2(B, C, m_MK[25], m_RK[25]);
120 round3(A, B, m_MK[26], m_RK[26]); round1(D, A, m_MK[27], m_RK[27]);
121 round1(D, A, m_MK[23], m_RK[23]); round3(A, B, m_MK[22], m_RK[22]);
122 round2(B, C, m_MK[21], m_RK[21]); round1(C, D, m_MK[20], m_RK[20]);
123 round1(D, A, m_MK[19], m_RK[19]); round3(A, B, m_MK[18], m_RK[18]);
124 round2(B, C, m_MK[17], m_RK[17]); round1(C, D, m_MK[16], m_RK[16]);
125 round1(D, A, m_MK[15], m_RK[15]); round3(A, B, m_MK[14], m_RK[14]);
126 round2(B, C, m_MK[13], m_RK[13]); round1(C, D, m_MK[12], m_RK[12]);
127 round1(D, A, m_MK[11], m_RK[11]); round3(A, B, m_MK[10], m_RK[10]);
128 round2(B, C, m_MK[ 9], m_RK[ 9]); round1(C, D, m_MK[ 8], m_RK[ 8]);
129 round1(D, A, m_MK[ 7], m_RK[ 7]); round3(A, B, m_MK[ 6], m_RK[ 6]);
130 round2(B, C, m_MK[ 5], m_RK[ 5]); round1(C, D, m_MK[ 4], m_RK[ 4]);
131 round1(D, A, m_MK[ 3], m_RK[ 3]); round3(A, B, m_MK[ 2], m_RK[ 2]);
132 round2(B, C, m_MK[ 1], m_RK[ 1]); round1(C, D, m_MK[ 0], m_RK[ 0]);
133
134 store_be(out, A, B, C, D);
135
136 in += BLOCK_SIZE;
137 out += BLOCK_SIZE;
138 }
139 }
140
141 /*
142 * CAST-256 Key Schedule
143 */
key_schedule(const uint8_t key[],size_t length)144 void CAST_256::key_schedule(const uint8_t key[], size_t length)
145 {
146 static const uint32_t KEY_MASK[192] = {
147 0x5A827999, 0xC95C653A, 0x383650DB, 0xA7103C7C, 0x15EA281D, 0x84C413BE,
148 0xF39DFF5F, 0x6277EB00, 0xD151D6A1, 0x402BC242, 0xAF05ADE3, 0x1DDF9984,
149 0x8CB98525, 0xFB9370C6, 0x6A6D5C67, 0xD9474808, 0x482133A9, 0xB6FB1F4A,
150 0x25D50AEB, 0x94AEF68C, 0x0388E22D, 0x7262CDCE, 0xE13CB96F, 0x5016A510,
151 0xBEF090B1, 0x2DCA7C52, 0x9CA467F3, 0x0B7E5394, 0x7A583F35, 0xE9322AD6,
152 0x580C1677, 0xC6E60218, 0x35BFEDB9, 0xA499D95A, 0x1373C4FB, 0x824DB09C,
153 0xF1279C3D, 0x600187DE, 0xCEDB737F, 0x3DB55F20, 0xAC8F4AC1, 0x1B693662,
154 0x8A432203, 0xF91D0DA4, 0x67F6F945, 0xD6D0E4E6, 0x45AAD087, 0xB484BC28,
155 0x235EA7C9, 0x9238936A, 0x01127F0B, 0x6FEC6AAC, 0xDEC6564D, 0x4DA041EE,
156 0xBC7A2D8F, 0x2B541930, 0x9A2E04D1, 0x0907F072, 0x77E1DC13, 0xE6BBC7B4,
157 0x5595B355, 0xC46F9EF6, 0x33498A97, 0xA2237638, 0x10FD61D9, 0x7FD74D7A,
158 0xEEB1391B, 0x5D8B24BC, 0xCC65105D, 0x3B3EFBFE, 0xAA18E79F, 0x18F2D340,
159 0x87CCBEE1, 0xF6A6AA82, 0x65809623, 0xD45A81C4, 0x43346D65, 0xB20E5906,
160 0x20E844A7, 0x8FC23048, 0xFE9C1BE9, 0x6D76078A, 0xDC4FF32B, 0x4B29DECC,
161 0xBA03CA6D, 0x28DDB60E, 0x97B7A1AF, 0x06918D50, 0x756B78F1, 0xE4456492,
162 0x531F5033, 0xC1F93BD4, 0x30D32775, 0x9FAD1316, 0x0E86FEB7, 0x7D60EA58,
163 0xEC3AD5F9, 0x5B14C19A, 0xC9EEAD3B, 0x38C898DC, 0xA7A2847D, 0x167C701E,
164 0x85565BBF, 0xF4304760, 0x630A3301, 0xD1E41EA2, 0x40BE0A43, 0xAF97F5E4,
165 0x1E71E185, 0x8D4BCD26, 0xFC25B8C7, 0x6AFFA468, 0xD9D99009, 0x48B37BAA,
166 0xB78D674B, 0x266752EC, 0x95413E8D, 0x041B2A2E, 0x72F515CF, 0xE1CF0170,
167 0x50A8ED11, 0xBF82D8B2, 0x2E5CC453, 0x9D36AFF4, 0x0C109B95, 0x7AEA8736,
168 0xE9C472D7, 0x589E5E78, 0xC7784A19, 0x365235BA, 0xA52C215B, 0x14060CFC,
169 0x82DFF89D, 0xF1B9E43E, 0x6093CFDF, 0xCF6DBB80, 0x3E47A721, 0xAD2192C2,
170 0x1BFB7E63, 0x8AD56A04, 0xF9AF55A5, 0x68894146, 0xD7632CE7, 0x463D1888,
171 0xB5170429, 0x23F0EFCA, 0x92CADB6B, 0x01A4C70C, 0x707EB2AD, 0xDF589E4E,
172 0x4E3289EF, 0xBD0C7590, 0x2BE66131, 0x9AC04CD2, 0x099A3873, 0x78742414,
173 0xE74E0FB5, 0x5627FB56, 0xC501E6F7, 0x33DBD298, 0xA2B5BE39, 0x118FA9DA,
174 0x8069957B, 0xEF43811C, 0x5E1D6CBD, 0xCCF7585E, 0x3BD143FF, 0xAAAB2FA0,
175 0x19851B41, 0x885F06E2, 0xF738F283, 0x6612DE24, 0xD4ECC9C5, 0x43C6B566,
176 0xB2A0A107, 0x217A8CA8, 0x90547849, 0xFF2E63EA, 0x6E084F8B, 0xDCE23B2C,
177 0x4BBC26CD, 0xBA96126E, 0x296FFE0F, 0x9849E9B0, 0x0723D551, 0x75FDC0F2,
178 0xE4D7AC93, 0x53B19834, 0xC28B83D5, 0x31656F76, 0xA03F5B17, 0x0F1946B8 };
179
180 static const uint8_t KEY_ROT[32] = {
181 0x13, 0x04, 0x15, 0x06, 0x17, 0x08, 0x19, 0x0A, 0x1B, 0x0C,
182 0x1D, 0x0E, 0x1F, 0x10, 0x01, 0x12, 0x03, 0x14, 0x05, 0x16,
183 0x07, 0x18, 0x09, 0x1A, 0x0B, 0x1C, 0x0D, 0x1E, 0x0F, 0x00,
184 0x11, 0x02 };
185
186 m_MK.resize(48);
187 m_RK.resize(48);
188
189 secure_vector<uint32_t> K(8);
190 for(size_t i = 0; i != length; ++i)
191 K[i/4] = (K[i/4] << 8) + key[i];
192
193 uint32_t A = K[0], B = K[1], C = K[2], D = K[3],
194 E = K[4], F = K[5], G = K[6], H = K[7];
195
196 for(size_t i = 0; i != 48; i += 4)
197 {
198 round1(G, H, KEY_MASK[4*i+ 0], KEY_ROT[(4*i+ 0) % 32]);
199 round2(F, G, KEY_MASK[4*i+ 1], KEY_ROT[(4*i+ 1) % 32]);
200 round3(E, F, KEY_MASK[4*i+ 2], KEY_ROT[(4*i+ 2) % 32]);
201 round1(D, E, KEY_MASK[4*i+ 3], KEY_ROT[(4*i+ 3) % 32]);
202 round2(C, D, KEY_MASK[4*i+ 4], KEY_ROT[(4*i+ 4) % 32]);
203 round3(B, C, KEY_MASK[4*i+ 5], KEY_ROT[(4*i+ 5) % 32]);
204 round1(A, B, KEY_MASK[4*i+ 6], KEY_ROT[(4*i+ 6) % 32]);
205 round2(H, A, KEY_MASK[4*i+ 7], KEY_ROT[(4*i+ 7) % 32]);
206 round1(G, H, KEY_MASK[4*i+ 8], KEY_ROT[(4*i+ 8) % 32]);
207 round2(F, G, KEY_MASK[4*i+ 9], KEY_ROT[(4*i+ 9) % 32]);
208 round3(E, F, KEY_MASK[4*i+10], KEY_ROT[(4*i+10) % 32]);
209 round1(D, E, KEY_MASK[4*i+11], KEY_ROT[(4*i+11) % 32]);
210 round2(C, D, KEY_MASK[4*i+12], KEY_ROT[(4*i+12) % 32]);
211 round3(B, C, KEY_MASK[4*i+13], KEY_ROT[(4*i+13) % 32]);
212 round1(A, B, KEY_MASK[4*i+14], KEY_ROT[(4*i+14) % 32]);
213 round2(H, A, KEY_MASK[4*i+15], KEY_ROT[(4*i+15) % 32]);
214
215 m_RK[i ] = (A % 32);
216 m_RK[i+1] = (C % 32);
217 m_RK[i+2] = (E % 32);
218 m_RK[i+3] = (G % 32);
219 m_MK[i ] = H;
220 m_MK[i+1] = F;
221 m_MK[i+2] = D;
222 m_MK[i+3] = B;
223 }
224 }
225
clear()226 void CAST_256::clear()
227 {
228 zap(m_MK);
229 zap(m_RK);
230 }
231
232 }
233