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