]> git.saurik.com Git - apt.git/commitdiff
merge lp:~mvo/apt/sha512-template to add support for sha512
authorMichael Vogt <michael.vogt@ubuntu.com>
Wed, 8 Jun 2011 10:03:34 +0000 (12:03 +0200)
committerMichael Vogt <michael.vogt@ubuntu.com>
Wed, 8 Jun 2011 10:03:34 +0000 (12:03 +0200)
28 files changed:
apt-pkg/acquire-item.cc
apt-pkg/acquire-method.cc
apt-pkg/acquire-method.h
apt-pkg/contrib/hashes.cc
apt-pkg/contrib/hashes.h
apt-pkg/contrib/hashsum_template.h [new file with mode: 0644]
apt-pkg/contrib/md5.cc
apt-pkg/contrib/md5.h
apt-pkg/contrib/sha1.cc
apt-pkg/contrib/sha1.h
apt-pkg/contrib/sha2.cc [new file with mode: 0644]
apt-pkg/contrib/sha2.h [new file with mode: 0644]
apt-pkg/contrib/sha256.cc [deleted file]
apt-pkg/contrib/sha256.h
apt-pkg/contrib/sha2_internal.cc [new file with mode: 0644]
apt-pkg/contrib/sha2_internal.h [new file with mode: 0644]
apt-pkg/deb/debrecords.cc
apt-pkg/deb/debrecords.h
apt-pkg/makefile
apt-pkg/pkgrecords.h
apt-pkg/tagfile.cc
cmdline/apt-get.cc
debian/changelog
ftparchive/cachedb.cc
ftparchive/cachedb.h
ftparchive/writer.cc
ftparchive/writer.h
test/hash.cc

index 6785b4e1be9413d1d80787fa340cbed4f5e0ec82..36abe0ac3266a1eab8d3002c3a297d122602b66c 100644 (file)
@@ -1682,6 +1682,8 @@ bool pkgAcqArchive::QueueNext()
       string PkgFile = Parse.FileName();
       if (ForceHash.empty() == false)
       {
+        if(stringcasecmp(ForceHash, "sha512") == 0)
+           ExpectedHash = HashString("SHA512", Parse.SHA512Hash());
         if(stringcasecmp(ForceHash, "sha256") == 0)
            ExpectedHash = HashString("SHA256", Parse.SHA256Hash());
         else if (stringcasecmp(ForceHash, "sha1") == 0)
@@ -1692,7 +1694,9 @@ bool pkgAcqArchive::QueueNext()
       else
       {
         string Hash;
-        if ((Hash = Parse.SHA256Hash()).empty() == false)
+        if ((Hash = Parse.SHA512Hash()).empty() == false)
+           ExpectedHash = HashString("SHA512", Hash);
+        else if ((Hash = Parse.SHA256Hash()).empty() == false)
            ExpectedHash = HashString("SHA256", Hash);
         else if ((Hash = Parse.SHA1Hash()).empty() == false)
            ExpectedHash = HashString("SHA1", Hash);
index e9e102488739df093d096e32800244692fe43b4d..8c353beb2ac0c637565da77e0773e50921d946fd 100644 (file)
@@ -166,6 +166,8 @@ void pkgAcqMethod::URIDone(FetchResult &Res, FetchResult *Alt)
       std::cout << "SHA1-Hash: " << Res.SHA1Sum << "\n";
    if (Res.SHA256Sum.empty() == false)
       std::cout << "SHA256-Hash: " << Res.SHA256Sum << "\n";
+   if (Res.SHA512Sum.empty() == false)
+      std::cout << "SHA512-Hash: " << Res.SHA512Sum << "\n";
    if (UsedMirror.empty() == false)
       std::cout << "UsedMirror: " << UsedMirror << "\n";
    if (Res.GPGVOutput.empty() == false)
@@ -199,7 +201,9 @@ void pkgAcqMethod::URIDone(FetchResult &Res, FetchResult *Alt)
         std::cout << "Alt-SHA1-Hash: " << Alt->SHA1Sum << "\n";
       if (Alt->SHA256Sum.empty() == false)
         std::cout << "Alt-SHA256-Hash: " << Alt->SHA256Sum << "\n";
-
+      if (Alt->SHA512Sum.empty() == false)
+         std::cout << "Alt-SHA512-Hash: " << Alt->SHA512Sum << "\n";
+     
       if (Alt->IMSHit == true)
         std::cout << "Alt-IMS-Hit: true\n";
    }
@@ -460,5 +464,6 @@ void pkgAcqMethod::FetchResult::TakeHashes(Hashes &Hash)
    MD5Sum = Hash.MD5.Result();
    SHA1Sum = Hash.SHA1.Result();
    SHA256Sum = Hash.SHA256.Result();
+   SHA512Sum = Hash.SHA512.Result();
 }
                                                                        /*}}}*/
index 72efa8065491e644370363a2fa7e97f1797c5f67..2d0fa4590d6fc14967139303e03a2821f9ad4fe1 100644 (file)
@@ -46,6 +46,7 @@ class pkgAcqMethod
       string MD5Sum;
       string SHA1Sum;
       string SHA256Sum;
+      string SHA512Sum;
       vector<string> GPGVOutput;
       time_t LastModified;
       bool IMSHit;
index 985d89d903ea502c448d28aa2bb819c121d8eb64..66ae33146403b44bfd71ffc73af02ec741674843 100644 (file)
@@ -23,7 +23,7 @@
 
 const char* HashString::_SupportedHashes[] = 
 {
-   "SHA256", "SHA1", "MD5Sum", NULL
+   "SHA512", "SHA256", "SHA1", "MD5Sum", NULL
 };
 
 HashString::HashString()
@@ -57,6 +57,7 @@ bool HashString::VerifyFile(string filename) const                    /*{{{*/
    MD5Summation MD5;
    SHA1Summation SHA1;
    SHA256Summation SHA256;
+   SHA256Summation SHA512;
    string fileHash;
 
    FileFd Fd(filename, FileFd::ReadOnly);
@@ -75,6 +76,11 @@ bool HashString::VerifyFile(string filename) const                   /*{{{*/
       SHA256.AddFD(Fd.Fd(), Fd.Size());
       fileHash = (string)SHA256.Result();
    }
+   else if (Type == "SHA512") 
+   {
+      SHA512.AddFD(Fd.Fd(), Fd.Size());
+      fileHash = (string)SHA512.Result();
+   }
    Fd.Close();
 
    if(_config->FindB("Debug::Hashes",false) == true)
@@ -119,6 +125,7 @@ bool Hashes::AddFD(int Fd,unsigned long Size)
       MD5.Add(Buf,Res);
       SHA1.Add(Buf,Res);
       SHA256.Add(Buf,Res);
+      SHA512.Add(Buf,Res);
    }
    return true;
 }
index 264f7fe904434d2cd2dd995311405cda3d6f9291..4b6a08b1f25e91cb86c4ae77d65440aee76e3b5b 100644 (file)
@@ -16,7 +16,7 @@
 
 #include <apt-pkg/md5.h>
 #include <apt-pkg/sha1.h>
-#include <apt-pkg/sha256.h>
+#include <apt-pkg/sha2.h>
 
 #include <algorithm>
 #include <vector>
@@ -60,10 +60,11 @@ class Hashes
    MD5Summation MD5;
    SHA1Summation SHA1;
    SHA256Summation SHA256;
+   SHA512Summation SHA512;
    
    inline bool Add(const unsigned char *Data,unsigned long Size)
    {
-      return MD5.Add(Data,Size) && SHA1.Add(Data,Size) && SHA256.Add(Data,Size);
+      return MD5.Add(Data,Size) && SHA1.Add(Data,Size) && SHA256.Add(Data,Size) && SHA512.Add(Data,Size);
    };
    inline bool Add(const char *Data) {return Add((unsigned char *)Data,strlen(Data));};
    bool AddFD(int Fd,unsigned long Size);
diff --git a/apt-pkg/contrib/hashsum_template.h b/apt-pkg/contrib/hashsum_template.h
new file mode 100644 (file)
index 0000000..7667baf
--- /dev/null
@@ -0,0 +1,87 @@
+// -*- mode: cpp; mode: fold -*-
+// Description                                                          /*{{{*/
+// $Id: hashsum_template.h,v 1.3 2001/05/07 05:05:47 jgg Exp $
+/* ######################################################################
+
+   HashSumValueTemplate - Generic Storage for a hash value
+   
+   ##################################################################### */
+                                                                        /*}}}*/
+#ifndef APTPKG_HASHSUM_TEMPLATE_H
+#define APTPKG_HASHSUM_TEMPLATE_H
+
+#include <string>
+#include <cstring>
+#include <algorithm>
+#include <stdint.h>
+
+using std::string;
+using std::min;
+
+template<int N>
+class HashSumValue
+{
+   unsigned char Sum[N/8];
+   
+   public:
+
+   // Accessors
+   bool operator ==(const HashSumValue &rhs) const
+   {
+      return memcmp(Sum,rhs.Sum,sizeof(Sum)) == 0;
+   }; 
+
+   string Value() const
+   {
+      char Conv[16] =
+      { '0','1','2','3','4','5','6','7','8','9','a','b',
+        'c','d','e','f'
+      };
+      char Result[((N/8)*2)+1];
+      Result[(N/8)*2] = 0;
+      
+      // Convert each char into two letters
+      int J = 0;
+      int I = 0;
+      for (; I != (N/8)*2; J++,I += 2)
+      {
+         Result[I] = Conv[Sum[J] >> 4];
+         Result[I + 1] = Conv[Sum[J] & 0xF];
+      }
+      return string(Result);
+   };
+   
+   inline void Value(unsigned char S[N/8])
+   {
+      for (int I = 0; I != sizeof(Sum); I++) 
+         S[I] = Sum[I];
+   };
+
+   inline operator string() const 
+   {
+      return Value();
+   };
+
+   bool Set(string Str) 
+   {
+      return Hex2Num(Str,Sum,sizeof(Sum));
+   };
+
+   inline void Set(unsigned char S[N/8]) 
+   {
+      for (int I = 0; I != sizeof(Sum); I++) 
+         Sum[I] = S[I];
+   };
+
+   HashSumValue(string Str) 
+   {
+         memset(Sum,0,sizeof(Sum));
+         Set(Str);
+   }
+   HashSumValue()
+   {
+      memset(Sum,0,sizeof(Sum));
+   }
+};
+
+#endif
index c0fa8493dff2e161099c57ad2ac7377a0006139f..6c60ffd743a69bfad91b7ce66031be367e34a831 100644 (file)
@@ -165,61 +165,6 @@ static void MD5Transform(uint32_t buf[4], uint32_t const in[16])
    buf[3] += d;
 }
                                                                        /*}}}*/
-// MD5SumValue::MD5SumValue - Constructs the summation from a string   /*{{{*/
-// ---------------------------------------------------------------------
-/* The string form of a MD5 is a 32 character hex number */
-MD5SumValue::MD5SumValue(string Str)
-{
-   memset(Sum,0,sizeof(Sum));
-   Set(Str);
-}
-                                                                       /*}}}*/
-// MD5SumValue::MD5SumValue - Default constructor                      /*{{{*/
-// ---------------------------------------------------------------------
-/* Sets the value to 0 */
-MD5SumValue::MD5SumValue()
-{
-   memset(Sum,0,sizeof(Sum));
-}
-                                                                       /*}}}*/
-// MD5SumValue::Set - Set the sum from a string                                /*{{{*/
-// ---------------------------------------------------------------------
-/* Converts the hex string into a set of chars */
-bool MD5SumValue::Set(string Str)
-{
-   return Hex2Num(Str,Sum,sizeof(Sum));
-}
-                                                                       /*}}}*/
-// MD5SumValue::Value - Convert the number into a string               /*{{{*/
-// ---------------------------------------------------------------------
-/* Converts the set of chars into a hex string in lower case */
-string MD5SumValue::Value() const
-{
-   char Conv[16] = {'0','1','2','3','4','5','6','7','8','9','a','b',
-                    'c','d','e','f'};
-   char Result[33];
-   Result[32] = 0;
-   
-   // Convert each char into two letters
-   int J = 0;
-   int I = 0;
-   for (; I != 32; J++, I += 2)
-   {
-      Result[I] = Conv[Sum[J] >> 4];
-      Result[I + 1] = Conv[Sum[J] & 0xF];
-   } 
-
-   return string(Result);
-}
-                                                                       /*}}}*/
-// MD5SumValue::operator == - Comparitor                               /*{{{*/
-// ---------------------------------------------------------------------
-/* Call memcmp on the buffer */
-bool MD5SumValue::operator ==(const MD5SumValue &rhs) const
-{
-   return memcmp(Sum,rhs.Sum,sizeof(Sum)) == 0;
-}
-                                                                       /*}}}*/
 // MD5Summation::MD5Summation - Initialize the summer                  /*{{{*/
 // ---------------------------------------------------------------------
 /* This assigns the deep magic initial values */
