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