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