<PackageReference Include="BouncyCastle.Cryptography" Version="2.5.1" />

TlsCryptoUtilities

public abstract class TlsCryptoUtilities
using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Nist; using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.Rosstandart; using Org.BouncyCastle.Asn1.X509; using System; namespace Org.BouncyCastle.Tls.Crypto { public abstract class TlsCryptoUtilities { private static readonly byte[] Tls13Prefix = new byte[6] { 116, 108, 115, 49, 51, 32 }; public static int GetHash(short hashAlgorithm) { switch (hashAlgorithm) { case 1: return 1; case 2: return 2; case 3: return 3; case 4: return 4; case 5: return 5; case 6: return 6; default: throw new ArgumentException("specified HashAlgorithm invalid: " + HashAlgorithm.GetText(hashAlgorithm)); } } public static int GetHashForHmac(int macAlgorithm) { switch (macAlgorithm) { case 1: return 1; case 2: return 2; case 3: return 4; case 4: return 5; case 5: return 6; default: throw new ArgumentException("specified MacAlgorithm not an HMAC: " + MacAlgorithm.GetText(macAlgorithm)); } } public static int GetHashForPrf(int prfAlgorithm) { switch (prfAlgorithm) { case 0: case 1: throw new ArgumentException("legacy PRF not a valid algorithm"); case 2: case 4: return 4; case 3: case 5: return 5; case 7: return 7; case 8: return 8; default: throw new ArgumentException("unknown PrfAlgorithm: " + PrfAlgorithm.GetText(prfAlgorithm)); } } public static int GetHashInternalSize(int cryptoHashAlgorithm) { switch (cryptoHashAlgorithm) { case 1: case 2: case 3: case 4: case 7: case 8: return 64; case 5: case 6: return 128; default: throw new ArgumentException(); } } public static int GetHashOutputSize(int cryptoHashAlgorithm) { switch (cryptoHashAlgorithm) { case 1: return 16; case 2: return 20; case 3: return 28; case 4: case 7: case 8: return 32; case 5: return 48; case 6: return 64; default: throw new ArgumentException(); } } public static DerObjectIdentifier GetOidForHash(int cryptoHashAlgorithm) { switch (cryptoHashAlgorithm) { case 1: return PkcsObjectIdentifiers.MD5; case 2: return X509ObjectIdentifiers.IdSha1; case 3: return NistObjectIdentifiers.IdSha224; case 4: return NistObjectIdentifiers.IdSha256; case 5: return NistObjectIdentifiers.IdSha384; case 6: return NistObjectIdentifiers.IdSha512; case 8: return RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256; default: throw new ArgumentException(); } } public static int GetSignature(short signatureAlgorithm) { switch (signatureAlgorithm) { case 1: return 1; case 2: return 2; case 3: return 3; case 4: return 4; case 5: return 5; case 6: return 6; case 7: return 7; case 8: return 8; case 9: return 9; case 10: return 10; case 11: return 11; case 26: return 26; case 27: return 27; case 28: return 28; case 64: return 64; case 65: return 65; default: throw new ArgumentException("specified SignatureAlgorithm invalid: " + SignatureAlgorithm.GetText(signatureAlgorithm)); } } public static TlsSecret HkdfExpandLabel(TlsSecret secret, int cryptoHashAlgorithm, string label, byte[] context, int length) { return HkdfExpandLabel(secret, cryptoHashAlgorithm, label.AsSpan(), context.AsSpan(), length); } public unsafe static TlsSecret HkdfExpandLabel(TlsSecret secret, int cryptoHashAlgorithm, ReadOnlySpan<char> label, ReadOnlySpan<byte> context, int length) { int length2 = label.Length; if (length2 < 1) throw new TlsFatalAlert(80); int length3 = context.Length; int num = Tls13Prefix.Length + length2; int num2 = 2 + (1 + num) + (1 + length3); Span<byte> span; if (num2 <= 512) { int num3 = num2; span = new Span<byte>(stackalloc byte[(int)(uint)num3], num3); } else span = new byte[num2]; Span<byte> span2 = span; TlsUtilities.CheckUint16(length); TlsUtilities.WriteUint16(length, span2); TlsUtilities.CheckUint8(num); TlsUtilities.WriteUint8(num, span2.Slice(2, span2.Length - 2)); Tls13Prefix.CopyTo(span2.Slice(3, span2.Length - 3)); int num4 = 2 + (1 + Tls13Prefix.Length); for (int i = 0; i < length2; i++) { span2[num4 + i] = (byte)label[i]; } TlsUtilities.WriteOpaque8(context, span2.Slice(2 + (1 + num))); return secret.HkdfExpand(cryptoHashAlgorithm, span2, length); } } }