You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by jp...@apache.org on 2018/01/27 03:03:54 UTC

[trafficserver] branch master updated: Add a --enable-fips flag which will eliminate MD5 and MMH and replace them with SHA256. This will effectively clear the cache because existing documents will not be found.

This is an automated email from the ASF dual-hosted git repository.

jplevyak pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new c93790a  Add a --enable-fips flag which will eliminate MD5 and MMH and replace them with SHA256.  This will effectively clear the cache because existing documents will not be found.
c93790a is described below

commit c93790aa7de7d8bad35cd84f20d88ab225a4f30d
Author: John Plevyak <jp...@apache.org>
AuthorDate: Fri Nov 10 11:42:49 2017 -0800

    Add a --enable-fips flag which will eliminate MD5 and MMH and
    replace them with SHA256.  This will effectively clear the cache
    because existing documents will not be found.
---
 configure.ac                                |  13 ++
 iocore/cache/Cache.cc                       |   2 +-
 iocore/cache/CacheTest.cc                   |  48 ++---
 iocore/cache/I_CacheDefs.h                  |  12 +-
 iocore/cache/P_CacheInternal.h              |  14 +-
 iocore/cache/P_CacheVol.h                   |  20 +-
 iocore/cache/P_RamCache.h                   |   9 +-
 iocore/cache/RamCacheCLFUS.cc               |  17 +-
 iocore/cache/RamCacheLRU.cc                 |  15 +-
 iocore/hostdb/HostDB.cc                     | 280 ++++++++++++++--------------
 iocore/hostdb/I_HostDB.h                    |   3 +-
 iocore/hostdb/I_HostDBProcessor.h           |   2 +-
 iocore/hostdb/P_HostDB.h                    |   4 +-
 iocore/hostdb/P_HostDBProcessor.h           |  57 +++---
 lib/ts/{ink_code.cc => CryptoHash.cc}       | 117 +++++-------
 lib/ts/CryptoHash.h                         |  92 ++++++---
 lib/ts/INK_MD5.h                            |   5 +-
 lib/ts/MMH.h                                |   2 +-
 lib/ts/Makefile.am                          |   2 +
 lib/ts/{INK_MD5.h => SHA256.h}              |  26 ++-
 lib/ts/ink_code.cc                          |  39 +---
 lib/ts/ink_code.h                           |   4 +-
 lib/ts/ink_config.h.in                      |   1 +
 lib/ts/ink_inet.cc                          |  41 ++--
 plugins/experimental/memcache/tsmemcache.cc |   6 +-
 plugins/experimental/memcache/tsmemcache.h  |   2 +-
 proxy/InkAPI.cc                             |  14 +-
 proxy/InkAPIInternal.h                      |   2 +-
 proxy/Main.cc                               |   2 +
 proxy/hdrs/HTTP.h                           |  46 ++---
 proxy/hdrs/URL.cc                           |  51 ++---
 proxy/hdrs/URL.h                            |  58 +-----
 proxy/http/HttpConnectionCount.h            |  27 ++-
 proxy/http/HttpSM.cc                        |  14 +-
 proxy/http/HttpServerSession.h              |   4 +-
 proxy/http/HttpSessionManager.cc            |  10 +-
 proxy/http/HttpSessionManager.h             |   6 +-
 proxy/logging/LogFormat.cc                  |   5 +-
 proxy/logging/LogObject.cc                  |   3 +-
 tools/Makefile.am                           |   2 +-
 tools/jtest/jtest.cc                        |  13 ++
 41 files changed, 522 insertions(+), 568 deletions(-)

diff --git a/configure.ac b/configure.ac
index e4e16a8..1a68f69 100644
--- a/configure.ac
+++ b/configure.ac
@@ -255,6 +255,19 @@ AC_MSG_RESULT([$enable_diags])
 TS_ARG_ENABLE_VAR([use], [diags])
 
 #
+# FIPS
+#
+
+AC_MSG_CHECKING([whether to enable fips])
+AC_ARG_ENABLE([fips],
+  [AS_HELP_STRING([--enable-fips],[turn on FIPS compliance])],
+  [],
+  [enable_fips=no]
+)
+AC_MSG_RESULT([$enable_fips])
+TS_ARG_ENABLE_VAR([enable], [fips])
+
+#
 # Build regression tests?
 #
 
diff --git a/iocore/cache/Cache.cc b/iocore/cache/Cache.cc
index 23c362c..fbcb57c 100644
--- a/iocore/cache/Cache.cc
+++ b/iocore/cache/Cache.cc
@@ -1276,7 +1276,7 @@ Vol::init(char *s, off_t blocks, off_t dir_skip, bool clear)
   ink_strlcpy(hash_text, seed_str, hash_text_size);
   snprintf(hash_text + hash_seed_size, (hash_text_size - hash_seed_size), " %" PRIu64 ":%" PRIu64 "", (uint64_t)dir_skip,
            (uint64_t)blocks);
-  MD5Context().hash_immediate(hash_id, hash_text, strlen(hash_text));
+  CryptoContext().hash_immediate(hash_id, hash_text, strlen(hash_text));
 
   dir_skip = ROUND_TO_STORE_BLOCK((dir_skip < START_POS ? START_POS : dir_skip));
   path     = ats_strdup(s);
diff --git a/iocore/cache/CacheTest.cc b/iocore/cache/CacheTest.cc
index 8483c4b..83e4be6 100644
--- a/iocore/cache/CacheTest.cc
+++ b/iocore/cache/CacheTest.cc
@@ -452,7 +452,7 @@ REGRESSION_TEST(cache_disk_replacement_stability)(RegressionTest *t, int level,
     vols[i].disk = &disk;
     vols[i].len  = DEFAULT_STRIPE_SIZE;
     snprintf(buff, sizeof(buff), "/dev/sd%c %" PRIu64 ":%" PRIu64, 'a' + i, DEFAULT_SKIP, vols[i].len);
-    MD5Context().hash_immediate(vols[i].hash_id, buff, strlen(buff));
+    CryptoContext().hash_immediate(vols[i].hash_id, buff, strlen(buff));
   }
 
   hr1.vol_hash_table = nullptr;
