diff --git a/tools/autotools/tsk_gettimes.cpp b/tools/autotools/tsk_gettimes.cpp
index de388a3c0733727f94125a6fd900e95da241c419..1f8f169e96a569b2389e9ed199ea4dfa2e8480c1 100644
--- a/tools/autotools/tsk_gettimes.cpp
+++ b/tools/autotools/tsk_gettimes.cpp
@@ -21,12 +21,13 @@ usage()
 {
     TFPRINTF(stderr,
         _TSK_T
-        ("usage: %s [-vV] [-i imgtype] [-b dev_sector_size] [-z zone] [-s seconds] image [image]\n"),
+        ("usage: %s [-vVm] [-i imgtype] [-b dev_sector_size] [-z zone] [-s seconds] image [image]\n"),
         progname);
     tsk_fprintf(stderr,
         "\t-i imgtype: The format of the image file (use '-i list' for supported types)\n");
     tsk_fprintf(stderr,
         "\t-b dev_sector_size: The size (in bytes) of the device sectors\n");
+	tsk_fprintf(stderr, "\t-m: Calculate MD5 hash in output (slow)\n");
     tsk_fprintf(stderr, "\t-v: verbose output to stderr\n");
     tsk_fprintf(stderr, "\t-V: Print version\n");
     tsk_fprintf(stderr,
@@ -42,6 +43,7 @@ usage()
 class TskGetTimes:public TskAuto {
 public:
     TskGetTimes(int32_t);
+	TskGetTimes(int32_t, bool);
     virtual TSK_RETVAL_ENUM processFile(TSK_FS_FILE * fs_file, const char *path);
     virtual TSK_FILTER_ENUM filterVol(const TSK_VS_PART_INFO * vs_part);
     virtual TSK_FILTER_ENUM filterFs(TSK_FS_INFO * fs_info);
@@ -50,6 +52,7 @@ class TskGetTimes:public TskAuto {
 private:
     int m_curVolAddr;
     int32_t m_secSkew;
+	bool m_compute_hash;
 };
 
 
@@ -57,6 +60,14 @@ TskGetTimes::TskGetTimes(int32_t a_secSkew)
 {
     m_curVolAddr = -1;
     m_secSkew = a_secSkew;
+	m_compute_hash = false;
+}
+
+TskGetTimes::TskGetTimes(int32_t a_secSkew, bool a_compute_hash)
+{
+    m_curVolAddr = -1;
+    m_secSkew = a_secSkew;
+	m_compute_hash = a_compute_hash;
 }
 
 // Print errors as they are encountered
@@ -82,10 +93,16 @@ TskGetTimes::filterFs(TSK_FS_INFO * fs_info)
     else 
         volName[0] = '\0';
 
-    if (tsk_fs_fls(fs_info, (TSK_FS_FLS_FLAG_ENUM)(TSK_FS_FLS_MAC | TSK_FS_FLS_DIR | TSK_FS_FLS_FILE | TSK_FS_FLS_FULL),
-       fs_info->root_inum, (TSK_FS_DIR_WALK_FLAG_ENUM)(TSK_FS_DIR_WALK_FLAG_ALLOC | TSK_FS_DIR_WALK_FLAG_UNALLOC | TSK_FS_DIR_WALK_FLAG_RECURSE), volName, m_secSkew)) {
-        
-    }
+	TSK_FS_FLS_FLAG_ENUM fls_flags = (TSK_FS_FLS_FLAG_ENUM)(TSK_FS_FLS_MAC | TSK_FS_FLS_DIR | TSK_FS_FLS_FILE | TSK_FS_FLS_FULL);
+	if(m_compute_hash){
+		fls_flags = (TSK_FS_FLS_FLAG_ENUM)(fls_flags | TSK_FS_FLS_HASH);
+	}
+
+	if (tsk_fs_fls(fs_info, (TSK_FS_FLS_FLAG_ENUM)(fls_flags),
+		fs_info->root_inum, (TSK_FS_DIR_WALK_FLAG_ENUM)(TSK_FS_DIR_WALK_FLAG_ALLOC | TSK_FS_DIR_WALK_FLAG_UNALLOC | TSK_FS_DIR_WALK_FLAG_RECURSE), volName, m_secSkew)) {
+	}
+
+
     return TSK_FILTER_SKIP;
 }
 
@@ -107,6 +124,7 @@ main(int argc, char **argv1)
     unsigned int ssize = 0;
     TSK_TCHAR *cp;
     int32_t sec_skew = 0;
+	bool do_hash = false;
 
 #ifdef TSK_WIN32
     // On Windows, get the wide arguments (mingw doesn't support wmain)
@@ -122,7 +140,7 @@ main(int argc, char **argv1)
     progname = argv[0];
     setlocale(LC_ALL, "");
 
-    while ((ch = GETOPT(argc, argv, _TSK_T("b:i:s:vVz:"))) > 0) {
+    while ((ch = GETOPT(argc, argv, _TSK_T("b:i:s:mvVz:"))) > 0) {
         switch (ch) {
         case _TSK_T('?'):
         default:
@@ -161,6 +179,9 @@ main(int argc, char **argv1)
             sec_skew = TATOI(OPTARG);
             break;
 
+        case _TSK_T('m'):
+            do_hash = true;
+            break;
 
         case _TSK_T('v'):
             tsk_verbose++;
@@ -194,7 +215,7 @@ main(int argc, char **argv1)
         usage();
     }
 
-    TskGetTimes tskGetTimes(sec_skew);
+    TskGetTimes tskGetTimes(sec_skew, do_hash);
     if (tskGetTimes.openImage(argc - OPTIND, &argv[OPTIND], imgtype,
             ssize)) {
         tsk_error_print(stderr);
diff --git a/tsk/base/tsk_base.h b/tsk/base/tsk_base.h
index 3de0c9b7403c0f720ee224597076d1c2031df041..9caa4404e4586b57f877e40aa96d49fae45830b5 100644
--- a/tsk/base/tsk_base.h
+++ b/tsk/base/tsk_base.h
@@ -473,6 +473,16 @@ documentation and/or software.
     void TSK_SHA_Init(TSK_SHA_CTX *);
     void TSK_SHA_Update(TSK_SHA_CTX *, BYTE * buffer, int count);
     void TSK_SHA_Final(BYTE * output, TSK_SHA_CTX *);
+
+/* Flags for which type of hash(es) to run */
+	typedef enum{
+		TSK_HASH_INVALID_ID = 0,
+		TSK_HASH_MD5 = 0x01,
+		TSK_HASH_SHA1 = 0x02
+		//TSK_HASH_SHA256 = 0x04,
+	} TSK_HASH_ENUM;
+
+
 //@}
 
 #ifdef __cplusplus
diff --git a/tsk/fs/fls_lib.c b/tsk/fs/fls_lib.c
index fc28c751bb17202173edbc88a7bc81d9c4007cda..48a1d51266af0e8a5049b4e1e259844e04bc4412 100644
--- a/tsk/fs/fls_lib.c
+++ b/tsk/fs/fls_lib.c
@@ -50,6 +50,7 @@ static void
 printit(TSK_FS_FILE * fs_file, const char *a_path,
     const TSK_FS_ATTR * fs_attr, const FLS_DATA * fls_data)
 {
+	TSK_HASH_RESULTS hash_results;
     unsigned int i;
 
     if ((!(fls_data->flags & TSK_FS_FLS_FULL)) && (a_path)) {
@@ -66,10 +67,18 @@ printit(TSK_FS_FILE * fs_file, const char *a_path,
     }
 
 
-    if (fls_data->flags & TSK_FS_FLS_MAC) {
-        tsk_fs_name_print_mac(stdout, fs_file, a_path,
-            fs_attr, fls_data->macpre, fls_data->sec_skew);
-    }
+	if(fls_data->flags & TSK_FS_FLS_MAC){
+		if(fls_data->flags & TSK_FS_FLS_HASH){
+			tsk_fs_file_hash_calc(fs_file, &hash_results, TSK_HASH_MD5);
+			tsk_fs_name_print_mac_md5(stdout, fs_file, a_path,
+				fs_attr, fls_data->macpre, fls_data->sec_skew,
+				hash_results.md5_digest);
+		}
+		else{
+			tsk_fs_name_print_mac(stdout, fs_file, a_path,
+				fs_attr, fls_data->macpre, fls_data->sec_skew);
+		}
+	}
     else if (fls_data->flags & TSK_FS_FLS_LONG) {
         tsk_fs_name_print_long(stdout, fs_file, a_path, fs_file->fs_info,
             fs_attr, TSK_FS_FLS_FULL & fls_data->flags ? 1 : 0,
diff --git a/tsk/fs/fs_file.c b/tsk/fs/fs_file.c
index b4e0d31517e2f062b874dca09ef99ff1d1478832..74417d832a99308e7fa89162d04b827e6ea44232 100644
--- a/tsk/fs/fs_file.c
+++ b/tsk/fs/fs_file.c
@@ -563,3 +563,88 @@ tsk_fs_file_get_owner_sid(TSK_FS_FILE * a_fs_file, char **sid_str)
 
     return a_fs_file->fs_info->fread_owner_sid(a_fs_file, sid_str);
 }
+
+
+/**
+ * Internal struct used for hash calculations
+ */
+typedef struct {
+	TSK_HASH_ENUM flags;
+	TSK_MD5_CTX md5_context;
+	TSK_SHA_CTX sha1_context;
+} TSK_HASH_DATA;
+
+/**
+ * Helper function for tsk_fs_file_get_md5
+ */
+TSK_WALK_RET_ENUM
+tsk_fs_file_hash_calc_callback(TSK_FS_FILE * file, TSK_OFF_T offset,
+    TSK_DADDR_T addr, char *buf, size_t size,
+    TSK_FS_BLOCK_FLAG_ENUM a_flags, void *ptr)
+{
+    TSK_HASH_DATA * hash_data = (TSK_HASH_DATA *) ptr;
+    if (hash_data == NULL)
+        return TSK_WALK_CONT;
+
+	if(hash_data->flags & TSK_HASH_MD5){
+		TSK_MD5_Update(&(hash_data->md5_context), (unsigned char *) buf, (unsigned int) size);
+	}
+
+	if(hash_data->flags & TSK_HASH_SHA1){
+		TSK_SHA_Update(&(hash_data->sha1_context), (unsigned char *) buf, (unsigned int) size);
+	}
+
+
+    return TSK_WALK_CONT;
+}
+
+/**
+ * Returns a string containing the md5 hash of the given file
+ *
+ * @param a_fs_file The file to calculate the hash of
+ * @param a_hash_results The results will be stored here (must be allocated beforehand)
+ * @param a_flags Indicates which hash algorithm(s) to use
+ * @returns 0 on success or 1 on error
+ */
+extern uint8_t tsk_fs_file_hash_calc(TSK_FS_FILE * a_fs_file, TSK_HASH_RESULTS * a_hash_results, TSK_HASH_ENUM a_flags){
+	TSK_HASH_DATA hash_data;
+	int i;
+
+    if ((a_fs_file == NULL) || (a_fs_file->fs_info == NULL)
+        || (a_fs_file->meta == NULL)) {
+        tsk_error_set_errno(TSK_ERR_FS_ARG);
+        tsk_error_set_errstr("tsk_fs_file_hash_calc: fs_info is NULL");
+        return 1;
+    }
+
+	if(a_hash_results == NULL){
+        tsk_error_set_errno(TSK_ERR_FS_ARG);
+        tsk_error_set_errstr("tsk_fs_file_hash_calc: hash_results is NULL");
+        return 1;
+    }
+
+	if(a_flags & TSK_HASH_MD5){
+		TSK_MD5_Init(&(hash_data.md5_context));
+	}
+	if(a_flags & TSK_HASH_SHA1){
+		TSK_SHA_Init(&(hash_data.sha1_context));
+	}
+
+	hash_data.flags = a_flags;
+	if(tsk_fs_file_walk(a_fs_file, TSK_FS_FILE_WALK_FLAG_NONE,
+            tsk_fs_file_hash_calc_callback, (void *) &hash_data)) {
+        tsk_error_set_errno(TSK_ERR_FS_ARG);
+        tsk_error_set_errstr("tsk_fs_file_hash_calc: error in file walk");     
+        return 1;
+    }
+
+	a_hash_results->flags = a_flags;
+	if(a_flags & TSK_HASH_MD5){
+		TSK_MD5_Final(a_hash_results->md5_digest, &(hash_data.md5_context));
+	}
+	if(a_flags & TSK_HASH_MD5){
+		TSK_SHA_Final(a_hash_results->sha1_digest, &(hash_data.sha1_context));
+	}
+
+	return 0;
+}
diff --git a/tsk/fs/fs_name.c b/tsk/fs/fs_name.c
index aaa12c495da7b19bb0d7a7c15339d3e852884035..189ab8292044e2511db4d551597795aacdae3c21 100644
--- a/tsk/fs/fs_name.c
+++ b/tsk/fs/fs_name.c
@@ -582,6 +582,33 @@ void
 tsk_fs_name_print_mac(FILE * hFile, const TSK_FS_FILE * fs_file,
     const char *a_path, const TSK_FS_ATTR * fs_attr,
     const char *prefix, int32_t time_skew)
+{
+	tsk_fs_name_print_mac_md5(hFile, fs_file, a_path, fs_attr, prefix, time_skew, NULL);
+}
+
+/**
+ * \internal
+ *
+** Print output in the format that mactime reads.
+**
+** If the flags in the fs_file->meta structure are set to FS_FLAG_ALLOC
+** then it is assumed that the inode has been reallocated and the
+** contents are not displayed
+**
+** fs is not required (only used for block size).
+ * @param hFile handle to print results to
+ * @param fs_file File to print details about
+ * @param a_path Parent directory of file (needs to end with "/")
+ * @param fs_attr Attribute in file that is being called for (NULL for non-NTFS)
+ * @param prefix Path of mounting point for image
+ * @param time_skew number of seconds skew to adjust time
+ * @param hash_results Holds the calculated md5 hash
+*/
+void
+tsk_fs_name_print_mac_md5(FILE * hFile, const TSK_FS_FILE * fs_file,
+    const char *a_path, const TSK_FS_ATTR * fs_attr,
+    const char *prefix, int32_t time_skew,
+	const unsigned char * hash_results)
 {
     char ls[12];
     size_t i;
@@ -600,8 +627,18 @@ tsk_fs_name_print_mac(FILE * hFile, const TSK_FS_FILE * fs_file,
         isADS = 1;
     }
 
-    /* md5 */
-    tsk_fprintf(hFile, "0|");
+    /* hash
+	 * Print out the hash buffer (if not null)
+	 */
+	if(hash_results == NULL){
+		tsk_fprintf(hFile, "0|");
+	}
+	else{
+		for(i = 0;i < 16;i++){
+			tsk_fprintf(hFile, "%02x", hash_results[i]);
+		}
+		tsk_fprintf(hFile, "|");
+	}
 
     /* file name */
     tsk_fprintf(hFile, "%s", prefix);
diff --git a/tsk/fs/tsk_fs.h b/tsk/fs/tsk_fs.h
index 2814434832abe172432abd9ede450b92dcb30d76..936d4ee8c3c219c465ff8172431acc4a3c7fa397 100644
--- a/tsk/fs/tsk_fs.h
+++ b/tsk/fs/tsk_fs.h
@@ -722,6 +722,14 @@ extern "C" {
 
     extern uint8_t tsk_fs_file_get_owner_sid(TSK_FS_FILE *, char **);
 
+	typedef struct {
+		TSK_HASH_ENUM flags;
+		unsigned char md5_digest[16];
+		unsigned char sha1_digest[20];
+	} TSK_HASH_RESULTS;
+
+	extern uint8_t tsk_fs_file_hash_calc(TSK_FS_FILE *, TSK_HASH_RESULTS *, TSK_HASH_ENUM);
+
     //@}
 
 
@@ -1043,6 +1051,7 @@ extern "C" {
         TSK_FS_FLS_DIR = 0x08,
         TSK_FS_FLS_FULL = 0x10,
         TSK_FS_FLS_MAC = 0x20,
+		TSK_FS_FLS_HASH = 0x40
     };
     typedef enum TSK_FS_FLS_FLAG_ENUM TSK_FS_FLS_FLAG_ENUM;
     extern uint8_t tsk_fs_fls(TSK_FS_INFO * fs,
diff --git a/tsk/fs/tsk_fs_i.h b/tsk/fs/tsk_fs_i.h
index 27538e28de4e49c4039f9adf942957cbe15a56b7..944f2818d24eacc29df7ab03768372f497127703 100644
--- a/tsk/fs/tsk_fs_i.h
+++ b/tsk/fs/tsk_fs_i.h
@@ -162,6 +162,9 @@ extern "C" {
         int32_t);
     extern void tsk_fs_name_print_mac(FILE *, const TSK_FS_FILE *,
         const char *, const TSK_FS_ATTR * fs_attr, const char *, int32_t);
+    extern void tsk_fs_name_print_mac_md5(FILE *, const TSK_FS_FILE *,
+        const char *, const TSK_FS_ATTR * fs_attr, const char *, int32_t,
+		const unsigned char *);
     extern uint8_t tsk_fs_name_copy(TSK_FS_NAME * a_fs_name_to,
         const TSK_FS_NAME * a_fs_name_from);
     extern void tsk_fs_name_reset(TSK_FS_NAME * a_fs_name);