1 /*
2 * ProFTPD - mod_sftp ciphers
3 * Copyright (c) 2008-2020 TJ Saunders
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18 *
19 * As a special exemption, TJ Saunders and other respective copyright holders
20 * give permission to link this program with OpenSSL, and distribute the
21 * resulting executable, without including the source code for OpenSSL in the
22 * source distribution.
23 */
24
25 #include "mod_sftp.h"
26
27 #include "packet.h"
28 #include "msg.h"
29 #include "crypto.h"
30 #include "cipher.h"
31 #include "session.h"
32 #include "interop.h"
33
34 struct sftp_cipher {
35 pool *pool;
36 const char *algo;
37 const EVP_CIPHER *cipher;
38
39 unsigned char *iv;
40 uint32_t iv_len;
41
42 unsigned char *key;
43 uint32_t key_len;
44
45 size_t discard_len;
46 };
47
48 /* We need to keep the old ciphers around, so that we can handle N
49 * arbitrary packets to/from the client using the old keys, as during rekeying.
50 * Thus we have two read cipher contexts, two write cipher contexts.
51 * The cipher idx variable indicates which of the ciphers is currently in use.
52 */
53
54 static struct sftp_cipher read_ciphers[2] = {
55 { NULL, NULL, NULL, NULL, 0, NULL, 0, 0 },
56 { NULL, NULL, NULL, NULL, 0, NULL, 0, 0 }
57 };
58 static EVP_CIPHER_CTX *read_ctxs[2];
59
60 static struct sftp_cipher write_ciphers[2] = {
61 { NULL, NULL, NULL, NULL, 0, NULL, 0, 0 },
62 { NULL, NULL, NULL, NULL, 0, NULL, 0, 0 }
63 };
64 static EVP_CIPHER_CTX *write_ctxs[2];
65
66 #define SFTP_CIPHER_DEFAULT_BLOCK_SZ 8
67 static size_t cipher_blockszs[2] = {
68 SFTP_CIPHER_DEFAULT_BLOCK_SZ,
69 SFTP_CIPHER_DEFAULT_BLOCK_SZ,
70 };
71
72 /* Buffer size for reading/writing keys */
73 #define SFTP_CIPHER_BUFSZ 4096
74
75 static unsigned int read_cipher_idx = 0;
76 static unsigned int write_cipher_idx = 0;
77
78 static const char *trace_channel = "ssh2";
79
80 static void clear_cipher(struct sftp_cipher *);
81
get_next_read_index(void)82 static unsigned int get_next_read_index(void) {
83 if (read_cipher_idx == 1)
84 return 0;
85
86 return 1;
87 }
88
get_next_write_index(void)89 static unsigned int get_next_write_index(void) {
90 if (write_cipher_idx == 1)
91 return 0;
92
93 return 1;
94 }
95
switch_read_cipher(void)96 static void switch_read_cipher(void) {
97 /* First, clear the context of the existing read cipher, if any. */
98 if (read_ciphers[read_cipher_idx].key) {
99 clear_cipher(&(read_ciphers[read_cipher_idx]));
100 if (EVP_CIPHER_CTX_cleanup(read_ctxs[read_cipher_idx]) != 1) {
101 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
102 "error clearing cipher context: %s", sftp_crypto_get_errors());
103 }
104
105 cipher_blockszs[read_cipher_idx] = SFTP_CIPHER_DEFAULT_BLOCK_SZ;
106
107 /* Now we can switch the index. */
108 if (read_cipher_idx == 1) {
109 read_cipher_idx = 0;
110 return;
111 }
112
113 read_cipher_idx = 1;
114 }
115 }
116
switch_write_cipher(void)117 static void switch_write_cipher(void) {
118 /* First, clear the context of the existing read cipher, if any. */
119 if (write_ciphers[write_cipher_idx].key) {
120 clear_cipher(&(write_ciphers[write_cipher_idx]));
121 if (EVP_CIPHER_CTX_cleanup(write_ctxs[write_cipher_idx]) != 1) {
122 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
123 "error clearing cipher context: %s", sftp_crypto_get_errors());
124 }
125
126 cipher_blockszs[write_cipher_idx] = SFTP_CIPHER_DEFAULT_BLOCK_SZ;
127
128 /* Now we can switch the index. */
129 if (write_cipher_idx == 1) {
130 write_cipher_idx = 0;
131 return;
132 }
133
134 write_cipher_idx = 1;
135 }
136 }
137
clear_cipher(struct sftp_cipher * cipher)138 static void clear_cipher(struct sftp_cipher *cipher) {
139 if (cipher->iv) {
140 pr_memscrub(cipher->iv, cipher->iv_len);
141 free(cipher->iv);
142 cipher->iv = NULL;
143 cipher->iv_len = 0;
144 }
145
146 if (cipher->key) {
147 pr_memscrub(cipher->key, cipher->key_len);
148 free(cipher->key);
149 cipher->key = NULL;
150 cipher->key_len = 0;
151 }
152
153 cipher->cipher = NULL;
154 cipher->algo = NULL;
155 }
156
set_cipher_iv(struct sftp_cipher * cipher,const EVP_MD * hash,const unsigned char * k,uint32_t klen,const char * h,uint32_t hlen,char * letter,const unsigned char * id,uint32_t id_len)157 static int set_cipher_iv(struct sftp_cipher *cipher, const EVP_MD *hash,
158 const unsigned char *k, uint32_t klen, const char *h, uint32_t hlen,
159 char *letter, const unsigned char *id, uint32_t id_len) {
160 EVP_MD_CTX *ctx;
161 unsigned char *iv = NULL;
162 size_t cipher_iv_len = 0, iv_sz = 0;
163 uint32_t iv_len = 0;
164
165 if (strncmp(cipher->algo, "none", 5) == 0) {
166 cipher->iv = iv;
167 cipher->iv_len = iv_len;
168
169 return 0;
170 }
171
172 /* Some ciphers do not use IVs; handle this case. */
173 cipher_iv_len = EVP_CIPHER_iv_length(cipher->cipher);
174 if (cipher_iv_len != 0) {
175 iv_sz = sftp_crypto_get_size(cipher_iv_len, EVP_MD_size(hash));
176
177 } else {
178 iv_sz = EVP_MD_size(hash);
179 }
180
181 if (iv_sz == 0) {
182 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
183 "unable to determine IV length for cipher '%s'", cipher->algo);
184 errno = EINVAL;
185 return -1;
186 }
187
188 iv = malloc(iv_sz);
189 if (iv == NULL) {
190 pr_log_pri(PR_LOG_ALERT, MOD_SFTP_VERSION ": Out of memory!");
191 _exit(1);
192 }
193
194 ctx = EVP_MD_CTX_create();
195 EVP_DigestInit(ctx, hash);
196 if (sftp_interop_supports_feature(SFTP_SSH2_FEAT_CIPHER_USE_K)) {
197 EVP_DigestUpdate(ctx, k, klen);
198 }
199 EVP_DigestUpdate(ctx, h, hlen);
200 EVP_DigestUpdate(ctx, letter, sizeof(char));
201 EVP_DigestUpdate(ctx, (char *) id, id_len);
202 EVP_DigestFinal(ctx, iv, &iv_len);
203 EVP_MD_CTX_destroy(ctx);
204
205 /* If we need more, keep hashing, as per RFC, until we have enough
206 * material.
207 */
208 while (iv_sz > iv_len) {
209 uint32_t len = iv_len;
210
211 pr_signals_handle();
212
213 ctx = EVP_MD_CTX_create();
214 EVP_DigestInit(ctx, hash);
215 if (sftp_interop_supports_feature(SFTP_SSH2_FEAT_CIPHER_USE_K)) {
216 EVP_DigestUpdate(ctx, k, klen);
217 }
218 EVP_DigestUpdate(ctx, h, hlen);
219 EVP_DigestUpdate(ctx, iv, len);
220 EVP_DigestFinal(ctx, iv + len, &len);
221 EVP_MD_CTX_destroy(ctx);
222
223 iv_len += len;
224 }
225
226 cipher->iv = iv;
227 cipher->iv_len = iv_len;
228
229 return 0;
230 }
231
set_cipher_key(struct sftp_cipher * cipher,const EVP_MD * hash,const unsigned char * k,uint32_t klen,const char * h,uint32_t hlen,char * letter,const unsigned char * id,uint32_t id_len)232 static int set_cipher_key(struct sftp_cipher *cipher, const EVP_MD *hash,
233 const unsigned char *k, uint32_t klen, const char *h, uint32_t hlen,
234 char *letter, const unsigned char *id, uint32_t id_len) {
235 EVP_MD_CTX *ctx;
236 unsigned char *key = NULL;
237 size_t key_sz = 0;
238 uint32_t key_len = 0;
239
240 if (strncmp(cipher->algo, "none", 5) == 0) {
241 cipher->key = key;
242 cipher->key_len = key_len;
243
244 return 0;
245 }
246
247 key_sz = sftp_crypto_get_size(cipher->key_len > 0 ?
248 cipher->key_len : EVP_CIPHER_key_length(cipher->cipher),
249 EVP_MD_size(hash));
250 if (key_sz == 0) {
251 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
252 "unable to determine key length for cipher '%s'", cipher->algo);
253 errno = EINVAL;
254 return -1;
255 }
256
257 pr_trace_msg(trace_channel, 19, "setting key (%lu bytes) for cipher %s",
258 (unsigned long) key_sz, cipher->algo);
259
260 key = malloc(key_sz);
261 if (key == NULL) {
262 pr_log_pri(PR_LOG_ALERT, MOD_SFTP_VERSION ": Out of memory!");
263 _exit(1);
264 }
265
266 ctx = EVP_MD_CTX_create();
267 EVP_DigestInit(ctx, hash);
268 EVP_DigestUpdate(ctx, k, klen);
269 EVP_DigestUpdate(ctx, h, hlen);
270 EVP_DigestUpdate(ctx, letter, sizeof(char));
271 EVP_DigestUpdate(ctx, (char *) id, id_len);
272 EVP_DigestFinal(ctx, key, &key_len);
273 EVP_MD_CTX_destroy(ctx);
274
275 pr_trace_msg(trace_channel, 19, "hashed data to produce key (%lu bytes)",
276 (unsigned long) key_len);
277
278 /* If we need more, keep hashing, as per RFC, until we have enough
279 * material.
280 */
281 while (key_sz > key_len) {
282 uint32_t len = key_len;
283
284 pr_signals_handle();
285
286 ctx = EVP_MD_CTX_create();
287 EVP_DigestInit(ctx, hash);
288 EVP_DigestUpdate(ctx, k, klen);
289 EVP_DigestUpdate(ctx, h, hlen);
290 EVP_DigestUpdate(ctx, key, len);
291 EVP_DigestFinal(ctx, key + len, &len);
292 EVP_MD_CTX_destroy(ctx);
293
294 key_len += len;
295 }
296
297 cipher->key = key;
298 return 0;
299 }
300
301 /* If the chosen cipher requires that we discard some of the initial bytes of
302 * the cipher stream, then do so. (This is mostly for any RC4 ciphers.)
303 */
set_cipher_discarded(struct sftp_cipher * cipher,EVP_CIPHER_CTX * cipher_ctx)304 static int set_cipher_discarded(struct sftp_cipher *cipher,
305 EVP_CIPHER_CTX *cipher_ctx) {
306 unsigned char *garbage_in, *garbage_out;
307
308 if (cipher->discard_len == 0) {
309 return 0;
310 }
311
312 garbage_in = malloc(cipher->discard_len);
313 if (garbage_in == NULL) {
314 pr_log_pri(PR_LOG_ALERT, MOD_SFTP_VERSION ": Out of memory!");
315 _exit(1);
316 }
317
318 garbage_out = malloc(cipher->discard_len);
319 if (garbage_out == NULL) {
320 free(garbage_in);
321 pr_log_pri(PR_LOG_ALERT, MOD_SFTP_VERSION ": Out of memory!");
322 _exit(1);
323 }
324
325 if (EVP_Cipher(cipher_ctx, garbage_out, garbage_in,
326 cipher->discard_len) != 1) {
327 free(garbage_in);
328 pr_memscrub(garbage_out, cipher->discard_len);
329 free(garbage_out);
330 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
331 "error ciphering discard data: %s", sftp_crypto_get_errors());
332
333 return -1;
334 }
335
336 pr_trace_msg(trace_channel, 19, "discarded %lu bytes of cipher data",
337 (unsigned long) cipher->discard_len);
338 free(garbage_in);
339 pr_memscrub(garbage_out, cipher->discard_len);
340 free(garbage_out);
341
342 return 0;
343 }
344
sftp_cipher_get_block_size(void)345 size_t sftp_cipher_get_block_size(void) {
346 return cipher_blockszs[read_cipher_idx];
347 }
348
sftp_cipher_set_block_size(size_t blocksz)349 void sftp_cipher_set_block_size(size_t blocksz) {
350 if (blocksz > cipher_blockszs[read_cipher_idx]) {
351 cipher_blockszs[read_cipher_idx] = blocksz;
352 }
353 }
354
sftp_cipher_get_read_algo(void)355 const char *sftp_cipher_get_read_algo(void) {
356 if (read_ciphers[read_cipher_idx].key != NULL ||
357 strncmp(read_ciphers[read_cipher_idx].algo, "none", 5) == 0) {
358 return read_ciphers[read_cipher_idx].algo;
359 }
360
361 return NULL;
362 }
363
sftp_cipher_set_read_algo(const char * algo)364 int sftp_cipher_set_read_algo(const char *algo) {
365 unsigned int idx = read_cipher_idx;
366 size_t key_len = 0, discard_len = 0;
367
368 if (read_ciphers[idx].key) {
369 /* If we have an existing key, it means that we are currently rekeying. */
370 idx = get_next_read_index();
371 }
372
373 read_ciphers[idx].cipher = sftp_crypto_get_cipher(algo, &key_len,
374 &discard_len);
375 if (read_ciphers[idx].cipher == NULL) {
376 return -1;
377 }
378
379 if (key_len > 0) {
380 pr_trace_msg(trace_channel, 19,
381 "setting read key for cipher %s: key len = %lu", algo,
382 (unsigned long) key_len);
383 }
384
385 if (discard_len > 0) {
386 pr_trace_msg(trace_channel, 19,
387 "setting read key for cipher %s: discard len = %lu", algo,
388 (unsigned long) discard_len);
389 }
390
391 /* Note that we use a new pool, each time the algorithm is set (which
392 * happens during key exchange) to prevent undue memory growth for
393 * long-lived sessions with many rekeys.
394 */
395 if (read_ciphers[idx].pool != NULL) {
396 destroy_pool(read_ciphers[idx].pool);
397 }
398
399 read_ciphers[idx].pool = make_sub_pool(sftp_pool);
400 pr_pool_tag(read_ciphers[idx].pool, "SFTP cipher read pool");
401 read_ciphers[idx].algo = pstrdup(read_ciphers[idx].pool, algo);
402
403 read_ciphers[idx].key_len = (uint32_t) key_len;
404 read_ciphers[idx].discard_len = discard_len;
405 return 0;
406 }
407
sftp_cipher_set_read_key(pool * p,const EVP_MD * hash,const BIGNUM * k,const char * h,uint32_t hlen,int role)408 int sftp_cipher_set_read_key(pool *p, const EVP_MD *hash, const BIGNUM *k,
409 const char *h, uint32_t hlen, int role) {
410 const unsigned char *id = NULL;
411 unsigned char *buf, *ptr;
412 char letter;
413 uint32_t buflen, bufsz, id_len;
414 int key_len;
415 struct sftp_cipher *cipher;
416 EVP_CIPHER_CTX *cipher_ctx;
417
418 switch_read_cipher();
419
420 cipher = &(read_ciphers[read_cipher_idx]);
421 cipher_ctx = read_ctxs[read_cipher_idx];
422
423 /* XXX EVP_CIPHER_CTX_init() first appeared in OpenSSL 0.9.7. What to do
424 * for older OpenSSL installations?
425 */
426 EVP_CIPHER_CTX_init(cipher_ctx);
427
428 bufsz = buflen = SFTP_CIPHER_BUFSZ;
429 ptr = buf = sftp_msg_getbuf(p, bufsz);
430
431 /* Need to use SSH2-style format of K for the IV and key. */
432 sftp_msg_write_mpint(&buf, &buflen, k);
433
434 id_len = sftp_session_get_id(&id);
435
436 /* The letters used depend on the role; see:
437 * https://tools.ietf.org/html/rfc4253#section-7.2
438 *
439 * If we are the SERVER, then we use the letters for the "client to server"
440 * flows, since we are READING from the client.
441 */
442
443 /* client-to-server IV: HASH(K || H || "A" || session_id)
444 * server-to-client IV: HASH(K || H || "B" || session_id)
445 */
446 letter = (role == SFTP_ROLE_SERVER ? 'A' : 'B');
447 if (set_cipher_iv(cipher, hash, ptr, (bufsz - buflen), h, hlen, &letter, id,
448 id_len) < 0) {
449 pr_memscrub(ptr, bufsz);
450 return -1;
451 }
452
453 /* client-to-server key: HASH(K || H || "C" || session_id)
454 * server-to-client key: HASH(K || H || "D" || session_id)
455 */
456 letter = (role == SFTP_ROLE_SERVER ? 'C' : 'D');
457 if (set_cipher_key(cipher, hash, ptr, (bufsz - buflen), h, hlen, &letter,
458 id, id_len) < 0) {
459 pr_memscrub(ptr, bufsz);
460 return -1;
461 }
462
463 #if defined(PR_USE_OPENSSL_EVP_CIPHERINIT_EX)
464 if (EVP_CipherInit_ex(cipher_ctx, cipher->cipher, NULL, NULL,
465 cipher->iv, 0) != 1) {
466 #else
467 if (EVP_CipherInit(cipher_ctx, cipher->cipher, NULL, cipher->iv, 0) != 1) {
468 #endif /* PR_USE_OPENSSL_EVP_CIPHERINIT_EX */
469 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
470 "error initializing %s cipher for decryption: %s", cipher->algo,
471 sftp_crypto_get_errors());
472 pr_memscrub(ptr, bufsz);
473 return -1;
474 }
475
476 /* Next, set the key length. */
477 key_len = (int) cipher->key_len;
478 if (key_len > 0) {
479 if (EVP_CIPHER_CTX_set_key_length(cipher_ctx, key_len) != 1) {
480 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
481 "error setting key length (%d bytes) for %s cipher for decryption: %s",
482 key_len, cipher->algo, sftp_crypto_get_errors());
483 pr_memscrub(ptr, bufsz);
484 return -1;
485 }
486
487 pr_trace_msg(trace_channel, 19,
488 "set key length (%d) for %s cipher for decryption", key_len,
489 cipher->algo);
490 }
491
492 #if defined(PR_USE_OPENSSL_EVP_CIPHERINIT_EX)
493 if (EVP_CipherInit_ex(cipher_ctx, NULL, NULL, cipher->key, NULL, -1) != 1) {
494 #else
495 if (EVP_CipherInit(cipher_ctx, NULL, cipher->key, NULL, -1) != 1) {
496 #endif /* PR_USE_OPENSSL_EVP_CIPHERINIT_EX */
497 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
498 "error re-initializing %s cipher for decryption: %s", cipher->algo,
499 sftp_crypto_get_errors());
500 pr_memscrub(ptr, bufsz);
501 return -1;
502 }
503
504 if (set_cipher_discarded(cipher, cipher_ctx) < 0) {
505 pr_memscrub(ptr, bufsz);
506 return -1;
507 }
508
509 pr_memscrub(ptr, bufsz);
510 sftp_cipher_set_block_size(EVP_CIPHER_block_size(cipher->cipher));
511 return 0;
512 }
513
514 int sftp_cipher_read_data(pool *p, unsigned char *data, uint32_t data_len,
515 unsigned char **buf, uint32_t *buflen) {
516 struct sftp_cipher *cipher;
517 EVP_CIPHER_CTX *cipher_ctx;
518 size_t cipher_blocksz;
519
520 cipher = &(read_ciphers[read_cipher_idx]);
521 cipher_ctx = read_ctxs[read_cipher_idx];
522 cipher_blocksz = cipher_blockszs[read_cipher_idx];
523
524 if (cipher->key) {
525 int res;
526 unsigned char *ptr = NULL;
527
528 if (*buflen % cipher_blocksz != 0) {
529 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
530 "bad input length for decryption (%u bytes, %u block size)", *buflen,
531 (unsigned int) cipher_blocksz);
532 return -1;
533 }
534
535 if (*buf == NULL) {
536 size_t bufsz;
537
538 /* Allocate a buffer that's large enough. */
539 bufsz = (data_len + cipher_blocksz - 1);
540 ptr = palloc(p, bufsz);
541
542 } else {
543 ptr = *buf;
544 }
545
546 res = EVP_Cipher(cipher_ctx, ptr, data, data_len);
547 if (res != 1) {
548 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
549 "error decrypting %s data from client: %s", cipher->algo,
550 sftp_crypto_get_errors());
551 return -1;
552 }
553
554 *buflen = data_len;
555 *buf = ptr;
556
557 return 0;
558 }
559
560 *buf = data;
561 *buflen = data_len;
562 return 0;
563 }
564
565 const char *sftp_cipher_get_write_algo(void) {
566 if (write_ciphers[write_cipher_idx].key != NULL ||
567 strncmp(write_ciphers[write_cipher_idx].algo, "none", 5) == 0) {
568 return write_ciphers[write_cipher_idx].algo;
569 }
570
571 return NULL;
572 }
573
574 int sftp_cipher_set_write_algo(const char *algo) {
575 unsigned int idx = write_cipher_idx;
576 size_t key_len = 0, discard_len = 0;
577
578 if (write_ciphers[idx].key) {
579 /* If we have an existing key, it means that we are currently rekeying. */
580 idx = get_next_write_index();
581 }
582
583 write_ciphers[idx].cipher = sftp_crypto_get_cipher(algo, &key_len,
584 &discard_len);
585 if (write_ciphers[idx].cipher == NULL) {
586 return -1;
587 }
588
589 if (key_len > 0) {
590 pr_trace_msg(trace_channel, 19,
591 "setting write key for cipher %s: key len = %lu", algo,
592 (unsigned long) key_len);
593 }
594
595 if (discard_len > 0) {
596 pr_trace_msg(trace_channel, 19,
597 "setting write key for cipher %s: discard len = %lu", algo,
598 (unsigned long) discard_len);
599 }
600
601 /* Note that we use a new pool, each time the algorithm is set (which
602 * happens during key exchange) to prevent undue memory growth for
603 * long-lived sessions with many rekeys.
604 */
605 if (write_ciphers[idx].pool != NULL) {
606 destroy_pool(write_ciphers[idx].pool);
607 }
608
609 write_ciphers[idx].pool = make_sub_pool(sftp_pool);
610 pr_pool_tag(write_ciphers[idx].pool, "SFTP cipher write pool");
611 write_ciphers[idx].algo = pstrdup(write_ciphers[idx].pool, algo);
612
613 write_ciphers[idx].key_len = (uint32_t) key_len;
614 write_ciphers[idx].discard_len = discard_len;
615 return 0;
616 }
617
618 int sftp_cipher_set_write_key(pool *p, const EVP_MD *hash, const BIGNUM *k,
619 const char *h, uint32_t hlen, int role) {
620 const unsigned char *id = NULL;
621 unsigned char *buf, *ptr;
622 char letter;
623 uint32_t buflen, bufsz, id_len;
624 int key_len;
625 struct sftp_cipher *cipher;
626 EVP_CIPHER_CTX *cipher_ctx;
627
628 switch_write_cipher();
629
630 cipher = &(write_ciphers[write_cipher_idx]);
631 cipher_ctx = write_ctxs[write_cipher_idx];
632
633 /* XXX EVP_CIPHER_CTX_init() first appeared in OpenSSL 0.9.7. What to do
634 * for older OpenSSL installations?
635 */
636 EVP_CIPHER_CTX_init(cipher_ctx);
637
638 bufsz = buflen = SFTP_CIPHER_BUFSZ;
639 ptr = buf = sftp_msg_getbuf(p, bufsz);
640
641 /* Need to use SSH2-style format of K for the IV and key. */
642 sftp_msg_write_mpint(&buf, &buflen, k);
643
644 id_len = sftp_session_get_id(&id);
645
646 /* The letters used depend on the role; see:
647 * https://tools.ietf.org/html/rfc4253#section-7.2
648 *
649 * If we are the SERVER, then we use the letters for the "server to client"
650 * flows, since we are WRITING to the client.
651 */
652
653 /* client-to-server IV: HASH(K || H || "A" || session_id)
654 * server-to-client IV: HASH(K || H || "B" || session_id)
655 */
656 letter = (role == SFTP_ROLE_SERVER ? 'B' : 'A');
657 if (set_cipher_iv(cipher, hash, ptr, (bufsz - buflen), h, hlen, &letter, id,
658 id_len) < 0) {
659 pr_memscrub(ptr, bufsz);
660 return -1;
661 }
662
663 /* client-to-server key: HASH(K || H || "C" || session_id)
664 * server-to-client key: HASH(K || H || "D" || session_id)
665 */
666 letter = (role == SFTP_ROLE_SERVER ? 'D' : 'C');
667 if (set_cipher_key(cipher, hash, ptr, (bufsz - buflen), h, hlen, &letter,
668 id, id_len) < 0) {
669 pr_memscrub(ptr, bufsz);
670 return -1;
671 }
672
673 #if defined(PR_USE_OPENSSL_EVP_CIPHERINIT_EX)
674 if (EVP_CipherInit_ex(cipher_ctx, cipher->cipher, NULL, NULL,
675 cipher->iv, 1) != 1) {
676 #else
677 if (EVP_CipherInit(cipher_ctx, cipher->cipher, NULL, cipher->iv, 1) != 1) {
678 #endif /* PR_USE_OPENSSL_EVP_CIPHERINIT_EX */
679 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
680 "error initializing %s cipher for encryption: %s", cipher->algo,
681 sftp_crypto_get_errors());
682 pr_memscrub(ptr, bufsz);
683 return -1;
684 }
685
686 /* Next, set the key length. */
687 key_len = (int) cipher->key_len;
688 if (key_len > 0) {
689 if (EVP_CIPHER_CTX_set_key_length(cipher_ctx, key_len) != 1) {
690 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
691 "error setting key length (%d bytes) for %s cipher for decryption: %s",
692 key_len, cipher->algo, sftp_crypto_get_errors());
693 pr_memscrub(ptr, bufsz);
694 return -1;
695 }
696
697 pr_trace_msg(trace_channel, 19,
698 "set key length (%d) for %s cipher for encryption", key_len,
699 cipher->algo);
700 }
701
702 #if defined(PR_USE_OPENSSL_EVP_CIPHERINIT_EX)
703 if (EVP_CipherInit_ex(cipher_ctx, NULL, NULL, cipher->key, NULL, -1) != 1) {
704 #else
705 if (EVP_CipherInit(cipher_ctx, NULL, cipher->key, NULL, -1) != 1) {
706 #endif /* PR_USE_OPENSSL_EVP_CIPHERINIT_EX */
707 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
708 "error re-initializing %s cipher for encryption: %s", cipher->algo,
709 sftp_crypto_get_errors());
710 pr_memscrub(ptr, bufsz);
711 return -1;
712 }
713
714 if (set_cipher_discarded(cipher, cipher_ctx) < 0) {
715 pr_memscrub(ptr, bufsz);
716 return -1;
717 }
718
719 pr_memscrub(ptr, bufsz);
720 return 0;
721 }
722
723 int sftp_cipher_write_data(struct ssh2_packet *pkt, unsigned char *buf,
724 size_t *buflen) {
725 struct sftp_cipher *cipher;
726 EVP_CIPHER_CTX *cipher_ctx;
727
728 cipher = &(write_ciphers[write_cipher_idx]);
729 cipher_ctx = write_ctxs[write_cipher_idx];
730
731 if (cipher->key) {
732 int res;
733 unsigned char *data, *ptr;
734 uint32_t datalen, datasz = sizeof(uint32_t) + pkt->packet_len;
735
736 datalen = datasz;
737 ptr = data = palloc(pkt->pool, datasz);
738
739 sftp_msg_write_int(&data, &datalen, pkt->packet_len);
740 sftp_msg_write_byte(&data, &datalen, pkt->padding_len);
741 sftp_msg_write_data(&data, &datalen, pkt->payload, pkt->payload_len, FALSE);
742 sftp_msg_write_data(&data, &datalen, pkt->padding, pkt->padding_len, FALSE);
743
744 res = EVP_Cipher(cipher_ctx, buf, ptr, (datasz - datalen));
745 if (res != 1) {
746 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
747 "error encrypting %s data for client: %s", cipher->algo,
748 sftp_crypto_get_errors());
749 errno = EIO;
750 return -1;
751 }
752
753 *buflen = (datasz - datalen);
754
755 #ifdef SFTP_DEBUG_PACKET
756 {
757 unsigned int i;
758
759 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
760 "encrypted packet data (len %lu):", (unsigned long) *buflen);
761 for (i = 0; i < *buflen;) {
762 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
763 " %02x%02x %02x%02x %02x%02x %02x%02x",
764 ((unsigned char *) buf)[i], ((unsigned char *) buf)[i+1],
765 ((unsigned char *) buf)[i+2], ((unsigned char *) buf)[i+3],
766 ((unsigned char *) buf)[i+4], ((unsigned char *) buf)[i+5],
767 ((unsigned char *) buf)[i+6], ((unsigned char *) buf)[i+7]);
768 i += 8;
769 }
770 }
771 #endif
772
773 return 0;
774 }
775
776 *buflen = 0;
777 return 0;
778 }
779
780 #if OPENSSL_VERSION_NUMBER < 0x1000000fL
781 /* In older versions of OpenSSL, there was not a way to dynamically allocate
782 * an EVP_CIPHER_CTX object. Thus we have these static objects for those
783 * older versions.
784 */
785 static EVP_CIPHER_CTX read_ctx1, read_ctx2;
786 static EVP_CIPHER_CTX write_ctx1, write_ctx2;
787 #endif /* prior to OpenSSL-1.0.0 */
788
789 int sftp_cipher_init(void) {
790 #if OPENSSL_VERSION_NUMBER < 0x1000000fL
791 read_ctxs[0] = &read_ctx1;
792 read_ctxs[1] = &read_ctx2;
793 write_ctxs[0] = &write_ctx1;
794 write_ctxs[1] = &write_ctx2;
795 #else
796 read_ctxs[0] = EVP_CIPHER_CTX_new();
797 read_ctxs[1] = EVP_CIPHER_CTX_new();
798 write_ctxs[0] = EVP_CIPHER_CTX_new();
799 write_ctxs[1] = EVP_CIPHER_CTX_new();
800 #endif /* OpenSSL-1.0.0 and later */
801 return 0;
802 }
803
804 int sftp_cipher_free(void) {
805 #if OPENSSL_VERSION_NUMBER >= 0x1000000fL
806 EVP_CIPHER_CTX_free(read_ctxs[0]);
807 EVP_CIPHER_CTX_free(read_ctxs[1]);
808 EVP_CIPHER_CTX_free(write_ctxs[0]);
809 EVP_CIPHER_CTX_free(write_ctxs[1]);
810 #endif /* OpenSSL-1.0.0 and later */
811 return 0;
812 }
813