openat: detect Solaris fchownat bug
[pspp] / lib / sha512.c
index 66cfaa9bfc18a9465fce6cd7999661593770e2ca..becafaee845add178d15fe7cb095faf868d0c9ba 100644 (file)
@@ -25,6 +25,7 @@
 #include "sha512.h"
 
 #include <stddef.h>
+#include <stdlib.h>
 #include <string.h>
 
 #if USE_UNLOCKED_IO
@@ -45,7 +46,7 @@
                         u64shr (n, 56))))
 #endif
 
-#define BLOCKSIZE 4096
+#define BLOCKSIZE 32768
 #if BLOCKSIZE % 128 != 0
 # error "invalid BLOCKSIZE"
 #endif
@@ -141,10 +142,14 @@ sha512_conclude_ctx (struct sha512_ctx *ctx)
   if (u64lt (ctx->total[0], u64lo (bytes)))
     ctx->total[1] = u64plus (ctx->total[1], u64lo (1));
 
-  /* Put the 128-bit file length in *bits* at the end of the buffer.  */
-  ctx->buffer[size - 2] = SWAP (u64or (u64shl (ctx->total[1], 3),
-                                      u64shr (ctx->total[0], 61)));
-  ctx->buffer[size - 1] = SWAP (u64shl (ctx->total[0], 3));
+  /* Put the 128-bit file length in *bits* at the end of the buffer.
+     Use set_uint64 rather than a simple assignment, to avoid risk of
+     unaligned access.  */
+  set_uint64 ((char *) &ctx->buffer[size - 2],
+             SWAP (u64or (u64shl (ctx->total[1], 3),
+                          u64shr (ctx->total[0], 61))));
+  set_uint64 ((char *) &ctx->buffer[size - 1],
+             SWAP (u64shl (ctx->total[0], 3)));
 
   memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 8 - bytes);
 
@@ -173,9 +178,12 @@ int
 sha512_stream (FILE *stream, void *resblock)
 {
   struct sha512_ctx ctx;
-  char buffer[BLOCKSIZE + 72];
   size_t sum;
 
+  char *buffer = malloc (BLOCKSIZE + 72);
+  if (!buffer)
+    return 1;
+
   /* Initialize the computation context.  */
   sha512_init_ctx (&ctx);
 
@@ -204,7 +212,10 @@ sha512_stream (FILE *stream, void *resblock)
                 exit the loop after a partial read due to e.g., EAGAIN
                 or EWOULDBLOCK.  */
              if (ferror (stream))
-               return 1;
+               {
+                 free (buffer);
+                 return 1;
+               }
              goto process_partial_block;
            }
 
@@ -229,6 +240,7 @@ sha512_stream (FILE *stream, void *resblock)
 
   /* Construct result in desired memory.  */
   sha512_finish_ctx (&ctx, resblock);
+  free (buffer);
   return 0;
 }
 
@@ -237,9 +249,12 @@ int
 sha384_stream (FILE *stream, void *resblock)
 {
   struct sha512_ctx ctx;
-  char buffer[BLOCKSIZE + 72];
   size_t sum;
 
+  char *buffer = malloc (BLOCKSIZE + 72);
+  if (!buffer)
+    return 1;
+
   /* Initialize the computation context.  */
   sha384_init_ctx (&ctx);
 
@@ -268,7 +283,10 @@ sha384_stream (FILE *stream, void *resblock)
                 exit the loop after a partial read due to e.g., EAGAIN
                 or EWOULDBLOCK.  */
              if (ferror (stream))
-               return 1;
+               {
+                 free (buffer);
+                 return 1;
+               }
              goto process_partial_block;
            }
 
@@ -293,6 +311,7 @@ sha384_stream (FILE *stream, void *resblock)
 
   /* Construct result in desired memory.  */
   sha384_finish_ctx (&ctx, resblock);
+  free (buffer);
   return 0;
 }