Blame glib/gchecksum.c

Packit Service d3d246
/* gchecksum.h - data hashing functions
Packit Service d3d246
 *
Packit Service d3d246
 * Copyright (C) 2007  Emmanuele Bassi  <ebassi@gnome.org>
Packit Service d3d246
 *
Packit Service d3d246
 * This library is free software; you can redistribute it and/or
Packit Service d3d246
 * modify it under the terms of the GNU Lesser General Public
Packit Service d3d246
 * License as published by the Free Software Foundation; either
Packit Service d3d246
 * version 2.1 of the License, or (at your option) any later version.
Packit Service d3d246
 *
Packit Service d3d246
 * This library is distributed in the hope that it will be useful,
Packit Service d3d246
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service d3d246
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service d3d246
 * Lesser General Public License for more details.
Packit Service d3d246
 *
Packit Service d3d246
 * You should have received a copy of the GNU Lesser General Public License
Packit Service d3d246
 * along with this library; if not, see <http://www.gnu.org/licenses/>.
Packit Service d3d246
 */
Packit Service d3d246
Packit Service d3d246
#include "config.h"
Packit Service d3d246
Packit Service d3d246
#include <string.h>
Packit Service d3d246
Packit Service d3d246
#include "gchecksum.h"
Packit Service d3d246
Packit Service d3d246
#include "gslice.h"
Packit Service d3d246
#include "gmem.h"
Packit Service d3d246
#include "gstrfuncs.h"
Packit Service d3d246
#include "gtestutils.h"
Packit Service d3d246
#include "gtypes.h"
Packit Service d3d246
#include "glibintl.h"
Packit Service d3d246
Packit Service d3d246
Packit Service d3d246
/**
Packit Service d3d246
 * SECTION:checksum
Packit Service d3d246
 * @title: Data Checksums
Packit Service d3d246
 * @short_description: computes the checksum for data
Packit Service d3d246
 *
Packit Service d3d246
 * GLib provides a generic API for computing checksums (or "digests")
Packit Service d3d246
 * for a sequence of arbitrary bytes, using various hashing algorithms
Packit Service d3d246
 * like MD5, SHA-1 and SHA-256. Checksums are commonly used in various
Packit Service d3d246
 * environments and specifications.
Packit Service d3d246
 *
Packit Service d3d246
 * GLib supports incremental checksums using the GChecksum data
Packit Service d3d246
 * structure, by calling g_checksum_update() as long as there's data
Packit Service d3d246
 * available and then using g_checksum_get_string() or
Packit Service d3d246
 * g_checksum_get_digest() to compute the checksum and return it either
Packit Service d3d246
 * as a string in hexadecimal form, or as a raw sequence of bytes. To
Packit Service d3d246
 * compute the checksum for binary blobs and NUL-terminated strings in
Packit Service d3d246
 * one go, use the convenience functions g_compute_checksum_for_data()
Packit Service d3d246
 * and g_compute_checksum_for_string(), respectively.
Packit Service d3d246
 *
Packit Service d3d246
 * Support for checksums has been added in GLib 2.16
Packit Service d3d246
 **/
Packit Service d3d246
Packit Service d3d246
#define IS_VALID_TYPE(type)     ((type) >= G_CHECKSUM_MD5 && (type) <= G_CHECKSUM_SHA384)
Packit Service d3d246
Packit Service d3d246
/* The fact that these are lower case characters is part of the ABI */
Packit Service d3d246
static const gchar hex_digits[] = "0123456789abcdef";
Packit Service d3d246
Packit Service d3d246
#define MD5_DATASIZE    64
Packit Service d3d246
#define MD5_DIGEST_LEN  16
Packit Service d3d246
Packit Service d3d246
typedef struct
Packit Service d3d246
{
Packit Service d3d246
  guint32 buf[4];
Packit Service d3d246
  guint32 bits[2];
Packit Service d3d246
Packit Service d3d246
  union {
Packit Service d3d246
    guchar data[MD5_DATASIZE];
Packit Service d3d246
    guint32 data32[MD5_DATASIZE / 4];
Packit Service d3d246
  } u;
Packit Service d3d246
Packit Service d3d246
  guchar digest[MD5_DIGEST_LEN];
Packit Service d3d246
} Md5sum;
Packit Service d3d246
Packit Service d3d246
#define SHA1_DATASIZE   64
Packit Service d3d246
#define SHA1_DIGEST_LEN 20
Packit Service d3d246
Packit Service d3d246
typedef struct
Packit Service d3d246
{
Packit Service d3d246
  guint32 buf[5];
Packit Service d3d246
  guint32 bits[2];
Packit Service d3d246
Packit Service d3d246
  /* we pack 64 unsigned chars into 16 32-bit unsigned integers */
Packit Service d3d246
  guint32 data[16];
Packit Service d3d246
Packit Service d3d246
  guchar digest[SHA1_DIGEST_LEN];
Packit Service d3d246
} Sha1sum;
Packit Service d3d246
Packit Service d3d246
#define SHA256_DATASIZE         64
Packit Service d3d246
#define SHA256_DIGEST_LEN       32
Packit Service d3d246
Packit Service d3d246
typedef struct
Packit Service d3d246
{
Packit Service d3d246
  guint32 buf[8];
Packit Service d3d246
  guint32 bits[2];
Packit Service d3d246
Packit Service d3d246
  guint8 data[SHA256_DATASIZE];
Packit Service d3d246
Packit Service d3d246
  guchar digest[SHA256_DIGEST_LEN];
Packit Service d3d246
} Sha256sum;
Packit Service d3d246
Packit Service d3d246
/* SHA2 is common thing for SHA-384, SHA-512, SHA-512/224 and SHA-512/256 */
Packit Service d3d246
#define SHA2_BLOCK_LEN         128 /* 1024 bits message block */
Packit Service d3d246
#define SHA384_DIGEST_LEN       48
Packit Service d3d246
#define SHA512_DIGEST_LEN       64
Packit Service d3d246
Packit Service d3d246
typedef struct
Packit Service d3d246
{
Packit Service d3d246
  guint64 H[8];
Packit Service d3d246
Packit Service d3d246
  guint8 block[SHA2_BLOCK_LEN];
Packit Service d3d246
  guint8 block_len;
Packit Service d3d246
Packit Service d3d246
  guint64 data_len[2];
Packit Service d3d246
Packit Service d3d246
  guchar digest[SHA512_DIGEST_LEN];
Packit Service d3d246
} Sha512sum;
Packit Service d3d246
Packit Service d3d246
struct _GChecksum
Packit Service d3d246
{
Packit Service d3d246
  GChecksumType type;
Packit Service d3d246
Packit Service d3d246
  gchar *digest_str;
Packit Service d3d246
Packit Service d3d246
  union {
Packit Service d3d246
    Md5sum md5;
Packit Service d3d246
    Sha1sum sha1;
Packit Service d3d246
    Sha256sum sha256;
Packit Service d3d246
    Sha512sum sha512;
Packit Service d3d246
  } sum;
Packit Service d3d246
};
Packit Service d3d246
Packit Service d3d246
/* we need different byte swapping functions because MD5 expects buffers
Packit Service d3d246
 * to be little-endian, while SHA1 and SHA256 expect them in big-endian
Packit Service d3d246
 * form.
Packit Service d3d246
 */
Packit Service d3d246
Packit Service d3d246
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
Packit Service d3d246
#define md5_byte_reverse(buffer,length)
Packit Service d3d246
#else
Packit Service d3d246
/* assume that the passed buffer is integer aligned */
Packit Service d3d246
static inline void
Packit Service d3d246
md5_byte_reverse (guchar *buffer,
Packit Service d3d246
                  gulong  length)
Packit Service d3d246
{
Packit Service d3d246
  guint32 bit;
Packit Service d3d246
Packit Service d3d246
  do
Packit Service d3d246
    {
Packit Service d3d246
      bit = (guint32) ((unsigned) buffer[3] << 8 | buffer[2]) << 16 |
Packit Service d3d246
                      ((unsigned) buffer[1] << 8 | buffer[0]);
Packit Service d3d246
      * (guint32 *) buffer = bit;
Packit Service d3d246
      buffer += 4;
Packit Service d3d246
    }
Packit Service d3d246
  while (--length);
Packit Service d3d246
}
Packit Service d3d246
#endif /* G_BYTE_ORDER == G_LITTLE_ENDIAN */
Packit Service d3d246
Packit Service d3d246
#if G_BYTE_ORDER == G_BIG_ENDIAN
Packit Service d3d246
#define sha_byte_reverse(buffer,length)
Packit Service d3d246
#else
Packit Service d3d246
static inline void
Packit Service d3d246
sha_byte_reverse (guint32 *buffer,
Packit Service d3d246
                  gint     length)
Packit Service d3d246
{
Packit Service d3d246
  length /= sizeof (guint32);
Packit Service d3d246
  while (length--)
Packit Service d3d246
    {
Packit Service d3d246
      *buffer = GUINT32_SWAP_LE_BE (*buffer);
Packit Service d3d246
      ++buffer;
Packit Service d3d246
    }
Packit Service d3d246
}
Packit Service d3d246
#endif /* G_BYTE_ORDER == G_BIG_ENDIAN */
Packit Service d3d246
Packit Service d3d246
static gchar *
Packit Service d3d246
digest_to_string (guint8 *digest,
Packit Service d3d246
                  gsize   digest_len)
