2 * fontconfig/src/fchash.c
4 * Copyright © 2003 Keith Packard
5 * Copyright © 2013 Red Hat, Inc.
6 * Red Hat Author(s): Akira TAGOH
8 * Permission to use, copy, modify, distribute, and sell this software and its
9 * documentation for any purpose is hereby granted without fee, provided that
10 * the above copyright notice appear in all copies and that both that
11 * copyright notice and this permission notice appear in supporting
12 * documentation, and that the name of the author(s) not be used in
13 * advertising or publicity pertaining to distribution of the software without
14 * specific, written prior permission. The authors make no
15 * representations about the suitability of this software for any purpose. It
16 * is provided "as is" without express or implied warranty.
18 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
20 * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
21 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
23 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
24 * PERFORMANCE OF THIS SOFTWARE.
30 #define ROTRN(w, v, n) ((((FcChar32)v) >> n) | (((FcChar32)v) << (w - n)))
31 #define ROTR32(v, n) ROTRN(32, v, n)
32 #define SHR(v, n) (v >> n)
33 #define Ch(x, y, z) ((x & y) ^ (~x & z))
34 #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
35 #define SS0(x) (ROTR32(x, 2) ^ ROTR32(x, 13) ^ ROTR32(x, 22))
36 #define SS1(x) (ROTR32(x, 6) ^ ROTR32(x, 11) ^ ROTR32(x, 25))
37 #define ss0(x) (ROTR32(x, 7) ^ ROTR32(x, 18) ^ SHR(x, 3))
38 #define ss1(x) (ROTR32(x, 17) ^ ROTR32(x, 19) ^ SHR(x, 10))
42 FcHashInitSHA256Digest (void)
45 static const FcChar32 h[] = {
46 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL,
47 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL
49 FcChar32 *ret = malloc (sizeof (FcChar32) * 8);
54 for (i = 0; i < 8; i++)
61 FcHashComputeSHA256Digest (FcChar32 *hash,
64 static const FcChar32 k[] = {
65 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
66 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
67 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
68 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
69 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
70 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
71 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
72 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
73 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
74 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
75 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
76 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
77 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
78 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
79 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
80 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
82 FcChar32 w[64], i, j, t1, t2;
83 FcChar32 a, b, c, d, e, f, g, h;
85 #define H(n) (hash[n])
96 for (i = 0; i < 16; i++)
98 j = (block[(i * 4) + 0] & 0xff) << (8 * 3);
99 j |= (block[(i * 4) + 1] & 0xff) << (8 * 2);
100 j |= (block[(i * 4) + 2] & 0xff) << (8 * 1);
101 j |= (block[(i * 4) + 3] & 0xff);
104 for (i = 16; i < 64; i++)
105 w[i] = ss1(w[i - 2]) + w[i - 7] + ss0(w[i - 15]) + w[i - 16];
107 for (i = 0; i < 64; i++)
109 t1 = h + SS1(e) + Ch(e, f, g) + k[i] + w[i];
110 t2 = SS0(a) + Maj(a, b, c);
134 FcHashSHA256ToString (FcChar32 *hash)
137 static const char hex[] = "0123456789abcdef";
142 ret = malloc (sizeof (FcChar8) * (8 * 8 + 7 + 1));
145 memcpy (ret, "sha256:", 7);
147 for (i = 0; i < 8; i++)
151 for (j = 0; j < 8; j++)
152 ret[7 + (i * 8) + j] = hex[(v >> (28 - j * 4)) & 0xf];
163 FcHashGetSHA256Digest (const FcChar8 *input_strings,
166 size_t i, round_len = len / 64;
168 FcChar32 *ret = FcHashInitSHA256Digest ();
173 for (i = 0; i < round_len; i++)
175 FcHashComputeSHA256Digest (ret, (const char *)&input_strings[i * 64]);
179 memcpy (block, &input_strings[len / 64], len % 64);
180 memset (&block[len % 64], 0, 64 - (len % 64));
181 block[len % 64] = 0x80;
182 if ((64 - (len % 64)) < 9)
184 /* process a block once */
185 FcHashComputeSHA256Digest (ret, block);
186 memset (block, 0, 64);
188 /* set input size at the end */
190 block[63 - 0] = (uint64_t)len & 0xff;
191 block[63 - 1] = ((uint64_t)len >> 8) & 0xff;
192 block[63 - 2] = ((uint64_t)len >> 16) & 0xff;
193 block[63 - 3] = ((uint64_t)len >> 24) & 0xff;
194 block[63 - 4] = ((uint64_t)len >> 32) & 0xff;
195 block[63 - 5] = ((uint64_t)len >> 40) & 0xff;
196 block[63 - 6] = ((uint64_t)len >> 48) & 0xff;
197 block[63 - 7] = ((uint64_t)len >> 56) & 0xff;
198 FcHashComputeSHA256Digest (ret, block);
200 return FcHashSHA256ToString (ret);
204 FcHashGetSHA256DigestFromFile (const FcChar8 *filename)
206 FILE *fp = fopen ((const char *)filename, "rb");
215 if (FcStat (filename, &st))
218 ret = FcHashInitSHA256Digest ();
224 if ((len = fread (ibuf, sizeof (char), 64, fp)) < 64)
229 memset (&ibuf[len], 0, 64 - len);
233 /* process a block once */
234 FcHashComputeSHA256Digest (ret, ibuf);
235 memset (ibuf, 0, 64);
237 /* set input size at the end */
238 v = (long)st.st_size * 8;
239 ibuf[63 - 0] = v & 0xff;
240 ibuf[63 - 1] = (v >> 8) & 0xff;
241 ibuf[63 - 2] = (v >> 16) & 0xff;
242 ibuf[63 - 3] = (v >> 24) & 0xff;
243 ibuf[63 - 4] = (v >> 32) & 0xff;
244 ibuf[63 - 5] = (v >> 40) & 0xff;
245 ibuf[63 - 6] = (v >> 48) & 0xff;
246 ibuf[63 - 7] = (v >> 56) & 0xff;
247 FcHashComputeSHA256Digest (ret, ibuf);
252 FcHashComputeSHA256Digest (ret, ibuf);
257 return FcHashSHA256ToString (ret);
266 FcHashGetSHA256DigestFromMemory (const char *fontdata,
273 ret = FcHashInitSHA256Digest ();
279 if ((length - i) < 64)
287 memcpy (ibuf, &fontdata[i], n);
288 memset (&ibuf[n], 0, 64 - n);
292 /* process a block once */
293 FcHashComputeSHA256Digest (ret, ibuf);
294 memset (ibuf, 0, 64);
296 /* set input size at the end */
298 ibuf[63 - 0] = v & 0xff;
299 ibuf[63 - 1] = (v >> 8) & 0xff;
300 ibuf[63 - 2] = (v >> 16) & 0xff;
301 ibuf[63 - 3] = (v >> 24) & 0xff;
302 ibuf[63 - 4] = (v >> 32) & 0xff;
303 ibuf[63 - 5] = (v >> 40) & 0xff;
304 ibuf[63 - 6] = (v >> 48) & 0xff;
305 ibuf[63 - 7] = (v >> 56) & 0xff;
306 FcHashComputeSHA256Digest (ret, ibuf);
311 FcHashComputeSHA256Digest (ret, &fontdata[i]);
316 return FcHashSHA256ToString (ret);