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+
26+package com.sun.crypto.provider;
27+
28+import java.util.Arrays;
29+
30+import java.nio.ByteBuffer;
31+
32+import javax.crypto.MacSpi;
33+import javax.crypto.SecretKey;
34+import java.security.*;
35+import 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+ */
46+final 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+}