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