Explorar el Código

Adds an HMAC_MD5() implementation, removes dependency over openssl

Julien 'Lta' BALLET hace 11 años
padre
commit
8d12f016f1
Se han modificado 5 ficheros con 125 adiciones y 15 borrados
  1. 6 3
      Makefile
  2. 1 1
      dsm.c
  3. 30 0
      include/bdsm/hmac_md5.h
  4. 78 0
      src/hmac_md5.c
  5. 10 11
      src/smb_ntlm.c

+ 6 - 3
Makefile

@@ -18,8 +18,8 @@
 
 
 
-CFLAGS      	= -Iinclude -DBDSM_DEBUG=1 -D_BSD_SOURCE -std=c99 -fPIC
-LDFLAGS     	= -lcrypto #-levent
+CFLAGS      	= -Iinclude -I contrib -DBDSM_DEBUG=1 -D_BSD_SOURCE -std=c99 -fPIC
+LDFLAGS     	= #-levent
 CC          	= clang
 AR						= ar
 RANLIB				= ranlib
@@ -28,7 +28,10 @@ LIB						= libdsm.so
 LIB_STATIC		= libdsm.a
 UTILS					= dsm discover inverse lookup
 
-LIB_SRC				= src/netbios_utils.c	\
+LIB_SRC				= contrib/mdx/md5.c \
+			contrib/mdx/md4.c				\
+			src/hmac_md5.c					\
+			src/netbios_utils.c			\
 			src/netbios_ns.c				\
 			src/netbios_ns_entry.c	\
 			src/netbios_query.c			\

+ 1 - 1
dsm.c

@@ -161,7 +161,7 @@ int main(int ac, char **av)
   files = smb_stat(session, test, av[4]);
 
   if (files)
-    printf("File %s is %lu bytes long", av[4], files->size);
+    printf("File %s is %lu bytes long\n", av[4], files->size);
 
 
   smb_session_destroy(session);

+ 30 - 0
include/bdsm/hmac_md5.h

@@ -0,0 +1,30 @@
+//---------------------------------------------------------------------------
+//  __________________    _________  _____            _____  .__         ._.
+//  \______   \______ \  /   _____/ /     \          /  _  \ |__| ____   | |
+//   |    |  _/|    |  \ \_____  \ /  \ /  \        /  /_\  \|  _/ __ \  | |
+//   |    |   \|    `   \/        /    Y    \      /    |    |  \  ___/   \|
+//   |______  /_______  /_______  \____|__  / /\   \____|__  |__|\___ |   __
+//          \/        \/        \/        \/  )/           \/        \/   \/
+//
+// This file is part of libdsm. Copyright © 2014 VideoLabs SAS
+//
+// Author: Julien 'Lta' BALLET <contact@lta.io>
+//
+// This program is free software. It comes without any warranty, to the extent
+// permitted by applicable law. You can redistribute it and/or modify it under
+// the terms of the Do What The Fuck You Want To Public License, Version 2, as
+// published by Sam Hocevar. See the COPYING file for more details.
+//----------------------------------------------------------------------------
+
+#ifndef __BDSM_SMB_SESSION_H_
+#define __BDSM_SMB_SESSION_H_
+
+#include <stdint.h>
+#include <mdx/md5.h>
+
+// Pay attention that this is not HMAC_MD5 stricto sensus, this is a variation
+// to respect MS non-standard implementation in NTLMv2 auth.
+unsigned char *HMAC_MD5(const void *key, size_t key_len, const void *msg,
+                        size_t msg_len, void *hmac);
+
+#endif

+ 78 - 0
src/hmac_md5.c

