Revert the previous change and rework to not export freetype API outside fcfreetype.c
[platform/upstream/fontconfig.git] / src / fchash.c
1 /*
2  * fontconfig/src/fchash.c
3  *
4  * Copyright © 2003 Keith Packard
5  * Copyright © 2013 Red Hat, Inc.
6  * Red Hat Author(s): Akira TAGOH
7  *
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.
17  *
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.
25  */
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 #include "fcint.h"
30 #include <stdio.h>
31 #include <string.h>
32
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))
42
43
44 static FcChar32 *
45 FcHashInitSHA256Digest (void)
46 {
47     int i;
48     static const FcChar32 h[] = {
49         0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL,
50         0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL
51     };
52     FcChar32 *ret = malloc (sizeof (FcChar32) * 8);
53
54     if (!ret)
55         return NULL;
56
57     for (i = 0; i < 8; i++)
58         ret[i] = h[i];
59
60     return ret;
61 }
62
63 static void
64 FcHashComputeSHA256Digest (FcChar32   *hash,
65                            const char *block)
66 {
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
84     };
85     FcChar32 w[64], i, j, t1, t2;
86     FcChar32 a, b, c, d, e, f, g, h;
87
88 #define H(n)    (hash[n])
89
90     a = H(0);
91     b = H(1);
92     c = H(2);
93     d = H(3);
94     e = H(4);
95     f = H(5);
96     g = H(6);
97     h = H(7);
98
99     for (i = 0; i < 16; i++)
100     {
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);
105         w[i] = j;
106     }
107     for (i = 16; i < 64; i++)
108         w[i] = ss1(w[i - 2]) + w[i - 7] + ss0(w[i - 15]) + w[i - 16];
109
110     for (i = 0; i < 64; i++)
111     {
112         t1 = h + SS1(e) + Ch(e, f, g) + k[i] + w[i];
113         t2 = SS0(a) + Maj(a, b, c);
114         h = g;
115         g = f;
116         f = e;
117         e = d + t1;
118         d = c;
119         c = b;
120         b = a;
121         a = t1 + t2;
122     }
123
124     H(0) += a;
125     H(1) += b;
126     H(2) += c;
127     H(3) += d;
128     H(4) += e;
129     H(5) += f;
130     H(6) += g;
131     H(7) += h;
132
133 #undef H
134 }
135
136 static FcChar8 *
137 FcHashSHA256ToString (FcChar32 *hash)
138 {
139     FcChar8 *ret = NULL;
140     static const char hex[] = "0123456789abcdef";
141     int i, j;
142
143     if (hash)
144     {
145         ret = malloc (sizeof (FcChar8) * (8 * 8 + 7 + 1));
146         if (!ret)
147             return NULL;
148         memcpy (ret, "sha256:", 7);
149 #define H(n)    hash[n]
150         for (i = 0; i < 8; i++)
151         {
152             FcChar32 v = H(i);
153
154             for (j = 0; j < 8; j++)
155                 ret[7 + (i * 8) + j] = hex[(v >> (28 - j * 4)) & 0xf];
156         }
157         ret[7 + i * 8] = 0;
158 #undef H
159         free (hash);
160     }
161
162     return ret;
163 }
164
165 FcChar8 *
166 FcHashGetSHA256Digest (const FcChar8 *input_strings,
167                        size_t         len)
168 {
169     size_t i, round_len = len / 64;
170     char block[64];
171     FcChar32 *ret = FcHashInitSHA256Digest ();
172
173     if (!ret)
174         return NULL;
175
176     for (i = 0; i < round_len; i++)
177     {
178         FcHashComputeSHA256Digest (ret, (const char *)&input_strings[i * 64]);
179     }
180     /* padding */
181     if ((len % 64) != 0)
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)
186     {
187         /* process a block once */
188         FcHashComputeSHA256Digest (ret, block);
189         memset (block, 0, 64);
190     }
191     /* set input size at the end */
192     len *= 8;
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);
202
203     return FcHashSHA256ToString (ret);
204 }
205
206 FcChar8 *
207 FcHashGetSHA256DigestFromMemory (const char *fontdata,
208                                  size_t      length)
209 {
210     char ibuf[64];
211     FcChar32 *ret;
212     size_t i = 0;
213
214     ret = FcHashInitSHA256Digest ();
215     if (!ret)
216         return NULL;
217
218     while (i <= length)
219     {
220         if ((length - i) < 64)
221         {
222             long v;
223             size_t n;
224
225             /* add a padding */
226             n = length - i;
227             if (n > 0)
228                 memcpy (ibuf, &fontdata[i], n);
229             memset (&ibuf[n], 0, 64 - n);
230             ibuf[n] = 0x80;
231             if ((64 - n) < 9)
232             {
233                 /* process a block once */
234                 FcHashComputeSHA256Digest (ret, ibuf);
235                 memset (ibuf, 0, 64);
236             }
237             /* set input size at the end */
238             v = length * 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);
248             break;
249         }
250         else
251         {
252             FcHashComputeSHA256Digest (ret, &fontdata[i]);
253         }
254         i += 64;
255     }
256
257     return FcHashSHA256ToString (ret);
258 }