From e08cbb29d8374118d1e5d3f1666d038b4bc86369 Mon Sep 17 00:00:00 2001
From: Dirkjan Bussink <d.bussink@gmail.com>
Date: Fri, 8 Feb 2019 19:37:35 +0000
Subject: [PATCH 3/6] Refactor ssh_packet_hmac_verify to allow for direct
 buffer

This will make it easier to do Encrypt-then-MAC checks as those will be
on the direct encrypted data received before decrypting which means they
are not allocated in an ssh buffer at that point yet.

Reviewed-by: Jon Simons <jon@jonsimons.org>
---
 include/libssh/packet.h |  2 +-
 src/packet.c            |  3 ++-
 src/packet_crypt.c      | 18 ++++++++++--------
 3 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/include/libssh/packet.h b/include/libssh/packet.h
index 2328cc5b..8fc7ce42 100644
--- a/include/libssh/packet.h
+++ b/include/libssh/packet.h
@@ -81,7 +81,7 @@ int ssh_packet_decrypt(ssh_session session, uint8_t *destination, uint8_t *sourc
 unsigned char *ssh_packet_encrypt(ssh_session session,
                                   void *packet,
                                   unsigned int len);
-int ssh_packet_hmac_verify(ssh_session session,ssh_buffer buffer,
+int ssh_packet_hmac_verify(ssh_session session, const void *data, size_t len,
                            unsigned char *mac, enum ssh_hmac_e type);
 int ssh_packet_set_newkeys(ssh_session session,
                            enum ssh_crypto_direction_e direction);
diff --git a/src/packet.c b/src/packet.c
index 1181ca7d..d0c5d60b 100644
--- a/src/packet.c
+++ b/src/packet.c
@@ -1186,7 +1186,8 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
                     mac = packet_second_block + packet_remaining;
 
                     rc = ssh_packet_hmac_verify(session,
-                                                session->in_buffer,
+                                                ssh_buffer_get(session->in_buffer),
+                                                ssh_buffer_get_len(session->in_buffer),
                                                 mac,
                                                 crypto->in_hmac);
                     if (rc < 0) {
diff --git a/src/packet_crypt.c b/src/packet_crypt.c
index 59a6dcc5..d146c634 100644
--- a/src/packet_crypt.c
+++ b/src/packet_crypt.c
@@ -204,21 +204,23 @@ static int secure_memcmp(const void *s1, const void *s2, size_t n) {
  * @brief Verify the hmac of a packet
  *
  * @param  session      The session to use.
- * @param  buffer       The buffer to verify the hmac from.
+ * @param  data         The buffer to verify the hmac from.
+ * @param  len          The length of the given buffer.
  * @param  mac          The mac to compare with the hmac.
  *
  * @return              0 if hmac and mac are equal, < 0 if not or an error
  *                      occurred.
  */
 int ssh_packet_hmac_verify(ssh_session session,
-                           ssh_buffer buffer,
+                           const void *data,
+                           size_t len,
                            uint8_t *mac,
                            enum ssh_hmac_e type)
 {
   struct ssh_crypto_struct *crypto = NULL;
   unsigned char hmacbuf[DIGEST_MAX_LEN] = {0};
   HMACCTX ctx;
-  unsigned int len;
+  unsigned int hmaclen;
   uint32_t seq;
 
   /* AEAD types have no mac checking */
@@ -236,15 +238,15 @@ int ssh_packet_hmac_verify(ssh_session session,
   seq = htonl(session->recv_seq);
 
   hmac_update(ctx, (unsigned char *) &seq, sizeof(uint32_t));
-  hmac_update(ctx, ssh_buffer_get(buffer), ssh_buffer_get_len(buffer));
-  hmac_final(ctx, hmacbuf, &len);
+  hmac_update(ctx, data, len);
+  hmac_final(ctx, hmacbuf, &hmaclen);
 
 #ifdef DEBUG_CRYPTO
-  ssh_print_hexa("received mac",mac,len);
-  ssh_print_hexa("Computed mac",hmacbuf,len);
+  ssh_print_hexa("received mac",mac,hmaclen);
+  ssh_print_hexa("Computed mac",hmacbuf,hmaclen);
   ssh_print_hexa("seq",(unsigned char *)&seq,sizeof(uint32_t));
 #endif
-  if (secure_memcmp(mac, hmacbuf, len) == 0) {
+  if (secure_memcmp(mac, hmacbuf, hmaclen) == 0) {
     return 0;
   }
 
-- 
2.11.0