@@ -467,7 +467,7 @@ REGRESSION_TEST(cache_disk_replacement_stability)(RegressionTest *t, int level,
   sample      = vols + sample_idx;
   sample->len = 1024ULL * 1024 * 1024 * (1024 + 128); // 1.1 TB
   snprintf(buff, sizeof(buff), "/dev/sd%c %" PRIu64 ":%" PRIu64, 'a' + sample_idx, DEFAULT_SKIP, sample->len);
-  MD5Context().hash_immediate(sample->hash_id, buff, strlen(buff));
+  CryptoContext().hash_immediate(sample->hash_id, buff, strlen(buff));
   build_vol_hash_table(&hr2);
 
   // See what the difference is
@@ -556,32 +556,32 @@ test_RamCache(RegressionTest *t, RamCache *cache, const char *name, int64_t cach
   for (int l = 0; l < 10; l++) {
     for (int i = 0; i < 200; i++) {
       IOBufferData *d = THREAD_ALLOC(ioDataAllocator, this_thread());
-      INK_MD5 md5;
+      CryptoHash hash;
 
       d->alloc(BUFFER_SIZE_INDEX_16K);
       data.push_back(make_ptr(d));
-      md5.u64[0] = ((uint64_t)i << 32) + i;
-      md5.u64[1] = ((uint64_t)i << 32) + i;
-      cache->put(&md5, data[i].get(), 1 << 15);
+      hash.u64[0] = ((uint64_t)i << 32) + i;
+      hash.u64[1] = ((uint64_t)i << 32) + i;
+      cache->put(&hash, data[i].get(), 1 << 15);
       // More hits for the first 10.
       for (int j = 0; j <= i && j < 10; j++) {
         Ptr<IOBufferData> data;
-        INK_MD5 md5;
+        CryptoHash hash;
 
-        md5.u64[0] = ((uint64_t)j << 32) + j;
-        md5.u64[1] = ((uint64_t)j << 32) + j;
-        cache->get(&md5, &data);
+        hash.u64[0] = ((uint64_t)j << 32) + j;
+        hash.u64[1] = ((uint64_t)j << 32) + j;
+        cache->get(&hash, &data);
       }
     }
   }
 
   for (int i = 0; i < 10; i++) {
-    INK_MD5 md5;
+    CryptoHash hash;
     Ptr<IOBufferData> data;
 
-    md5.u64[0] = ((uint64_t)i << 32) + i;
-    md5.u64[1] = ((uint64_t)i << 32) + i;
-    if (!cache->get(&md5, &data)) {
+    hash.u64[0] = ((uint64_t)i << 32) + i;
+    hash.u64[1] = ((uint64_t)i << 32) + i;
+    if (!cache->get(&hash, &data)) {
       pass = false;
     }
   }
@@ -597,15 +597,15 @@ test_RamCache(RegressionTest *t, RamCache *cache, const char *name, int64_t cach
   data.clear();
   int misses = 0;
   for (int i = 0; i < sample_size; i++) {
-    INK_MD5 md5;
-    md5.u64[0] = ((uint64_t)r[i] << 32) + r[i];
-    md5.u64[1] = ((uint64_t)r[i] << 32) + r[i];
+    CryptoHash hash;
+    hash.u64[0] = ((uint64_t)r[i] << 32) + r[i];
+    hash.u64[1] = ((uint64_t)r[i] << 32) + r[i];
     Ptr<IOBufferData> get_data;
-    if (!cache->get(&md5, &get_data)) {
+    if (!cache->get(&hash, &get_data)) {
       IOBufferData *d = THREAD_ALLOC(ioDataAllocator, this_thread());
       d->alloc(BUFFER_SIZE_INDEX_16K);
       data.push_back(make_ptr(d));
-      cache->put(&md5, data.back().get(), 1 << 15);
+      cache->put(&hash, data.back().get(), 1 << 15);
       if (i >= sample_size / 2) {
         misses++; // Sample last half of the gets.
       }
@@ -617,15 +617,15 @@ test_RamCache(RegressionTest *t, RamCache *cache, const char *name, int64_t cach
   data.clear();
   misses = 0;
   for (int i = 0; i < sample_size; i++) {
-    INK_MD5 md5;
-    md5.u64[0] = ((uint64_t)r[i] << 32) + r[i];
-    md5.u64[1] = ((uint64_t)r[i] << 32) + r[i];
+    CryptoHash hash;
+    hash.u64[0] = ((uint64_t)r[i] << 32) + r[i];
+    hash.u64[1] = ((uint64_t)r[i] << 32) + r[i];
     Ptr<IOBufferData> get_data;
-    if (!cache->get(&md5, &get_data)) {
+    if (!cache->get(&hash, &get_data)) {
       IOBufferData *d = THREAD_ALLOC(ioDataAllocator, this_thread());
       d->alloc(BUFFER_SIZE_INDEX_8K + (r[i] % 3));
       data.push_back(make_ptr(d));
-      cache->put(&md5, data.back().get(), d->block_size());
+      cache->put(&hash, data.back().get(), d->block_size());
       if (i >= sample_size / 2) {
         misses++; // Sample last half of the gets.
       }
diff --git a/iocore/cache/I_CacheDefs.h b/iocore/cache/I_CacheDefs.h
index 8df3c93..0995dc6 100644
--- a/iocore/cache/I_CacheDefs.h
+++ b/iocore/cache/I_CacheDefs.h
@@ -124,20 +124,10 @@ enum CacheFragType {
 typedef CryptoHash CacheKey;
 
 struct HttpCacheKey {
-  uint64_t
-  slice64(int i) const
-  {
-    return hash.slice64(i);
-  }
-  uint32_t
-  slice32(int i) const
-  {
-    return hash.slice32(i);
-  }
-
   int hostlen;
   const char *hostname;
   CacheKey hash;
+  CacheKey hash2;
 };
 
 #define CACHE_ALLOW_MULTIPLE_WRITES 1
diff --git a/iocore/cache/P_CacheInternal.h b/iocore/cache/P_CacheInternal.h
index 5361173..14b6c37 100644
--- a/iocore/cache/P_CacheInternal.h
+++ b/iocore/cache/P_CacheInternal.h
@@ -799,7 +799,7 @@ Vol::open_write_lock(CacheVC *cont, int allow_if_writers, int max_writers)
 }
 
 TS_INLINE OpenDirEntry *
-Vol::open_read_lock(INK_MD5 *key, EThread *t)
+Vol::open_read_lock(CryptoHash *key, EThread *t)
 {
   CACHE_TRY_LOCK(lock, mutex, t);
   if (!lock.is_locked())
@@ -969,8 +969,8 @@ struct Cache {
   Action *open_write(Continuation *cont, const CacheKey *key, CacheHTTPInfo *old_info, time_t pin_in_cache = (time_t)0,
                      const CacheKey *key1 = nullptr, CacheFragType type = CACHE_FRAG_TYPE_HTTP, const char *hostname = 0,
                      int host_len = 0);
-  static void generate_key(INK_MD5 *md5, CacheURL *url);
-  static void generate_key(HttpCacheKey *md5, CacheURL *url, cache_generation_t generation = -1);
+  static void generate_key(CryptoHash *hash, CacheURL *url);
+  static void generate_key(HttpCacheKey *hash, CacheURL *url, cache_generation_t generation = -1);
 
   Action *link(Continuation *cont, const CacheKey *from, const CacheKey *to, CacheFragType type, const char *hostname,
                int host_len);
@@ -1000,9 +1000,9 @@ extern Cache *theStreamCache;
 inkcoreapi extern Cache *caches[NUM_CACHE_FRAG_TYPES];
 
 TS_INLINE void
-Cache::generate_key(INK_MD5 *md5, CacheURL *url)
+Cache::generate_key(CryptoHash *hash, CacheURL *url)
 {
-  url->hash_get(md5);
+  url->hash_get(hash);
 }
 
 TS_INLINE void
@@ -1013,9 +1013,9 @@ Cache::generate_key(HttpCacheKey *key, CacheURL *url, cache_generation_t generat
 }
 
 TS_INLINE unsigned int
-cache_hash(const INK_MD5 &md5)
+cache_hash(const CryptoHash &hash)
 {
-  uint64_t f         = md5.fold();
+  uint64_t f         = hash.fold();
   unsigned int mhash = (unsigned int)(f >> 32);
   return mhash;
 }
diff --git a/iocore/cache/P_CacheVol.h b/iocore/cache/P_CacheVol.h
index f89956d..6747161 100644
--- a/iocore/cache/P_CacheVol.h
+++ b/iocore/cache/P_CacheVol.h
@@ -276,11 +276,18 @@ struct CacheVol {
 
 // Note : hdr() needs to be 8 byte aligned.
 struct Doc {
-  uint32_t magic;        // DOC_MAGIC
-  uint32_t len;          // length of this fragment (including hlen & sizeof(Doc), unrounded)
-  uint64_t total_len;    // total length of document
-  CryptoHash first_key;  ///< first key in object.
-  CryptoHash key;        ///< Key for this doc.
+  uint32_t magic;     // DOC_MAGIC
+  uint32_t len;       // length of this fragment (including hlen & sizeof(Doc), unrounded)
+  uint64_t total_len; // total length of document
+#ifndef TS_ENABLE_FIPS
+  CryptoHash first_key; ///< first key in object.
+  CryptoHash key;       ///< Key for this doc.
+#else
+  // For FIPS CryptoHash is 256 bits vs. 128, and the 'first_key' must be checked first, so
+  // ensure that the new 'first_key' overlaps the old 'first_key' and that the rest of the data layout
+  // is the same by putting 'key' at the ned.
+  CryptoHash first_key; ///< first key in object.
+#endif
   uint32_t hlen;         ///< Length of this header.
   uint32_t doc_type : 8; ///< Doc type - indicates the format of this structure and its content.
   uint32_t v_major : 8;  ///< Major version number.
@@ -290,6 +297,9 @@ struct Doc {
   uint32_t write_serial;
   uint32_t pinned; // pinned until
   uint32_t checksum;
+#ifdef TS_ENABLE_FIPS
+  CryptoHash key; ///< Key for this doc.
+#endif
 
   uint32_t data_len();
   uint32_t prefix_len();
diff --git a/iocore/cache/P_RamCache.h b/iocore/cache/P_RamCache.h
index ae653a4..823b789 100644
--- a/iocore/cache/P_RamCache.h
+++ b/iocore/cache/P_RamCache.h
@@ -30,11 +30,12 @@
 
 struct RamCache {
   // returns 1 on found/stored, 0 on not found/stored, if provided auxkey1 and auxkey2 must match
-  virtual int get(INK_MD5 *key, Ptr<IOBufferData> *ret_data, uint32_t auxkey1 = 0, uint32_t auxkey2 = 0) = 0;
-  virtual int put(INK_MD5 *key, IOBufferData *data, uint32_t len, bool copy = false, uint32_t auxkey1 = 0,
+  virtual int get(CryptoHash *key, Ptr<IOBufferData> *ret_data, uint32_t auxkey1 = 0, uint32_t auxkey2 = 0) = 0;
+  virtual int put(CryptoHash *key, IOBufferData *data, uint32_t len, bool copy = false, uint32_t auxkey1 = 0,
                   uint32_t auxkey2 = 0) = 0;
-  virtual int fixup(const INK_MD5 *key, uint32_t old_auxkey1, uint32_t old_auxkey2, uint32_t new_auxkey1, uint32_t new_auxkey2) = 0;
-  virtual int64_t size() const = 0;
+  virtual int fixup(const CryptoHash *key, uint32_t old_auxkey1, uint32_t old_auxkey2, uint32_t new_auxkey1,
+                    uint32_t new_auxkey2) = 0;
+  virtual int64_t size() const            = 0;
 
   virtual void init(int64_t max_bytes, Vol *vol) = 0;
   virtual ~RamCache(){};
diff --git a/iocore/cache/RamCacheCLFUS.cc b/iocore/cache/RamCacheCLFUS.cc
index 2cee965..9f383f5 100644
--- a/iocore/cache/RamCacheCLFUS.cc
+++ b/iocore/cache/RamCacheCLFUS.cc
@@ -49,7 +49,7 @@
 #define REQUEUE_LIMIT 100
 
 struct RamCacheCLFUSEntry {
-  INK_MD5 key;
+  CryptoHash key;
   uint32_t auxkey1;
   uint32_t auxkey2;
   uint64_t hits;
@@ -76,9 +76,10 @@ struct RamCacheCLFUS : public RamCache {
   int64_t objects;
 
   // returns 1 on found/stored, 0 on not found/stored, if provided auxkey1 and auxkey2 must match
-  int get(INK_MD5 *key, Ptr<IOBufferData> *ret_data, uint32_t auxkey1 = 0, uint32_t auxkey2 = 0) override;
-  int put(INK_MD5 *key, IOBufferData *data, uint32_t len, bool copy = false, uint32_t auxkey1 = 0, uint32_t auxkey2 = 0) override;
-  int fixup(const INK_MD5 *key, uint32_t old_auxkey1, uint32_t old_auxkey2, uint32_t new_auxkey1, uint32_t new_auxkey2) override;
+  int get(CryptoHash *key, Ptr<IOBufferData> *ret_data, uint32_t auxkey1 = 0, uint32_t auxkey2 = 0) override;
+  int put(CryptoHash *key, IOBufferData *data, uint32_t len, bool copy = false, uint32_t auxkey1 = 0,
+          uint32_t auxkey2 = 0) override;
+  int fixup(const CryptoHash *key, uint32_t old_auxkey1, uint32_t old_auxkey2, uint32_t new_auxkey1, uint32_t new_auxkey2) override;
   int64_t size() const override;
 
   void init(int64_t max_bytes, Vol *vol) override;
@@ -244,7 +245,7 @@ check_accounting(RamCacheCLFUS *c)
 #endif
 
 int
-RamCacheCLFUS::get(INK_MD5 *key, Ptr<IOBufferData> *ret_data, uint32_t auxkey1, uint32_t auxkey2)
+RamCacheCLFUS::get(CryptoHash *key, Ptr<IOBufferData> *ret_data, uint32_t auxkey1, uint32_t auxkey2)
 {
   if (!max_bytes) {
     return 0;
@@ -464,7 +465,7 @@ RamCacheCLFUS::compress_entries(EThread *thread, int do_at_most)
       // store transient data for lock release
       Ptr<IOBufferData> edata = e->data;
       uint32_t elen           = e->len;
-      INK_MD5 key             = e->key;
+      CryptoHash key          = e->key;
       MUTEX_UNTAKE_LOCK(vol->mutex, thread);
       b           = (char *)ats_malloc(l);
       bool failed = false;
@@ -581,7 +582,7 @@ void RamCacheCLFUS::requeue_victims(Que(RamCacheCLFUSEntry, lru_link) & victims)
 }
 
 int
-RamCacheCLFUS::put(INK_MD5 *key, IOBufferData *data, uint32_t len, bool copy, uint32_t auxkey1, uint32_t auxkey2)
+RamCacheCLFUS::put(CryptoHash *key, IOBufferData *data, uint32_t len, bool copy, uint32_t auxkey1, uint32_t auxkey2)
 {
   if (!max_bytes) {
     return 0;
@@ -758,7 +759,7 @@ Lhistory:
 }
 
 int
-RamCacheCLFUS::fixup(const INK_MD5 *key, uint32_t old_auxkey1, uint32_t old_auxkey2, uint32_t new_auxkey1, uint32_t new_auxkey2)
+RamCacheCLFUS::fixup(const CryptoHash *key, uint32_t old_auxkey1, uint32_t old_auxkey2, uint32_t new_auxkey1, uint32_t new_auxkey2)
 {
   if (!max_bytes) {
     return 0;
diff --git a/iocore/cache/RamCacheLRU.cc b/iocore/cache/RamCacheLRU.cc
index 38fa7f0..6473f26 100644
--- a/iocore/cache/RamCacheLRU.cc
+++ b/iocore/cache/RamCacheLRU.cc
@@ -24,7 +24,7 @@
 #include "P_Cache.h"
 
 struct RamCacheLRUEntry {
-  INK_MD5 key;
+  CryptoHash key;
   uint32_t auxkey1;
   uint32_t auxkey2;
   LINK(RamCacheLRUEntry, lru_link);
@@ -40,9 +40,10 @@ struct RamCacheLRU : public RamCache {
   int64_t objects   = 0;
 
   // returns 1 on found/stored, 0 on not found/stored, if provided auxkey1 and auxkey2 must match
-  int get(INK_MD5 *key, Ptr<IOBufferData> *ret_data, uint32_t auxkey1 = 0, uint32_t auxkey2 = 0) override;
-  int put(INK_MD5 *key, IOBufferData *data, uint32_t len, bool copy = false, uint32_t auxkey1 = 0, uint32_t auxkey2 = 0) override;
-  int fixup(const INK_MD5 *key, uint32_t old_auxkey1, uint32_t old_auxkey2, uint32_t new_auxkey1, uint32_t new_auxkey2) override;
+  int get(CryptoHash *key, Ptr<IOBufferData> *ret_data, uint32_t auxkey1 = 0, uint32_t auxkey2 = 0) override;
+  int put(CryptoHash *key, IOBufferData *data, uint32_t len, bool copy = false, uint32_t auxkey1 = 0,
+          uint32_t auxkey2 = 0) override;
+  int fixup(const CryptoHash *key, uint32_t old_auxkey1, uint32_t old_auxkey2, uint32_t new_auxkey1, uint32_t new_auxkey2) override;
   int64_t size() const override;
 
   void init(int64_t max_bytes, Vol *vol) override;
@@ -118,7 +119,7 @@ RamCacheLRU::init(int64_t abytes, Vol *avol)
 }
 
 int
-RamCacheLRU::get(INK_MD5 *key, Ptr<IOBufferData> *ret_data, uint32_t auxkey1, uint32_t auxkey2)
+RamCacheLRU::get(CryptoHash *key, Ptr<IOBufferData> *ret_data, uint32_t auxkey1, uint32_t auxkey2)
 {
   if (!max_bytes) {
     return 0;
@@ -159,7 +160,7 @@ RamCacheLRU::remove(RamCacheLRUEntry *e)
 
 // ignore 'copy' since we don't touch the data
 int
-RamCacheLRU::put(INK_MD5 *key, IOBufferData *data, uint32_t len, bool, uint32_t auxkey1, uint32_t auxkey2)
+RamCacheLRU::put(CryptoHash *key, IOBufferData *data, uint32_t len, bool, uint32_t auxkey1, uint32_t auxkey2)
 {
   if (!max_bytes) {
     return 0;
@@ -215,7 +216,7 @@ RamCacheLRU::put(INK_MD5 *key, IOBufferData *data, uint32_t len, bool, uint32_t
 }
 
 int
-RamCacheLRU::fixup(const INK_MD5 *key, uint32_t old_auxkey1, uint32_t old_auxkey2, uint32_t new_auxkey1, uint32_t new_auxkey2)
+RamCacheLRU::fixup(const CryptoHash *key, uint32_t old_auxkey1, uint32_t old_auxkey2, uint32_t new_auxkey1, uint32_t new_auxkey2)
 {
   if (!max_bytes) {
     return 0;
diff --git a/iocore/hostdb/HostDB.cc b/iocore/hostdb/HostDB.cc
index af42b1c..9695fa0 100644
--- a/iocore/hostdb/HostDB.cc
+++ b/iocore/hostdb/HostDB.cc
@@ -166,8 +166,8 @@ string_for(HostDBMark mark)
 //
 static Action *register_ShowHostDB(Continuation *c, HTTPHdr *h);
 
-HostDBMD5 &
-HostDBMD5::set_host(const char *name, int len)
+HostDBHash &
+HostDBHash::set_host(const char *name, int len)
 {
   host_name = name;
   host_len  = len;
@@ -196,9 +196,9 @@ HostDBMD5::set_host(const char *name, int len)
 }
 
 void
-HostDBMD5::refresh()
+HostDBHash::refresh()
 {
-  MD5Context ctx;
+  CryptoContext ctx;
 
   if (host_name) {
     const char *server_line = dns_server ? dns_server->x_dns_ip_line : nullptr;
@@ -211,7 +211,7 @@ HostDBMD5::refresh()
       ctx.update(server_line, strlen(server_line));
     }
   } else {
-    // INK_MD5 the ip, pad on both sizes with 0's
+    // CryptoHash the ip, pad on both sizes with 0's
     // so that it does not intersect the string space
     //
     char buff[TS_IP6_SIZE + 4];
@@ -224,11 +224,11 @@ HostDBMD5::refresh()
   ctx.finalize(hash);
 }
 
-HostDBMD5::HostDBMD5() : host_name(nullptr), host_len(0), port(0), dns_server(nullptr), pSD(nullptr), db_mark(HOSTDB_MARK_GENERIC)
+HostDBHash::HostDBHash() : host_name(nullptr), host_len(0), port(0), dns_server(nullptr), pSD(nullptr), db_mark(HOSTDB_MARK_GENERIC)
 {
 }
 
-HostDBMD5::~HostDBMD5()
+HostDBHash::~HostDBHash()
 {
   if (pSD) {
     SplitDNSConfig::release(pSD);
@@ -241,11 +241,11 @@ HostDBCache::HostDBCache() : refcountcache(nullptr), pending_dns(nullptr), remot
 }
 
 bool
-HostDBCache::is_pending_dns_for_hash(const INK_MD5 &md5_hash)
+HostDBCache::is_pending_dns_for_hash(const CryptoHash &hash)
 {
-  Queue<HostDBContinuation> &q = pending_dns_for_hash(md5_hash);
+  Queue<HostDBContinuation> &q = pending_dns_for_hash(hash);
   for (HostDBContinuation *c = q.head; c; c = (HostDBContinuation *)c->link.next) {
-    if (md5_hash == c->md5.hash) {
+    if (hash == c->hash.hash) {
       return true;
     }
   }
@@ -426,24 +426,24 @@ HostDBProcessor::start(int, size_t)
 }
 
 void
-HostDBContinuation::init(HostDBMD5 const &the_md5, Options const &opt)
+HostDBContinuation::init(HostDBHash const &the_hash, Options const &opt)
 {
-  md5 = the_md5;
-  if (md5.host_name) {
+  hash = the_hash;
+  if (hash.host_name) {
     // copy to backing store.
-    if (md5.host_len > static_cast<int>(sizeof(md5_host_name_store) - 1)) {
-      md5.host_len = sizeof(md5_host_name_store) - 1;
+    if (hash.host_len > static_cast<int>(sizeof(hash_host_name_store) - 1)) {
+      hash.host_len = sizeof(hash_host_name_store) - 1;
     }
-    memcpy(md5_host_name_store, md5.host_name, md5.host_len);
+    memcpy(hash_host_name_store, hash.host_name, hash.host_len);
   } else {
-    md5.host_len = 0;
+    hash.host_len = 0;
   }
-  md5_host_name_store[md5.host_len] = 0;
-  md5.host_name                     = md5_host_name_store;
+  hash_host_name_store[hash.host_len] = 0;
+  hash.host_name                      = hash_host_name_store;
 
   host_res_style     = opt.host_res_style;
   dns_lookup_timeout = opt.timeout;
-  mutex              = hostDB.refcountcache->lock_for_key(md5.hash.fold());
+  mutex              = hostDB.refcountcache->lock_for_key(hash.hash.fold());
   if (opt.cont) {
     action = opt.cont;
   } else {
@@ -453,16 +453,16 @@ HostDBContinuation::init(HostDBMD5 const &the_md5, Options const &opt)
 }
 
 void
-HostDBContinuation::refresh_MD5()
+HostDBContinuation::refresh_hash()
 {
-  ProxyMutex *old_bucket_mutex = hostDB.refcountcache->lock_for_key(md5.hash.fold());
+  ProxyMutex *old_bucket_mutex = hostDB.refcountcache->lock_for_key(hash.hash.fold());
   // We're not pending DNS anymore.
   remove_trigger_pending_dns();
-  md5.refresh();
+  hash.refresh();
   // Update the mutex if it's from the bucket.
   // Some call sites modify this after calling @c init so need to check.
   if (mutex.get() == old_bucket_mutex) {
-    mutex = hostDB.refcountcache->lock_for_key(md5.hash.fold());
+    mutex = hostDB.refcountcache->lock_for_key(hash.hash.fold());
   }
 }
 
@@ -539,7 +539,7 @@ db_mark_for(IpAddr const &ip)
 }
 
 Ptr<HostDBInfo>
-probe(ProxyMutex *mutex, HostDBMD5 const &md5, bool ignore_timeout)
+probe(ProxyMutex *mutex, HostDBHash const &hash, bool ignore_timeout)
 {
   // If hostdb is disabled, don't return anything
   if (!hostdb_enable) {
@@ -547,11 +547,11 @@ probe(ProxyMutex *mutex, HostDBMD5 const &md5, bool ignore_timeout)
   }
 
   // Otherwise HostDB is enabled, so we'll do our thing
-  ink_assert(this_ethread() == hostDB.refcountcache->lock_for_key(md5.hash.fold())->thread_holding);
-  uint64_t folded_md5 = md5.hash.fold();
+  ink_assert(this_ethread() == hostDB.refcountcache->lock_for_key(hash.hash.fold())->thread_holding);
+  uint64_t folded_hash = hash.hash.fold();
 
   // get the item from cache
-  Ptr<HostDBInfo> r = hostDB.refcountcache->get(folded_md5);
+  Ptr<HostDBInfo> r = hostDB.refcountcache->get(folded_hash);
   // If there was nothing in the cache-- this is a miss
   if (r.get() == nullptr) {
     return r;
@@ -568,7 +568,7 @@ probe(ProxyMutex *mutex, HostDBMD5 const &md5, bool ignore_timeout)
 
   // If the record is stale, but we want to revalidate-- lets start that up
   if ((!ignore_timeout && r->is_ip_stale() && !r->reverse_dns) || (r->is_ip_timeout() && r->serve_stale_but_revalidate())) {
-    if (hostDB.is_pending_dns_for_hash(md5.hash)) {
+    if (hostDB.is_pending_dns_for_hash(hash.hash)) {
       Debug("hostdb", "stale %u %u %u, using it and pending to refresh it", r->ip_interval(), r->ip_timestamp,
             r->ip_timeout_interval);
       return r;
@@ -577,7 +577,7 @@ probe(ProxyMutex *mutex, HostDBMD5 const &md5, bool ignore_timeout)
     HostDBContinuation *c = hostDBContAllocator.alloc();
     HostDBContinuation::Options copt;
     copt.host_res_style = host_res_style_for(r->ip());
-    c->init(md5, copt);
+    c->init(hash, copt);
     c->do_dns();
   }
   return r;
@@ -590,21 +590,21 @@ probe(ProxyMutex *mutex, HostDBMD5 const &md5, bool ignore_timeout)
 HostDBInfo *
 HostDBContinuation::insert(unsigned int attl)
 {
-  uint64_t folded_md5 = md5.hash.fold();
+  uint64_t folded_hash = hash.hash.fold();
 
-  ink_assert(this_ethread() == hostDB.refcountcache->lock_for_key(folded_md5)->thread_holding);
+  ink_assert(this_ethread() == hostDB.refcountcache->lock_for_key(folded_hash)->thread_holding);
 
   HostDBInfo *r = HostDBInfo::alloc();
-  r->key        = folded_md5;
+  r->key        = folded_hash;
   if (attl > HOST_DB_MAX_TTL) {
     attl = HOST_DB_MAX_TTL;
   }
   r->ip_timeout_interval = attl;
   r->ip_timestamp        = hostdb_current_interval;
-  Debug("hostdb", "inserting for: %.*s: (md5: %" PRIx64 ") now: %u timeout: %u ttl: %u", md5.host_len, md5.host_name, folded_md5,
-        r->ip_timestamp, r->ip_timeout_interval, attl);
+  Debug("hostdb", "inserting for: %.*s: (hash: %" PRIx64 ") now: %u timeout: %u ttl: %u", hash.host_len, hash.host_name,
+        folded_hash, r->ip_timestamp, r->ip_timeout_interval, attl);
 
-  hostDB.refcountcache->put(folded_md5, r, 0, r->expiry_time());
+  hostDB.refcountcache->put(folded_hash, r, 0, r->expiry_time());
   return r;
 }
 
@@ -615,7 +615,7 @@ Action *
 HostDBProcessor::getby(Continuation *cont, const char *hostname, int len, sockaddr const *ip, bool aforce_dns,
                        HostResStyle host_res_style, int dns_lookup_timeout)
 {
-  HostDBMD5 md5;
+  HostDBHash hash;
   EThread *thread   = this_ethread();
   ProxyMutex *mutex = thread->mutex.get();
   ip_text_buffer ipb;
@@ -631,12 +631,12 @@ HostDBProcessor::getby(Continuation *cont, const char *hostname, int len, sockad
     return ACTION_RESULT_DONE;
   }
 
-  // Load the MD5 data.
-  md5.set_host(hostname, hostname ? (len ? len : strlen(hostname)) : 0);
-  md5.ip.assign(ip);
-  md5.port    = ip ? ats_ip_port_host_order(ip) : 0;
-  md5.db_mark = db_mark_for(host_res_style);
-  md5.refresh();
+  // Load the hash data.
+  hash.set_host(hostname, hostname ? (len ? len : strlen(hostname)) : 0);
+  hash.ip.assign(ip);
+  hash.port    = ip ? ats_ip_port_host_order(ip) : 0;
+  hash.db_mark = db_mark_for(host_res_style);
+  hash.refresh();
 
   // Attempt to find the result in-line, for level 1 hits
   //
@@ -647,16 +647,16 @@ HostDBProcessor::getby(Continuation *cont, const char *hostname, int len, sockad
       // find the partition lock
       //
       // TODO: Could we reuse the "mutex" above safely? I think so but not sure.
-      ProxyMutex *bmutex = hostDB.refcountcache->lock_for_key(md5.hash.fold());
+      ProxyMutex *bmutex = hostDB.refcountcache->lock_for_key(hash.hash.fold());
       MUTEX_TRY_LOCK(lock, bmutex, thread);
       MUTEX_TRY_LOCK(lock2, cont->mutex, thread);
 
       if (lock.is_locked() && lock2.is_locked()) {
         // If we can get the lock and a level 1 probe succeeds, return
-        Ptr<HostDBInfo> r = probe(bmutex, md5, aforce_dns);
+        Ptr<HostDBInfo> r = probe(bmutex, hash, aforce_dns);
         if (r) {
           if (r->is_failed() && hostname) {
-            loop = check_for_retry(md5.db_mark, host_res_style);
+            loop = check_for_retry(hash.db_mark, host_res_style);
           }
           if (!loop) {
             // No retry -> final result. Return it.
@@ -666,7 +666,7 @@ HostDBProcessor::getby(Continuation *cont, const char *hostname, int len, sockad
             reply_to_cont(cont, r.get());
             return ACTION_RESULT_DONE;
           }
-          md5.refresh(); // only on reloop, because we've changed the family.
+          hash.refresh(); // only on reloop, because we've changed the family.
         }
       }
     } while (loop);
@@ -683,7 +683,7 @@ Lretry:
   opt.force_dns      = aforce_dns;
   opt.cont           = cont;
   opt.host_res_style = host_res_style;
-  c->init(md5, opt);
+  c->init(hash, opt);
   SET_CONTINUATION_HANDLER(c, (HostDBContHandler)&HostDBContinuation::probeEvent);
 
   // Since ProxyMutexPtr has a cast operator, gcc-3.x get upset
@@ -759,7 +759,7 @@ HostDBProcessor::getSRVbyname_imm(Continuation *cont, process_srv_info_pfn proce
     }
   }
 
-  HostDBMD5 md5;
+  HostDBHash hash;
 
   HOSTDB_INCREMENT_DYN_STAT(hostdb_total_lookups_stat);
 
@@ -768,21 +768,21 @@ HostDBProcessor::getSRVbyname_imm(Continuation *cont, process_srv_info_pfn proce
     return ACTION_RESULT_DONE;
   }
 
-  md5.host_name = hostname;
-  md5.host_len  = len ? len : strlen(hostname);
-  md5.port      = 0;
-  md5.db_mark   = HOSTDB_MARK_SRV;
-  md5.refresh();
+  hash.host_name = hostname;
+  hash.host_len  = len ? len : strlen(hostname);
+  hash.port      = 0;
+  hash.db_mark   = HOSTDB_MARK_SRV;
+  hash.refresh();
 
   // Attempt to find the result in-line, for level 1 hits
   if (!force_dns) {
     // find the partition lock
-    ProxyMutex *bucket_mutex = hostDB.refcountcache->lock_for_key(md5.hash.fold());
+    ProxyMutex *bucket_mutex = hostDB.refcountcache->lock_for_key(hash.hash.fold());
     MUTEX_TRY_LOCK(lock, bucket_mutex, thread);
 
     // If we can get the lock and a level 1 probe succeeds, return
     if (lock.is_locked()) {
-      Ptr<HostDBInfo> r = probe(bucket_mutex, md5, false);
+      Ptr<HostDBInfo> r = probe(bucket_mutex, hash, false);
       if (r) {
         Debug("hostdb", "immediate SRV answer for %s from hostdb", hostname);
         Debug("dns_srv", "immediate SRV answer for %s from hostdb", hostname);
@@ -793,7 +793,7 @@ HostDBProcessor::getSRVbyname_imm(Continuation *cont, process_srv_info_pfn proce
     }
   }
 
-  Debug("dns_srv", "delaying (force=%d) SRV answer for %.*s [timeout = %d]", force_dns, md5.host_len, md5.host_name, opt.timeout);
+  Debug("dns_srv", "delaying (force=%d) SRV answer for %.*s [timeout = %d]", force_dns, hash.host_len, hash.host_name, opt.timeout);
 
   // Otherwise, create a continuation to do a deeper probe in the background
   HostDBContinuation *c = hostDBContAllocator.alloc();
@@ -801,7 +801,7 @@ HostDBProcessor::getSRVbyname_imm(Continuation *cont, process_srv_info_pfn proce
   copt.timeout   = opt.timeout;
   copt.cont      = cont;
   copt.force_dns = force_dns;
-  c->init(md5, copt);
+  c->init(hash, copt);
   SET_CONTINUATION_HANDLER(c, (HostDBContHandler)&HostDBContinuation::probeEvent);
 
   if (thread->mutex == cont->mutex) {
@@ -823,7 +823,7 @@ HostDBProcessor::getbyname_imm(Continuation *cont, process_hostdb_info_pfn proce
   bool force_dns    = false;
   EThread *thread   = cont->mutex->thread_holding;
   ProxyMutex *mutex = thread->mutex.get();
-  HostDBMD5 md5;
+  HostDBHash hash;
 
   ink_assert(nullptr != hostname);
 
@@ -843,10 +843,10 @@ HostDBProcessor::getbyname_imm(Continuation *cont, process_hostdb_info_pfn proce
     return ACTION_RESULT_DONE;
   }
 
-  md5.set_host(hostname, len ? len : strlen(hostname));
-  md5.port    = opt.port;
-  md5.db_mark = db_mark_for(opt.host_res_style);
-  md5.refresh();
+  hash.set_host(hostname, len ? len : strlen(hostname));
+  hash.port    = opt.port;
+  hash.db_mark = db_mark_for(opt.host_res_style);
+  hash.refresh();
 
   // Attempt to find the result in-line, for level 1 hits
   if (!force_dns) {
@@ -854,27 +854,27 @@ HostDBProcessor::getbyname_imm(Continuation *cont, process_hostdb_info_pfn proce
     do {
       loop = false; // loop only on explicit set for retry
       // find the partition lock
-      ProxyMutex *bucket_mutex = hostDB.refcountcache->lock_for_key(md5.hash.fold());
+      ProxyMutex *bucket_mutex = hostDB.refcountcache->lock_for_key(hash.hash.fold());
       SCOPED_MUTEX_LOCK(lock, bucket_mutex, thread);
       // do a level 1 probe for immediate result.
-      Ptr<HostDBInfo> r = probe(bucket_mutex, md5, false);
+      Ptr<HostDBInfo> r = probe(bucket_mutex, hash, false);
       if (r) {
         if (r->is_failed()) { // fail, see if we should retry with alternate
-          loop = check_for_retry(md5.db_mark, opt.host_res_style);
+          loop = check_for_retry(hash.db_mark, opt.host_res_style);
         }
         if (!loop) {
           // No retry -> final result. Return it.
-          Debug("hostdb", "immediate answer for %.*s", md5.host_len, md5.host_name);
+          Debug("hostdb", "immediate answer for %.*s", hash.host_len, hash.host_name);
           HOSTDB_INCREMENT_DYN_STAT(hostdb_total_hits_stat);
           (cont->*process_hostdb_info)(r.get());
           return ACTION_RESULT_DONE;
         }
-        md5.refresh(); // Update for retry.
+        hash.refresh(); // Update for retry.
       }
     } while (loop);
   }
 
-  Debug("hostdb", "delaying force %d answer for %.*s [timeout %d]", force_dns, md5.host_len, md5.host_name, opt.timeout);
+  Debug("hostdb", "delaying force %d answer for %.*s [timeout %d]", force_dns, hash.host_len, hash.host_name, opt.timeout);
 
   // Otherwise, create a continuation to do a deeper probe in the background
   HostDBContinuation *c = hostDBContAllocator.alloc();
@@ -883,7 +883,7 @@ HostDBProcessor::getbyname_imm(Continuation *cont, process_hostdb_info_pfn proce
   copt.force_dns      = force_dns;
   copt.timeout        = opt.timeout;
   copt.host_res_style = opt.host_res_style;
-  c->init(md5, copt);
+  c->init(hash, copt);
   SET_CONTINUATION_HANDLER(c, (HostDBContHandler)&HostDBContinuation::probeEvent);
 
   thread->schedule_in(c, HOST_DB_RETRY_PERIOD);
@@ -906,7 +906,7 @@ HostDBProcessor::iterate(Continuation *cont)
   copt.force_dns      = false;
   copt.timeout        = 0;
   copt.host_res_style = HOST_RES_NONE;
-  c->init(HostDBMD5(), copt);
+  c->init(HostDBHash(), copt);
   c->current_iterate_pos = 0;
   SET_CONTINUATION_HANDLER(c, (HostDBContHandler)&HostDBContinuation::iterateEvent);
 
@@ -965,30 +965,30 @@ HostDBProcessor::setby(const char *hostname, int len, sockaddr const *ip, HostDB
     return;
   }
 
-  HostDBMD5 md5;
-  md5.set_host(hostname, hostname ? (len ? len : strlen(hostname)) : 0);
-  md5.ip.assign(ip);
-  md5.port    = ip ? ats_ip_port_host_order(ip) : 0;
-  md5.db_mark = db_mark_for(ip);
-  md5.refresh();
+  HostDBHash hash;
+  hash.set_host(hostname, hostname ? (len ? len : strlen(hostname)) : 0);
+  hash.ip.assign(ip);
+  hash.port    = ip ? ats_ip_port_host_order(ip) : 0;
+  hash.db_mark = db_mark_for(ip);
+  hash.refresh();
 
   // Attempt to find the result in-line, for level 1 hits
 
-  ProxyMutex *mutex = hostDB.refcountcache->lock_for_key(md5.hash.fold());
+  ProxyMutex *mutex = hostDB.refcountcache->lock_for_key(hash.hash.fold());
   EThread *thread   = this_ethread();
   MUTEX_TRY_LOCK(lock, mutex, thread);
 
   if (lock.is_locked()) {
-    Ptr<HostDBInfo> r = probe(mutex, md5, false);
+    Ptr<HostDBInfo> r = probe(mutex, hash, false);
     if (r) {
-      do_setby(r.get(), app, hostname, md5.ip);
+      do_setby(r.get(), app, hostname, hash.ip);
     }
     return;
   }
   // Create a continuation to do a deaper probe in the background
 
   HostDBContinuation *c = hostDBContAllocator.alloc();
-  c->init(md5);
+  c->init(hash);
   c->app.allotment.application1 = app->allotment.application1;
   c->app.allotment.application2 = app->allotment.application2;
   SET_CONTINUATION_HANDLER(c, (HostDBContHandler)&HostDBContinuation::setbyEvent);
@@ -1002,16 +1002,16 @@ HostDBProcessor::setby_srv(const char *hostname, int len, const char *target, Ho
     return;
   }
 
-  HostDBMD5 md5;
-  md5.set_host(hostname, len ? len : strlen(hostname));
-  md5.port    = 0;
-  md5.db_mark = HOSTDB_MARK_SRV;
-  md5.refresh();
+  HostDBHash hash;
+  hash.set_host(hostname, len ? len : strlen(hostname));
+  hash.port    = 0;
+  hash.db_mark = HOSTDB_MARK_SRV;
+  hash.refresh();
 
   // Create a continuation to do a deaper probe in the background
 
   HostDBContinuation *c = hostDBContAllocator.alloc();
-  c->init(md5);
+  c->init(hash);
   ink_strlcpy(c->srv_target_name, target, MAXDNAME);
   c->app.allotment.application1 = app->allotment.application1;
   c->app.allotment.application2 = app->allotment.application2;
@@ -1021,10 +1021,10 @@ HostDBProcessor::setby_srv(const char *hostname, int len, const char *target, Ho
 int
 HostDBContinuation::setbyEvent(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */)
 {
-  Ptr<HostDBInfo> r = probe(mutex.get(), md5, false);
+  Ptr<HostDBInfo> r = probe(mutex.get(), hash, false);
 
   if (r) {
-    do_setby(r.get(), &app, md5.host_name, md5.ip, is_srv());
+    do_setby(r.get(), &app, hash.host_name, hash.ip, is_srv());
   }
 
   hostdb_cont_free(this);
@@ -1090,10 +1090,10 @@ HostDBContinuation::removeEvent(int /* event ATS_UNUSED */, Event *e)
         cont->handleEvent(EVENT_HOST_DB_IP_REMOVED, (void *)nullptr);
       }
     } else {
-      Ptr<HostDBInfo> r = probe(mutex.get(), md5, false);
-      bool res          = remove_round_robin(r.get(), md5.host_name, md5.ip);
+      Ptr<HostDBInfo> r = probe(mutex.get(), hash, false);
+      bool res          = remove_round_robin(r.get(), hash.host_name, hash.ip);
       if (cont) {
-        cont->handleEvent(EVENT_HOST_DB_IP_REMOVED, res ? static_cast<void *>(&md5.ip) : static_cast<void *>(nullptr));
+        cont->handleEvent(EVENT_HOST_DB_IP_REMOVED, res ? static_cast<void *>(&hash.ip) : static_cast<void *>(nullptr));
       }
     }
   }
@@ -1109,15 +1109,15 @@ HostDBInfo *
 HostDBContinuation::lookup_done(IpAddr const &ip, const char *aname, bool around_robin, unsigned int ttl_seconds, SRVHosts *srv,
                                 HostDBInfo *r)
 {
-  ink_assert(this_ethread() == hostDB.refcountcache->lock_for_key(md5.hash.fold())->thread_holding);
+  ink_assert(this_ethread() == hostDB.refcountcache->lock_for_key(hash.hash.fold())->thread_holding);
   if (!ip.isValid() || !aname || !aname[0]) {
     if (is_byname()) {
-      Debug("hostdb", "lookup_done() failed for '%.*s'", md5.host_len, md5.host_name);
+      Debug("hostdb", "lookup_done() failed for '%.*s'", hash.host_len, hash.host_name);
     } else if (is_srv()) {
-      Debug("dns_srv", "SRV failed for '%.*s'", md5.host_len, md5.host_name);
+      Debug("dns_srv", "SRV failed for '%.*s'", hash.host_len, hash.host_name);
     } else {
       ip_text_buffer b;
-      Debug("hostdb", "failed for %s", md5.ip.toString(b, sizeof b));
+      Debug("hostdb", "failed for %s", hash.ip.toString(b, sizeof b));
     }
     if (r == nullptr) {
       r = insert(hostdb_ip_fail_timeout_interval); // currently ... 0
@@ -1169,8 +1169,8 @@ HostDBContinuation::lookup_done(IpAddr const &ip, const char *aname, bool around
       ats_ip_set(r->ip(), ip);
       r->round_robin = around_robin;
       r->reverse_dns = false;
-      if (md5.host_name != aname) {
-        ink_strlcpy(md5_host_name_store, aname, sizeof(md5_host_name_store));
+      if (hash.host_name != aname) {
+        ink_strlcpy(hash_host_name_store, aname, sizeof(hash_host_name_store));
       }
       r->is_srv = false;
     } else if (is_srv()) {
@@ -1181,8 +1181,8 @@ HostDBContinuation::lookup_done(IpAddr const &ip, const char *aname, bool around
       r->is_srv              = true;
       r->round_robin         = around_robin;
 
-      if (md5.host_name != aname) {
-        ink_strlcpy(md5_host_name_store, aname, sizeof(md5_host_name_store));
+      if (hash.host_name != aname) {
+        ink_strlcpy(hash_host_name_store, aname, sizeof(hash_host_name_store));
       }
 
     } else {
@@ -1208,7 +1208,7 @@ HostDBContinuation::lookup_done(IpAddr const &ip, const char *aname, bool around
 int
 HostDBContinuation::dnsPendingEvent(int event, Event *e)
 {
-  ink_assert(this_ethread() == hostDB.refcountcache->lock_for_key(md5.hash.fold())->thread_holding);
+  ink_assert(this_ethread() == hostDB.refcountcache->lock_for_key(hash.hash.fold())->thread_holding);
   if (timeout) {
     timeout->cancel(this);
     timeout = nullptr;
@@ -1223,7 +1223,7 @@ HostDBContinuation::dnsPendingEvent(int event, Event *e)
     if (!action.cancelled && action.continuation) {
       action.continuation->handleEvent(EVENT_HOST_DB_LOOKUP, nullptr);
     }
-    hostDB.pending_dns_for_hash(md5.hash).remove(this);
+    hostDB.pending_dns_for_hash(hash.hash).remove(this);
     hostdb_cont_free(this);
     return EVENT_DONE;
   } else {
@@ -1257,7 +1257,7 @@ restore_info(HostDBInfo *r, HostDBInfo *old_r, HostDBInfo &old_info, HostDBRound
 int
 HostDBContinuation::dnsEvent(int event, HostEnt *e)
 {
-  ink_assert(this_ethread() == hostDB.refcountcache->lock_for_key(md5.hash.fold())->thread_holding);
+  ink_assert(this_ethread() == hostDB.refcountcache->lock_for_key(hash.hash.fold())->thread_holding);
   if (timeout) {
     timeout->cancel(this);
     timeout = nullptr;
@@ -1302,7 +1302,7 @@ HostDBContinuation::dnsEvent(int event, HostEnt *e)
     ttl             = failed ? 0 : e->ttl / 60;
     int ttl_seconds = failed ? 0 : e->ttl; // ebalsa: moving to second accuracy
 
-    Ptr<HostDBInfo> old_r = probe(mutex.get(), md5, false);
+    Ptr<HostDBInfo> old_r = probe(mutex.get(), hash, false);
     // If the DNS lookup failed with NXDOMAIN, remove the old record
     if (e && e->isNameError() && old_r) {
       hostDB.refcountcache->erase(old_r->key);
@@ -1340,7 +1340,7 @@ HostDBContinuation::dnsEvent(int event, HostEnt *e)
 
             ++valid_records;
           } else {
-            Warning("Zero address removed from round-robin list for '%s'", md5.host_name);
+            Warning("Zero address removed from round-robin list for '%s'", hash.host_name);
           }
         }
         if (!first_record) {
@@ -1354,8 +1354,8 @@ HostDBContinuation::dnsEvent(int event, HostEnt *e)
 
     IpAddr tip; // temp storage if needed.
 
-    // In the event that the lookup failed (SOA response-- for example) we want to use md5.host_name, since it'll be ""
-    const char *aname = (failed || strlen(md5.host_name)) ? md5.host_name : e->ent.h_name;
+    // In the event that the lookup failed (SOA response-- for example) we want to use hash.host_name, since it'll be ""
+    const char *aname = (failed || strlen(hash.host_name)) ? hash.host_name : e->ent.h_name;
 
     const size_t s_size = strlen(aname) + 1;
     const size_t rrsize = is_rr ? HostDBRoundRobin::size(valid_records, e->srv_hosts.srv_hosts_length) : 0;
@@ -1367,7 +1367,7 @@ HostDBContinuation::dnsEvent(int event, HostEnt *e)
     HostDBInfo *r = HostDBInfo::alloc(allocSize);
     Debug("hostdb", "allocating %d bytes for %s with %d RR records at [%p]", allocSize, aname, valid_records, r);
     // set up the record
-    r->key = md5.hash.fold(); // always set the key
+    r->key = hash.hash.fold(); // always set the key
 
     r->hostname_offset = offset;
     ink_strlcpy(r->perm_hostname(), aname, s_size);
@@ -1383,20 +1383,20 @@ HostDBContinuation::dnsEvent(int event, HostEnt *e)
       if (first_record) {
         ip_addr_set(tip, af, first_record);
       }
-      r = lookup_done(tip, md5.host_name, is_rr, ttl_seconds, failed ? nullptr : &e->srv_hosts, r);
+      r = lookup_done(tip, hash.host_name, is_rr, ttl_seconds, failed ? nullptr : &e->srv_hosts, r);
     } else if (is_srv()) {
       if (!failed) {
         tip._family = AF_INET; // force the tip valid, or else the srv will fail
       }
-      r = lookup_done(tip,           /* junk: FIXME: is the code in lookup_done() wrong to NEED this? */
-                      md5.host_name, /* hostname */
-                      is_rr,         /* is round robin, doesnt matter for SRV since we recheck getCount() inside lookup_done() */
-                      ttl_seconds,   /* ttl in seconds */
+      r = lookup_done(tip,            /* junk: FIXME: is the code in lookup_done() wrong to NEED this? */
+                      hash.host_name, /* hostname */
+                      is_rr,          /* is round robin, doesnt matter for SRV since we recheck getCount() inside lookup_done() */
+                      ttl_seconds,    /* ttl in seconds */
                       failed ? nullptr : &e->srv_hosts, r);
     } else if (failed) {
-      r = lookup_done(tip, md5.host_name, false, ttl_seconds, nullptr, r);
+      r = lookup_done(tip, hash.host_name, false, ttl_seconds, nullptr, r);
     } else {
-      r = lookup_done(md5.ip, e->ent.h_name, false, ttl_seconds, &e->srv_hosts, r);
+      r = lookup_done(hash.ip, e->ent.h_name, false, ttl_seconds, &e->srv_hosts, r);
     }
 
     // Conditionally make rr record entries
@@ -1488,14 +1488,14 @@ HostDBContinuation::dnsEvent(int event, HostEnt *e)
     ink_assert(!r || !r->round_robin || !r->reverse_dns);
     ink_assert(failed || !r->round_robin || r->app.rr.offset);
 
-    hostDB.refcountcache->put(md5.hash.fold(), r, allocSize, r->expiry_time());
+    hostDB.refcountcache->put(hash.hash.fold(), r, allocSize, r->expiry_time());
 
     // try to callback the user
     //
     if (action.continuation) {
       // Check for IP family failover
-      if (failed && check_for_retry(md5.db_mark, host_res_style)) {
-        this->refresh_MD5(); // family changed if we're doing a retry.
+      if (failed && check_for_retry(hash.db_mark, host_res_style)) {
+        this->refresh_hash(); // family changed if we're doing a retry.
         SET_CONTINUATION_HANDLER(this, (HostDBContHandler)&HostDBContinuation::probeEvent);
         thread->schedule_in(this, MUTEX_RETRY_DELAY);
         return EVENT_CONT;
@@ -1597,7 +1597,7 @@ HostDBContinuation::probeEvent(int /* event ATS_UNUSED */, Event *e)
     return EVENT_DONE;
   }
 
-  if (!hostdb_enable || (!*md5.host_name && !md5.ip.isValid())) {
+  if (!hostdb_enable || (!*hash.host_name && !hash.ip.isValid())) {
     if (action.continuation) {
       action.continuation->handleEvent(EVENT_HOST_DB_LOOKUP, nullptr);
     }
@@ -1608,7 +1608,7 @@ HostDBContinuation::probeEvent(int /* event ATS_UNUSED */, Event *e)
   if (!force_dns) {
     // Do the probe
     //
-    Ptr<HostDBInfo> r = probe(mutex.get(), md5, false);
+    Ptr<HostDBInfo> r = probe(mutex.get(), hash, false);
 
     if (r) {
       HOSTDB_INCREMENT_DYN_STAT(hostdb_total_hits_stat);
@@ -1634,10 +1634,10 @@ HostDBContinuation::probeEvent(int /* event ATS_UNUSED */, Event *e)
 int
 HostDBContinuation::set_check_pending_dns()
 {
-  Queue<HostDBContinuation> &q = hostDB.pending_dns_for_hash(md5.hash);
+  Queue<HostDBContinuation> &q = hostDB.pending_dns_for_hash(hash.hash);
   HostDBContinuation *c        = q.head;
   for (; c; c = (HostDBContinuation *)c->link.next) {
-    if (md5.hash == c->md5.hash) {
+    if (hash.hash == c->hash.hash) {
       Debug("hostdb", "enqueuing additional request");
       q.enqueue(this);
       return false;
@@ -1650,13 +1650,13 @@ HostDBContinuation::set_check_pending_dns()
 void
 HostDBContinuation::remove_trigger_pending_dns()
 {
-  Queue<HostDBContinuation> &q = hostDB.pending_dns_for_hash(md5.hash);
+  Queue<HostDBContinuation> &q = hostDB.pending_dns_for_hash(hash.hash);
   q.remove(this);
   HostDBContinuation *c = q.head;
   Queue<HostDBContinuation> qq;
   while (c) {
     HostDBContinuation *n = (HostDBContinuation *)c->link.next;
-    if (md5.hash == c->md5.hash) {
+    if (hash.hash == c->hash.hash) {
       Debug("hostdb", "dequeuing additional request");
       q.remove(c);
       qq.enqueue(c);
@@ -1676,25 +1676,25 @@ HostDBContinuation::do_dns()
 {
   ink_assert(!action.cancelled);
   if (is_byname()) {
-    Debug("hostdb", "DNS %s", md5.host_name);
+    Debug("hostdb", "DNS %s", hash.host_name);
     IpAddr tip;
-    if (0 == tip.load(md5.host_name)) {
+    if (0 == tip.load(hash.host_name)) {
       // check 127.0.0.1 format // What the heck does that mean? - AMC
       if (action.continuation) {
-        HostDBInfo *r = lookup_done(tip, md5.host_name, false, HOST_DB_MAX_TTL, nullptr);
+        HostDBInfo *r = lookup_done(tip, hash.host_name, false, HOST_DB_MAX_TTL, nullptr);
 
         reply_to_cont(action.continuation, r);
       }
       hostdb_cont_free(this);
       return;
     }
-    ts::ConstBuffer hname(md5.host_name, md5.host_len);
+    ts::ConstBuffer hname(hash.host_name, hash.host_len);
     Ptr<RefCountedHostsFileMap> current_host_file_map = hostDB.hosts_file_ptr;
     HostsFileMap::iterator find_result                = current_host_file_map->hosts_file_map.find(hname);
     if (find_result != current_host_file_map->hosts_file_map.end()) {
       if (action.continuation) {
         // Set the TTL based on how much time remains until the next sync
-        HostDBInfo *r = lookup_done(IpAddr(find_result->second), md5.host_name, false,
+        HostDBInfo *r = lookup_done(IpAddr(find_result->second), hash.host_name, false,
                                     current_host_file_map->next_sync_time - ink_time(), nullptr);
         reply_to_cont(action.continuation, r);
       }
@@ -1710,20 +1710,20 @@ HostDBContinuation::do_dns()
   if (set_check_pending_dns()) {
     DNSProcessor::Options opt;
     opt.timeout        = dns_lookup_timeout;
-    opt.host_res_style = host_res_style_for(md5.db_mark);
+    opt.host_res_style = host_res_style_for(hash.db_mark);
     SET_HANDLER((HostDBContHandler)&HostDBContinuation::dnsEvent);
     if (is_byname()) {
-      if (md5.dns_server) {
-        opt.handler = md5.dns_server->x_dnsH;
+      if (hash.dns_server) {
+        opt.handler = hash.dns_server->x_dnsH;
       }
-      pending_action = dnsProcessor.gethostbyname(this, md5.host_name, opt);
+      pending_action = dnsProcessor.gethostbyname(this, hash.host_name, opt);
     } else if (is_srv()) {
-      Debug("dns_srv", "SRV lookup of %s", md5.host_name);
-      pending_action = dnsProcessor.getSRVbyname(this, md5.host_name, opt);
+      Debug("dns_srv", "SRV lookup of %s", hash.host_name);
+      pending_action = dnsProcessor.getSRVbyname(this, hash.host_name, opt);
     } else {
       ip_text_buffer ipb;
-      Debug("hostdb", "DNS IP %s", md5.ip.toString(ipb, sizeof ipb));
-      pending_action = dnsProcessor.gethostbyaddr(this, &md5.ip, opt);
+      Debug("hostdb", "DNS IP %s", hash.ip.toString(ipb, sizeof ipb));
+      pending_action = dnsProcessor.gethostbyaddr(this, &hash.ip, opt);
     }
   } else {
     SET_HANDLER((HostDBContHandler)&HostDBContinuation::dnsPendingEvent);
@@ -1949,7 +1949,7 @@ struct ShowHostDB : public ShowCont {
         CHECK_SHOW(show("<tr><td>%s</td><td>%s</td></tr>\n", "Hostname", r->srvname(hostdb_rr)));
       }
 
-      // Let's display the MD5.
+      // Let's display the hash.
       CHECK_SHOW(show("<tr><td>%s</td><td>%u</td></tr>\n", "App1", r->app.allotment.application1));
       CHECK_SHOW(show("<tr><td>%s</td><td>%u</td></tr>\n", "App2", r->app.allotment.application2));
       CHECK_SHOW(show("<tr><td>%s</td><td>%u</td></tr>\n", "LastFailure", r->app.http_data.last_failure));
@@ -2219,12 +2219,12 @@ struct HostFilePair {
 
 struct HostDBFileContinuation : public Continuation {
   using self = HostDBFileContinuation;
-  using Keys = std::vector<INK_MD5>;
+  using Keys = std::vector<CryptoHash>;
 
   int idx          = 0;       ///< Working index.
   const char *name = nullptr; ///< Host name (just for debugging)
   Keys *keys       = nullptr; ///< Entries from file.
-  INK_MD5 md5;                ///< Key for entry.
+  CryptoHash hash;            ///< Key for entry.
   ats_scoped_str path;        ///< Used to keep the host file name around.
 
   HostDBFileContinuation() : Continuation(nullptr) {}
diff --git a/iocore/hostdb/I_HostDB.h b/iocore/hostdb/I_HostDB.h
index a143467..bc41ea9 100644
--- a/iocore/hostdb/I_HostDB.h
+++ b/iocore/hostdb/I_HostDB.h
@@ -38,8 +38,9 @@
 #include "I_HostDBProcessor.h"
 
 // TS-1925: switch from MMH to MD5 hash; bumped to version 2
+// switch from MD5 to SHA256 hash; bumped to version 3
 // 2.1: Switched to mark RR elements.
-#define HOSTDB_MODULE_MAJOR_VERSION 2
+#define HOSTDB_MODULE_MAJOR_VERSION 3
 #define HOSTDB_MODULE_MINOR_VERSION 1
 
 #define HOSTDB_MODULE_VERSION makeModuleVersion(HOSTDB_MODULE_MAJOR_VERSION, HOSTDB_MODULE_MINOR_VERSION, PUBLIC_MODULE_HEADER)
diff --git a/iocore/hostdb/I_HostDBProcessor.h b/iocore/hostdb/I_HostDBProcessor.h
index 565efe1..d0a2a06 100644
--- a/iocore/hostdb/I_HostDBProcessor.h
+++ b/iocore/hostdb/I_HostDBProcessor.h
@@ -26,7 +26,7 @@
 
 #include "ts/HashFNV.h"
 #include "ts/ink_time.h"
-#include "ts/INK_MD5.h"
+#include "ts/CryptoHash.h"
 #include "ts/ink_align.h"
 #include "ts/ink_resolver.h"
 #include "I_EventSystem.h"
diff --git a/iocore/hostdb/P_HostDB.h b/iocore/hostdb/P_HostDB.h
index 2ca0925..29c1a2e 100644
--- a/iocore/hostdb/P_HostDB.h
+++ b/iocore/hostdb/P_HostDB.h
@@ -48,7 +48,7 @@
 
 #undef HOSTDB_MODULE_VERSION
 #define HOSTDB_MODULE_VERSION makeModuleVersion(HOSTDB_MODULE_MAJOR_VERSION, HOSTDB_MODULE_MINOR_VERSION, PRIVATE_MODULE_HEADER)
-Ptr<HostDBInfo> probe(ProxyMutex *mutex, HostDBMD5 const &md5, bool ignore_timeout);
+Ptr<HostDBInfo> probe(ProxyMutex *mutex, CryptoHash const &hash, bool ignore_timeout);
 
-void make_md5(INK_MD5 &md5, const char *hostname, int len, int port, const char *pDNSServers, HostDBMark mark);
+void make_crypto_hash(CryptoHash &hash, const char *hostname, int len, int port, const char *pDNSServers, HostDBMark mark);
 #endif
diff --git a/iocore/hostdb/P_HostDBProcessor.h b/iocore/hostdb/P_HostDBProcessor.h
index d4d6b46..737287e 100644
--- a/iocore/hostdb/P_HostDBProcessor.h
+++ b/iocore/hostdb/P_HostDBProcessor.h
@@ -199,10 +199,10 @@ struct HostDBCache {
 
   // TODO configurable number of items in the cache
   Queue<HostDBContinuation, Continuation::Link_link> *pending_dns;
-  Queue<HostDBContinuation, Continuation::Link_link> &pending_dns_for_hash(const INK_MD5 &md5);
+  Queue<HostDBContinuation, Continuation::Link_link> &pending_dns_for_hash(const CryptoHash &hash);
   Queue<HostDBContinuation, Continuation::Link_link> *remoteHostDBQueue;
   HostDBCache();
-  bool is_pending_dns_for_hash(const INK_MD5 &md5);
+  bool is_pending_dns_for_hash(const CryptoHash &hash);
 };
 
 inline int
@@ -392,30 +392,30 @@ HostDBRoundRobin::select_best_srv(char *target, InkRand *rand, ink_time_t now, i
 // Types
 //
 
-/** Container for an MD5 hash and its dependent data.
+/** Container for a hash and its dependent data.
     This handles both the host name and raw address cases.
 */
-struct HostDBMD5 {
-  typedef HostDBMD5 self; ///< Self reference type.
+struct HostDBHash {
+  typedef HostDBHash self; ///< Self reference type.
 
-  INK_MD5 hash; ///< The hash value.
+  CryptoHash hash; ///< The hash value.
 
   const char *host_name; ///< Host name.
   int host_len;          ///< Length of @a _host_name
   IpAddr ip;             ///< IP address.
   in_port_t port;        ///< IP port (host order).
-  /// DNS server. Not strictly part of the MD5 data but
+  /// DNS server. Not strictly part of the hash data but
   /// it's both used by @c HostDBContinuation and provides access to
-  /// MD5 data. It's just handier to store it here for both uses.
+  /// hash data. It's just handier to store it here for both uses.
   DNSServer *dns_server;
   SplitDNS *pSD;      ///< Hold the container for @a dns_server.
   HostDBMark db_mark; ///< Mark / type of record.
 
   /// Default constructor.
-  HostDBMD5();
+  HostDBHash();
   /// Destructor.
-  ~HostDBMD5();
-  /// Recompute and update the MD5 hash.
+  ~HostDBHash();
+  /// Recompute and update the hash.
   void refresh();
   /** Assign a hostname.
       This updates the split DNS data as well.
@@ -431,24 +431,23 @@ typedef int (HostDBContinuation::*HostDBContHandler)(int, void *);
 
 struct HostDBContinuation : public Continuation {
   Action action;
-  HostDBMD5 md5;
+  HostDBHash hash;
   //  IpEndpoint ip;
   unsigned int ttl = 0;
   //  HostDBMark db_mark; ///< Target type.
   /// Original IP address family style. Note this will disagree with
-  /// @a md5.db_mark when doing a retry on an alternate family. The retry
+  /// @a hash.db_mark when doing a retry on an alternate family. The retry
   /// logic depends on it to avoid looping.
   HostResStyle host_res_style = DEFAULT_OPTIONS.host_res_style; ///< Address family priority.
   int dns_lookup_timeout      = DEFAULT_OPTIONS.timeout;
-  //  INK_MD5 md5;
-  Event *timeout          = nullptr;
-  Continuation *from_cont = nullptr;
+  Event *timeout              = nullptr;
+  Continuation *from_cont     = nullptr;
   HostDBApplicationInfo app;
   int probe_depth            = 0;
   size_t current_iterate_pos = 0;
   //  char name[MAXDNAME];
   //  int namelen;
-  char md5_host_name_store[MAXDNAME + 1]; // used as backing store for @a md5
+  char hash_host_name_store[MAXDNAME + 1]; // used as backing store for @a hash
   char srv_target_name[MAXDNAME];
   //  void *m_pDS;
   Action *pending_action = nullptr;
@@ -466,18 +465,18 @@ struct HostDBContinuation : public Continuation {
   int removeEvent(int event, Event *e);
   int setbyEvent(int event, Event *e);
 
-  /// Recompute the MD5 and update ancillary values.
-  void refresh_MD5();
+  /// Recompute the hash and update ancillary values.
+  void refresh_hash();
   void do_dns();
   bool
   is_byname()
   {
-    return md5.db_mark == HOSTDB_MARK_IPV4 || md5.db_mark == HOSTDB_MARK_IPV6;
+    return hash.db_mark == HOSTDB_MARK_IPV4 || hash.db_mark == HOSTDB_MARK_IPV6;
   }
   bool
   is_srv()
   {
-    return md5.db_mark == HOSTDB_MARK_SRV;
+    return hash.db_mark == HOSTDB_MARK_SRV;
   }
   HostDBInfo *lookup_done(IpAddr const &ip, const char *aname, bool round_robin, unsigned int attl, SRVHosts *s = nullptr,
                           HostDBInfo *r = nullptr);
@@ -500,22 +499,22 @@ struct HostDBContinuation : public Continuation {
     Options() : timeout(0), host_res_style(HOST_RES_NONE), force_dns(false), cont(0) {}
   };
   static const Options DEFAULT_OPTIONS; ///< Default defaults.
-  void init(HostDBMD5 const &md5, Options const &opt = DEFAULT_OPTIONS);
+  void init(HostDBHash const &hash, Options const &opt = DEFAULT_OPTIONS);
   int make_get_message(char *buf, int len);
   int make_put_message(HostDBInfo *r, Continuation *c, char *buf, int len);
 
   HostDBContinuation() : missing(false), force_dns(DEFAULT_OPTIONS.force_dns), round_robin(false)
   {
-    ink_zero(md5_host_name_store);
-    ink_zero(md5.hash);
+    ink_zero(hash_host_name_store);
+    ink_zero(hash.hash);
     SET_HANDLER((HostDBContHandler)&HostDBContinuation::probeEvent);
   }
 };
 
 inline unsigned int
-master_hash(INK_MD5 const &md5)
+master_hash(CryptoHash const &hash)
 {
-  return static_cast<int>(md5[1] >> 32);
+  return static_cast<int>(hash[1] >> 32);
 }
 
 inline bool
@@ -525,15 +524,15 @@ is_dotted_form_hostname(const char *c)
 }
 
 inline Queue<HostDBContinuation> &
-HostDBCache::pending_dns_for_hash(const INK_MD5 &md5)
+HostDBCache::pending_dns_for_hash(const CryptoHash &hash)
 {
-  return pending_dns[this->refcountcache->partition_for_key(md5.fold())];
+  return pending_dns[this->refcountcache->partition_for_key(hash.fold())];
 }
 
 inline int
 HostDBContinuation::key_partition()
 {
-  return hostDB.refcountcache->partition_for_key(md5.hash.fold());
+  return hostDB.refcountcache->partition_for_key(hash.hash.fold());
 }
 
 #endif /* _P_HostDBProcessor_h_ */
diff --git a/lib/ts/ink_code.cc b/lib/ts/CryptoHash.cc
similarity index 52%
copy from lib/ts/ink_code.cc
copy to lib/ts/CryptoHash.cc
index fba8147..4e5792c 100644
--- a/lib/ts/ink_code.cc
+++ b/lib/ts/CryptoHash.cc
@@ -1,6 +1,6 @@
 /** @file
 
-  A brief file description
+  Generic wrapper for cryptographic hashes.
 
   @section license License
 
@@ -21,79 +21,50 @@
   limitations under the License.
  */
 
+#include <cstdlib>
 #include <cstring>
-#include <cstdio>
-#include "ts/ink_code.h"
-#include "ts/INK_MD5.h"
+#include <new>
 #include "ts/ink_assert.h"
+#include "ts/ink_platform.h"
+#include "ts/ink_code.h"
+#include "ts/CryptoHash.h"
+#include "ts/SHA256.h"
 
-ats::CryptoHash const ats::CRYPTO_HASH_ZERO; // default constructed is correct.
-
-MD5Context::MD5Context()
-{
-  MD5_Init(&_ctx);
-}
-
-bool
-MD5Context::update(void const *data, int length)
-{
-  return 0 != MD5_Update(&_ctx, data, length);
-}
-
-bool
-MD5Context::finalize(CryptoHash &hash)
-{
-  return 0 != MD5_Final(hash.u8, &_ctx);
-}
-
-/**
-  @brief Wrapper around MD5_Init
-*/
-int
-ink_code_incr_md5_init(INK_DIGEST_CTX *context)
-{
-  return MD5_Init(context);
-}
-
-/**
-  @brief Wrapper around MD5_Update
-*/
-int
-ink_code_incr_md5_update(INK_DIGEST_CTX *context, const char *input, int input_length)
-{
-  return MD5_Update(context, input, input_length);
-}
-
-/**
-  @brief Wrapper around MD5_Final
-*/
-int
-ink_code_incr_md5_final(char *sixteen_byte_hash_pointer, INK_DIGEST_CTX *context)
-{
-  return MD5_Final((unsigned char *)sixteen_byte_hash_pointer, context);
-}
-
-/**
-  @brief Helper that will init, update, and create a final MD5
+#ifndef TS_ENABLE_FIPS
+CryptoContext::HashType CryptoContext::Setting = CryptoContext::MD5;
+#else
+CryptoContext::HashType CryptoContext::Setting = CryptoContext::SHA256;
+#endif
 
-  @return always returns 0, maybe some error checking should be done
-*/
-int
-ink_code_md5(unsigned const char *input, int input_length, unsigned char *sixteen_byte_hash_pointer)
+CryptoContext::CryptoContext()
 {
-  MD5_CTX context;
-
-  MD5_Init(&context);
-  MD5_Update(&context, input, input_length);
-  MD5_Final(sixteen_byte_hash_pointer, &context);
-
-  return (0);
+  switch (Setting) {
+  case UNSPECIFIED:
+#ifndef TS_ENABLE_FIPS
+  case MD5:
+    new (_obj) MD5Context;
+    break;
+  case MMH:
+    new (_obj) MMHContext;
+    break;
+#endif
+  case SHA256:
+    new (_obj) SHA256Context;
+    break;
+  default:
+    ink_release_assert("Invalid global URL hash context");
+  };
+#ifndef TS_ENABLE_FIPS
+  static_assert(CryptoContext::OBJ_SIZE >= sizeof(MD5Context), "bad OBJ_SIZE");
+  static_assert(CryptoContext::OBJ_SIZE >= sizeof(MMHContext), "bad OBJ_SIZE");
+#endif
+  static_assert(CryptoContext::OBJ_SIZE >= sizeof(SHA256Context), "bad OBJ_SIZE");
 }
 
 /**
-  @brief Converts a MD5 to a null-terminated string
+  @brief Converts a hash to a null-terminated string
 
-  Externalizes an INK_MD5 as a null-terminated string into the first argument.
+  Externalizes an hash as a null-terminated string into the first argument.
   Does so without intenal procedure calls.
   Side Effects: none.
   Reentrancy:     n/a.
@@ -103,16 +74,16 @@ ink_code_md5(unsigned const char *input, int input_length, unsigned char *sixtee
   @return returns the passed destination string ptr.
 */
 /* reentrant version */
-char *
-ink_code_to_hex_str(char *dest33, uint8_t const *hash)
+static char *
+ink_code_to_hex_str(char *dest, uint8_t const *hash)
 {
   int i;
   char *d;
 
   static char hex_digits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
 
-  d = dest33;
-  for (i = 0; i < 16; i += 4) {
+  d = dest;
+  for (i = 0; i < CRYPTO_HASH_SIZE; i += 4) {
     *(d + 0) = hex_digits[hash[i + 0] >> 4];
     *(d + 1) = hex_digits[hash[i + 0] & 15];
     *(d + 2) = hex_digits[hash[i + 1] >> 4];
@@ -124,5 +95,11 @@ ink_code_to_hex_str(char *dest33, uint8_t const *hash)
     d += 8;
   }
   *d = '\0';
-  return (dest33);
+  return (dest);
+}
+
+char *
+CryptoHash::toHexStr(char buffer[(CRYPTO_HASH_SIZE * 2) + 1])
+{
+  return ink_code_to_hex_str(buffer, u8);
 }
diff --git a/lib/ts/CryptoHash.h b/lib/ts/CryptoHash.h
index aae1a3d..7d4cea7 100644
--- a/lib/ts/CryptoHash.h
+++ b/lib/ts/CryptoHash.h
@@ -1,5 +1,5 @@
 /** @file
-    Protocol class for crypto hashes.
+    Wrapper class for crypto hashes.
 
     @section license License
 
@@ -25,30 +25,32 @@
 
 /// Apache Traffic Server commons.
 
-#include "ts/ink_code.h"
+#ifdef TS_ENABLE_FIPS
+// #include "ts/SHA256.h"
+#define CRYPTO_HASH_SIZE (256 / 8)
+#else
+// #include "ts/ink_code.h"
+#define CRYPTO_HASH_SIZE (128 / 8)
+#endif
+#define CRYPTO_HEX_SIZE ((CRYPTO_HASH_SIZE * 2) + 1)
 
 namespace ats
 {
 /// Crypto hash output.
 union CryptoHash {
-  uint64_t b[2]; // Legacy placeholder
-  uint64_t u64[2];
-  uint32_t u32[4];
-  uint8_t u8[16];
+  uint64_t b[CRYPTO_HASH_SIZE / sizeof(uint64_t)]; // Legacy placeholder
+  uint64_t u64[CRYPTO_HASH_SIZE / sizeof(uint64_t)];
+  uint32_t u32[CRYPTO_HASH_SIZE / sizeof(uint32_t)];
+  uint8_t u8[CRYPTO_HASH_SIZE / sizeof(uint8_t)];
 
   /// Default constructor - init to zero.
-  CryptoHash()
-  {
-    u64[0] = 0;
-    u64[1] = 0;
-  }
+  CryptoHash() { memset(this, 0, sizeof(*this)); }
 
   /// Assignment - bitwise copy.
   CryptoHash &
   operator=(CryptoHash const &that)
   {
-    u64[0] = that.u64[0];
-    u64[1] = that.u64[1];
+    memcpy(this, &that, sizeof(*this));
     return *this;
   }
 
@@ -56,7 +58,7 @@ union CryptoHash {
   bool
   operator==(CryptoHash const &that) const
   {
-    return u64[0] == that.u64[0] && u64[1] == that.u64[1];
+    return memcmp(this, &that, sizeof(*this)) == 0;
   }
 
   /// Equality - bitwise identical.
@@ -70,7 +72,11 @@ union CryptoHash {
   uint64_t
   fold() const
   {
+#if CRYPTO_HASH_SIZE == 16
     return u64[0] ^ u64[1];
+#elif CRYPTO_HASH_SIZE == 32
+    return u64[0] ^ u64[1] ^ u64[2] ^ u64[3];
+#endif
   }
 
   /// Access 64 bit slice.
@@ -91,11 +97,7 @@ union CryptoHash {
   }
 
   /// Fast conversion to hex in fixed sized string.
-  char *
-  toHexStr(char buffer[33])
-  {
-    return ink_code_to_hex_str(buffer, u8);
-  }
+  char *toHexStr(char buffer[(CRYPTO_HASH_SIZE * 2) + 1]);
 };
 
 extern CryptoHash const CRYPTO_HASH_ZERO;
@@ -104,12 +106,12 @@ extern CryptoHash const CRYPTO_HASH_ZERO;
 
     A hash of this type is used for strong hashing, such as for URLs.
 */
-class CryptoContext
+class CryptoContextBase
 {
-  typedef CryptoContext self; ///< Self reference type.
+  typedef CryptoContextBase self; ///< Self reference type.
 public:
   /// Destructor (force virtual)
-  virtual ~CryptoContext() {}
+  virtual ~CryptoContextBase() {}
   /// Update the hash with @a data of @a length bytes.
   virtual bool update(void const *data, int length) = 0;
   /// Finalize and extract the @a hash.
@@ -121,23 +123,61 @@ public:
   /// Convenience - compute final @a hash for @a data.
   /// @note This is just as fast as the previous style, as a new context must be initialized
   /// everytime this is done.
-  virtual bool hash_immediate(CryptoHash &hash, void const *data, int length);
+  bool hash_immediate(CryptoHash &hash, void const *data, int length);
 };
 
 inline bool
-CryptoContext::hash_immediate(CryptoHash &hash, void const *data, int length)
+CryptoContextBase::hash_immediate(CryptoHash &hash, void const *data, int length)
 {
   return this->update(data, length) && this->finalize(hash);
 }
+
 inline bool
-CryptoContext::finalize(CryptoHash *hash)
+CryptoContextBase::finalize(CryptoHash *hash)
 {
   return this->finalize(*hash);
 }
 
+class CryptoContext : public CryptoContextBase
+{
+public:
+  CryptoContext();
+  /// Update the hash with @a data of @a length bytes.
+  virtual bool update(void const *data, int length);
+  /// Finalize and extract the @a hash.
+  virtual bool finalize(CryptoHash &hash);
+
+  enum HashType {
+    UNSPECIFIED,
+#ifndef TS_ENABLE_FIPS
+    MD5,
+    MMH,
+#endif
+    SHA256,
+  }; ///< What type of hash we really are.
+  static HashType Setting;
+
+  /// Size of storage for placement @c new of hashing context.
+  static size_t const OBJ_SIZE = 256;
+
+protected:
+  char _obj[OBJ_SIZE]; ///< Raw storage for instantiated context.
+};
+
+inline bool
+CryptoContext::update(void const *data, int length)
+{
+  return reinterpret_cast<CryptoContextBase *>(_obj)->update(data, length);
+}
+
+inline bool
+CryptoContext::finalize(CryptoHash &hash)
+{
+  return reinterpret_cast<CryptoContextBase *>(_obj)->finalize(hash);
+}
+
 } // end namespace
 
-// Promote for the primitives who don't use namespaces...
 using ats::CryptoHash;
 using ats::CryptoContext;
 using ats::CRYPTO_HASH_ZERO;
diff --git a/lib/ts/INK_MD5.h b/lib/ts/INK_MD5.h
index 0ba8e81..1fee6bf 100644
--- a/lib/ts/INK_MD5.h
+++ b/lib/ts/INK_MD5.h
@@ -28,7 +28,9 @@
 #include "ts/ink_defs.h"
 #include "ts/CryptoHash.h"
 
-class MD5Context : public CryptoContext
+#ifndef TS_ENABLE_FIPS
+
+class MD5Context : public ats::CryptoContextBase
 {
 protected:
   MD5_CTX _ctx;
@@ -42,5 +44,6 @@ public:
 };
 
 typedef CryptoHash INK_MD5;
+#endif
 
 #endif
diff --git a/lib/ts/MMH.h b/lib/ts/MMH.h
index 5aa6334..68e2e5a 100644
--- a/lib/ts/MMH.h
+++ b/lib/ts/MMH.h
@@ -49,7 +49,7 @@ int inkcoreapi ink_code_MMH(unsigned char *input, int len, unsigned char *sixtee
   cost.
 
 */
-class MMHContext : public CryptoContext
+class MMHContext : public ats::CryptoContextBase
 {
 protected:
   MMH_CTX _ctx;
diff --git a/lib/ts/Makefile.am b/lib/ts/Makefile.am
index c35d703..6ef15e6 100644
--- a/lib/ts/Makefile.am
+++ b/lib/ts/Makefile.am
@@ -56,6 +56,8 @@ libtsutil_la_SOURCES = \
   ConsistentHash.h \
   ContFlags.cc \
   ContFlags.h \
+  CryptoHash.cc \
+  CryptoHash.h \
   defalloc.h \
   Diags.cc \
   Diags.h \
diff --git a/lib/ts/INK_MD5.h b/lib/ts/SHA256.h
similarity index 73%
copy from lib/ts/INK_MD5.h
copy to lib/ts/SHA256.h
index 0ba8e81..eff7e1d 100644
--- a/lib/ts/INK_MD5.h
+++ b/lib/ts/SHA256.h
@@ -1,6 +1,6 @@
 /** @file
 
-  MD5 support class.
+  SHA256 support class.
 
   @section license License
 
@@ -27,20 +27,30 @@
 #include "ts/ink_code.h"
 #include "ts/ink_defs.h"
 #include "ts/CryptoHash.h"
+#include <openssl/sha.h>
 
-class MD5Context : public CryptoContext
+#ifdef TS_ENABLE_FIPS
+
+class SHA256Context : public ats::CryptoContextBase
 {
 protected:
-  MD5_CTX _ctx;
+  SHA256_CTX _ctx;
 
 public:
-  MD5Context();
+  SHA256Context() { SHA256_Init(&_ctx); }
   /// Update the hash with @a data of @a length bytes.
-  virtual bool update(void const *data, int length);
+  virtual bool
+  update(void const *data, int length)
+  {
+    return SHA256_Update(&_ctx, data, length);
+  }
   /// Finalize and extract the @a hash.
-  virtual bool finalize(CryptoHash &hash);
+  virtual bool
+  finalize(CryptoHash &hash)
+  {
+    return SHA256_Final(hash.u8, &_ctx);
+  }
 };
 
-typedef CryptoHash INK_MD5;
-
+#endif
 #endif
diff --git a/lib/ts/ink_code.cc b/lib/ts/ink_code.cc
index fba8147..60270d0 100644
--- a/lib/ts/ink_code.cc
+++ b/lib/ts/ink_code.cc
@@ -28,6 +28,7 @@
 #include "ts/ink_assert.h"
 
 ats::CryptoHash const ats::CRYPTO_HASH_ZERO; // default constructed is correct.
+#ifndef TS_ENABLE_FIPS
 
 MD5Context::MD5Context()
 {
@@ -89,40 +90,4 @@ ink_code_md5(unsigned const char *input, int input_length, unsigned char *sixtee
 
   return (0);
 }
-
-/**
-  @brief Converts a MD5 to a null-terminated string
-
-  Externalizes an INK_MD5 as a null-terminated string into the first argument.
-  Does so without intenal procedure calls.
-  Side Effects: none.
-  Reentrancy:     n/a.
-  Thread Safety:  safe.
-  Mem Management: stomps the passed dest char*.
-
-  @return returns the passed destination string ptr.
-*/
-/* reentrant version */
-char *
-ink_code_to_hex_str(char *dest33, uint8_t const *hash)
-{
-  int i;
-  char *d;
-
-  static char hex_digits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
-
-  d = dest33;
-  for (i = 0; i < 16; i += 4) {
-    *(d + 0) = hex_digits[hash[i + 0] >> 4];
-    *(d + 1) = hex_digits[hash[i + 0] & 15];
-    *(d + 2) = hex_digits[hash[i + 1] >> 4];
-    *(d + 3) = hex_digits[hash[i + 1] & 15];
-    *(d + 4) = hex_digits[hash[i + 2] >> 4];
-    *(d + 5) = hex_digits[hash[i + 2] & 15];
-    *(d + 6) = hex_digits[hash[i + 3] >> 4];
-    *(d + 7) = hex_digits[hash[i + 3] & 15];
-    d += 8;
-  }
-  *d = '\0';
-  return (dest33);
-}
+#endif
diff --git a/lib/ts/ink_code.h b/lib/ts/ink_code.h
index 739b2c8..996ed3c 100644
--- a/lib/ts/ink_code.h
+++ b/lib/ts/ink_code.h
@@ -26,6 +26,7 @@
 
 #include "ts/ink_apidefs.h"
 #include "ts/ink_defs.h"
+#ifndef TS_ENABLE_FIPS
 #include <openssl/md5.h>
 
 /* INK_MD5 context. */
@@ -36,9 +37,8 @@ typedef MD5_CTX INK_DIGEST_CTX;
 */
 
 inkcoreapi int ink_code_md5(unsigned const char *input, int input_length, unsigned char *sixteen_byte_hash_pointer);
-inkcoreapi char *ink_code_to_hex_str(char *dest33, uint8_t const *md5);
-
 inkcoreapi int ink_code_incr_md5_init(INK_DIGEST_CTX *context);
 inkcoreapi int ink_code_incr_md5_update(INK_DIGEST_CTX *context, const char *input, int input_length);
 inkcoreapi int ink_code_incr_md5_final(char *sixteen_byte_hash_pointer, INK_DIGEST_CTX *context);
 #endif
+#endif
diff --git a/lib/ts/ink_config.h.in b/lib/ts/ink_config.h.in
index 79b2c00..0d104de 100644
--- a/lib/ts/ink_config.h.in
+++ b/lib/ts/ink_config.h.in
@@ -59,6 +59,7 @@
 #define TS_HAS_BACKTRACE @has_backtrace@
 #define TS_HAS_PROFILER @has_profiler@
 #define TS_USE_FAST_SDK @use_fast_sdk@
+#define TS_ENABLE_FIPS @enable_fips@
 #define TS_USE_DIAGS @use_diags@
 #define TS_USE_EPOLL @use_epoll@
 #define TS_USE_KQUEUE @use_kqueue@
diff --git a/lib/ts/ink_inet.cc b/lib/ts/ink_inet.cc
index 8a96985..5c2624c 100644
--- a/lib/ts/ink_inet.cc
+++ b/lib/ts/ink_inet.cc
@@ -25,7 +25,7 @@
 #include "ts/ink_defs.h"
 #include "ts/ink_inet.h"
 #include "ts/ParseRules.h"
-#include "ts/ink_code.h"
+#include "ts/CryptoHash.h"
 #include "ts/ink_assert.h"
 #include <fstream>
 #include <ts/TextView.h>
@@ -265,38 +265,35 @@ ats_ip_pton(const ts::string_view &src, sockaddr *ip)
 uint32_t
 ats_ip_hash(sockaddr const *addr)
 {
-  union md5sum {
-    unsigned char c[16];
-    uint32_t i;
-  } zret;
-  zret.i = 0;
-
   if (ats_is_ip4(addr)) {
-    zret.i = ats_ip4_addr_cast(addr);
+    return ats_ip4_addr_cast(addr);
   } else if (ats_is_ip6(addr)) {
-    ink_code_md5(const_cast<uint8_t *>(ats_ip_addr8_cast(addr)), TS_IP6_SIZE, zret.c);
+    CryptoHash hash;
+    CryptoContext().hash_immediate(hash, const_cast<uint8_t *>(ats_ip_addr8_cast(addr)), TS_IP6_SIZE);
+    return hash.u32[0];
+  } else {
+    // Bad address type.
+    return 0;
   }
-  return zret.i;
 }
 
 uint64_t
 ats_ip_port_hash(sockaddr const *addr)
 {
-  union md5sum {
-    uint64_t i;
-    uint16_t b[4];
-    unsigned char c[16];
-  } zret;
-
-  zret.i = 0;
   if (ats_is_ip4(addr)) {
-    zret.i = (static_cast<uint64_t>(ats_ip4_addr_cast(addr)) << 16) | (ats_ip_port_cast(addr));
+    return (static_cast<uint64_t>(ats_ip4_addr_cast(addr)) << 16) | (ats_ip_port_cast(addr));
   } else if (ats_is_ip6(addr)) {
-    ink_code_md5(const_cast<uint8_t *>(ats_ip_addr8_cast(addr)), TS_IP6_SIZE, zret.c);
-    // now replace the bottom 16bits so we can account for the port.
-    zret.b[3] = ats_ip_port_cast(addr);
+    CryptoHash hash;
+    CryptoContext hash_context;
+    hash_context.update(const_cast<uint8_t *>(ats_ip_addr8_cast(addr)), TS_IP6_SIZE);
+    in_port_t port = ats_ip_port_cast(addr);
+    hash_context.update((uint8_t *)(&port), sizeof(port));
+    hash_context.finalize(hash);
+    return hash.u64[0];
+  } else {
+    // Bad address type.
+    return 0;
   }
-  return zret.i;
 }
 
 int
diff --git a/plugins/experimental/memcache/tsmemcache.cc b/plugins/experimental/memcache/tsmemcache.cc
index 40f9517..a3cdebc 100644
--- a/plugins/experimental/memcache/tsmemcache.cc
+++ b/plugins/experimental/memcache/tsmemcache.cc
@@ -471,7 +471,7 @@ int
 MC::get_item()
 {
   TS_PUSH_HANDLER(&MC::cache_read_event);
-  MD5Context().hash_immediate(cache_key, (void *)key, (int)header.nkey);
+  CryptoContext().hash_immediate(cache_key, (void *)key, (int)header.nkey);
   pending_action = cacheProcessor.open_read(this, &cache_key);
   return EVENT_CONT;
 }
@@ -479,7 +479,7 @@ MC::get_item()
 int
 MC::set_item()
 {
-  MD5Context().hash_immediate(cache_key, (void *)key, (int)header.nkey);
+  CryptoContext().hash_immediate(cache_key, (void *)key, (int)header.nkey);
   pending_action = cacheProcessor.open_write(this, &cache_key, CACHE_FRAG_TYPE_NONE, header.nbytes,
                                              CACHE_WRITE_OPT_OVERWRITE | TSMEMCACHE_WRITE_SYNC);
   return EVENT_CONT;
@@ -488,7 +488,7 @@ MC::set_item()
 int
 MC::delete_item()
 {
-  MD5Context().hash_immediate(cache_key, (void *)key, (int)header.nkey);
+  CryptoContext().hash_immediate(cache_key, (void *)key, (int)header.nkey);
   pending_action = cacheProcessor.remove(this, &cache_key, CACHE_FRAG_TYPE_NONE);
   return EVENT_CONT;
 }
diff --git a/plugins/experimental/memcache/tsmemcache.h b/plugins/experimental/memcache/tsmemcache.h
index af17e36..aab5c32 100644
--- a/plugins/experimental/memcache/tsmemcache.h
+++ b/plugins/experimental/memcache/tsmemcache.h
@@ -33,7 +33,7 @@
 #include "protocol_binary.h"
 #include "ink_memory.h"
 #include "ink_hrtime.h"
-#include "INK_MD5.h"
+#include "CryptoHash.h"
 
 #define TSMEMCACHE_VERSION "1.0.0"
 #define TSMEMCACHE_MAX_CMD_SIZE (128 * 1024 * 1024) // silly large
diff --git a/proxy/InkAPI.cc b/proxy/InkAPI.cc
index 139b31d..e28d76f 100644
--- a/proxy/InkAPI.cc
+++ b/proxy/InkAPI.cc
@@ -4064,7 +4064,7 @@ TSCacheKeyDigestSet(TSCacheKey key, const char *input, int length)
     return TS_ERROR;
   }
 
-  MD5Context().hash_immediate(ci->cache_key, input, length);
+  CryptoContext().hash_immediate(ci->cache_key, input, length);
   return TS_SUCCESS;
 }
 
@@ -4077,7 +4077,7 @@ TSCacheKeyDigestFromUrlSet(TSCacheKey key, TSMLoc url)
     return TS_ERROR;
   }
 
-  url_MD5_get((URLImpl *)url, &((CacheInfo *)key)->cache_key);
+  url_CryptoHash_get((URLImpl *)url, &((CacheInfo *)key)->cache_key);
   return TS_SUCCESS;
 }
 
@@ -5122,7 +5122,7 @@ TSHttpTxnNewCacheLookupDo(TSHttpTxn txnp, TSMBuffer bufp, TSMLoc url_loc)
   sdk_assert(sdk_sanity_check_url_handle(url_loc) == TS_SUCCESS);
 
   URL new_url, *client_url, *l_url, *o_url;
-  INK_MD5 md51, md52;
+  CryptoHash crypto_hash1, crypto_hash2;
 
   new_url.m_heap     = ((HdrHeapSDKHandle *)bufp)->m_heap;
   new_url.m_url_impl = (URLImpl *)url_loc;
@@ -5146,9 +5146,9 @@ TSHttpTxnNewCacheLookupDo(TSHttpTxn txnp, TSMBuffer bufp, TSMLoc url_loc)
     s->cache_info.lookup_url = &(s->cache_info.lookup_url_storage);
     l_url                    = s->cache_info.lookup_url;
   } else {
-    l_url->hash_get(&md51);
-    new_url.hash_get(&md52);
-    if (md51 == md52) {
+    l_url->hash_get(&crypto_hash1);
+    new_url.hash_get(&crypto_hash2);
+    if (crypto_hash1 == crypto_hash2) {
       return TS_ERROR;
     }
     o_url = &(s->cache_info.original_url);
@@ -7465,7 +7465,7 @@ TSCacheHttpInfoKeySet(TSCacheHttpInfo infop, TSCacheKey keyp)
 {
   // TODO: Check input ?
   CacheHTTPInfo *info = (CacheHTTPInfo *)infop;
-  INK_MD5 *key        = (INK_MD5 *)keyp;
+  CryptoHash *key     = (CryptoHash *)keyp;
 
   info->object_key_set(*key);
 }
diff --git a/proxy/InkAPIInternal.h b/proxy/InkAPIInternal.h
index 2f2b222..9d5544c 100644
--- a/proxy/InkAPIInternal.h
+++ b/proxy/InkAPIInternal.h
@@ -53,7 +53,7 @@ enum CacheInfoMagic {
 };
 
 struct CacheInfo {
-  INK_MD5 cache_key;
+  CryptoHash cache_key;
   CacheFragType frag_type;
   char *hostname;
   int len;
diff --git a/proxy/Main.cc b/proxy/Main.cc
index 0f2a6e2..5117954 100644
--- a/proxy/Main.cc
+++ b/proxy/Main.cc
@@ -687,6 +687,7 @@ CB_After_Cache_Init()
 
   start = ink_atomic_swap(&delay_listen_for_cache_p, -1);
 
+#ifndef TS_ENABLE_FIPS
   // Check for cache BC after the cache is initialized and before listen, if possible.
   if (cacheProcessor.min_stripe_version.ink_major < CACHE_DB_MAJOR_VERSION) {
     // Versions before 23 need the MMH hash.
@@ -696,6 +697,7 @@ CB_After_Cache_Init()
       URLHashContext::Setting = URLHashContext::MMH;
     }
   }
+#endif
 
   if (1 == start) {
     Debug("http_listen", "Delayed listen enable, cache initialization finished");
diff --git a/proxy/hdrs/HTTP.h b/proxy/hdrs/HTTP.h
index 62f01b3..bc18c02 100644
--- a/proxy/hdrs/HTTP.h
+++ b/proxy/hdrs/HTTP.h
@@ -26,7 +26,7 @@
 
 #include <assert.h>
 #include "ts/Arena.h"
-#include "ts/INK_MD5.h"
+#include "ts/CryptoHash.h"
 #include "MIME.h"
 #include "URL.h"
 
@@ -1318,7 +1318,7 @@ struct HTTPCacheAlt {
   int32_t m_id;
   int32_t m_rid;
 
-  int32_t m_object_key[4];
+  int32_t m_object_key[sizeof(CryptoHash) / sizeof(int32_t)];
   int32_t m_object_size[2];
 
   HTTPHdr m_request_hdr;
@@ -1413,9 +1413,9 @@ public:
     m_alt->m_rid = id;
   }
 
-  INK_MD5 object_key_get();
-  void object_key_get(INK_MD5 *);
-  bool compare_object_key(const INK_MD5 *);
+  CryptoHash object_key_get();
+  void object_key_get(CryptoHash *);
+  bool compare_object_key(const CryptoHash *);
   int64_t object_size_get();
 
   void
@@ -1457,7 +1457,7 @@ public:
     return m_alt->m_response_received_time;
   }
 
-  void object_key_set(INK_MD5 &md5);
+  void object_key_set(CryptoHash &hash);
   void object_size_set(int64_t size);
 
   void
@@ -1520,36 +1520,29 @@ HTTPInfo::operator=(const HTTPInfo &m)
   return *this;
 }
 
-inline INK_MD5
+inline CryptoHash
 HTTPInfo::object_key_get()
 {
-  INK_MD5 val;
+  CryptoHash val;
   int32_t *pi = reinterpret_cast<int32_t *>(&val);
 
-  pi[0] = m_alt->m_object_key[0];
-  pi[1] = m_alt->m_object_key[1];
-  pi[2] = m_alt->m_object_key[2];
-  pi[3] = m_alt->m_object_key[3];
+  memcpy(pi, m_alt->m_object_key, sizeof(CryptoHash));
 
   return val;
 }
 
 inline void
-HTTPInfo::object_key_get(INK_MD5 *md5)
+HTTPInfo::object_key_get(CryptoHash *hash)
 {
-  int32_t *pi = reinterpret_cast<int32_t *>(md5);
-  pi[0]       = m_alt->m_object_key[0];
-  pi[1]       = m_alt->m_object_key[1];
-  pi[2]       = m_alt->m_object_key[2];
-  pi[3]       = m_alt->m_object_key[3];
+  int32_t *pi = reinterpret_cast<int32_t *>(hash);
+  memcpy(pi, m_alt->m_object_key, CRYPTO_HASH_SIZE);
 }
 
 inline bool
-HTTPInfo::compare_object_key(const INK_MD5 *md5)
+HTTPInfo::compare_object_key(const CryptoHash *hash)
 {
-  int32_t const *pi = reinterpret_cast<int32_t const *>(md5);
-  return ((m_alt->m_object_key[0] == pi[0]) && (m_alt->m_object_key[1] == pi[1]) && (m_alt->m_object_key[2] == pi[2]) &&
-          (m_alt->m_object_key[3] == pi[3]));
+  int32_t const *pi = reinterpret_cast<int32_t const *>(hash);
+  return memcmp(pi, m_alt->m_object_key, CRYPTO_HASH_SIZE) == 0;
 }
 
 inline int64_t
@@ -1564,13 +1557,10 @@ HTTPInfo::object_size_get()
 }
 
 inline void
-HTTPInfo::object_key_set(INK_MD5 &md5)
+HTTPInfo::object_key_set(CryptoHash &hash)
 {
-  int32_t *pi            = reinterpret_cast<int32_t *>(&md5);
-  m_alt->m_object_key[0] = pi[0];
-  m_alt->m_object_key[1] = pi[1];
-  m_alt->m_object_key[2] = pi[2];
-  m_alt->m_object_key[3] = pi[3];
+  int32_t *pi = reinterpret_cast<int32_t *>(&hash);
+  memcpy(m_alt->m_object_key, pi, CRYPTO_HASH_SIZE);
 }
 
 inline void
diff --git a/proxy/hdrs/URL.cc b/proxy/hdrs/URL.cc
index 2846f54..e44cb7f 100644
--- a/proxy/hdrs/URL.cc
+++ b/proxy/hdrs/URL.cc
@@ -94,8 +94,8 @@ int URL_LEN_MMS;
 int URL_LEN_MMSU;
 int URL_LEN_MMST;
 
-// Whether we should implement url_MD5_get() using url_MD5_get_fast(). Note that
-// url_MD5_get_fast() does NOT produce the same result as url_MD5_get_general().
+// Whether we should implement url_CryptoHash_get() using url_CryptoHash_get_fast(). Note that
+// url_CryptoHash_get_fast() does NOT produce the same result as url_CryptoHash_get_general().
 static int url_hash_method = 0;
 
 // test to see if a character is a valid character for a host in a URI according to
@@ -116,22 +116,6 @@ validate_host_name(ts::string_view addr)
 
 /*-------------------------------------------------------------------------
   -------------------------------------------------------------------------*/
-URLHashContext::HashType URLHashContext::Setting = URLHashContext::MD5;
-
-URLHashContext::URLHashContext()
-{
-  switch (Setting) {
-  case UNSPECIFIED:
-  case MD5:
-    new (_obj) MD5Context;
-    break;
-  case MMH:
-    new (_obj) MMHContext;
-    break;
-  default:
-    ink_assert("Invalid global URL hash context");
-  };
-}
 
 void
 url_init()
@@ -210,9 +194,6 @@ url_init()
     URL_LEN_MMS      = hdrtoken_wks_to_length(URL_SCHEME_MMS);
     URL_LEN_MMSU     = hdrtoken_wks_to_length(URL_SCHEME_MMSU);
     URL_LEN_MMST     = hdrtoken_wks_to_length(URL_SCHEME_MMST);
-
-    ink_assert(URLHashContext::OBJ_SIZE >= sizeof(MD5Context));
-    ink_assert(URLHashContext::OBJ_SIZE >= sizeof(MMHContext));
   }
 }
 
@@ -1652,11 +1633,11 @@ memcpy_tolower(char *d, const char *s, int n)
 
 #define BUFSIZE 512
 
-// fast path for MD5, HTTP, no user/password/params/query,
+// fast path for CryptoHash, HTTP, no user/password/params/query,
 // no buffer overflow, no unescaping needed
 
 static inline void
-url_MD5_get_fast(const URLImpl *url, CryptoContext &ctx, CryptoHash *hash, cache_generation_t generation)
+url_CryptoHash_get_fast(const URLImpl *url, CryptoContext &ctx, CryptoHash *hash, cache_generation_t generation)
 {
   char buffer[BUFSIZE];
   char *p;
@@ -1691,11 +1672,11 @@ url_MD5_get_fast(const URLImpl *url, CryptoContext &ctx, CryptoHash *hash, cache
     ctx.update(&generation, sizeof(generation));
   }
 
-  ctx.finalize(hash);
+  ctx.finalize(*hash);
 }
 
 static inline void
-url_MD5_get_general(const URLImpl *url, CryptoContext &ctx, CryptoHash &hash, cache_generation_t generation)
+url_CryptoHash_get_general(const URLImpl *url, CryptoContext &ctx, CryptoHash &hash, cache_generation_t generation)
 {
   char buffer[BUFSIZE];
   char *p, *e;
@@ -1771,21 +1752,21 @@ url_MD5_get_general(const URLImpl *url, CryptoContext &ctx, CryptoHash &hash, ca
 }
 
 void
-url_MD5_get(const URLImpl *url, CryptoHash *hash, cache_generation_t generation)
+url_CryptoHash_get(const URLImpl *url, CryptoHash *hash, cache_generation_t generation)
 {
   URLHashContext ctx;
   if ((url_hash_method != 0) && (url->m_url_type == URL_TYPE_HTTP) &&
       ((url->m_len_user + url->m_len_password + url->m_len_params + url->m_len_query) == 0) &&
       (3 + 1 + 1 + 1 + 1 + 1 + 2 + url->m_len_scheme + url->m_len_host + url->m_len_path < BUFSIZE) &&
       (memchr(url->m_ptr_host, '%', url->m_len_host) == nullptr) && (memchr(url->m_ptr_path, '%', url->m_len_path) == nullptr)) {
-    url_MD5_get_fast(url, ctx, hash, generation);
+    url_CryptoHash_get_fast(url, ctx, hash, generation);
 #ifdef DEBUG
-    CryptoHash md5_general;
-    url_MD5_get_general(url, ctx, md5_general, generation);
-    ink_assert(*hash == md5_general);
+    CryptoHash hash_general;
+    url_CryptoHash_get_general(url, ctx, hash_general, generation);
+    ink_assert(*hash == hash_general);
 #endif
   } else {
-    url_MD5_get_general(url, ctx, *hash, generation);
+    url_CryptoHash_get_general(url, ctx, *hash, generation);
   }
 }
 
@@ -1795,9 +1776,9 @@ url_MD5_get(const URLImpl *url, CryptoHash *hash, cache_generation_t generation)
   -------------------------------------------------------------------------*/
 
 void
-url_host_MD5_get(URLImpl *url, INK_MD5 *md5)
+url_host_CryptoHash_get(URLImpl *url, CryptoHash *hash)
 {
-  MD5Context ctx;
+  CryptoContext ctx;
 
   if (url->m_ptr_scheme) {
     ctx.update(url->m_ptr_scheme, url->m_len_scheme);
@@ -1812,10 +1793,10 @@ url_host_MD5_get(URLImpl *url, INK_MD5 *md5)
   ctx.update(":", 1);
 
   // [amc] Why is this <int> and not <in_port_t>?
-  // Especially since it's in_port_t for url_MD5_get.
+  // Especially since it's in_port_t for url_CryptoHash_get.
   int port = url_canonicalize_port(url->m_url_type, url->m_port);
   ctx.update(&port, sizeof(port));
-  ctx.finalize(*md5);
+  ctx.finalize(*hash);
 }
 
 /*-------------------------------------------------------------------------
diff --git a/proxy/hdrs/URL.h b/proxy/hdrs/URL.h
index d34a936..dda33bc 100644
--- a/proxy/hdrs/URL.h
+++ b/proxy/hdrs/URL.h
@@ -27,8 +27,7 @@
 #include "ts/Arena.h"
 #include "HdrToken.h"
 #include "HdrHeap.h"
-#include "ts/INK_MD5.h"
-#include "ts/MMH.h"
+#include "ts/CryptoHash.h"
 #include "MIME.h"
 #include <ts/string_view.h>
 
@@ -88,44 +87,7 @@ struct URLImpl : public HdrHeapObjImpl {
   void check_strings(HeapCheck *heaps, int num_heaps);
 };
 
-/// Crypto Hash context for URLs.
-/// @internal This just forwards on to another specific context but avoids
-/// putting that switch logic in multiple places. The working context is put
-/// in to class local storage (@a _obj) via placement @a new.
-class URLHashContext : public CryptoContext
-{
-public:
-  URLHashContext();
-  /// Update the hash with @a data of @a length bytes.
-  virtual bool update(void const *data, int length);
-  /// Finalize and extract the @a hash.
-  virtual bool finalize(CryptoHash &hash);
-
-  enum HashType {
-    UNSPECIFIED,
-    MD5,
-    MMH,
-  }; ///< What type of hash we really are.
-  static HashType Setting;
-
-  /// Size of storage for placement @c new of hashing context.
-  static size_t const OBJ_SIZE = 256;
-
-protected:
-  char _obj[OBJ_SIZE]; ///< Raw storage for instantiated context.
-};
-
-inline bool
-URLHashContext::update(void const *data, int length)
-{
-  return reinterpret_cast<CryptoContext *>(_obj)->update(data, length);
-}
-
-inline bool
-URLHashContext::finalize(CryptoHash &hash)
-{
-  return reinterpret_cast<CryptoContext *>(_obj)->finalize(hash);
-}
+using URLHashContext = CryptoContext;
 
 extern const char *URL_SCHEME_FILE;
 extern const char *URL_SCHEME_FTP;
@@ -216,8 +178,8 @@ void url_called_set(URLImpl *url);
 char *url_string_get_buf(URLImpl *url, char *dstbuf, int dstbuf_size, int *length);
 
 const char *url_scheme_get(URLImpl *url, int *length);
-void url_MD5_get(const URLImpl *url, CryptoHash *md5, cache_generation_t generation = -1);
-void url_host_MD5_get(URLImpl *url, CryptoHash *md5);
+void url_CryptoHash_get(const URLImpl *url, CryptoHash *hash, cache_generation_t generation = -1);
+void url_host_CryptoHash_get(URLImpl *url, CryptoHash *hash);
 const char *url_scheme_set(HdrHeap *heap, URLImpl *url, const char *value, int value_wks_idx, int length, bool copy_string);
 
 /* Internet specific */
@@ -287,8 +249,8 @@ public:
   char *string_get(Arena *arena, int *length = NULL);
   char *string_get_ref(int *length = NULL);
   char *string_get_buf(char *dstbuf, int dsbuf_size, int *length = NULL);
-  void hash_get(CryptoHash *md5, cache_generation_t generation = -1) const;
-  void host_hash_get(CryptoHash *md5);
+  void hash_get(CryptoHash *hash, cache_generation_t generation = -1) const;
+  void host_hash_get(CryptoHash *hash);
 
   const char *scheme_get(int *length);
   int scheme_get_wksidx();
@@ -471,20 +433,20 @@ URL::string_get_buf(char *dstbuf, int dsbuf_size, int *length)
   -------------------------------------------------------------------------*/
 
 inline void
-URL::hash_get(CryptoHash *md5, cache_generation_t generation) const
+URL::hash_get(CryptoHash *hash, cache_generation_t generation) const
 {
   ink_assert(valid());
-  url_MD5_get(m_url_impl, md5, generation);
+  url_CryptoHash_get(m_url_impl, hash, generation);
 }
 
 /*-------------------------------------------------------------------------
   -------------------------------------------------------------------------*/
 
 inline void
-URL::host_hash_get(CryptoHash *md5)
+URL::host_hash_get(CryptoHash *hash)
 {
   ink_assert(valid());
-  url_host_MD5_get(m_url_impl, md5);
+  url_host_CryptoHash_get(m_url_impl, hash);
 }
 
 /*-------------------------------------------------------------------------
diff --git a/proxy/http/HttpConnectionCount.h b/proxy/http/HttpConnectionCount.h
index 6774caa..916ce93 100644
--- a/proxy/http/HttpConnectionCount.h
+++ b/proxy/http/HttpConnectionCount.h
@@ -27,7 +27,7 @@
 #include "ts/ink_mutex.h"
 #include "ts/Map.h"
 #include "ts/Diags.h"
-#include "ts/INK_MD5.h"
+#include "ts/CryptoHash.h"
 #include "ts/ink_config.h"
 #include "HttpProxyAPIEnums.h"
 #include "Show.h"
@@ -58,7 +58,7 @@ public:
    * @return Number of connections
    */
   int
-  getCount(const IpEndpoint &addr, const INK_MD5 &hostname_hash, TSServerSessionSharingMatchType match_type)
+  getCount(const IpEndpoint &addr, const CryptoHash &hostname_hash, TSServerSessionSharingMatchType match_type)
   {
     if (TS_SERVER_SESSION_SHARING_MATCH_NONE == match_type) {
       return 0; // We can never match a node if match type is NONE
@@ -76,7 +76,7 @@ public:
    * @param delta Default is +1, can be set to negative to decrement
    */
   void
-  incrementCount(const IpEndpoint &addr, const INK_MD5 &hostname_hash, TSServerSessionSharingMatchType match_type,
+  incrementCount(const IpEndpoint &addr, const CryptoHash &hostname_hash, TSServerSessionSharingMatchType match_type,
                  const int delta = 1)
   {
     if (TS_SERVER_SESSION_SHARING_MATCH_NONE == match_type) {
@@ -97,7 +97,7 @@ public:
 
   struct ConnAddr {
     IpEndpoint _addr;
-    INK_MD5 _hostname_hash;
+    CryptoHash _hostname_hash;
     TSServerSessionSharingMatchType _match_type;
 
     ConnAddr() : _match_type(TS_SERVER_SESSION_SHARING_MATCH_NONE)
@@ -113,7 +113,7 @@ public:
       ink_zero(_hostname_hash);
     }
 
-    ConnAddr(const IpEndpoint &addr, const INK_MD5 &hostname_hash, TSServerSessionSharingMatchType match_type)
+    ConnAddr(const IpEndpoint &addr, const CryptoHash &hostname_hash, TSServerSessionSharingMatchType match_type)
       : _addr(addr), _hostname_hash(hostname_hash), _match_type(match_type)
     {
     }
@@ -121,8 +121,7 @@ public:
     ConnAddr(const IpEndpoint &addr, const char *hostname, TSServerSessionSharingMatchType match_type)
       : _addr(addr), _match_type(match_type)
     {
-      MD5Context md5_ctx;
-      md5_ctx.hash_immediate(_hostname_hash, static_cast<const void *>(hostname), strlen(hostname));
+      CryptoContext().hash_immediate(_hostname_hash, static_cast<const void *>(hostname), strlen(hostname));
     }
 
     operator bool() { return ats_is_ip(&_addr); }
@@ -143,7 +142,7 @@ public:
     std::string
     getHostnameHashStr()
     {
-      char hashBuffer[33];
+      char hashBuffer[CRYPTO_HEX_SIZE];
       return std::string(_hostname_hash.toHexStr(hashBuffer));
     }
   };
@@ -170,12 +169,12 @@ public:
     {
       char addrbuf1[INET6_ADDRSTRLEN];
       char addrbuf2[INET6_ADDRSTRLEN];
-      char md5buf1[33];
-      char md5buf2[33];
-      ink_code_to_hex_str(md5buf1, a._hostname_hash.u8);
-      ink_code_to_hex_str(md5buf2, b._hostname_hash.u8);
-      Debug("conn_count", "Comparing hostname hash %s dest %s match method %d to hostname hash %s dest %s match method %d", md5buf1,
-            ats_ip_nptop(&a._addr.sa, addrbuf1, sizeof(addrbuf1)), a._match_type, md5buf2,
+      char crypto_hashbuf1[CRYPTO_HEX_SIZE];
+      char crypto_hashbuf2[CRYPTO_HEX_SIZE];
+      a._hostname_hash.toHexStr(crypto_hashbuf1);
+      b._hostname_hash.toHexStr(crypto_hashbuf2);
+      Debug("conn_count", "Comparing hostname hash %s dest %s match method %d to hostname hash %s dest %s match method %d",
+            crypto_hashbuf1, ats_ip_nptop(&a._addr.sa, addrbuf1, sizeof(addrbuf1)), a._match_type, crypto_hashbuf2,
             ats_ip_nptop(&b._addr.sa, addrbuf2, sizeof(addrbuf2)), b._match_type);
 
       if (a._match_type != b._match_type || a._match_type == TS_SERVER_SESSION_SHARING_MATCH_NONE) {
diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
index 9d0a7a5..159cc36 100644
--- a/proxy/http/HttpSM.cc
+++ b/proxy/http/HttpSM.cc
@@ -4838,10 +4838,9 @@ HttpSM::do_http_server_open(bool raw)
   if (t_state.txn_conf->origin_max_connections > 0) {
     ConnectionCount *connections = ConnectionCount::getInstance();
 
-    INK_MD5 hostname_hash;
-    MD5Context md5_ctx;
-    md5_ctx.hash_immediate(hostname_hash, static_cast<const void *>(t_state.current.server->name),
-                           strlen(t_state.current.server->name));
+    CryptoHash hostname_hash;
+    CryptoContext().hash_immediate(hostname_hash, static_cast<const void *>(t_state.current.server->name),
+                                   strlen(t_state.current.server->name));
 
     if (connections->getCount(t_state.current.server->dst_addr, hostname_hash,
                               (TSServerSessionSharingMatchType)t_state.txn_conf->server_session_sharing_match) >=
@@ -5299,10 +5298,9 @@ HttpSM::handle_http_server_open()
 {
   // if we were a queued request, we need to decrement the queue size-- as we got a connection
   if (t_state.origin_request_queued) {
-    INK_MD5 hostname_hash;
-    MD5Context md5_ctx;
-    md5_ctx.hash_immediate(hostname_hash, static_cast<const void *>(t_state.current.server->name),
-                           strlen(t_state.current.server->name));
+    CryptoHash hostname_hash;
+    CryptoContext().hash_immediate(hostname_hash, static_cast<const void *>(t_state.current.server->name),
+                                   strlen(t_state.current.server->name));
 
     ConnectionCountQueue *waiting_connections = ConnectionCountQueue::getInstance();
     waiting_connections->incrementCount(t_state.current.server->dst_addr, hostname_hash,
diff --git a/proxy/http/HttpServerSession.h b/proxy/http/HttpServerSession.h
index 48624d6..ac1c50f 100644
--- a/proxy/http/HttpServerSession.h
+++ b/proxy/http/HttpServerSession.h
@@ -137,7 +137,7 @@ public:
     return server_vc->get_remote_endpoint();
   }
 
-  INK_MD5 hostname_hash;
+  CryptoHash hostname_hash;
 
   int64_t con_id;
   int transact_count;
@@ -209,7 +209,7 @@ inline void
 HttpServerSession::attach_hostname(const char *hostname)
 {
   if (CRYPTO_HASH_ZERO == hostname_hash) {
-    ink_code_md5((unsigned char *)hostname, strlen(hostname), (unsigned char *)&hostname_hash);
+    CryptoContext().hash_immediate(hostname_hash, (unsigned char *)hostname, strlen(hostname));
   }
 }
 #endif
diff --git a/proxy/http/HttpSessionManager.cc b/proxy/http/HttpSessionManager.cc
index ffe82e8..24ceab0 100644
--- a/proxy/http/HttpSessionManager.cc
+++ b/proxy/http/HttpSessionManager.cc
@@ -64,7 +64,7 @@ ServerSessionPool::purge()
 }
 
 bool
-ServerSessionPool::match(HttpServerSession *ss, sockaddr const *addr, INK_MD5 const &hostname_hash,
+ServerSessionPool::match(HttpServerSession *ss, sockaddr const *addr, CryptoHash const &hostname_hash,
                          TSServerSessionSharingMatchType match_style)
 {
   return TS_SERVER_SESSION_SHARING_MATCH_NONE != match_style && // if no matching allowed, fail immediately.
@@ -92,8 +92,8 @@ ServerSessionPool::validate_sni(HttpSM *sm, NetVConnection *netvc)
 }
 
 HSMresult_t
-ServerSessionPool::acquireSession(sockaddr const *addr, INK_MD5 const &hostname_hash, TSServerSessionSharingMatchType match_style,
-                                  HttpSM *sm, HttpServerSession *&to_return)
+ServerSessionPool::acquireSession(sockaddr const *addr, CryptoHash const &hostname_hash,
+                                  TSServerSessionSharingMatchType match_style, HttpSM *sm, HttpServerSession *&to_return)
 {
   HSMresult_t zret = HSM_NOT_FOUND;
   if (TS_SERVER_SESSION_SHARING_MATCH_HOST == match_style) {
@@ -269,10 +269,10 @@ HttpSessionManager::acquire_session(Continuation * /* cont ATS_UNUSED */, sockad
   HttpServerSession *to_return = nullptr;
   TSServerSessionSharingMatchType match_style =
     static_cast<TSServerSessionSharingMatchType>(sm->t_state.txn_conf->server_session_sharing_match);
-  INK_MD5 hostname_hash;
+  CryptoHash hostname_hash;
   HSMresult_t retval = HSM_NOT_FOUND;
 
-  ink_code_md5((unsigned char *)hostname, strlen(hostname), (unsigned char *)&hostname_hash);
+  CryptoContext().hash_immediate(hostname_hash, (unsigned char *)hostname, strlen(hostname));
 
   // First check to see if there is a server session bound
   //   to the user agent session
diff --git a/proxy/http/HttpSessionManager.h b/proxy/http/HttpSessionManager.h
index 766f657..5cb0cae 100644
--- a/proxy/http/HttpSessionManager.h
+++ b/proxy/http/HttpSessionManager.h
@@ -95,7 +95,7 @@ protected:
   /// Interface class for FQDN map.
   struct HostHashing {
     typedef uint64_t ID;
-    typedef INK_MD5 const &Key;
+    typedef CryptoHash const &Key;
     typedef HttpServerSession Value;
     typedef DList(HttpServerSession, host_hash_link) ListHead;
 
@@ -122,7 +122,7 @@ protected:
 public:
   /** Check if a session matches address and host name.
    */
-  static bool match(HttpServerSession *ss, sockaddr const *addr, INK_MD5 const &host_hash,
+  static bool match(HttpServerSession *ss, sockaddr const *addr, CryptoHash const &host_hash,
                     TSServerSessionSharingMatchType match_style);
 
   /** Get a session from the pool.
@@ -132,7 +132,7 @@ public:
 
       @return A pointer to the session or @c NULL if not matching session was found.
   */
-  HSMresult_t acquireSession(sockaddr const *addr, INK_MD5 const &host_hash, TSServerSessionSharingMatchType match_style,
+  HSMresult_t acquireSession(sockaddr const *addr, CryptoHash const &host_hash, TSServerSessionSharingMatchType match_style,
                              HttpSM *sm, HttpServerSession *&server_session);
   /** Release a session to to pool.
    */
diff --git a/proxy/logging/LogFormat.cc b/proxy/logging/LogFormat.cc
index c9e2ff7..a30c94e 100644
--- a/proxy/logging/LogFormat.cc
+++ b/proxy/logging/LogFormat.cc
@@ -32,9 +32,8 @@
 #include <cstring>
 #include <cstdlib>
 
-#include "ts/INK_MD5.h"
-
 #include "ts/SimpleTokenizer.h"
+#include "ts/CryptoHash.h"
 
 #include "LogUtils.h"
 #include "LogFile.h"
@@ -109,7 +108,7 @@ LogFormat::id_from_name(const char *name)
   int32_t id = 0;
   if (name) {
     CryptoHash hash;
-    MD5Context().hash_immediate(hash, name, static_cast<int>(strlen(name)));
+    CryptoContext().hash_immediate(hash, name, static_cast<int>(strlen(name)));
 #if defined(linux)
     /* Mask most signficant bit so that return value of this function
      * is not sign extended to be a negative number.
diff --git a/proxy/logging/LogObject.cc b/proxy/logging/LogObject.cc
index 3d0cd8b..8d2643d 100644
--- a/proxy/logging/LogObject.cc
+++ b/proxy/logging/LogObject.cc
@@ -28,7 +28,6 @@
  ***************************************************************************/
 #include "ts/ink_platform.h"
 #include "ts/CryptoHash.h"
-#include "ts/INK_MD5.h"
 #include "P_EventSystem.h"
 #include "LogUtils.h"
 #include "LogField.h"
@@ -338,7 +337,7 @@ LogObject::compute_signature(LogFormat *format, char *filename, unsigned int fla
                                    flags & LogObject::BINARY ? "B" : (flags & LogObject::WRITES_TO_PIPE ? "P" : "A"), NULL);
 
     CryptoHash hash;
-    MD5Context().hash_immediate(hash, buffer, buf_size - 1);
+    CryptoContext().hash_immediate(hash, buffer, buf_size - 1);
     signature = hash.fold();
 
     ats_free(buffer);
diff --git a/tools/Makefile.am b/tools/Makefile.am
index e61d814..af4f15d 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -33,7 +33,7 @@ noinst_PROGRAMS = jtest/jtest
 endif
 
 jtest_jtest_SOURCES = jtest/jtest.cc
-jtest_jtest_LDADD = $(top_builddir)/lib/ts/libtsutil.la
+jtest_jtest_LDADD = $(top_builddir)/lib/ts/libtsutil.la -lssl -lcrypto
 
 if BUILD_HTTP_LOAD
 
diff --git a/tools/jtest/jtest.cc b/tools/jtest/jtest.cc
index c351048..6a9d0fa 100644
--- a/tools/jtest/jtest.cc
+++ b/tools/jtest/jtest.cc
@@ -44,6 +44,7 @@
 #include <limits.h>
 #include <sys/mman.h>
 #include <cmath>
+#include <openssl/md5.h>
 
 #include <inttypes.h>
 
@@ -3437,6 +3438,18 @@ UrlHashTable::~UrlHashTable()
 } // UrlHashTable::~UrlHashTable
 
 static int
+ink_code_md5(unsigned const char *input, int input_length, unsigned char *sixteen_byte_hash_pointer)
+{
+  MD5_CTX context;
+
+  MD5_Init(&context);
+  MD5_Update(&context, input, input_length);
+  MD5_Final(sixteen_byte_hash_pointer, &context);
+
+  return (0);
+}
+
+static int
 seen_it(char *url)
 {
   if (!url_hash_entries) {

-- 
To stop receiving notification emails like this one, please contact
jplevyak@apache.org.