@@ -353,7 +298,7 @@ MD5SumValue MD5Summation::Result()
    }
    
    MD5SumValue V;
-   memcpy(V.Sum,buf,16);
+   V.Set((char *)buf);
    return V;
 }
                                                                        /*}}}*/
index 96c8975b46f6cc165b257f889bd1bb2f56ac5168..9cc88cfbe6811b7adfc484cb99c260eea712b027 100644 (file)
 using std::string;
 using std::min;
 
-class MD5Summation;
+#include "hashsum_template.h"
 
-class MD5SumValue
-{
-   friend class MD5Summation;
-   unsigned char Sum[4*4];
-   
-   public:
-
-   // Accessors
-   bool operator ==(const MD5SumValue &rhs) const; 
-   string Value() const;
-   inline void Value(unsigned char S[16]) 
-         {for (int I = 0; I != sizeof(Sum); I++) S[I] = Sum[I];};
-   inline operator string() const {return Value();};
-   bool Set(string Str);
-   inline void Set(unsigned char S[16]) 
-         {for (int I = 0; I != sizeof(Sum); I++) Sum[I] = S[I];};
+class MD5Summation;
 
-   MD5SumValue(string Str);
-   MD5SumValue();
-};
+typedef HashSumValue<128> MD5SumValue;
 
 class MD5Summation
 {
index eae52d52f6341ea22abdb3ee3493bd48c3407316..0b1c16dc3af3ae111cc30715500fbdd006a1911b 100644 (file)
@@ -178,67 +178,6 @@ static void SHA1Transform(uint32_t state[5],uint8_t const buffer[64])
 }
                                                                        /*}}}*/
 
-// SHA1SumValue::SHA1SumValue - Constructs the summation from a string  /*{{{*/
-// ---------------------------------------------------------------------
-/* The string form of a SHA1 is a 40 character hex number */
-SHA1SumValue::SHA1SumValue(string Str)
-{
-   memset(Sum,0,sizeof(Sum));
-   Set(Str);
-}
-
-                                                                       /*}}} */
-// SHA1SumValue::SHA1SumValue - Default constructor                     /*{{{*/
-// ---------------------------------------------------------------------
-/* Sets the value to 0 */
-SHA1SumValue::SHA1SumValue()
-{
-   memset(Sum,0,sizeof(Sum));
-}
-
-                                                                       /*}}} */
-// SHA1SumValue::Set - Set the sum from a string                        /*{{{*/
-// ---------------------------------------------------------------------
-/* Converts the hex string into a set of chars */
-bool SHA1SumValue::Set(string Str)
-{
-   return Hex2Num(Str,Sum,sizeof(Sum));
-}
-
-                                                                       /*}}} */
-// SHA1SumValue::Value - Convert the number into a string               /*{{{*/
-// ---------------------------------------------------------------------
-/* Converts the set of chars into a hex string in lower case */
-string SHA1SumValue::Value() const
-{
-   char Conv[16] =
-      { '0','1','2','3','4','5','6','7','8','9','a','b',
-      'c','d','e','f'
-   };
-   char Result[41];
-   Result[40] = 0;
-
-   // Convert each char into two letters
-   int J = 0;
-   int I = 0;
-   for (; I != 40; J++,I += 2)
-   {
-      Result[I] = Conv[Sum[J] >> 4];
-      Result[I + 1] = Conv[Sum[J] & 0xF];
-   }
-
-   return string(Result);
-}
-
-                                                                       /*}}} */
-// SHA1SumValue::operator == - Comparator                               /*{{{*/
-// ---------------------------------------------------------------------
-/* Call memcmp on the buffer */
-bool SHA1SumValue::operator == (const SHA1SumValue & rhs) const
-{
-   return memcmp(Sum,rhs.Sum,sizeof(Sum)) == 0;
-}
-                                                                       /*}}}*/
 // SHA1Summation::SHA1Summation - Constructor                           /*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -290,11 +229,13 @@ SHA1SumValue SHA1Summation::Result()
 
    // Transfer over the result
    SHA1SumValue Value;
