diff options
Diffstat (limited to 'fontconfig/src/fchash.c')
-rw-r--r-- | fontconfig/src/fchash.c | 234 |
1 files changed, 53 insertions, 181 deletions
diff --git a/fontconfig/src/fchash.c b/fontconfig/src/fchash.c index 38300028c..1526cfd2b 100644 --- a/fontconfig/src/fchash.c +++ b/fontconfig/src/fchash.c @@ -3,7 +3,9 @@ * * Copyright © 2003 Keith Packard * Copyright © 2013 Red Hat, Inc. + * Copyright © 2014 Google, Inc. * Red Hat Author(s): Akira TAGOH + * Google Author(s): Behdad Esfahbod * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -27,6 +29,9 @@ #include <stdio.h> #include <string.h> +/* SHA256 */ + + #define ROTRN(w, v, n) ((((FcChar32)v) >> n) | (((FcChar32)v) << (w - n))) #define ROTR32(v, n) ROTRN(32, v, n) #define SHR(v, n) (v >> n) @@ -38,28 +43,21 @@ #define ss1(x) (ROTR32(x, 17) ^ ROTR32(x, 19) ^ SHR(x, 10)) -static FcChar32 * -FcHashInitSHA256Digest (void) + +void +FcHashInitDigest (FcHashDigest digest) { - int i; - static const FcChar32 h[] = { + static const FcHashDigest init = { 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL, 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL }; - FcChar32 *ret = malloc (sizeof (FcChar32) * 8); - if (!ret) - return NULL; - - for (i = 0; i < 8; i++) - ret[i] = h[i]; - - return ret; + memcpy (digest, init, sizeof (FcHashDigest)); } -static void -FcHashComputeSHA256Digest (FcChar32 *hash, - const char *block) +void +FcHashDigestAddBlock (FcHashDigest digest, + const char block[64]) { static const FcChar32 k[] = { 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, @@ -82,7 +80,7 @@ FcHashComputeSHA256Digest (FcChar32 *hash, FcChar32 w[64], i, j, t1, t2; FcChar32 a, b, c, d, e, f, g, h; -#define H(n) (hash[n]) +#define H(n) (digest[n]) a = H(0); b = H(1); @@ -130,188 +128,62 @@ FcHashComputeSHA256Digest (FcChar32 *hash, #undef H } -static FcChar8 * -FcHashSHA256ToString (FcChar32 *hash) -{ - FcChar8 *ret = NULL; - static const char hex[] = "0123456789abcdef"; - int i, j; - - if (hash) - { - ret = malloc (sizeof (FcChar8) * (8 * 8 + 7 + 1)); - if (!ret) - return NULL; - memcpy (ret, "sha256:", 7); -#define H(n) hash[n] - for (i = 0; i < 8; i++) - { - FcChar32 v = H(i); - - for (j = 0; j < 8; j++) - ret[7 + (i * 8) + j] = hex[(v >> (28 - j * 4)) & 0xf]; - } - ret[7 + i * 8] = 0; -#undef H - free (hash); - } - - return ret; -} - -FcChar8 * -FcHashGetSHA256Digest (const FcChar8 *input_strings, - size_t len) -{ - size_t i, round_len = len / 64; - char block[64]; - FcChar32 *ret = FcHashInitSHA256Digest (); - - if (!ret) - return NULL; - - for (i = 0; i < round_len; i++) - { - FcHashComputeSHA256Digest (ret, (const char *)&input_strings[i * 64]); - } - /* padding */ - if ((len % 64) != 0) - memcpy (block, &input_strings[len / 64], len % 64); - memset (&block[len % 64], 0, 64 - (len % 64)); - block[len % 64] = 0x80; - if ((64 - (len % 64)) < 9) - { - /* process a block once */ - FcHashComputeSHA256Digest (ret, block); - memset (block, 0, 64); - } - /* set input size at the end */ - len *= 8; - block[63 - 0] = (uint64_t)len & 0xff; - block[63 - 1] = ((uint64_t)len >> 8) & 0xff; - block[63 - 2] = ((uint64_t)len >> 16) & 0xff; - block[63 - 3] = ((uint64_t)len >> 24) & 0xff; - block[63 - 4] = ((uint64_t)len >> 32) & 0xff; - block[63 - 5] = ((uint64_t)len >> 40) & 0xff; - block[63 - 6] = ((uint64_t)len >> 48) & 0xff; - block[63 - 7] = ((uint64_t)len >> 56) & 0xff; - FcHashComputeSHA256Digest (ret, block); - - return FcHashSHA256ToString (ret); -} - -FcChar8 * -FcHashGetSHA256DigestFromFile (const FcChar8 *filename) +void +FcHashDigestFinish (FcHashDigest digest, + const char *residual, /* < 64 bytes */ + size_t total_len) { - FILE *fp = fopen ((const char *)filename, "rb"); char ibuf[64]; - FcChar32 *ret; - size_t len; - struct stat st; - - if (!fp) - return NULL; + unsigned int len = total_len % 64; + uint64_t v; - if (FcStat (filename, &st)) - goto bail0; + if (!len) + return; - ret = FcHashInitSHA256Digest (); - if (!ret) - goto bail0; + memcpy (ibuf, residual, len); + memset (ibuf + len, 0, 64 - len); + ibuf[len] = 0x80; - while (!feof (fp)) + if ((64 - len) < 9) { - if ((len = fread (ibuf, sizeof (char), 64, fp)) < 64) - { - uint64_t v; - - /* add a padding */ - memset (&ibuf[len], 0, 64 - len); - ibuf[len] = 0x80; - if ((64 - len) < 9) - { - /* process a block once */ - FcHashComputeSHA256Digest (ret, ibuf); - memset (ibuf, 0, 64); - } - /* set input size at the end */ - v = (long)st.st_size * 8; - ibuf[63 - 0] = v & 0xff; - ibuf[63 - 1] = (v >> 8) & 0xff; - ibuf[63 - 2] = (v >> 16) & 0xff; - ibuf[63 - 3] = (v >> 24) & 0xff; - ibuf[63 - 4] = (v >> 32) & 0xff; - ibuf[63 - 5] = (v >> 40) & 0xff; - ibuf[63 - 6] = (v >> 48) & 0xff; - ibuf[63 - 7] = (v >> 56) & 0xff; - FcHashComputeSHA256Digest (ret, ibuf); - break; - } - else - { - FcHashComputeSHA256Digest (ret, ibuf); - } + FcHashDigestAddBlock (digest, ibuf); + memset (ibuf, 0, 64); } - fclose (fp); - - return FcHashSHA256ToString (ret); - -bail0: - fclose (fp); - return NULL; + /* set input size at the end */ + v = (uint64_t) total_len * 8; + ibuf[63 - 0] = v & 0xff; + ibuf[63 - 1] = (v >> 8) & 0xff; + ibuf[63 - 2] = (v >> 16) & 0xff; + ibuf[63 - 3] = (v >> 24) & 0xff; + ibuf[63 - 4] = (v >> 32) & 0xff; + ibuf[63 - 5] = (v >> 40) & 0xff; + ibuf[63 - 6] = (v >> 48) & 0xff; + ibuf[63 - 7] = (v >> 56) & 0xff; + FcHashDigestAddBlock (digest, ibuf); } FcChar8 * -FcHashGetSHA256DigestFromMemory (const char *fontdata, - size_t length) +FcHashToString (const FcHashDigest digest) { - char ibuf[64]; - FcChar32 *ret; - size_t i = 0; + FcChar8 *ret = NULL; + static const char hex[] = "0123456789abcdef"; + int i, j; - ret = FcHashInitSHA256Digest (); + ret = malloc (sizeof (FcChar8) * (8 * 8 + 7 + 1)); if (!ret) return NULL; - - while (i <= length) + memcpy (ret, "sha256:", 7); +#define H(n) digest[n] + for (i = 0; i < 8; i++) { - if ((length - i) < 64) - { - uint64_t v; - size_t n; + FcChar32 v = H(i); - /* add a padding */ - n = length - i; - if (n > 0) - memcpy (ibuf, &fontdata[i], n); - memset (&ibuf[n], 0, 64 - n); - ibuf[n] = 0x80; - if ((64 - n) < 9) - { - /* process a block once */ - FcHashComputeSHA256Digest (ret, ibuf); - memset (ibuf, 0, 64); - } - /* set input size at the end */ - v = length * 8; - ibuf[63 - 0] = v & 0xff; - ibuf[63 - 1] = (v >> 8) & 0xff; - ibuf[63 - 2] = (v >> 16) & 0xff; - ibuf[63 - 3] = (v >> 24) & 0xff; - ibuf[63 - 4] = (v >> 32) & 0xff; - ibuf[63 - 5] = (v >> 40) & 0xff; - ibuf[63 - 6] = (v >> 48) & 0xff; - ibuf[63 - 7] = (v >> 56) & 0xff; - FcHashComputeSHA256Digest (ret, ibuf); - break; - } - else - { - FcHashComputeSHA256Digest (ret, &fontdata[i]); - } - i += 64; + for (j = 0; j < 8; j++) + ret[7 + (i * 8) + j] = hex[(v >> (28 - j * 4)) & 0xf]; } + ret[7 + i * 8] = 0; +#undef H - return FcHashSHA256ToString (ret); + return ret; } |