]> git.deb.at Git - rhonda/impostor.hazel.git/commitdiff
Stream data blocks directly to SHA256
authorMatthew Endsley <mendsley@gmail.com>
Wed, 14 Apr 2021 00:21:27 +0000 (17:21 -0700)
committerMatthew Endsley <mendsley@gmail.com>
Wed, 14 Apr 2021 00:22:02 +0000 (17:22 -0700)
This removes the need to buffer all data in a MemoryStream to simply
hash it when required.

Hazel/Crypto/Sha256Stream.cs

index 8fb53cd70b0da6205df913569ec66f56b541b27b..0c23f89f6ff72d000d45acdbb85f5f9b82d20725 100644 (file)
@@ -1,5 +1,4 @@
 using System;
-using System.IO;
 using System.Security.Cryptography;
 
 namespace Hazel.Crypto
@@ -14,7 +13,12 @@ namespace Hazel.Crypto
         /// </summary>
         public const int DigestSize = 32;
 
-        private MemoryStream innerStream = new MemoryStream();
+        private SHA256 hash = SHA256.Create();
+
+        struct EmptyArray
+        {
+            public static readonly byte[] Value = new byte[0];
+        }
 
         /// <summary>
         /// Create a new instance of a SHA256 stream
@@ -28,12 +32,8 @@ namespace Hazel.Crypto
         /// </summary>
         public void Dispose()
         {
-            if  (this.innerStream != null)
-            {
-                this.Reset();
-                this.innerStream.Dispose();
-                this.innerStream = null;
-            }
+            this.hash?.Dispose();
+            this.hash = null;
 
             GC.SuppressFinalize(this);
         }
@@ -43,10 +43,8 @@ namespace Hazel.Crypto
         /// </summary>
         public void Reset()
         {
-            ByteSpan buffer = this.innerStream.GetBuffer();
-            buffer.SecureClear();
-
-            this.innerStream.SetLength(0);
+            this.hash?.Dispose();
+            this.hash = SHA256.Create();
         }
 
         /// <summary>
@@ -54,7 +52,11 @@ namespace Hazel.Crypto
         /// </summary>
         public void AddData(ByteSpan data)
         {
-            this.innerStream.Write(data.GetUnderlyingArray(), data.Offset, data.Length);
+            while (data.Length > 0)
+            {
+                int offset = this.hash.TransformBlock(data.GetUnderlyingArray(), data.Offset, data.Length, null, 0);
+                data = data.Slice(offset);
+            }
         }
 
         /// <summary>
@@ -70,12 +72,8 @@ namespace Hazel.Crypto
                 throw new ArgumentException($"Expected a span of {DigestSize} bytes. Got a span of {output.Length} bytes", nameof(output));
             }
 
-            using (SHA256 sha256 = SHA256.Create())
-            {
-                this.innerStream.Position = 0;
-                ByteSpan digest = sha256.ComputeHash(this.innerStream);
-                digest.CopyTo(output);
-            }
+            this.hash.TransformFinalBlock(EmptyArray.Value, 0, 0);
+            new ByteSpan(this.hash.Hash).CopyTo(output);
         }
     }
 }