-
Notifications
You must be signed in to change notification settings - Fork 42
/
Gost_28147_89_ImitHashAlgorithm.cs
156 lines (125 loc) · 3.97 KB
/
Gost_28147_89_ImitHashAlgorithm.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
using System;
using System.Security;
using GostCryptography.Base;
using GostCryptography.Native;
namespace GostCryptography.Gost_28147_89
{
/// <summary>
/// Реализация функции вычисления имитовставки по ГОСТ 28147-89.
/// </summary>
public sealed class Gost_28147_89_ImitHashAlgorithm : Gost_28147_89_ImitHashAlgorithmBase, ISafeHandleProvider<SafeHashHandleImpl>
{
/// <summary>
/// Размер имитовставки ГОСТ 28147-89.
/// </summary>
public const int DefaultHashSize = 32;
/// <summary>
/// Наименование алгоритма вычисления имитовставки ГОСТ 28147-89.
/// </summary>
public const string AlgorithmNameValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gost28147imit";
/// <summary>
/// Известные наименования алгоритма вычисления имитовставки ГОСТ 28147-89.
/// </summary>
public static readonly string[] KnownAlgorithmNames = { AlgorithmNameValue };
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_28147_89_ImitHashAlgorithm() : base(DefaultHashSize)
{
_keyAlgorithm = new Gost_28147_89_SymmetricAlgorithm(ProviderType);
}
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_28147_89_ImitHashAlgorithm(ProviderType providerType) : base(providerType, DefaultHashSize)
{
_keyAlgorithm = new Gost_28147_89_SymmetricAlgorithm(ProviderType);
}
/// <summary>
/// Конструктор.
/// </summary>
/// <param name="key">Ключ симметричного шифрования для подсчета имитовставки.</param>
/// <exception cref="ArgumentNullException"></exception>
[SecuritySafeCritical]
public Gost_28147_89_ImitHashAlgorithm(Gost_28147_89_SymmetricAlgorithmBase key) : base(key.ProviderType, DefaultHashSize)
{
if (key == null)
{
throw ExceptionUtility.ArgumentNull(nameof(key));
}
KeyValue = null;
_keyAlgorithm = Gost_28147_89_SymmetricAlgorithm.CreateFromKey(key);
}
[SecurityCritical]
private Gost_28147_89_SymmetricAlgorithm _keyAlgorithm;
[SecurityCritical]
private SafeHashHandleImpl _hashHandle;
/// <inheritdoc />
public override string AlgorithmName => AlgorithmNameValue;
/// <inheritdoc />
SafeHashHandleImpl ISafeHandleProvider<SafeHashHandleImpl>.SafeHandle
{
[SecurityCritical]
get { return _hashHandle; }
}
/// <inheritdoc />
public override byte[] Key
{
[SecuritySafeCritical]
get => _keyAlgorithm.Key;
[SecuritySafeCritical]
set => _keyAlgorithm.Key = value;
}
/// <inheritdoc />
public override Gost_28147_89_SymmetricAlgorithmBase KeyAlgorithm
{
[SecuritySafeCritical]
get => Gost_28147_89_SymmetricAlgorithm.CreateFromKey(_keyAlgorithm);
[SecuritySafeCritical]
set => _keyAlgorithm = Gost_28147_89_SymmetricAlgorithm.CreateFromKey(value);
}
/// <inheritdoc />
[SecuritySafeCritical]
protected override void HashCore(byte[] data, int dataOffset, int dataLength)
{
if (_hashHandle == null)
{
InitHash();
}
CryptoApiHelper.HashData(_hashHandle, data, dataOffset, dataLength);
}
/// <inheritdoc />
[SecuritySafeCritical]
protected override byte[] HashFinal()
{
if (_hashHandle == null)
{
InitHash();
}
return CryptoApiHelper.EndHashData(_hashHandle);
}
[SecurityCritical]
private void InitHash()
{
var providerHandle = CryptoApiHelper.GetProviderHandle(ProviderType);
var hashHandle = CryptoApiHelper.CreateHashImit(providerHandle, _keyAlgorithm.GetSafeHandle(), Constants.CALG_G28147_IMIT);
_hashHandle = hashHandle;
}
/// <inheritdoc />
[SecuritySafeCritical]
public override void Initialize()
{
_hashHandle.TryDispose();
_hashHandle = null;
}
/// <inheritdoc />
[SecuritySafeCritical]
protected override void Dispose(bool disposing)
{
if (disposing)
{
_keyAlgorithm?.Clear();
_hashHandle.TryDispose();
}
base.Dispose(disposing);
}
}
}