@@ -0,0 +1,78 @@
+//---------------------------------------------------------------------------
+//  __________________    _________  _____            _____  .__         ._.
+//  \______   \______ \  /   _____/ /     \          /  _  \ |__| ____   | |
+//   |    |  _/|    |  \ \_____  \ /  \ /  \        /  /_\  \|  _/ __ \  | |
+//   |    |   \|    `   \/        /    Y    \      /    |    |  \  ___/   \|
+//   |______  /_______  /_______  \____|__  / /\   \____|__  |__|\___ |   __
+//          \/        \/        \/        \/  )/           \/        \/   \/
+//
+// This file is part of libdsm. Copyright © 2014 VideoLabs SAS
+//
+// Author: Julien 'Lta' BALLET <contact@lta.io>
+//
+// This program is free software. It comes without any warranty, to the extent
+// permitted by applicable law. You can redistribute it and/or modify it under
+// the terms of the Do What The Fuck You Want To Public License, Version 2, as
+// published by Sam Hocevar. See the COPYING file for more details.
+//----------------------------------------------------------------------------
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "bdsm/hmac_md5.h"
+
+unsigned char *HMAC_MD5(const void *key, size_t key_len, const void *msg,
+                        size_t msg_len, void *hmac)
+{
+  static uint8_t  hmac_static[16];
+
+  uint8_t         key_pad[64], o_key_pad[64], i_key_pad[64], kcat[80];
+  void            *cat, *out;
+  MD5_CTX         ctx;
+
+  assert(key != NULL && msg != NULL);
+
+  // This is Microsoft variation for NTLMv2 (afaik)
+  // afaik, they truncate the key instead of hashing it
+  if (key_len > 64)
+    key_len = 64;
+  else
+  {
+    memcpy(key_pad, key, key_len);
+    memset(key_pad + key_len, 0, 64 - key_len);
+  }
+
+  // Compute the o/i XORed padded keys
+  for (unsigned i = 0; i < 64; i++)
+  {
+   o_key_pad[i] = 0x5c ^ key_pad[i];
+   i_key_pad[i] = 0x36 ^ key_pad[i];
+  }
+
+  // Concatenate inner padded key with message
+  cat = malloc(msg_len + 64);
+  assert (cat != NULL);
+  memcpy(cat, i_key_pad, 64);
+  memcpy(cat + 64, msg, msg_len);
+
+  // MD5 of the result
+  MD5_Init(&ctx);
+  MD5_Update(&ctx, cat, msg_len + 64);
+  MD5_Final(key_pad, &ctx);
+  free(cat);
+
+  memcpy(kcat, o_key_pad, 64);
+  memcpy(kcat + 64, key_pad, 16);
+
+  if (hmac != NULL)
+    out = hmac;
+  else
+    out = hmac_static;
+
+  MD5_Init(&ctx);
+  MD5_Update(&ctx, kcat, 80);
+  MD5_Final(out, &ctx);
+
+  return (out);
+}

+ 10 - 11
src/smb_ntlm.c

@@ -22,10 +22,8 @@
 #include <string.h>
 #include <sys/time.h>
 
-#include <openssl/hmac.h>
-#include <openssl/md4.h>
-#include <openssl/md5.h>
-
+#include "mdx/md4.h"
+#include "bdsm/hmac_md5.h"
 #include "bdsm/smb_utils.h"
 #include "bdsm/smb_ntlm.h"
 
@@ -47,6 +45,7 @@ uint64_t    smb_ntlm_generate_challenge()
 
 void        smb_ntlm_hash(const char *password, smb_ntlmh_t *hash)
 {
+  MD4_CTX   ctx;
   char      *ucs2le_pass;
   size_t    sz;
 
@@ -54,7 +53,11 @@ void        smb_ntlm_hash(const char *password, smb_ntlmh_t *hash)
 
   sz = smb_to_utf16("ASCII", password, strlen(password), &ucs2le_pass);
   memset((void *)hash, 0, SMB_NTLM_HASH_SIZE);
-  MD4((uint8_t *)ucs2le_pass, sz, (uint8_t *)hash);
+
+  MD4_Init(&ctx);
+  MD4_Update(&ctx, (uint8_t *)ucs2le_pass, sz);
+  MD4_Final((uint8_t *)hash, &ctx);
+
   free(ucs2le_pass);
 }
 
@@ -76,10 +79,7 @@ void        smb_ntlm2_hash(const char *user, const char *password,
   memcpy(data, ucs_user, ucs_user_len);
   memcpy(data + ucs_user_len, ucs_dest, ucs_dest_len);
 
-  HMAC(EVP_md5(),
-       (uint8_t *)hash_v1, SMB_NTLM_HASH_SIZE,
-       (uint8_t *)data, data_len,
-       (uint8_t *)hash, NULL);
+  HMAC_MD5(hash_v1, SMB_NTLM_HASH_SIZE, data, data_len, hash);
 
   free(ucs_user);
   free(ucs_dest);
@@ -99,8 +99,7 @@ uint8_t     *smb_ntlm2_response(smb_ntlmh_t *hash_v2, uint64_t srv_challenge,
   memcpy(data, (void *)&srv_challenge, sizeof(uint64_t));
   memcpy(data + sizeof(uint64_t), blob, blob_size);
 
-  HMAC(EVP_md5(), (uint8_t *)hash_v2, SMB_NTLM_HASH_SIZE,
-       data, data_len, (uint8_t *)&hmac, 0);
+  HMAC_MD5(hash_v2, SMB_NTLM_HASH_SIZE, data, data_len, &hmac);
 
   response = malloc(blob_size + 16);
   assert(response != NULL);