Botan  1.11.15
src/lib/block/camellia/camellia.cpp
Go to the documentation of this file.
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 }