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