Added hammock project to debug streaming issues
[pithos-ms-client] / trunk / hammock / src / netCF / Hammock.Compact / Mono / Security / Cryptography / HMACAlgorithm.cs
1 using System;
2 using System.Security.Cryptography;
3
4 namespace Hammock.Mono.Security.Cryptography
5 {
6   internal class HMACAlgorithm
7   {
8     private HashAlgorithm algo;
9     private BlockProcessor block;
10     private byte[] hash;
11     private string hashName;
12     private byte[] key;
13
14     public HashAlgorithm Algo
15     {
16       get
17       {
18         return this.algo;
19       }
20     }
21
22     public string HashName
23     {
24       get
25       {
26         return this.hashName;
27       }
28       set
29       {
30         this.CreateHash(value);
31       }
32     }
33
34     public byte[] Key
35     {
36       get
37       {
38         return this.key;
39       }
40       set
41       {
42         if (value != null && value.Length > 64)
43           this.key = this.algo.ComputeHash(value);
44         else if (value != null)
45           this.key = (byte[])value.Clone();
46       }
47     }
48
49     public HMACAlgorithm(string algoName)
50     {
51       this.CreateHash(algoName);
52     }
53
54     ~HMACAlgorithm()
55     {
56       this.Dispose();
57     }
58
59     private void CreateHash(string algoName)
60     {
61       this.algo = HashAlgorithm.Create(algoName);
62       this.hashName = algoName;
63       this.block = new BlockProcessor((ICryptoTransform)this.algo, 8);
64     }
65
66     public void Dispose()
67     {
68       if (this.key != null)
69         Array.Clear((Array)this.key, 0, this.key.Length);
70     }
71
72     public void Initialize()
73     {
74       this.hash = (byte[])null;
75       this.block.Initialize();
76       byte[] rgb = HMACAlgorithm.KeySetup(this.key, (byte)54);
77       this.algo.Initialize();
78       this.block.Core(rgb);
79       Array.Clear((Array)rgb, 0, rgb.Length);
80     }
81
82     private static byte[] KeySetup(byte[] key, byte padding)
83     {
84       byte[] numArray = new byte[64];
85       for (int index = 0; index < key.Length; ++index)
86         numArray[index] = (byte)((uint)key[index] ^ (uint)padding);
87       for (int length = key.Length; length < 64; ++length)
88         numArray[length] = padding;
89       return numArray;
90     }
91
92     public void Core(byte[] rgb, int ib, int cb)
93     {
94       this.block.Core(rgb, ib, cb);
95     }
96
97     public byte[] Final()
98     {
99       this.block.Final();
100       byte[] hash = this.algo.Hash;
101       byte[] numArray = HMACAlgorithm.KeySetup(this.key, (byte)92);
102       this.algo.Initialize();
103       this.algo.TransformBlock(numArray, 0, numArray.Length, numArray, 0);
104       this.algo.TransformFinalBlock(hash, 0, hash.Length);
105       this.hash = this.algo.Hash;
106       Array.Clear((Array)numArray, 0, numArray.Length);
107       Array.Clear((Array)hash, 0, hash.Length);
108       return this.hash;
109     }
110   }
111 }