3 // Permission is hereby granted, free of charge, to any person obtaining
4 // a copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to
8 // permit persons to whom the Software is furnished to do so, subject to
9 // the following conditions:
11 // The above copyright notice and this permission notice shall be
12 // included in all copies or substantial portions of the Software.
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 /* Transport Security Layer (TLS)
23 * Copyright (c) 2003-2004 Carlos Guzman Alvarez
25 * Permission is hereby granted, free of charge, to any person
26 * obtaining a copy of this software and associated documentation
27 * files (the "Software"), to deal in the Software without restriction,
28 * including without limitation the rights to use, copy, modify, merge,
29 * publish, distribute, sublicense, and/or sell copies of the Software,
30 * and to permit persons to whom the Software is furnished to do so,
31 * subject to the following conditions:
33 * The above copyright notice and this permission notice shall be included
34 * in all copies or substantial portions of the Software.
36 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
37 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
38 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
39 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
40 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
41 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
42 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
43 * DEALINGS IN THE SOFTWARE.
47 using System
.Security
.Cryptography
;
49 namespace Mono
.Security
.Cryptography
53 * RFC 2104 (http://www.ietf.org/rfc/rfc2104.txt)
54 * RFC 2202 (http://www.ietf.org/rfc/rfc2202.txt)
57 * Extending the KeyedHashAlgorithm Class (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconextendingkeyedhashalgorithmclass.asp)
59 internal class HMAC
: System
.Security
.Cryptography
.KeyedHashAlgorithm
63 private HashAlgorithm hash
;
66 private byte[] innerPad
;
67 private byte[] outerPad
;
73 public override byte[] Key
75 get { return (byte[])KeyValue.Clone(); }
80 throw new Exception("Cannot change key during hash operation.");
83 /* if key is longer than 64 bytes reset it to rgbKey = Hash(rgbKey) */
84 if (value.Length
> 64)
86 KeyValue
= hash
.ComputeHash(value);
90 KeyValue
= (byte[])value.Clone();
106 HashSizeValue
= hash
.HashSize
;
108 // Generate a radom key
109 byte[] rgbKey
= new byte[64];
110 RNGCryptoServiceProvider rng
= new RNGCryptoServiceProvider();
111 rng
.GetNonZeroBytes(rgbKey
);
113 KeyValue
= (byte[])rgbKey
.Clone();
118 public HMAC(string hashName
, byte[] rgbKey
)
121 if (hashName
== null || hashName
.Length
== 0)
125 hash
= HashAlgorithm
.Create(hashName
);
127 HashSizeValue
= hash
.HashSize
;
129 /* if key is longer than 64 bytes reset it to rgbKey = Hash(rgbKey) */
130 if (rgbKey
.Length
> 64)
132 KeyValue
= hash
.ComputeHash(rgbKey
);
136 KeyValue
= (byte[])rgbKey
.Clone();
146 public override void Initialize()
153 protected override byte[] HashFinal()
157 hash
.TransformBlock(innerPad
, 0, innerPad
.Length
, innerPad
, 0);
160 // Finalize the original hash
161 hash
.TransformFinalBlock(new byte[0], 0, 0);
163 byte[] firstResult
= hash
.Hash
;
166 hash
.TransformBlock(outerPad
, 0, outerPad
.Length
, outerPad
, 0);
167 hash
.TransformFinalBlock(firstResult
, 0, firstResult
.Length
);
174 protected override void HashCore(
181 hash
.TransformBlock(innerPad
, 0, innerPad
.Length
, innerPad
, 0);
184 hash
.TransformBlock(array
, ibStart
, cbSize
, array
, ibStart
);
189 #region Private Methods
191 private void initializePad()
194 innerPad
= new byte[64];
195 outerPad
= new byte[64];
197 /* Pad the key for inner and outer digest */
198 for (int i
= 0 ; i
< KeyValue
.Length
; ++i
)
200 innerPad
[i
] = (byte)(KeyValue
[i
] ^
0x36);
201 outerPad
[i
] = (byte)(KeyValue
[i
] ^
0x5C);
203 for (int i
= KeyValue
.Length
; i
< 64; ++i
)