2 // Mono.Security.Cryptography.CapiHash
5 // Sebastien Pouliot (sebastien@ximian.com)
7 // Copyright (C) 2003 Motus Technologies Inc. (http://www.motus.com)
8 // Copyright (C) 2004 Novell (http://www.novell.com)
12 using System
.Security
.Cryptography
;
14 namespace Mono
.Security
.Cryptography
{
16 public class CapiHash
: IDisposable
{
18 private CapiContext context
;
19 private IntPtr handle
;
20 private uint hashSize
;
22 public CapiHash (int hashAlgorithm
)
24 context
= new CapiContext ();
25 Initialize (hashAlgorithm
);
28 public CapiHash (CapiContext ctx
, int hashAlgorithm
)
31 Initialize (hashAlgorithm
);
34 public CapiHash (CspParameters cspParams
, int hashAlgorithm
)
36 context
= new CapiContext (cspParams
);
37 Initialize (hashAlgorithm
);
45 public IntPtr Handle
{
46 get { return handle; }
50 get { return (int) hashSize; }
53 public void Initialize (int algo
)
55 if (context
!= null) {
56 context
.InternalResult
= CryptoAPI
.CryptCreateHash (context
.Handle
, (uint)algo
, IntPtr
.Zero
, 0, ref handle
);
59 context
.InternalResult
= CryptoAPI
.CryptGetHashParam (handle
, CryptoAPI
.HP_HASHVAL
, null, ref hashSize
, 0);
64 public void Dispose ()
66 if (handle
!= IntPtr
.Zero
) {
67 CryptoAPI
.CryptDestroyHash (handle
);
71 GC
.SuppressFinalize (this);
75 // FIXME: calling this function 1,000,000 times (with a single character)
76 // is a good way to lose time (and hung NUnit)
77 // TODO: find the bug that hang NUnit
78 // TODO: optimize the function to call CryptHashData less often (bufferize)
79 public void HashCore (byte[] data
, int start
, int length
)
81 byte[] toBeHashed
= data
;
83 toBeHashed
= new byte [length
];
84 Array
.Copy (data
, start
, toBeHashed
, 0, length
);
86 context
.InternalResult
= CryptoAPI
.CryptHashData (handle
, toBeHashed
, (uint)length
, 0);
90 public byte[] HashFinal ()
92 byte[] hash
= new byte [hashSize
];
93 context
.InternalResult
= CryptoAPI
.CryptGetHashParam (handle
, CryptoAPI
.HP_HASHVAL
, hash
, ref hashSize
, 0);