+   char res[20];
    for (unsigned i = 0; i < 20; i++)
    {
-      Value.Sum[i] = (unsigned char)
+      res[i] = (unsigned char)
         ((state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
    }
+   Value.Set(res);
    return Value;
 }
                                                                        /*}}}*/
index 8ddd889f18a22a70b2ac9015e4772fbc195ce3a1..e7683fa7b034527d8742421971e25755dc087917 100644 (file)
 using std::string;
 using std::min;
 
-class SHA1Summation;
+#include "hashsum_template.h"
 
-class SHA1SumValue
-{
-   friend class SHA1Summation;
-   unsigned char Sum[20];
-   
-   public:
-
-   // Accessors
-   bool operator ==(const SHA1SumValue &rhs) const; 
-   string Value() const;
-   inline void Value(unsigned char S[20])
-         {for (int I = 0; I != sizeof(Sum); I++) S[I] = Sum[I];};
-   inline operator string() const {return Value();};
-   bool Set(string Str);
-   inline void Set(unsigned char S[20]) 
-         {for (int I = 0; I != sizeof(Sum); I++) Sum[I] = S[I];};
+class SHA1Summation;
 
-   SHA1SumValue(string Str);
-   SHA1SumValue();
-};
+typedef  HashSumValue<160> SHA1SumValue;
 
 class SHA1Summation
 {
diff --git a/apt-pkg/contrib/sha2.cc b/apt-pkg/contrib/sha2.cc
new file mode 100644 (file)
index 0000000..4604d31
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Cryptographic API.                                                  {{{
+ *
+ * SHA-512, as specified in
+ * http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */                                                                    /*}}}*/
+
+#ifdef __GNUG__
+#pragma implementation "apt-pkg/sha2.h"
+#endif
+
+#include <apt-pkg/sha2.h>
+#include <apt-pkg/strutl.h>
+
+// SHA2Summation::AddFD - Add content of file into the checksum      /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool SHA2SummationBase::AddFD(int Fd,unsigned long Size){
+   unsigned char Buf[64 * 64];
+   int Res = 0;
+   int ToEOF = (Size == 0);
+   while (Size != 0 || ToEOF)
+   {
+      unsigned n = sizeof(Buf);
+      if (!ToEOF) n = min(Size,(unsigned long)n);
+      Res = read(Fd,Buf,n);
+      if (Res < 0 || (!ToEOF && (unsigned) Res != n)) // error, or short read
+         return false;
+      if (ToEOF && Res == 0) // EOF
+         break;
+      Size -= Res;
+      Add(Buf,Res);
+   }
+   return true;
+}
+                                                                       /*}}}*/
+
diff --git a/apt-pkg/contrib/sha2.h b/apt-pkg/contrib/sha2.h
new file mode 100644 (file)
index 0000000..bd54725
--- /dev/null
@@ -0,0 +1,114 @@
+// -*- mode: cpp; mode: fold -*-
+// Description                                                          /*{{{*/
+// $Id: sha512.h,v 1.3 2001/05/07 05:05:47 jgg Exp $
+/* ######################################################################
+
+   SHA{512,256}SumValue - Storage for a SHA-{512,256} hash.
+   SHA{512,256}Summation - SHA-{512,256} Secure Hash Algorithm.
+   
+   This is a C++ interface to a set of SHA{512,256}Sum functions, that mirrors
+   the equivalent MD5 & SHA1 classes. 
+
+   ##################################################################### */
+                                                                        /*}}}*/
+#ifndef APTPKG_SHA2_H
+#define APTPKG_SHA2_H
+
+#include <string>
+#include <cstring>
+#include <algorithm>
+#include <stdint.h>
+
+#include "sha2_internal.h"
+#include "hashsum_template.h"
+
+using std::string;
+using std::min;
+
+class SHA512Summation;
+class SHA256Summation;
+
+typedef HashSumValue<512> SHA512SumValue;
+typedef HashSumValue<256> SHA256SumValue;
+
+class SHA2SummationBase
+{
+ protected:
+   bool Done;
+ public:
+   virtual bool Add(const unsigned char *inbuf,unsigned long inlen) = 0;
+   virtual bool AddFD(int Fd,unsigned long Size);
+
+   inline bool Add(const char *Data) 
+   {
+      return Add((unsigned char *)Data,strlen(Data));
+   };
+   inline bool Add(const unsigned char *Beg,const unsigned char *End) 
+   {
+      return Add(Beg,End-Beg);
+   };
+   void Result();
+};
+
+class SHA256Summation : public SHA2SummationBase
+{
+   SHA256_CTX ctx;
+   unsigned char Sum[32];
+
+   public:
+   virtual bool Add(const unsigned char *inbuf, unsigned long len)
+   {
+      if (Done) 
+         return false;
+      SHA256_Update(&ctx, inbuf, len);
+      return true;
+   };
+   SHA256SumValue Result()
+   {
+      if (!Done) {
+         SHA256_Final(Sum, &ctx);
+         Done = true;
+      }
+      SHA256SumValue res;
+      res.Set(Sum);
+      return res;
+   };
+   SHA256Summation() 
+   {
+      SHA256_Init(&ctx);
+      Done = false;
+   };
+};
+
+class SHA512Summation : public SHA2SummationBase
+{
+   SHA512_CTX ctx;
+   unsigned char Sum[64];
+
+   public:
+   virtual bool Add(const unsigned char *inbuf, unsigned long len)
+   {
+      if (Done) 
+         return false;
+      SHA512_Update(&ctx, inbuf, len);
+      return true;
+   };
+   SHA512SumValue Result()
+   {
+      if (!Done) {
+         SHA512_Final(Sum, &ctx);
+         Done = true;
+      }
+      SHA512SumValue res;
+      res.Set(Sum);
+      return res;
+   };
+   SHA512Summation()
+   {
+      SHA512_Init(&ctx);
+      Done = false;
+   };
+};
+
+
+#endif
diff --git a/apt-pkg/contrib/sha256.cc b/apt-pkg/contrib/sha256.cc
deleted file mode 100644 (file)
index e380c13..0000000
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Cryptographic API.                                                  {{{
- *
- * SHA-256, as specified in
- * http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf
- *
- * SHA-256 code by Jean-Luc Cooke <jlcooke@certainkey.com>.
- *
- * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
- * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- *
- * Ported from the Linux kernel to Apt by Anthony Towns <ajt@debian.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option) 
- * any later version.
- *
- */                                                                    /*}}}*/
-
-#ifdef __GNUG__
-#pragma implementation "apt-pkg/sha256.h"
-#endif
-
-
-#define SHA256_DIGEST_SIZE      32
-#define SHA256_HMAC_BLOCK_SIZE  64
-
-#define ror32(value,bits) (((value) >> (bits)) | ((value) << (32 - (bits))))
-
-#include <apt-pkg/sha256.h>
-#include <apt-pkg/strutl.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <arpa/inet.h>
-
-typedef uint32_t u32;
-typedef uint8_t  u8;
-
-static inline u32 Ch(u32 x, u32 y, u32 z)
-{
-        return z ^ (x & (y ^ z));
-}
-
-static inline u32 Maj(u32 x, u32 y, u32 z)
-{
-        return (x & y) | (z & (x | y));
-}
-
-#define e0(x)       (ror32(x, 2) ^ ror32(x,13) ^ ror32(x,22))
-#define e1(x)       (ror32(x, 6) ^ ror32(x,11) ^ ror32(x,25))
-#define s0(x)       (ror32(x, 7) ^ ror32(x,18) ^ (x >> 3))
-#define s1(x)       (ror32(x,17) ^ ror32(x,19) ^ (x >> 10))
-
-#define H0         0x6a09e667
-#define H1         0xbb67ae85
-#define H2         0x3c6ef372
-#define H3         0xa54ff53a
-#define H4         0x510e527f
-#define H5         0x9b05688c
-#define H6         0x1f83d9ab
-#define H7         0x5be0cd19
-
-static inline void LOAD_OP(int I, u32 *W, const u8 *input)             /*{{{*/
-{
-       W[I] = (  ((u32) input[I * 4 + 0] << 24)
-               | ((u32) input[I * 4 + 1] << 16)
-               | ((u32) input[I * 4 + 2] << 8)
-               | ((u32) input[I * 4 + 3]));
-}
-                                                                       /*}}}*/
-static inline void BLEND_OP(int I, u32 *W)
-{
-        W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
-}
-
-static void sha256_transform(u32 *state, const u8 *input)              /*{{{*/
-{
-        u32 a, b, c, d, e, f, g, h, t1, t2;
-        u32 W[64];
-        int i;
-
-        /* load the input */
-        for (i = 0; i < 16; i++)
-                LOAD_OP(i, W, input);
-
-        /* now blend */
-        for (i = 16; i < 64; i++)
-                BLEND_OP(i, W);
-    
-        /* load the state into our registers */
-        a=state[0];  b=state[1];  c=state[2];  d=state[3];
-        e=state[4];  f=state[5];  g=state[6];  h=state[7];
-
-        /* now iterate */
-        t1 = h + e1(e) + Ch(e,f,g) + 0x428a2f98 + W[ 0];
-        t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
-        t1 = g + e1(d) + Ch(d,e,f) + 0x71374491 + W[ 1];
-        t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
-        t1 = f + e1(c) + Ch(c,d,e) + 0xb5c0fbcf + W[ 2];
-        t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
-        t1 = e + e1(b) + Ch(b,c,d) + 0xe9b5dba5 + W[ 3];
-        t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
-        t1 = d + e1(a) + Ch(a,b,c) + 0x3956c25b + W[ 4];
-        t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
-        t1 = c + e1(h) + Ch(h,a,b) + 0x59f111f1 + W[ 5];
-        t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
-        t1 = b + e1(g) + Ch(g,h,a) + 0x923f82a4 + W[ 6];
-        t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
-        t1 = a + e1(f) + Ch(f,g,h) + 0xab1c5ed5 + W[ 7];
-        t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
-
-        t1 = h + e1(e) + Ch(e,f,g) + 0xd807aa98 + W[ 8];
-        t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
-        t1 = g + e1(d) + Ch(d,e,f) + 0x12835b01 + W[ 9];
-        t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
-        t1 = f + e1(c) + Ch(c,d,e) + 0x243185be + W[10];
-        t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
-        t1 = e + e1(b) + Ch(b,c,d) + 0x550c7dc3 + W[11];
-        t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
-        t1 = d + e1(a) + Ch(a,b,c) + 0x72be5d74 + W[12];
-        t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
-        t1 = c + e1(h) + Ch(h,a,b) + 0x80deb1fe + W[13];
-        t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
-        t1 = b + e1(g) + Ch(g,h,a) + 0x9bdc06a7 + W[14];
-        t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
-        t1 = a + e1(f) + Ch(f,g,h) + 0xc19bf174 + W[15];
-        t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
-
-        t1 = h + e1(e) + Ch(e,f,g) + 0xe49b69c1 + W[16];
-        t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
-        t1 = g + e1(d) + Ch(d,e,f) + 0xefbe4786 + W[17];
-        t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
-        t1 = f + e1(c) + Ch(c,d,e) + 0x0fc19dc6 + W[18];
-        t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
-        t1 = e + e1(b) + Ch(b,c,d) + 0x240ca1cc + W[19];
-        t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
-        t1 = d + e1(a) + Ch(a,b,c) + 0x2de92c6f + W[20];
-        t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
-        t1 = c + e1(h) + Ch(h,a,b) + 0x4a7484aa + W[21];
-        t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
-        t1 = b + e1(g) + Ch(g,h,a) + 0x5cb0a9dc + W[22];
-        t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
-        t1 = a + e1(f) + Ch(f,g,h) + 0x76f988da + W[23];
-        t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
-
-        t1 = h + e1(e) + Ch(e,f,g) + 0x983e5152 + W[24];
-        t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
-        t1 = g + e1(d) + Ch(d,e,f) + 0xa831c66d + W[25];
-        t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
-        t1 = f + e1(c) + Ch(c,d,e) + 0xb00327c8 + W[26];
-        t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
-        t1 = e + e1(b) + Ch(b,c,d) + 0xbf597fc7 + W[27];
-        t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
-        t1 = d + e1(a) + Ch(a,b,c) + 0xc6e00bf3 + W[28];
-        t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
-        t1 = c + e1(h) + Ch(h,a,b) + 0xd5a79147 + W[29];
-        t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
-        t1 = b + e1(g) + Ch(g,h,a) + 0x06ca6351 + W[30];
-        t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
-        t1 = a + e1(f) + Ch(f,g,h) + 0x14292967 + W[31];
-        t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
-
-        t1 = h + e1(e) + Ch(e,f,g) + 0x27b70a85 + W[32];
-        t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
-        t1 = g + e1(d) + Ch(d,e,f) + 0x2e1b2138 + W[33];
-        t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
-        t1 = f + e1(c) + Ch(c,d,e) + 0x4d2c6dfc + W[34];
-        t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
-        t1 = e + e1(b) + Ch(b,c,d) + 0x53380d13 + W[35];
-        t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
-        t1 = d + e1(a) + Ch(a,b,c) + 0x650a7354 + W[36];
-        t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
-        t1 = c + e1(h) + Ch(h,a,b) + 0x766a0abb + W[37];
-        t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
-        t1 = b + e1(g) + Ch(g,h,a) + 0x81c2c92e + W[38];
-        t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
-        t1 = a + e1(f) + Ch(f,g,h) + 0x92722c85 + W[39];
-        t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
-
-        t1 = h + e1(e) + Ch(e,f,g) + 0xa2bfe8a1 + W[40];
-        t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
-        t1 = g + e1(d) + Ch(d,e,f) + 0xa81a664b + W[41];
-        t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
-        t1 = f + e1(c) + Ch(c,d,e) + 0xc24b8b70 + W[42];
-        t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
-        t1 = e + e1(b) + Ch(b,c,d) + 0xc76c51a3 + W[43];
-        t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
-        t1 = d + e1(a) + Ch(a,b,c) + 0xd192e819 + W[44];
-        t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
-        t1 = c + e1(h) + Ch(h,a,b) + 0xd6990624 + W[45];
-        t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
-        t1 = b + e1(g) + Ch(g,h,a) + 0xf40e3585 + W[46];
-        t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
-        t1 = a + e1(f) + Ch(f,g,h) + 0x106aa070 + W[47];
-        t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
-
-        t1 = h + e1(e) + Ch(e,f,g) + 0x19a4c116 + W[48];
-        t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
-        t1 = g + e1(d) + Ch(d,e,f) + 0x1e376c08 + W[49];
-        t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
-        t1 = f + e1(c) + Ch(c,d,e) + 0x2748774c + W[50];
-        t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
-        t1 = e + e1(b) + Ch(b,c,d) + 0x34b0bcb5 + W[51];
-        t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
-        t1 = d + e1(a) + Ch(a,b,c) + 0x391c0cb3 + W[52];
-        t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
-        t1 = c + e1(h) + Ch(h,a,b) + 0x4ed8aa4a + W[53];
-        t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
-        t1 = b + e1(g) + Ch(g,h,a) + 0x5b9cca4f + W[54];
-        t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
-        t1 = a + e1(f) + Ch(f,g,h) + 0x682e6ff3 + W[55];
-        t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
-
-        t1 = h + e1(e) + Ch(e,f,g) + 0x748f82ee + W[56];
-        t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
-        t1 = g + e1(d) + Ch(d,e,f) + 0x78a5636f + W[57];
-        t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
-        t1 = f + e1(c) + Ch(c,d,e) + 0x84c87814 + W[58];
-        t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
-        t1 = e + e1(b) + Ch(b,c,d) + 0x8cc70208 + W[59];
-        t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
-        t1 = d + e1(a) + Ch(a,b,c) + 0x90befffa + W[60];
-        t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
-        t1 = c + e1(h) + Ch(h,a,b) + 0xa4506ceb + W[61];
-        t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
-        t1 = b + e1(g) + Ch(g,h,a) + 0xbef9a3f7 + W[62];
-        t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
-        t1 = a + e1(f) + Ch(f,g,h) + 0xc67178f2 + W[63];
-        t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
-
-        state[0] += a; state[1] += b; state[2] += c; state[3] += d;
-        state[4] += e; state[5] += f; state[6] += g; state[7] += h;
-
-        /* clear any sensitive info... */
-        a = b = c = d = e = f = g = h = t1 = t2 = 0;
-        memset(W, 0, 64 * sizeof(u32));
-}
-                                                                       /*}}}*/
-SHA256Summation::SHA256Summation()                                     /*{{{*/
-{
-        Sum.state[0] = H0;
-        Sum.state[1] = H1;
-        Sum.state[2] = H2;
-        Sum.state[3] = H3;
-        Sum.state[4] = H4;
-        Sum.state[5] = H5;
-        Sum.state[6] = H6;
-        Sum.state[7] = H7;
-        Sum.count[0] = Sum.count[1] = 0;
-        memset(Sum.buf, 0, sizeof(Sum.buf));
-        Done = false;
-}
-                                                                       /*}}}*/
-bool SHA256Summation::Add(const u8 *data, unsigned long len)           /*{{{*/
-{
-        struct sha256_ctx *sctx = &Sum;
-        unsigned int i, index, part_len;
-
-        if (Done) return false;
-
-        /* Compute number of bytes mod 128 */
-        index = (unsigned int)((sctx->count[0] >> 3) & 0x3f);
-
-        /* Update number of bits */
-        if ((sctx->count[0] += (len << 3)) < (len << 3)) {
-                sctx->count[1]++;
-                sctx->count[1] += (len >> 29);
-        }
-
-        part_len = 64 - index;
-
-        /* Transform as many times as possible. */
-        if (len >= part_len) {
-                memcpy(&sctx->buf[index], data, part_len);
-                sha256_transform(sctx->state, sctx->buf);
-
-                for (i = part_len; i + 63 < len; i += 64)
-                        sha256_transform(sctx->state, &data[i]);
-                index = 0;
-        } else {
-                i = 0;
-        }
-
-        /* Buffer remaining input */
-        memcpy(&sctx->buf[index], &data[i], len-i);
-
-        return true;
-}
-                                                                       /*}}}*/
-SHA256SumValue SHA256Summation::Result()                               /*{{{*/
-{
-   struct sha256_ctx *sctx = &Sum;
-   if (!Done) {
-        u8 bits[8];
-        unsigned int index, pad_len, t;
-        static const u8 padding[64] = { 0x80, };
-
-        /* Save number of bits */
-        t = sctx->count[0];
-        bits[7] = t; t >>= 8;
-        bits[6] = t; t >>= 8;
-        bits[5] = t; t >>= 8;
-        bits[4] = t;
-        t = sctx->count[1];
-        bits[3] = t; t >>= 8;
-        bits[2] = t; t >>= 8;
-        bits[1] = t; t >>= 8;
-        bits[0] = t;
-
-        /* Pad out to 56 mod 64. */
-        index = (sctx->count[0] >> 3) & 0x3f;
-        pad_len = (index < 56) ? (56 - index) : ((64+56) - index);
-        Add(padding, pad_len);
-
-        /* Append length (before padding) */
-        Add(bits, 8);
-   }
-
-   Done = true;
-
-   /* Store state in digest */
-
-   SHA256SumValue res;
-   u8 *out = res.Sum;
-
-   int i, j;
-   unsigned int t;
-   for (i = j = 0; i < 8; i++, j += 4) {
-      t = sctx->state[i];
-      out[j+3] = t; t >>= 8;
-      out[j+2] = t; t >>= 8;
-      out[j+1] = t; t >>= 8;
-      out[j  ] = t;
-   }
-
-   return res;
-}
-                                                                       /*}}}*/
-// SHA256SumValue::SHA256SumValue - Constructs the sum from a string   /*{{{*/
-// ---------------------------------------------------------------------
-/* The string form of a SHA256 is a 64 character hex number */
-SHA256SumValue::SHA256SumValue(string Str)
-{
-   memset(Sum,0,sizeof(Sum));
-   Set(Str);
-}
-                                                                       /*}}}*/
-// SHA256SumValue::SHA256SumValue - Default constructor                /*{{{*/
-// ---------------------------------------------------------------------
-/* Sets the value to 0 */
-SHA256SumValue::SHA256SumValue()
-{
-   memset(Sum,0,sizeof(Sum));
-}
-                                                                       /*}}}*/
-// SHA256SumValue::Set - Set the sum from a string                     /*{{{*/
-// ---------------------------------------------------------------------
-/* Converts the hex string into a set of chars */
-bool SHA256SumValue::Set(string Str)
-{
-   return Hex2Num(Str,Sum,sizeof(Sum));
-}
-                                                                       /*}}}*/
-// SHA256SumValue::Value - Convert the number into a string            /*{{{*/
-// ---------------------------------------------------------------------
-/* Converts the set of chars into a hex string in lower case */
-string SHA256SumValue::Value() const
-{
-   char Conv[16] =
-      { '0','1','2','3','4','5','6','7','8','9','a','b',
-      'c','d','e','f'
-   };
-   char Result[65];
-   Result[64] = 0;
-
-   // Convert each char into two letters
-   int J = 0;
-   int I = 0;
-   for (; I != 64; J++,I += 2)
-   {
-      Result[I] = Conv[Sum[J] >> 4];
-      Result[I + 1] = Conv[Sum[J] & 0xF];
-   }
-
-   return string(Result);
-}
-                                                                       /*}}}*/
-// SHA256SumValue::operator == - Comparator                            /*{{{*/
-// ---------------------------------------------------------------------
-/* Call memcmp on the buffer */
-bool SHA256SumValue::operator == (const SHA256SumValue & rhs) const
-{
-   return memcmp(Sum,rhs.Sum,sizeof(Sum)) == 0;
-}
-                                                                       /*}}}*/
-// SHA256Summation::AddFD - Add content of file into the checksum      /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool SHA256Summation::AddFD(int Fd,unsigned long Size)
-{
-   unsigned char Buf[64 * 64];
-   int Res = 0;
-   int ToEOF = (Size == 0);
-   while (Size != 0 || ToEOF)
-   {
-      unsigned n = sizeof(Buf);
-      if (!ToEOF) n = min(Size,(unsigned long)n);
-      Res = read(Fd,Buf,n);
-      if (Res < 0 || (!ToEOF && (unsigned) Res != n)) // error, or short read
-         return false;
-      if (ToEOF && Res == 0) // EOF
-         break;
-      Size -= Res;
-      Add(Buf,Res);
-   }
-   return true;
-}
-                                                                       /*}}}*/
-
index 5934b5641dccba20c896252cc460f29f49d74091..fe2b30ac265e3d3691943ace328faf42bf5b4891 100644 (file)
@@ -1,72 +1,8 @@
-// -*- mode: cpp; mode: fold -*-
-// Description                                                          /*{{{*/
-// $Id: sha1.h,v 1.3 2001/05/07 05:05:47 jgg Exp $
-/* ######################################################################
-
-   SHA256SumValue - Storage for a SHA-256 hash.
-   SHA256Summation - SHA-256 Secure Hash Algorithm.
-   
-   This is a C++ interface to a set of SHA256Sum functions, that mirrors
-   the equivalent MD5 & SHA1 classes. 
-
-   ##################################################################### */
-                                                                        /*}}}*/
 #ifndef APTPKG_SHA256_H
 #define APTPKG_SHA256_H
 
-#include <string>
-#include <cstring>
-#include <algorithm>
-#include <stdint.h>
-
-using std::string;
-using std::min;
-
-class SHA256Summation;
-
-class SHA256SumValue
-{
-   friend class SHA256Summation;
-   unsigned char Sum[32];
-   
-   public:
-
-   // Accessors
-   bool operator ==(const SHA256SumValue &rhs) const; 
-   string Value() const;
-   inline void Value(unsigned char S[32])
-         {for (int I = 0; I != sizeof(Sum); I++) S[I] = Sum[I];};
-   inline operator string() const {return Value();};
-   bool Set(string Str);
-   inline void Set(unsigned char S[32]) 
-         {for (int I = 0; I != sizeof(Sum); I++) Sum[I] = S[I];};
-
-   SHA256SumValue(string Str);
-   SHA256SumValue();
-};
-
-struct sha256_ctx {
-    uint32_t count[2];
-    uint32_t state[8];
-    uint8_t buf[128];
-};
-
-class SHA256Summation
-{
-   struct sha256_ctx Sum;
-
-   bool Done;
-
-   public:
+#include "sha2.h"
 
-   bool Add(const unsigned char *inbuf,unsigned long inlen);
-   inline bool Add(const char *Data) {return Add((unsigned char *)Data,strlen(Data));};
-   bool AddFD(int Fd,unsigned long Size);
-   inline bool Add(const unsigned char *Beg,const unsigned char *End) 
-                  {return Add(Beg,End-Beg);};
-   SHA256SumValue Result();
-   
-   SHA256Summation();
-};
+#warn "This header is deprecated, please include sha2.h instead"
 
 #endif
diff --git a/apt-pkg/contrib/sha2_internal.cc b/apt-pkg/contrib/sha2_internal.cc
new file mode 100644 (file)
index 0000000..10b82de
--- /dev/null
@@ -0,0 +1,1065 @@
+/*
+ * FILE:       sha2.c
+ * AUTHOR:     Aaron D. Gifford - http://www.aarongifford.com/
+ * 
+ * Copyright (c) 2000-2001, Aaron D. Gifford
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
+ */
+
+#include <string.h>    /* memcpy()/memset() or bcopy()/bzero() */
+#include <assert.h>    /* assert() */
+#include "sha2_internal.h"
+
+/*
+ * ASSERT NOTE:
+ * Some sanity checking code is included using assert().  On my FreeBSD
+ * system, this additional code can be removed by compiling with NDEBUG
+ * defined.  Check your own systems manpage on assert() to see how to
+ * compile WITHOUT the sanity checking code on your system.
+ *
+ * UNROLLED TRANSFORM LOOP NOTE:
+ * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
+ * loop version for the hash transform rounds (defined using macros
+ * later in this file).  Either define on the command line, for example:
+ *
+ *   cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
+ *
+ * or define below:
+ *
+ *   #define SHA2_UNROLL_TRANSFORM
+ *
+ */
+
+
+/*** SHA-256/384/512 Machine Architecture Definitions *****************/
+/*
+ * BYTE_ORDER NOTE:
+ *
+ * Please make sure that your system defines BYTE_ORDER.  If your
+ * architecture is little-endian, make sure it also defines
+ * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
+ * equivilent.
+ *
+ * If your system does not define the above, then you can do so by
+ * hand like this:
+ *
+ *   #define LITTLE_ENDIAN 1234
+ *   #define BIG_ENDIAN    4321
+ *
+ * And for little-endian machines, add:
+ *
+ *   #define BYTE_ORDER LITTLE_ENDIAN 
+ *
+ * Or for big-endian machines:
+ *
+ *   #define BYTE_ORDER BIG_ENDIAN
+ *
+ * The FreeBSD machine this was written on defines BYTE_ORDER
+ * appropriately by including <sys/types.h> (which in turn includes
+ * <machine/endian.h> where the appropriate definitions are actually
+ * made).
+ */
+#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
+#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
+#endif
+
+/*
+ * Define the followingsha2_* types to types of the correct length on
+ * the native archtecture.   Most BSD systems and Linux define u_intXX_t
+ * types.  Machines with very recent ANSI C headers, can use the
+ * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H
+ * during compile or in the sha.h header file.
+ *
+ * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t
+ * will need to define these three typedefs below (and the appropriate
+ * ones in sha.h too) by hand according to their system architecture.
+ *
+ * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t
+ * types and pointing out recent ANSI C support for uintXX_t in inttypes.h.
+ */
+#ifdef SHA2_USE_INTTYPES_H
+
+typedef uint8_t  sha2_byte;    /* Exactly 1 byte */
+typedef uint32_t sha2_word32;  /* Exactly 4 bytes */
+typedef uint64_t sha2_word64;  /* Exactly 8 bytes */
+
+#else /* SHA2_USE_INTTYPES_H */
+
+typedef u_int8_t  sha2_byte;   /* Exactly 1 byte */
+typedef u_int32_t sha2_word32; /* Exactly 4 bytes */
+typedef u_int64_t sha2_word64; /* Exactly 8 bytes */
+
+#endif /* SHA2_USE_INTTYPES_H */
+
+
+/*** SHA-256/384/512 Various Length Definitions ***********************/
+/* NOTE: Most of these are in sha2.h */
+#define SHA256_SHORT_BLOCK_LENGTH      (SHA256_BLOCK_LENGTH - 8)
+#define SHA384_SHORT_BLOCK_LENGTH      (SHA384_BLOCK_LENGTH - 16)
+#define SHA512_SHORT_BLOCK_LENGTH      (SHA512_BLOCK_LENGTH - 16)
+
+
+/*** ENDIAN REVERSAL MACROS *******************************************/
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define REVERSE32(w,x) { \
+       sha2_word32 tmp = (w); \
+       tmp = (tmp >> 16) | (tmp << 16); \
+       (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
+}
+#define REVERSE64(w,x) { \
+       sha2_word64 tmp = (w); \
+       tmp = (tmp >> 32) | (tmp << 32); \
+       tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
+             ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
+       (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
+             ((tmp & 0x0000ffff0000ffffULL) << 16); \
+}
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+/*
+ * Macro for incrementally adding the unsigned 64-bit integer n to the
+ * unsigned 128-bit integer (represented using a two-element array of
+ * 64-bit words):
+ */
+#define ADDINC128(w,n) { \
+       (w)[0] += (sha2_word64)(n); \
+       if ((w)[0] < (n)) { \
+               (w)[1]++; \
+       } \
+}
+
+/*
+ * Macros for copying blocks of memory and for zeroing out ranges
+ * of memory.  Using these macros makes it easy to switch from
+ * using memset()/memcpy() and using bzero()/bcopy().
+ *
+ * Please define either SHA2_USE_MEMSET_MEMCPY or define
+ * SHA2_USE_BZERO_BCOPY depending on which function set you
+ * choose to use:
+ */
+#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
+/* Default to memset()/memcpy() if no option is specified */
+#define        SHA2_USE_MEMSET_MEMCPY  1
+#endif
+#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
+/* Abort with an error if BOTH options are defined */
+#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
+#endif
+
+#ifdef SHA2_USE_MEMSET_MEMCPY
+#define MEMSET_BZERO(p,l)      memset((p), 0, (l))
+#define MEMCPY_BCOPY(d,s,l)    memcpy((d), (s), (l))
+#endif
+#ifdef SHA2_USE_BZERO_BCOPY
+#define MEMSET_BZERO(p,l)      bzero((p), (l))
+#define MEMCPY_BCOPY(d,s,l)    bcopy((s), (d), (l))
+#endif
+
+
+/*** THE SIX LOGICAL FUNCTIONS ****************************************/
+/*
+ * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
+ *
+ *   NOTE:  The naming of R and S appears backwards here (R is a SHIFT and
+ *   S is a ROTATION) because the SHA-256/384/512 description document
+ *   (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
+ *   same "backwards" definition.
+ */
+/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
+#define R(b,x)                 ((x) >> (b))
+/* 32-bit Rotate-right (used in SHA-256): */
+#define S32(b,x)       (((x) >> (b)) | ((x) << (32 - (b))))
+/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
+#define S64(b,x)       (((x) >> (b)) | ((x) << (64 - (b))))
+
+/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
+#define Ch(x,y,z)      (((x) & (y)) ^ ((~(x)) & (z)))
+#define Maj(x,y,z)     (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+/* Four of six logical functions used in SHA-256: */
+#define Sigma0_256(x)  (S32(2,  (x)) ^ S32(13, (x)) ^ S32(22, (x)))
+#define Sigma1_256(x)  (S32(6,  (x)) ^ S32(11, (x)) ^ S32(25, (x)))
+#define sigma0_256(x)  (S32(7,  (x)) ^ S32(18, (x)) ^ R(3 ,   (x)))
+#define sigma1_256(x)  (S32(17, (x)) ^ S32(19, (x)) ^ R(10,   (x)))
+
+/* Four of six logical functions used in SHA-384 and SHA-512: */
+#define Sigma0_512(x)  (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
+#define Sigma1_512(x)  (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
+#define sigma0_512(x)  (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7,   (x)))
+#define sigma1_512(x)  (S64(19, (x)) ^ S64(61, (x)) ^ R( 6,   (x)))
+
+/*** INTERNAL FUNCTION PROTOTYPES *************************************/
+/* NOTE: These should not be accessed directly from outside this
+ * library -- they are intended for private internal visibility/use
+ * only.
+ */
+void SHA512_Last(SHA512_CTX*);
+void SHA256_Transform(SHA256_CTX*, const sha2_word32*);
+void SHA512_Transform(SHA512_CTX*, const sha2_word64*);
+
+
+/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
+/* Hash constant words K for SHA-256: */
+const static sha2_word32 K256[64] = {
+       0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
+       0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
+       0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
+       0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
+       0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+       0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
+       0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
+       0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
+       0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
+       0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+       0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
+       0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
+       0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
+       0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
+       0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+       0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+};
+
+/* Initial hash value H for SHA-256: */
+const static sha2_word32 sha256_initial_hash_value[8] = {
+       0x6a09e667UL,
+       0xbb67ae85UL,
+       0x3c6ef372UL,
+       0xa54ff53aUL,
+       0x510e527fUL,
+       0x9b05688cUL,
+       0x1f83d9abUL,
+       0x5be0cd19UL
+};
+
+/* Hash constant words K for SHA-384 and SHA-512: */
+const static sha2_word64 K512[80] = {
+       0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
+       0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
+       0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+       0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
+       0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
+       0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+       0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
+       0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
+       0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+       0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+       0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
+       0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+       0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
+       0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
+       0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+       0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
+       0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
+       0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+       0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
+       0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+       0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+       0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
+       0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
+       0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+       0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
+       0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
+       0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+       0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
+       0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
+       0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+       0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
+       0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
+       0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+       0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
+       0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
+       0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+       0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
+       0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
+       0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+       0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
+};
+
+/* Initial hash value H for SHA-384 */
+const static sha2_word64 sha384_initial_hash_value[8] = {
+       0xcbbb9d5dc1059ed8ULL,
+       0x629a292a367cd507ULL,
+       0x9159015a3070dd17ULL,
+       0x152fecd8f70e5939ULL,
+       0x67332667ffc00b31ULL,
+       0x8eb44a8768581511ULL,
+       0xdb0c2e0d64f98fa7ULL,
+       0x47b5481dbefa4fa4ULL
+};
+
+/* Initial hash value H for SHA-512 */
+const static sha2_word64 sha512_initial_hash_value[8] = {
+       0x6a09e667f3bcc908ULL,
+       0xbb67ae8584caa73bULL,
+       0x3c6ef372fe94f82bULL,
+       0xa54ff53a5f1d36f1ULL,
+       0x510e527fade682d1ULL,
+       0x9b05688c2b3e6c1fULL,
+       0x1f83d9abfb41bd6bULL,
+       0x5be0cd19137e2179ULL
+};
+
+/*
+ * Constant used by SHA256/384/512_End() functions for converting the
+ * digest to a readable hexadecimal character string:
+ */
+static const char *sha2_hex_digits = "0123456789abcdef";
+
+
+/*** SHA-256: *********************************************************/
+void SHA256_Init(SHA256_CTX* context) {
+       if (context == (SHA256_CTX*)0) {
+               return;
+       }
+       MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
+       MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH);
+       context->bitcount = 0;
+}
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-256 round macros: */
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)      \
+       REVERSE32(*data++, W256[j]); \
+       T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
+             K256[j] + W256[j]; \
+       (d) += T1; \
+       (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
+       j++
+
+
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)      \
+       T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
+            K256[j] + (W256[j] = *data++); \
+       (d) += T1; \
+       (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
+       j++
+
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND256(a,b,c,d,e,f,g,h)      \
+       s0 = W256[(j+1)&0x0f]; \
+       s0 = sigma0_256(s0); \
+       s1 = W256[(j+14)&0x0f]; \
+       s1 = sigma1_256(s1); \
+       T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
+            (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
+       (d) += T1; \
+       (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
+       j++
+
+void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
+       sha2_word32     a, b, c, d, e, f, g, h, s0, s1;
+       sha2_word32     T1, *W256;
+       int             j;
+
+       W256 = (sha2_word32*)context->buffer;
+
+       /* Initialize registers with the prev. intermediate value */
+       a = context->state[0];
+       b = context->state[1];
+       c = context->state[2];
+       d = context->state[3];
+       e = context->state[4];
+       f = context->state[5];
+       g = context->state[6];
+       h = context->state[7];
+
+       j = 0;
+       do {
+               /* Rounds 0 to 15 (unrolled): */
+               ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
+               ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
+               ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
+               ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
+               ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
+               ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
+               ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
+               ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
+       } while (j < 16);
+
+       /* Now for the remaining rounds to 64: */
+       do {
+               ROUND256(a,b,c,d,e,f,g,h);
+               ROUND256(h,a,b,c,d,e,f,g);
+               ROUND256(g,h,a,b,c,d,e,f);
+               ROUND256(f,g,h,a,b,c,d,e);
+               ROUND256(e,f,g,h,a,b,c,d);
+               ROUND256(d,e,f,g,h,a,b,c);
+               ROUND256(c,d,e,f,g,h,a,b);
+               ROUND256(b,c,d,e,f,g,h,a);
+       } while (j < 64);
+
+       /* Compute the current intermediate hash value */
+       context->state[0] += a;
+       context->state[1] += b;
+       context->state[2] += c;
+       context->state[3] += d;
+       context->state[4] += e;
+       context->state[5] += f;
+       context->state[6] += g;
+       context->state[7] += h;
+
+       /* Clean up */
+       a = b = c = d = e = f = g = h = T1 = 0;
+}
+
+#else /* SHA2_UNROLL_TRANSFORM */
+
+void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
+       sha2_word32     a, b, c, d, e, f, g, h, s0, s1;
+       sha2_word32     T1, T2, *W256;
+       int             j;
+
+       W256 = (sha2_word32*)context->buffer;
+
+       /* Initialize registers with the prev. intermediate value */
+       a = context->state[0];
+       b = context->state[1];
+       c = context->state[2];
+       d = context->state[3];
+       e = context->state[4];
+       f = context->state[5];
+       g = context->state[6];
+       h = context->state[7];
+
+       j = 0;
+       do {
+#if BYTE_ORDER == LITTLE_ENDIAN
+               /* Copy data while converting to host byte order */
+               REVERSE32(*data++,W256[j]);
+               /* Apply the SHA-256 compression function to update a..h */
+               T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+               /* Apply the SHA-256 compression function to update a..h with copy */
+               T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+               T2 = Sigma0_256(a) + Maj(a, b, c);
+               h = g;
+               g = f;
+               f = e;
+               e = d + T1;
+               d = c;
+               c = b;
+               b = a;
+               a = T1 + T2;
+
+               j++;
+       } while (j < 16);
+
+       do {
+               /* Part of the message block expansion: */
+               s0 = W256[(j+1)&0x0f];
+               s0 = sigma0_256(s0);
+               s1 = W256[(j+14)&0x0f]; 
+               s1 = sigma1_256(s1);
+
+               /* Apply the SHA-256 compression function to update a..h */
+               T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + 
+                    (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
+               T2 = Sigma0_256(a) + Maj(a, b, c);
+               h = g;
+               g = f;
+               f = e;
+               e = d + T1;
+               d = c;
+               c = b;
+               b = a;
+               a = T1 + T2;
+
+               j++;
+       } while (j < 64);
+
+       /* Compute the current intermediate hash value */
+       context->state[0] += a;
+       context->state[1] += b;
+       context->state[2] += c;
+       context->state[3] += d;
+       context->state[4] += e;
+       context->state[5] += f;
+       context->state[6] += g;
+       context->state[7] += h;
+
+       /* Clean up */
+       a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
+#endif /* SHA2_UNROLL_TRANSFORM */
+
+void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
+       unsigned int    freespace, usedspace;
+
+       if (len == 0) {
+               /* Calling with no data is valid - we do nothing */
+               return;
+       }
+
+       /* Sanity check: */
+       assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0);
+
+       usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
+       if (usedspace > 0) {
+               /* Calculate how much free space is available in the buffer */
+               freespace = SHA256_BLOCK_LENGTH - usedspace;
+
+               if (len >= freespace) {
+                       /* Fill the buffer completely and process it */
+                       MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
+                       context->bitcount += freespace << 3;
+                       len -= freespace;
+                       data += freespace;
+                       SHA256_Transform(context, (sha2_word32*)context->buffer);
+               } else {
+                       /* The buffer is not yet full */
+                       MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
+                       context->bitcount += len << 3;
+                       /* Clean up: */
+                       usedspace = freespace = 0;
+                       return;
+               }
+       }
+       while (len >= SHA256_BLOCK_LENGTH) {
+               /* Process as many complete blocks as we can */
+               SHA256_Transform(context, (sha2_word32*)data);
+               context->bitcount += SHA256_BLOCK_LENGTH << 3;
+               len -= SHA256_BLOCK_LENGTH;
+               data += SHA256_BLOCK_LENGTH;
+       }
+       if (len > 0) {
+               /* There's left-overs, so save 'em */
+               MEMCPY_BCOPY(context->buffer, data, len);
+               context->bitcount += len << 3;
+       }
+       /* Clean up: */
+       usedspace = freespace = 0;
+}
+
+void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
+       sha2_word32     *d = (sha2_word32*)digest;
+       unsigned int    usedspace;
+
+       /* Sanity check: */
+       assert(context != (SHA256_CTX*)0);
+
+       /* If no digest buffer is passed, we don't bother doing this: */
+       if (digest != (sha2_byte*)0) {
+               usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
+#if BYTE_ORDER == LITTLE_ENDIAN
+               /* Convert FROM host byte order */
+               REVERSE64(context->bitcount,context->bitcount);
+#endif
+               if (usedspace > 0) {
+                       /* Begin padding with a 1 bit: */
+                       context->buffer[usedspace++] = 0x80;
+
+                       if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
+                               /* Set-up for the last transform: */
+                               MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
+                       } else {
+                               if (usedspace < SHA256_BLOCK_LENGTH) {
+                                       MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
+                               }
+                               /* Do second-to-last transform: */
+                               SHA256_Transform(context, (sha2_word32*)context->buffer);
+
+                               /* And set-up for the last transform: */
+                               MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
+                       }
+               } else {
+                       /* Set-up for the last transform: */
+                       MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
+
+                       /* Begin padding with a 1 bit: */
+                       *context->buffer = 0x80;
+               }
+               /* Set the bit count: */
+               *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
+
+               /* Final transform: */
+               SHA256_Transform(context, (sha2_word32*)context->buffer);
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+               {
+                       /* Convert TO host byte order */
+                       int     j;
+                       for (j = 0; j < 8; j++) {
+                               REVERSE32(context->state[j],context->state[j]);
+                               *d++ = context->state[j];
+                       }
+               }
+#else
+               MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH);
+#endif
+       }
+
+       /* Clean up state data: */
+       MEMSET_BZERO(context, sizeof(context));
+       usedspace = 0;
+}
+
+char *SHA256_End(SHA256_CTX* context, char buffer[]) {
+       sha2_byte       digest[SHA256_DIGEST_LENGTH], *d = digest;
+       int             i;
+
+       /* Sanity check: */
+       assert(context != (SHA256_CTX*)0);
+
+       if (buffer != (char*)0) {
+               SHA256_Final(digest, context);
+
+               for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
+                       *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
+                       *buffer++ = sha2_hex_digits[*d & 0x0f];
+                       d++;
+               }
+               *buffer = (char)0;
+       } else {
+               MEMSET_BZERO(context, sizeof(context));
+       }
+       MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH);
+       return buffer;
+}
+
+char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) {
+       SHA256_CTX      context;
+
+       SHA256_Init(&context);
+       SHA256_Update(&context, data, len);
+       return SHA256_End(&context, digest);
+}
+
+
+/*** SHA-512: *********************************************************/
+void SHA512_Init(SHA512_CTX* context) {
+       if (context == (SHA512_CTX*)0) {
+               return;
+       }
+       MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
+       MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH);
+       context->bitcount[0] = context->bitcount[1] =  0;
+}
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-512 round macros: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)      \
+       REVERSE64(*data++, W512[j]); \
+       T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
+             K512[j] + W512[j]; \
+       (d) += T1, \
+       (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
+       j++
+
+
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)      \
+       T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
+             K512[j] + (W512[j] = *data++); \
+       (d) += T1; \
+       (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
+       j++
+
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND512(a,b,c,d,e,f,g,h)      \
+       s0 = W512[(j+1)&0x0f]; \
+       s0 = sigma0_512(s0); \
+       s1 = W512[(j+14)&0x0f]; \
+       s1 = sigma1_512(s1); \
+       T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
+             (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
+       (d) += T1; \
+       (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
+       j++
+
+void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
+       sha2_word64     a, b, c, d, e, f, g, h, s0, s1;
+       sha2_word64     T1, *W512 = (sha2_word64*)context->buffer;
+       int             j;
+
+       /* Initialize registers with the prev. intermediate value */
+       a = context->state[0];
+       b = context->state[1];
+       c = context->state[2];
+       d = context->state[3];
+       e = context->state[4];
+       f = context->state[5];
+       g = context->state[6];
+       h = context->state[7];
+
+       j = 0;
+       do {
+               ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
+               ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
+               ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
+               ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
+               ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
+               ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
+               ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
+               ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
+       } while (j < 16);
+
+       /* Now for the remaining rounds up to 79: */
+       do {
+               ROUND512(a,b,c,d,e,f,g,h);
+               ROUND512(h,a,b,c,d,e,f,g);
+               ROUND512(g,h,a,b,c,d,e,f);
+               ROUND512(f,g,h,a,b,c,d,e);
+               ROUND512(e,f,g,h,a,b,c,d);
+               ROUND512(d,e,f,g,h,a,b,c);
+               ROUND512(c,d,e,f,g,h,a,b);
+               ROUND512(b,c,d,e,f,g,h,a);
+       } while (j < 80);
+
+       /* Compute the current intermediate hash value */
+       context->state[0] += a;
+       context->state[1] += b;
+       context->state[2] += c;
+       context->state[3] += d;
+       context->state[4] += e;
+       context->state[5] += f;
+       context->state[6] += g;
+       context->state[7] += h;
+
+       /* Clean up */
+       a = b = c = d = e = f = g = h = T1 = 0;
+}
+
+#else /* SHA2_UNROLL_TRANSFORM */
+
+void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
+       sha2_word64     a, b, c, d, e, f, g, h, s0, s1;
+       sha2_word64     T1, T2, *W512 = (sha2_word64*)context->buffer;
+       int             j;
+
+       /* Initialize registers with the prev. intermediate value */
+       a = context->state[0];
+       b = context->state[1];
+       c = context->state[2];
+       d = context->state[3];
+       e = context->state[4];
+       f = context->state[5];
+       g = context->state[6];
+       h = context->state[7];
+
+       j = 0;
+       do {
+#if BYTE_ORDER == LITTLE_ENDIAN
+               /* Convert TO host byte order */
+               REVERSE64(*data++, W512[j]);
+               /* Apply the SHA-512 compression function to update a..h */
+               T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+               /* Apply the SHA-512 compression function to update a..h with copy */
+               T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+               T2 = Sigma0_512(a) + Maj(a, b, c);
+               h = g;
+               g = f;
+               f = e;
+               e = d + T1;
+               d = c;
+               c = b;
+               b = a;
+               a = T1 + T2;
+
+               j++;
+       } while (j < 16);
+
+       do {
+               /* Part of the message block expansion: */
+               s0 = W512[(j+1)&0x0f];
+               s0 = sigma0_512(s0);
+               s1 = W512[(j+14)&0x0f];
+               s1 =  sigma1_512(s1);
+
+               /* Apply the SHA-512 compression function to update a..h */
+               T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
+                    (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
+               T2 = Sigma0_512(a) + Maj(a, b, c);
+               h = g;
+               g = f;
+               f = e;
+               e = d + T1;
+               d = c;
+               c = b;
+               b = a;
+               a = T1 + T2;
+
+               j++;
+       } while (j < 80);
+
+       /* Compute the current intermediate hash value */
+       context->state[0] += a;
+       context->state[1] += b;
+       context->state[2] += c;
+       context->state[3] += d;
+       context->state[4] += e;
+       context->state[5] += f;
+       context->state[6] += g;
+       context->state[7] += h;
+
+       /* Clean up */
+       a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
+#endif /* SHA2_UNROLL_TRANSFORM */
+
+void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
+       unsigned int    freespace, usedspace;
+
+       if (len == 0) {
+               /* Calling with no data is valid - we do nothing */
+               return;
+       }
+
+       /* Sanity check: */
+       assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0);
+
+       usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
+       if (usedspace > 0) {
+               /* Calculate how much free space is available in the buffer */
+               freespace = SHA512_BLOCK_LENGTH - usedspace;
+
+               if (len >= freespace) {
+                       /* Fill the buffer completely and process it */
+                       MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
+                       ADDINC128(context->bitcount, freespace << 3);
+                       len -= freespace;
+                       data += freespace;
+                       SHA512_Transform(context, (sha2_word64*)context->buffer);
+               } else {
+                       /* The buffer is not yet full */
+                       MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
+                       ADDINC128(context->bitcount, len << 3);
+                       /* Clean up: */
+                       usedspace = freespace = 0;
+                       return;
+               }
+       }
+       while (len >= SHA512_BLOCK_LENGTH) {
+               /* Process as many complete blocks as we can */
+               SHA512_Transform(context, (sha2_word64*)data);
+               ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
+               len -= SHA512_BLOCK_LENGTH;
+               data += SHA512_BLOCK_LENGTH;
+       }
+       if (len > 0) {
+               /* There's left-overs, so save 'em */
+               MEMCPY_BCOPY(context->buffer, data, len);
+               ADDINC128(context->bitcount, len << 3);
+       }
+       /* Clean up: */
+       usedspace = freespace = 0;
+}
+
+void SHA512_Last(SHA512_CTX* context) {
+       unsigned int    usedspace;
+
+       usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
+#if BYTE_ORDER == LITTLE_ENDIAN
+       /* Convert FROM host byte order */
+       REVERSE64(context->bitcount[0],context->bitcount[0]);
+       REVERSE64(context->bitcount[1],context->bitcount[1]);
+#endif
+       if (usedspace > 0) {
+               /* Begin padding with a 1 bit: */
+               context->buffer[usedspace++] = 0x80;
+
+               if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
+                       /* Set-up for the last transform: */
+                       MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
+               } else {
+                       if (usedspace < SHA512_BLOCK_LENGTH) {
+                               MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
+                       }
+                       /* Do second-to-last transform: */
+                       SHA512_Transform(context, (sha2_word64*)context->buffer);
+
+                       /* And set-up for the last transform: */
+                       MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2);
+               }
+       } else {
+               /* Prepare for final transform: */
+               MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH);
+
+               /* Begin padding with a 1 bit: */
+               *context->buffer = 0x80;
+       }
+       /* Store the length of input data (in bits): */
+       *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];
+       *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];
+
+       /* Final transform: */
+       SHA512_Transform(context, (sha2_word64*)context->buffer);
+}
+
+void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
+       sha2_word64     *d = (sha2_word64*)digest;
+
+       /* Sanity check: */
+       assert(context != (SHA512_CTX*)0);
+
+       /* If no digest buffer is passed, we don't bother doing this: */
+       if (digest != (sha2_byte*)0) {
+               SHA512_Last(context);
+
+               /* Save the hash data for output: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+               {
+                       /* Convert TO host byte order */
+                       int     j;
+                       for (j = 0; j < 8; j++) {
+                               REVERSE64(context->state[j],context->state[j]);
+                               *d++ = context->state[j];
+                       }
+               }
+#else
+               MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH);
+#endif
+       }
+
+       /* Zero out state data */
+       MEMSET_BZERO(context, sizeof(context));
+}
+
+char *SHA512_End(SHA512_CTX* context, char buffer[]) {
+       sha2_byte       digest[SHA512_DIGEST_LENGTH], *d = digest;
+       int             i;
+
+       /* Sanity check: */
+       assert(context != (SHA512_CTX*)0);
+
+       if (buffer != (char*)0) {
+               SHA512_Final(digest, context);
+
+               for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {
+                       *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
+                       *buffer++ = sha2_hex_digits[*d & 0x0f];
+                       d++;
+               }
+               *buffer = (char)0;
+       } else {
+               MEMSET_BZERO(context, sizeof(context));
+       }
+       MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH);
+       return buffer;
+}
+
+char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) {
+       SHA512_CTX      context;
+
+       SHA512_Init(&context);
+       SHA512_Update(&context, data, len);
+       return SHA512_End(&context, digest);
+}
+
+
+/*** SHA-384: *********************************************************/
+void SHA384_Init(SHA384_CTX* context) {
+       if (context == (SHA384_CTX*)0) {
+               return;
+       }
+       MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
+       MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH);
+       context->bitcount[0] = context->bitcount[1] = 0;
+}
+
+void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) {
+       SHA512_Update((SHA512_CTX*)context, data, len);
+}
+
+void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) {
+       sha2_word64     *d = (sha2_word64*)digest;
+
+       /* Sanity check: */
+       assert(context != (SHA384_CTX*)0);
+
+       /* If no digest buffer is passed, we don't bother doing this: */
+       if (digest != (sha2_byte*)0) {
+               SHA512_Last((SHA512_CTX*)context);
+
+               /* Save the hash data for output: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+               {
+                       /* Convert TO host byte order */
+                       int     j;
+                       for (j = 0; j < 6; j++) {
+                               REVERSE64(context->state[j],context->state[j]);
+                               *d++ = context->state[j];
+                       }
+               }
+#else
+               MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH);
+#endif
+       }
+
+       /* Zero out state data */
+       MEMSET_BZERO(context, sizeof(context));
+}
+
+char *SHA384_End(SHA384_CTX* context, char buffer[]) {
+       sha2_byte       digest[SHA384_DIGEST_LENGTH], *d = digest;
+       int             i;
+
+       /* Sanity check: */
+       assert(context != (SHA384_CTX*)0);
+
+       if (buffer != (char*)0) {
+               SHA384_Final(digest, context);
+
+               for (i = 0; i < SHA384_DIGEST_LENGTH; i++) {
+                       *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
+                       *buffer++ = sha2_hex_digits[*d & 0x0f];
+                       d++;
+               }
+               *buffer = (char)0;
+       } else {
+               MEMSET_BZERO(context, sizeof(context));
+       }
+       MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH);
+       return buffer;
+}
+
+char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) {
+       SHA384_CTX      context;
+
+       SHA384_Init(&context);
+       SHA384_Update(&context, data, len);
+       return SHA384_End(&context, digest);
+}
+
diff --git a/apt-pkg/contrib/sha2_internal.h b/apt-pkg/contrib/sha2_internal.h
new file mode 100644 (file)
index 0000000..bf759ad
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * FILE:       sha2.h
+ * AUTHOR:     Aaron D. Gifford - http://www.aarongifford.com/
+ * 
+ * Copyright (c) 2000-2001, Aaron D. Gifford
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $
+ */
+
+#ifndef __SHA2_H__
+#define __SHA2_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * Import u_intXX_t size_t type definitions from system headers.  You
+ * may need to change this, or define these things yourself in this
+ * file.
+ */
+#include <sys/types.h>
+
+#ifdef SHA2_USE_INTTYPES_H
+
+#include <inttypes.h>
+
+#endif /* SHA2_USE_INTTYPES_H */
+
+
+/*** SHA-256/384/512 Various Length Definitions ***********************/
+#define SHA256_BLOCK_LENGTH            64
+#define SHA256_DIGEST_LENGTH           32
+#define SHA256_DIGEST_STRING_LENGTH    (SHA256_DIGEST_LENGTH * 2 + 1)
+#define SHA384_BLOCK_LENGTH            128
+#define SHA384_DIGEST_LENGTH           48
+#define SHA384_DIGEST_STRING_LENGTH    (SHA384_DIGEST_LENGTH * 2 + 1)
+#define SHA512_BLOCK_LENGTH            128
+#define SHA512_DIGEST_LENGTH           64
+#define SHA512_DIGEST_STRING_LENGTH    (SHA512_DIGEST_LENGTH * 2 + 1)
+
+
+/*** SHA-256/384/512 Context Structures *******************************/
+/* NOTE: If your architecture does not define either u_intXX_t types or
+ * uintXX_t (from inttypes.h), you may need to define things by hand
+ * for your system:
+ */
+#if 0
+typedef unsigned char u_int8_t;                /* 1-byte  (8-bits)  */
+typedef unsigned int u_int32_t;                /* 4-bytes (32-bits) */
+typedef unsigned long long u_int64_t;  /* 8-bytes (64-bits) */
+#endif
+/*
+ * Most BSD systems already define u_intXX_t types, as does Linux.
+ * Some systems, however, like Compaq's Tru64 Unix instead can use
+ * uintXX_t types defined by very recent ANSI C standards and included
+ * in the file:
+ *
+ *   #include <inttypes.h>
+ *
+ * If you choose to use <inttypes.h> then please define: 
+ *
+ *   #define SHA2_USE_INTTYPES_H
+ *
+ * Or on the command line during compile:
+ *
+ *   cc -DSHA2_USE_INTTYPES_H ...
+ */
+#ifdef SHA2_USE_INTTYPES_H
+
+typedef struct _SHA256_CTX {
+       uint32_t        state[8];
+       uint64_t        bitcount;
+       uint8_t buffer[SHA256_BLOCK_LENGTH];
+} SHA256_CTX;
+typedef struct _SHA512_CTX {
+       uint64_t        state[8];
+       uint64_t        bitcount[2];
+       uint8_t buffer[SHA512_BLOCK_LENGTH];
+} SHA512_CTX;
+
+#else /* SHA2_USE_INTTYPES_H */
+
+typedef struct _SHA256_CTX {
+       u_int32_t       state[8];
+       u_int64_t       bitcount;
+       u_int8_t        buffer[SHA256_BLOCK_LENGTH];
+} SHA256_CTX;
+typedef struct _SHA512_CTX {
+       u_int64_t       state[8];
+       u_int64_t       bitcount[2];
+       u_int8_t        buffer[SHA512_BLOCK_LENGTH];
+} SHA512_CTX;
+
+#endif /* SHA2_USE_INTTYPES_H */
+
+typedef SHA512_CTX SHA384_CTX;
+
+
+/*** SHA-256/384/512 Function Prototypes ******************************/
+#ifndef NOPROTO
+#ifdef SHA2_USE_INTTYPES_H
+
+void SHA256_Init(SHA256_CTX *);
+void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t);
+void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*);
+char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]);
+char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]);
+
+void SHA384_Init(SHA384_CTX*);
+void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t);
+void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*);
+char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]);
+char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]);
+
+void SHA512_Init(SHA512_CTX*);
+void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t);
+void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
+char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]);
+char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]);
+
+#else /* SHA2_USE_INTTYPES_H */
+
+void SHA256_Init(SHA256_CTX *);
+void SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t);
+void SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*);
+char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]);
+char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]);
+
+void SHA384_Init(SHA384_CTX*);
+void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t);
+void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*);
+char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]);
+char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]);
+
+void SHA512_Init(SHA512_CTX*);
+void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t);
+void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
+char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]);
+char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]);
+
+#endif /* SHA2_USE_INTTYPES_H */
+
+#else /* NOPROTO */
+
+void SHA256_Init();
+void SHA256_Update();
+void SHA256_Final();
+char* SHA256_End();
+char* SHA256_Data();
+
+void SHA384_Init();
+void SHA384_Update();
+void SHA384_Final();
+char* SHA384_End();
+char* SHA384_Data();
+
+void SHA512_Init();
+void SHA512_Update();
+void SHA512_Final();
+char* SHA512_End();
+char* SHA512_Data();
+
+#endif /* NOPROTO */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __SHA2_H__ */
+
index ec9e395ef9d1e636d5456affc2e28941fea55257..1ca9ae1d2d602d83c6aedfe4c1b73f0cd8ffdff6 100644 (file)
@@ -77,7 +77,7 @@ string debRecordParser::SHA1Hash()
    return Section.FindS("SHA1");
 }
                                                                        /*}}}*/
