view src/ch/ethz/ssh2/crypto/digest/HMAC.java @ 402:14aa0621aa7d stable-1.9.0

Backed out changeset 2f2b5a244a4d
author Carl Byington <carl@five-ten-sg.com>
date Mon, 20 Oct 2014 19:14:39 -0700
parents 071eccdff8ea
children
line wrap: on
line source

/*
 * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
 * Please refer to the LICENSE.txt for licensing details.
 */
package ch.ethz.ssh2.crypto.digest;

import java.security.DigestException;

/**
 * HMAC.
 *
 * @author Christian Plattner
 * @version 2.50, 03/15/10
 */
public final class HMAC implements Digest {
    Digest md;
    byte[] k_xor_ipad;
    byte[] k_xor_opad;

    byte[] tmp;

    int size;

    public HMAC(Digest md, byte[] key, int size) throws DigestException {
        this.md = md;
        this.size = size;
        tmp = new byte[md.getDigestLength()];
        final int BLOCKSIZE = 64;
        k_xor_ipad = new byte[BLOCKSIZE];
        k_xor_opad = new byte[BLOCKSIZE];

        if (key.length > BLOCKSIZE) {
            md.reset();
            md.update(key);
            md.digest(tmp);
            key = tmp;
        }

        System.arraycopy(key, 0, k_xor_ipad, 0, key.length);
        System.arraycopy(key, 0, k_xor_opad, 0, key.length);

        for (int i = 0; i < BLOCKSIZE; i++) {
            k_xor_ipad[i] ^= 0x36;
            k_xor_opad[i] ^= 0x5C;
        }

        md.update(k_xor_ipad);
    }

    public final int getDigestLength() {
        return size;
    }

    public final void update(byte b) {
        md.update(b);
    }

    public final void update(byte[] b) {
        md.update(b);
    }

    public final void update(byte[] b, int off, int len) {
        md.update(b, off, len);
    }

    public final void reset() {
        md.reset();
        md.update(k_xor_ipad);
    }

    public final void digest(byte[] out) throws DigestException {
        digest(out, 0);
    }

    public final void digest(byte[] out, int off) throws DigestException {
        md.digest(tmp);
        md.update(k_xor_opad);
        md.update(tmp);
        md.digest(tmp);
        System.arraycopy(tmp, 0, out, off, size);
        md.update(k_xor_ipad);
    }
}