History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/crypto/provider/HmacCore.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/crypto/provider/HmacCore.java+348−0
@@ -0,0 +1,348 @@
1/*
2 * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.crypto.provider;
27
28import java.util.Arrays;
29
30import java.nio.ByteBuffer;
31
32import javax.crypto.MacSpi;
33import javax.crypto.SecretKey;
34import java.security.*;
35import java.security.spec.*;
36
37/**
38 * This class constitutes the core of HMAC-<MD> algorithms, where
39 * <MD> can be SHA1 or MD5, etc. See RFC 2104 for spec.
40 *
41 * It also contains the implementation classes for the SHA-256,
42 * SHA-384, and SHA-512 HMACs.
43 *
44 * @author Jan Luehe
45 */
46final class HmacCore implements Cloneable {
47
48 private final MessageDigest md;
49 private final byte[] k_ipad; // inner padding - key XORd with ipad
50 private final byte[] k_opad; // outer padding - key XORd with opad
51 private boolean first; // Is this the first data to be processed?
52
53 private final int blockLen;
54
55 /**
56 * Standard constructor, creates a new HmacCore instance using the
57 * specified MessageDigest object.
58 */
59 HmacCore(MessageDigest md, int bl) {
60 this.md = md;
61 this.blockLen = bl;
62 this.k_ipad = new byte[blockLen];
63 this.k_opad = new byte[blockLen];
64 first = true;
65 }
66
67 /**
68 * Standard constructor, creates a new HmacCore instance instantiating
69 * a MessageDigest of the specified name.
70 */
71 HmacCore(String digestAlgorithm, int bl) throws NoSuchAlgorithmException {
72 this(MessageDigest.getInstance(digestAlgorithm), bl);
73 }
74
75 /**
76 * Constructor used for cloning.
77 */
78 private HmacCore(HmacCore other) throws CloneNotSupportedException {
79 this.md = (MessageDigest)other.md.clone();
80 this.blockLen = other.blockLen;
81 this.k_ipad = (byte[])other.k_ipad.clone();
82 this.k_opad = (byte[])other.k_opad.clone();
83 this.first = other.first;
84 }
85
86 /**
87 * Returns the length of the HMAC in bytes.
88 *
89 * @return the HMAC length in bytes.
90 */
91 int getDigestLength() {
92 return this.md.getDigestLength();
93 }
94
95 /**
96 * Initializes the HMAC with the given secret key and algorithm parameters.
97 *
98 * @param key the secret key.
99 * @param params the algorithm parameters.
100 *
101 * @exception InvalidKeyException if the given key is inappropriate for
102 * initializing this MAC.
103 * @exception InvalidAlgorithmParameterException if the given algorithm
104 * parameters are inappropriate for this MAC.
105 */
106 void init(Key key, AlgorithmParameterSpec params)
107 throws InvalidKeyException, InvalidAlgorithmParameterException {
108
109 if (params != null) {
110 throw new InvalidAlgorithmParameterException
111 ("HMAC does not use parameters");
112 }
113
114 if (!(key instanceof SecretKey)) {
115 throw new InvalidKeyException("Secret key expected");
116 }
117
118 byte[] secret = key.getEncoded();
119 if (secret == null) {
120 throw new InvalidKeyException("Missing key data");
121 }
122
123 // if key is longer than the block length, reset it using
124 // the message digest object.
125 if (secret.length > blockLen) {
126 byte[] tmp = md.digest(secret);
127 // now erase the secret
128 Arrays.fill(secret, (byte)0);
129 secret = tmp;
130 }
131
132 // XOR k with ipad and opad, respectively
133 for (int i = 0; i < blockLen; i++) {
134 int si = (i < secret.length) ? secret[i] : 0;
135 k_ipad[i] = (byte)(si ^ 0x36);
136 k_opad[i] = (byte)(si ^ 0x5c);
137 }
138
139 // now erase the secret
140 Arrays.fill(secret, (byte)0);
141 secret = null;
142
143 reset();
144 }
145
146 /**
147 * Processes the given byte.
148 *
149 * @param input the input byte to be processed.
150 */
151 void update(byte input) {
152 if (first == true) {
153 // compute digest for 1st pass; start with inner pad
154 md.update(k_ipad);
155 first = false;
156 }
157
158 // add the passed byte to the inner digest
159 md.update(input);
160 }
161
162 /**
163 * Processes the first <code>len</code> bytes in <code>input</code>,
164 * starting at <code>offset</code>.
165 *
166 * @param input the input buffer.
167 * @param offset the offset in <code>input</code> where the input starts.
168 * @param len the number of bytes to process.
169 */
170 void update(byte input[], int offset, int len) {
171 if (first == true) {
172 // compute digest for 1st pass; start with inner pad
173 md.update(k_ipad);
174 first = false;
175 }
176
177 // add the selected part of an array of bytes to the inner digest
178 md.update(input, offset, len);
179 }
180
181 void update(ByteBuffer input) {
182 if (first == true) {
183 // compute digest for 1st pass; start with inner pad
184 md.update(k_ipad);
185 first = false;
186 }
187
188 md.update(input);
189 }
190
191 /**
192 * Completes the HMAC computation and resets the HMAC for further use,
193 * maintaining the secret key that the HMAC was initialized with.
194 *
195 * @return the HMAC result.
196 */
197 byte[] doFinal() {
198 if (first == true) {
199 // compute digest for 1st pass; start with inner pad
200 md.update(k_ipad);
201 } else {
202 first = true;
203 }
204
205 try {
206 // finish the inner digest
207 byte[] tmp = md.digest();
208
209 // compute digest for 2nd pass; start with outer pad
210 md.update(k_opad);
211 // add result of 1st hash
212 md.update(tmp);
213
214 md.digest(tmp, 0, tmp.length);
215 return tmp;
216 } catch (DigestException e) {
217 // should never occur
218 throw new ProviderException(e);
219 }
220 }
221
222 /**
223 * Resets the HMAC for further use, maintaining the secret key that the
224 * HMAC was initialized with.
225 */
226 void reset() {
227 if (first == false) {
228 md.reset();
229 first = true;
230 }
231 }
232
233 /*
234 * Clones this object.
235 */
236 public Object clone() throws CloneNotSupportedException {
237 return new HmacCore(this);
238 }
239
240 // nested static class for the HmacSHA256 implementation
241 public static final class HmacSHA256 extends MacSpi implements Cloneable {
242 private final HmacCore core;
243 public HmacSHA256() throws NoSuchAlgorithmException {
244 core = new HmacCore("SHA-256", 64);
245 }
246 private HmacSHA256(HmacSHA256 base) throws CloneNotSupportedException {
247 core = (HmacCore)base.core.clone();
248 }
249 protected int engineGetMacLength() {
250 return core.getDigestLength();
251 }
252 protected void engineInit(Key key, AlgorithmParameterSpec params)
253 throws InvalidKeyException, InvalidAlgorithmParameterException {
254 core.init(key, params);
255 }
256 protected void engineUpdate(byte input) {
257 core.update(input);
258 }
259 protected void engineUpdate(byte input[], int offset, int len) {
260 core.update(input, offset, len);
261 }
262 protected void engineUpdate(ByteBuffer input) {
263 core.update(input);
264 }
265 protected byte[] engineDoFinal() {
266 return core.doFinal();
267 }
268 protected void engineReset() {
269 core.reset();
270 }
271 public Object clone() throws CloneNotSupportedException {
272 return new HmacSHA256(this);
273 }
274 }
275
276 // nested static class for the HmacSHA384 implementation
277 public static final class HmacSHA384 extends MacSpi implements Cloneable {
278 private final HmacCore core;
279 public HmacSHA384() throws NoSuchAlgorithmException {
280 core = new HmacCore("SHA-384", 128);
281 }
282 private HmacSHA384(HmacSHA384 base) throws CloneNotSupportedException {
283 core = (HmacCore)base.core.clone();
284 }
285 protected int engineGetMacLength() {
286 return core.getDigestLength();
287 }
288 protected void engineInit(Key key, AlgorithmParameterSpec params)
289 throws InvalidKeyException, InvalidAlgorithmParameterException {
290 core.init(key, params);
291 }
292 protected void engineUpdate(byte input) {
293 core.update(input);
294 }
295 protected void engineUpdate(byte input[], int offset, int len) {
296 core.update(input, offset, len);
297 }
298 protected void engineUpdate(ByteBuffer input) {
299 core.update(input);
300 }
301 protected byte[] engineDoFinal() {
302 return core.doFinal();
303 }
304 protected void engineReset() {
305 core.reset();
306 }
307 public Object clone() throws CloneNotSupportedException {
308 return new HmacSHA384(this);
309 }
310 }
311
312 // nested static class for the HmacSHA512 implementation
313 public static final class HmacSHA512 extends MacSpi implements Cloneable {
314 private final HmacCore core;
315 public HmacSHA512() throws NoSuchAlgorithmException {
316 core = new HmacCore("SHA-512", 128);
317 }
318 private HmacSHA512(HmacSHA512 base) throws CloneNotSupportedException {
319 core = (HmacCore)base.core.clone();
320 }
321 protected int engineGetMacLength() {
322 return core.getDigestLength();
323 }
324 protected void engineInit(Key key, AlgorithmParameterSpec params)
325 throws InvalidKeyException, InvalidAlgorithmParameterException {
326 core.init(key, params);
327 }
328 protected void engineUpdate(byte input) {
329 core.update(input);
330 }
331 protected void engineUpdate(byte input[], int offset, int len) {
332 core.update(input, offset, len);
333 }
334 protected void engineUpdate(ByteBuffer input) {
335 core.update(input);
336 }
337 protected byte[] engineDoFinal() {
338 return core.doFinal();
339 }
340 protected void engineReset() {
341 core.reset();
342 }
343 public Object clone() throws CloneNotSupportedException {
344 return new HmacSHA512(this);
345 }
346 }
347
348}