1 /*
2 * MISTY1
3 * (C) 1999-2009 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/misty1.h>
9 #include <botan/loadstor.h>
10 
11 namespace Botan {
12 
13 namespace {
14 
15 alignas(64) static const uint8_t MISTY1_SBOX_S7[128] = {
16    0x1B, 0x32, 0x33, 0x5A, 0x3B, 0x10, 0x17, 0x54, 0x5B, 0x1A, 0x72, 0x73,
17    0x6B, 0x2C, 0x66, 0x49, 0x1F, 0x24, 0x13, 0x6C, 0x37, 0x2E, 0x3F, 0x4A,
18    0x5D, 0x0F, 0x40, 0x56, 0x25, 0x51, 0x1C, 0x04, 0x0B, 0x46, 0x20, 0x0D,
19    0x7B, 0x35, 0x44, 0x42, 0x2B, 0x1E, 0x41, 0x14, 0x4B, 0x79, 0x15, 0x6F,
20    0x0E, 0x55, 0x09, 0x36, 0x74, 0x0C, 0x67, 0x53, 0x28, 0x0A, 0x7E, 0x38,
21    0x02, 0x07, 0x60, 0x29, 0x19, 0x12, 0x65, 0x2F, 0x30, 0x39, 0x08, 0x68,
22    0x5F, 0x78, 0x2A, 0x4C, 0x64, 0x45, 0x75, 0x3D, 0x59, 0x48, 0x03, 0x57,
23    0x7C, 0x4F, 0x62, 0x3C, 0x1D, 0x21, 0x5E, 0x27, 0x6A, 0x70, 0x4D, 0x3A,
24    0x01, 0x6D, 0x6E, 0x63, 0x18, 0x77, 0x23, 0x05, 0x26, 0x76, 0x00, 0x31,
25    0x2D, 0x7A, 0x7F, 0x61, 0x50, 0x22, 0x11, 0x06, 0x47, 0x16, 0x52, 0x4E,
26    0x71, 0x3E, 0x69, 0x43, 0x34, 0x5C, 0x58, 0x7D };
27 
28 alignas(64) static const uint16_t MISTY1_SBOX_S9[512] = {
29    0x01C3, 0x00CB, 0x0153, 0x019F, 0x01E3, 0x00E9, 0x00FB, 0x0035, 0x0181,
30    0x00B9, 0x0117, 0x01EB, 0x0133, 0x0009, 0x002D, 0x00D3, 0x00C7, 0x014A,
31    0x0037, 0x007E, 0x00EB, 0x0164, 0x0193, 0x01D8, 0x00A3, 0x011E, 0x0055,
32    0x002C, 0x001D, 0x01A2, 0x0163, 0x0118, 0x014B, 0x0152, 0x01D2, 0x000F,
33    0x002B, 0x0030, 0x013A, 0x00E5, 0x0111, 0x0138, 0x018E, 0x0063, 0x00E3,
34    0x00C8, 0x01F4, 0x001B, 0x0001, 0x009D, 0x00F8, 0x01A0, 0x016D, 0x01F3,
35    0x001C, 0x0146, 0x007D, 0x00D1, 0x0082, 0x01EA, 0x0183, 0x012D, 0x00F4,
36    0x019E, 0x01D3, 0x00DD, 0x01E2, 0x0128, 0x01E0, 0x00EC, 0x0059, 0x0091,
37    0x0011, 0x012F, 0x0026, 0x00DC, 0x00B0, 0x018C, 0x010F, 0x01F7, 0x00E7,
38    0x016C, 0x00B6, 0x00F9, 0x00D8, 0x0151, 0x0101, 0x014C, 0x0103, 0x00B8,
39    0x0154, 0x012B, 0x01AE, 0x0017, 0x0071, 0x000C, 0x0047, 0x0058, 0x007F,
40    0x01A4, 0x0134, 0x0129, 0x0084, 0x015D, 0x019D, 0x01B2, 0x01A3, 0x0048,
41    0x007C, 0x0051, 0x01CA, 0x0023, 0x013D, 0x01A7, 0x0165, 0x003B, 0x0042,
42    0x00DA, 0x0192, 0x00CE, 0x00C1, 0x006B, 0x009F, 0x01F1, 0x012C, 0x0184,
43    0x00FA, 0x0196, 0x01E1, 0x0169, 0x017D, 0x0031, 0x0180, 0x010A, 0x0094,
44    0x01DA, 0x0186, 0x013E, 0x011C, 0x0060, 0x0175, 0x01CF, 0x0067, 0x0119,
45    0x0065, 0x0068, 0x0099, 0x0150, 0x0008, 0x0007, 0x017C, 0x00B7, 0x0024,
46    0x0019, 0x00DE, 0x0127, 0x00DB, 0x00E4, 0x01A9, 0x0052, 0x0109, 0x0090,
47    0x019C, 0x01C1, 0x0028, 0x01B3, 0x0135, 0x016A, 0x0176, 0x00DF, 0x01E5,
48    0x0188, 0x00C5, 0x016E, 0x01DE, 0x01B1, 0x00C3, 0x01DF, 0x0036, 0x00EE,
49    0x01EE, 0x00F0, 0x0093, 0x0049, 0x009A, 0x01B6, 0x0069, 0x0081, 0x0125,
50    0x000B, 0x005E, 0x00B4, 0x0149, 0x01C7, 0x0174, 0x003E, 0x013B, 0x01B7,
51    0x008E, 0x01C6, 0x00AE, 0x0010, 0x0095, 0x01EF, 0x004E, 0x00F2, 0x01FD,
52    0x0085, 0x00FD, 0x00F6, 0x00A0, 0x016F, 0x0083, 0x008A, 0x0156, 0x009B,
53    0x013C, 0x0107, 0x0167, 0x0098, 0x01D0, 0x01E9, 0x0003, 0x01FE, 0x00BD,
54    0x0122, 0x0089, 0x00D2, 0x018F, 0x0012, 0x0033, 0x006A, 0x0142, 0x00ED,
55    0x0170, 0x011B, 0x00E2, 0x014F, 0x0158, 0x0131, 0x0147, 0x005D, 0x0113,
56    0x01CD, 0x0079, 0x0161, 0x01A5, 0x0179, 0x009E, 0x01B4, 0x00CC, 0x0022,
57    0x0132, 0x001A, 0x00E8, 0x0004, 0x0187, 0x01ED, 0x0197, 0x0039, 0x01BF,
58    0x01D7, 0x0027, 0x018B, 0x00C6, 0x009C, 0x00D0, 0x014E, 0x006C, 0x0034,
59    0x01F2, 0x006E, 0x00CA, 0x0025, 0x00BA, 0x0191, 0x00FE, 0x0013, 0x0106,
60    0x002F, 0x01AD, 0x0172, 0x01DB, 0x00C0, 0x010B, 0x01D6, 0x00F5, 0x01EC,
61    0x010D, 0x0076, 0x0114, 0x01AB, 0x0075, 0x010C, 0x01E4, 0x0159, 0x0054,
62    0x011F, 0x004B, 0x00C4, 0x01BE, 0x00F7, 0x0029, 0x00A4, 0x000E, 0x01F0,
63    0x0077, 0x004D, 0x017A, 0x0086, 0x008B, 0x00B3, 0x0171, 0x00BF, 0x010E,
64    0x0104, 0x0097, 0x015B, 0x0160, 0x0168, 0x00D7, 0x00BB, 0x0066, 0x01CE,
65    0x00FC, 0x0092, 0x01C5, 0x006F, 0x0016, 0x004A, 0x00A1, 0x0139, 0x00AF,
66    0x00F1, 0x0190, 0x000A, 0x01AA, 0x0143, 0x017B, 0x0056, 0x018D, 0x0166,
67    0x00D4, 0x01FB, 0x014D, 0x0194, 0x019A, 0x0087, 0x01F8, 0x0123, 0x00A7,
68    0x01B8, 0x0141, 0x003C, 0x01F9, 0x0140, 0x002A, 0x0155, 0x011A, 0x01A1,
69    0x0198, 0x00D5, 0x0126, 0x01AF, 0x0061, 0x012E, 0x0157, 0x01DC, 0x0072,
70    0x018A, 0x00AA, 0x0096, 0x0115, 0x00EF, 0x0045, 0x007B, 0x008D, 0x0145,
71    0x0053, 0x005F, 0x0178, 0x00B2, 0x002E, 0x0020, 0x01D5, 0x003F, 0x01C9,
72    0x01E7, 0x01AC, 0x0044, 0x0038, 0x0014, 0x00B1, 0x016B, 0x00AB, 0x00B5,
73    0x005A, 0x0182, 0x01C8, 0x01D4, 0x0018, 0x0177, 0x0064, 0x00CF, 0x006D,
74    0x0100, 0x0199, 0x0130, 0x015A, 0x0005, 0x0120, 0x01BB, 0x01BD, 0x00E0,
75    0x004F, 0x00D6, 0x013F, 0x01C4, 0x012A, 0x0015, 0x0006, 0x00FF, 0x019B,
76    0x00A6, 0x0043, 0x0088, 0x0050, 0x015F, 0x01E8, 0x0121, 0x0073, 0x017E,
77    0x00BC, 0x00C2, 0x00C9, 0x0173, 0x0189, 0x01F5, 0x0074, 0x01CC, 0x01E6,
78    0x01A8, 0x0195, 0x001F, 0x0041, 0x000D, 0x01BA, 0x0032, 0x003D, 0x01D1,
79    0x0080, 0x00A8, 0x0057, 0x01B9, 0x0162, 0x0148, 0x00D9, 0x0105, 0x0062,
80    0x007A, 0x0021, 0x01FF, 0x0112, 0x0108, 0x01C0, 0x00A9, 0x011D, 0x01B0,
81    0x01A6, 0x00CD, 0x00F3, 0x005C, 0x0102, 0x005B, 0x01D9, 0x0144, 0x01F6,
82    0x00AD, 0x00A5, 0x003A, 0x01CB, 0x0136, 0x017F, 0x0046, 0x00E1, 0x001E,
83    0x01DD, 0x00E6, 0x0137, 0x01FA, 0x0185, 0x008C, 0x008F, 0x0040, 0x01B5,
84    0x00BE, 0x0078, 0x0000, 0x00AC, 0x0110, 0x015E, 0x0124, 0x0002, 0x01BC,
85    0x00A2, 0x00EA, 0x0070, 0x01FC, 0x0116, 0x015C, 0x004C, 0x01C2 };
86 
87 /*
88 * MISTY1 FI Function
89 */
FI(uint16_t input,uint16_t key7,uint16_t key9)90 uint16_t FI(uint16_t input, uint16_t key7, uint16_t key9)
91    {
92    uint16_t D9 = input >> 7, D7 = input & 0x7F;
93    D9 = MISTY1_SBOX_S9[D9] ^ D7;
94    D7 = (MISTY1_SBOX_S7[D7] ^ key7 ^ D9) & 0x7F;
95    D9 = MISTY1_SBOX_S9[D9 ^ key9] ^ D7;
96    return static_cast<uint16_t>(D7 << 9) | D9;
97    }
98 
99 }
100 
101 /*
102 * MISTY1 Encryption
103 */
encrypt_n(const uint8_t in[],uint8_t out[],size_t blocks) const104 void MISTY1::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
105    {
106    verify_key_set(m_EK.empty() == false);
107 
108    for(size_t i = 0; i != blocks; ++i)
109       {
110       uint16_t B0 = load_be<uint16_t>(in, 0);
111       uint16_t B1 = load_be<uint16_t>(in, 1);
112       uint16_t B2 = load_be<uint16_t>(in, 2);
113       uint16_t B3 = load_be<uint16_t>(in, 3);
114 
115       for(size_t j = 0; j != 12; j += 3)
116          {
117          const uint16_t* RK = &m_EK[8 * j];
118 
119          B1 ^= B0 & RK[0];
120          B0 ^= B1 | RK[1];
121          B3 ^= B2 & RK[2];
122          B2 ^= B3 | RK[3];
123 
124          uint16_t T0, T1;
125 
126          T0  = FI(B0 ^ RK[ 4], RK[ 5], RK[ 6]) ^ B1;
127          T1  = FI(B1 ^ RK[ 7], RK[ 8], RK[ 9]) ^ T0;
128          T0  = FI(T0 ^ RK[10], RK[11], RK[12]) ^ T1;
129 
130          B2 ^= T1 ^ RK[13];
131          B3 ^= T0;
132 
133          T0  = FI(B2 ^ RK[14], RK[15], RK[16]) ^ B3;
134          T1  = FI(B3 ^ RK[17], RK[18], RK[19]) ^ T0;
135          T0  = FI(T0 ^ RK[20], RK[21], RK[22]) ^ T1;
136 
137          B0 ^= T1 ^ RK[23];
138          B1 ^= T0;
139          }
140 
141       B1 ^= B0 & m_EK[96];
142       B0 ^= B1 | m_EK[97];
143       B3 ^= B2 & m_EK[98];
144       B2 ^= B3 | m_EK[99];
145 
146       store_be(out, B2, B3, B0, B1);
147 
148       in += BLOCK_SIZE;
149       out += BLOCK_SIZE;
150       }
151    }
152 
153 /*
154 * MISTY1 Decryption
155 */
decrypt_n(const uint8_t in[],uint8_t out[],size_t blocks) const156 void MISTY1::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
157    {
158    verify_key_set(m_DK.empty() == false);
159 
160    for(size_t i = 0; i != blocks; ++i)
161       {
162       uint16_t B0 = load_be<uint16_t>(in, 2);
163       uint16_t B1 = load_be<uint16_t>(in, 3);
164       uint16_t B2 = load_be<uint16_t>(in, 0);
165       uint16_t B3 = load_be<uint16_t>(in, 1);
166 
167       for(size_t j = 0; j != 12; j += 3)
168          {
169          const uint16_t* RK = &m_DK[8 * j];
170 
171          B2 ^= B3 | RK[0];
172          B3 ^= B2 & RK[1];
173          B0 ^= B1 | RK[2];
174          B1 ^= B0 & RK[3];
175 
176          uint16_t T0, T1;
177 
178          T0  = FI(B2 ^ RK[ 4], RK[ 5], RK[ 6]) ^ B3;
179          T1  = FI(B3 ^ RK[ 7], RK[ 8], RK[ 9]) ^ T0;
180          T0  = FI(T0 ^ RK[10], RK[11], RK[12]) ^ T1;
181 
182          B0 ^= T1 ^ RK[13];
183          B1 ^= T0;
184 
185          T0  = FI(B0 ^ RK[14], RK[15], RK[16]) ^ B1;
186          T1  = FI(B1 ^ RK[17], RK[18], RK[19]) ^ T0;
187          T0  = FI(T0 ^ RK[20], RK[21], RK[22]) ^ T1;
188 
189          B2 ^= T1 ^ RK[23];
190          B3 ^= T0;
191          }
192 
193       B2 ^= B3 | m_DK[96];
194       B3 ^= B2 & m_DK[97];
195       B0 ^= B1 | m_DK[98];
196       B1 ^= B0 & m_DK[99];
197 
198       store_be(out, B0, B1, B2, B3);
199 
200       in += BLOCK_SIZE;
201       out += BLOCK_SIZE;
202       }
203    }
204 
205 /*
206 * MISTY1 Key Schedule
207 */
key_schedule(const uint8_t key[],size_t length)208 void MISTY1::key_schedule(const uint8_t key[], size_t length)
209    {
210    secure_vector<uint16_t> KS(32);
211    for(size_t i = 0; i != length / 2; ++i)
212       KS[i] = load_be<uint16_t>(key, i);
213 
214    for(size_t i = 0; i != 8; ++i)
215       {
216       KS[i+ 8] = FI(KS[i], KS[(i+1) % 8] >> 9, KS[(i+1) % 8] & 0x1FF);
217       KS[i+16] = KS[i+8] >> 9;
218       KS[i+24] = KS[i+8] & 0x1FF;
219       }
220 
221    /*
222    * Precomputed indexes for the orderings of the subkeys (MISTY1 reuses
223    * values)
224    */
225    static const uint8_t EK_ORDER[100] = {
226       0x00, 0x0E, 0x0A, 0x04, 0x00, 0x15, 0x1D, 0x02, 0x11, 0x19, 0x07, 0x13,
227       0x1B, 0x04, 0x01, 0x16, 0x1E, 0x03, 0x12, 0x1A, 0x00, 0x14, 0x1C, 0x05,
228       0x01, 0x0F, 0x0B, 0x05, 0x02, 0x17, 0x1F, 0x04, 0x13, 0x1B, 0x01, 0x15,
229       0x1D, 0x06, 0x03, 0x10, 0x18, 0x05, 0x14, 0x1C, 0x02, 0x16, 0x1E, 0x07,
230       0x02, 0x08, 0x0C, 0x06, 0x04, 0x11, 0x19, 0x06, 0x15, 0x1D, 0x03, 0x17,
231       0x1F, 0x00, 0x05, 0x12, 0x1A, 0x07, 0x16, 0x1E, 0x04, 0x10, 0x18, 0x01,
232       0x03, 0x09, 0x0D, 0x07, 0x06, 0x13, 0x1B, 0x00, 0x17, 0x1F, 0x05, 0x11,
233       0x19, 0x02, 0x07, 0x14, 0x1C, 0x01, 0x10, 0x18, 0x06, 0x12, 0x1A, 0x03,
234       0x04, 0x0A, 0x0E, 0x00 };
235 
236    static const uint8_t DK_ORDER[100] = {
237       0x00, 0x0E, 0x0A, 0x04, 0x07, 0x14, 0x1C, 0x01, 0x10, 0x18, 0x06, 0x12,
238       0x1A, 0x03, 0x06, 0x13, 0x1B, 0x00, 0x17, 0x1F, 0x05, 0x11, 0x19, 0x02,
239       0x07, 0x0D, 0x09, 0x03, 0x05, 0x12, 0x1A, 0x07, 0x16, 0x1E, 0x04, 0x10,
240       0x18, 0x01, 0x04, 0x11, 0x19, 0x06, 0x15, 0x1D, 0x03, 0x17, 0x1F, 0x00,
241       0x06, 0x0C, 0x08, 0x02, 0x03, 0x10, 0x18, 0x05, 0x14, 0x1C, 0x02, 0x16,
242       0x1E, 0x07, 0x02, 0x17, 0x1F, 0x04, 0x13, 0x1B, 0x01, 0x15, 0x1D, 0x06,
243       0x05, 0x0B, 0x0F, 0x01, 0x01, 0x16, 0x1E, 0x03, 0x12, 0x1A, 0x00, 0x14,
244       0x1C, 0x05, 0x00, 0x15, 0x1D, 0x02, 0x11, 0x19, 0x07, 0x13, 0x1B, 0x04,
245       0x04, 0x0A, 0x0E, 0x00 };
246 
247    m_EK.resize(100);
248    m_DK.resize(100);
249 
250    for(size_t i = 0; i != 100; ++i)
251       {
252       m_EK[i] = KS[EK_ORDER[i]];
253       m_DK[i] = KS[DK_ORDER[i]];
254       }
255    }
256 
clear()257 void MISTY1::clear()
258    {
259    zap(m_EK);
260    zap(m_DK);
261    }
262 
263 }
264