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.
33 #define ROTRN(w, v, n) ((((FcChar32)v) >> n) | (((FcChar32)v) << (w - n)))
34 #define ROTR32(v, n) ROTRN(32, v, n)
35 #define SHR(v, n) (v >> n)
36 #define Ch(x, y, z) ((x & y) ^ (~x & z))
37 #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
38 #define SS0(x) (ROTR32(x, 2) ^ ROTR32(x, 13) ^ ROTR32(x, 22))
39 #define SS1(x) (ROTR32(x, 6) ^ ROTR32(x, 11) ^ ROTR32(x, 25))
40 #define ss0(x) (ROTR32(x, 7) ^ ROTR32(x, 18) ^ SHR(x, 3))
41 #define ss1(x) (ROTR32(x, 17) ^ ROTR32(x, 19) ^ SHR(x, 10))
45 FcHashInitSHA256Digest (void)
48 static const FcChar32 h[] = {
49 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL,
50 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL
52 FcChar32 *ret = malloc (sizeof (FcChar32) * 8);
57 for (i = 0; i < 8; i++)
64 FcHashComputeSHA256Digest (FcChar32 *hash,
67 static const FcChar32 k[] = {
68 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
69 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
70 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
71 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
72 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
73 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
74 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
75 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
76 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
77 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
78 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
79 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
80 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
81 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
82 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
83 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
85 FcChar32 w[64], i, j, t1, t2;
86 FcChar32 a, b, c, d, e, f, g, h;
88 #define H(n) (hash[n])
99 for (i = 0; i < 16; i++)
101 j = (block[(i * 4) + 0] & 0xff) << (8 * 3);
102 j |= (block[(i * 4) + 1] & 0xff) << (8 * 2);
103 j |= (block[(i * 4) + 2] & 0xff) << (8 * 1);
104 j |= (block[(i * 4) + 3] & 0xff);
107 for (i = 16; i < 64; i++)
108 w[i] = ss1(w[i - 2]) + w[i - 7] + ss0(w[i - 15]) + w[i - 16];
110 for (i = 0; i < 64; i++)
112 t1 = h + SS1(e) + Ch(e, f, g) + k[i] + w[i];
113 t2 = SS0(a) + Maj(a, b, c);
137 FcHashSHA256ToString (FcChar32 *hash)
140 static const char hex[] = "0123456789abcdef";
145 ret = malloc (sizeof (FcChar8) * (8 * 8 + 7 + 1));
148 memcpy (ret, "sha256:", 7);
150 for (i = 0; i < 8; i++)
154 for (j = 0; j < 8; j++)
155 ret[7 + (i * 8) + j] = hex[(v >> (28 - j * 4)) & 0xf];
166 FcHashGetSHA256Digest (const FcChar8 *input_strings,
169 size_t i, round_len = len / 64;
171 FcChar32 *ret = FcHashInitSHA256Digest ();
176 for (i = 0; i < round_len; i++)
178 FcHashComputeSHA256Digest (ret, (const char *)&input_strings[i * 64]);
182 memcpy (block, &input_strings[len / 64], len % 64);
183 memset (&block[len % 64], 0, 64 - (len % 64));
184 block[len % 64] = 0x80;
185 if ((64 - (len % 64)) < 9)
187 /* process a block once */
188 FcHashComputeSHA256Digest (ret, block);
189 memset (block, 0, 64);
191 /* set input size at the end */
193 block[63 - 0] = len & 0xff;
194 block[63 - 1] = (len >> 8) & 0xff;
195 block[63 - 2] = (len >> 16) & 0xff;
196 block[63 - 3] = (len >> 24) & 0xff;
197 block[63 - 4] = (len >> 32) & 0xff;
198 block[63 - 5] = (len >> 40) & 0xff;
199 block[63 - 6] = (len >> 48) & 0xff;
200 block[63 - 7] = (len >> 56) & 0xff;
201 FcHashComputeSHA256Digest (ret, block);
203 return FcHashSHA256ToString (ret);
207 FcHashGetSHA256DigestFromMemory (const char *fontdata,
214 ret = FcHashInitSHA256Digest ();
220 if ((length - i) < 64)
228 memcpy (ibuf, &fontdata[i], n);
229 memset (&ibuf[n], 0, 64 - n);
233 /* process a block once */
234 FcHashComputeSHA256Digest (ret, ibuf);
235 memset (ibuf, 0, 64);
237 /* set input size at the end */
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, &fontdata[i]);
257 return FcHashSHA256ToString (ret);