-// RecordParser::SHA1Hash - Return the archive hash                    /*{{{*/
+// RecordParser::SHA256Hash - Return the archive hash                  /*{{{*/
 // ---------------------------------------------------------------------
 /* */
 string debRecordParser::SHA256Hash()
@@ -85,6 +85,14 @@ string debRecordParser::SHA256Hash()
    return Section.FindS("SHA256");
 }
                                                                        /*}}}*/
+// RecordParser::SHA512Hash - Return the archive hash                  /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+string debRecordParser::SHA512Hash()
+{
+   return Section.FindS("SHA512");
+}
+                                                                       /*}}}*/
 // RecordParser::Maintainer - Return the maintainer email              /*{{{*/
 // ---------------------------------------------------------------------
 /* */
index 6f358abfa3225b5a2034fbb88ea1de20a63a689d..05159ea1eaae1caa78d6a015d382dc410863c5b4 100644 (file)
@@ -36,6 +36,7 @@ class debRecordParser : public pkgRecords::Parser
    virtual string MD5Hash();
    virtual string SHA1Hash();
    virtual string SHA256Hash();
+   virtual string SHA512Hash();
    virtual string SourcePkg();
    virtual string SourceVer();
    
index e6bcf852470dc158f2b21d72136a382c2e92c899..b11e35250a55dd22a598dd824df034f88e94e684 100644 (file)
@@ -20,11 +20,15 @@ APT_DOMAIN:=libapt-pkg$(LIBAPTPKG_MAJOR)
 # Source code for the contributed non-core things
 SOURCE = contrib/mmap.cc contrib/error.cc contrib/strutl.cc \
          contrib/configuration.cc contrib/progress.cc contrib/cmndline.cc \
