001: /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
002: /*
003: Copyright (c) 2006-2008 ymnk, JCraft,Inc. All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without
006: modification, are permitted provided that the following conditions are met:
007:
008: 1. Redistributions of source code must retain the above copyright notice,
009: this list of conditions and the following disclaimer.
010:
011: 2. Redistributions in binary form must reproduce the above copyright
012: notice, this list of conditions and the following disclaimer in
013: the documentation and/or other materials provided with the distribution.
014:
015: 3. The names of the authors may not be used to endorse or promote products
016: derived from this software without specific prior written permission.
017:
018: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
019: INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
020: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
021: INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
022: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
023: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
024: OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025: LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026: NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
027: EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: */
029:
030: package com.jcraft.jsch.jcraft;
031:
032: import java.security.*;
033:
034: class HMAC {
035:
036: /*
037: * Refer to RFC2104.
038: *
039: * H(K XOR opad, H(K XOR ipad, text))
040: *
041: * where K is an n byte key
042: * ipad is the byte 0x36 repeated 64 times
043: * opad is the byte 0x5c repeated 64 times
044: * and text is the data being protected
045: */
046: private static final int B = 64;
047: private byte[] k_ipad = null;
048: private byte[] k_opad = null;
049:
050: private MessageDigest md = null;
051:
052: private int bsize = 0;
053:
054: protected void setH(MessageDigest md) {
055: this .md = md;
056: bsize = md.getDigestLength();
057: }
058:
059: public int getBlockSize() {
060: return bsize;
061: };
062:
063: public void init(byte[] key) throws Exception {
064: if (key.length > bsize) {
065: byte[] tmp = new byte[bsize];
066: System.arraycopy(key, 0, tmp, 0, bsize);
067: key = tmp;
068: }
069:
070: /* if key is longer than B bytes reset it to key=MD5(key) */
071: if (key.length > B) {
072: md.update(key, 0, key.length);
073: key = md.digest();
074: }
075:
076: k_ipad = new byte[B];
077: System.arraycopy(key, 0, k_ipad, 0, key.length);
078: k_opad = new byte[B];
079: System.arraycopy(key, 0, k_opad, 0, key.length);
080:
081: /* XOR key with ipad and opad values */
082: for (int i = 0; i < B; i++) {
083: k_ipad[i] ^= (byte) 0x36;
084: k_opad[i] ^= (byte) 0x5c;
085: }
086:
087: md.update(k_ipad, 0, B);
088: }
089:
090: private final byte[] tmp = new byte[4];
091:
092: public void update(int i) {
093: tmp[0] = (byte) (i >>> 24);
094: tmp[1] = (byte) (i >>> 16);
095: tmp[2] = (byte) (i >>> 8);
096: tmp[3] = (byte) i;
097: update(tmp, 0, 4);
098: }
099:
100: public void update(byte foo[], int s, int l) {
101: md.update(foo, s, l);
102: }
103:
104: public void doFinal(byte[] buf, int offset) {
105: byte[] result = md.digest();
106: md.update(k_opad, 0, B);
107: md.update(result, 0, bsize);
108: try {
109: md.digest(buf, offset, bsize);
110: } catch (Exception e) {
111: }
112: md.update(k_ipad, 0, B);
113: }
114: }
|