Exemple #1
0
        /// <summary>
        /// HKDF-Expand-Label(Secret, Label, Context, Length) =
        ///   HKDF-Expand(Secret, HkdfLabel, Length)
        ///
        /// The Hash function used by Transcript-Hash and HKDF is the cipher
        ///    suite hash algorithm.  Hash.length is its output length in bytes.
        ///    Messages is the concatenation of the indicated handshake messages,
        ///    including the handshake message type and length fields, but not
        ///    including record layer headers.  Note that in some cases a zero-
        ///    length Context (indicated by "") is passed to HKDF-Expand-Label.  The
        ///    labels specified in this document are all ASCII strings and do not
        ///    include a trailing NUL byte.
        /// </summary>
        /// <param name="secret">The secret.</param>
        /// <param name="label">The label of the intermediate value.</param>
        /// <param name="context">The context of the KDF step.</param>
        /// <param name="hashLengthBytes">Hash output length in bytes.</param>
        /// <returns>HKDF expanded bitstring based on the secret and built other info.</returns>
        public BitString ExpandLabel(BitString secret, string label, BitString context, int hashLengthBytes)
        {
            const int maxLabelContextSizes = 255;
            var       expandedLabel        = Encoding.ASCII.GetBytes("tls13 " + label);

            if (label.Length > maxLabelContextSizes)
            {
                throw new ArgumentOutOfRangeException($"{nameof(label)} exceeds max labels length of {maxLabelContextSizes}");
            }

            if (context.BitLength.CeilingDivide(maxLabelContextSizes) > maxLabelContextSizes)
            {
                throw new ArgumentOutOfRangeException($"{nameof(context)} exceeds max labels length of {maxLabelContextSizes}");
            }

            var otherInfo = BitString.Empty()
                            .ConcatenateBits(BitString.To16BitString((short)hashLengthBytes))
                            .ConcatenateBits(BitString.To8BitString((byte)expandedLabel.Length))
                            .ConcatenateBits(new BitString(expandedLabel))
                            .ConcatenateBits(BitString.To8BitString((byte)(context.BitLength / BitString.BITSINBYTE)))
                            .ConcatenateBits(context);

            return(_hkdf.Expand(secret, otherInfo, hashLengthBytes));
        }