-        contrib/md5.cc contrib/sha1.cc contrib/sha256.cc contrib/hashes.cc \
+        contrib/md5.cc contrib/sha1.cc contrib/sha2.cc  \
+        contrib/sha2_internal.cc\
+         contrib/hashes.cc \
         contrib/cdromutl.cc contrib/crc-16.cc contrib/netrc.cc \
         contrib/fileutl.cc 
 HEADERS = mmap.h error.h configuration.h fileutl.h  cmndline.h netrc.h\
-         md5.h crc-16.h cdromutl.h strutl.h sptr.h sha1.h sha256.h hashes.h \
+         md5.h crc-16.h cdromutl.h strutl.h sptr.h sha1.h sha2.h \
+         sha2_internal.h \
+          hashes.h hashsum_template.h\
          macros.h weakptr.h
 
 # Source code for the core main library
index c2c98188a7e12fce76b512c767e56f1c9b256c21..2d994211db38ae1f7c1306d03f0af43d3b5cfd6e 100644 (file)
@@ -58,6 +58,7 @@ class pkgRecords::Parser                                              /*{{{*/
    virtual string MD5Hash() {return string();};
    virtual string SHA1Hash() {return string();};
    virtual string SHA256Hash() {return string();};
+   virtual string SHA512Hash() {return string();};
    virtual string SourcePkg() {return string();};
    virtual string SourceVer() {return string();};
 
