1 /* crypto-3des.c --- 3DES crypto functions.
2 * Copyright (C) 2002-2013 Simon Josefsson
3 *
4 * This file is part of Shishi.
5 *
6 * Shishi is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Shishi is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, see http://www.gnu.org/licenses or write
18 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19 * Floor, Boston, MA 02110-1301, USA
20 *
21 */
22
23 #include "internal.h"
24
25 /* Get prototypes. */
26 #include "crypto.h"
27
28 /* Get _shishi_escapeprint, etc. */
29 #include "utils.h"
30
31 static int
_des3_encrypt(Shishi * handle,Shishi_key * key,int keyusage,const char * iv,size_t ivlen,char ** ivout,size_t * ivoutlen,const char * in,size_t inlen,char ** out,size_t * outlen)32 _des3_encrypt (Shishi * handle,
33 Shishi_key * key,
34 int keyusage,
35 const char *iv,
36 size_t ivlen,
37 char **ivout, size_t * ivoutlen,
38 const char *in, size_t inlen, char **out, size_t * outlen)
39 {
40 return _shishi_simplified_encrypt (handle, key, keyusage, iv, ivlen, ivout,
41 ivoutlen, in, inlen, out, outlen);
42 }
43
44 static int
_des3_decrypt(Shishi * handle,Shishi_key * key,int keyusage,const char * iv,size_t ivlen,char ** ivout,size_t * ivoutlen,const char * in,size_t inlen,char ** out,size_t * outlen)45 _des3_decrypt (Shishi * handle,
46 Shishi_key * key,
47 int keyusage,
48 const char *iv,
49 size_t ivlen,
50 char **ivout, size_t * ivoutlen,
51 const char *in, size_t inlen, char **out, size_t * outlen)
52 {
53 return _shishi_simplified_decrypt (handle, key, keyusage, iv, ivlen, ivout,
54 ivoutlen, in, inlen, out, outlen);
55 }
56
57 static int
des3none_dencrypt(Shishi * handle,Shishi_key * key,int keyusage,const char * iv,size_t ivlen,char ** ivout,size_t * ivoutlen,const char * in,size_t inlen,char ** out,size_t * outlen,int direction)58 des3none_dencrypt (Shishi * handle,
59 Shishi_key * key,
60 int keyusage,
61 const char *iv, size_t ivlen,
62 char **ivout, size_t * ivoutlen,
63 const char *in, size_t inlen,
64 char **out, size_t * outlen, int direction)
65 {
66 int res;
67
68 if (keyusage != 0)
69 {
70 Shishi_key *derivedkey;
71
72 res = _shishi_simplified_derivekey (handle, key, keyusage,
73 SHISHI_DERIVEKEYMODE_PRIVACY,
74 &derivedkey);
75 if (res != SHISHI_OK)
76 return res;
77
78 res =
79 _shishi_simplified_dencrypt (handle, derivedkey, iv, ivlen, ivout,
80 ivoutlen, in, inlen, out, outlen,
81 direction);
82
83 shishi_key_done (derivedkey);
84
85 if (res != SHISHI_OK)
86 return res;
87 }
88 else
89 {
90 res =
91 _shishi_simplified_dencrypt (handle, key, iv, ivlen, ivout, ivoutlen,
92 in, inlen, out, outlen, direction);
93 if (res != SHISHI_OK)
94 return res;
95 }
96
97 return SHISHI_OK;
98 }
99
100 static int
des3none_encrypt(Shishi * handle,Shishi_key * key,int keyusage,const char * iv,size_t ivlen,char ** ivout,size_t * ivoutlen,const char * in,size_t inlen,char ** out,size_t * outlen)101 des3none_encrypt (Shishi * handle,
102 Shishi_key * key,
103 int keyusage,
104 const char *iv, size_t ivlen,
105 char **ivout, size_t * ivoutlen,
106 const char *in, size_t inlen, char **out, size_t * outlen)
107 {
108 return des3none_dencrypt (handle, key, keyusage, iv, ivlen, ivout, ivoutlen,
109 in, inlen, out, outlen, 0);
110 }
111
112 static int
des3none_decrypt(Shishi * handle,Shishi_key * key,int keyusage,const char * iv,size_t ivlen,char ** ivout,size_t * ivoutlen,const char * in,size_t inlen,char ** out,size_t * outlen)113 des3none_decrypt (Shishi * handle,
114 Shishi_key * key,
115 int keyusage,
116 const char *iv, size_t ivlen,
117 char **ivout, size_t * ivoutlen,
118 const char *in, size_t inlen, char **out, size_t * outlen)
119 {
120 return des3none_dencrypt (handle, key, keyusage, iv, ivlen, ivout, ivoutlen,
121 in, inlen, out, outlen, 1);
122 }
123
124 static void
des_set_odd_key_parity(char key[8])125 des_set_odd_key_parity (char key[8])
126 {
127 int i, j;
128
129 for (i = 0; i < 8; i++)
130 {
131 int n_set_bits = 0;
132
133 for (j = 1; j < 8; j++)
134 if (key[i] & (1 << j))
135 n_set_bits++;
136
137 key[i] &= ~1;
138 if ((n_set_bits % 2) == 0)
139 key[i] |= 1;
140 }
141 }
142
143 /* The 168 bits of random key data are converted to a protocol key
144 * value as follows. First, the 168 bits are divided into three
145 * groups of 56 bits, which are expanded individually into 64 bits as
146 * follows:
147 *
148 * 1 2 3 4 5 6 7 p
149 * 9 10 11 12 13 14 15 p
150 * 17 18 19 20 21 22 23 p
151 * 25 26 27 28 29 30 31 p
152 * 33 34 35 36 37 38 39 p
153 * 41 42 43 44 45 46 47 p
154 * 49 50 51 52 53 54 55 p
155 * 56 48 40 32 24 16 8 p
156 *
157 * The "p" bits are parity bits computed over the data bits. The
158 * output of the three expansions are concatenated to form the
159 * protocol key value.
160 *
161 */
162 static int
des3_random_to_key(Shishi * handle,const char * rnd,size_t rndlen,Shishi_key * outkey)163 des3_random_to_key (Shishi * handle,
164 const char *rnd, size_t rndlen, Shishi_key * outkey)
165 {
166 char tmpkey[3 * 8];
167 int i;
168
169 if (rndlen < 168 / 8)
170 return !SHISHI_OK;
171
172 if (VERBOSECRYPTO (handle))
173 {
174 printf ("des3_random_to_key (random)\n");
175 printf ("\t ;; random (length %d):\n", 168 / 8);
176 _shishi_hexprint (rnd, 168 / 8);
177 _shishi_binprint (rnd, 168 / 8);
178 }
179
180 memcpy (tmpkey, rnd, 7);
181 memcpy (tmpkey + 8, rnd + 7, 7);
182 memcpy (tmpkey + 16, rnd + 14, 7);
183 for (i = 0; i < 3; i++)
184 {
185 tmpkey[i * 8 + 7] =
186 ((tmpkey[i * 8 + 0] & 0x01) << 1) |
187 ((tmpkey[i * 8 + 1] & 0x01) << 2) |
188 ((tmpkey[i * 8 + 2] & 0x01) << 3) |
189 ((tmpkey[i * 8 + 3] & 0x01) << 4) |
190 ((tmpkey[i * 8 + 4] & 0x01) << 5) |
191 ((tmpkey[i * 8 + 5] & 0x01) << 6) | ((tmpkey[i * 8 + 6] & 0x01) << 7);
192 des_set_odd_key_parity (tmpkey + i * 8);
193 }
194
195 shishi_key_value_set (outkey, tmpkey);
196
197 if (VERBOSECRYPTO (handle))
198 {
199 printf ("key = des3_random_to_key (random)\n");
200 printf ("\t ;; key:\n");
201 _shishi_hexprint (tmpkey, 3 * 8);
202 _shishi_binprint (tmpkey, 3 * 8);
203 }
204
205 return SHISHI_OK;
206 }
207
208 static int
des3_string_to_key(Shishi * handle,const char * string,size_t stringlen,const char * salt,size_t saltlen,const char * parameter,Shishi_key * outkey)209 des3_string_to_key (Shishi * handle,
210 const char *string,
211 size_t stringlen,
212 const char *salt,
213 size_t saltlen,
214 const char *parameter, Shishi_key * outkey)
215 {
216 char *s;
217 int n_s;
218 Shishi_key *key;
219 char nfold[168 / 8];
220 int nfoldlen = 168 / 8;
221 int res;
222
223 if (VERBOSECRYPTO (handle))
224 {
225 printf ("des3_string_to_key (string, salt)\n");
226 printf ("\t ;; String:\n");
227 _shishi_escapeprint (string, stringlen);
228 _shishi_hexprint (string, stringlen);
229 printf ("\t ;; Salt:\n");
230 _shishi_escapeprint (salt, saltlen);
231 _shishi_hexprint (salt, saltlen);
232 }
233
234 /* s = passwordString + salt */
235 n_s = stringlen + saltlen;
236 s = xmalloc (n_s);
237 memcpy (s, string, stringlen);
238 memcpy (s + stringlen, salt, saltlen);
239
240 /* tmpKey = random-to-key(168-fold(s)) */
241 res = shishi_n_fold (handle, s, n_s, nfold, nfoldlen);
242 free (s);
243 if (res != SHISHI_OK)
244 return res;
245
246 res = shishi_key_from_value (handle, shishi_key_type (outkey), NULL, &key);
247 if (res != SHISHI_OK)
248 return res;
249
250 res = des3_random_to_key (handle, nfold, nfoldlen, key);
251 if (res == SHISHI_OK)
252 /* key = DK (tmpKey, Constant) */
253 res = shishi_dk (handle, key, SHISHI_DK_CONSTANT,
254 strlen (SHISHI_DK_CONSTANT), outkey);
255
256 shishi_key_done (key);
257
258 if (res != SHISHI_OK)
259 return res;
260
261 if (VERBOSECRYPTO (handle))
262 {
263 printf ("des3_string_to_key (string, salt)\n");
264 printf ("\t ;; Key:\n");
265 _shishi_hexprint (shishi_key_value (outkey),
266 shishi_key_length (outkey));
267 _shishi_binprint (shishi_key_value (outkey),
268 shishi_key_length (outkey));
269 }
270
271 return SHISHI_OK;
272 }
273
274 static int
des3_checksum(Shishi * handle,Shishi_key * key,int keyusage,int cksumtype,const char * in,size_t inlen,char ** out,size_t * outlen)275 des3_checksum (Shishi * handle,
276 Shishi_key * key,
277 int keyusage,
278 int cksumtype,
279 const char *in, size_t inlen, char **out, size_t * outlen)
280 {
281 return _shishi_simplified_checksum (handle, key, keyusage, cksumtype,
282 in, inlen, out, outlen);
283 }
284
285 cipherinfo des3_cbc_none_info = {
286 SHISHI_DES3_CBC_NONE,
287 "des3-cbc-none",
288 8,
289 8,
290 3 * 8,
291 3 * 8,
292 SHISHI_HMAC_SHA1_DES3_KD,
293 des3_random_to_key,
294 des3_string_to_key,
295 des3none_encrypt,
296 des3none_decrypt
297 };
298
299 cipherinfo des3_cbc_sha1_kd_info = {
300 SHISHI_DES3_CBC_HMAC_SHA1_KD,
301 "des3-cbc-sha1-kd",
302 8,
303 8,
304 3 * 8,
305 3 * 8,
306 SHISHI_HMAC_SHA1_DES3_KD,
307 des3_random_to_key,
308 des3_string_to_key,
309 _des3_encrypt,
310 _des3_decrypt
311 };
312
313 checksuminfo hmac_sha1_des3_kd_info = {
314 SHISHI_HMAC_SHA1_DES3_KD,
315 "hmac-sha1-des3-kd",
316 20,
317 des3_checksum,
318 NULL
319 };
320