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