index 4a2f3f7e6ed76e3063f64142bb88ff0d1d6320bf..b7245073d3152237d22f36e95fea31244d797316 100644 (file)
@@ -457,6 +457,7 @@ static const char *iTFRewritePackageOrder[] = {
                           "MD5Sum",
                           "SHA1",
                           "SHA256",
+                          "SHA512",
                            "MSDOS-Filename",   // Obsolete
                           "Description",
                           0};
index 65eaef0d84d298bb492f80ac2dbebb0cfb71704b..66ebd30b817ee0e9cd8e8c8ee9cdd79f460e716c 100644 (file)
@@ -2299,6 +2299,8 @@ bool DoDownload(CommandLine &CmdL)
       strprintf(descr, _("Downloading %s %s"), Pkg.Name(), Ver.VerStr());
       // get the most appropriate hash
       HashString hash;
+      if (rec.SHA512Hash() != "")
+         hash = HashString("sha512", rec.SHA512Hash());
       if (rec.SHA256Hash() != "")
          hash = HashString("sha256", rec.SHA256Hash());
       else if (rec.SHA1Hash() != "")
index 71f64dc2347dcbf5f2f78b54082616605245a1c4..b144d35ad05e8a03b29d6bcd9e50132ad61b202e 100644 (file)
@@ -23,6 +23,9 @@ apt (0.8.15) UNRELEASED; urgency=low
   [ Stefano Zacchiroli ]
   * doc/external-dependency-solver-protocol.txt:
     - describe EDSP and the configuration interface around it
