]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/sha1.c
Added fix for bug #1275 where acl or xattr data is saved for virtual filenames genera...
[bacula/bacula] / bacula / src / lib / sha1.c
index 063fad0e9436f5c18fc843dbc28668ed11045595..9fd9e40e2b150e42f73c2ec04695efacf85f746a 100644 (file)
@@ -2,30 +2,30 @@
  *  sha1.c
  *
  *  Description:
- *     This file implements the Secure Hashing Algorithm 1 as
- *     defined in FIPS PUB 180-1 published April 17, 1995.
+ *      This file implements the Secure Hashing Algorithm 1 as
+ *      defined in FIPS PUB 180-1 published April 17, 1995.
  *
- *     The SHA-1, produces a 160-bit message digest for a given
- *     data stream.  It should take about 2**n steps to find a
- *     message with the same digest as a given message and
- *     2**(n/2) to find any two messages with the same digest,
- *     when n is the digest size in bits.  Therefore, this
- *     algorithm can serve as a means of providing a
+ *      The SHA-1, produces a 160-bit message digest for a given
+ *      data stream.  It should take about 2**n steps to find a
+ *      message with the same digest as a given message and
+ *      2**(n/2) to find any two messages with the same digest,
+ *      when n is the digest size in bits.  Therefore, this
+ *      algorithm can serve as a means of providing a
  *      "fingerprint" for a message.
  *
  *  Portability Issues:
  *      SHA-1 is defined in terms of 32-bit "words".  This code
  *      uses <stdint.h> (included via "sha1.h" to define 32 and 8
- *     bit unsigned integer types.  If your C compiler does not
- *     support 32 bit unsigned integers, this code is not
- *     appropriate.
+ *      bit unsigned integer types.  If your C compiler does not
+ *      support 32 bit unsigned integers, this code is not
+ *      appropriate.
  *
  *  Caveats:
- *     SHA-1 is designed to work with messages less than 2^64 bits
- *     long.  Although SHA-1 allows a message digest to be generated
- *     for messages of any number of bits less than 2^64, this
- *     implementation only works with messages with a length that is
- *     a multiple of the size of an 8-bit character.
+ *      SHA-1 is designed to work with messages less than 2^64 bits
+ *      long.  Although SHA-1 allows a message digest to be generated
+ *      for messages of any number of bits less than 2^64, this
+ *      implementation only works with messages with a length that is
+ *      a multiple of the size of an 8-bit character.
  *
  *  See sha1.h for copyright
  */
@@ -36,7 +36,7 @@
  *  Define the SHA1 circular left shift macro
  */
 #define SHA1CircularShift(bits,word) \
-               (((word) << (bits)) | ((word) >> (32-(bits))))
+                (((word) << (bits)) | ((word) >> (32-(bits))))
 
 /* Local Function Prototyptes */
 static void SHA1PadMessage(SHA1Context *);
@@ -46,26 +46,26 @@ static void SHA1ProcessMessageBlock(SHA1Context *);
  *  SHA1Init
  *
  *  Description:
- *     This function will initialize the SHA1Context in preparation
- *     for computing a new SHA1 message digest.
+ *      This function will initialize the SHA1Context in preparation
+ *      for computing a new SHA1 message digest.
  *
  *  Parameters:
- *     context: [in/out]
- *         The context to reset.
+ *      context: [in/out]
+ *          The context to reset.
  *
  *  Returns:
- *     sha Error Code.
+ *      sha Error Code.
  *
  */
 int SHA1Init(SHA1Context *context)
 {
     if (!context)
     {
-       return shaNull;
+        return shaNull;
     }
 
-    context->Length_Low            = 0;
-    context->Length_High           = 0;
+    context->Length_Low             = 0;
+    context->Length_High            = 0;
     context->Message_Block_Index    = 0;
 
     context->Intermediate_Hash[0]   = 0x67452301;
@@ -74,8 +74,8 @@ int SHA1Init(SHA1Context *context)
     context->Intermediate_Hash[3]   = 0x10325476;
     context->Intermediate_Hash[4]   = 0xC3D2E1F0;
 
-    context->Computed  = 0;
-    context->Corrupted = 0;
+    context->Computed   = 0;
+    context->Corrupted  = 0;
 
     return shaSuccess;
 }
@@ -84,49 +84,49 @@ int SHA1Init(SHA1Context *context)
  *  SHA1Final
  *
  *  Description:
- *     This function will return the 160-bit message digest into the
- *     Message_Digest array  provided by the caller.
- *     NOTE: The first octet of hash is stored in the 0th element,
- *           the last octet of hash in the 19th element.
+ *      This function will return the 160-bit message digest into the
+ *      Message_Digest array  provided by the caller.
+ *      NOTE: The first octet of hash is stored in the 0th element,
+ *            the last octet of hash in the 19th element.
  *
  *  Parameters:
- *     context: [in/out]
- *         The context to use to calculate the SHA-1 hash.
- *     Message_Digest: [out]
- *         Where the digest is returned.
+ *      context: [in/out]
+ *          The context to use to calculate the SHA-1 hash.
+ *      Message_Digest: [out]
+ *          Where the digest is returned.
  *
  *  Returns:
- *     sha Error Code.
+ *      sha Error Code.
  *
  */
 int SHA1Final(SHA1Context *context,
-             uint8_t Message_Digest[SHA1HashSize])
+              uint8_t Message_Digest[SHA1HashSize])
 {
     int i;
 
     if (!context || !Message_Digest) {
-       return shaNull;
+        return shaNull;
     }
 
     if (context->Corrupted) {
-       return context->Corrupted;
+        return context->Corrupted;
     }
 
     if (!context->Computed) {
-       SHA1PadMessage(context);
-       for(i=0; i<64; ++i) {
-           /* message may be sensitive, clear it out */
-           context->Message_Block[i] = 0;
-       }
-       context->Length_Low = 0;    /* and clear length */
-       context->Length_High = 0;
-       context->Computed = 1;
+        SHA1PadMessage(context);
+        for(i=0; i<64; ++i) {
+            /* message may be sensitive, clear it out */
+            context->Message_Block[i] = 0;
+        }
+        context->Length_Low = 0;    /* and clear length */
+        context->Length_High = 0;
+        context->Computed = 1;
 
     }
 
     for(i = 0; i < SHA1HashSize; ++i) {
-       Message_Digest[i] = context->Intermediate_Hash[i>>2]
-                           >> 8 * ( 3 - ( i & 0x03 ) );
+        Message_Digest[i] = context->Intermediate_Hash[i>>2]
+                            >> 8 * ( 3 - ( i & 0x03 ) );
     }
 
     return shaSuccess;
@@ -136,58 +136,58 @@ int SHA1Final(SHA1Context *context,
  *  SHA1Update
  *
  *  Description:
- *     This function accepts an array of octets as the next portion
- *     of the message.
+ *      This function accepts an array of octets as the next portion
+ *      of the message.
  *
  *  Parameters:
- *     context: [in/out]
- *         The SHA context to update
- *     message_array: [in]
- *         An array of characters representing the next portion of
- *         the message.
- *     length: [in]
- *         The length of the message in message_array
+ *      context: [in/out]
+ *          The SHA context to update
+ *      message_array: [in]
+ *          An array of characters representing the next portion of
+ *          the message.
+ *      length: [in]
+ *          The length of the message in message_array
  *
  *  Returns:
- *     sha Error Code.
+ *      sha Error Code.
  *
  */
 int SHA1Update(SHA1Context    *context,
-              const uint8_t  *message_array,
-              unsigned       length)
+               const uint8_t  *message_array,
+               unsigned       length)
 {
     if (!length) {
-       return shaSuccess;
+        return shaSuccess;
     }
 
     if (!context || !message_array) {
-       return shaNull;
+        return shaNull;
     }
 
     if (context->Computed) {
-       context->Corrupted = shaStateError;
+        context->Corrupted = shaStateError;
 
-       return shaStateError;
+        return shaStateError;
     }
 
     if (context->Corrupted) {
-        return context->Corrupted;
+         return context->Corrupted;
     }
     while(length-- && !context->Corrupted) {
        context->Message_Block[context->Message_Block_Index++] =
-                   (*message_array & 0xFF);
+                    (*message_array & 0xFF);
 
        context->Length_Low += 8;
        if (context->Length_Low == 0) {
-          context->Length_High++;
-          if (context->Length_High == 0) {
-              /* Message is too long */
-              context->Corrupted = 1;
-          }
+           context->Length_High++;
+           if (context->Length_High == 0) {
+               /* Message is too long */
+               context->Corrupted = 1;
+           }
        }
 
        if (context->Message_Block_Index == 64) {
-          SHA1ProcessMessageBlock(context);
+           SHA1ProcessMessageBlock(context);
        }
 
        message_array++;
@@ -200,44 +200,44 @@ int SHA1Update(SHA1Context    *context,
  *  SHA1ProcessMessageBlock
  *
  *  Description:
- *     This function will process the next 512 bits of the message
- *     stored in the Message_Block array.
+ *      This function will process the next 512 bits of the message
+ *      stored in the Message_Block array.
  *
  *  Parameters:
- *     None.
+ *      None.
  *
  *  Returns:
- *     Nothing.
+ *      Nothing.
  *
  *  Comments:
 
- *     Many of the variable names in this code, especially the
- *     single character names, were used because those were the
- *     names used in the publication.
+ *      Many of the variable names in this code, especially the
+ *      single character names, were used because those were the
+ *      names used in the publication.
  *
  *
  */
 static void SHA1ProcessMessageBlock(SHA1Context *context)
 {
-    const uint32_t K[] =    {      /* Constants defined in SHA-1   */
-                           0x5A827999,
-                           0x6ED9EBA1,
-                           0x8F1BBCDC,
-                           0xCA62C1D6
-                           };
-    int          t;                 /* Loop counter                */
-    uint32_t     temp;              /* Temporary word value        */
-    uint32_t     W[80];             /* Word sequence               */
-    uint32_t     A, B, C, D, E;     /* Word buffers                */
+    const uint32_t K[] =    {       /* Constants defined in SHA-1   */
+                            0x5A827999,
+                            0x6ED9EBA1,
+                            0x8F1BBCDC,
+                            0xCA62C1D6
+                            };
+    int           t;                 /* Loop counter                */
+    uint32_t      temp;              /* Temporary word value        */
+    uint32_t      W[80];             /* Word sequence               */
+    uint32_t      A, B, C, D, E;     /* Word buffers                */
 
     /*
-     * Initialize the first 16 words in the array W
+     *  Initialize the first 16 words in the array W
      */
     for(t = 0; t < 16; t++) {
-       W[t] = context->Message_Block[t * 4] << 24;
-       W[t] |= context->Message_Block[t * 4 + 1] << 16;
-       W[t] |= context->Message_Block[t * 4 + 2] << 8;
-       W[t] |= context->Message_Block[t * 4 + 3];
+        W[t] = context->Message_Block[t * 4] << 24;
+        W[t] |= context->Message_Block[t * 4 + 1] << 16;
+        W[t] |= context->Message_Block[t * 4 + 2] << 8;
+        W[t] |= context->Message_Block[t * 4 + 3];
     }
 
     for(t = 16; t < 80; t++) {
@@ -251,42 +251,42 @@ static void SHA1ProcessMessageBlock(SHA1Context *context)
     E = context->Intermediate_Hash[4];
 
     for(t = 0; t < 20; t++) {
-       temp =  SHA1CircularShift(5,A) +
-               ((B & C) | ((~B) & D)) + E + W[t] + K[0];
-       E = D;
-       D = C;
-       C = SHA1CircularShift(30,B);
-
-       B = A;
-       A = temp;
+        temp =  SHA1CircularShift(5,A) +
+                ((B & C) | ((~B) & D)) + E + W[t] + K[0];
+        E = D;
+        D = C;
+        C = SHA1CircularShift(30,B);
+
+        B = A;
+        A = temp;
     }
 
     for(t = 20; t < 40; t++) {
-       temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
-       E = D;
-       D = C;
-       C = SHA1CircularShift(30,B);
-       B = A;
-       A = temp;
+        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
+        E = D;
+        D = C;
+        C = SHA1CircularShift(30,B);
+        B = A;
+        A = temp;
     }
 
     for(t = 40; t < 60; t++) {
-       temp = SHA1CircularShift(5,A) +
-              ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
-       E = D;
-       D = C;
-       C = SHA1CircularShift(30,B);
-       B = A;
-       A = temp;
+        temp = SHA1CircularShift(5,A) +
+               ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
+        E = D;
+        D = C;
+        C = SHA1CircularShift(30,B);
+        B = A;
+        A = temp;
     }
 
     for(t = 60; t < 80; t++) {
-       temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
-       E = D;
-       D = C;
-       C = SHA1CircularShift(30,B);
-       B = A;
-       A = temp;
+        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
+        E = D;
+        D = C;
+        C = SHA1CircularShift(30,B);
+        B = A;
+        A = temp;
     }
 
     context->Intermediate_Hash[0] += A;
@@ -303,54 +303,54 @@ static void SHA1ProcessMessageBlock(SHA1Context *context)
  *
 
  *  Description:
- *     According to the standard, the message must be padded to an even
+ *      According to the standard, the message must be padded to an even
  *      512 bits.  The first padding bit must be a '1'.  The last 64
- *     bits represent the length of the original message.  All bits in
- *     between should be 0.  This function will pad the message
- *     according to those rules by filling the Message_Block array
- *     accordingly.  It will also call the ProcessMessageBlock function
- *     provided appropriately.  When it returns, it can be assumed that
- *     the message digest has been computed.
+ *      bits represent the length of the original message.  All bits in
+ *      between should be 0.  This function will pad the message
+ *      according to those rules by filling the Message_Block array
+ *      accordingly.  It will also call the ProcessMessageBlock function
+ *      provided appropriately.  When it returns, it can be assumed that
+ *      the message digest has been computed.
  *
  *  Parameters:
- *     context: [in/out]
- *         The context to pad
- *     ProcessMessageBlock: [in]
- *         The appropriate SHA*ProcessMessageBlock function
+ *      context: [in/out]
+ *          The context to pad
+ *      ProcessMessageBlock: [in]
+ *          The appropriate SHA*ProcessMessageBlock function
  *  Returns:
- *     Nothing.
+ *      Nothing.
  *
  */
 
 static void SHA1PadMessage(SHA1Context *context)
 {
     /*
-     * Check to see if the current message block is too small to hold
-     * the initial padding bits and length.  If so, we will pad the
-     * block, process it, and then continue padding into a second
-     * block.
+     *  Check to see if the current message block is too small to hold
+     *  the initial padding bits and length.  If so, we will pad the
+     *  block, process it, and then continue padding into a second
+     *  block.
      */
     if (context->Message_Block_Index > 55) {
-       context->Message_Block[context->Message_Block_Index++] = 0x80;
-       while(context->Message_Block_Index < 64) {
-           context->Message_Block[context->Message_Block_Index++] = 0;
-       }
+        context->Message_Block[context->Message_Block_Index++] = 0x80;
+        while(context->Message_Block_Index < 64) {
+            context->Message_Block[context->Message_Block_Index++] = 0;
+        }
 
-       SHA1ProcessMessageBlock(context);
+        SHA1ProcessMessageBlock(context);
 
-       while(context->Message_Block_Index < 56) {
-           context->Message_Block[context->Message_Block_Index++] = 0;
-       }
+        while(context->Message_Block_Index < 56) {
+            context->Message_Block[context->Message_Block_Index++] = 0;
+        }
     } else {
-       context->Message_Block[context->Message_Block_Index++] = 0x80;
-       while(context->Message_Block_Index < 56) {
+        context->Message_Block[context->Message_Block_Index++] = 0x80;
+        while(context->Message_Block_Index < 56) {
 
-           context->Message_Block[context->Message_Block_Index++] = 0;
-       }
+            context->Message_Block[context->Message_Block_Index++] = 0;
+        }
     }
 
     /*
-     * Store the message length as the last 8 octets
+     *  Store the message length as the last 8 octets
      */
     context->Message_Block[56] = context->Length_High >> 24;
     context->Message_Block[57] = context->Length_High >> 16;
@@ -370,13 +370,13 @@ static void SHA1PadMessage(SHA1Context *context)
  *  sha1test.c
  *
  *  Description:
- *     This file will exercise the SHA-1 code performing the three
- *     tests documented in FIPS PUB 180-1 plus one which calls
- *     SHA1Input with an exact multiple of 512 bits, plus a few
- *     error test checks.
+ *      This file will exercise the SHA-1 code performing the three
+ *      tests documented in FIPS PUB 180-1 plus one which calls
+ *      SHA1Input with an exact multiple of 512 bits, plus a few
+ *      error test checks.
  *
  *  Portability Issues:
- *     None.
+ *      None.
  *
  */
 
@@ -392,12 +392,12 @@ static void SHA1PadMessage(SHA1Context *context)
 #define TEST2a  "abcdbcdecdefdefgefghfghighijhi"
 
 #define TEST2b  "jkijkljklmklmnlmnomnopnopq"
-#define TEST2  TEST2a TEST2b
+#define TEST2   TEST2a TEST2b
 #define TEST3   "a"
 #define TEST4a  "01234567012345670123456701234567"
 #define TEST4b  "01234567012345670123456701234567"
     /* an exact multiple of 512 bits */
-#define TEST4  TEST4a TEST4b
+#define TEST4   TEST4a TEST4b
 char *testarray[4] =
 {
     TEST1,
@@ -421,47 +421,47 @@ int main()
     uint8_t Message_Digest[20];
 
     /*
-     * Perform SHA-1 tests
+     *  Perform SHA-1 tests
      */
     for(j = 0; j < 4; ++j) {
-       printf( "\nTest %d: %d, '%s'\n",
-               j+1,
-               repeatcount[j],
-               testarray[j]);
-
-       err = SHA1Init(&sha);
-       if (err) {
-           fprintf(stderr, "SHA1Reset Error %d.\n", err );
-           break;    /* out of for j loop */
-       }
-
-       for(i = 0; i < repeatcount[j]; ++i) {
-
-           err = SHA1Input(&sha,
-                 (const unsigned char *) testarray[j],
-                 strlen(testarray[j]));
-           if (err) {
-               fprintf(stderr, "SHA1Input Error %d.\n", err );
-               break;    /* out of for i loop */
-           }
-       }
-
-       err = SHA1Final(&sha, Message_Digest);
-       if (err) {
-           fprintf(stderr,
-           "SHA1Result Error %d, could not compute message digest.\n",
-           err );
-       }
-       else
-       {
-           printf("\t");
-           for(i = 0; i < 20 ; ++i) {
-               printf("%02X ", Message_Digest[i]);
-           }
-           printf("\n");
-       }
-       printf("Should match:\n");
-       printf("\t%s\n", resultarray[j]);
+        printf( "\nTest %d: %d, '%s'\n",
+                j+1,
+                repeatcount[j],
+                testarray[j]);
+
+        err = SHA1Init(&sha);
+        if (err) {
+            fprintf(stderr, "SHA1Reset Error %d.\n", err );
+            break;    /* out of for j loop */
+        }
+
+        for(i = 0; i < repeatcount[j]; ++i) {
+
+            err = SHA1Input(&sha,
+                  (const unsigned char *) testarray[j],
+                  strlen(testarray[j]));
+            if (err) {
+                fprintf(stderr, "SHA1Input Error %d.\n", err );
+                break;    /* out of for i loop */
+            }
+        }
+
+        err = SHA1Final(&sha, Message_Digest);
+        if (err) {
+            fprintf(stderr,
+            "SHA1Result Error %d, could not compute message digest.\n",
+            err );
+        }
+        else
+        {
+            printf("\t");
+            for(i = 0; i < 20 ; ++i) {
+                printf("%02X ", Message_Digest[i]);
+            }
+            printf("\n");
+        }
+        printf("Should match:\n");
+        printf("\t%s\n", resultarray[j]);
     }
 
     /* Test some error returns */
@@ -492,7 +492,8 @@ int main(int argc, char *argv[])
    }
    fd = fopen(argv[1], "rb");
    if (!fd) {
-      printf("Could not open %s: ERR=%s\n", argv[1], strerror(errno));
+      berrno be;
+      printf("Could not open %s: ERR=%s\n", argv[1], be.bstrerror(errno));
       exit(1);
    }
    SHA1Init(&ctx);