Botan  2.10.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 #include <botan/rotate.h>
12 
13 namespace Botan {
14 
15 namespace {
16 
17 /*
18 * CAST-256 Round Type 1
19 */
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 */
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 */
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 */
52 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 */
98 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 */
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 
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 
227  {
228  zap(m_MK);
229  zap(m_RK);
230  }
231 
232 }
const uint32_t CAST_SBOX3[256]
Definition: cast_sboxes.h:105
void verify_key_set(bool cond) const
Definition: sym_algo.h:89
void zap(std::vector< T, Alloc > &vec)
Definition: secmem.h:170
void store_be(uint16_t in, uint8_t out[2])
Definition: loadstor.h:436
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
constexpr uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:39
void clear() override
Definition: cast256.cpp:226
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
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition: cast256.cpp:52
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:98