Terraria v1.4.4.9
Terraria source code documentation
All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Events Macros
HashProviderCng.cs
Go to the documentation of this file.
1using System;
3
5
6internal sealed class HashProviderCng : HashProvider
7{
9
11
12 private byte[] _key;
13
14 private readonly bool _reusable;
15
16 private readonly int _hashSize;
17
18 private bool _running;
19
20 public sealed override int HashSizeInBytes => _hashSize;
21
22 public HashProviderCng(string hashAlgId, byte[] key)
23 : this(hashAlgId, key, key != null)
24 {
25 }
26
27 internal HashProviderCng(string hashAlgId, ReadOnlySpan<byte> key, bool isHmac)
28 {
29 global::Interop.BCrypt.BCryptOpenAlgorithmProviderFlags bCryptOpenAlgorithmProviderFlags = global::Interop.BCrypt.BCryptOpenAlgorithmProviderFlags.None;
30 if (isHmac)
31 {
32 _key = key.ToArray();
33 bCryptOpenAlgorithmProviderFlags |= global::Interop.BCrypt.BCryptOpenAlgorithmProviderFlags.BCRYPT_ALG_HANDLE_HMAC_FLAG;
34 }
35 _hAlgorithm = global::Interop.BCrypt.BCryptAlgorithmCache.GetCachedBCryptAlgorithmHandle(hashAlgId, bCryptOpenAlgorithmProviderFlags, out _hashSize);
37 global::Interop.BCrypt.NTSTATUS nTSTATUS = global::Interop.BCrypt.BCryptCreateHash(_hAlgorithm, out phHash, IntPtr.Zero, 0, key, (!(key == null)) ? key.Length : 0, global::Interop.BCrypt.BCryptCreateHashFlags.BCRYPT_HASH_REUSABLE_FLAG);
38 switch (nTSTATUS)
39 {
40 case global::Interop.BCrypt.NTSTATUS.STATUS_INVALID_PARAMETER:
41 phHash.Dispose();
42 Reset();
43 break;
44 default:
45 phHash.Dispose();
46 throw global::Interop.BCrypt.CreateCryptographicException(nTSTATUS);
47 case global::Interop.BCrypt.NTSTATUS.STATUS_SUCCESS:
48 _hHash = phHash;
49 _reusable = true;
50 break;
51 }
52 }
53
54 public sealed override void AppendHashData(ReadOnlySpan<byte> source)
55 {
56 global::Interop.BCrypt.NTSTATUS nTSTATUS = global::Interop.BCrypt.BCryptHashData(_hHash, source, source.Length, 0);
57 if (nTSTATUS != 0)
58 {
59 throw global::Interop.BCrypt.CreateCryptographicException(nTSTATUS);
60 }
61 _running = true;
62 }
63
65 {
66 global::Interop.BCrypt.NTSTATUS nTSTATUS = global::Interop.BCrypt.BCryptFinishHash(_hHash, destination, _hashSize, 0);
67 if (nTSTATUS != 0)
68 {
69 throw global::Interop.BCrypt.CreateCryptographicException(nTSTATUS);
70 }
71 _running = false;
72 Reset();
73 return _hashSize;
74 }
75
77 {
78 using SafeBCryptHashHandle hHash = global::Interop.BCrypt.BCryptDuplicateHash(_hHash);
79 global::Interop.BCrypt.NTSTATUS nTSTATUS = global::Interop.BCrypt.BCryptFinishHash(hHash, destination, _hashSize, 0);
80 if (nTSTATUS != 0)
81 {
82 throw global::Interop.BCrypt.CreateCryptographicException(nTSTATUS);
83 }
84 return _hashSize;
85 }
86
87 public sealed override void Dispose(bool disposing)
88 {
89 if (disposing)
90 {
92 if (_key != null)
93 {
94 byte[] key = _key;
95 _key = null;
97 }
98 }
99 }
100
101 public override void Reset()
102 {
103 if (!_reusable || _running)
104 {
105 DestroyHash();
107 global::Interop.BCrypt.NTSTATUS nTSTATUS = global::Interop.BCrypt.BCryptCreateHash(_hAlgorithm, out phHash, IntPtr.Zero, 0, _key, (_key != null) ? _key.Length : 0, global::Interop.BCrypt.BCryptCreateHashFlags.None);
108 if (nTSTATUS != 0)
109 {
110 throw global::Interop.BCrypt.CreateCryptographicException(nTSTATUS);
111 }
112 _hHash = phHash;
113 }
114 }
115
116 private void DestroyHash()
117 {
119 _hHash = null;
120 hHash?.Dispose();
121 }
122}
readonly SafeBCryptAlgorithmHandle _hAlgorithm
override int GetCurrentHash(Span< byte > destination)
override void Dispose(bool disposing)
HashProviderCng(string hashAlgId, ReadOnlySpan< byte > key, bool isHmac)
HashProviderCng(string hashAlgId, byte[] key)
override void AppendHashData(ReadOnlySpan< byte > source)
override int FinalizeHashAndReset(Span< byte > destination)
static unsafe void Clear(Array array)
Definition Array.cs:755
static readonly IntPtr Zero
Definition IntPtr.cs:18