1 /* crypto-aes.c --- AES 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
aes128_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 aes128_encrypt (Shishi * handle,
33 		Shishi_key * key,
34 		int keyusage,
35 		const char *iv, size_t ivlen,
36 		char **ivout, size_t * ivoutlen,
37 		const char *in, size_t inlen, char **out, size_t * outlen)
38 {
39   return _shishi_simplified_encrypt (handle, key, keyusage, iv, ivlen, ivout,
40 				     ivoutlen, in, inlen, out, outlen);
41 }
42 
43 static int
aes128_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)44 aes128_decrypt (Shishi * handle,
45 		Shishi_key * key,
46 		int keyusage,
47 		const char *iv, size_t ivlen,
48 		char **ivout, size_t * ivoutlen,
49 		const char *in, size_t inlen, char **out, size_t * outlen)
50 {
51   return _shishi_simplified_decrypt (handle, key, keyusage, iv, ivlen, ivout,
52 				     ivoutlen, in, inlen, out, outlen);
53 }
54 
55 static int
aes256_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)56 aes256_encrypt (Shishi * handle,
57 		Shishi_key * key,
58 		int keyusage,
59 		const char *iv, size_t ivlen,
60 		char **ivout, size_t * ivoutlen,
61 		const char *in, size_t inlen, char **out, size_t * outlen)
62 {
63   return _shishi_simplified_encrypt (handle, key, keyusage, iv, ivlen, ivout,
64 				     ivoutlen, in, inlen, out, outlen);
65 }
66 
67 static int
aes256_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)68 aes256_decrypt (Shishi * handle,
69 		Shishi_key * key,
70 		int keyusage,
71 		const char *iv, size_t ivlen,
72 		char **ivout, size_t * ivoutlen,
73 		const char *in, size_t inlen, char **out, size_t * outlen)
74 {
75   return _shishi_simplified_decrypt (handle, key, keyusage, iv, ivlen, ivout,
76 				     ivoutlen, in, inlen, out, outlen);
77 }
78 
79 static int
aes_string_to_key(Shishi * handle,const char * password,size_t passwordlen,const char * salt,size_t saltlen,const char * parameter,Shishi_key * outkey)80 aes_string_to_key (Shishi * handle,
81 		   const char *password,
82 		   size_t passwordlen,
83 		   const char *salt,
84 		   size_t saltlen, const char *parameter, Shishi_key * outkey)
85 {
86   char key[256 / 8];
87   int keylen = shishi_key_length (outkey);
88   Shishi_key *tmpkey;
89   int iterations = 0x00001000;
90   int res;
91 
92   if (parameter)
93     {
94       iterations = (parameter[0] & 0xFF) << 24;
95       iterations |= (parameter[1] & 0xFF) << 16;
96       iterations |= (parameter[2] & 0xFF) << 8;
97       iterations |= parameter[3] & 0xFF;
98     }
99 
100   if (VERBOSECRYPTO (handle))
101     {
102       printf ("aes_string_to_key (password, salt)\n");
103       printf ("\t ;; Password:\n");
104       _shishi_escapeprint (password, passwordlen);
105       _shishi_hexprint (password, passwordlen);
106       printf ("\t ;; Salt:\n");
107       _shishi_escapeprint (salt, saltlen);
108       _shishi_hexprint (salt, saltlen);
109       printf ("\t ;; Iteration count %d (%08x):\n", iterations, iterations);
110     }
111 
112   /* tkey = random2key(PBKDF2(passphrase, salt, iter_count, keylength)) */
113   res = shishi_pbkdf2_sha1 (handle, password, passwordlen, salt, saltlen,
114 			    iterations, keylen, key);
115   if (res != SHISHI_OK)
116     return res;
117 
118   res = shishi_key_from_value (handle, shishi_key_type (outkey),
119 			       key, &tmpkey);
120   if (res != SHISHI_OK)
121     return res;
122 
123   /* key = DK(tkey, Constant) */
124   res = shishi_dk (handle, tmpkey, SHISHI_DK_CONSTANT,
125 		   strlen (SHISHI_DK_CONSTANT), outkey);
126 
127   shishi_key_done (tmpkey);
128 
129   if (res != SHISHI_OK)
130     return res;
131 
132   if (VERBOSECRYPTO (handle))
133     {
134       printf ("aes_string_to_key (password, salt)\n");
135       printf ("\t ;; Key:\n");
136       _shishi_hexprint (shishi_key_value (outkey),
137 			shishi_key_length (outkey));
138       _shishi_binprint (shishi_key_value (outkey),
139 			shishi_key_length (outkey));
140     }
141 
142   return SHISHI_OK;
143 }
144 
145 static int
aes128_string_to_key(Shishi * handle,const char * password,size_t passwordlen,const char * salt,size_t saltlen,const char * parameter,Shishi_key * outkey)146 aes128_string_to_key (Shishi * handle,
147 		      const char *password,
148 		      size_t passwordlen,
149 		      const char *salt,
150 		      size_t saltlen,
151 		      const char *parameter, Shishi_key * outkey)
152 {
153   return aes_string_to_key (handle, password, passwordlen,
154 			    salt, saltlen, parameter, outkey);
155 }
156 
157 static int
aes256_string_to_key(Shishi * handle,const char * password,size_t passwordlen,const char * salt,size_t saltlen,const char * parameter,Shishi_key * outkey)158 aes256_string_to_key (Shishi * handle,
159 		      const char *password,
160 		      size_t passwordlen,
161 		      const char *salt,
162 		      size_t saltlen,
163 		      const char *parameter, Shishi_key * outkey)
164 {
165   return aes_string_to_key (handle, password, passwordlen,
166 			    salt, saltlen, parameter, outkey);
167 }
168 
169 static int
aes128_random_to_key(Shishi * handle,const char * rnd,size_t rndlen,Shishi_key * outkey)170 aes128_random_to_key (Shishi * handle,
171 		      const char *rnd, size_t rndlen, Shishi_key * outkey)
172 {
173   if (rndlen < shishi_key_length (outkey))
174     return SHISHI_CRYPTO_ERROR;
175 
176   shishi_key_value_set (outkey, rnd);
177 
178   return SHISHI_OK;
179 }
180 
181 static int
aes256_random_to_key(Shishi * handle,const char * rnd,size_t rndlen,Shishi_key * outkey)182 aes256_random_to_key (Shishi * handle,
183 		      const char *rnd, size_t rndlen, Shishi_key * outkey)
184 {
185   if (rndlen < shishi_key_length (outkey))
186     return SHISHI_CRYPTO_ERROR;
187 
188   shishi_key_value_set (outkey, rnd);
189 
190   return SHISHI_OK;
191 }
192 
193 static int
aes128_checksum(Shishi * handle,Shishi_key * key,int keyusage,int cksumtype,const char * in,size_t inlen,char ** out,size_t * outlen)194 aes128_checksum (Shishi * handle,
195 		 Shishi_key * key,
196 		 int keyusage,
197 		 int cksumtype,
198 		 const char *in, size_t inlen, char **out, size_t * outlen)
199 {
200   return _shishi_simplified_checksum (handle, key, keyusage, cksumtype,
201 				      in, inlen, out, outlen);
202 }
203 
204 static int
aes256_checksum(Shishi * handle,Shishi_key * key,int keyusage,int cksumtype,const char * in,size_t inlen,char ** out,size_t * outlen)205 aes256_checksum (Shishi * handle,
206 		 Shishi_key * key,
207 		 int keyusage,
208 		 int cksumtype,
209 		 const char *in, size_t inlen, char **out, size_t * outlen)
210 {
211   return _shishi_simplified_checksum (handle, key, keyusage, cksumtype,
212 				      in, inlen, out, outlen);
213 }
214 
215 cipherinfo aes128_cts_hmac_sha1_96_info = {
216   SHISHI_AES128_CTS_HMAC_SHA1_96,
217   "aes128-cts-hmac-sha1-96",
218   16,
219   16,
220   128 / 8,
221   128 / 8,
222   SHISHI_HMAC_SHA1_96_AES128,
223   aes128_random_to_key,
224   aes128_string_to_key,
225   aes128_encrypt,
226   aes128_decrypt
227 };
228 
229 cipherinfo aes256_cts_hmac_sha1_96_info = {
230   SHISHI_AES256_CTS_HMAC_SHA1_96,
231   "aes256-cts-hmac-sha1-96",
232   16,
233   16,
234   256 / 8,
235   256 / 8,
236   SHISHI_HMAC_SHA1_96_AES256,
237   aes256_random_to_key,
238   aes256_string_to_key,
239   aes256_encrypt,
240   aes256_decrypt
241 };
242 
243 checksuminfo hmac_sha1_96_aes128_info = {
244   SHISHI_HMAC_SHA1_96_AES128,
245   "hmac-sha1-96-aes128",
246   96 / 8,
247   aes128_checksum,
248   NULL
249 };
250 
251 checksuminfo hmac_sha1_96_aes256_info = {
252   SHISHI_HMAC_SHA1_96_AES256,
253   "hmac-sha1-96-aes256",
254   96 / 8,
255   aes256_checksum,
256   NULL
257 };
258