#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.Collections.Generic;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement.Srp;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Modes;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Prng;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
{
/**
* Class for providing cryptographic services for TLS based on implementations in the BC light-weight API.
*
* This class provides default implementations for everything. If you need to customise it, extend the class
* and override the appropriate methods.
*
*/
public class BcTlsCrypto
: AbstractTlsCrypto
{
private readonly SecureRandom m_entropySource;
public BcTlsCrypto()
: this(CryptoServicesRegistrar.GetSecureRandom())
{
}
public BcTlsCrypto(SecureRandom entropySource)
{
if (entropySource == null)
throw new ArgumentNullException(nameof(entropySource));
this.m_entropySource = entropySource;
}
internal virtual BcTlsSecret AdoptLocalSecret(byte[] data)
{
return new BcTlsSecret(this, data);
}
public override SecureRandom SecureRandom
{
get { return m_entropySource; }
}
public override TlsCertificate CreateCertificate(short type, byte[] encoding)
{
switch (type)
{
case CertificateType.X509:
return new BcTlsCertificate(this, encoding);
case CertificateType.RawPublicKey:
return new BcTlsRawKeyCertificate(this, encoding);
default:
throw new TlsFatalAlert(AlertDescription.internal_error);
}
}
public override TlsCipher CreateCipher(TlsCryptoParameters cryptoParams, int encryptionAlgorithm,
int macAlgorithm)
{
switch (encryptionAlgorithm)
{
case EncryptionAlgorithm.AES_128_CBC:
case EncryptionAlgorithm.ARIA_128_CBC:
case EncryptionAlgorithm.CAMELLIA_128_CBC:
case EncryptionAlgorithm.SEED_CBC:
case EncryptionAlgorithm.SM4_CBC:
return CreateCipher_Cbc(cryptoParams, encryptionAlgorithm, 16, macAlgorithm);
case EncryptionAlgorithm.cls_3DES_EDE_CBC:
return CreateCipher_Cbc(cryptoParams, encryptionAlgorithm, 24, macAlgorithm);
case EncryptionAlgorithm.AES_256_CBC:
case EncryptionAlgorithm.ARIA_256_CBC:
case EncryptionAlgorithm.CAMELLIA_256_CBC:
return CreateCipher_Cbc(cryptoParams, encryptionAlgorithm, 32, macAlgorithm);
case EncryptionAlgorithm.AES_128_CCM:
// NOTE: Ignores macAlgorithm
return CreateCipher_Aes_Ccm(cryptoParams, 16, 16);
case EncryptionAlgorithm.AES_128_CCM_8:
// NOTE: Ignores macAlgorithm
return CreateCipher_Aes_Ccm(cryptoParams, 16, 8);
case EncryptionAlgorithm.AES_128_GCM:
// NOTE: Ignores macAlgorithm
return CreateCipher_Aes_Gcm(cryptoParams, 16, 16);
case EncryptionAlgorithm.AES_256_CCM:
// NOTE: Ignores macAlgorithm
return CreateCipher_Aes_Ccm(cryptoParams, 32, 16);
case EncryptionAlgorithm.AES_256_CCM_8:
// NOTE: Ignores macAlgorithm
return CreateCipher_Aes_Ccm(cryptoParams, 32, 8);
case EncryptionAlgorithm.AES_256_GCM:
// NOTE: Ignores macAlgorithm
return CreateCipher_Aes_Gcm(cryptoParams, 32, 16);
case EncryptionAlgorithm.ARIA_128_GCM:
// NOTE: Ignores macAlgorithm
return CreateCipher_Aria_Gcm(cryptoParams, 16, 16);
case EncryptionAlgorithm.ARIA_256_GCM:
// NOTE: Ignores macAlgorithm
return CreateCipher_Aria_Gcm(cryptoParams, 32, 16);
case EncryptionAlgorithm.CAMELLIA_128_GCM:
// NOTE: Ignores macAlgorithm
return CreateCipher_Camellia_Gcm(cryptoParams, 16, 16);
case EncryptionAlgorithm.CAMELLIA_256_GCM:
// NOTE: Ignores macAlgorithm
return CreateCipher_Camellia_Gcm(cryptoParams, 32, 16);
case EncryptionAlgorithm.CHACHA20_POLY1305:
// NOTE: Ignores macAlgorithm
return CreateChaCha20Poly1305(cryptoParams);
case EncryptionAlgorithm.NULL:
return CreateNullCipher(cryptoParams, macAlgorithm);
case EncryptionAlgorithm.SM4_CCM:
// NOTE: Ignores macAlgorithm
return CreateCipher_SM4_Ccm(cryptoParams);
case EncryptionAlgorithm.SM4_GCM:
// NOTE: Ignores macAlgorithm
return CreateCipher_SM4_Gcm(cryptoParams);
case EncryptionAlgorithm.DES40_CBC:
case EncryptionAlgorithm.DES_CBC:
case EncryptionAlgorithm.IDEA_CBC:
case EncryptionAlgorithm.RC2_CBC_40:
case EncryptionAlgorithm.RC4_128:
case EncryptionAlgorithm.RC4_40:
default:
throw new TlsFatalAlert(AlertDescription.internal_error);
}
}
public override TlsDHDomain CreateDHDomain(TlsDHConfig dhConfig)
{
return new BcTlsDHDomain(this, dhConfig);
}
public override TlsECDomain CreateECDomain(TlsECConfig ecConfig)
{
switch (ecConfig.NamedGroup)
{
case NamedGroup.x25519:
return new BcX25519Domain(this);
case NamedGroup.x448:
return new BcX448Domain(this);
default:
return new BcTlsECDomain(this, ecConfig);
}
}
public override TlsNonceGenerator CreateNonceGenerator(byte[] additionalSeedMaterial)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
return CreateNonceGenerator(Spans.FromNullableReadOnly(additionalSeedMaterial));
#else
int cryptoHashAlgorithm = CryptoHashAlgorithm.sha256;
IDigest digest = CreateDigest(cryptoHashAlgorithm);
int seedLength = TlsCryptoUtilities.GetHashOutputSize(cryptoHashAlgorithm);
byte[] seed = new byte[seedLength];
SecureRandom.NextBytes(seed);
DigestRandomGenerator randomGenerator = new DigestRandomGenerator(digest);
randomGenerator.AddSeedMaterial(additionalSeedMaterial);
randomGenerator.AddSeedMaterial(seed);
return new BcTlsNonceGenerator(randomGenerator);
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override TlsNonceGenerator CreateNonceGenerator(ReadOnlySpan additionalSeedMaterial)
{
int cryptoHashAlgorithm = CryptoHashAlgorithm.sha256;
IDigest digest = CreateDigest(cryptoHashAlgorithm);
int seedLength = TlsCryptoUtilities.GetHashOutputSize(cryptoHashAlgorithm);
Span seed = seedLength <= 128
? stackalloc byte[seedLength]
: new byte[seedLength];
SecureRandom.NextBytes(seed);
DigestRandomGenerator randomGenerator = new DigestRandomGenerator(digest);
randomGenerator.AddSeedMaterial(additionalSeedMaterial);
randomGenerator.AddSeedMaterial(seed);
return new BcTlsNonceGenerator(randomGenerator);
}
#endif
public override bool HasAnyStreamVerifiers(IList signatureAndHashAlgorithms)
{
foreach (SignatureAndHashAlgorithm algorithm in signatureAndHashAlgorithms)
{
switch (SignatureScheme.From(algorithm))
{
case SignatureScheme.ed25519:
case SignatureScheme.ed448:
return true;
}
}
return false;
}
public override bool HasAnyStreamVerifiersLegacy(short[] clientCertificateTypes)
{
return false;
}
public override bool HasCryptoHashAlgorithm(int cryptoHashAlgorithm)
{
switch (cryptoHashAlgorithm)
{
case CryptoHashAlgorithm.md5:
case CryptoHashAlgorithm.sha1:
case CryptoHashAlgorithm.sha224:
case CryptoHashAlgorithm.sha256:
case CryptoHashAlgorithm.sha384:
case CryptoHashAlgorithm.sha512:
case CryptoHashAlgorithm.sm3:
return true;
default:
return false;
}
}
public override bool HasCryptoSignatureAlgorithm(int cryptoSignatureAlgorithm)
{
switch (cryptoSignatureAlgorithm)
{
case CryptoSignatureAlgorithm.rsa:
case CryptoSignatureAlgorithm.dsa:
case CryptoSignatureAlgorithm.ecdsa:
case CryptoSignatureAlgorithm.rsa_pss_rsae_sha256:
case CryptoSignatureAlgorithm.rsa_pss_rsae_sha384:
case CryptoSignatureAlgorithm.rsa_pss_rsae_sha512:
case CryptoSignatureAlgorithm.ed25519:
case CryptoSignatureAlgorithm.ed448:
case CryptoSignatureAlgorithm.rsa_pss_pss_sha256:
case CryptoSignatureAlgorithm.rsa_pss_pss_sha384:
case CryptoSignatureAlgorithm.rsa_pss_pss_sha512:
return true;
// TODO[draft-smyshlyaev-tls12-gost-suites-10]
case CryptoSignatureAlgorithm.gostr34102012_256:
case CryptoSignatureAlgorithm.gostr34102012_512:
// TODO[RFC 8998]
case CryptoSignatureAlgorithm.sm2:
default:
return false;
}
}
public override bool HasDHAgreement()
{
return true;
}
public override bool HasECDHAgreement()
{
return true;
}
public override bool HasEncryptionAlgorithm(int encryptionAlgorithm)
{
switch (encryptionAlgorithm)
{
case EncryptionAlgorithm.AES_128_CBC:
case EncryptionAlgorithm.AES_128_CCM:
case EncryptionAlgorithm.AES_128_CCM_8:
case EncryptionAlgorithm.AES_128_GCM:
case EncryptionAlgorithm.AES_256_CBC:
case EncryptionAlgorithm.AES_256_CCM:
case EncryptionAlgorithm.AES_256_CCM_8:
case EncryptionAlgorithm.AES_256_GCM:
case EncryptionAlgorithm.ARIA_128_CBC:
case EncryptionAlgorithm.ARIA_128_GCM:
case EncryptionAlgorithm.ARIA_256_CBC:
case EncryptionAlgorithm.ARIA_256_GCM:
case EncryptionAlgorithm.CAMELLIA_128_CBC:
case EncryptionAlgorithm.CAMELLIA_128_GCM:
case EncryptionAlgorithm.CAMELLIA_256_CBC:
case EncryptionAlgorithm.CAMELLIA_256_GCM:
case EncryptionAlgorithm.CHACHA20_POLY1305:
case EncryptionAlgorithm.cls_3DES_EDE_CBC:
case EncryptionAlgorithm.NULL:
case EncryptionAlgorithm.SEED_CBC:
case EncryptionAlgorithm.SM4_CBC:
case EncryptionAlgorithm.SM4_CCM:
case EncryptionAlgorithm.SM4_GCM:
return true;
case EncryptionAlgorithm.DES_CBC:
case EncryptionAlgorithm.DES40_CBC:
case EncryptionAlgorithm.IDEA_CBC:
case EncryptionAlgorithm.RC2_CBC_40:
case EncryptionAlgorithm.RC4_128:
case EncryptionAlgorithm.RC4_40:
default:
return false;
}
}
public override bool HasHkdfAlgorithm(int cryptoHashAlgorithm)
{
switch (cryptoHashAlgorithm)
{
case CryptoHashAlgorithm.sha256:
case CryptoHashAlgorithm.sha384:
case CryptoHashAlgorithm.sha512:
case CryptoHashAlgorithm.sm3:
return true;
default:
return false;
}
}
public override bool HasMacAlgorithm(int macAlgorithm)
{
switch (macAlgorithm)
{
case MacAlgorithm.hmac_md5:
case MacAlgorithm.hmac_sha1:
case MacAlgorithm.hmac_sha256:
case MacAlgorithm.hmac_sha384:
case MacAlgorithm.hmac_sha512:
return true;
default:
return false;
}
}
public override bool HasNamedGroup(int namedGroup)
{
return NamedGroup.RefersToASpecificGroup(namedGroup);
}
public override bool HasRsaEncryption()
{
return true;
}
public override bool HasSignatureAlgorithm(short signatureAlgorithm)
{
switch (signatureAlgorithm)
{
case SignatureAlgorithm.rsa:
case SignatureAlgorithm.dsa:
case SignatureAlgorithm.ecdsa:
case SignatureAlgorithm.ed25519:
case SignatureAlgorithm.ed448:
case SignatureAlgorithm.rsa_pss_rsae_sha256:
case SignatureAlgorithm.rsa_pss_rsae_sha384:
case SignatureAlgorithm.rsa_pss_rsae_sha512:
case SignatureAlgorithm.rsa_pss_pss_sha256:
case SignatureAlgorithm.rsa_pss_pss_sha384:
case SignatureAlgorithm.rsa_pss_pss_sha512:
case SignatureAlgorithm.ecdsa_brainpoolP256r1tls13_sha256:
case SignatureAlgorithm.ecdsa_brainpoolP384r1tls13_sha384:
case SignatureAlgorithm.ecdsa_brainpoolP512r1tls13_sha512:
return true;
// TODO[draft-smyshlyaev-tls12-gost-suites-10]
case SignatureAlgorithm.gostr34102012_256:
case SignatureAlgorithm.gostr34102012_512:
// TODO[RFC 8998]
//case SignatureAlgorithm.sm2:
default:
return false;
}
}
public override bool HasSignatureAndHashAlgorithm(SignatureAndHashAlgorithm sigAndHashAlgorithm)
{
short signature = sigAndHashAlgorithm.Signature;
switch (sigAndHashAlgorithm.Hash)
{
case HashAlgorithm.md5:
return SignatureAlgorithm.rsa == signature && HasSignatureAlgorithm(signature);
default:
return HasSignatureAlgorithm(signature);
}
}
public override bool HasSignatureScheme(int signatureScheme)
{
switch (signatureScheme)
{
case SignatureScheme.sm2sig_sm3:
return false;
default:
{
short signature = SignatureScheme.GetSignatureAlgorithm(signatureScheme);
switch(SignatureScheme.GetCryptoHashAlgorithm(signatureScheme))
{
case CryptoHashAlgorithm.md5:
return SignatureAlgorithm.rsa == signature && HasSignatureAlgorithm(signature);
default:
return HasSignatureAlgorithm(signature);
}
}
}
}
public override bool HasSrpAuthentication()
{
return true;
}
public override TlsSecret CreateSecret(byte[] data)
{
try
{
return AdoptLocalSecret(Arrays.Clone(data));
}
finally
{
// TODO[tls-ops] Add this after checking all callers
//if (data != null)
//{
// Array.Clear(data, 0, data.Length);
//}
}
}
public override TlsSecret GenerateRsaPreMasterSecret(ProtocolVersion version)
{
byte[] data = new byte[48];
SecureRandom.NextBytes(data);
TlsUtilities.WriteVersion(version, data, 0);
return AdoptLocalSecret(data);
}
public virtual IDigest CloneDigest(int cryptoHashAlgorithm, IDigest digest)
{
switch (cryptoHashAlgorithm)
{
case CryptoHashAlgorithm.md5:
return new MD5Digest((MD5Digest)digest);
case CryptoHashAlgorithm.sha1:
return new Sha1Digest((Sha1Digest)digest);
case CryptoHashAlgorithm.sha224:
return new Sha224Digest((Sha224Digest)digest);
case CryptoHashAlgorithm.sha256:
return new Sha256Digest((Sha256Digest)digest);
case CryptoHashAlgorithm.sha384:
return new Sha384Digest((Sha384Digest)digest);
case CryptoHashAlgorithm.sha512:
return new Sha512Digest((Sha512Digest)digest);
case CryptoHashAlgorithm.sm3:
return new SM3Digest((SM3Digest)digest);
default:
throw new ArgumentException("invalid CryptoHashAlgorithm: " + cryptoHashAlgorithm);
}
}
public virtual IDigest CreateDigest(int cryptoHashAlgorithm)
{
switch (cryptoHashAlgorithm)
{
case CryptoHashAlgorithm.md5:
return new MD5Digest();
case CryptoHashAlgorithm.sha1:
return new Sha1Digest();
case CryptoHashAlgorithm.sha224:
return new Sha224Digest();
case CryptoHashAlgorithm.sha256:
return new Sha256Digest();
case CryptoHashAlgorithm.sha384:
return new Sha384Digest();
case CryptoHashAlgorithm.sha512:
return new Sha512Digest();
case CryptoHashAlgorithm.sm3:
return new SM3Digest();
default:
throw new ArgumentException("invalid CryptoHashAlgorithm: " + cryptoHashAlgorithm);
}
}
public override TlsHash CreateHash(int cryptoHashAlgorithm)
{
return new BcTlsHash(this, cryptoHashAlgorithm);
}
protected virtual IBlockCipher CreateBlockCipher(int encryptionAlgorithm)
{
switch (encryptionAlgorithm)
{
case EncryptionAlgorithm.cls_3DES_EDE_CBC:
return CreateDesEdeEngine();
case EncryptionAlgorithm.AES_128_CBC:
case EncryptionAlgorithm.AES_256_CBC:
return CreateAesEngine();
case EncryptionAlgorithm.ARIA_128_CBC:
case EncryptionAlgorithm.ARIA_256_CBC:
return CreateAriaEngine();
case EncryptionAlgorithm.CAMELLIA_128_CBC:
case EncryptionAlgorithm.CAMELLIA_256_CBC:
return CreateCamelliaEngine();
case EncryptionAlgorithm.SEED_CBC:
return CreateSeedEngine();
case EncryptionAlgorithm.SM4_CBC:
return CreateSM4Engine();
default:
throw new TlsFatalAlert(AlertDescription.internal_error);
}
}
protected virtual IBlockCipher CreateCbcBlockCipher(IBlockCipher blockCipher)
{
return new CbcBlockCipher(blockCipher);
}
protected virtual IBlockCipher CreateCbcBlockCipher(int encryptionAlgorithm)
{
return CreateCbcBlockCipher(CreateBlockCipher(encryptionAlgorithm));
}
protected virtual TlsCipher CreateChaCha20Poly1305(TlsCryptoParameters cryptoParams)
{
BcChaCha20Poly1305 encrypt = new BcChaCha20Poly1305(true);
BcChaCha20Poly1305 decrypt = new BcChaCha20Poly1305(false);
return new TlsAeadCipher(cryptoParams, encrypt, decrypt, 32, 16, TlsAeadCipher.AEAD_CHACHA20_POLY1305);
}
protected virtual TlsAeadCipher CreateCipher_Aes_Ccm(TlsCryptoParameters cryptoParams, int cipherKeySize,
int macSize)
{
BcTlsAeadCipherImpl encrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_Aes_Ccm(), true);
BcTlsAeadCipherImpl decrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_Aes_Ccm(), false);
return new TlsAeadCipher(cryptoParams, encrypt, decrypt, cipherKeySize, macSize, TlsAeadCipher.AEAD_CCM);
}
protected virtual TlsAeadCipher CreateCipher_Aes_Gcm(TlsCryptoParameters cryptoParams, int cipherKeySize,
int macSize)
{
BcTlsAeadCipherImpl encrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_Aes_Gcm(), true);
BcTlsAeadCipherImpl decrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_Aes_Gcm(), false);
return new TlsAeadCipher(cryptoParams, encrypt, decrypt, cipherKeySize, macSize, TlsAeadCipher.AEAD_GCM);
}
protected virtual TlsAeadCipher CreateCipher_Aria_Gcm(TlsCryptoParameters cryptoParams, int cipherKeySize,
int macSize)
{
BcTlsAeadCipherImpl encrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_Aria_Gcm(), true);
BcTlsAeadCipherImpl decrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_Aria_Gcm(), false);
return new TlsAeadCipher(cryptoParams, encrypt, decrypt, cipherKeySize, macSize, TlsAeadCipher.AEAD_GCM);
}
protected virtual TlsAeadCipher CreateCipher_Camellia_Gcm(TlsCryptoParameters cryptoParams, int cipherKeySize,
int macSize)
{
BcTlsAeadCipherImpl encrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_Camellia_Gcm(), true);
BcTlsAeadCipherImpl decrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_Camellia_Gcm(), false);
return new TlsAeadCipher(cryptoParams, encrypt, decrypt, cipherKeySize, macSize, TlsAeadCipher.AEAD_GCM);
}
protected virtual TlsCipher CreateCipher_Cbc(TlsCryptoParameters cryptoParams, int encryptionAlgorithm,
int cipherKeySize, int macAlgorithm)
{
BcTlsBlockCipherImpl encrypt = new BcTlsBlockCipherImpl(CreateCbcBlockCipher(encryptionAlgorithm), true);
BcTlsBlockCipherImpl decrypt = new BcTlsBlockCipherImpl(CreateCbcBlockCipher(encryptionAlgorithm), false);
TlsHmac clientMac = CreateMac(cryptoParams, macAlgorithm);
TlsHmac serverMac = CreateMac(cryptoParams, macAlgorithm);
return new TlsBlockCipher(cryptoParams, encrypt, decrypt, clientMac, serverMac, cipherKeySize);
}
protected virtual TlsAeadCipher CreateCipher_SM4_Ccm(TlsCryptoParameters cryptoParams)
{
BcTlsAeadCipherImpl encrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_SM4_Ccm(), true);
BcTlsAeadCipherImpl decrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_SM4_Ccm(), false);
return new TlsAeadCipher(cryptoParams, encrypt, decrypt, 16, 16, TlsAeadCipher.AEAD_CCM);
}
protected virtual TlsAeadCipher CreateCipher_SM4_Gcm(TlsCryptoParameters cryptoParams)
{
BcTlsAeadCipherImpl encrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_SM4_Gcm(), true);
BcTlsAeadCipherImpl decrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_SM4_Gcm(), false);
return new TlsAeadCipher(cryptoParams, encrypt, decrypt, 16, 16, TlsAeadCipher.AEAD_GCM);
}
protected virtual TlsNullCipher CreateNullCipher(TlsCryptoParameters cryptoParams, int macAlgorithm)
{
return new TlsNullCipher(cryptoParams, CreateMac(cryptoParams, macAlgorithm),
CreateMac(cryptoParams, macAlgorithm));
}
protected virtual IBlockCipher CreateAesEngine()
{
return AesUtilities.CreateEngine();
}
protected virtual IBlockCipher CreateAriaEngine()
{
return new AriaEngine();
}
protected virtual IBlockCipher CreateCamelliaEngine()
{
return new CamelliaEngine();
}
protected virtual IBlockCipher CreateDesEdeEngine()
{
return new DesEdeEngine();
}
protected virtual IBlockCipher CreateSeedEngine()
{
return new SeedEngine();
}
protected virtual IBlockCipher CreateSM4Engine()
{
return new SM4Engine();
}
protected virtual IAeadCipher CreateCcmMode(IBlockCipher engine)
{
return new CcmBlockCipher(engine);
}
protected virtual IAeadCipher CreateGcmMode(IBlockCipher engine)
{
// TODO Consider allowing custom configuration of multiplier
return new GcmBlockCipher(engine);
}
protected virtual IAeadCipher CreateAeadCipher_Aes_Ccm()
{
return CreateCcmMode(CreateAesEngine());
}
protected virtual IAeadCipher CreateAeadCipher_Aes_Gcm()
{
return CreateGcmMode(CreateAesEngine());
}
protected virtual IAeadCipher CreateAeadCipher_Aria_Gcm()
{
return CreateGcmMode(CreateAriaEngine());
}
protected virtual IAeadCipher CreateAeadCipher_Camellia_Gcm()
{
return CreateGcmMode(CreateCamelliaEngine());
}
protected virtual IAeadCipher CreateAeadCipher_SM4_Ccm()
{
return CreateCcmMode(CreateSM4Engine());
}
protected virtual IAeadCipher CreateAeadCipher_SM4_Gcm()
{
return CreateGcmMode(CreateSM4Engine());
}
public override TlsHmac CreateHmac(int macAlgorithm)
{
switch (macAlgorithm)
{
case MacAlgorithm.hmac_md5:
case MacAlgorithm.hmac_sha1:
case MacAlgorithm.hmac_sha256:
case MacAlgorithm.hmac_sha384:
case MacAlgorithm.hmac_sha512:
return CreateHmacForHash(TlsCryptoUtilities.GetHashForHmac(macAlgorithm));
default:
throw new ArgumentException("invalid MacAlgorithm: " + macAlgorithm);
}
}
public override TlsHmac CreateHmacForHash(int cryptoHashAlgorithm)
{
return new BcTlsHmac(new HMac(CreateDigest(cryptoHashAlgorithm)));
}
protected virtual TlsHmac CreateHmac_Ssl(int macAlgorithm)
{
switch (macAlgorithm)
{
case MacAlgorithm.hmac_md5:
return new BcSsl3Hmac(CreateDigest(CryptoHashAlgorithm.md5));
case MacAlgorithm.hmac_sha1:
return new BcSsl3Hmac(CreateDigest(CryptoHashAlgorithm.sha1));
case MacAlgorithm.hmac_sha256:
return new BcSsl3Hmac(CreateDigest(CryptoHashAlgorithm.sha256));
case MacAlgorithm.hmac_sha384:
return new BcSsl3Hmac(CreateDigest(CryptoHashAlgorithm.sha384));
case MacAlgorithm.hmac_sha512:
return new BcSsl3Hmac(CreateDigest(CryptoHashAlgorithm.sha512));
default:
throw new TlsFatalAlert(AlertDescription.internal_error);
}
}
protected virtual TlsHmac CreateMac(TlsCryptoParameters cryptoParams, int macAlgorithm)
{
if (TlsImplUtilities.IsSsl(cryptoParams))
{
return CreateHmac_Ssl(macAlgorithm);
}
else
{
return CreateHmac(macAlgorithm);
}
}
public override TlsSrp6Client CreateSrp6Client(TlsSrpConfig srpConfig)
{
BigInteger[] ng = srpConfig.GetExplicitNG();
Srp6GroupParameters srpGroup = new Srp6GroupParameters(ng[0], ng[1]);
Srp6Client srp6Client = new Srp6Client();
srp6Client.Init(srpGroup, CreateDigest(CryptoHashAlgorithm.sha1), SecureRandom);
return new BcTlsSrp6Client(srp6Client);
}
public override TlsSrp6Server CreateSrp6Server(TlsSrpConfig srpConfig, BigInteger srpVerifier)
{
BigInteger[] ng = srpConfig.GetExplicitNG();
Srp6GroupParameters srpGroup = new Srp6GroupParameters(ng[0], ng[1]);
Srp6Server srp6Server = new Srp6Server();
srp6Server.Init(srpGroup, srpVerifier, CreateDigest(CryptoHashAlgorithm.sha1), SecureRandom);
return new BcTlsSrp6Server(srp6Server);
}
public override TlsSrp6VerifierGenerator CreateSrp6VerifierGenerator(TlsSrpConfig srpConfig)
{
BigInteger[] ng = srpConfig.GetExplicitNG();
Srp6VerifierGenerator srp6VerifierGenerator = new Srp6VerifierGenerator();
srp6VerifierGenerator.Init(ng[0], ng[1], CreateDigest(CryptoHashAlgorithm.sha1));
return new BcTlsSrp6VerifierGenerator(srp6VerifierGenerator);
}
public override TlsSecret HkdfInit(int cryptoHashAlgorithm)
{
return AdoptLocalSecret(new byte[TlsCryptoUtilities.GetHashOutputSize(cryptoHashAlgorithm)]);
}
}
}
#pragma warning restore
#endif