+  
+  [ Michael Vogt ]
+  * merge lp:~mvo/apt/sha512-template to add support for sha512
 
  -- David Kalnischkies <kalnischkies@gmail.com>  Tue, 17 May 2011 18:43:21 +0200
 
index b04244347f4bd258a0d593712a91287fc52eaafc..7e4c2e9fec82320baa16ea2739ff6e553dd2412f 100644 (file)
@@ -16,7 +16,7 @@
 #include <apt-pkg/error.h>
 #include <apt-pkg/md5.h>
 #include <apt-pkg/sha1.h>
-#include <apt-pkg/sha256.h>
+#include <apt-pkg/sha2.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/configuration.h>
     
@@ -162,7 +162,8 @@ bool CacheDB::GetCurStat()
 // ---------------------------------------------------------------------
 bool CacheDB::GetFileInfo(string const &FileName, bool const &DoControl, bool const &DoContents,
                                bool const &GenContentsOnly, bool const &DoMD5, bool const &DoSHA1,
-                               bool const &DoSHA256, bool const &checkMtime)
+                               bool const &DoSHA256,   bool const &DoSHA512, 
+                          bool const &checkMtime)
 {
        this->FileName = FileName;
 
@@ -190,7 +191,9 @@ bool CacheDB::GetFileInfo(string const &FileName, bool const &DoControl, bool co
                || (DoContents && LoadContents(GenContentsOnly) == false)
                || (DoMD5 && GetMD5(false) == false)
                || (DoSHA1 && GetSHA1(false) == false)
-               || (DoSHA256 && GetSHA256(false) == false))
+               || (DoSHA256 && GetSHA256(false) == false)
+               || (DoSHA512 && GetSHA512(false) == false)
+           )
        {
                delete Fd;
                Fd = NULL;
@@ -412,6 +415,37 @@ bool CacheDB::GetSHA256(bool const &GenOnly)
    return true;
 }
                                                                        /*}}}*/
