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)