Packit Service d3d246
{
Packit Service d3d246
  gint len = digest_len * 2;
Packit Service d3d246
  gint i;
Packit Service d3d246
  gchar *retval;
Packit Service d3d246
Packit Service d3d246
  retval = g_new (gchar, len + 1);
Packit Service d3d246
Packit Service d3d246
  for (i = 0; i < digest_len; i++)
Packit Service d3d246
    {
Packit Service d3d246
      guint8 byte = digest[i];
Packit Service d3d246
Packit Service d3d246
      retval[2 * i] = hex_digits[byte >> 4];
Packit Service d3d246
      retval[2 * i + 1] = hex_digits[byte & 0xf];
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  retval[len] = 0;
Packit Service d3d246
Packit Service d3d246
  return retval;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/*
Packit Service d3d246
 * MD5 Checksum
Packit Service d3d246
 */
Packit Service d3d246
Packit Service d3d246
/* This MD5 digest computation is based on the equivalent code
Packit Service d3d246
 * written by Colin Plumb. It came with this notice:
Packit Service d3d246
 *
Packit Service d3d246
 * This code implements the MD5 message-digest algorithm.
Packit Service d3d246
 * The algorithm is due to Ron Rivest.  This code was
Packit Service d3d246
 * written by Colin Plumb in 1993, no copyright is claimed.
Packit Service d3d246
 * This code is in the public domain; do with it what you wish.
Packit Service d3d246
 *
Packit Service d3d246
 * Equivalent code is available from RSA Data Security, Inc.
Packit Service d3d246
 * This code has been tested against that, and is equivalent,
Packit Service d3d246
 * except that you don't need to include two pages of legalese
Packit Service d3d246
 * with every copy.
Packit Service d3d246
 */
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
md5_sum_init (Md5sum *md5)
Packit Service d3d246
{
Packit Service d3d246
  /* arbitrary constants */
Packit Service d3d246
  md5->buf[0] = 0x67452301;
Packit Service d3d246
  md5->buf[1] = 0xefcdab89;
Packit Service d3d246
  md5->buf[2] = 0x98badcfe;
Packit Service d3d246
  md5->buf[3] = 0x10325476;
Packit Service d3d246
Packit Service d3d246
  md5->bits[0] = md5->bits[1] = 0;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/*
Packit Service d3d246
 * The core of the MD5 algorithm, this alters an existing MD5 hash to
Packit Service d3d246
 * reflect the addition of 16 longwords of new data.  md5_sum_update()
Packit Service d3d246
 * blocks the data and converts bytes into longwords for this routine.
Packit Service d3d246
 */
Packit Service d3d246
static void
Packit Service d3d246
md5_transform (guint32       buf[4],
Packit Service d3d246
               guint32 const in[16])
Packit Service d3d246
{
Packit Service d3d246
  guint32 a, b, c, d;
Packit Service d3d246
Packit Service d3d246
/* The four core functions - F1 is optimized somewhat */
Packit Service d3d246
#define F1(x, y, z)     (z ^ (x & (y ^ z)))
Packit Service d3d246
#define F2(x, y, z)     F1 (z, x, y)
Packit Service d3d246
#define F3(x, y, z)     (x ^ y ^ z)
Packit Service d3d246
#define F4(x, y, z)     (y ^ (x | ~z))
Packit Service d3d246
Packit Service d3d246
/* This is the central step in the MD5 algorithm. */
Packit Service d3d246
#define md5_step(f, w, x, y, z, data, s) \
Packit Service d3d246
        ( w += f (x, y, z) + data,  w = w << s | w >> (32 - s),  w += x )
Packit Service d3d246
Packit Service d3d246
  a = buf[0];
Packit Service d3d246
  b = buf[1];
Packit Service d3d246
  c = buf[2];
Packit Service d3d246
  d = buf[3];
Packit Service d3d246
Packit Service d3d246
  md5_step (F1, a, b, c, d, in[0]  + 0xd76aa478,  7);
Packit Service d3d246
  md5_step (F1, d, a, b, c, in[1]  + 0xe8c7b756, 12);
Packit Service d3d246
  md5_step (F1, c, d, a, b, in[2]  + 0x242070db, 17);
Packit Service d3d246
  md5_step (F1, b, c, d, a, in[3]  + 0xc1bdceee, 22);
Packit Service d3d246
  md5_step (F1, a, b, c, d, in[4]  + 0xf57c0faf,  7);
Packit Service d3d246
  md5_step (F1, d, a, b, c, in[5]  + 0x4787c62a, 12);
Packit Service d3d246
  md5_step (F1, c, d, a, b, in[6]  + 0xa8304613, 17);
Packit Service d3d246
  md5_step (F1, b, c, d, a, in[7]  + 0xfd469501, 22);
Packit Service d3d246
  md5_step (F1, a, b, c, d, in[8]  + 0x698098d8,  7);
Packit Service d3d246
  md5_step (F1, d, a, b, c, in[9]  + 0x8b44f7af, 12);
Packit Service d3d246
  md5_step (F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
Packit Service d3d246
  md5_step (F1, b, c, d, a, in[11] + 0x895cd7be, 22);
Packit Service d3d246
  md5_step (F1, a, b, c, d, in[12] + 0x6b901122,  7);
Packit Service d3d246
  md5_step (F1, d, a, b, c, in[13] + 0xfd987193, 12);
Packit Service d3d246
  md5_step (F1, c, d, a, b, in[14] + 0xa679438e, 17);
Packit Service d3d246
  md5_step (F1, b, c, d, a, in[15] + 0x49b40821, 22);
Packit Service d3d246
        
Packit Service d3d246
  md5_step (F2, a, b, c, d, in[1]  + 0xf61e2562,  5);
Packit Service d3d246
  md5_step (F2, d, a, b, c, in[6]  + 0xc040b340,  9);
Packit Service d3d246
  md5_step (F2, c, d, a, b, in[11] + 0x265e5a51, 14);
Packit Service d3d246
  md5_step (F2, b, c, d, a, in[0]  + 0xe9b6c7aa, 20);
Packit Service d3d246
  md5_step (F2, a, b, c, d, in[5]  + 0xd62f105d,  5);
Packit Service d3d246
  md5_step (F2, d, a, b, c, in[10] + 0x02441453,  9);
Packit Service d3d246
  md5_step (F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
Packit Service d3d246
  md5_step (F2, b, c, d, a, in[4]  + 0xe7d3fbc8, 20);
Packit Service d3d246
  md5_step (F2, a, b, c, d, in[9]  + 0x21e1cde6,  5);
Packit Service d3d246
  md5_step (F2, d, a, b, c, in[14] + 0xc33707d6,  9);
Packit Service d3d246
  md5_step (F2, c, d, a, b, in[3]  + 0xf4d50d87, 14);
Packit Service d3d246
  md5_step (F2, b, c, d, a, in[8]  + 0x455a14ed, 20);
Packit Service d3d246
  md5_step (F2, a, b, c, d, in[13] + 0xa9e3e905,  5);
Packit Service d3d246
  md5_step (F2, d, a, b, c, in[2]  + 0xfcefa3f8,  9);
Packit Service d3d246
  md5_step (F2, c, d, a, b, in[7]  + 0x676f02d9, 14);
Packit Service d3d246
  md5_step (F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
Packit Service d3d246
Packit Service d3d246
  md5_step (F3, a, b, c, d, in[5]  + 0xfffa3942,  4);
Packit Service d3d246
  md5_step (F3, d, a, b, c, in[8]  + 0x8771f681, 11);
Packit Service d3d246
  md5_step (F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
Packit Service d3d246
  md5_step (F3, b, c, d, a, in[14] + 0xfde5380c, 23);
Packit Service d3d246
  md5_step (F3, a, b, c, d, in[1]  + 0xa4beea44,  4);
Packit Service d3d246
  md5_step (F3, d, a, b, c, in[4]  + 0x4bdecfa9, 11);
Packit Service d3d246
  md5_step (F3, c, d, a, b, in[7]  + 0xf6bb4b60, 16);
Packit Service d3d246
  md5_step (F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
Packit Service d3d246
  md5_step (F3, a, b, c, d, in[13] + 0x289b7ec6,  4);
Packit Service d3d246
  md5_step (F3, d, a, b, c, in[0]  + 0xeaa127fa, 11);
Packit Service d3d246
  md5_step (F3, c, d, a, b, in[3]  + 0xd4ef3085, 16);
Packit Service d3d246
  md5_step (F3, b, c, d, a, in[6]  + 0x04881d05, 23);
Packit Service d3d246
  md5_step (F3, a, b, c, d, in[9]  + 0xd9d4d039,  4);
Packit Service d3d246
  md5_step (F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
Packit Service d3d246
  md5_step (F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
Packit Service d3d246
  md5_step (F3, b, c, d, a, in[2]  + 0xc4ac5665, 23);
Packit Service d3d246
Packit Service d3d246
  md5_step (F4, a, b, c, d, in[0]  + 0xf4292244,  6);
Packit Service d3d246
  md5_step (F4, d, a, b, c, in[7]  + 0x432aff97, 10);
Packit Service d3d246
  md5_step (F4, c, d, a, b, in[14] + 0xab9423a7, 15);
Packit Service d3d246
  md5_step (F4, b, c, d, a, in[5]  + 0xfc93a039, 21);
Packit Service d3d246
  md5_step (F4, a, b, c, d, in[12] + 0x655b59c3,  6);
Packit Service d3d246
  md5_step (F4, d, a, b, c, in[3]  + 0x8f0ccc92, 10);
Packit Service d3d246
  md5_step (F4, c, d, a, b, in[10] + 0xffeff47d, 15);
Packit Service d3d246
  md5_step (F4, b, c, d, a, in[1]  + 0x85845dd1, 21);
Packit Service d3d246
  md5_step (F4, a, b, c, d, in[8]  + 0x6fa87e4f,  6);
Packit Service d3d246
  md5_step (F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
Packit Service d3d246
  md5_step (F4, c, d, a, b, in[6]  + 0xa3014314, 15);
Packit Service d3d246
  md5_step (F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
Packit Service d3d246
  md5_step (F4, a, b, c, d, in[4]  + 0xf7537e82,  6);
Packit Service d3d246
  md5_step (F4, d, a, b, c, in[11] + 0xbd3af235, 10);
Packit Service d3d246
  md5_step (F4, c, d, a, b, in[2]  + 0x2ad7d2bb, 15);
Packit Service d3d246
  md5_step (F4, b, c, d, a, in[9]  + 0xeb86d391, 21);
Packit Service d3d246
Packit Service d3d246
  buf[0] += a;
Packit Service d3d246
  buf[1] += b;
Packit Service d3d246
  buf[2] += c;
Packit Service d3d246
  buf[3] += d;
Packit Service d3d246
Packit Service d3d246
#undef F1
Packit Service d3d246
#undef F2
Packit Service d3d246
#undef F3
Packit Service d3d246
#undef F4
Packit Service d3d246
#undef md5_step
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
md5_sum_update (Md5sum       *md5,
Packit Service d3d246
                const guchar *data,
Packit Service d3d246
                gsize         length)
Packit Service d3d246
{
Packit Service d3d246
  guint32 bit;
Packit Service d3d246
Packit Service d3d246
  bit = md5->bits[0];
Packit Service d3d246
  md5->bits[0] = bit + ((guint32) length << 3);
Packit Service d3d246
Packit Service d3d246
  /* carry from low to high */
Packit Service d3d246
  if (md5->bits[0] < bit)
Packit Service d3d246
    md5->bits[1] += 1;
Packit Service d3d246
Packit Service d3d246
  md5->bits[1] += length >> 29;
Packit Service d3d246
Packit Service d3d246
  /* bytes already in Md5sum->u.data */
Packit Service d3d246
  bit = (bit >> 3) & 0x3f;
Packit Service d3d246
Packit Service d3d246
  /* handle any leading odd-sized chunks */
Packit Service d3d246
  if (bit)
Packit Service d3d246
    {
Packit Service d3d246
      guchar *p = md5->u.data + bit;
Packit Service d3d246
Packit Service d3d246
      bit = MD5_DATASIZE - bit;
Packit Service d3d246
      if (length < bit)
Packit Service d3d246
        {
Packit Service d3d246
          memcpy (p, data, length);
Packit Service d3d246
          return;
Packit Service d3d246
        }
Packit Service d3d246
Packit Service d3d246
      memcpy (p, data, bit);
Packit Service d3d246
Packit Service d3d246
      md5_byte_reverse (md5->u.data, 16);
Packit Service d3d246
      md5_transform (md5->buf, md5->u.data32);
Packit Service d3d246
Packit Service d3d246
      data += bit;
Packit Service d3d246
      length -= bit;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  /* process data in 64-byte chunks */
Packit Service d3d246
  while (length >= MD5_DATASIZE)
Packit Service d3d246
    {
Packit Service d3d246
      memcpy (md5->u.data, data, MD5_DATASIZE);
Packit Service d3d246
Packit Service d3d246
      md5_byte_reverse (md5->u.data, 16);
Packit Service d3d246
      md5_transform (md5->buf, md5->u.data32);
Packit Service d3d246
Packit Service d3d246
      data += MD5_DATASIZE;
Packit Service d3d246
      length -= MD5_DATASIZE;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  /* handle any remaining bytes of data */
Packit Service d3d246
  memcpy (md5->u.data, data, length);
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/* closes a checksum */
Packit Service d3d246
static void
Packit Service d3d246
md5_sum_close (Md5sum *md5)
Packit Service d3d246
{
Packit Service d3d246
  guint count;
Packit Service d3d246
  guchar *p;
Packit Service d3d246
Packit Service d3d246
  /* Compute number of bytes mod 64 */
Packit Service d3d246
  count = (md5->bits[0] >> 3) & 0x3F;
Packit Service d3d246
Packit Service d3d246
  /* Set the first char of padding to 0x80.
Packit Service d3d246
   * This is safe since there is always at least one byte free
Packit Service d3d246
   */
Packit Service d3d246
  p = md5->u.data + count;
Packit Service d3d246
  *p++ = 0x80;
Packit Service d3d246
Packit Service d3d246
  /* Bytes of padding needed to make 64 bytes */
Packit Service d3d246
  count = MD5_DATASIZE - 1 - count;
Packit Service d3d246
Packit Service d3d246
  /* Pad out to 56 mod 64 */
Packit Service d3d246
  if (count < 8)
Packit Service d3d246
    {
Packit Service d3d246
      /* Two lots of padding:  Pad the first block to 64 bytes */
Packit Service d3d246
      memset (p, 0, count);
Packit Service d3d246
Packit Service d3d246
      md5_byte_reverse (md5->u.data, 16);
Packit Service d3d246
      md5_transform (md5->buf, md5->u.data32);
Packit Service d3d246
Packit Service d3d246
      /* Now fill the next block with 56 bytes */
Packit Service d3d246
      memset (md5->u.data, 0, MD5_DATASIZE - 8);
Packit Service d3d246
    }
Packit Service d3d246
  else
Packit Service d3d246
    {
Packit Service d3d246
      /* Pad block to 56 bytes */
Packit Service d3d246
      memset (p, 0, count - 8);
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  md5_byte_reverse (md5->u.data, 14);
Packit Service d3d246
Packit Service d3d246
  /* Append length in bits and transform */
Packit Service d3d246
  md5->u.data32[14] = md5->bits[0];
Packit Service d3d246
  md5->u.data32[15] = md5->bits[1];
Packit Service d3d246
Packit Service d3d246
  md5_transform (md5->buf, md5->u.data32);
Packit Service d3d246
  md5_byte_reverse ((guchar *) md5->buf, 4);
Packit Service d3d246
Packit Service d3d246
  memcpy (md5->digest, md5->buf, 16);
Packit Service d3d246
Packit Service d3d246
  /* Reset buffers in case they contain sensitive data */
Packit Service d3d246
  memset (md5->buf, 0, sizeof (md5->buf));
Packit Service d3d246
  memset (md5->u.data, 0, sizeof (md5->u.data));
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static gchar *
Packit Service d3d246
md5_sum_to_string (Md5sum *md5)
Packit Service d3d246
{
Packit Service d3d246
  return digest_to_string (md5->digest, MD5_DIGEST_LEN);
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
md5_sum_digest (Md5sum *md5,
Packit Service d3d246
                guint8 *digest)
Packit Service d3d246
{
Packit Service d3d246
  gint i;
Packit Service d3d246
Packit Service d3d246
  for (i = 0; i < MD5_DIGEST_LEN; i++)
Packit Service d3d246
    digest[i] = md5->digest[i];
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/*
Packit Service d3d246
 * SHA-1 Checksum
Packit Service d3d246
 */
Packit Service d3d246
Packit Service d3d246
/* The following implementation comes from D-Bus dbus-sha.c. I've changed
Packit Service d3d246
 * it to use GLib types and to work more like the MD5 implementation above.
Packit Service d3d246
 * I left the comments to have an history of this code.
Packit Service d3d246
 *      -- Emmanuele Bassi, ebassi@gnome.org
Packit Service d3d246
 */
Packit Service d3d246
Packit Service d3d246
/* The following comments have the history of where this code
Packit Service d3d246
 * comes from. I actually copied it from GNet in GNOME CVS.
Packit Service d3d246
 * - hp@redhat.com
Packit Service d3d246
 */
Packit Service d3d246
Packit Service d3d246
/*
Packit Service d3d246
 *  sha.h : Implementation of the Secure Hash Algorithm
Packit Service d3d246
 *
Packit Service d3d246
 * Part of the Python Cryptography Toolkit, version 1.0.0
Packit Service d3d246
 *
Packit Service d3d246
 * Copyright (C) 1995, A.M. Kuchling
Packit Service d3d246
 *
Packit Service d3d246
 * Distribute and use freely; there are no restrictions on further
Packit Service d3d246
 * dissemination and usage except those imposed by the laws of your
Packit Service d3d246
 * country of residence.
Packit Service d3d246
 *
Packit Service d3d246
 */
Packit Service d3d246
Packit Service d3d246
/* SHA: NIST's Secure Hash Algorithm */
Packit Service d3d246
Packit Service d3d246
/* Based on SHA code originally posted to sci.crypt by Peter Gutmann
Packit Service d3d246
   in message <30ajo5$oe8@ccu2.auckland.ac.nz>.
Packit Service d3d246
   Modified to test for endianness on creation of SHA objects by AMK.
Packit Service d3d246
   Also, the original specification of SHA was found to have a weakness
Packit Service d3d246
   by NSA/NIST.  This code implements the fixed version of SHA.
Packit Service d3d246
*/
Packit Service d3d246
Packit Service d3d246
/* Here's the first paragraph of Peter Gutmann's posting:
Packit Service d3d246
Packit Service d3d246
The following is my SHA (FIPS 180) code updated to allow use of the "fixed"
Packit Service d3d246
SHA, thanks to Jim Gillogly and an anonymous contributor for the information on
Packit Service d3d246
what's changed in the new version.  The fix is a simple change which involves
Packit Service d3d246
adding a single rotate in the initial expansion function.  It is unknown
Packit Service d3d246
whether this is an optimal solution to the problem which was discovered in the
Packit Service d3d246
SHA or whether it's simply a bandaid which fixes the problem with a minimum of
Packit Service d3d246
effort (for example the reengineering of a great many Capstone chips).
Packit Service d3d246
*/
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
sha1_sum_init (Sha1sum *sha1)
Packit Service d3d246
{
Packit Service d3d246
  /* initialize constants */
Packit Service d3d246
  sha1->buf[0] = 0x67452301L;
Packit Service d3d246
  sha1->buf[1] = 0xEFCDAB89L;
Packit Service d3d246
  sha1->buf[2] = 0x98BADCFEL;
Packit Service d3d246
  sha1->buf[3] = 0x10325476L;
Packit Service d3d246
  sha1->buf[4] = 0xC3D2E1F0L;
Packit Service d3d246
Packit Service d3d246
  /* initialize bits */
Packit Service d3d246
  sha1->bits[0] = sha1->bits[1] = 0;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/* The SHA f()-functions. */
Packit Service d3d246
Packit Service d3d246
#define f1(x,y,z)       (z ^ (x & (y ^ z)))             /* Rounds  0-19 */
Packit Service d3d246
#define f2(x,y,z)       (x ^ y ^ z)                     /* Rounds 20-39 */
Packit Service d3d246
#define f3(x,y,z)       (( x & y) | (z & (x | y)))      /* Rounds 40-59 */
Packit Service d3d246
#define f4(x,y,z)       (x ^ y ^ z)                     /* Rounds 60-79 */
Packit Service d3d246
Packit Service d3d246
/* The SHA Mysterious Constants */
Packit Service d3d246
#define K1  0x5A827999L                                 /* Rounds  0-19 */
Packit Service d3d246
#define K2  0x6ED9EBA1L                                 /* Rounds 20-39 */
Packit Service d3d246
#define K3  0x8F1BBCDCL                                 /* Rounds 40-59 */
Packit Service d3d246
#define K4  0xCA62C1D6L                                 /* Rounds 60-79 */
Packit Service d3d246
Packit Service d3d246
/* 32-bit rotate left - kludged with shifts */
Packit Service d3d246
#define ROTL(n,X) (((X) << n ) | ((X) >> (32 - n)))
Packit Service d3d246
Packit Service d3d246
/* The initial expanding function.  The hash function is defined over an
Packit Service d3d246
   80-word expanded input array W, where the first 16 are copies of the input
Packit Service d3d246
   data, and the remaining 64 are defined by
Packit Service d3d246
Packit Service d3d246
        W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
Packit Service d3d246
Packit Service d3d246
   This implementation generates these values on the fly in a circular
Packit Service d3d246
   buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this
Packit Service d3d246
   optimization.
Packit Service d3d246
Packit Service d3d246
   The updated SHA changes the expanding function by adding a rotate of 1
Packit Service d3d246
   bit.  Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor
Packit Service d3d246
   for this information */
Packit Service d3d246
Packit Service d3d246
#define expand(W,i) (W[ i & 15 ] = ROTL (1, (W[ i       & 15] ^ \
Packit Service d3d246
                                             W[(i - 14) & 15] ^ \
Packit Service d3d246
                                             W[(i -  8) & 15] ^ \
Packit Service d3d246
                                             W[(i -  3) & 15])))
Packit Service d3d246
Packit Service d3d246
Packit Service d3d246
/* The prototype SHA sub-round.  The fundamental sub-round is:
Packit Service d3d246
Packit Service d3d246
        a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
Packit Service d3d246
        b' = a;
Packit Service d3d246
        c' = ROTL( 30, b );
Packit Service d3d246
        d' = c;
Packit Service d3d246
        e' = d;
Packit Service d3d246
Packit Service d3d246
   but this is implemented by unrolling the loop 5 times and renaming the
Packit Service d3d246
   variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
Packit Service d3d246
   This code is then replicated 20 times for each of the 4 functions, using
Packit Service d3d246
   the next 20 values from the W[] array each time */
Packit Service d3d246
Packit Service d3d246
#define subRound(a, b, c, d, e, f, k, data) \
Packit Service d3d246
   (e += ROTL (5, a) + f(b, c, d) + k + data, b = ROTL (30, b))
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
sha1_transform (guint32  buf[5],
Packit Service d3d246
                guint32  in[16])
Packit Service d3d246
{
Packit Service d3d246
  guint32 A, B, C, D, E;
Packit Service d3d246
Packit Service d3d246
  A = buf[0];
Packit Service d3d246
  B = buf[1];
Packit Service d3d246
  C = buf[2];
Packit Service d3d246
  D = buf[3];
Packit Service d3d246
  E = buf[4];
Packit Service d3d246
Packit Service d3d246
  /* Heavy mangling, in 4 sub-rounds of 20 iterations each. */
Packit Service d3d246
  subRound (A, B, C, D, E, f1, K1, in[0]);
Packit Service d3d246
  subRound (E, A, B, C, D, f1, K1, in[1]);
Packit Service d3d246
  subRound (D, E, A, B, C, f1, K1, in[2]);
Packit Service d3d246
  subRound (C, D, E, A, B, f1, K1, in[3]);
Packit Service d3d246
  subRound (B, C, D, E, A, f1, K1, in[4]);
Packit Service d3d246
  subRound (A, B, C, D, E, f1, K1, in[5]);
Packit Service d3d246
  subRound (E, A, B, C, D, f1, K1, in[6]);
Packit Service d3d246
  subRound (D, E, A, B, C, f1, K1, in[7]);
Packit Service d3d246
  subRound (C, D, E, A, B, f1, K1, in[8]);
Packit Service d3d246
  subRound (B, C, D, E, A, f1, K1, in[9]);
Packit Service d3d246
  subRound (A, B, C, D, E, f1, K1, in[10]);
Packit Service d3d246
  subRound (E, A, B, C, D, f1, K1, in[11]);
Packit Service d3d246
  subRound (D, E, A, B, C, f1, K1, in[12]);
Packit Service d3d246
  subRound (C, D, E, A, B, f1, K1, in[13]);
Packit Service d3d246
  subRound (B, C, D, E, A, f1, K1, in[14]);
Packit Service d3d246
  subRound (A, B, C, D, E, f1, K1, in[15]);
Packit Service d3d246
  subRound (E, A, B, C, D, f1, K1, expand (in, 16));
Packit Service d3d246
  subRound (D, E, A, B, C, f1, K1, expand (in, 17));
Packit Service d3d246
  subRound (C, D, E, A, B, f1, K1, expand (in, 18));
Packit Service d3d246
  subRound (B, C, D, E, A, f1, K1, expand (in, 19));
Packit Service d3d246
Packit Service d3d246
  subRound (A, B, C, D, E, f2, K2, expand (in, 20));
Packit Service d3d246
  subRound (E, A, B, C, D, f2, K2, expand (in, 21));
Packit Service d3d246
  subRound (D, E, A, B, C, f2, K2, expand (in, 22));
Packit Service d3d246
  subRound (C, D, E, A, B, f2, K2, expand (in, 23));
Packit Service d3d246
  subRound (B, C, D, E, A, f2, K2, expand (in, 24));
Packit Service d3d246
  subRound (A, B, C, D, E, f2, K2, expand (in, 25));
Packit Service d3d246
  subRound (E, A, B, C, D, f2, K2, expand (in, 26));
Packit Service d3d246
  subRound (D, E, A, B, C, f2, K2, expand (in, 27));
Packit Service d3d246
  subRound (C, D, E, A, B, f2, K2, expand (in, 28));
Packit Service d3d246
  subRound (B, C, D, E, A, f2, K2, expand (in, 29));
Packit Service d3d246
  subRound (A, B, C, D, E, f2, K2, expand (in, 30));
Packit Service d3d246
  subRound (E, A, B, C, D, f2, K2, expand (in, 31));
Packit Service d3d246
  subRound (D, E, A, B, C, f2, K2, expand (in, 32));
Packit Service d3d246
  subRound (C, D, E, A, B, f2, K2, expand (in, 33));
Packit Service d3d246
  subRound (B, C, D, E, A, f2, K2, expand (in, 34));
Packit Service d3d246
  subRound (A, B, C, D, E, f2, K2, expand (in, 35));
Packit Service d3d246
  subRound (E, A, B, C, D, f2, K2, expand (in, 36));
Packit Service d3d246
  subRound (D, E, A, B, C, f2, K2, expand (in, 37));
Packit Service d3d246
  subRound (C, D, E, A, B, f2, K2, expand (in, 38));
Packit Service d3d246
  subRound (B, C, D, E, A, f2, K2, expand (in, 39));
Packit Service d3d246
Packit Service d3d246
  subRound (A, B, C, D, E, f3, K3, expand (in, 40));
Packit Service d3d246
  subRound (E, A, B, C, D, f3, K3, expand (in, 41));
Packit Service d3d246
  subRound (D, E, A, B, C, f3, K3, expand (in, 42));
Packit Service d3d246
  subRound (C, D, E, A, B, f3, K3, expand (in, 43));
Packit Service d3d246
  subRound (B, C, D, E, A, f3, K3, expand (in, 44));
Packit Service d3d246
  subRound (A, B, C, D, E, f3, K3, expand (in, 45));
Packit Service d3d246
  subRound (E, A, B, C, D, f3, K3, expand (in, 46));
Packit Service d3d246
  subRound (D, E, A, B, C, f3, K3, expand (in, 47));
Packit Service d3d246
  subRound (C, D, E, A, B, f3, K3, expand (in, 48));
Packit Service d3d246
  subRound (B, C, D, E, A, f3, K3, expand (in, 49));
Packit Service d3d246
  subRound (A, B, C, D, E, f3, K3, expand (in, 50));
Packit Service d3d246
  subRound (E, A, B, C, D, f3, K3, expand (in, 51));
Packit Service d3d246
  subRound (D, E, A, B, C, f3, K3, expand (in, 52));
Packit Service d3d246
  subRound (C, D, E, A, B, f3, K3, expand (in, 53));
Packit Service d3d246
  subRound (B, C, D, E, A, f3, K3, expand (in, 54));
Packit Service d3d246
  subRound (A, B, C, D, E, f3, K3, expand (in, 55));
Packit Service d3d246
  subRound (E, A, B, C, D, f3, K3, expand (in, 56));
Packit Service d3d246
  subRound (D, E, A, B, C, f3, K3, expand (in, 57));
Packit Service d3d246
  subRound (C, D, E, A, B, f3, K3, expand (in, 58));
Packit Service d3d246
  subRound (B, C, D, E, A, f3, K3, expand (in, 59));
Packit Service d3d246
Packit Service d3d246
  subRound (A, B, C, D, E, f4, K4, expand (in, 60));
Packit Service d3d246
  subRound (E, A, B, C, D, f4, K4, expand (in, 61));
Packit Service d3d246
  subRound (D, E, A, B, C, f4, K4, expand (in, 62));
Packit Service d3d246
  subRound (C, D, E, A, B, f4, K4, expand (in, 63));
Packit Service d3d246
  subRound (B, C, D, E, A, f4, K4, expand (in, 64));
Packit Service d3d246
  subRound (A, B, C, D, E, f4, K4, expand (in, 65));
Packit Service d3d246
  subRound (E, A, B, C, D, f4, K4, expand (in, 66));
Packit Service d3d246
  subRound (D, E, A, B, C, f4, K4, expand (in, 67));
Packit Service d3d246
  subRound (C, D, E, A, B, f4, K4, expand (in, 68));
Packit Service d3d246
  subRound (B, C, D, E, A, f4, K4, expand (in, 69));
Packit Service d3d246
  subRound (A, B, C, D, E, f4, K4, expand (in, 70));
Packit Service d3d246
  subRound (E, A, B, C, D, f4, K4, expand (in, 71));
Packit Service d3d246
  subRound (D, E, A, B, C, f4, K4, expand (in, 72));
Packit Service d3d246
  subRound (C, D, E, A, B, f4, K4, expand (in, 73));
Packit Service d3d246
  subRound (B, C, D, E, A, f4, K4, expand (in, 74));
Packit Service d3d246
  subRound (A, B, C, D, E, f4, K4, expand (in, 75));
Packit Service d3d246
  subRound (E, A, B, C, D, f4, K4, expand (in, 76));
Packit Service d3d246
  subRound (D, E, A, B, C, f4, K4, expand (in, 77));
Packit Service d3d246
  subRound (C, D, E, A, B, f4, K4, expand (in, 78));
Packit Service d3d246
  subRound (B, C, D, E, A, f4, K4, expand (in, 79));
Packit Service d3d246
Packit Service d3d246
  /* Build message digest */
Packit Service d3d246
  buf[0] += A;
Packit Service d3d246
  buf[1] += B;
Packit Service d3d246
  buf[2] += C;
Packit Service d3d246
  buf[3] += D;
Packit Service d3d246
  buf[4] += E;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
#undef K1
Packit Service d3d246
#undef K2
Packit Service d3d246
#undef K3
Packit Service d3d246
#undef K4
Packit Service d3d246
#undef f1
Packit Service d3d246
#undef f2
Packit Service d3d246
#undef f3
Packit Service d3d246
#undef f4
Packit Service d3d246
#undef ROTL
Packit Service d3d246
#undef expand
Packit Service d3d246
#undef subRound
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
sha1_sum_update (Sha1sum      *sha1,
Packit Service d3d246
                 const guchar *buffer,
Packit Service d3d246
                 gsize         count)
Packit Service d3d246
{
Packit Service d3d246
  guint32 tmp;
Packit Service d3d246
  guint dataCount;
Packit Service d3d246
Packit Service d3d246
  /* Update bitcount */
Packit Service d3d246
  tmp = sha1->bits[0];
Packit Service d3d246
  if ((sha1->bits[0] = tmp + ((guint32) count << 3) ) < tmp)
Packit Service d3d246
    sha1->bits[1] += 1;             /* Carry from low to high */
Packit Service d3d246
  sha1->bits[1] += count >> 29;
Packit Service d3d246
Packit Service d3d246
  /* Get count of bytes already in data */
Packit Service d3d246
  dataCount = (guint) (tmp >> 3) & 0x3F;
Packit Service d3d246
Packit Service d3d246
  /* Handle any leading odd-sized chunks */
Packit Service d3d246
  if (dataCount)
Packit Service d3d246
    {
Packit Service d3d246
      guchar *p = (guchar *) sha1->data + dataCount;
Packit Service d3d246
Packit Service d3d246
      dataCount = SHA1_DATASIZE - dataCount;
Packit Service d3d246
      if (count < dataCount)
Packit Service d3d246
        {
Packit Service d3d246
          memcpy (p, buffer, count);
Packit Service d3d246
          return;
Packit Service d3d246
        }
Packit Service d3d246
Packit Service d3d246
      memcpy (p, buffer, dataCount);
Packit Service d3d246
Packit Service d3d246
      sha_byte_reverse (sha1->data, SHA1_DATASIZE);
Packit Service d3d246
      sha1_transform (sha1->buf, sha1->data);
Packit Service d3d246
Packit Service d3d246
      buffer += dataCount;
Packit Service d3d246
      count -= dataCount;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  /* Process data in SHA1_DATASIZE chunks */
Packit Service d3d246
  while (count >= SHA1_DATASIZE)
Packit Service d3d246
    {
Packit Service d3d246
      memcpy (sha1->data, buffer, SHA1_DATASIZE);
Packit Service d3d246
Packit Service d3d246
      sha_byte_reverse (sha1->data, SHA1_DATASIZE);
Packit Service d3d246
      sha1_transform (sha1->buf, sha1->data);
Packit Service d3d246
Packit Service d3d246
      buffer += SHA1_DATASIZE;
Packit Service d3d246
      count -= SHA1_DATASIZE;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  /* Handle any remaining bytes of data. */
Packit Service d3d246
  memcpy (sha1->data, buffer, count);
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/* Final wrapup - pad to SHA_DATASIZE-byte boundary with the bit pattern
Packit Service d3d246
   1 0* (64-bit count of bits processed, MSB-first) */
Packit Service d3d246
static void
Packit Service d3d246
sha1_sum_close (Sha1sum *sha1)
Packit Service d3d246
{
Packit Service d3d246
  gint count;
Packit Service d3d246
  guchar *data_p;
Packit Service d3d246
Packit Service d3d246
  /* Compute number of bytes mod 64 */
Packit Service d3d246
  count = (gint) ((sha1->bits[0] >> 3) & 0x3f);
Packit Service d3d246
Packit Service d3d246
  /* Set the first char of padding to 0x80.  This is safe since there is
Packit Service d3d246
     always at least one byte free */
Packit Service d3d246
  data_p = (guchar *) sha1->data + count;
Packit Service d3d246
  *data_p++ = 0x80;
Packit Service d3d246
Packit Service d3d246
  /* Bytes of padding needed to make 64 bytes */
Packit Service d3d246
  count = SHA1_DATASIZE - 1 - count;
Packit Service d3d246
Packit Service d3d246
  /* Pad out to 56 mod 64 */
Packit Service d3d246
  if (count < 8)
Packit Service d3d246
    {
Packit Service d3d246
      /* Two lots of padding:  Pad the first block to 64 bytes */
Packit Service d3d246
      memset (data_p, 0, count);
Packit Service d3d246
Packit Service d3d246
      sha_byte_reverse (sha1->data, SHA1_DATASIZE);
Packit Service d3d246
      sha1_transform (sha1->buf, sha1->data);
Packit Service d3d246
Packit Service d3d246
      /* Now fill the next block with 56 bytes */
Packit Service d3d246
      memset (sha1->data, 0, SHA1_DATASIZE - 8);
Packit Service d3d246
    }
Packit Service d3d246
  else
Packit Service d3d246
    {
Packit Service d3d246
      /* Pad block to 56 bytes */
Packit Service d3d246
      memset (data_p, 0, count - 8);
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  /* Append length in bits and transform */
Packit Service d3d246
  sha1->data[14] = sha1->bits[1];
Packit Service d3d246
  sha1->data[15] = sha1->bits[0];
Packit Service d3d246
Packit Service d3d246
  sha_byte_reverse (sha1->data, SHA1_DATASIZE - 8);
Packit Service d3d246
  sha1_transform (sha1->buf, sha1->data);
Packit Service d3d246
  sha_byte_reverse (sha1->buf, SHA1_DIGEST_LEN);
Packit Service d3d246
Packit Service d3d246
  memcpy (sha1->digest, sha1->buf, SHA1_DIGEST_LEN);
Packit Service d3d246
Packit Service d3d246
  /* Reset buffers in case they contain sensitive data */
Packit Service d3d246
  memset (sha1->buf, 0, sizeof (sha1->buf));
Packit Service d3d246
  memset (sha1->data, 0, sizeof (sha1->data));
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static gchar *
Packit Service d3d246
sha1_sum_to_string (Sha1sum *sha1)
Packit Service d3d246
{
Packit Service d3d246
  return digest_to_string (sha1->digest, SHA1_DIGEST_LEN);
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
sha1_sum_digest (Sha1sum *sha1,
Packit Service d3d246
                 guint8  *digest)
Packit Service d3d246
{
Packit Service d3d246
  gint i;
Packit Service d3d246
Packit Service d3d246
  for (i = 0; i < SHA1_DIGEST_LEN; i++)
Packit Service d3d246
    digest[i] = sha1->digest[i];
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/*
Packit Service d3d246
 * SHA-256 Checksum
Packit Service d3d246
 */
Packit Service d3d246
Packit Service d3d246
/* adapted from the SHA256 implementation in gsk/src/hash/gskhash.c.
Packit Service d3d246
 *
Packit Service d3d246
 * Copyright (C) 2006 Dave Benson
Packit Service d3d246
 * Released under the terms of the GNU Lesser General Public License
Packit Service d3d246
 */
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
sha256_sum_init (Sha256sum *sha256)
Packit Service d3d246
{
Packit Service d3d246
  sha256->buf[0] = 0x6a09e667;
Packit Service d3d246
  sha256->buf[1] = 0xbb67ae85;
Packit Service d3d246
  sha256->buf[2] = 0x3c6ef372;
Packit Service d3d246
  sha256->buf[3] = 0xa54ff53a;
Packit Service d3d246
  sha256->buf[4] = 0x510e527f;
Packit Service d3d246
  sha256->buf[5] = 0x9b05688c;
Packit Service d3d246
  sha256->buf[6] = 0x1f83d9ab;
Packit Service d3d246
  sha256->buf[7] = 0x5be0cd19;
Packit Service d3d246
Packit Service d3d246
  sha256->bits[0] = sha256->bits[1] = 0;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
#define GET_UINT32(n,b,i)               G_STMT_START{   \
Packit Service d3d246
    (n) = ((guint32) (b)[(i)    ] << 24)                \
Packit Service d3d246
        | ((guint32) (b)[(i) + 1] << 16)                \
Packit Service d3d246
        | ((guint32) (b)[(i) + 2] <<  8)                \
Packit Service d3d246
        | ((guint32) (b)[(i) + 3]      ); } G_STMT_END
Packit Service d3d246
Packit Service d3d246
#define PUT_UINT32(n,b,i)               G_STMT_START{   \
Packit Service d3d246
    (b)[(i)    ] = (guint8) ((n) >> 24);                \
Packit Service d3d246
    (b)[(i) + 1] = (guint8) ((n) >> 16);                \
Packit Service d3d246
    (b)[(i) + 2] = (guint8) ((n) >>  8);                \
Packit Service d3d246
    (b)[(i) + 3] = (guint8) ((n)      ); } G_STMT_END
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
sha256_transform (guint32      buf[8],
Packit Service d3d246
                  guint8 const data[64])
Packit Service d3d246
{
Packit Service d3d246
  guint32 temp1, temp2, W[64];
Packit Service d3d246
  guint32 A, B, C, D, E, F, G, H;
Packit Service d3d246
Packit Service d3d246
  GET_UINT32 (W[0],  data,  0);
Packit Service d3d246
  GET_UINT32 (W[1],  data,  4);
Packit Service d3d246
  GET_UINT32 (W[2],  data,  8);
Packit Service d3d246
  GET_UINT32 (W[3],  data, 12);
Packit Service d3d246
  GET_UINT32 (W[4],  data, 16);
Packit Service d3d246
  GET_UINT32 (W[5],  data, 20);
Packit Service d3d246
  GET_UINT32 (W[6],  data, 24);
Packit Service d3d246
  GET_UINT32 (W[7],  data, 28);
Packit Service d3d246
  GET_UINT32 (W[8],  data, 32);
Packit Service d3d246
  GET_UINT32 (W[9],  data, 36);
Packit Service d3d246
  GET_UINT32 (W[10], data, 40);
Packit Service d3d246
  GET_UINT32 (W[11], data, 44);
Packit Service d3d246
  GET_UINT32 (W[12], data, 48);
Packit Service d3d246
  GET_UINT32 (W[13], data, 52);
Packit Service d3d246
  GET_UINT32 (W[14], data, 56);
Packit Service d3d246
  GET_UINT32 (W[15], data, 60);
Packit Service d3d246
Packit Service d3d246
#define SHR(x,n)        ((x & 0xFFFFFFFF) >> n)
Packit Service d3d246
#define ROTR(x,n)       (SHR (x,n) | (x << (32 - n)))
Packit Service d3d246
Packit Service d3d246
#define S0(x) (ROTR (x, 7) ^ ROTR (x,18) ^  SHR (x, 3))
Packit Service d3d246
#define S1(x) (ROTR (x,17) ^ ROTR (x,19) ^  SHR (x,10))
Packit Service d3d246
#define S2(x) (ROTR (x, 2) ^ ROTR (x,13) ^ ROTR (x,22))
Packit Service d3d246
#define S3(x) (ROTR (x, 6) ^ ROTR (x,11) ^ ROTR (x,25))
Packit Service d3d246
Packit Service d3d246
#define F0(x,y,z) ((x & y) | (z & (x | y)))
Packit Service d3d246
#define F1(x,y,z) (z ^ (x & (y ^ z)))
Packit Service d3d246
Packit Service d3d246
#define R(t)    (W[t] = S1(W[t -  2]) + W[t -  7] + \
Packit Service d3d246
                        S0(W[t - 15]) + W[t - 16])
Packit Service d3d246
Packit Service d3d246
#define P(a,b,c,d,e,f,g,h,x,K)          G_STMT_START {  \
Packit Service d3d246
        temp1 = h + S3(e) + F1(e,f,g) + K + x;          \
Packit Service d3d246
        temp2 = S2(a) + F0(a,b,c);                      \
Packit Service d3d246
        d += temp1; h = temp1 + temp2; } G_STMT_END
Packit Service d3d246
Packit Service d3d246
  A = buf[0];
Packit Service d3d246
  B = buf[1];
Packit Service d3d246
  C = buf[2];
Packit Service d3d246
  D = buf[3];
Packit Service d3d246
  E = buf[4];
Packit Service d3d246
  F = buf[5];
Packit Service d3d246
  G = buf[6];
Packit Service d3d246
  H = buf[7];
Packit Service d3d246
Packit Service d3d246
  P (A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98);
Packit Service d3d246
  P (H, A, B, C, D, E, F, G, W[ 1], 0x71374491);
Packit Service d3d246
  P (G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF);
Packit Service d3d246
  P (F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5);
Packit Service d3d246
  P (E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B);
Packit Service d3d246
  P (D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1);
Packit Service d3d246
  P (C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4);
Packit Service d3d246
  P (B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5);
Packit Service d3d246
  P (A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98);
Packit Service d3d246
  P (H, A, B, C, D, E, F, G, W[ 9], 0x12835B01);
Packit Service d3d246
  P (G, H, A, B, C, D, E, F, W[10], 0x243185BE);
Packit Service d3d246
  P (F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
Packit Service d3d246
  P (E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
Packit Service d3d246
  P (D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
Packit Service d3d246
  P (C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
Packit Service d3d246
  P (B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
Packit Service d3d246
  P (A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
Packit Service d3d246
  P (H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
Packit Service d3d246
  P (G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
Packit Service d3d246
  P (F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
Packit Service d3d246
  P (E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
Packit Service d3d246
  P (D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
Packit Service d3d246
  P (C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
Packit Service d3d246
  P (B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
Packit Service d3d246
  P (A, B, C, D, E, F, G, H, R(24), 0x983E5152);
Packit Service d3d246
  P (H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
Packit Service d3d246
  P (G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
Packit Service d3d246
  P (F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
Packit Service d3d246
  P (E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
Packit Service d3d246
  P (D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
Packit Service d3d246
  P (C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
Packit Service d3d246
  P (B, C, D, E, F, G, H, A, R(31), 0x14292967);
Packit Service d3d246
  P (A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
Packit Service d3d246
  P (H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
Packit Service d3d246
  P (G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
Packit Service d3d246
  P (F, G, H, A, B, C, D, E, R(35), 0x53380D13);
Packit Service d3d246
  P (E, F, G, H, A, B, C, D, R(36), 0x650A7354);
Packit Service d3d246
  P (D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
Packit Service d3d246
  P (C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
Packit Service d3d246
  P (B, C, D, E, F, G, H, A, R(39), 0x92722C85);
Packit Service d3d246
  P (A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
Packit Service d3d246
  P (H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
Packit Service d3d246
  P (G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
Packit Service d3d246
  P (F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
Packit Service d3d246
  P (E, F, G, H, A, B, C, D, R(44), 0xD192E819);
Packit Service d3d246
  P (D, E, F, G, H, A, B, C, R(45), 0xD6990624);
Packit Service d3d246
  P (C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
Packit Service d3d246
  P (B, C, D, E, F, G, H, A, R(47), 0x106AA070);
Packit Service d3d246
  P (A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
Packit Service d3d246
  P (H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
Packit Service d3d246
  P (G, H, A, B, C, D, E, F, R(50), 0x2748774C);
Packit Service d3d246
  P (F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
Packit Service d3d246
  P (E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
Packit Service d3d246
  P (D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
Packit Service d3d246
  P (C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
Packit Service d3d246
  P (B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
Packit Service d3d246
  P (A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
Packit Service d3d246
  P (H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
Packit Service d3d246
  P (G, H, A, B, C, D, E, F, R(58), 0x84C87814);
Packit Service d3d246
  P (F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
Packit Service d3d246
  P (E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
Packit Service d3d246
  P (D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
Packit Service d3d246
  P (C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
Packit Service d3d246
  P (B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
Packit Service d3d246
Packit Service d3d246
#undef SHR
Packit Service d3d246
#undef ROTR
Packit Service d3d246
#undef S0
Packit Service d3d246
#undef S1
Packit Service d3d246
#undef S2
Packit Service d3d246
#undef S3
Packit Service d3d246
#undef F0
Packit Service d3d246
#undef F1
Packit Service d3d246
#undef R
Packit Service d3d246
#undef P
Packit Service d3d246
Packit Service d3d246
  buf[0] += A;
Packit Service d3d246
  buf[1] += B;
Packit Service d3d246
  buf[2] += C;
Packit Service d3d246
  buf[3] += D;
Packit Service d3d246
  buf[4] += E;
Packit Service d3d246
  buf[5] += F;
Packit Service d3d246
  buf[6] += G;
Packit Service d3d246
  buf[7] += H;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
sha256_sum_update (Sha256sum    *sha256,
Packit Service d3d246
                   const guchar *buffer,
Packit Service d3d246
                   gsize         length)
Packit Service d3d246
{
Packit Service d3d246
  guint32 left, fill;
Packit Service d3d246
  const guint8 *input = buffer;
Packit Service d3d246
Packit Service d3d246
  if (length == 0)
Packit Service d3d246
    return;
Packit Service d3d246
Packit Service d3d246
  left = sha256->bits[0] & 0x3F;
Packit Service d3d246
  fill = 64 - left;
Packit Service d3d246
Packit Service d3d246
  sha256->bits[0] += length;
Packit Service d3d246
  sha256->bits[0] &= 0xFFFFFFFF;
Packit Service d3d246
Packit Service d3d246
  if (sha256->bits[0] < length)
Packit Service d3d246
      sha256->bits[1]++;
Packit Service d3d246
Packit Service d3d246
  if (left > 0 && length >= fill)
Packit Service d3d246
    {
Packit Service d3d246
      memcpy ((sha256->data + left), input, fill);
Packit Service d3d246
Packit Service d3d246
      sha256_transform (sha256->buf, sha256->data);
Packit Service d3d246
      length -= fill;
Packit Service d3d246
      input += fill;
Packit Service d3d246
Packit Service d3d246
      left = 0;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  while (length >= SHA256_DATASIZE)
Packit Service d3d246
    {
Packit Service d3d246
      sha256_transform (sha256->buf, input);
Packit Service d3d246
Packit Service d3d246
      length -= 64;
Packit Service d3d246
      input += 64;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  if (length)
Packit Service d3d246
    memcpy (sha256->data + left, input, length);
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static guint8 sha256_padding[64] =
Packit Service d3d246
{
Packit Service d3d246
 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Packit Service d3d246
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Packit Service d3d246
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Packit Service d3d246
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Packit Service d3d246
};
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
sha256_sum_close (Sha256sum *sha256)
Packit Service d3d246
{
Packit Service d3d246
  guint32 last, padn;
Packit Service d3d246
  guint32 high, low;
Packit Service d3d246
  guint8 msglen[8];
Packit Service d3d246
Packit Service d3d246
  high = (sha256->bits[0] >> 29)
Packit Service d3d246
       | (sha256->bits[1] <<  3);
Packit Service d3d246
  low  = (sha256->bits[0] <<  3);
Packit Service d3d246
Packit Service d3d246
  PUT_UINT32 (high, msglen, 0);
Packit Service d3d246
  PUT_UINT32 (low, msglen, 4);
Packit Service d3d246
Packit Service d3d246
  last = sha256->bits[0] & 0x3F;
Packit Service d3d246
  padn = (last < 56) ? (56 - last) : (120 - last);
Packit Service d3d246
Packit Service d3d246
  sha256_sum_update (sha256, sha256_padding, padn);
Packit Service d3d246
  sha256_sum_update (sha256, msglen, 8);
Packit Service d3d246
Packit Service d3d246
  PUT_UINT32 (sha256->buf[0], sha256->digest,  0);
Packit Service d3d246
  PUT_UINT32 (sha256->buf[1], sha256->digest,  4);
Packit Service d3d246
  PUT_UINT32 (sha256->buf[2], sha256->digest,  8);
Packit Service d3d246
  PUT_UINT32 (sha256->buf[3], sha256->digest, 12);
Packit Service d3d246
  PUT_UINT32 (sha256->buf[4], sha256->digest, 16);
Packit Service d3d246
  PUT_UINT32 (sha256->buf[5], sha256->digest, 20);
Packit Service d3d246
  PUT_UINT32 (sha256->buf[6], sha256->digest, 24);
Packit Service d3d246
  PUT_UINT32 (sha256->buf[7], sha256->digest, 28);
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
#undef PUT_UINT32
Packit Service d3d246
#undef GET_UINT32
Packit Service d3d246
Packit Service d3d246
static gchar *
Packit Service d3d246
sha256_sum_to_string (Sha256sum *sha256)
Packit Service d3d246
{
Packit Service d3d246
  return digest_to_string (sha256->digest, SHA256_DIGEST_LEN);
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
sha256_sum_digest (Sha256sum *sha256,
Packit Service d3d246
                   guint8    *digest)
Packit Service d3d246
{
Packit Service d3d246
  gint i;
Packit Service d3d246
Packit Service d3d246
  for (i = 0; i < SHA256_DIGEST_LEN; i++)
Packit Service d3d246
    digest[i] = sha256->digest[i];
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/*
Packit Service d3d246
 * SHA-384, SHA-512, SHA-512/224 and SHA-512/256 Checksums
Packit Service d3d246
 *
Packit Service d3d246
 * Implemented following FIPS-180-4 standard at
Packit Service d3d246
 * http://csrc.nist.gov/publications/fips/fips180-4/fips180-4.pdf.
Packit Service d3d246
 * References in the form [§x.y.z] map to sections in that document.
Packit Service d3d246
 *
Packit Service d3d246
 *   Author(s): Eduardo Lima Mitev <elima@igalia.com>
Packit Service d3d246
 *              Igor Gnatenko <ignatenko@src.gnome.org>
Packit Service d3d246
 */
Packit Service d3d246
Packit Service d3d246
/* SHA-384, SHA-512, SHA-512/224 and SHA-512/256 functions [§4.1.3] */
Packit Service d3d246
#define Ch(x,y,z)  ((x & y) ^ (~x & z))
Packit Service d3d246
#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
Packit Service d3d246
#define SHR(n,x)   (x >> n)
Packit Service d3d246
#define ROTR(n,x)  (SHR (n, x) | (x << (64 - n)))
Packit Service d3d246
#define SIGMA0(x)  (ROTR (28, x) ^ ROTR (34, x) ^ ROTR (39, x))
Packit Service d3d246
#define SIGMA1(x)  (ROTR (14, x) ^ ROTR (18, x) ^ ROTR (41, x))
Packit Service d3d246
#define sigma0(x)  (ROTR ( 1, x) ^ ROTR ( 8, x) ^ SHR  ( 7, x))
Packit Service d3d246
#define sigma1(x)  (ROTR (19, x) ^ ROTR (61, x) ^ SHR  ( 6, x))
Packit Service d3d246
Packit Service d3d246
#define PUT_UINT64(n,b,i)                G_STMT_START{   \
Packit Service d3d246
    (b)[(i)    ] = (guint8) (n >> 56);                   \
Packit Service d3d246
    (b)[(i) + 1] = (guint8) (n >> 48);                   \
Packit Service d3d246
    (b)[(i) + 2] = (guint8) (n >> 40);                   \
Packit Service d3d246
    (b)[(i) + 3] = (guint8) (n >> 32);                   \
Packit Service d3d246
    (b)[(i) + 4] = (guint8) (n >> 24);                   \
Packit Service d3d246
    (b)[(i) + 5] = (guint8) (n >> 16);                   \
Packit Service d3d246
    (b)[(i) + 6] = (guint8) (n >>  8);                   \
Packit Service d3d246
    (b)[(i) + 7] = (guint8) (n      ); } G_STMT_END
Packit Service d3d246
Packit Service d3d246
/* SHA-384 and SHA-512 constants [§4.2.3] */
Packit Service d3d246
static const guint64 SHA2_K[80] = {
Packit Service d3d246
  0x428a2f98d728ae22, 0x7137449123ef65cd,
Packit Service d3d246
  0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
Packit Service d3d246
  0x3956c25bf348b538, 0x59f111f1b605d019,
Packit Service d3d246
  0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
Packit Service d3d246
  0xd807aa98a3030242, 0x12835b0145706fbe,
Packit Service d3d246
  0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
Packit Service d3d246
  0x72be5d74f27b896f, 0x80deb1fe3b1696b1,
Packit Service d3d246
  0x9bdc06a725c71235, 0xc19bf174cf692694,
Packit Service d3d246
  0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
Packit Service d3d246
  0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
Packit Service d3d246
  0x2de92c6f592b0275, 0x4a7484aa6ea6e483,
Packit Service d3d246
  0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
Packit Service d3d246
  0x983e5152ee66dfab, 0xa831c66d2db43210,
Packit Service d3d246
  0xb00327c898fb213f, 0xbf597fc7beef0ee4,
Packit Service d3d246
  0xc6e00bf33da88fc2, 0xd5a79147930aa725,
Packit Service d3d246
  0x06ca6351e003826f, 0x142929670a0e6e70,
Packit Service d3d246
  0x27b70a8546d22ffc, 0x2e1b21385c26c926,
Packit Service d3d246
  0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
Packit Service d3d246
  0x650a73548baf63de, 0x766a0abb3c77b2a8,
Packit Service d3d246
  0x81c2c92e47edaee6, 0x92722c851482353b,
Packit Service d3d246
  0xa2bfe8a14cf10364, 0xa81a664bbc423001,
Packit Service d3d246
  0xc24b8b70d0f89791, 0xc76c51a30654be30,
Packit Service d3d246
  0xd192e819d6ef5218, 0xd69906245565a910,
Packit Service d3d246
  0xf40e35855771202a, 0x106aa07032bbd1b8,
Packit Service d3d246
  0x19a4c116b8d2d0c8, 0x1e376c085141ab53,
Packit Service d3d246
  0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
Packit Service d3d246
  0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
Packit Service d3d246
  0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
Packit Service d3d246
  0x748f82ee5defb2fc, 0x78a5636f43172f60,
Packit Service d3d246
  0x84c87814a1f0ab72, 0x8cc702081a6439ec,
Packit Service d3d246
  0x90befffa23631e28, 0xa4506cebde82bde9,
Packit Service d3d246
  0xbef9a3f7b2c67915, 0xc67178f2e372532b,
Packit Service d3d246
  0xca273eceea26619c, 0xd186b8c721c0c207,
Packit Service d3d246
  0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
Packit Service d3d246
  0x06f067aa72176fba, 0x0a637dc5a2c898a6,
Packit Service d3d246
  0x113f9804bef90dae, 0x1b710b35131c471b,
Packit Service d3d246
  0x28db77f523047d84, 0x32caab7b40c72493,
Packit Service d3d246
  0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
Packit Service d3d246
  0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
Packit Service d3d246
  0x5fcb6fab3ad6faec, 0x6c44198c4a475817
Packit Service d3d246
};
Packit Service d3d246
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
sha384_sum_init (Sha512sum *sha512)
Packit Service d3d246
{
Packit Service d3d246
  /* Initial Hash Value [§5.3.4] */
Packit Service d3d246
  sha512->H[0] = 0xcbbb9d5dc1059ed8;
Packit Service d3d246
  sha512->H[1] = 0x629a292a367cd507;
Packit Service d3d246
  sha512->H[2] = 0x9159015a3070dd17;
Packit Service d3d246
  sha512->H[3] = 0x152fecd8f70e5939;
Packit Service d3d246
  sha512->H[4] = 0x67332667ffc00b31;
Packit Service d3d246
  sha512->H[5] = 0x8eb44a8768581511;
Packit Service d3d246
  sha512->H[6] = 0xdb0c2e0d64f98fa7;
Packit Service d3d246
  sha512->H[7] = 0x47b5481dbefa4fa4;
Packit Service d3d246
Packit Service d3d246
  sha512->block_len = 0;
Packit Service d3d246
Packit Service d3d246
  sha512->data_len[0] = 0;
Packit Service d3d246
  sha512->data_len[1] = 0;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
sha512_sum_init (Sha512sum *sha512)
Packit Service d3d246
{
Packit Service d3d246
  /* Initial Hash Value [§5.3.5] */
Packit Service d3d246
  sha512->H[0] = 0x6a09e667f3bcc908;
Packit Service d3d246
  sha512->H[1] = 0xbb67ae8584caa73b;
Packit Service d3d246
  sha512->H[2] = 0x3c6ef372fe94f82b;
Packit Service d3d246
  sha512->H[3] = 0xa54ff53a5f1d36f1;
Packit Service d3d246
  sha512->H[4] = 0x510e527fade682d1;
Packit Service d3d246
  sha512->H[5] = 0x9b05688c2b3e6c1f;
Packit Service d3d246
  sha512->H[6] = 0x1f83d9abfb41bd6b;
Packit Service d3d246
  sha512->H[7] = 0x5be0cd19137e2179;
Packit Service d3d246
Packit Service d3d246
  sha512->block_len = 0;
Packit Service d3d246
Packit Service d3d246
  sha512->data_len[0] = 0;
Packit Service d3d246
  sha512->data_len[1] = 0;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
sha512_transform (guint64      H[8],
Packit Service d3d246
                  guint8 const data[SHA2_BLOCK_LEN])
Packit Service d3d246
{
Packit Service d3d246
  gint i;
Packit Service d3d246
  gint t;
Packit Service d3d246
  guint64 a, b, c, d, e, f, g, h;
Packit Service d3d246
  guint64 M[16];
Packit Service d3d246
  guint64 W[80];
Packit Service d3d246
Packit Service d3d246
  /* SHA-512 hash computation [§6.4.2] */
Packit Service d3d246
Packit Service d3d246
  /* prepare the message schedule */
Packit Service d3d246
  for (i = 0; i < 16; i++)
Packit Service d3d246
    {
Packit Service d3d246
      gint p = i * 8;
Packit Service d3d246
Packit Service d3d246
      M[i] =
Packit Service d3d246
        ((guint64) data[p + 0] << 56) |
Packit Service d3d246
        ((guint64) data[p + 1] << 48) |
Packit Service d3d246
        ((guint64) data[p + 2] << 40) |
Packit Service d3d246
        ((guint64) data[p + 3] << 32) |
Packit Service d3d246
        ((guint64) data[p + 4] << 24) |
Packit Service d3d246
        ((guint64) data[p + 5] << 16) |
Packit Service d3d246
        ((guint64) data[p + 6] <<  8) |
Packit Service d3d246
        ((guint64) data[p + 7]      );
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  for (t = 0; t < 80; t++)
Packit Service d3d246
    if (t < 16)
Packit Service d3d246
      W[t] = M[t];
Packit Service d3d246
    else
Packit Service d3d246
      W[t] = sigma1 (W[t - 2]) + W[t - 7] + sigma0 (W[t - 15]) + W[t - 16];
Packit Service d3d246
Packit Service d3d246
  /* initialize the eight working variables */
Packit Service d3d246
  a = H[0];
Packit Service d3d246
  b = H[1];
Packit Service d3d246
  c = H[2];
Packit Service d3d246
  d = H[3];
Packit Service d3d246
  e = H[4];
Packit Service d3d246
  f = H[5];
Packit Service d3d246
  g = H[6];
Packit Service d3d246
  h = H[7];
Packit Service d3d246
Packit Service d3d246
  for (t = 0; t < 80; t++)
Packit Service d3d246
    {
Packit Service d3d246
      guint64 T1, T2;
Packit Service d3d246
Packit Service d3d246
      T1 = h + SIGMA1 (e) + Ch (e, f, g) + SHA2_K[t] + W[t];
Packit Service d3d246
      T2 = SIGMA0 (a) + Maj (a, b, c);
Packit Service d3d246
      h = g;
Packit Service d3d246
      g = f;
Packit Service d3d246
      f = e;
Packit Service d3d246
      e = d + T1;
Packit Service d3d246
      d = c;
Packit Service d3d246
      c = b;
Packit Service d3d246
      b = a;
Packit Service d3d246
      a = T1 + T2;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  /* Compute the intermediate hash value H */
Packit Service d3d246
  H[0] += a;
Packit Service d3d246
  H[1] += b;
Packit Service d3d246
  H[2] += c;
Packit Service d3d246
  H[3] += d;
Packit Service d3d246
  H[4] += e;
Packit Service d3d246
  H[5] += f;
Packit Service d3d246
  H[6] += g;
Packit Service d3d246
  H[7] += h;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
sha512_sum_update (Sha512sum    *sha512,
Packit Service d3d246
                   const guchar *buffer,
Packit Service d3d246
                   gsize         length)
Packit Service d3d246
{
Packit Service d3d246
  gsize block_left, offset = 0;
Packit Service d3d246
Packit Service d3d246
  if (length == 0)
Packit Service d3d246
    return;
Packit Service d3d246
Packit Service d3d246
  sha512->data_len[0] += length * 8;
Packit Service d3d246
  if (sha512->data_len[0] < length)
Packit Service d3d246
    sha512->data_len[1]++;
Packit Service d3d246
Packit Service d3d246
  /* try to fill current block */
Packit Service d3d246
  block_left = SHA2_BLOCK_LEN - sha512->block_len;
Packit Service d3d246
  if (block_left > 0)
Packit Service d3d246
    {
Packit Service d3d246
      gsize fill_len;
Packit Service d3d246
Packit Service d3d246
      fill_len = MIN (block_left, length);
Packit Service d3d246
      memcpy (sha512->block + sha512->block_len, buffer, fill_len);
Packit Service d3d246
      sha512->block_len += fill_len;
Packit Service d3d246
      length -= fill_len;
Packit Service d3d246
      offset += fill_len;
Packit Service d3d246
Packit Service d3d246
      if (sha512->block_len == SHA2_BLOCK_LEN)
Packit Service d3d246
        {
Packit Service d3d246
          sha512_transform (sha512->H, sha512->block);
Packit Service d3d246
          sha512->block_len = 0;
Packit Service d3d246
        }
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  /* process complete blocks */
Packit Service d3d246
  while (length >= SHA2_BLOCK_LEN)
Packit Service d3d246
    {
Packit Service d3d246
      memcpy (sha512->block, buffer + offset, SHA2_BLOCK_LEN);
Packit Service d3d246
Packit Service d3d246
      sha512_transform (sha512->H, sha512->block);
Packit Service d3d246
Packit Service d3d246
      length -= SHA2_BLOCK_LEN;
Packit Service d3d246
      offset += SHA2_BLOCK_LEN;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  /* keep remaining data for next block */
Packit Service d3d246
  if (length > 0)
Packit Service d3d246
    {
Packit Service d3d246
      memcpy (sha512->block, buffer + offset, length);
Packit Service d3d246
      sha512->block_len = length;
Packit Service d3d246
    }
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
sha512_sum_close (Sha512sum *sha512)
Packit Service d3d246
{
Packit Service d3d246
  guint l;
Packit Service d3d246
  gint zeros;
Packit Service d3d246
  guint8 pad[SHA2_BLOCK_LEN * 2] = { 0, };
Packit Service d3d246
  guint pad_len = 0;
Packit Service d3d246
  gint i;
Packit Service d3d246
Packit Service d3d246
  /* apply padding [§5.1.2] */
Packit Service d3d246
  l = sha512->block_len * 8;
Packit Service d3d246
  zeros = 896 - (l + 1);
Packit Service d3d246
Packit Service d3d246
  if (zeros < 0)
Packit Service d3d246
    zeros += 128 * 8;
Packit Service d3d246
Packit Service d3d246
  pad[0] = 0x80; /* 1000 0000 */
Packit Service d3d246
  zeros -= 7;
Packit Service d3d246
  pad_len++;
Packit Service d3d246
Packit Service d3d246
  memset (pad + pad_len, 0x00, zeros / 8);
Packit Service d3d246
  pad_len += zeros / 8;
Packit Service d3d246
  zeros = zeros % 8;
Packit Service d3d246
Packit Service d3d246
  /* put message bit length at the end of padding */
Packit Service d3d246
  PUT_UINT64 (sha512->data_len[1], pad, pad_len);
Packit Service d3d246
  pad_len += 8;
Packit Service d3d246
Packit Service d3d246
  PUT_UINT64 (sha512->data_len[0], pad, pad_len);
Packit Service d3d246
  pad_len += 8;
Packit Service d3d246
Packit Service d3d246
  /* update checksum with the padded block */
Packit Service d3d246
  sha512_sum_update (sha512, pad, pad_len);
Packit Service d3d246
Packit Service d3d246
  /* copy resulting 64-bit words into digest */
Packit Service d3d246
  for (i = 0; i < 8; i++)
Packit Service d3d246
    PUT_UINT64 (sha512->H[i], sha512->digest, i * 8);
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static gchar *
Packit Service d3d246
sha384_sum_to_string (Sha512sum *sha512)
Packit Service d3d246
{
Packit Service d3d246
  return digest_to_string (sha512->digest, SHA384_DIGEST_LEN);
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static gchar *
Packit Service d3d246
sha512_sum_to_string (Sha512sum *sha512)
Packit Service d3d246
{
Packit Service d3d246
  return digest_to_string (sha512->digest, SHA512_DIGEST_LEN);
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
sha384_sum_digest (Sha512sum *sha512,
Packit Service d3d246
                   guint8    *digest)
Packit Service d3d246
{
Packit Service d3d246
  memcpy (digest, sha512->digest, SHA384_DIGEST_LEN);
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
sha512_sum_digest (Sha512sum *sha512,
Packit Service d3d246
                   guint8    *digest)
Packit Service d3d246
{
Packit Service d3d246
  memcpy (digest, sha512->digest, SHA512_DIGEST_LEN);
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
#undef Ch
Packit Service d3d246
#undef Maj
Packit Service d3d246
#undef SHR
Packit Service d3d246
#undef ROTR
Packit Service d3d246
#undef SIGMA0
Packit Service d3d246
#undef SIGMA1
Packit Service d3d246
#undef sigma0
Packit Service d3d246
#undef sigma1
Packit Service d3d246
Packit Service d3d246
#undef PUT_UINT64
Packit Service d3d246
Packit Service d3d246
/*
Packit Service d3d246
 * Public API
Packit Service d3d246
 */
Packit Service d3d246
Packit Service d3d246
/**
Packit Service d3d246
 * g_checksum_type_get_length:
Packit Service d3d246
 * @checksum_type: a #GChecksumType
Packit Service d3d246
 *
Packit Service d3d246
 * Gets the length in bytes of digests of type @checksum_type
Packit Service d3d246
 *
Packit Service d3d246
 * Returns: the checksum length, or -1 if @checksum_type is
Packit Service d3d246
 * not supported.
Packit Service d3d246
 *
Packit Service d3d246
 * Since: 2.16
Packit Service d3d246
 */
Packit Service d3d246
gssize
Packit Service d3d246
g_checksum_type_get_length (GChecksumType checksum_type)
Packit Service d3d246
{
Packit Service d3d246
  gssize len = -1;
Packit Service d3d246
Packit Service d3d246
  switch (checksum_type)
Packit Service d3d246
    {
Packit Service d3d246
    case G_CHECKSUM_MD5:
Packit Service d3d246
      len = MD5_DIGEST_LEN;
Packit Service d3d246
      break;
Packit Service d3d246
    case G_CHECKSUM_SHA1:
Packit Service d3d246
      len = SHA1_DIGEST_LEN;
Packit Service d3d246
      break;
Packit Service d3d246
    case G_CHECKSUM_SHA256:
Packit Service d3d246
      len = SHA256_DIGEST_LEN;
Packit Service d3d246
      break;
Packit Service d3d246
    case G_CHECKSUM_SHA384:
Packit Service d3d246
      len = SHA384_DIGEST_LEN;
Packit Service d3d246
      break;
Packit Service d3d246
    case G_CHECKSUM_SHA512:
Packit Service d3d246
      len = SHA512_DIGEST_LEN;
Packit Service d3d246
      break;
Packit Service d3d246
    default:
Packit Service d3d246
      len = -1;
Packit Service d3d246
      break;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  return len;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/**
Packit Service d3d246
 * g_checksum_new:
Packit Service d3d246
 * @checksum_type: the desired type of checksum
Packit Service d3d246
 *
Packit Service d3d246
 * Creates a new #GChecksum, using the checksum algorithm @checksum_type.
Packit Service d3d246
 * If the @checksum_type is not known, %NULL is returned.
Packit Service d3d246
 * A #GChecksum can be used to compute the checksum, or digest, of an
Packit Service d3d246
 * arbitrary binary blob, using different hashing algorithms.
Packit Service d3d246
 *
Packit Service d3d246
 * A #GChecksum works by feeding a binary blob through g_checksum_update()
Packit Service d3d246
 * until there is data to be checked; the digest can then be extracted
Packit Service d3d246
 * using g_checksum_get_string(), which will return the checksum as a
Packit Service d3d246
 * hexadecimal string; or g_checksum_get_digest(), which will return a
Packit Service d3d246
 * vector of raw bytes. Once either g_checksum_get_string() or
Packit Service d3d246
 * g_checksum_get_digest() have been called on a #GChecksum, the checksum
Packit Service d3d246
 * will be closed and it won't be possible to call g_checksum_update()
Packit Service d3d246
 * on it anymore.
Packit Service d3d246
 *
Packit Service d3d246
 * Returns: (transfer full): the newly created #GChecksum, or %NULL.
Packit Service d3d246
 *   Use g_checksum_free() to free the memory allocated by it.
Packit Service d3d246
 *
Packit Service d3d246
 * Since: 2.16
Packit Service d3d246
 */
Packit Service d3d246
GChecksum *
Packit Service d3d246
g_checksum_new (GChecksumType checksum_type)
Packit Service d3d246
{
Packit Service d3d246
  GChecksum *checksum;
Packit Service d3d246
Packit Service d3d246
  if (! IS_VALID_TYPE (checksum_type))
Packit Service d3d246
    return NULL;
Packit Service d3d246
Packit Service d3d246
  checksum = g_slice_new0 (GChecksum);
Packit Service d3d246
  checksum->type = checksum_type;
Packit Service d3d246
Packit Service d3d246
  g_checksum_reset (checksum);
Packit Service d3d246
Packit Service d3d246
  return checksum;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/**
Packit Service d3d246
 * g_checksum_reset:
Packit Service d3d246
 * @checksum: the #GChecksum to reset
Packit Service d3d246
 *
Packit Service d3d246
 * Resets the state of the @checksum back to its initial state.
Packit Service d3d246
 *
Packit Service d3d246
 * Since: 2.18
Packit Service d3d246
 **/
Packit Service d3d246
void
Packit Service d3d246
g_checksum_reset (GChecksum *checksum)
Packit Service d3d246
{
Packit Service d3d246
  g_return_if_fail (checksum != NULL);
Packit Service d3d246
Packit Service d3d246
  g_free (checksum->digest_str);
Packit Service d3d246
  checksum->digest_str = NULL;
Packit Service d3d246
Packit Service d3d246
  switch (checksum->type)
Packit Service d3d246
    {
Packit Service d3d246
    case G_CHECKSUM_MD5:
Packit Service d3d246
      md5_sum_init (&(checksum->sum.md5));
Packit Service d3d246
      break;
Packit Service d3d246
    case G_CHECKSUM_SHA1:
Packit Service d3d246
      sha1_sum_init (&(checksum->sum.sha1));
Packit Service d3d246
      break;
Packit Service d3d246
    case G_CHECKSUM_SHA256:
Packit Service d3d246
      sha256_sum_init (&(checksum->sum.sha256));
Packit Service d3d246
      break;
Packit Service d3d246
    case G_CHECKSUM_SHA384:
Packit Service d3d246
      sha384_sum_init (&(checksum->sum.sha512));
Packit Service d3d246
      break;
Packit Service d3d246
    case G_CHECKSUM_SHA512:
Packit Service d3d246
      sha512_sum_init (&(checksum->sum.sha512));
Packit Service d3d246
      break;
Packit Service d3d246
    default:
Packit Service d3d246
      g_assert_not_reached ();
Packit Service d3d246
      break;
Packit Service d3d246
    }
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/**
Packit Service d3d246
 * g_checksum_copy:
Packit Service d3d246
 * @checksum: the #GChecksum to copy
Packit Service d3d246
 *
Packit Service d3d246
 * Copies a #GChecksum. If @checksum has been closed, by calling
Packit Service d3d246
 * g_checksum_get_string() or g_checksum_get_digest(), the copied
Packit Service d3d246
 * checksum will be closed as well.
Packit Service d3d246
 *
Packit Service d3d246
 * Returns: the copy of the passed #GChecksum. Use g_checksum_free()
Packit Service d3d246
 *   when finished using it.
Packit Service d3d246
 *
Packit Service d3d246
 * Since: 2.16
Packit Service d3d246
 */
Packit Service d3d246
GChecksum *
Packit Service d3d246
g_checksum_copy (const GChecksum *checksum)
Packit Service d3d246
{
Packit Service d3d246
  GChecksum *copy;
Packit Service d3d246
Packit Service d3d246
  g_return_val_if_fail (checksum != NULL, NULL);
Packit Service d3d246
Packit Service d3d246
  copy = g_slice_new (GChecksum);
Packit Service d3d246
  *copy = *checksum;
Packit Service d3d246
Packit Service d3d246
  copy->digest_str = g_strdup (checksum->digest_str);
Packit Service d3d246
Packit Service d3d246
  return copy;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/**
Packit Service d3d246
 * g_checksum_free:
Packit Service d3d246
 * @checksum: a #GChecksum
Packit Service d3d246
 *
Packit Service d3d246
 * Frees the memory allocated for @checksum.
Packit Service d3d246
 *
Packit Service d3d246
 * Since: 2.16
Packit Service d3d246
 */
Packit Service d3d246
void
Packit Service d3d246
g_checksum_free (GChecksum *checksum)
Packit Service d3d246
{
Packit Service d3d246
  if (G_LIKELY (checksum))
Packit Service d3d246
    {
Packit Service d3d246
      g_free (checksum->digest_str);
Packit Service d3d246
Packit Service d3d246
      g_slice_free (GChecksum, checksum);
Packit Service d3d246
    }
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/**
Packit Service d3d246
 * g_checksum_update:
Packit Service d3d246
 * @checksum: a #GChecksum
Packit Service d3d246
 * @data: (array length=length) (element-type guint8): buffer used to compute the checksum
Packit Service d3d246
 * @length: size of the buffer, or -1 if it is a null-terminated string.
Packit Service d3d246
 *
Packit Service d3d246
 * Feeds @data into an existing #GChecksum. The checksum must still be
Packit Service d3d246
 * open, that is g_checksum_get_string() or g_checksum_get_digest() must
Packit Service d3d246
 * not have been called on @checksum.
Packit Service d3d246
 *
Packit Service d3d246
 * Since: 2.16
Packit Service d3d246
 */
Packit Service d3d246
void
Packit Service d3d246
g_checksum_update (GChecksum    *checksum,
Packit Service d3d246
                   const guchar *data,
Packit Service d3d246
                   gssize        length)
Packit Service d3d246
{
Packit Service d3d246
  g_return_if_fail (checksum != NULL);
Packit Service d3d246
  g_return_if_fail (length == 0 || data != NULL);
Packit Service d3d246
Packit Service d3d246
  if (length < 0)
Packit Service d3d246
    length = strlen ((const gchar *) data);
Packit Service d3d246
Packit Service d3d246
  if (checksum->digest_str)
Packit Service d3d246
    {
Packit Service d3d246
      g_warning ("The checksum '%s' has been closed and cannot be updated "
Packit Service d3d246
                 "anymore.",
Packit Service d3d246
                 checksum->digest_str);
Packit Service d3d246
      return;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  switch (checksum->type)
Packit Service d3d246
    {
Packit Service d3d246
    case G_CHECKSUM_MD5:
Packit Service d3d246
      md5_sum_update (&(checksum->sum.md5), data, length);
Packit Service d3d246
      break;
Packit Service d3d246
    case G_CHECKSUM_SHA1:
Packit Service d3d246
      sha1_sum_update (&(checksum->sum.sha1), data, length);
Packit Service d3d246
      break;
Packit Service d3d246
    case G_CHECKSUM_SHA256:
Packit Service d3d246
      sha256_sum_update (&(checksum->sum.sha256), data, length);
Packit Service d3d246
      break;
Packit Service d3d246
    case G_CHECKSUM_SHA384:
Packit Service d3d246
    case G_CHECKSUM_SHA512:
Packit Service d3d246
      sha512_sum_update (&(checksum->sum.sha512), data, length);
Packit Service d3d246
      break;
Packit Service d3d246
    default:
Packit Service d3d246
      g_assert_not_reached ();
Packit Service d3d246
      break;
Packit Service d3d246
    }
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/**
Packit Service d3d246
 * g_checksum_get_string:
Packit Service d3d246
 * @checksum: a #GChecksum
Packit Service d3d246
 *
Packit Service d3d246
 * Gets the digest as an hexadecimal string.
Packit Service d3d246
 *
Packit Service d3d246
 * Once this function has been called the #GChecksum can no longer be
Packit Service d3d246
 * updated with g_checksum_update().
Packit Service d3d246
 *
Packit Service d3d246
 * The hexadecimal characters will be lower case.
Packit Service d3d246
 *
Packit Service d3d246
 * Returns: the hexadecimal representation of the checksum. The
Packit Service d3d246
 *   returned string is owned by the checksum and should not be modified
Packit Service d3d246
 *   or freed.
Packit Service d3d246
 *
Packit Service d3d246
 * Since: 2.16
Packit Service d3d246
 */
Packit Service d3d246
const gchar *
Packit Service d3d246
g_checksum_get_string (GChecksum *checksum)
Packit Service d3d246
{
Packit Service d3d246
  gchar *str = NULL;
Packit Service d3d246
Packit Service d3d246
  g_return_val_if_fail (checksum != NULL, NULL);
Packit Service d3d246
Packit Service d3d246
  if (checksum->digest_str)
Packit Service d3d246
    return checksum->digest_str;
Packit Service d3d246
Packit Service d3d246
  switch (checksum->type)
Packit Service d3d246
    {
Packit Service d3d246
    case G_CHECKSUM_MD5:
Packit Service d3d246
      md5_sum_close (&(checksum->sum.md5));
Packit Service d3d246
      str = md5_sum_to_string (&(checksum->sum.md5));
Packit Service d3d246
      break;
Packit Service d3d246
    case G_CHECKSUM_SHA1:
Packit Service d3d246
      sha1_sum_close (&(checksum->sum.sha1));
Packit Service d3d246
      str = sha1_sum_to_string (&(checksum->sum.sha1));
Packit Service d3d246
      break;
Packit Service d3d246
    case G_CHECKSUM_SHA256:
Packit Service d3d246
      sha256_sum_close (&(checksum->sum.sha256));
Packit Service d3d246
      str = sha256_sum_to_string (&(checksum->sum.sha256));
Packit Service d3d246
      break;
Packit Service d3d246
    case G_CHECKSUM_SHA384:
Packit Service d3d246
      sha512_sum_close (&(checksum->sum.sha512));
Packit Service d3d246
      str = sha384_sum_to_string (&(checksum->sum.sha512));
Packit Service d3d246
      break;
Packit Service d3d246
    case G_CHECKSUM_SHA512:
Packit Service d3d246
      sha512_sum_close (&(checksum->sum.sha512));
Packit Service d3d246
      str = sha512_sum_to_string (&(checksum->sum.sha512));
Packit Service d3d246
      break;
Packit Service d3d246
    default:
Packit Service d3d246
      g_assert_not_reached ();
Packit Service d3d246
      break;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  checksum->digest_str = str;
Packit Service d3d246
Packit Service d3d246
  return checksum->digest_str;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/**
Packit Service d3d246
 * g_checksum_get_digest: (skip)
Packit Service d3d246
 * @checksum: a #GChecksum
Packit Service d3d246
 * @buffer: output buffer
Packit Service d3d246
 * @digest_len: an inout parameter. The caller initializes it to the size of @buffer.
Packit Service d3d246
 *   After the call it contains the length of the digest.
Packit Service d3d246
 *
Packit Service d3d246
 * Gets the digest from @checksum as a raw binary vector and places it
Packit Service d3d246
 * into @buffer. The size of the digest depends on the type of checksum.
Packit Service d3d246
 *
Packit Service d3d246
 * Once this function has been called, the #GChecksum is closed and can
Packit Service d3d246
 * no longer be updated with g_checksum_update().
Packit Service d3d246
 *
Packit Service d3d246
 * Since: 2.16
Packit Service d3d246
 */
Packit Service d3d246
void
Packit Service d3d246
g_checksum_get_digest (GChecksum  *checksum,
Packit Service d3d246
                       guint8     *buffer,
Packit Service d3d246
                       gsize      *digest_len)
Packit Service d3d246
{
Packit Service d3d246
  gboolean checksum_open = FALSE;
Packit Service d3d246
  gchar *str = NULL;
Packit Service d3d246
  gsize len;
Packit Service d3d246
Packit Service d3d246
  g_return_if_fail (checksum != NULL);
Packit Service d3d246
Packit Service d3d246
  len = g_checksum_type_get_length (checksum->type);
Packit Service d3d246
  g_return_if_fail (*digest_len >= len);
Packit Service d3d246
Packit Service d3d246
  checksum_open = !!(checksum->digest_str == NULL);
Packit Service d3d246
Packit Service d3d246
  switch (checksum->type)
Packit Service d3d246
    {
Packit Service d3d246
    case G_CHECKSUM_MD5:
Packit Service d3d246
      if (checksum_open)
Packit Service d3d246
        {
Packit Service d3d246
          md5_sum_close (&(checksum->sum.md5));
Packit Service d3d246
          str = md5_sum_to_string (&(checksum->sum.md5));
Packit Service d3d246
        }
Packit Service d3d246
      md5_sum_digest (&(checksum->sum.md5), buffer);
Packit Service d3d246
      break;
Packit Service d3d246
    case G_CHECKSUM_SHA1:
Packit Service d3d246
      if (checksum_open)
Packit Service d3d246
        {
Packit Service d3d246
          sha1_sum_close (&(checksum->sum.sha1));
Packit Service d3d246
          str = sha1_sum_to_string (&(checksum->sum.sha1));
Packit Service d3d246
        }
Packit Service d3d246
      sha1_sum_digest (&(checksum->sum.sha1), buffer);
Packit Service d3d246
      break;
Packit Service d3d246
    case G_CHECKSUM_SHA256:
Packit Service d3d246
      if (checksum_open)
Packit Service d3d246
        {
Packit Service d3d246
          sha256_sum_close (&(checksum->sum.sha256));
Packit Service d3d246
          str = sha256_sum_to_string (&(checksum->sum.sha256));
Packit Service d3d246
        }
Packit Service d3d246
      sha256_sum_digest (&(checksum->sum.sha256), buffer);
Packit Service d3d246
      break;
Packit Service d3d246
    case G_CHECKSUM_SHA384:
Packit Service d3d246
      if (checksum_open)
Packit Service d3d246
        {
Packit Service d3d246
          sha512_sum_close (&(checksum->sum.sha512));
Packit Service d3d246
          str = sha384_sum_to_string (&(checksum->sum.sha512));
Packit Service d3d246
        }
Packit Service d3d246
      sha384_sum_digest (&(checksum->sum.sha512), buffer);
Packit Service d3d246
      break;
Packit Service d3d246
    case G_CHECKSUM_SHA512:
Packit Service d3d246
      if (checksum_open)
Packit Service d3d246
        {
Packit Service d3d246
          sha512_sum_close (&(checksum->sum.sha512));
Packit Service d3d246
          str = sha512_sum_to_string (&(checksum->sum.sha512));
Packit Service d3d246
        }
Packit Service d3d246
      sha512_sum_digest (&(checksum->sum.sha512), buffer);
Packit Service d3d246
      break;
Packit Service d3d246
    default:
Packit Service d3d246
      g_assert_not_reached ();
Packit Service d3d246
      break;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  if (str)
Packit Service d3d246
    checksum->digest_str = str;
Packit Service d3d246
Packit Service d3d246
  *digest_len = len;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/**
Packit Service d3d246
 * g_compute_checksum_for_data:
Packit Service d3d246
 * @checksum_type: a #GChecksumType
Packit Service d3d246
 * @data: (array length=length) (element-type guint8): binary blob to compute the digest of
Packit Service d3d246
 * @length: length of @data
Packit Service d3d246
 *
Packit Service d3d246
 * Computes the checksum for a binary @data of @length. This is a
Packit Service d3d246
 * convenience wrapper for g_checksum_new(), g_checksum_get_string()
Packit Service d3d246
 * and g_checksum_free().
Packit Service d3d246
 *
Packit Service d3d246
 * The hexadecimal string returned will be in lower case.
Packit Service d3d246
 *
Packit Service d3d246
 * Returns: the digest of the binary data as a string in hexadecimal.
Packit Service d3d246
 *   The returned string should be freed with g_free() when done using it.
Packit Service d3d246
 *
Packit Service d3d246
 * Since: 2.16
Packit Service d3d246
 */
Packit Service d3d246
gchar *
Packit Service d3d246
g_compute_checksum_for_data (GChecksumType  checksum_type,
Packit Service d3d246
                             const guchar  *data,
Packit Service d3d246
                             gsize          length)
Packit Service d3d246
{
Packit Service d3d246
  GChecksum *checksum;
Packit Service d3d246
  gchar *retval;
Packit Service d3d246
Packit Service d3d246
  g_return_val_if_fail (IS_VALID_TYPE (checksum_type), NULL);
Packit Service d3d246
  g_return_val_if_fail (length == 0 || data != NULL, NULL);
Packit Service d3d246
Packit Service d3d246
  checksum = g_checksum_new (checksum_type);
Packit Service d3d246
  if (!checksum)
Packit Service d3d246
    return NULL;
Packit Service d3d246
Packit Service d3d246
  g_checksum_update (checksum, data, length);
Packit Service d3d246
  retval = g_strdup (g_checksum_get_string (checksum));
Packit Service d3d246
  g_checksum_free (checksum);
Packit Service d3d246
Packit Service d3d246
  return retval;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/**
Packit Service d3d246
 * g_compute_checksum_for_string:
Packit Service d3d246
 * @checksum_type: a #GChecksumType
Packit Service d3d246
 * @str: the string to compute the checksum of
Packit Service d3d246
 * @length: the length of the string, or -1 if the string is null-terminated.
Packit Service d3d246
 *
Packit Service d3d246
 * Computes the checksum of a string.
Packit Service d3d246
 *
Packit Service d3d246
 * The hexadecimal string returned will be in lower case.
Packit Service d3d246
 *
Packit Service d3d246
 * Returns: the checksum as a hexadecimal string. The returned string
Packit Service d3d246
 *   should be freed with g_free() when done using it.
Packit Service d3d246
 *
Packit Service d3d246
 * Since: 2.16
Packit Service d3d246
 */
Packit Service d3d246
gchar *
Packit Service d3d246
g_compute_checksum_for_string (GChecksumType  checksum_type,
Packit Service d3d246
                               const gchar   *str,
Packit Service d3d246
                               gssize         length)
Packit Service d3d246
{
Packit Service d3d246
  g_return_val_if_fail (IS_VALID_TYPE (checksum_type), NULL);
Packit Service d3d246
  g_return_val_if_fail (length == 0 || str != NULL, NULL);
Packit Service d3d246
Packit Service d3d246
  if (length < 0)
Packit Service d3d246
    length = strlen (str);
Packit Service d3d246
Packit Service d3d246
  return g_compute_checksum_for_data (checksum_type, (const guchar *) str, length);
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/**
Packit Service d3d246
 * g_compute_checksum_for_bytes:
Packit Service d3d246
 * @checksum_type: a #GChecksumType
Packit Service d3d246
 * @data: binary blob to compute the digest of
Packit Service d3d246
 *
Packit Service d3d246
 * Computes the checksum for a binary @data. This is a
Packit Service d3d246
 * convenience wrapper for g_checksum_new(), g_checksum_get_string()
Packit Service d3d246
 * and g_checksum_free().
Packit Service d3d246
 *
Packit Service d3d246
 * The hexadecimal string returned will be in lower case.
Packit Service d3d246
 *
Packit Service d3d246
 * Returns: the digest of the binary data as a string in hexadecimal.
Packit Service d3d246
 *   The returned string should be freed with g_free() when done using it.
Packit Service d3d246
 *
Packit Service d3d246
 * Since: 2.34
Packit Service d3d246
 */
Packit Service d3d246
gchar *
Packit Service d3d246
g_compute_checksum_for_bytes (GChecksumType  checksum_type,
Packit Service d3d246
                              GBytes        *data)
Packit Service d3d246
{
Packit Service d3d246
  gconstpointer byte_data;
Packit Service d3d246
  gsize length;
Packit Service d3d246
Packit Service d3d246
  g_return_val_if_fail (IS_VALID_TYPE (checksum_type), NULL);
Packit Service d3d246
  g_return_val_if_fail (data != NULL, NULL);
Packit Service d3d246
Packit Service d3d246
  byte_data = g_bytes_get_data (data, &length);
Packit Service d3d246
  return g_compute_checksum_for_data (checksum_type, byte_data, length);
Packit Service d3d246
}