Botan
1.11.15
|
00001 /* 00002 * Camellia 00003 * (C) 2012 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/internal/block_utils.h> 00009 #include <botan/camellia.h> 00010 #include <botan/internal/camellia_sbox.h> 00011 00012 namespace Botan { 00013 00014 BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(Camellia_128, "Camellia-128"); 00015 BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(Camellia_192, "Camellia-192"); 00016 BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(Camellia_256, "Camellia-256"); 00017 00018 namespace Camellia_F { 00019 00020 namespace { 00021 00022 /* 00023 * We use the slow byte-wise version of F in the first and last rounds 00024 * to help protect against timing attacks 00025 */ 00026 u64bit F_SLOW(u64bit v, u64bit K) 00027 { 00028 static const byte SBOX[256] = { 00029 0x70, 0x82, 0x2C, 0xEC, 0xB3, 0x27, 0xC0, 0xE5, 0xE4, 0x85, 0x57, 00030 0x35, 0xEA, 0x0C, 0xAE, 0x41, 0x23, 0xEF, 0x6B, 0x93, 0x45, 0x19, 00031 0xA5, 0x21, 0xED, 0x0E, 0x4F, 0x4E, 0x1D, 0x65, 0x92, 0xBD, 0x86, 00032 0xB8, 0xAF, 0x8F, 0x7C, 0xEB, 0x1F, 0xCE, 0x3E, 0x30, 0xDC, 0x5F, 00033 0x5E, 0xC5, 0x0B, 0x1A, 0xA6, 0xE1, 0x39, 0xCA, 0xD5, 0x47, 0x5D, 00034 0x3D, 0xD9, 0x01, 0x5A, 0xD6, 0x51, 0x56, 0x6C, 0x4D, 0x8B, 0x0D, 00035 0x9A, 0x66, 0xFB, 0xCC, 0xB0, 0x2D, 0x74, 0x12, 0x2B, 0x20, 0xF0, 00036 0xB1, 0x84, 0x99, 0xDF, 0x4C, 0xCB, 0xC2, 0x34, 0x7E, 0x76, 0x05, 00037 0x6D, 0xB7, 0xA9, 0x31, 0xD1, 0x17, 0x04, 0xD7, 0x14, 0x58, 0x3A, 00038 0x61, 0xDE, 0x1B, 0x11, 0x1C, 0x32, 0x0F, 0x9C, 0x16, 0x53, 0x18, 00039 0xF2, 0x22, 0xFE, 0x44, 0xCF, 0xB2, 0xC3, 0xB5, 0x7A, 0x91, 0x24, 00040 0x08, 0xE8, 0xA8, 0x60, 0xFC, 0x69, 0x50, 0xAA, 0xD0, 0xA0, 0x7D, 00041 0xA1, 0x89, 0x62, 0x97, 0x54, 0x5B, 0x1E, 0x95, 0xE0, 0xFF, 0x64, 00042 0xD2, 0x10, 0xC4, 0x00, 0x48, 0xA3, 0xF7, 0x75, 0xDB, 0x8A, 0x03, 00043 0xE6, 0xDA, 0x09, 0x3F, 0xDD, 0x94, 0x87, 0x5C, 0x83, 0x02, 0xCD, 00044 0x4A, 0x90, 0x33, 0x73, 0x67, 0xF6, 0xF3, 0x9D, 0x7F, 0xBF, 0xE2, 00045 0x52, 0x9B, 0xD8, 0x26, 0xC8, 0x37, 0xC6, 0x3B, 0x81, 0x96, 0x6F, 00046 0x4B, 0x13, 0xBE, 0x63, 0x2E, 0xE9, 0x79, 0xA7, 0x8C, 0x9F, 0x6E, 00047 0xBC, 0x8E, 0x29, 0xF5, 0xF9, 0xB6, 0x2F, 0xFD, 0xB4, 0x59, 0x78, 00048 0x98, 0x06, 0x6A, 0xE7, 0x46, 0x71, 0xBA, 0xD4, 0x25, 0xAB, 0x42, 00049 0x88, 0xA2, 0x8D, 0xFA, 0x72, 0x07, 0xB9, 0x55, 0xF8, 0xEE, 0xAC, 00050 0x0A, 0x36, 0x49, 0x2A, 0x68, 0x3C, 0x38, 0xF1, 0xA4, 0x40, 0x28, 00051 0xD3, 0x7B, 0xBB, 0xC9, 0x43, 0xC1, 0x15, 0xE3, 0xAD, 0xF4, 0x77, 00052 0xC7, 0x80, 0x9E }; 00053 00054 const u64bit x = v ^ K; 00055 00056 const byte t1 = SBOX[get_byte(0, x)]; 00057 const byte t2 = rotate_left(SBOX[get_byte(1, x)], 1); 00058 const byte t3 = rotate_left(SBOX[get_byte(2, x)], 7); 00059 const byte t4 = SBOX[rotate_left(get_byte(3, x), 1)]; 00060 const byte t5 = rotate_left(SBOX[get_byte(4, x)], 1); 00061 const byte t6 = rotate_left(SBOX[get_byte(5, x)], 7); 00062 const byte t7 = SBOX[rotate_left(get_byte(6, x), 1)]; 00063 const byte t8 = SBOX[get_byte(7, x)]; 00064 00065 const byte y1 = t1 ^ t3 ^ t4 ^ t6 ^ t7 ^ t8; 00066 const byte y2 = t1 ^ t2 ^ t4 ^ t5 ^ t7 ^ t8; 00067 const byte y3 = t1 ^ t2 ^ t3 ^ t5 ^ t6 ^ t8; 00068 const byte y4 = t2 ^ t3 ^ t4 ^ t5 ^ t6 ^ t7; 00069 const byte y5 = t1 ^ t2 ^ t6 ^ t7 ^ t8; 00070 const byte y6 = t2 ^ t3 ^ t5 ^ t7 ^ t8; 00071 const byte y7 = t3 ^ t4 ^ t5 ^ t6 ^ t8; 00072 const byte y8 = t1 ^ t4 ^ t5 ^ t6 ^ t7; 00073 00074 return make_u64bit(y1, y2, y3, y4, y5, y6, y7, y8); 00075 } 00076 00077 inline u64bit F(u64bit v, u64bit K) 00078 { 00079 const u64bit x = v ^ K; 00080 00081 return Camellia_SBOX1[get_byte(0, x)] ^ 00082 Camellia_SBOX2[get_byte(1, x)] ^ 00083 Camellia_SBOX3[get_byte(2, x)] ^ 00084 Camellia_SBOX4[get_byte(3, x)] ^ 00085 Camellia_SBOX5[get_byte(4, x)] ^ 00086 Camellia_SBOX6[get_byte(5, x)] ^ 00087 Camellia_SBOX7[get_byte(6, x)] ^ 00088 Camellia_SBOX8[get_byte(7, x)]; 00089 } 00090 00091 inline u64bit FL(u64bit v, u64bit K) 00092 { 00093 u32bit x1 = (v >> 32); 00094 u32bit x2 = (v & 0xFFFFFFFF); 00095 00096 const u32bit k1 = (K >> 32); 00097 const u32bit k2 = (K & 0xFFFFFFFF); 00098 00099 x2 ^= rotate_left(x1 & k1, 1); 00100 x1 ^= (x2 | k2); 00101 00102 return ((static_cast<u64bit>(x1) << 32) | x2); 00103 } 00104 00105 inline u64bit FLINV(u64bit v, u64bit K) 00106 { 00107 u32bit x1 = (v >> 32); 00108 u32bit x2 = (v & 0xFFFFFFFF); 00109 00110 const u32bit k1 = (K >> 32); 00111 const u32bit k2 = (K & 0xFFFFFFFF); 00112 00113 x1 ^= (x2 | k2); 00114 x2 ^= rotate_left(x1 & k1, 1); 00115 00116 return ((static_cast<u64bit>(x1) << 32) | x2); 00117 } 00118 00119 /* 00120 * Camellia Encryption 00121 */ 00122 void encrypt(const byte in[], byte out[], size_t blocks, 00123 const secure_vector<u64bit>& SK, const size_t rounds) 00124 { 00125 for(size_t i = 0; i != blocks; ++i) 00126 { 00127 u64bit D1 = load_be<u64bit>(in, 0); 00128 u64bit D2 = load_be<u64bit>(in, 1); 00129 00130 const u64bit* K = &SK[0]; 00131 00132 D1 ^= *K++; 00133 D2 ^= *K++; 00134 00135 D2 ^= F_SLOW(D1, *K++); 00136 D1 ^= F_SLOW(D2, *K++); 00137 00138 for(size_t r = 1; r != rounds - 1; ++r) 00139 { 00140 if(r % 3 == 0) 00141 { 00142 D1 = FL (D1, *K++); 00143 D2 = FLINV(D2, *K++); 00144 } 00145 00146 D2 ^= F(D1, *K++); 00147 D1 ^= F(D2, *K++); 00148 } 00149 00150 D2 ^= F_SLOW(D1, *K++); 00151 D1 ^= F_SLOW(D2, *K++); 00152 00153 D2 ^= *K++; 00154 D1 ^= *K++; 00155 00156 store_be(out, D2, D1); 00157 00158 in += 16; 00159 out += 16; 00160 } 00161 } 00162 00163 /* 00164 * Camellia Decryption 00165 */ 00166 void decrypt(const byte in[], byte out[], size_t blocks, 00167 const secure_vector<u64bit>& SK, const size_t rounds) 00168 { 00169 for(size_t i = 0; i != blocks; ++i) 00170 { 00171 u64bit D1 = load_be<u64bit>(in, 0); 00172 u64bit D2 = load_be<u64bit>(in, 1); 00173 00174 const u64bit* K = &SK[SK.size()-1]; 00175 00176 D2 ^= *K--; 00177 D1 ^= *K--; 00178 00179 D2 ^= F_SLOW(D1, *K--); 00180 D1 ^= F_SLOW(D2, *K--); 00181 00182 for(size_t r = 1; r != rounds - 1; ++r) 00183 { 00184 if(r % 3 == 0) 00185 { 00186 D1 = FL (D1, *K--); 00187 D2 = FLINV(D2, *K--); 00188 } 00189 00190 D2 ^= F(D1, *K--); 00191 D1 ^= F(D2, *K--); 00192 } 00193 00194 D2 ^= F_SLOW(D1, *K--); 00195 D1 ^= F_SLOW(D2, *K--); 00196 00197 D1 ^= *K--; 00198 D2 ^= *K; 00199 00200 store_be(out, D2, D1); 00201 00202 in += 16; 00203 out += 16; 00204 } 00205 } 00206 00207 u64bit left_rot_hi(u64bit h, u64bit l, size_t shift) 00208 { 00209 return (h << shift) | ((l >> (64-shift))); 00210 } 00211 00212 u64bit left_rot_lo(u64bit h, u64bit l, size_t shift) 00213 { 00214 return (h >> (64-shift)) | (l << shift); 00215 } 00216 00217 /* 00218 * Camellia Key Schedule 00219 */ 00220 void key_schedule(secure_vector<u64bit>& SK, const byte key[], size_t length) 00221 { 00222 const u64bit Sigma1 = 0xA09E667F3BCC908B; 00223 const u64bit Sigma2 = 0xB67AE8584CAA73B2; 00224 const u64bit Sigma3 = 0xC6EF372FE94F82BE; 00225 const u64bit Sigma4 = 0x54FF53A5F1D36F1C; 00226 const u64bit Sigma5 = 0x10E527FADE682D1D; 00227 const u64bit Sigma6 = 0xB05688C2B3E6C1FD; 00228 00229 const u64bit KL_H = load_be<u64bit>(key, 0); 00230 const u64bit KL_L = load_be<u64bit>(key, 1); 00231 00232 const u64bit KR_H = (length >= 24) ? load_be<u64bit>(key, 2) : 0; 00233 const u64bit KR_L = 00234 (length == 32) ? load_be<u64bit>(key, 3) : ((length == 24) ? ~KR_H : 0); 00235 00236 u64bit D1 = KL_H ^ KR_H; 00237 u64bit D2 = KL_L ^ KR_L; 00238 D2 ^= F(D1, Sigma1); 00239 D1 ^= F(D2, Sigma2); 00240 D1 ^= KL_H; 00241 D2 ^= KL_L; 00242 D2 ^= F(D1, Sigma3); 00243 D1 ^= F(D2, Sigma4); 00244 00245 const u64bit KA_H = D1; 00246 const u64bit KA_L = D2; 00247 00248 D1 = KA_H ^ KR_H; 00249 D2 = KA_L ^ KR_L; 00250 D2 ^= F(D1, Sigma5); 00251 D1 ^= F(D2, Sigma6); 00252 00253 const u64bit KB_H = D1; 00254 const u64bit KB_L = D2; 00255 00256 if(length == 16) 00257 { 00258 SK.resize(26); 00259 00260 SK[ 0] = KL_H; 00261 SK[ 1] = KL_L; 00262 SK[ 2] = KA_H; 00263 SK[ 3] = KA_L; 00264 SK[ 4] = left_rot_hi(KL_H, KL_L, 15); 00265 SK[ 5] = left_rot_lo(KL_H, KL_L, 15); 00266 SK[ 6] = left_rot_hi(KA_H, KA_L, 15); 00267 SK[ 7] = left_rot_lo(KA_H, KA_L, 15); 00268 SK[ 8] = left_rot_hi(KA_H, KA_L, 30); 00269 SK[ 9] = left_rot_lo(KA_H, KA_L, 30); 00270 SK[10] = left_rot_hi(KL_H, KL_L, 45); 00271 SK[11] = left_rot_lo(KL_H, KL_L, 45); 00272 SK[12] = left_rot_hi(KA_H, KA_L, 45); 00273 SK[13] = left_rot_lo(KL_H, KL_L, 60); 00274 SK[14] = left_rot_hi(KA_H, KA_L, 60); 00275 SK[15] = left_rot_lo(KA_H, KA_L, 60); 00276 SK[16] = left_rot_lo(KL_H, KL_L, 77-64); 00277 SK[17] = left_rot_hi(KL_H, KL_L, 77-64); 00278 SK[18] = left_rot_lo(KL_H, KL_L, 94-64); 00279 SK[19] = left_rot_hi(KL_H, KL_L, 94-64); 00280 SK[20] = left_rot_lo(KA_H, KA_L, 94-64); 00281 SK[21] = left_rot_hi(KA_H, KA_L, 94-64); 00282 SK[22] = left_rot_lo(KL_H, KL_L, 111-64); 00283 SK[23] = left_rot_hi(KL_H, KL_L, 111-64); 00284 SK[24] = left_rot_lo(KA_H, KA_L, 111-64); 00285 SK[25] = left_rot_hi(KA_H, KA_L, 111-64); 00286 } 00287 else 00288 { 00289 SK.resize(34); 00290 00291 SK[ 0] = KL_H; 00292 SK[ 1] = KL_L; 00293 SK[ 2] = KB_H; 00294 SK[ 3] = KB_L; 00295 00296 SK[ 4] = left_rot_hi(KR_H, KR_L, 15); 00297 SK[ 5] = left_rot_lo(KR_H, KR_L, 15); 00298 SK[ 6] = left_rot_hi(KA_H, KA_L, 15); 00299 SK[ 7] = left_rot_lo(KA_H, KA_L, 15); 00300 00301 SK[ 8] = left_rot_hi(KR_H, KR_L, 30); 00302 SK[ 9] = left_rot_lo(KR_H, KR_L, 30); 00303 SK[10] = left_rot_hi(KB_H, KB_L, 30); 00304 SK[11] = left_rot_lo(KB_H, KB_L, 30); 00305 00306 SK[12] = left_rot_hi(KL_H, KL_L, 45); 00307 SK[13] = left_rot_lo(KL_H, KL_L, 45); 00308 SK[14] = left_rot_hi(KA_H, KA_L, 45); 00309 SK[15] = left_rot_lo(KA_H, KA_L, 45); 00310 00311 SK[16] = left_rot_hi(KL_H, KL_L, 60); 00312 SK[17] = left_rot_lo(KL_H, KL_L, 60); 00313 SK[18] = left_rot_hi(KR_H, KR_L, 60); 00314 SK[19] = left_rot_lo(KR_H, KR_L, 60); 00315 SK[20] = left_rot_hi(KB_H, KB_L, 60); 00316 SK[21] = left_rot_lo(KB_H, KB_L, 60); 00317 00318 SK[22] = left_rot_lo(KL_H, KL_L, 77-64); 00319 SK[23] = left_rot_hi(KL_H, KL_L, 77-64); 00320 SK[24] = left_rot_lo(KA_H, KA_L, 77-64); 00321 SK[25] = left_rot_hi(KA_H, KA_L, 77-64); 00322 00323 SK[26] = left_rot_lo(KR_H, KR_L, 94-64); 00324 SK[27] = left_rot_hi(KR_H, KR_L, 94-64); 00325 SK[28] = left_rot_lo(KA_H, KA_L, 94-64); 00326 SK[29] = left_rot_hi(KA_H, KA_L, 94-64); 00327 SK[30] = left_rot_lo(KL_H, KL_L, 111-64); 00328 SK[31] = left_rot_hi(KL_H, KL_L, 111-64); 00329 SK[32] = left_rot_lo(KB_H, KB_L, 111-64); 00330 SK[33] = left_rot_hi(KB_H, KB_L, 111-64); 00331 } 00332 } 00333 00334 } 00335 00336 } 00337 00338 void Camellia_128::encrypt_n(const byte in[], byte out[], size_t blocks) const 00339 { 00340 Camellia_F::encrypt(in, out, blocks, SK, 9); 00341 } 00342 00343 void Camellia_192::encrypt_n(const byte in[], byte out[], size_t blocks) const 00344 { 00345 Camellia_F::encrypt(in, out, blocks, SK, 12); 00346 } 00347 00348 void Camellia_256::encrypt_n(const byte in[], byte out[], size_t blocks) const 00349 { 00350 Camellia_F::encrypt(in, out, blocks, SK, 12); 00351 } 00352 00353 void Camellia_128::decrypt_n(const byte in[], byte out[], size_t blocks) const 00354 { 00355 Camellia_F::decrypt(in, out, blocks, SK, 9); 00356 } 00357 00358 void Camellia_192::decrypt_n(const byte in[], byte out[], size_t blocks) const 00359 { 00360 Camellia_F::decrypt(in, out, blocks, SK, 12); 00361 } 00362 00363 void Camellia_256::decrypt_n(const byte in[], byte out[], size_t blocks) const 00364 { 00365 Camellia_F::decrypt(in, out, blocks, SK, 12); 00366 } 00367 00368 void Camellia_128::key_schedule(const byte key[], size_t length) 00369 { 00370 Camellia_F::key_schedule(SK, key, length); 00371 } 00372 00373 void Camellia_192::key_schedule(const byte key[], size_t length) 00374 { 00375 Camellia_F::key_schedule(SK, key, length); 00376 } 00377 00378 void Camellia_256::key_schedule(const byte key[], size_t length) 00379 { 00380 Camellia_F::key_schedule(SK, key, length); 00381 } 00382 00383 void Camellia_128::clear() 00384 { 00385 zap(SK); 00386 } 00387 00388 void Camellia_192::clear() 00389 { 00390 zap(SK); 00391 } 00392 00393 void Camellia_256::clear() 00394 { 00395 zap(SK); 00396 } 00397 00398 }