Mercurial > projects > dcrypt
comparison dcrypt/crypto/macs/HMAC.d @ 15:0de48552be35
Added LimitReachedError and PBKDF2. Fixed some errors with the previous commit in PRNGFromHash, etc. Re-implemented HMAC. Changed the name() format of HMAC and PBKDF2.
author | Thomas Dixon <reikon@reikon.us> |
---|---|
date | Wed, 19 Nov 2008 19:30:52 -0500 |
parents | 5ce3012f1def |
children | 4589f8c5eb3c |
comparison
equal
deleted
inserted
replaced
14:5ce3012f1def | 15:0de48552be35 |
---|---|
24 * References: http://www.faqs.org/rfcs/rfc2104.html | 24 * References: http://www.faqs.org/rfcs/rfc2104.html |
25 */ | 25 */ |
26 class HMAC : MAC { | 26 class HMAC : MAC { |
27 private { | 27 private { |
28 ubyte[] ipad, opad, key; | 28 ubyte[] ipad, opad, key; |
29 Hash inner, outer; | 29 Hash hash; |
30 bool initialized; | 30 bool initialized; |
31 } | 31 } |
32 | 32 |
33 this (Hash hash, void[] key=null) { | 33 this (Hash hash, void[] key=null) { |
34 hash.reset(); | 34 this.hash = hash.copy(); |
35 | 35 this.hash.reset(); |
36 inner = hash; | |
37 outer = hash.copy(); | |
38 | 36 |
39 ipad = new ubyte[blockSize]; | 37 ipad = new ubyte[blockSize]; |
40 opad = new ubyte[blockSize]; | 38 opad = new ubyte[blockSize]; |
41 | |
42 reset(); | |
43 | 39 |
44 if (key) | 40 if (key) |
45 init(new SymmetricKey(key)); // I'm lazy. | 41 init(new SymmetricKey(key)); // I'm lazy. |
46 } | 42 } |
47 | 43 |
49 SymmetricKey keyParams = cast(SymmetricKey)params; | 45 SymmetricKey keyParams = cast(SymmetricKey)params; |
50 if (!keyParams) | 46 if (!keyParams) |
51 throw new InvalidParameterError( | 47 throw new InvalidParameterError( |
52 name()~": Invalid parameter passed to init"); | 48 name()~": Invalid parameter passed to init"); |
53 | 49 |
50 hash.reset(); | |
51 | |
54 if (keyParams.key.length > blockSize) { | 52 if (keyParams.key.length > blockSize) { |
55 inner.update(keyParams.key); | 53 hash.update(keyParams.key); |
56 key = inner.digest(); | 54 key = hash.digest(); |
57 } else | 55 } else |
58 key = keyParams.key; | 56 key = keyParams.key; |
57 | |
58 ipad[] = 0x36; | |
59 opad[] = 0x5c; | |
59 | 60 |
60 foreach (uint i, ubyte j; key) { | 61 foreach (uint i, ubyte j; key) { |
61 ipad[i] ^= j; | 62 ipad[i] ^= j; |
62 opad[i] ^= j; | 63 opad[i] ^= j; |
63 } | 64 } |
64 | 65 |
65 inner.update(ipad); | 66 reset(); |
66 outer.update(opad); | |
67 | 67 |
68 initialized = true; | 68 initialized = true; |
69 } | 69 } |
70 | 70 |
71 void update(void[] input_) { | 71 void update(void[] input_) { |
72 if (!initialized) | 72 if (!initialized) |
73 throw new NotInitializedError( | 73 throw new NotInitializedError( |
74 name()~": MAC not initialized."); | 74 name()~": MAC not initialized."); |
75 inner.update(input_); | 75 hash.update(input_); |
76 } | 76 } |
77 | 77 |
78 char[] name() { | 78 char[] name() { |
79 return inner.name~"/HMAC"; | 79 return "HMAC-"~hash.name; |
80 } | 80 } |
81 | 81 |
82 void reset() { | 82 void reset() { |
83 ipad[] = 0x36; | 83 hash.reset(); |
84 opad[] = 0x5c; | 84 hash.update(ipad); |
85 | |
86 inner.reset(); | |
87 outer.reset(); | |
88 } | 85 } |
89 | 86 |
90 uint blockSize() { | 87 uint blockSize() { |
91 return inner.blockSize; | 88 return hash.blockSize; |
92 } | 89 } |
93 | 90 |
94 uint macSize() { | 91 uint macSize() { |
95 return inner.digestSize; | 92 return hash.digestSize; |
96 } | 93 } |
97 | 94 |
98 ubyte[] digest() { | 95 ubyte[] digest() { |
99 outer.update(inner.digest()); | 96 ubyte[] t = hash.digest(); |
100 ubyte[] r = outer.digest(); | 97 hash.update(opad); |
98 hash.update(t); | |
99 ubyte[] r = hash.digest(); | |
101 reset(); | 100 reset(); |
102 return r; | 101 return r; |
103 } | 102 } |
104 | 103 |
105 char[] hexDigest() { | 104 char[] hexDigest() { |
106 return Util.ubytesToHex(finish()); | 105 return Util.ubytesToHex(digest()); |
107 } | 106 } |
108 | 107 |
109 HMAC copy() { | 108 HMAC copy() { |
110 // Ghetto... oh so ghetto :\ | 109 // Ghetto... oh so ghetto :\ |
111 HMAC h = new HMAC(inner.copy()); | 110 HMAC h = new HMAC(hash.copy()); |
112 h.inner = inner.copy(); | 111 h.hash = hash.copy(); |
113 h.outer = outer.copy(); | |
114 h.initialized = true; | 112 h.initialized = true; |
115 return h; | 113 return h; |
116 } | 114 } |
117 | 115 |
118 version (UnitTest) { | 116 version (UnitTest) { |