Commit 4e2ee3178 for imagemagick.org

commit 4e2ee3178c70706be46a96652854f2071f961df9
Author: Cristy <urban-warrior@imagemagick.org>
Date:   Mon Nov 2 13:27:06 2026 -0500

    https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-c764-55gw-gj6c

diff --git a/MagickCore/distribute-cache.c b/MagickCore/distribute-cache.c
index 331ed68e3..a50c2f818 100644
--- a/MagickCore/distribute-cache.c
+++ b/MagickCore/distribute-cache.c
@@ -1049,59 +1049,63 @@ static int DeriveDPCKey(const uint64_t session_key,const char label,
     sizeof(info),key,DPCMacLength));
 }

-static inline uint64_t LoadDPCWord(const unsigned char *p)
+static inline void WipeDPCKey(unsigned char *key,const size_t length)
 {
-  return(((uint64_t) p[0]) | ((uint64_t) p[1] << 8) |
-    ((uint64_t) p[2] << 16) | ((uint64_t) p[3] << 24) |
-    ((uint64_t) p[4] << 32) | ((uint64_t) p[5] << 40) |
-    ((uint64_t) p[6] << 48) | ((uint64_t) p[7] << 56));
+  volatile unsigned char
+    *p = key;
+
+  size_t
+    i;
+
+  for (i=0; i < length; i++)
+    p[i]=0;
 }

-static void SplitMix64Keystream(const unsigned char *stream_key,
+static void DPCKeystream(const unsigned char *stream_key,
   const unsigned char *mac,const MagickSizeType offset,unsigned char *data,
   const size_t length)
 {
+  SHA256Hash
+    block_hash,
+    keyed_hash;
+
   size_t
-    i;
+    i,
+    k;

   uint64_t
-    block,
-    seed,
-    z;
+    block;
+
+  unsigned char
+    counter[8],
+    keystream[32];

   /*
-    XOR data with the SplitMix64 keystream starting at byte 'offset'.
+    XOR data with keystream block n = SHA-256(stream key || mac || n),
   */
-  seed=LoadDPCWord(stream_key) ^ LoadDPCWord(mac);
-  block=(uint64_t) (offset >> 3);
-  z=0;
+  InitializeSHA256Hash(&keyed_hash);
+  UpdateSHA256Hash(&keyed_hash,stream_key,DPCMacLength);
+  UpdateSHA256Hash(&keyed_hash,mac,DPCMacLength);
+  (void) memset(keystream,0,sizeof(keystream));
   for (i=0; i < length; i++)
   {
     size_t
-      j = (size_t) ((offset+i) & 7);
+      j = (size_t) ((offset+i) & 31);

     if ((i == 0) || (j == 0))
       {
-        block=(uint64_t) ((offset+i) >> 3);
-        z=seed+(block+1)*0x9e3779b97f4a7c15ULL;
-        z=(z ^ (z >> 30))*0xbf58476d1ce4e5b9ULL;
-        z=(z ^ (z >> 27))*0x94d049bb133111ebULL;
-        z^=z >> 31;
+        block=(uint64_t) ((offset+i) >> 5);
+        for (k=0; k < sizeof(counter); k++)
+          counter[k]=(unsigned char) (block >> (8*k));
+        block_hash=keyed_hash;
+        UpdateSHA256Hash(&block_hash,counter,sizeof(counter));
+        FinalizeSHA256Hash(&block_hash,keystream);
       }
-    data[i]^=(unsigned char) (z >> (j*8));
+    data[i]^=keystream[j];
   }
-}
-
-static inline void WipeDPCKey(unsigned char *key,const size_t length)
-{
-  volatile unsigned char
-    *p = key;
-
-  size_t
-    i;
-
-  for (i=0; i < length; i++)
-    p[i]=0;
+  WipeDPCKey(keystream,sizeof(keystream));
+  WipeDPCKey((unsigned char *) &block_hash,sizeof(block_hash));
+  WipeDPCKey((unsigned char *) &keyed_hash,sizeof(keyed_hash));
 }

 static inline int mac_compare(const unsigned char *a,const unsigned char *b,
@@ -1170,7 +1174,7 @@ static inline MagickOffsetType dpc_send_mac(SOCKET_TYPE file,
         sizeof(scratch));

     (void) memcpy(scratch,p+offset,chunk);
-    SplitMix64Keystream(stream_key,mac,offset,scratch,chunk);
+    DPCKeystream(stream_key,mac,offset,scratch,chunk);
     status=dpc_send(file,(MagickSizeType) chunk,scratch);
     if (status != (MagickOffsetType) chunk)
       break;
@@ -1213,7 +1217,7 @@ static inline MagickOffsetType dpc_receive_mac(SOCKET_TYPE file,
   status=DeriveDPCKey(session_key,'e',stream_key);
   if (status == 0)
     {
-      SplitMix64Keystream(stream_key,received_mac,0,message,(size_t) length);
+      DPCKeystream(stream_key,received_mac,0,message,(size_t) length);
       status=DeriveDPCKey(session_key,'m',mac_key);
     }
   if (status == 0)