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     8,                     /* blocksize (SSH2 defines minimum blocksize as 8) */
57     0,                     /* iv_len */
58     0,                     /* secret_len */
59     0,                     /* flags */
60     NULL,
61     crypt_none_crypt,
62     NULL
63 };
64 #endif /* LIBSSH2_CRYPT_NONE */
65 
66 struct crypt_ctx
67 {
68     int encrypt;
69     _libssh2_cipher_type(algo);
70     _libssh2_cipher_ctx h;
71 };
72 
73 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)74 crypt_init(LIBSSH2_SESSION * session,
75            const LIBSSH2_CRYPT_METHOD * method,
76            unsigned char *iv, int *free_iv,
77            unsigned char *secret, int *free_secret,
78            int encrypt, void **abstract)
79 {
80     struct crypt_ctx *ctx = LIBSSH2_ALLOC(session,
81                                           sizeof(struct crypt_ctx));
82     if (!ctx)
83         return LIBSSH2_ERROR_ALLOC;
84 
85     ctx->encrypt = encrypt;
86     ctx->algo = method->algo;
87     if (_libssh2_cipher_init(&ctx->h, ctx->algo, iv, secret, encrypt)) {
88         LIBSSH2_FREE(session, ctx);
89         return -1;
90     }
91     *abstract = ctx;
92     *free_iv = 1;
93     *free_secret = 1;
94     return 0;
95 }
96 
97 static int
crypt_encrypt(LIBSSH2_SESSION * session,unsigned char * block,size_t blocksize,void ** abstract)98 crypt_encrypt(LIBSSH2_SESSION * session, unsigned char *block,
99               size_t blocksize, void **abstract)
100 {
101     struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
102     (void) session;
103     return _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block,
104                                  blocksize);
105 }
106 
107 static int
crypt_dtor(LIBSSH2_SESSION * session,void ** abstract)108 crypt_dtor(LIBSSH2_SESSION * session, void **abstract)
109 {
110     struct crypt_ctx **cctx = (struct crypt_ctx **) abstract;
111     if (cctx && *cctx) {
112         _libssh2_cipher_dtor(&(*cctx)->h);
113         LIBSSH2_FREE(session, *cctx);
114         *abstract = NULL;
115     }
116     return 0;
117 }
118 
119 #if LIBSSH2_AES_CTR
120 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_ctr = {
121     "aes128-ctr",
122     16,                         /* blocksize */
123     16,                         /* initial value length */
124     16,                         /* secret length -- 16*8 == 128bit */
125     0,                          /* flags */
126     &crypt_init,
127     &crypt_encrypt,
128     &crypt_dtor,
129     _libssh2_cipher_aes128ctr
130 };
131 
132 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_ctr = {
133     "aes192-ctr",
134     16,                         /* blocksize */
135     16,                         /* initial value length */
136     24,                         /* secret length -- 24*8 == 192bit */
137     0,                          /* flags */
138     &crypt_init,
139     &crypt_encrypt,
140     &crypt_dtor,
141     _libssh2_cipher_aes192ctr
142 };
143 
144 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_ctr = {
145     "aes256-ctr",
146     16,                         /* blocksize */
147     16,                         /* initial value length */
148     32,                         /* secret length -- 32*8 == 256bit */
149     0,                          /* flags */
150     &crypt_init,
151     &crypt_encrypt,
152     &crypt_dtor,
153     _libssh2_cipher_aes256ctr
154 };
155 #endif
156 
157 #if LIBSSH2_AES
158 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
159     "aes128-cbc",
160     16,                         /* blocksize */
161     16,                         /* initial value length */
162     16,                         /* secret length -- 16*8 == 128bit */
163     0,                          /* flags */
164     &crypt_init,
165     &crypt_encrypt,
166     &crypt_dtor,
167     _libssh2_cipher_aes128
168 };
169 
170 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = {
171     "aes192-cbc",
172     16,                         /* blocksize */
173     16,                         /* initial value length */
174     24,                         /* secret length -- 24*8 == 192bit */
175     0,                          /* flags */
176     &crypt_init,
177     &crypt_encrypt,
178     &crypt_dtor,
179     _libssh2_cipher_aes192
180 };
181 
182 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = {
183     "aes256-cbc",
184     16,                         /* blocksize */
185     16,                         /* initial value length */
186     32,                         /* secret length -- 32*8 == 256bit */
187     0,                          /* flags */
188     &crypt_init,
189     &crypt_encrypt,
190     &crypt_dtor,
191     _libssh2_cipher_aes256
192 };
193 
194 /* rijndael-cbc@lysator.liu.se == aes256-cbc */
195 static const LIBSSH2_CRYPT_METHOD
196     libssh2_crypt_method_rijndael_cbc_lysator_liu_se = {
197     "rijndael-cbc@lysator.liu.se",
198     16,                         /* blocksize */
199     16,                         /* initial value length */
200     32,                         /* secret length -- 32*8 == 256bit */
201     0,                          /* flags */
202     &crypt_init,
203     &crypt_encrypt,
204     &crypt_dtor,
205     _libssh2_cipher_aes256
206 };
207 #endif /* LIBSSH2_AES */
208 
209 #if LIBSSH2_BLOWFISH
210 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = {
211     "blowfish-cbc",
212     8,                          /* blocksize */
213     8,                          /* initial value length */
214     16,                         /* secret length */
215     0,                          /* flags */
216     &crypt_init,
217     &crypt_encrypt,
218     &crypt_dtor,
219     _libssh2_cipher_blowfish
220 };
221 #endif /* LIBSSH2_BLOWFISH */
222 
223 #if LIBSSH2_RC4
224 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = {
225     "arcfour",
226     8,                          /* blocksize */
227     8,                          /* initial value length */
228     16,                         /* secret length */
229     0,                          /* flags */
230     &crypt_init,
231     &crypt_encrypt,
232     &crypt_dtor,
233     _libssh2_cipher_arcfour
234 };
235 
236 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)237 crypt_init_arcfour128(LIBSSH2_SESSION * session,
238                       const LIBSSH2_CRYPT_METHOD * method,
239                       unsigned char *iv, int *free_iv,
240                       unsigned char *secret, int *free_secret,
241                       int encrypt, void **abstract)
242 {
243     int rc;
244 
245     rc = crypt_init (session, method, iv, free_iv, secret, free_secret,
246                      encrypt, abstract);
247     if (rc == 0) {
248         struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
249         unsigned char block[8];
250         size_t discard = 1536;
251         for (; discard; discard -= 8)
252             _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block,
253                                   method->blocksize);
254     }
255 
256     return rc;
257 }
258 
259 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour128 = {
260     "arcfour128",
261     8,                          /* blocksize */
262     8,                          /* initial value length */
263     16,                         /* secret length */
264     0,                          /* flags */
265     &crypt_init_arcfour128,
266     &crypt_encrypt,
267     &crypt_dtor,
268     _libssh2_cipher_arcfour
269 };
270 #endif /* LIBSSH2_RC4 */
271 
272 #if LIBSSH2_CAST
273 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = {
274     "cast128-cbc",
275     8,                          /* blocksize */
276     8,                          /* initial value length */
277     16,                         /* secret length */
278     0,                          /* flags */
279     &crypt_init,
280     &crypt_encrypt,
281     &crypt_dtor,
282     _libssh2_cipher_cast5
283 };
284 #endif /* LIBSSH2_CAST */
285 
286 #if LIBSSH2_3DES
287 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = {
288     "3des-cbc",
289     8,                          /* blocksize */
290     8,                          /* initial value length */
291     24,                         /* secret length */
292     0,                          /* flags */
293     &crypt_init,
294     &crypt_encrypt,
295     &crypt_dtor,
296     _libssh2_cipher_3des
297 };
298 #endif
299 
300 static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
301 #if LIBSSH2_AES_CTR
302   &libssh2_crypt_method_aes128_ctr,
303   &libssh2_crypt_method_aes192_ctr,
304   &libssh2_crypt_method_aes256_ctr,
305 #endif /* LIBSSH2_AES */
306 #if LIBSSH2_AES
307     &libssh2_crypt_method_aes256_cbc,
308     &libssh2_crypt_method_rijndael_cbc_lysator_liu_se,  /* == aes256-cbc */
309     &libssh2_crypt_method_aes192_cbc,
310     &libssh2_crypt_method_aes128_cbc,
311 #endif /* LIBSSH2_AES */
312 #if LIBSSH2_BLOWFISH
313     &libssh2_crypt_method_blowfish_cbc,
314 #endif /* LIBSSH2_BLOWFISH */
315 #if LIBSSH2_RC4
316     &libssh2_crypt_method_arcfour128,
317     &libssh2_crypt_method_arcfour,
318 #endif /* LIBSSH2_RC4 */
319 #if LIBSSH2_CAST
320     &libssh2_crypt_method_cast128_cbc,
321 #endif /* LIBSSH2_CAST */
322 #if LIBSSH2_3DES
323     &libssh2_crypt_method_3des_cbc,
324 #endif /*  LIBSSH2_DES */
325 #ifdef LIBSSH2_CRYPT_NONE
326     &libssh2_crypt_method_none,
327 #endif
328     NULL
329 };
330 
331 /* Expose to kex.c */
332 const LIBSSH2_CRYPT_METHOD **
libssh2_crypt_methods(void)333 libssh2_crypt_methods(void)
334 {
335     return _libssh2_crypt_methods;
336 }
337