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