示例#1
0
 //https://tools.ietf.org/html/rfc5869
 public static void HkdfExtract(this IHashProvider provider, HashType hashType, ReadOnlySpan <byte> salt, ReadOnlySpan <byte> ikm, Span <byte> output)
 {
     if (salt.Length == 0)
     {
         salt = Empty.Slice(0, provider.HashSize(hashType));
     }
     if (ikm.Length == 0)
     {
         ikm = Empty.Slice(0, provider.HashSize(hashType));
     }
     provider.HmacData(hashType, salt, ikm, output);
 }
示例#2
0
 public static unsafe void HkdfExtract(IHashProvider provider, HashType hashType, void *salt, int saltLength, void *ikm, int ikmLength, void *output, int outputLength)
 {
     if (saltLength == 0)
     {
         salt       = (byte *)s_zeroArray;
         saltLength = provider.HashSize(hashType);
     }
     if (ikmLength == 0)
     {
         ikm       = (byte *)s_zeroArray;
         ikmLength = provider.HashSize(hashType);
     }
     provider.HmacData(hashType, salt, saltLength, ikm, ikmLength, output, outputLength);
 }
示例#3
0
        //https://tools.ietf.org/html/rfc5869
        public static void HkdfExpand(this IHashProvider provider, HashType hashType, ReadOnlySpan <byte> prk, ReadOnlySpan <byte> info, Span <byte> output)
        {
            var hashLength = provider.HashSize(hashType);
            var tLength    = hashLength + info.Length + sizeof(byte);
            var t          = new Span <byte>(new byte[tLength]);

            info.CopyTo(t.Slice(hashLength));

            byte counter     = 1;
            var  counterSpan = t.Slice(t.Length - 1);

            counterSpan.Write(counter);
            provider.HmacData(hashType, prk, t.Slice(hashLength), t.Slice(0, hashLength));
            while (true)
            {
                var amountToCopy = Math.Min(hashLength, output.Length);
                t.Slice(0, amountToCopy).CopyTo(output);
                output = output.Slice(amountToCopy);
                if (output.Length == 0)
                {
                    return;
                }
                counter++;
                counterSpan.Write(counter);
                provider.HmacData(hashType, prk, t, t.Slice(0, hashLength));
            }
        }
示例#4
0
        public static unsafe void HkdfExpand(IHashProvider provider, HashType hashType, void *prk, int prkLength, Span <byte> info, Span <byte> output)
        {
            int hashLength = provider.HashSize(hashType);
            var tLength    = hashLength + info.Length + sizeof(byte);
            var t          = stackalloc byte[tLength];
            var tSpan      = new Span <byte>(t, tLength);

            info.CopyTo(tSpan.Slice(hashLength));

            byte counter     = 1;
            var  counterSpan = tSpan.Slice(tSpan.Length - 1);

            counterSpan.Write(counter);
            provider.HmacData(hashType, prk, prkLength, t + hashLength, tLength - hashLength, t, hashLength);
            while (true)
            {
                int amountToCopy = Math.Min(hashLength, output.Length);
                tSpan.Slice(0, amountToCopy).CopyTo(output);
                output = output.Slice(amountToCopy);
                if (output.Length == 0)
                {
                    break;
                }
                counter++;
                counterSpan.Write(counter);
                provider.HmacData(hashType, prk, prkLength, t, tLength, t, hashLength);
            }
        }
示例#5
0
        public unsafe static byte[] FinishedKey(IHashProvider provider, HashType hashType, byte *handshakeTrafficSecret)
        {
            var output = new byte[provider.HashSize(hashType)];

            HkdfExpandLabel(provider, hashType, handshakeTrafficSecret, output.Length, Tls1_3Consts.ServerFinishedKey, new Span <byte>(), output);
            return(output);
        }
