summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2021-07-26 15:01:25 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2021-07-26 15:01:25 +0700
commit188375136654c8c065b19aaf271c192022a5f58f (patch)
tree5db34aab5a15f0812734b2baf03f9face41560bd
parentInitial fix for reneg issue (diff)
downloadBouncyCastle.NET-ed25519-188375136654c8c065b19aaf271c192022a5f58f.tar.xz
PSK binder based on explicit PRF hash
-rw-r--r--crypto/src/tls/SecurityParameters.cs6
-rw-r--r--crypto/src/tls/TlsUtilities.cs67
2 files changed, 29 insertions, 44 deletions
diff --git a/crypto/src/tls/SecurityParameters.cs b/crypto/src/tls/SecurityParameters.cs
index a04c0af8c..1f63f6f33 100644
--- a/crypto/src/tls/SecurityParameters.cs
+++ b/crypto/src/tls/SecurityParameters.cs
@@ -13,7 +13,6 @@ namespace Org.BouncyCastle.Tls
         internal short m_maxFragmentLength = -1;
         internal int m_prfAlgorithm = -1;
         internal int m_prfCryptoHashAlgorithm = -1;
-        internal short m_prfHashAlgorithm = -1;
         internal int m_prfHashLength = -1;
         internal int m_verifyDataLength = -1;
         internal TlsSecret m_baseKeyClient = null;
@@ -244,11 +243,6 @@ namespace Org.BouncyCastle.Tls
             get { return m_prfCryptoHashAlgorithm; }
         }
 
