Botan
1.11.15
|
00001 /* 00002 * KASUMI 00003 * (C) 1999-2007 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/kasumi.h> 00010 00011 namespace Botan { 00012 00013 BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(KASUMI); 00014 00015 namespace { 00016 00017 /* 00018 * KASUMI S-Boxes 00019 */ 00020 const byte KASUMI_SBOX_S7[128] = { 00021 0x36, 0x32, 0x3E, 0x38, 0x16, 0x22, 0x5E, 0x60, 0x26, 0x06, 0x3F, 0x5D, 00022 0x02, 0x12, 0x7B, 0x21, 0x37, 0x71, 0x27, 0x72, 0x15, 0x43, 0x41, 0x0C, 00023 0x2F, 0x49, 0x2E, 0x1B, 0x19, 0x6F, 0x7C, 0x51, 0x35, 0x09, 0x79, 0x4F, 00024 0x34, 0x3C, 0x3A, 0x30, 0x65, 0x7F, 0x28, 0x78, 0x68, 0x46, 0x47, 0x2B, 00025 0x14, 0x7A, 0x48, 0x3D, 0x17, 0x6D, 0x0D, 0x64, 0x4D, 0x01, 0x10, 0x07, 00026 0x52, 0x0A, 0x69, 0x62, 0x75, 0x74, 0x4C, 0x0B, 0x59, 0x6A, 0x00, 0x7D, 00027 0x76, 0x63, 0x56, 0x45, 0x1E, 0x39, 0x7E, 0x57, 0x70, 0x33, 0x11, 0x05, 00028 0x5F, 0x0E, 0x5A, 0x54, 0x5B, 0x08, 0x23, 0x67, 0x20, 0x61, 0x1C, 0x42, 00029 0x66, 0x1F, 0x1A, 0x2D, 0x4B, 0x04, 0x55, 0x5C, 0x25, 0x4A, 0x50, 0x31, 00030 0x44, 0x1D, 0x73, 0x2C, 0x40, 0x6B, 0x6C, 0x18, 0x6E, 0x53, 0x24, 0x4E, 00031 0x2A, 0x13, 0x0F, 0x29, 0x58, 0x77, 0x3B, 0x03 }; 00032 00033 const u16bit KASUMI_SBOX_S9[512] = { 00034 0x00A7, 0x00EF, 0x00A1, 0x017B, 0x0187, 0x014E, 0x0009, 0x0152, 0x0026, 00035 0x00E2, 0x0030, 0x0166, 0x01C4, 0x0181, 0x005A, 0x018D, 0x00B7, 0x00FD, 00036 0x0093, 0x014B, 0x019F, 0x0154, 0x0033, 0x016A, 0x0132, 0x01F4, 0x0106, 00037 0x0052, 0x00D8, 0x009F, 0x0164, 0x00B1, 0x00AF, 0x00F1, 0x01E9, 0x0025, 00038 0x00CE, 0x0011, 0x0000, 0x014D, 0x002C, 0x00FE, 0x017A, 0x003A, 0x008F, 00039 0x00DC, 0x0051, 0x0190, 0x005F, 0x0003, 0x013B, 0x00F5, 0x0036, 0x00EB, 00040 0x00DA, 0x0195, 0x01D8, 0x0108, 0x00AC, 0x01EE, 0x0173, 0x0122, 0x018F, 00041 0x004C, 0x00A5, 0x00C5, 0x018B, 0x0079, 0x0101, 0x01E0, 0x01A7, 0x00D4, 00042 0x00F0, 0x001C, 0x01CE, 0x00B0, 0x0196, 0x01FB, 0x0120, 0x00DF, 0x01F5, 00043 0x0197, 0x00F9, 0x0109, 0x0059, 0x00BA, 0x00DD, 0x01AC, 0x00A4, 0x004A, 00044 0x01B8, 0x00C4, 0x01CA, 0x01A5, 0x015E, 0x00A3, 0x00E8, 0x009E, 0x0086, 00045 0x0162, 0x000D, 0x00FA, 0x01EB, 0x008E, 0x00BF, 0x0045, 0x00C1, 0x01A9, 00046 0x0098, 0x00E3, 0x016E, 0x0087, 0x0158, 0x012C, 0x0114, 0x00F2, 0x01B5, 00047 0x0140, 0x0071, 0x0116, 0x000B, 0x00F3, 0x0057, 0x013D, 0x0024, 0x005D, 00048 0x01F0, 0x001B, 0x01E7, 0x01BE, 0x01E2, 0x0029, 0x0044, 0x009C, 0x01C9, 00049 0x0083, 0x0146, 0x0193, 0x0153, 0x0014, 0x0027, 0x0073, 0x01BA, 0x007C, 00050 0x01DB, 0x0180, 0x01FC, 0x0035, 0x0070, 0x00AA, 0x01DF, 0x0097, 0x007E, 00051 0x00A9, 0x0049, 0x010C, 0x0117, 0x0141, 0x00A8, 0x016C, 0x016B, 0x0124, 00052 0x002E, 0x01F3, 0x0189, 0x0147, 0x0144, 0x0018, 0x01C8, 0x010B, 0x009D, 00053 0x01CC, 0x01E8, 0x01AA, 0x0135, 0x00E5, 0x01B7, 0x01FA, 0x00D0, 0x010F, 00054 0x015D, 0x0191, 0x01B2, 0x00EC, 0x0010, 0x00D1, 0x0167, 0x0034, 0x0038, 00055 0x0078, 0x00C7, 0x0115, 0x01D1, 0x01A0, 0x00FC, 0x011F, 0x00F6, 0x0006, 00056 0x0053, 0x0131, 0x01A4, 0x0159, 0x0099, 0x01F6, 0x0041, 0x003D, 0x00F4, 00057 0x011A, 0x00AD, 0x00DE, 0x01A2, 0x0043, 0x0182, 0x0170, 0x0105, 0x0065, 00058 0x01DC, 0x0123, 0x00C3, 0x01AE, 0x0031, 0x004F, 0x00A6, 0x014A, 0x0118, 00059 0x017F, 0x0175, 0x0080, 0x017E, 0x0198, 0x009B, 0x01EF, 0x016F, 0x0184, 00060 0x0112, 0x006B, 0x01CB, 0x01A1, 0x003E, 0x01C6, 0x0084, 0x00E1, 0x00CB, 00061 0x013C, 0x00EA, 0x000E, 0x012D, 0x005B, 0x01F7, 0x011E, 0x01A8, 0x00D3, 00062 0x015B, 0x0133, 0x008C, 0x0176, 0x0023, 0x0067, 0x007D, 0x01AB, 0x0013, 00063 0x00D6, 0x01C5, 0x0092, 0x01F2, 0x013A, 0x01BC, 0x00E6, 0x0100, 0x0149, 00064 0x00C6, 0x011D, 0x0032, 0x0074, 0x004E, 0x019A, 0x000A, 0x00CD, 0x01FE, 00065 0x00AB, 0x00E7, 0x002D, 0x008B, 0x01D3, 0x001D, 0x0056, 0x01F9, 0x0020, 00066 0x0048, 0x001A, 0x0156, 0x0096, 0x0139, 0x01EA, 0x01AF, 0x00EE, 0x019B, 00067 0x0145, 0x0095, 0x01D9, 0x0028, 0x0077, 0x00AE, 0x0163, 0x00B9, 0x00E9, 00068 0x0185, 0x0047, 0x01C0, 0x0111, 0x0174, 0x0037, 0x006E, 0x00B2, 0x0142, 00069 0x000C, 0x01D5, 0x0188, 0x0171, 0x00BE, 0x0001, 0x006D, 0x0177, 0x0089, 00070 0x00B5, 0x0058, 0x004B, 0x0134, 0x0104, 0x01E4, 0x0062, 0x0110, 0x0172, 00071 0x0113, 0x019C, 0x006F, 0x0150, 0x013E, 0x0004, 0x01F8, 0x01EC, 0x0103, 00072 0x0130, 0x004D, 0x0151, 0x01B3, 0x0015, 0x0165, 0x012F, 0x014C, 0x01E3, 00073 0x0012, 0x002F, 0x0055, 0x0019, 0x01F1, 0x01DA, 0x0121, 0x0064, 0x010D, 00074 0x0128, 0x01DE, 0x010E, 0x006A, 0x001F, 0x0068, 0x01B1, 0x0054, 0x019E, 00075 0x01E6, 0x018A, 0x0060, 0x0063, 0x009A, 0x01FF, 0x0094, 0x019D, 0x0169, 00076 0x0199, 0x00FF, 0x00A2, 0x00D7, 0x012E, 0x00C9, 0x010A, 0x015F, 0x0157, 00077 0x0090, 0x01B9, 0x016D, 0x006C, 0x012A, 0x00FB, 0x0022, 0x00B6, 0x01FD, 00078 0x008A, 0x00D2, 0x014F, 0x0085, 0x0137, 0x0160, 0x0148, 0x008D, 0x018C, 00079 0x015A, 0x007B, 0x013F, 0x01C2, 0x0119, 0x01AD, 0x00E4, 0x01BB, 0x01E1, 00080 0x005C, 0x0194, 0x01E5, 0x01A6, 0x00F8, 0x0129, 0x0017, 0x00D5, 0x0082, 00081 0x01D2, 0x0016, 0x00D9, 0x011B, 0x0046, 0x0126, 0x0168, 0x01A3, 0x007F, 00082 0x0138, 0x0179, 0x0007, 0x01D4, 0x00C2, 0x0002, 0x0075, 0x0127, 0x01CF, 00083 0x0102, 0x00E0, 0x01BF, 0x00F7, 0x00BB, 0x0050, 0x018E, 0x011C, 0x0161, 00084 0x0069, 0x0186, 0x012B, 0x01D7, 0x01D6, 0x00B8, 0x0039, 0x00C8, 0x015C, 00085 0x003F, 0x00CC, 0x00BC, 0x0021, 0x01C3, 0x0061, 0x001E, 0x0136, 0x00DB, 00086 0x005E, 0x00A0, 0x0081, 0x01ED, 0x0040, 0x00B3, 0x0107, 0x0066, 0x00BD, 00087 0x00CF, 0x0072, 0x0192, 0x01B6, 0x01DD, 0x0183, 0x007A, 0x00C0, 0x002A, 00088 0x017D, 0x0005, 0x0091, 0x0076, 0x00B4, 0x01C1, 0x0125, 0x0143, 0x0088, 00089 0x017C, 0x002B, 0x0042, 0x003C, 0x01C7, 0x0155, 0x01BD, 0x00CA, 0x01B0, 00090 0x0008, 0x00ED, 0x000F, 0x0178, 0x01B4, 0x01D0, 0x003B, 0x01CD }; 00091 00092 /* 00093 * KASUMI FI Function 00094 */ 00095 u16bit FI(u16bit I, u16bit K) 00096 { 00097 u16bit D9 = (I >> 7); 00098 byte D7 = (I & 0x7F); 00099 D9 = KASUMI_SBOX_S9[D9] ^ D7; 00100 D7 = KASUMI_SBOX_S7[D7] ^ (D9 & 0x7F); 00101 00102 D7 ^= (K >> 9); 00103 D9 = KASUMI_SBOX_S9[D9 ^ (K & 0x1FF)] ^ D7; 00104 D7 = KASUMI_SBOX_S7[D7] ^ (D9 & 0x7F); 00105 return (D7 << 9) | D9; 00106 } 00107 00108 } 00109 00110 /* 00111 * KASUMI Encryption 00112 */ 00113 void KASUMI::encrypt_n(const byte in[], byte out[], size_t blocks) const 00114 { 00115 for(size_t i = 0; i != blocks; ++i) 00116 { 00117 u16bit B0 = load_be<u16bit>(in, 0); 00118 u16bit B1 = load_be<u16bit>(in, 1); 00119 u16bit B2 = load_be<u16bit>(in, 2); 00120 u16bit B3 = load_be<u16bit>(in, 3); 00121 00122 for(size_t j = 0; j != 8; j += 2) 00123 { 00124 const u16bit* K = &EK[8*j]; 00125 00126 u16bit R = B1 ^ (rotate_left(B0, 1) & K[0]); 00127 u16bit L = B0 ^ (rotate_left(R, 1) | K[1]); 00128 00129 L = FI(L ^ K[ 2], K[ 3]) ^ R; 00130 R = FI(R ^ K[ 4], K[ 5]) ^ L; 00131 L = FI(L ^ K[ 6], K[ 7]) ^ R; 00132 00133 R = B2 ^= R; 00134 L = B3 ^= L; 00135 00136 R = FI(R ^ K[10], K[11]) ^ L; 00137 L = FI(L ^ K[12], K[13]) ^ R; 00138 R = FI(R ^ K[14], K[15]) ^ L; 00139 00140 R ^= (rotate_left(L, 1) & K[8]); 00141 L ^= (rotate_left(R, 1) | K[9]); 00142 00143 B0 ^= L; 00144 B1 ^= R; 00145 } 00146 00147 store_be(out, B0, B1, B2, B3); 00148 00149 in += BLOCK_SIZE; 00150 out += BLOCK_SIZE; 00151 } 00152 } 00153 00154 /* 00155 * KASUMI Decryption 00156 */ 00157 void KASUMI::decrypt_n(const byte in[], byte out[], size_t blocks) const 00158 { 00159 for(size_t i = 0; i != blocks; ++i) 00160 { 00161 u16bit B0 = load_be<u16bit>(in, 0); 00162 u16bit B1 = load_be<u16bit>(in, 1); 00163 u16bit B2 = load_be<u16bit>(in, 2); 00164 u16bit B3 = load_be<u16bit>(in, 3); 00165 00166 for(size_t j = 0; j != 8; j += 2) 00167 { 00168 const u16bit* K = &EK[8*(6-j)]; 00169 00170 u16bit L = B2, R = B3; 00171 00172 L = FI(L ^ K[10], K[11]) ^ R; 00173 R = FI(R ^ K[12], K[13]) ^ L; 00174 L = FI(L ^ K[14], K[15]) ^ R; 00175 00176 L ^= (rotate_left(R, 1) & K[8]); 00177 R ^= (rotate_left(L, 1) | K[9]); 00178 00179 R = B0 ^= R; 00180 L = B1 ^= L; 00181 00182 L ^= (rotate_left(R, 1) & K[0]); 00183 R ^= (rotate_left(L, 1) | K[1]); 00184 00185 R = FI(R ^ K[2], K[3]) ^ L; 00186 L = FI(L ^ K[4], K[5]) ^ R; 00187 R = FI(R ^ K[6], K[7]) ^ L; 00188 00189 B2 ^= L; 00190 B3 ^= R; 00191 } 00192 00193 store_be(out, B0, B1, B2, B3); 00194 00195 in += BLOCK_SIZE; 00196 out += BLOCK_SIZE; 00197 } 00198 } 00199 00200 /* 00201 * KASUMI Key Schedule 00202 */ 00203 void KASUMI::key_schedule(const byte key[], size_t) 00204 { 00205 static const u16bit RC[] = { 0x0123, 0x4567, 0x89AB, 0xCDEF, 00206 0xFEDC, 0xBA98, 0x7654, 0x3210 }; 00207 00208 secure_vector<u16bit> K(16); 00209 for(size_t i = 0; i != 8; ++i) 00210 { 00211 K[i] = load_be<u16bit>(key, i); 00212 K[i+8] = K[i] ^ RC[i]; 00213 } 00214 00215 EK.resize(64); 00216 00217 for(size_t i = 0; i != 8; ++i) 00218 { 00219 EK[8*i ] = rotate_left(K[(i+0) % 8 ], 2); 00220 EK[8*i+1] = rotate_left(K[(i+2) % 8 + 8], 1); 00221 EK[8*i+2] = rotate_left(K[(i+1) % 8 ], 5); 00222 EK[8*i+3] = K[(i+4) % 8 + 8]; 00223 EK[8*i+4] = rotate_left(K[(i+5) % 8 ], 8); 00224 EK[8*i+5] = K[(i+3) % 8 + 8]; 00225 EK[8*i+6] = rotate_left(K[(i+6) % 8 ], 13); 00226 EK[8*i+7] = K[(i+7) % 8 + 8]; 00227 } 00228 } 00229 00230 void KASUMI::clear() 00231 { 00232 zap(EK); 00233 } 00234 00235 }