1 /*
2 * ProFTPD - mod_sftp MACs
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 #include "ssh2.h"
27 #include "msg.h"
28 #include "packet.h"
29 #include "crypto.h"
30 #include "mac.h"
31 #include "session.h"
32 #include "disconnect.h"
33 #include "interop.h"
34 #include "umac.h"
35
36 struct sftp_mac {
37 pool *pool;
38 const char *algo;
39 int algo_type;
40
41 const EVP_MD *digest;
42
43 unsigned char *key;
44
45 /* The keysz and key_len are usually the same; they can differ if, for
46 * example, the client always truncates the MAC key len to 16 bits.
47 */
48 size_t keysz;
49 uint32_t key_len;
50
51 uint32_t mac_len;
52 };
53
54 #define SFTP_MAC_ALGO_TYPE_HMAC 1
55 #define SFTP_MAC_ALGO_TYPE_UMAC64 2
56 #define SFTP_MAC_ALGO_TYPE_UMAC128 3
57
58 #define SFTP_MAC_FL_READ_MAC 1
59 #define SFTP_MAC_FL_WRITE_MAC 2
60
61 /* We need to keep the old MACs around, so that we can handle N arbitrary
62 * packets to/from the client using the old keys, as during rekeying.
63 * Thus we have two read MAC contexts, two write MAC contexts.
64 * The cipher idx variable indicates which of the MACs is currently in use.
65 */
66
67 static struct sftp_mac read_macs[] = {
68 { NULL, NULL, 0, NULL, NULL, 0, 0, 0 },
69 { NULL, NULL, 0, NULL, NULL, 0, 0, 0 }
70 };
71 static HMAC_CTX *hmac_read_ctxs[2];
72 static struct umac_ctx *umac_read_ctxs[2];
73
74 static struct sftp_mac write_macs[] = {
75 { NULL, NULL, 0, NULL, NULL, 0, 0, 0 },
76 { NULL, NULL, 0, NULL, NULL, 0, 0, 0 }
77 };
78 static HMAC_CTX *hmac_write_ctxs[2];
79 static struct umac_ctx *umac_write_ctxs[2];
80
81 static size_t mac_blockszs[2] = { 0, 0 };
82
83 /* Buffer size for reading/writing keys */
84 #define SFTP_MAC_BUFSZ 4096
85
86 static unsigned int read_mac_idx = 0;
87 static unsigned int write_mac_idx = 0;
88
89 static void clear_mac(struct sftp_mac *);
90
get_next_read_index(void)91 static unsigned int get_next_read_index(void) {
92 if (read_mac_idx == 1) {
93 return 0;
94 }
95
96 return 1;
97 }
98
get_next_write_index(void)99 static unsigned int get_next_write_index(void) {
100 if (write_mac_idx == 1) {
101 return 0;
102 }
103
104 return 1;
105 }
106
switch_read_mac(void)107 static void switch_read_mac(void) {
108 /* First we can clear the read MAC, kept from rekeying. */
109 if (read_macs[read_mac_idx].key) {
110 clear_mac(&(read_macs[read_mac_idx]));
111 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
112 !defined(HAVE_LIBRESSL)
113 HMAC_CTX_reset(hmac_read_ctxs[read_mac_idx]);
114 #elif OPENSSL_VERSION_NUMBER > 0x000907000L
115 HMAC_CTX_cleanup(hmac_read_ctxs[read_mac_idx]);
116 #else
117 HMAC_cleanup(hmac_read_ctxs[read_mac_idx]);
118 #endif
119 if (read_macs[read_mac_idx].algo_type == SFTP_MAC_ALGO_TYPE_UMAC64) {
120 umac_reset(umac_read_ctxs[read_mac_idx]);
121
122 } else if (read_macs[read_mac_idx].algo_type == SFTP_MAC_ALGO_TYPE_UMAC128) {
123 umac128_reset(umac_read_ctxs[read_mac_idx]);
124 }
125
126 mac_blockszs[read_mac_idx] = 0;
127
128 /* Now we can switch the index. */
129 if (read_mac_idx == 1) {
130 read_mac_idx = 0;
131 return;
132 }
133
134 read_mac_idx = 1;
135 }
136 }
137
switch_write_mac(void)138 static void switch_write_mac(void) {
139 /* First we can clear the write MAC, kept from rekeying. */
140 if (write_macs[write_mac_idx].key) {
141 clear_mac(&(write_macs[write_mac_idx]));
142 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
143 !defined(HAVE_LIBRESSL)
144 HMAC_CTX_reset(hmac_write_ctxs[write_mac_idx]);
145 #elif OPENSSL_VERSION_NUMBER > 0x000907000L
146 HMAC_CTX_cleanup(hmac_write_ctxs[write_mac_idx]);
147 #else
148 HMAC_cleanup(hmac_write_ctxs[write_mac_idx]);
149 #endif
150 if (write_macs[write_mac_idx].algo_type == SFTP_MAC_ALGO_TYPE_UMAC64) {
151 umac_reset(umac_write_ctxs[write_mac_idx]);
152
153 } else if (write_macs[write_mac_idx].algo_type == SFTP_MAC_ALGO_TYPE_UMAC128) {
154 umac128_reset(umac_write_ctxs[write_mac_idx]);
155 }
156
157 /* Now we can switch the index. */
158 if (write_mac_idx == 1) {
159 write_mac_idx = 0;
160 return;
161 }
162
163 write_mac_idx = 1;
164 }
165 }
166
clear_mac(struct sftp_mac * mac)167 static void clear_mac(struct sftp_mac *mac) {
168 if (mac->key) {
169 pr_memscrub(mac->key, mac->keysz);
170 free(mac->key);
171 mac->key = NULL;
172 mac->keysz = 0;
173 mac->key_len = 0;
174 }
175
176 mac->digest = NULL;
177 mac->algo = NULL;
178 }
179
init_mac(pool * p,struct sftp_mac * mac,HMAC_CTX * hmac_ctx,struct umac_ctx * umac_ctx)180 static int init_mac(pool *p, struct sftp_mac *mac, HMAC_CTX *hmac_ctx,
181 struct umac_ctx *umac_ctx) {
182 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
183 !defined(HAVE_LIBRESSL)
184 HMAC_CTX_reset(hmac_ctx);
185 #elif OPENSSL_VERSION_NUMBER > 0x000907000L
186 HMAC_CTX_init(hmac_ctx);
187 #else
188 /* Reset the HMAC context. */
189 HMAC_Init(hmac_ctx, NULL, 0, NULL);
190 #endif
191
192 if (mac->algo_type == SFTP_MAC_ALGO_TYPE_HMAC) {
193 #if OPENSSL_VERSION_NUMBER > 0x000907000L
194 # if OPENSSL_VERSION_NUMBER >= 0x10000001L
195 if (HMAC_Init_ex(hmac_ctx, mac->key, mac->key_len, mac->digest,
196 NULL) != 1) {
197 pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
198 "error initializing HMAC: %s", sftp_crypto_get_errors());
199 errno = EPERM;
200 return -1;
201 }
202
203 # else
204 HMAC_Init_ex(hmac_ctx, mac->key, mac->key_len, mac->digest, NULL);
205 # endif /* OpenSSL-1.0.0 and later */
206
207 #else
208 HMAC_Init(hmac_ctx, mac->key, mac->key_len, mac->digest);
209 #endif
210
211 } else if (mac->algo_type == SFTP_MAC_ALGO_TYPE_UMAC64) {
212 umac_reset(umac_ctx);
213 umac_init(umac_ctx, mac->key);
214
215 } else if (mac->algo_type == SFTP_MAC_ALGO_TYPE_UMAC128) {
216 umac128_reset(umac_ctx);
217 umac128_init(umac_ctx, mac->key);
218 }
219
220 return 0;
221 }
222
get_mac(struct ssh2_packet * pkt,struct sftp_mac * mac,HMAC_CTX * hmac_ctx,struct umac_ctx * umac_ctx,int flags)223 static int get_mac(struct ssh2_packet *pkt, struct sftp_mac *mac,
224 HMAC_CTX *hmac_ctx, struct umac_ctx *umac_ctx, int flags) {
225 unsigned char *mac_data;
226 unsigned char *buf, *ptr;
227 uint32_t buflen, bufsz = 0, mac_len = 0;
228
229 if (mac->algo_type == SFTP_MAC_ALGO_TYPE_HMAC) {
230 bufsz = (sizeof(uint32_t) * 2) + pkt->packet_len;
231 mac_data = pcalloc(pkt->pool, EVP_MAX_MD_SIZE);
232
233 buflen = bufsz;
234 ptr = buf = sftp_msg_getbuf(pkt->pool, bufsz);
235
236 sftp_msg_write_int(&buf, &buflen, pkt->seqno);
237 sftp_msg_write_int(&buf, &buflen, pkt->packet_len);
238 sftp_msg_write_byte(&buf, &buflen, pkt->padding_len);
239 sftp_msg_write_data(&buf, &buflen, pkt->payload, pkt->payload_len, FALSE);
240 sftp_msg_write_data(&buf, &buflen, pkt->padding, pkt->padding_len, FALSE);
241
242 #if OPENSSL_VERSION_NUMBER > 0x000907000L
243 # if OPENSSL_VERSION_NUMBER >= 0x10000001L
244 if (HMAC_Init_ex(hmac_ctx, NULL, 0, NULL, NULL) != 1) {
245 pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
246 "error resetting HMAC context: %s", sftp_crypto_get_errors());
247 errno = EPERM;
248 return -1;
249 }
250 # else
251 HMAC_Init_ex(hmac_ctx, NULL, 0, NULL, NULL);
252 # endif /* OpenSSL-1.0.0 and later */
253
254 #else
255 HMAC_Init(hmac_ctx, NULL, 0, NULL);
256 #endif /* OpenSSL-0.9.7 and later */
257
258 #if OPENSSL_VERSION_NUMBER >= 0x10000001L
259 if (HMAC_Update(hmac_ctx, ptr, (bufsz - buflen)) != 1) {
260 pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
261 "error adding %lu bytes of data to HMAC context: %s",
262 (unsigned long) (bufsz - buflen), sftp_crypto_get_errors());
263 errno = EPERM;
264 return -1;
265 }
266
267 if (HMAC_Final(hmac_ctx, mac_data, &mac_len) != 1) {
268 pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
269 "error finalizing HMAC context: %s", sftp_crypto_get_errors());
270 errno = EPERM;
271 return -1;
272 }
273 #else
274 HMAC_Update(hmac_ctx, ptr, (bufsz - buflen));
275 HMAC_Final(hmac_ctx, mac_data, &mac_len);
276 #endif /* OpenSSL-1.0.0 and later */
277
278 } else if (mac->algo_type == SFTP_MAC_ALGO_TYPE_UMAC64 ||
279 mac->algo_type == SFTP_MAC_ALGO_TYPE_UMAC128) {
280 unsigned char nonce[8], *nonce_ptr;
281 uint32_t nonce_len = 0;
282
283 bufsz = sizeof(uint32_t) + pkt->packet_len;
284 mac_data = pcalloc(pkt->pool, EVP_MAX_MD_SIZE);
285
286 buflen = bufsz;
287 ptr = buf = sftp_msg_getbuf(pkt->pool, bufsz);
288
289 sftp_msg_write_int(&buf, &buflen, pkt->packet_len);
290 sftp_msg_write_byte(&buf, &buflen, pkt->padding_len);
291 sftp_msg_write_data(&buf, &buflen, pkt->payload, pkt->payload_len, FALSE);
292 sftp_msg_write_data(&buf, &buflen, pkt->padding, pkt->padding_len, FALSE);
293
294 nonce_ptr = nonce;
295 nonce_len = sizeof(nonce);
296 sftp_msg_write_long(&nonce_ptr, &nonce_len, pkt->seqno);
297
298 if (mac->algo_type == SFTP_MAC_ALGO_TYPE_UMAC64) {
299 umac_reset(umac_ctx);
300 umac_update(umac_ctx, ptr, (bufsz - buflen));
301 umac_final(umac_ctx, mac_data, nonce);
302 mac_len = 8;
303
304 } else if (mac->algo_type == SFTP_MAC_ALGO_TYPE_UMAC128) {
305 umac128_reset(umac_ctx);
306 umac128_update(umac_ctx, ptr, (bufsz - buflen));
307 umac128_final(umac_ctx, mac_data, nonce);
308 mac_len = 16;
309 }
310 }
311
312 if (mac_len == 0) {
313 pkt->mac = NULL;
314 pkt->mac_len = 0;
315
316 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
317 "error computing MAC using %s: %s", mac->algo,
318 sftp_crypto_get_errors());
319
320 errno = EIO;
321 return -1;
322 }
323
324 if (mac->mac_len != 0) {
325 mac_len = mac->mac_len;
326 }
327
328 if (flags & SFTP_MAC_FL_READ_MAC) {
329 if (memcmp(mac_data, pkt->mac, mac_len) != 0) {
330 unsigned int i = 0;
331
332 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
333 "MAC from client differs from expected MAC using %s", mac->algo);
334
335 #ifdef SFTP_DEBUG_PACKET
336 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
337 "client MAC (len %lu):", (unsigned long) pkt->mac_len);
338 for (i = 0; i < mac_len;) {
339 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
340 " %02x%02x %02x%02x %02x%02x %02x%02x",
341 ((unsigned char *) pkt->mac)[i], ((unsigned char *) pkt->mac)[i+1],
342 ((unsigned char *) pkt->mac)[i+2], ((unsigned char *) pkt->mac)[i+3],
343 ((unsigned char *) pkt->mac)[i+4], ((unsigned char *) pkt->mac)[i+5],
344 ((unsigned char *) pkt->mac)[i+6], ((unsigned char *) pkt->mac)[i+7]);
345 i += 8;
346 }
347
348 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
349 "server MAC (len %lu):", (unsigned long) mac_len);
350 for (i = 0; i < mac_len;) {
351 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
352 " %02x%02x %02x%02x %02x%02x %02x%02x",
353 ((unsigned char *) mac)[i], ((unsigned char *) mac)[i+1],
354 ((unsigned char *) mac)[i+2], ((unsigned char *) mac)[i+3],
355 ((unsigned char *) mac)[i+4], ((unsigned char *) mac)[i+5],
356 ((unsigned char *) mac)[i+6], ((unsigned char *) mac)[i+7]);
357 i += 8;
358 }
359 #else
360 /* Avoid compiler warning. */
361 (void) i;
362 #endif
363
364 errno = EINVAL;
365 return -1;
366 }
367
368 } else if (flags & SFTP_MAC_FL_WRITE_MAC) {
369 /* Debugging. */
370 #ifdef SFTP_DEBUG_PACKET
371 if (pkt->mac_len > 0) {
372 unsigned int i = 0;
373
374 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
375 "server MAC (len %lu, seqno %lu):",
376 (unsigned long) pkt->mac_len, (unsigned long) pkt->seqno);
377 for (i = 0; i < mac_len;) {
378 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
379 " %02x%02x %02x%02x %02x%02x %02x%02x",
380 ((unsigned char *) pkt->mac)[i], ((unsigned char *) pkt->mac)[i+1],
381 ((unsigned char *) pkt->mac)[i+2], ((unsigned char *) pkt->mac)[i+3],
382 ((unsigned char *) pkt->mac)[i+4], ((unsigned char *) pkt->mac)[i+5],
383 ((unsigned char *) pkt->mac)[i+6], ((unsigned char *) pkt->mac)[i+7]);
384 i += 8;
385 }
386 }
387 #endif
388 }
389
390 pkt->mac_len = mac_len;
391 pkt->mac = pcalloc(pkt->pool, pkt->mac_len);
392 memcpy(pkt->mac, mac_data, mac_len);
393
394 return 0;
395 }
396
set_mac_key(struct sftp_mac * mac,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)397 static int set_mac_key(struct sftp_mac *mac, const EVP_MD *hash,
398 const unsigned char *k, uint32_t klen, const char *h, uint32_t hlen,
399 char *letter, const unsigned char *id, uint32_t id_len) {
400 #if OPENSSL_VERSION_NUMBER < 0x10100000L || \
401 defined(HAVE_LIBRESSL)
402 EVP_MD_CTX ctx;
403 #endif /* prior to OpenSSL-1.1.0 */
404 EVP_MD_CTX *pctx;
405 unsigned char *key = NULL;
406 size_t key_sz;
407 uint32_t key_len = 0;
408
409 key_sz = sftp_crypto_get_size(EVP_MD_block_size(mac->digest),
410 EVP_MD_size(hash));
411 if (key_sz == 0) {
412 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
413 "unable to determine key length for MAC '%s'", mac->algo);
414 errno = EINVAL;
415 return -1;
416 }
417
418 key = malloc(key_sz);
419 if (key == NULL) {
420 pr_log_pri(PR_LOG_ALERT, MOD_SFTP_VERSION ": Out of memory!");
421 _exit(1);
422 }
423
424 #if OPENSSL_VERSION_NUMBER < 0x10100000L || \
425 defined(HAVE_LIBRESSL)
426 pctx = &ctx;
427 #else
428 pctx = EVP_MD_CTX_new();
429 #endif /* prior to OpenSSL-1.1.0 */
430
431 /* In OpenSSL 0.9.6, many of the EVP_Digest* functions returned void, not
432 * int. Without these ugly OpenSSL version preprocessor checks, the
433 * compiler will error out with "void value not ignored as it ought to be".
434 */
435
436 #if OPENSSL_VERSION_NUMBER >= 0x000907000L
437 if (EVP_DigestInit(pctx, hash) != 1) {
438 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
439 "error initializing message digest: %s", sftp_crypto_get_errors());
440 free(key);
441 # if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
442 !defined(HAVE_LIBRESSL)
443 EVP_MD_CTX_free(pctx);
444 # endif /* OpenSSL-1.1.0 and later */
445 return -1;
446 }
447 #else
448 EVP_DigestInit(pctx, hash);
449 #endif
450
451 #if OPENSSL_VERSION_NUMBER >= 0x000907000L
452 if (EVP_DigestUpdate(pctx, k, klen) != 1) {
453 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
454 "error updating message digest with K: %s", sftp_crypto_get_errors());
455 free(key);
456 # if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
457 !defined(HAVE_LIBRESSL)
458 EVP_MD_CTX_free(pctx);
459 # endif /* OpenSSL-1.1.0 and later */
460 return -1;
461 }
462 #else
463 EVP_DigestUpdate(pctx, k, klen);
464 #endif
465
466 #if OPENSSL_VERSION_NUMBER >= 0x000907000L
467 if (EVP_DigestUpdate(pctx, h, hlen) != 1) {
468 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
469 "error updating message digest with H: %s", sftp_crypto_get_errors());
470 free(key);
471 # if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
472 !defined(HAVE_LIBRESSL)
473 EVP_MD_CTX_free(pctx);
474 # endif /* OpenSSL-1.1.0 and later */
475 return -1;
476 }
477 #else
478 EVP_DigestUpdate(pctx, h, hlen);
479 #endif
480
481 #if OPENSSL_VERSION_NUMBER >= 0x000907000L
482 if (EVP_DigestUpdate(pctx, letter, sizeof(char)) != 1) {
483 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
484 "error updating message digest with '%c': %s", *letter,
485 sftp_crypto_get_errors());
486 free(key);
487 # if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
488 !defined(HAVE_LIBRESSL)
489 EVP_MD_CTX_free(pctx);
490 # endif /* OpenSSL-1.1.0 and later */
491 return -1;
492 }
493 #else
494 EVP_DigestUpdate(pctx, letter, sizeof(char));
495 #endif
496
497 #if OPENSSL_VERSION_NUMBER >= 0x000907000L
498 if (EVP_DigestUpdate(pctx, (char *) id, id_len) != 1) {
499 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
500 "error updating message digest with ID: %s", sftp_crypto_get_errors());
501 free(key);
502 # if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
503 !defined(HAVE_LIBRESSL)
504 EVP_MD_CTX_free(pctx);
505 # endif /* OpenSSL-1.1.0 and later */
506 return -1;
507 }
508 #else
509 EVP_DigestUpdate(pctx, (char *) id, id_len);
510 #endif
511
512 #if OPENSSL_VERSION_NUMBER >= 0x000907000L
513 if (EVP_DigestFinal(pctx, key, &key_len) != 1) {
514 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
515 "error finalizing message digest: %s", sftp_crypto_get_errors());
516 pr_memscrub(key, key_sz);
517 free(key);
518 # if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
519 !defined(HAVE_LIBRESSL)
520 EVP_MD_CTX_free(pctx);
521 # endif /* OpenSSL-1.1.0 and later */
522 return -1;
523 }
524 #else
525 EVP_DigestFinal(pctx, key, &key_len);
526 #endif
527
528 /* If we need more, keep hashing, as per RFC, until we have enough
529 * material.
530 */
531
532 while (key_sz > key_len) {
533 uint32_t len = key_len;
534
535 pr_signals_handle();
536
537 #if OPENSSL_VERSION_NUMBER >= 0x000907000L
538 if (EVP_DigestInit(pctx, hash) != 1) {
539 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
540 "error initializing message digest: %s", sftp_crypto_get_errors());
541 pr_memscrub(key, key_sz);
542 free(key);
543 # if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
544 !defined(HAVE_LIBRESSL)
545 EVP_MD_CTX_free(pctx);
546 # endif /* OpenSSL-1.1.0 and later */
547 return -1;
548 }
549 #else
550 EVP_DigestInit(pctx, hash);
551 #endif
552
553 #if OPENSSL_VERSION_NUMBER >= 0x000907000L
554 if (EVP_DigestUpdate(pctx, k, klen) != 1) {
555 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
556 "error updating message digest with K: %s", sftp_crypto_get_errors());
557 pr_memscrub(key, key_sz);
558 free(key);
559 # if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
560 !defined(HAVE_LIBRESSL)
561 EVP_MD_CTX_free(pctx);
562 # endif /* OpenSSL-1.1.0 and later */
563 return -1;
564 }
565 #else
566 EVP_DigestUpdate(pctx, k, klen);
567 #endif
568
569 #if OPENSSL_VERSION_NUMBER >= 0x000907000L
570 if (EVP_DigestUpdate(pctx, h, hlen) != 1) {
571 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
572 "error updating message digest with H: %s", sftp_crypto_get_errors());
573 pr_memscrub(key, key_sz);
574 free(key);
575 # if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
576 !defined(HAVE_LIBRESSL)
577 EVP_MD_CTX_free(pctx);
578 # endif /* OpenSSL-1.1.0 and later */
579 return -1;
580 }
581 #else
582 EVP_DigestUpdate(pctx, h, hlen);
583 #endif
584
585 #if OPENSSL_VERSION_NUMBER >= 0x000907000L
586 if (EVP_DigestUpdate(pctx, key, len) != 1) {
587 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
588 "error updating message digest with data: %s",
589 sftp_crypto_get_errors());
590 pr_memscrub(key, key_sz);
591 free(key);
592 # if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
593 !defined(HAVE_LIBRESSL)
594 EVP_MD_CTX_free(pctx);
595 # endif /* OpenSSL-1.1.0 and later */
596 return -1;
597 }
598 #else
599 EVP_DigestUpdate(pctx, key, len);
600 #endif
601
602 #if OPENSSL_VERSION_NUMBER >= 0x000907000L
603 if (EVP_DigestFinal(pctx, key + len, &len) != 1) {
604 (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
605 "error finalizing message digest: %s", sftp_crypto_get_errors());
606 pr_memscrub(key, key_sz);
607 free(key);
608 # if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
609 !defined(HAVE_LIBRESSL)
610 EVP_MD_CTX_free(pctx);
611 # endif /* OpenSSL-1.1.0 and later */
612 return -1;
613 }
614 #else
615 EVP_DigestFinal(pctx, key + len, &len);
616 #endif
617
618 key_len += len;
619 }
620
621 mac->key = key;
622 mac->keysz = key_sz;
623
624 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
625 !defined(HAVE_LIBRESSL)
626 EVP_MD_CTX_free(pctx);
627 #endif /* OpenSSL-1.1.0 and later */
628
629 if (mac->algo_type == SFTP_MAC_ALGO_TYPE_HMAC) {
630 mac->key_len = EVP_MD_size(mac->digest);
631
632 } else if (mac->algo_type == SFTP_MAC_ALGO_TYPE_UMAC64 ||
633 mac->algo_type == SFTP_MAC_ALGO_TYPE_UMAC128) {
634 mac->key_len = EVP_MD_block_size(mac->digest);
635 }
636
637 if (!sftp_interop_supports_feature(SFTP_SSH2_FEAT_MAC_LEN)) {
638 mac->key_len = 16;
639 }
640
641 return 0;
642 }
643
sftp_mac_get_block_size(void)644 size_t sftp_mac_get_block_size(void) {
645 return mac_blockszs[read_mac_idx];
646 }
647
sftp_mac_set_block_size(size_t blocksz)648 void sftp_mac_set_block_size(size_t blocksz) {
649 if (blocksz > mac_blockszs[read_mac_idx]) {
650 mac_blockszs[read_mac_idx] = blocksz;
651 }
652 }
653
sftp_mac_get_read_algo(void)654 const char *sftp_mac_get_read_algo(void) {
655 if (read_macs[read_mac_idx].key) {
656 return read_macs[read_mac_idx].algo;
657 }
658
659 return NULL;
660 }
661
sftp_mac_set_read_algo(const char * algo)662 int sftp_mac_set_read_algo(const char *algo) {
663 uint32_t mac_len;
664 unsigned int idx = read_mac_idx;
665
666 if (read_macs[idx].key) {
667 /* If we have an existing key, it means that we are currently rekeying. */
668 idx = get_next_read_index();
669 }
670
671 /* Clear any potential UMAC contexts at this index. */
672 if (umac_read_ctxs[idx] != NULL) {
673 switch (read_macs[idx].algo_type) {
674 case SFTP_MAC_ALGO_TYPE_UMAC64:
675 umac_delete(umac_read_ctxs[idx]);
676 umac_read_ctxs[idx] = NULL;
677 break;
678
679 case SFTP_MAC_ALGO_TYPE_UMAC128:
680 umac128_delete(umac_read_ctxs[idx]);
681 umac_read_ctxs[idx] = NULL;
682 break;
683 }
684 }
685
686 read_macs[idx].digest = sftp_crypto_get_digest(algo, &mac_len);
687 if (read_macs[idx].digest == NULL) {
688 return -1;
689 }
690
691 /* Note that we use a new pool, each time the algorithm is set (which
692 * happens during key exchange) to prevent undue memory growth for
693 * long-lived sessions with many rekeys.
694 */
695 if (read_macs[idx].pool != NULL) {
696 destroy_pool(read_macs[idx].pool);
697 }
698
699 read_macs[idx].pool = make_sub_pool(sftp_pool);
700 pr_pool_tag(read_macs[idx].pool, "SFTP MAC read pool");
701 read_macs[idx].algo = pstrdup(read_macs[idx].pool, algo);
702
703 if (strncmp(read_macs[idx].algo, "umac-64@openssh.com", 12) == 0) {
704 read_macs[idx].algo_type = SFTP_MAC_ALGO_TYPE_UMAC64;
705 umac_read_ctxs[idx] = umac_alloc();
706
707 } else if (strncmp(read_macs[idx].algo, "umac-128@openssh.com", 13) == 0) {
708 read_macs[idx].algo_type = SFTP_MAC_ALGO_TYPE_UMAC128;
709 umac_read_ctxs[idx] = umac128_alloc();
710
711 } else {
712 read_macs[idx].algo_type = SFTP_MAC_ALGO_TYPE_HMAC;
713 }
714
715 read_macs[idx].mac_len = mac_len;
716 return 0;
717 }
718
sftp_mac_set_read_key(pool * p,const EVP_MD * hash,const BIGNUM * k,const char * h,uint32_t hlen,int role)719 int sftp_mac_set_read_key(pool *p, const EVP_MD *hash, const BIGNUM *k,
720 const char *h, uint32_t hlen, int role) {
721 const unsigned char *id = NULL;
722 unsigned char *buf, *ptr;
723 uint32_t buflen, bufsz, id_len;
724 char letter;
725 size_t blocksz;
726 struct sftp_mac *mac;
727 HMAC_CTX *hmac_ctx;
728 struct umac_ctx *umac_ctx;
729
730 switch_read_mac();
731
732 mac = &(read_macs[read_mac_idx]);
733 hmac_ctx = hmac_read_ctxs[read_mac_idx];
734 umac_ctx = umac_read_ctxs[read_mac_idx];
735
736 bufsz = buflen = SFTP_MAC_BUFSZ;
737 ptr = buf = sftp_msg_getbuf(p, bufsz);
738
739 /* Need to use SSH2-style format of K for the key. */
740 sftp_msg_write_mpint(&buf, &buflen, k);
741
742 id_len = sftp_session_get_id(&id);
743
744 /* The letters used depend on the role; see:
745 * https://tools.ietf.org/html/rfc4253#section-7.2
746 *
747 * If we are the SERVER, then we use the letters for the "client to server"
748 * flows, since we are READING from the client.
749 */
750
751 /* client-to-server HASH(K || H || "E" || session_id)
752 * server-to-client HASH(K || H || "F" || session_id)
753 */
754 letter = (role == SFTP_ROLE_SERVER ? 'E' : 'F');
755 set_mac_key(mac, hash, ptr, (bufsz - buflen), h, hlen, &letter, id, id_len);
756
757 if (init_mac(p, mac, hmac_ctx, umac_ctx) < 0) {
758 return -1;
759 }
760
761 if (mac->mac_len == 0) {
762 blocksz = EVP_MD_size(mac->digest);
763
764 } else {
765 blocksz = mac->mac_len;
766 }
767
768 pr_memscrub(ptr, bufsz);
769 sftp_mac_set_block_size(blocksz);
770 return 0;
771 }
772
sftp_mac_read_data(struct ssh2_packet * pkt)773 int sftp_mac_read_data(struct ssh2_packet *pkt) {
774 struct sftp_mac *mac;
775 HMAC_CTX *hmac_ctx;
776 struct umac_ctx *umac_ctx;
777 int res;
778
779 mac = &(read_macs[read_mac_idx]);
780 hmac_ctx = hmac_read_ctxs[read_mac_idx];
781 umac_ctx = umac_read_ctxs[read_mac_idx];
782
783 if (mac->key == NULL) {
784 pkt->mac = NULL;
785 pkt->mac_len = 0;
786
787 return 0;
788 }
789
790 res = get_mac(pkt, mac, hmac_ctx, umac_ctx, SFTP_MAC_FL_READ_MAC);
791 if (res < 0) {
792 return -1;
793 }
794
795 return 0;
796 }
797
sftp_mac_get_write_algo(void)798 const char *sftp_mac_get_write_algo(void) {
799 if (write_macs[write_mac_idx].key) {
800 return write_macs[write_mac_idx].algo;
801 }
802
803 return NULL;
804 }
805
sftp_mac_set_write_algo(const char * algo)806 int sftp_mac_set_write_algo(const char *algo) {
807 uint32_t mac_len;
808 unsigned int idx = write_mac_idx;
809
810 if (write_macs[idx].key) {
811 /* If we have an existing key, it means that we are currently rekeying. */
812 idx = get_next_write_index();
813 }
814
815 /* Clear any potential UMAC contexts at this index. */
816 if (umac_write_ctxs[idx] != NULL) {
817 switch (write_macs[idx].algo_type) {
818 case SFTP_MAC_ALGO_TYPE_UMAC64:
819 umac_delete(umac_write_ctxs[idx]);
820 umac_write_ctxs[idx] = NULL;
821 break;
822
823 case SFTP_MAC_ALGO_TYPE_UMAC128:
824 umac128_delete(umac_write_ctxs[idx]);
825 umac_write_ctxs[idx] = NULL;
826 break;
827 }
828 }
829
830 write_macs[idx].digest = sftp_crypto_get_digest(algo, &mac_len);
831 if (write_macs[idx].digest == NULL) {
832 return -1;
833 }
834
835 /* Note that we use a new pool, each time the algorithm is set (which
836 * happens during key exchange) to prevent undue memory growth for
837 * long-lived sessions with many rekeys.
838 */
839 if (write_macs[idx].pool != NULL) {
840 destroy_pool(write_macs[idx].pool);
841 }
842
843 write_macs[idx].pool = make_sub_pool(sftp_pool);
844 pr_pool_tag(write_macs[idx].pool, "SFTP MAC write pool");
845 write_macs[idx].algo = pstrdup(write_macs[idx].pool, algo);
846
847 if (strncmp(write_macs[idx].algo, "umac-64@openssh.com", 12) == 0) {
848 write_macs[idx].algo_type = SFTP_MAC_ALGO_TYPE_UMAC64;
849 umac_write_ctxs[idx] = umac_alloc();
850
851 } else if (strncmp(write_macs[idx].algo, "umac-128@openssh.com", 13) == 0) {
852 write_macs[idx].algo_type = SFTP_MAC_ALGO_TYPE_UMAC128;
853 umac_write_ctxs[idx] = umac128_alloc();
854
855 } else {
856 write_macs[idx].algo_type = SFTP_MAC_ALGO_TYPE_HMAC;
857 }
858
859 write_macs[idx].mac_len = mac_len;
860 return 0;
861 }
862
sftp_mac_set_write_key(pool * p,const EVP_MD * hash,const BIGNUM * k,const char * h,uint32_t hlen,int role)863 int sftp_mac_set_write_key(pool *p, const EVP_MD *hash, const BIGNUM *k,
864 const char *h, uint32_t hlen, int role) {
865 const unsigned char *id = NULL;
866 unsigned char *buf, *ptr;
867 uint32_t buflen, bufsz, id_len;
868 char letter;
869 struct sftp_mac *mac;
870 HMAC_CTX *hmac_ctx;
871 struct umac_ctx *umac_ctx;
872
873 switch_write_mac();
874
875 mac = &(write_macs[write_mac_idx]);
876 hmac_ctx = hmac_write_ctxs[write_mac_idx];
877 umac_ctx = umac_write_ctxs[write_mac_idx];
878
879 bufsz = buflen = SFTP_MAC_BUFSZ;
880 ptr = buf = sftp_msg_getbuf(p, bufsz);
881
882 /* Need to use SSH2-style format of K for the key. */
883 sftp_msg_write_mpint(&buf, &buflen, k);
884
885 id_len = sftp_session_get_id(&id);
886
887 /* The letters used depend on the role; see:
888 * https://tools.ietf.org/html/rfc4253#section-7.2
889 *
890 * If we are the SERVER, then we use the letters for the "server to client"
891 * flows, since we are WRITING to the client.
892 */
893
894 /* client-to-server HASH(K || H || "E" || session_id)
895 * server-to-client HASH(K || H || "F" || session_id)
896 */
897 letter = (role == SFTP_ROLE_SERVER ? 'F' : 'E');
898 set_mac_key(mac, hash, ptr, (bufsz - buflen), h, hlen, &letter, id, id_len);
899
900 if (init_mac(p, mac, hmac_ctx, umac_ctx) < 0) {
901 return -1;
902 }
903
904 pr_memscrub(ptr, bufsz);
905 return 0;
906 }
907
sftp_mac_write_data(struct ssh2_packet * pkt)908 int sftp_mac_write_data(struct ssh2_packet *pkt) {
909 struct sftp_mac *mac;
910 HMAC_CTX *hmac_ctx;
911 struct umac_ctx *umac_ctx;
912 int res;
913
914 mac = &(write_macs[write_mac_idx]);
915 hmac_ctx = hmac_write_ctxs[write_mac_idx];
916 umac_ctx = umac_write_ctxs[write_mac_idx];
917
918 if (mac->key == NULL) {
919 pkt->mac = NULL;
920 pkt->mac_len = 0;
921
922 return 0;
923 }
924
925 res = get_mac(pkt, mac, hmac_ctx, umac_ctx, SFTP_MAC_FL_WRITE_MAC);
926 if (res < 0) {
927 return -1;
928 }
929
930 return 0;
931 }
932
933 #if OPENSSL_VERSION_NUMBER < 0x10100000L || \
934 defined(HAVE_LIBRESSL)
935 /* In older versions of OpenSSL, there was not a way to dynamically allocate
936 * an HMAC_CTX object. Thus we have these static objects for those
937 * older versions.
938 */
939 static HMAC_CTX read_ctx1, read_ctx2;
940 static HMAC_CTX write_ctx1, write_ctx2;
941 #endif /* prior to OpenSSL-1.1.0 */
942
sftp_mac_init(void)943 int sftp_mac_init(void) {
944 #if OPENSSL_VERSION_NUMBER < 0x10100000L || \
945 defined(HAVE_LIBRESSL)
946 hmac_read_ctxs[0] = &read_ctx1;
947 hmac_read_ctxs[1] = &read_ctx2;
948 hmac_write_ctxs[0] = &write_ctx1;
949 hmac_write_ctxs[1] = &write_ctx2;
950 #else
951 hmac_read_ctxs[0] = HMAC_CTX_new();
952 hmac_read_ctxs[1] = HMAC_CTX_new();
953 hmac_write_ctxs[0] = HMAC_CTX_new();
954 hmac_write_ctxs[1] = HMAC_CTX_new();
955 #endif /* OpenSSL-1.1.0 and later */
956
957 umac_read_ctxs[0] = NULL;
958 umac_read_ctxs[1] = NULL;
959 umac_write_ctxs[0] = NULL;
960 umac_write_ctxs[1] = NULL;
961
962 return 0;
963 }
964
sftp_mac_free(void)965 int sftp_mac_free(void) {
966 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
967 !defined(HAVE_LIBRESSL)
968 HMAC_CTX_free(hmac_read_ctxs[0]);
969 HMAC_CTX_free(hmac_read_ctxs[1]);
970 HMAC_CTX_free(hmac_write_ctxs[0]);
971 HMAC_CTX_free(hmac_write_ctxs[1]);
972 #endif /* OpenSSL-1.1.0 and later */
973 return 0;
974 }
975