-        public short PrfHashAlgorithm
-        {
-            get { return m_prfHashAlgorithm; }
-        }
-
         public int PrfHashLength
         {
             get { return m_prfHashLength; }
diff --git a/crypto/src/tls/TlsUtilities.cs b/crypto/src/tls/TlsUtilities.cs
index 252c385e1..c0ccfe9be 100644
--- a/crypto/src/tls/TlsUtilities.cs
+++ b/crypto/src/tls/TlsUtilities.cs
@@ -1462,13 +1462,21 @@ namespace Org.BouncyCastle.Tls
         private static byte[] CalculateFinishedHmac(SecurityParameters securityParameters, TlsSecret baseKey,
             byte[] transcriptHash)
         {
-            int cryptoHashAlgorithm = securityParameters.PrfCryptoHashAlgorithm;
-            TlsSecret finishedKey = TlsCryptoUtilities.HkdfExpandLabel(baseKey, cryptoHashAlgorithm, "finished",
-                EmptyBytes, securityParameters.PrfHashLength);
+            int prfCryptoHashAlgorithm = securityParameters.PrfCryptoHashAlgorithm;
+            int prfHashLength = securityParameters.PrfHashLength;
+
+            return CalculateFinishedHmac(prfCryptoHashAlgorithm, prfHashLength, baseKey, transcriptHash);
+        }
+
+        private static byte[] CalculateFinishedHmac(int prfCryptoHashAlgorithm, int prfHashLength, TlsSecret baseKey,
+            byte[] transcriptHash)
+        {
+            TlsSecret finishedKey = TlsCryptoUtilities.HkdfExpandLabel(baseKey, prfCryptoHashAlgorithm, "finished",
+                EmptyBytes, prfHashLength);
 
             try
             {
-                return finishedKey.CalculateHmac(cryptoHashAlgorithm, transcriptHash, 0, transcriptHash.Length);
+                return finishedKey.CalculateHmac(prfCryptoHashAlgorithm, transcriptHash, 0, transcriptHash.Length);
             }
             finally
             {
@@ -1496,21 +1504,21 @@ namespace Org.BouncyCastle.Tls
             return Prf(sp, preMasterSecret, asciiLabel, seed, 48);
         }
 
-        internal static byte[] CalculatePskBinder(TlsContext context, bool isExternalPsk, TlsSecret earlySecret,
-            byte[] transcriptHash)
+        internal static byte[] CalculatePskBinder(TlsCrypto crypto, bool isExternalPsk, int pskPRFAlgorithm,
+            TlsSecret earlySecret, byte[] transcriptHash)
         {
-            TlsCrypto crypto = context.Crypto;
-            SecurityParameters securityParameters = context.SecurityParameters;
-            int cryptoHashAlgorithm = securityParameters.PrfCryptoHashAlgorithm;
+            int prfCryptoHashAlgorithm = TlsCryptoUtilities.GetHashForPrf(pskPRFAlgorithm);
+            int prfHashLength = TlsCryptoUtilities.GetHashOutputSize(prfCryptoHashAlgorithm);
 
             string label = isExternalPsk ? "ext binder" : "res binder";
-            byte[] emptyTranscriptHash = crypto.CreateHash(cryptoHashAlgorithm).CalculateHash();
+            byte[] emptyTranscriptHash = crypto.CreateHash(prfCryptoHashAlgorithm).CalculateHash();
 
-            TlsSecret binderKey = DeriveSecret(securityParameters, earlySecret, label, emptyTranscriptHash);
+            TlsSecret binderKey = DeriveSecret(prfCryptoHashAlgorithm, prfHashLength, earlySecret, label,
+                emptyTranscriptHash);
 
             try
             {
-                return CalculateFinishedHmac(securityParameters, binderKey, transcriptHash);
+                return CalculateFinishedHmac(prfCryptoHashAlgorithm, prfHashLength, binderKey, transcriptHash);
             }
             finally
             {
@@ -1690,27 +1698,6 @@ namespace Org.BouncyCastle.Tls
                 EmptyBytes, securityParameters.PrfHashLength);
         }
 
-        public static short GetHashAlgorithmForPrfAlgorithm(int prfAlgorithm)
-        {
-            switch (prfAlgorithm)
-            {
-            case PrfAlgorithm.ssl_prf_legacy:
-            case PrfAlgorithm.tls_prf_legacy:
-                throw new ArgumentException("legacy PRF not a valid algorithm");
-            case PrfAlgorithm.tls_prf_sha256:
-            case PrfAlgorithm.tls13_hkdf_sha256:
-                return HashAlgorithm.sha256;
-            case PrfAlgorithm.tls_prf_sha384:
-            case PrfAlgorithm.tls13_hkdf_sha384:
-                return HashAlgorithm.sha384;
-            // TODO[RFC 8998]
-            //case PrfAlgorithm.tls13_hkdf_sm3:
-            //    return HashAlgorithm.sm3;
-            default:
-                throw new ArgumentException("unknown PrfAlgorithm: " + PrfAlgorithm.GetText(prfAlgorithm));
-            }
-        }
-
         public static DerObjectIdentifier GetOidForHashAlgorithm(short hashAlgorithm)
         {
             switch (hashAlgorithm)
@@ -4826,6 +4813,7 @@ namespace Org.BouncyCastle.Tls
 
             CollectKeyShares(clientContext.Crypto, supportedGroups, keyShareGroups, clientAgreements, clientShares);
 
+            // TODO[tls13-psk] When clientShares empty, consider not adding extension if pre_shared_key in use
             TlsExtensionsUtilities.AddKeyShareClientHello(clientExtensions, clientShares);
 
             return clientAgreements;
@@ -5107,18 +5095,15 @@ namespace Org.BouncyCastle.Tls
             case PrfAlgorithm.tls_prf_legacy:
             {
                 securityParameters.m_prfCryptoHashAlgorithm = -1;
-                securityParameters.m_prfHashAlgorithm = -1;
                 securityParameters.m_prfHashLength = -1;
                 break;
             }
             default:
             {
-                short prfHashAlgorithm = GetHashAlgorithmForPrfAlgorithm(prfAlgorithm);
-                int prfCryptoHashAlgorithm = TlsCryptoUtilities.GetHash(prfHashAlgorithm);
+                int prfCryptoHashAlgorithm = TlsCryptoUtilities.GetHashForPrf(prfAlgorithm);
 
                 securityParameters.m_prfCryptoHashAlgorithm = prfCryptoHashAlgorithm;
-                securityParameters.m_prfHashAlgorithm = prfHashAlgorithm;
-                securityParameters.m_prfHashLength = HashAlgorithm.GetOutputSize(prfHashAlgorithm);
+                securityParameters.m_prfHashLength = TlsCryptoUtilities.GetHashOutputSize(prfCryptoHashAlgorithm);
                 break;
             }
             }
@@ -5212,6 +5197,12 @@ namespace Org.BouncyCastle.Tls
             int prfCryptoHashAlgorithm = securityParameters.PrfCryptoHashAlgorithm;
             int prfHashLength = securityParameters.PrfHashLength;
 
+            return DeriveSecret(prfCryptoHashAlgorithm, prfHashLength, secret, label, transcriptHash);
+        }
+
+        internal static TlsSecret DeriveSecret(int prfCryptoHashAlgorithm, int prfHashLength, TlsSecret secret,
+            string label, byte[] transcriptHash)
+        {
             if (transcriptHash.Length != prfHashLength)
                 throw new TlsFatalAlert(AlertDescription.internal_error);