summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2021-07-24 16:38:43 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2021-07-24 16:38:43 +0700
commitceaebe902166d062635c444e2649c1a5849deaae (patch)
treec71f32288ad1d49e93fc61ec1ae203536a9211dd
parentRefactoring (diff)
downloadBouncyCastle.NET-ed25519-ceaebe902166d062635c444e2649c1a5849deaae.tar.xz
Calculate HMAC without extracting TlsSecret
-rw-r--r--crypto/src/tls/TlsUtilities.cs8
-rw-r--r--crypto/src/tls/crypto/TlsSecret.cs8
-rw-r--r--crypto/src/tls/crypto/impl/AbstractTlsSecret.cs13
-rw-r--r--crypto/test/src/tls/crypto/test/BcTlsCryptoTest.cs14
4 files changed, 25 insertions, 18 deletions
diff --git a/crypto/src/tls/TlsUtilities.cs b/crypto/src/tls/TlsUtilities.cs
index 4cec13bae..52b554801 100644
--- a/crypto/src/tls/TlsUtilities.cs
+++ b/crypto/src/tls/TlsUtilities.cs
@@ -1491,14 +1491,10 @@ namespace Org.BouncyCastle.Tls
                     :   securityParameters.BaseKeyClient;
 
                 TlsSecret finishedKey = DeriveSecret(securityParameters, baseKey, "finished", EmptyBytes);
+                int cryptoHashAlgorithm = TlsCryptoUtilities.GetHash(securityParameters.PrfHashAlgorithm);
                 byte[] transcriptHash = GetCurrentPrfHash(handshakeHash);
 
-                TlsCrypto crypto = context.Crypto;
-                byte[] hmacKey = crypto.AdoptSecret(finishedKey).Extract();
-                TlsHmac hmac = crypto.CreateHmacForHash(TlsCryptoUtilities.GetHash(securityParameters.PrfHashAlgorithm));
-                hmac.SetKey(hmacKey, 0, hmacKey.Length);
-                hmac.Update(transcriptHash, 0, transcriptHash.Length);
-                return hmac.CalculateMac();
+                return finishedKey.CalculateHmac(cryptoHashAlgorithm, transcriptHash, 0, transcriptHash.Length);
             }
 
             if (negotiatedVersion.IsSsl)
diff --git a/crypto/src/tls/crypto/TlsSecret.cs b/crypto/src/tls/crypto/TlsSecret.cs
index 0499d37c3..8c39c56f7 100644
--- a/crypto/src/tls/crypto/TlsSecret.cs
+++ b/crypto/src/tls/crypto/TlsSecret.cs
@@ -7,6 +7,14 @@ namespace Org.BouncyCastle.Tls.Crypto
     /// </summary>
     public interface TlsSecret
     {
+        /// <summary>Calculate an HMAC with this secret's data as the key.</summary>
+        /// <param name="cryptoHashAlgorithm">the hash algorithm to instantiate HMAC with. See
+        /// <see cref="CryptoHashAlgorithm"/> for values.</param>
+        /// <param name="buf">array containing the input data.</param>
+        /// <param name="off">offset into the input array the input starts at.</param>
+        /// <param name="len">the length of the input data.</param>
+        byte[] CalculateHmac(int cryptoHashAlgorithm, byte[] buf, int off, int len);
+
         /// <summary>Return a new secret based on applying a PRF to this one.</summary>
         /// <param name="prfAlgorithm">PRF algorithm to use.</param>
         /// <param name="label">the label details.</param>
diff --git a/crypto/src/tls/crypto/impl/AbstractTlsSecret.cs b/crypto/src/tls/crypto/impl/AbstractTlsSecret.cs
index e8298193f..1ea25344d 100644
--- a/crypto/src/tls/crypto/impl/AbstractTlsSecret.cs
+++ b/crypto/src/tls/crypto/impl/AbstractTlsSecret.cs
@@ -26,6 +26,19 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl
 
         protected abstract AbstractTlsCrypto Crypto { get; }
 
+        public virtual byte[] CalculateHmac(int cryptoHashAlgorithm, byte[] buf, int off, int len)
+        {
+            lock (this)
+            {
+                CheckAlive();
+
+                TlsHmac hmac = Crypto.CreateHmacForHash(cryptoHashAlgorithm);
+                hmac.SetKey(m_data, 0, m_data.Length);
+                hmac.Update(buf, off, len);
+                return hmac.CalculateMac();
+            }
+        }
+
         public abstract TlsSecret DeriveUsingPrf(int prfAlgorithm, string label, byte[] seed, int length);
 
         public virtual void Destroy()
diff --git a/crypto/test/src/tls/crypto/test/BcTlsCryptoTest.cs b/crypto/test/src/tls/crypto/test/BcTlsCryptoTest.cs
index a57212c73..cf1397ef2 100644
--- a/crypto/test/src/tls/crypto/test/BcTlsCryptoTest.cs
+++ b/crypto/test/src/tls/crypto/test/BcTlsCryptoTest.cs
@@ -311,7 +311,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Tests
                 byte[] transcriptHash = GetCurrentHash(prfHash);
                 Expect(transcriptHash, "ed b7 72 5f a7 a3 47 3b 03 1e c8 ef 65 a2 48 54 93 90 01 38 a2 b9 12 91 40 7d 79 51 a0 61 10 ed");
 
-                byte[] finished = CalculateHmac(hash, expanded, transcriptHash);
+                byte[] finished = expanded.CalculateHmac(hash, transcriptHash, 0, transcriptHash.Length);
                 Expect(finished, Hex("9b 9b 14 1d 90 63 37 fb d2 cb dc e7 1d f4 de da 4a b4 2c 30 95 72 cb 7f ff ee 54 54 b7 8f 07 18"));
             }
 
@@ -365,7 +365,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Tests
                 Expect(expanded, "b8 0a d0 10 15 fb 2f 0b d6 5f f7 d4 da 5d 6b f8 3f 84 82 1d 1f 87 fd c7 d3 c7 5b 5a 7b 42 d9 c4");
 
                 // TODO Mention this transcript hash in RFC 8448 data?
-                byte[] finished = CalculateHmac(hash, expanded, serverFinishedTranscriptHash);
+                byte[] finished = expanded.CalculateHmac(hash, serverFinishedTranscriptHash, 0, serverFinishedTranscriptHash.Length);
                 Expect(finished, Hex("a8 ec 43 6d 67 76 34 ae 52 5a c1 fc eb e1 1a 03 9e c1 76 94 fa c6 e9 85 27 b6 42 f2 ed d5 ce 61"));
             }
 
@@ -546,16 +546,6 @@ namespace Org.BouncyCastle.Tls.Crypto.Tests
             }
         }
 
-        private byte[] CalculateHmac(int cryptoHashAlgorithm, TlsSecret hmacKey, byte[] hmacInput)
-        {
-            byte[] keyBytes = Extract(hmacKey);
-
-            TlsHmac hmac = m_crypto.CreateHmacForHash(cryptoHashAlgorithm);
-            hmac.SetKey(keyBytes, 0, keyBytes.Length);
-            hmac.Update(hmacInput, 0, hmacInput.Length);
-            return hmac.CalculateMac();
-        }
-
         private void Expect(TlsSecret secret, string expectedHex)
         {
             Expect(Extract(secret), Hex(expectedHex));