示例#6
0
        public static unsafe void P_Hash12(IHashProvider hash, HashType hashType, Span <byte> keyMaterial, void *secret, int secretLength, Span <byte> seed)
        {
            var         hashSize = hash.HashSize(hashType);
            var         a1Length = hashSize + seed.Length;
            var         a1       = stackalloc byte[a1Length];
            Span <byte> a1Span   = new Span <byte>(a1, a1Length);

            seed.CopyTo(a1Span.Slice(hashSize));
            var seedPtr = a1 + hashSize;

            hash.HmacData(hashType, secret, secretLength, seedPtr, seed.Length, a1, hashSize);
            var currentKeyData = stackalloc byte[hashSize];

            int keyMaterialIndex = 0;

            while (true)
            {
                hash.HmacData(hashType, secret, secretLength, a1, a1Length, currentKeyData, hashSize);
                for (int i = 0; i < hashSize; i++)
                {
                    keyMaterial[keyMaterialIndex] = currentKeyData[i];
                    keyMaterialIndex++;
                    if (keyMaterialIndex == keyMaterial.Length)
                    {
                        return;
                    }
                }
                hash.HmacData(hashType, secret, secretLength, a1, hashSize, a1, hashSize);
            }
        }
示例#7
0
        public static void HkdfFact(string input, IHashProvider provider)
        {
            var lines    = input.Split('\n').Select(l => l.Trim().Split('=')).ToDictionary(val => val[0], val => val[1]);
            var hashType = (HashType)Enum.Parse(typeof(HashType), lines["Hash"], true);
            var ikm      = lines["IKM"].HexToByteArray();
            var salt     = string.IsNullOrEmpty(lines["salt"]) ? new byte[0] : lines["salt"].HexToByteArray();
            var info     = string.IsNullOrEmpty(lines["info"]) ? new byte[0] : lines["info"].HexToByteArray();
            var prk      = lines["PRK"].HexToByteArray();
            var okm      = lines["OKM"].HexToByteArray();

            var prkResult = new byte[provider.HashSize(hashType)];
            var okmResult = new byte[okm.Length];

            provider.HkdfExtract(hashType, salt, ikm, prkResult);
            provider.HkdfExpand(hashType, prkResult, info, okmResult);

            Assert.Equal(prk, prkResult);
            Assert.Equal(okm, okmResult);
        }
示例#8
0
        //https://tools.ietf.org/html/rfc5246#section-4.7
        //TLS 1.2 Secret Expansion into an n length run of bytes
        // P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
        //                     HMAC_hash(secret, A(2) + seed) +
        // A() is defined as:
        // A(0) = seed
        // A(i) = HMAC_hash(secret, A(i-1))
        public static void Tls12Prf(this IHashProvider hashProvider, HashType hashType, ReadOnlySpan <byte> secret, ReadOnlySpan <byte> label, ReadOnlySpan <byte> seed, Span <byte> keyMaterial)
        {
            var hashSize = hashProvider.HashSize(hashType);
            var aLength  = hashSize + seed.Length + label.Length;
            var a1       = new Span <byte>(new byte[aLength]);

            label.CopyTo(a1.Slice(hashSize));
            seed.CopyTo(a1.Slice(hashSize + label.Length));
            hashProvider.HmacData(hashType, secret, a1.Slice(hashSize), a1.Slice(0, hashSize));

            var currentKeyData = new Span <byte>(new byte[hashSize]);

            while (keyMaterial.Length > 0)
            {
                //HMAC_hash(secret, A(n) + seed)
                hashProvider.HmacData(hashType, secret, a1, currentKeyData);
                //Copy required bytes into the output keymaterial and reduce size remaining
                var amountToCopy = Math.Min(keyMaterial.Length, currentKeyData.Length);
                currentKeyData.Slice(0, amountToCopy).CopyTo(keyMaterial);
                keyMaterial = keyMaterial.Slice(amountToCopy);
                //A(n) = HMAC_hash(secret, A(n-1))
                hashProvider.HmacData(hashType, secret, a1.Slice(0, hashSize), a1.Slice(0, hashSize));
            }
        }