1 /* Copyright (c) 2009, 2010 Simon Josefsson <simon@josefsson.org>
2 * Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms,
6 * with or without modification, are permitted provided
7 * that the following conditions are met:
8 *
9 * Redistributions of source code must retain the above
10 * copyright notice, this list of conditions and the
11 * following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials
16 * provided with the distribution.
17 *
18 * Neither the name of the copyright holder nor the names
19 * of any other contributors may be used to endorse or
20 * promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
35 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
36 * OF SUCH DAMAGE.
37 */
38
39 #include "libssh2_priv.h"
40
41 #ifdef LIBSSH2_CRYPT_NONE
42
43 /* crypt_none_crypt
44 * Minimalist cipher: VERY secure *wink*
45 */
46 static int
crypt_none_crypt(LIBSSH2_SESSION * session,unsigned char * buf,void ** abstract)47 crypt_none_crypt(LIBSSH2_SESSION * session, unsigned char *buf,
48 void **abstract)
49 {
50 /* Do nothing to the data! */
51 return 0;
52 }
53
54 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = {
55 "none",
56 "DEK-Info: NONE",
57 8, /* blocksize (SSH2 defines minimum blocksize as 8) */
58 0, /* iv_len */
59 0, /* secret_len */
60 0, /* flags */
61 NULL,
62 crypt_none_crypt,
63 NULL
64 };
65 #endif /* LIBSSH2_CRYPT_NONE */
66
67 struct crypt_ctx
68 {
69 int encrypt;
70 _libssh2_cipher_type(algo);
71 _libssh2_cipher_ctx h;
72 };
73
74 static int
crypt_init(LIBSSH2_SESSION * session,const LIBSSH2_CRYPT_METHOD * method,unsigned char * iv,int * free_iv,unsigned char * secret,int * free_secret,int encrypt,void ** abstract)75 crypt_init(LIBSSH2_SESSION * session,
76 const LIBSSH2_CRYPT_METHOD * method,
77 unsigned char *iv, int *free_iv,
78 unsigned char *secret, int *free_secret,
79 int encrypt, void **abstract)
80 {
81 struct crypt_ctx *ctx = LIBSSH2_ALLOC(session,
82 sizeof(struct crypt_ctx));
83 if(!ctx)
84 return LIBSSH2_ERROR_ALLOC;
85
86 ctx->encrypt = encrypt;
87 ctx->algo = method->algo;
88 if(_libssh2_cipher_init(&ctx->h, ctx->algo, iv, secret, encrypt)) {
89 LIBSSH2_FREE(session, ctx);
90 return -1;
91 }
92 *abstract = ctx;
93 *free_iv = 1;
94 *free_secret = 1;
95 return 0;
96 }
97
98 static int
crypt_encrypt(LIBSSH2_SESSION * session,unsigned char * block,size_t blocksize,void ** abstract)99 crypt_encrypt(LIBSSH2_SESSION * session, unsigned char *block,
100 size_t blocksize, void **abstract)
101 {
102 struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
103 (void) session;
104 return _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block,
105 blocksize);
106 }
107
108 static int
crypt_dtor(LIBSSH2_SESSION * session,void ** abstract)109 crypt_dtor(LIBSSH2_SESSION * session, void **abstract)
110 {
111 struct crypt_ctx **cctx = (struct crypt_ctx **) abstract;
112 if(cctx && *cctx) {
113 _libssh2_cipher_dtor(&(*cctx)->h);
114 LIBSSH2_FREE(session, *cctx);
115 *abstract = NULL;
116 }
117 return 0;
118 }
119
120 #if LIBSSH2_AES_CTR
121 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_ctr = {
122 "aes128-ctr",
123 "",
124 16, /* blocksize */
125 16, /* initial value length */
126 16, /* secret length -- 16*8 == 128bit */
127 0, /* flags */
128 &crypt_init,
129 &crypt_encrypt,
130 &crypt_dtor,
131 _libssh2_cipher_aes128ctr
132 };
133
134 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_ctr = {
135 "aes192-ctr",
136 "",
137 16, /* blocksize */
138 16, /* initial value length */
139 24, /* secret length -- 24*8 == 192bit */
140 0, /* flags */
141 &crypt_init,
142 &crypt_encrypt,
143 &crypt_dtor,
144 _libssh2_cipher_aes192ctr
145 };
146
147 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_ctr = {
148 "aes256-ctr",
149 "",
150 16, /* blocksize */
151 16, /* initial value length */
152 32, /* secret length -- 32*8 == 256bit */
153 0, /* flags */
154 &crypt_init,
155 &crypt_encrypt,
156 &crypt_dtor,
157 _libssh2_cipher_aes256ctr
158 };
159 #endif
160
161 #if LIBSSH2_AES
162 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
163 "aes128-cbc",
164 "DEK-Info: AES-128-CBC",
165 16, /* blocksize */
166 16, /* initial value length */
167 16, /* secret length -- 16*8 == 128bit */
168 0, /* flags */
169 &crypt_init,
170 &crypt_encrypt,
171 &crypt_dtor,
172 _libssh2_cipher_aes128
173 };
174
175 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = {
176 "aes192-cbc",
177 "DEK-Info: AES-192-CBC",
178 16, /* blocksize */
179 16, /* initial value length */
180 24, /* secret length -- 24*8 == 192bit */
181 0, /* flags */
182 &crypt_init,
183 &crypt_encrypt,
184 &crypt_dtor,
185 _libssh2_cipher_aes192
186 };
187
188 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = {
189 "aes256-cbc",
190 "DEK-Info: AES-256-CBC",
191 16, /* blocksize */
192 16, /* initial value length */
193 32, /* secret length -- 32*8 == 256bit */
194 0, /* flags */
195 &crypt_init,
196 &crypt_encrypt,
197 &crypt_dtor,
198 _libssh2_cipher_aes256
199 };
200
201 /* rijndael-cbc@lysator.liu.se == aes256-cbc */
202 static const LIBSSH2_CRYPT_METHOD
203 libssh2_crypt_method_rijndael_cbc_lysator_liu_se = {
204 "rijndael-cbc@lysator.liu.se",
205 "DEK-Info: AES-256-CBC",
206 16, /* blocksize */
207 16, /* initial value length */
208 32, /* secret length -- 32*8 == 256bit */
209 0, /* flags */
210 &crypt_init,
211 &crypt_encrypt,
212 &crypt_dtor,
213 _libssh2_cipher_aes256
214 };
215 #endif /* LIBSSH2_AES */
216
217 #if LIBSSH2_BLOWFISH
218 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = {
219 "blowfish-cbc",
220 "",
221 8, /* blocksize */
222 8, /* initial value length */
223 16, /* secret length */
224 0, /* flags */
225 &crypt_init,
226 &crypt_encrypt,
227 &crypt_dtor,
228 _libssh2_cipher_blowfish
229 };
230 #endif /* LIBSSH2_BLOWFISH */
231
232 #if LIBSSH2_RC4
233 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = {
234 "arcfour",
235 "DEK-Info: RC4",
236 8, /* blocksize */
237 8, /* initial value length */
238 16, /* secret length */
239 0, /* flags */
240 &crypt_init,
241 &crypt_encrypt,
242 &crypt_dtor,
243 _libssh2_cipher_arcfour
244 };
245
246 static int
crypt_init_arcfour128(LIBSSH2_SESSION * session,const LIBSSH2_CRYPT_METHOD * method,unsigned char * iv,int * free_iv,unsigned char * secret,int * free_secret,int encrypt,void ** abstract)247 crypt_init_arcfour128(LIBSSH2_SESSION * session,
248 const LIBSSH2_CRYPT_METHOD * method,
249 unsigned char *iv, int *free_iv,
250 unsigned char *secret, int *free_secret,
251 int encrypt, void **abstract)
252 {
253 int rc;
254
255 rc = crypt_init(session, method, iv, free_iv, secret, free_secret,
256 encrypt, abstract);
257 if(rc == 0) {
258 struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
259 unsigned char block[8];
260 size_t discard = 1536;
261 for(; discard; discard -= 8)
262 _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block,
263 method->blocksize);
264 }
265
266 return rc;
267 }
268
269 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour128 = {
270 "arcfour128",
271 "",
272 8, /* blocksize */
273 8, /* initial value length */
274 16, /* secret length */
275 0, /* flags */
276 &crypt_init_arcfour128,
277 &crypt_encrypt,
278 &crypt_dtor,
279 _libssh2_cipher_arcfour
280 };
281 #endif /* LIBSSH2_RC4 */
282
283 #if LIBSSH2_CAST
284 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = {
285 "cast128-cbc",
286 "",
287 8, /* blocksize */
288 8, /* initial value length */
289 16, /* secret length */
290 0, /* flags */
291 &crypt_init,
292 &crypt_encrypt,
293 &crypt_dtor,
294 _libssh2_cipher_cast5
295 };
296 #endif /* LIBSSH2_CAST */
297
298 #if LIBSSH2_3DES
299 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = {
300 "3des-cbc",
301 "DEK-Info: DES-EDE3-CBC",
302 8, /* blocksize */
303 8, /* initial value length */
304 24, /* secret length */
305 0, /* flags */
306 &crypt_init,
307 &crypt_encrypt,
308 &crypt_dtor,
309 _libssh2_cipher_3des
310 };
311 #endif
312
313 static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
314 #if LIBSSH2_AES_CTR
315 &libssh2_crypt_method_aes128_ctr,
316 &libssh2_crypt_method_aes192_ctr,
317 &libssh2_crypt_method_aes256_ctr,
318 #endif /* LIBSSH2_AES */
319 #if LIBSSH2_AES
320 &libssh2_crypt_method_aes256_cbc,
321 &libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */
322 &libssh2_crypt_method_aes192_cbc,
323 &libssh2_crypt_method_aes128_cbc,
324 #endif /* LIBSSH2_AES */
325 #if LIBSSH2_BLOWFISH
326 &libssh2_crypt_method_blowfish_cbc,
327 #endif /* LIBSSH2_BLOWFISH */
328 #if LIBSSH2_RC4
329 &libssh2_crypt_method_arcfour128,
330 &libssh2_crypt_method_arcfour,
331 #endif /* LIBSSH2_RC4 */
332 #if LIBSSH2_CAST
333 &libssh2_crypt_method_cast128_cbc,
334 #endif /* LIBSSH2_CAST */
335 #if LIBSSH2_3DES
336 &libssh2_crypt_method_3des_cbc,
337 #endif /* LIBSSH2_DES */
338 #ifdef LIBSSH2_CRYPT_NONE
339 &libssh2_crypt_method_none,
340 #endif
341 NULL
342 };
343
344 /* Expose to kex.c */
345 const LIBSSH2_CRYPT_METHOD **
libssh2_crypt_methods(void)346 libssh2_crypt_methods(void)
347 {
348 return _libssh2_crypt_methods;
349 }
350