using GostCryptography.Base; using GostCryptography.Gost_28147_89; using GostCryptography.Native; using System; using System.Security; namespace GostCryptography.Gost_R3411 { /// /// Базовый класс для всех реализаций Hash-based Message Authentication Code (HMAC) на базе алгоритма хэширования ГОСТ Р 34.11 /// public abstract class Gost_R3411_HMAC : GostHMAC, ISafeHandleProvider where THash : GostHashAlgorithm { /// [SecuritySafeCritical] protected Gost_R3411_HMAC(int hashSize) : base(hashSize) { InitDefaults(new Gost_28147_89_SymmetricAlgorithm(ProviderType)); } /// [SecuritySafeCritical] protected Gost_R3411_HMAC(ProviderType providerType, int hashSize) : base(providerType, hashSize) { InitDefaults(new Gost_28147_89_SymmetricAlgorithm(ProviderType)); } /// /// Конструктор /// /// Алгоритм для вычисления HMAC /// Размер хэш-кода в битах /// [SecuritySafeCritical] protected Gost_R3411_HMAC(Gost_28147_89_SymmetricAlgorithmBase keyAlgorithm, int hashSize) : base(keyAlgorithm.ProviderType, hashSize) { if (keyAlgorithm == null) { throw ExceptionUtility.ArgumentNull(nameof(keyAlgorithm)); } InitDefaults(Gost_28147_89_SymmetricAlgorithm.CreateFromKey(keyAlgorithm)); } [SecuritySafeCritical] private void InitDefaults(Gost_28147_89_SymmetricAlgorithm keyAlgorithm) { HashName = typeof(THash).Name; _keyAlgorithm = keyAlgorithm; _hmacHandle = CreateHashHMAC(keyAlgorithm.ProviderType, CryptoApiHelper.GetProviderHandle(keyAlgorithm.ProviderType), keyAlgorithm.GetSafeHandle()); } /// /// Создает дескриптор функции хэширования HMAC криптографического провайдера /// [SecuritySafeCritical] protected abstract SafeHashHandleImpl CreateHashHMAC(ProviderType providerType, SafeProvHandleImpl providerHandle, SafeKeyHandleImpl symKeyHandle); [SecurityCritical] private SafeHashHandleImpl _hmacHandle; private Gost_28147_89_SymmetricAlgorithm _keyAlgorithm; /// SafeHashHandleImpl ISafeHandleProvider.SafeHandle { [SecurityCritical] get { return _hmacHandle; } } /// /// Алгоритм для вычисления HMAC /// public Gost_28147_89_SymmetricAlgorithmBase KeyAlgorithm { get { return _keyAlgorithm; } [SecuritySafeCritical] set { _keyAlgorithm = Gost_28147_89_SymmetricAlgorithm.CreateFromKey(value); } } /// public override byte[] Key { get { return _keyAlgorithm.Key; } set { _keyAlgorithm = new Gost_28147_89_SymmetricAlgorithm(ProviderType) { Key = value }; Initialize(); } } /// [SecuritySafeCritical] public override void Initialize() { var hmacHandle = CreateHashHMAC(ProviderType, CryptoApiHelper.GetProviderHandle(ProviderType), _keyAlgorithm.GetSafeHandle()); _hmacHandle.TryDispose(); _hmacHandle = hmacHandle; } /// [SecuritySafeCritical] protected override void HashCore(byte[] data, int dataOffset, int dataLength) { CryptoApiHelper.HashData(_hmacHandle, data, dataOffset, dataLength); } /// [SecuritySafeCritical] protected override byte[] HashFinal() { return CryptoApiHelper.EndHashData(_hmacHandle); } /// [SecuritySafeCritical] protected override void Dispose(bool disposing) { if (disposing) { _keyAlgorithm?.Clear(); _hmacHandle.TryDispose(); } base.Dispose(disposing); } } }