+// CacheDB::GetSHA256 - Get the SHA256 hash                            /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool CacheDB::GetSHA512(bool const &GenOnly)
+{
+   // Try to read the control information out of the DB.
+   if ((CurStat.Flags & FlSHA512) == FlSHA512)
+   {
+      if (GenOnly == true)
+        return true;
+
+      SHA512Res = bytes2hex(CurStat.SHA512, sizeof(CurStat.SHA512));
+      return true;
+   }
+   
+   Stats.SHA512Bytes += CurStat.FileSize;
+        
+   if (Fd == NULL && OpenFile() == false)
+   {
+      return false;
+   }
+   SHA512Summation SHA512;
+   if (Fd->Seek(0) == false || SHA512.AddFD(Fd->Fd(),CurStat.FileSize) == false)
+      return false;
+   
+   SHA512Res = SHA512.Result();
+   hex2bytes(CurStat.SHA512, SHA512Res.data(), sizeof(CurStat.SHA512));
+   CurStat.Flags |= FlSHA512;
+   return true;
+}
+                                                                       /*}}}*/
 // CacheDB::Finish - Write back the cache structure                    /*{{{*/
 // ---------------------------------------------------------------------
 /* */
index 0ba80909ae557ae1737e137f440efd76881197dc..15e796325ea15aa6544a5beada700f74f742bfcf 100644 (file)
@@ -70,10 +70,13 @@ class CacheDB
    bool GetMD5(bool const &GenOnly);
    bool GetSHA1(bool const &GenOnly);
    bool GetSHA256(bool const &GenOnly);
+   bool GetSHA512(bool const &GenOnly);
    
    // Stat info stored in the DB, Fixed types since it is written to disk.
    enum FlagList {FlControl = (1<<0),FlMD5=(1<<1),FlContents=(1<<2),
-       FlSize=(1<<3), FlSHA1=(1<<4), FlSHA256=(1<<5)};
+                  FlSize=(1<<3), FlSHA1=(1<<4), FlSHA256=(1<<5), 
+                  FlSHA512=(1<<6)};
+
    struct StatStore
    {
       uint32_t Flags;
@@ -82,6 +85,7 @@ class CacheDB
       uint8_t  MD5[16];
       uint8_t  SHA1[20];
       uint8_t  SHA256[32];
+      uint8_t  SHA512[64];
    } CurStat;
    struct StatStore OldStat;
    
@@ -98,6 +102,7 @@ class CacheDB
    string MD5Res;
    string SHA1Res;
    string SHA256Res;
+   string SHA512Res;
    
    // Runtime statistics
    struct Stats
@@ -106,14 +111,21 @@ class CacheDB
       double MD5Bytes;
       double SHA1Bytes;
       double SHA256Bytes;
+      double SHA512Bytes;
       unsigned long Packages;
       unsigned long Misses;  
       unsigned long DeLinkBytes;
       
       inline void Add(const Stats &S) {
-        Bytes += S.Bytes; MD5Bytes += S.MD5Bytes; SHA1Bytes += S.SHA1Bytes; 
+        Bytes += S.Bytes; 
+         MD5Bytes += S.MD5Bytes; 
+         SHA1Bytes += S.SHA1Bytes; 
         SHA256Bytes += S.SHA256Bytes;
-        Packages += S.Packages; Misses += S.Misses; DeLinkBytes += S.DeLinkBytes;};
+        SHA512Bytes += S.SHA512Bytes;
+        Packages += S.Packages;
+         Misses += S.Misses; 
+         DeLinkBytes += S.DeLinkBytes;
+      };
       Stats() : Bytes(0), MD5Bytes(0), SHA1Bytes(0), SHA256Bytes(0), Packages(0), Misses(0), DeLinkBytes(0) {};
    } Stats;
    
@@ -125,7 +137,7 @@ class CacheDB
    
    bool SetFile(string const &FileName,struct stat St,FileFd *Fd);
    bool GetFileInfo(string const &FileName, bool const &DoControl, bool const &DoContents, bool const &GenContentsOnly,
-                   bool const &DoMD5, bool const &DoSHA1, bool const &DoSHA256, bool const &checkMtime = false);
+                   bool const &DoMD5, bool const &DoSHA1, bool const &DoSHA256, bool const &DoSHA512, bool const &checkMtime = false);
    bool Finish();   
    
    bool Clean();
index 9f12cbf3d0e749204a1782485b06b76a558baf19..eb8938b9594708bc69335fc3216a5b5740c55dba 100644 (file)
@@ -20,7 +20,7 @@
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/md5.h>
 #include <apt-pkg/sha1.h>
-#include <apt-pkg/sha256.h>
+#include <apt-pkg/sha2.h>
 #include <apt-pkg/deblistparser.h>
 
 #include <sys/types.h>
@@ -316,6 +316,7 @@ PackagesWriter::PackagesWriter(string const &DB,string const &Overrides,string c
    DoMD5 = _config->FindB("APT::FTPArchive::Packages::MD5",DoMD5);
    DoSHA1 = _config->FindB("APT::FTPArchive::Packages::SHA1",DoSHA1);
    DoSHA256 = _config->FindB("APT::FTPArchive::Packages::SHA256",DoSHA256);
+   DoSHA256 = _config->FindB("APT::FTPArchive::Packages::SHA512",true);
    DoAlwaysStat = _config->FindB("APT::FTPArchive::AlwaysStat", false);
    DoContents = _config->FindB("APT::FTPArchive::Contents",true);
    NoOverride = _config->FindB("APT::FTPArchive::NoOverrideMsg",false);
@@ -370,7 +371,7 @@ bool FTWScanner::SetExts(string const &Vals)
 bool PackagesWriter::DoPackage(string FileName)
 {      
    // Pull all the data we need form the DB
-   if (Db.GetFileInfo(FileName, true, DoContents, true, DoMD5, DoSHA1, DoSHA256, DoAlwaysStat)
+   if (Db.GetFileInfo(FileName, true, DoContents, true, DoMD5, DoSHA1, DoSHA256, DoSHA512, DoAlwaysStat)
                  == false)
    {
       return false;
@@ -446,6 +447,8 @@ bool PackagesWriter::DoPackage(string FileName)
       SetTFRewriteData(Changes[End++], "SHA1", Db.SHA1Res.c_str());
    if (DoSHA256 == true)
       SetTFRewriteData(Changes[End++], "SHA256", Db.SHA256Res.c_str());
+   if (DoSHA512 == true)
+      SetTFRewriteData(Changes[End++], "SHA512", Db.SHA512Res.c_str());
    SetTFRewriteData(Changes[End++], "Filename", NewFileName.c_str());
    SetTFRewriteData(Changes[End++], "Priority", OverItem->Priority.c_str());
    SetTFRewriteData(Changes[End++], "Status", 0);
@@ -623,6 +626,7 @@ bool SourcesWriter::DoPackage(string FileName)
    MD5Summation MD5;
    SHA1Summation SHA1;
    SHA256Summation SHA256;
+   SHA256Summation SHA512;
 
    if (DoMD5 == true)
       MD5.Add((unsigned char *)Start,BlkEnd - Start);
@@ -630,6 +634,8 @@ bool SourcesWriter::DoPackage(string FileName)
       SHA1.Add((unsigned char *)Start,BlkEnd - Start);
    if (DoSHA256 == true)
       SHA256.Add((unsigned char *)Start,BlkEnd - Start);
+   if (DoSHA512 == true)
+      SHA512.Add((unsigned char *)Start,BlkEnd - Start);
 
    // Add an extra \n to the end, just in case
    *BlkEnd++ = '\n';
@@ -740,6 +746,12 @@ bool SourcesWriter::DoPackage(string FileName)
                   << strippedName << "\n " << Tags.FindS("Checksums-Sha256");
    string const ChecksumsSha256 = ostreamSha256.str();
 
+   std::ostringstream ostreamSha512;
+   if (Tags.Exists("Checksums-Sha512"))
+      ostreamSha512 << "\n " << string(SHA512.Result()) << " " << St.st_size << " "
+                  << strippedName << "\n " << Tags.FindS("Checksums-Sha512");
+   string const ChecksumsSha512 = ostreamSha512.str();
+
    // Strip the DirStrip prefix from the FileName and add the PathPrefix
    string NewFileName;
    if (DirStrip.empty() == false &&
@@ -795,6 +807,8 @@ bool SourcesWriter::DoPackage(string FileName)
       SetTFRewriteData(Changes[End++],"Checksums-Sha1",ChecksumsSha1.c_str());
    if (ChecksumsSha256.empty() == false)
       SetTFRewriteData(Changes[End++],"Checksums-Sha256",ChecksumsSha256.c_str());
+   if (ChecksumsSha512.empty() == false)
+      SetTFRewriteData(Changes[End++],"Checksums-Sha512",ChecksumsSha512.c_str());
    if (Directory != "./")
       SetTFRewriteData(Changes[End++],"Directory",Directory.c_str());
    SetTFRewriteData(Changes[End++],"Priority",BestPrio.c_str());
@@ -1046,6 +1060,10 @@ bool ReleaseWriter::DoPackage(string FileName)
       CheckSums[NewFileName].SHA256 = SHA256.Result();
    }
 
+   SHA256Summation SHA512;
+   SHA256.AddFD(fd.Fd(), fd.Size());
+   CheckSums[NewFileName].SHA512 = SHA512.Result();
+
    fd.Close();
    
    return true;
@@ -1092,4 +1110,16 @@ void ReleaseWriter::Finish()
                 (*I).first.c_str());
       }
    }
+
+   fprintf(Output, "SHA512:\n");
+   for(map<string,struct CheckSum>::const_iterator I = CheckSums.begin();
+       I != CheckSums.end();
+       ++I)
+   {
+      fprintf(Output, " %s %32ld %s\n",
+              (*I).second.SHA512.c_str(),
+              (*I).second.size,
+              (*I).first.c_str());
+   }
+
 }
index ce0eab7af9642b6469b236bd417f9082af84e990..b8747decddd90cfbdaab3b6f68f0e590fe6fe16e 100644 (file)
@@ -195,6 +195,7 @@ protected:
       string MD5;
       string SHA1;
       string SHA256;
+      string SHA512;
       // Limited by FileFd::Size()
       unsigned long size;
       ~CheckSum() {};
index cfdb4ea9d430c46c7357854193101139181e1aff..88f09fca028ab7bf7cc97e3b96db7b9dd6117c30 100644 (file)
@@ -1,6 +1,6 @@
 #include <apt-pkg/md5.h>
 #include <apt-pkg/sha1.h>
-#include <apt-pkg/sha256.h>
+#include <apt-pkg/sha2.h>
 #include <apt-pkg/strutl.h>
 #include <iostream>
 
@@ -10,9 +10,17 @@ template <class T> void Test(const char *In,const char *Out)
 {
    T Sum;
    Sum.Add(In);
-   cout << Sum.Result().Value() << endl;
-   if (stringcasecmp(Sum.Result().Value(),Out) != 0)
+
+   cout << "expected: '" << Out << "'" << endl;
+   cout << "got     : '" << Sum.Result().Value() << "'" << endl;
+   cout << "got     : '" << Sum.Result().Value() << "'" << endl;
+   cout << "got     : '" << Sum.Result().Value() << "'" << endl;
+   if (stringcasecmp(Sum.Result().Value(), Out) != 0) {
+      cout << "FAIL" << endl << endl;
       abort();
+   } else {
+      cout << "PASS" << endl << endl;
+   }
 }
 
 template <class T> void TestMill(const char *Out)
@@ -34,9 +42,8 @@ template <class T> void TestMill(const char *Out)
         Count = 0;
       }
    }
-   
-   cout << Sum.Result().Value() << endl;
-   if (stringcasecmp(Sum.Result().Value(),Out) != 0)
+
+   if (stringcasecmp(Sum.Result().Value(), Out) != 0)
       abort();
 }
 
@@ -62,8 +69,13 @@ int main()
    // SHA-256, From FIPS 180-2
    Test<SHA256Summation>("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 
                         "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1");
-   
 
+   // SHA-512, From 
+   Test<SHA512Summation>(
+      "abc", 
+      "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
+      "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f");
+   
    return 0; 
 }