@@ -0,0 +1,2409 @@
+package org.bouncycastle.crypto.tls;%0A%0Aimport org.bouncycastle.crypto.CipherParameters;%0Aimport org.bouncycastle.crypto.Digest;%0Aimport org.bouncycastle.crypto.Mac;%0Aimport org.bouncycastle.crypto.params.KeyParameter;%0Aimport org.bouncycastle.util.Arrays;%0A%0A/**%0A * HMAC implementation based on original internet draft for HMAC (RFC 2104)%0A * %0A * The difference is that padding is concatentated versus XORed with the key%0A * %0A * H(K + opad, H(K + ipad, text))%0A */%0Apublic class SSL3Mac implements Mac%0A%7B%0A    private final static byte IPAD = (byte)0x36;%0A    private final static byte OPAD = (byte)0x5C;%0A%0A    private Digest digest;%0A%0A    private byte%5B%5D secret;%0A    private byte%5B%5D ipad, opad;%0A%0A    /**%0A     * Base constructor for one of the standard digest algorithms that the byteLength of%0A     * the algorithm is know for. Pad length should be 48 for MD5 or 40 for SHA1.%0A     * %0A     * @param digest the digest.%0A     */%0A    public SSL3Mac(Digest digest, int padLength)%0A    %7B%0A        this.digest = digest;%0A        this.ipad = genPad(IPAD, padLength);%0A        this.opad = genPad(OPAD, padLength);%0A    %7D%0A%0A    public String getAlgorithmName()%0A    %7B%0A        return digest.getAlgorithmName() + %22/SSL3MAC%22;%0A    %7D%0A%0A    public Digest getUnderlyingDigest()%0A    %7B%0A        return digest;%0A    %7D%0A%0A    public void init(CipherParameters params)%0A    %7B%0A        secret = Arrays.clone(((KeyParameter)params).getKey());%0A%0A        reset();%0A    %7D%0A%0A    public int getMacSize()%0A    %7B%0A        return digest.getDigestSize();%0A    %7D%0A%0A    public void update(byte in)%0A    %7B%0A        digest.update(in);%0A    %7D%0A%0A    public void update(byte%5B%5D in, int inOff, int len)%0A    %7B%0A        digest.update(in, inOff, len);%0A    %7D%0A%0A    public int doFinal(byte%5B%5D out, int outOff)%0A    %7B%0A        byte%5B%5D tmp = new byte%5Bdigest.getDigestSize()%5D;%0A        digest.doFinal(tmp, 0);%0A%0A        digest.update(secret, 0, secret.length);%0A        digest.update(opad, 0, opad.length);%0A        digest.update(tmp, 0, tmp.length);%0A%0A        int len = digest.doFinal(out, outOff);%0A%0A        reset();%0A%0A        return len;%0A    %7D%0A%0A    /**%0A     * Reset the mac generator.%0A     */%0A    public void reset()%0A    %7B%0A        digest.reset();%0A        digest.update(secret, 0, secret.length);%0A        digest.update(ipad, 0, ipad.length);%0A    %7D%0A%0A    private static byte%5B%5D genPad(byte b, int count)%0A    %7B%0A        byte%5B%5D padding = new byte%5Bcount%5D;%0A        Arrays.fill(padding, b);%0A        return padding;%0A    %7D%0A%7D%0A

Add SSL3MAC (early draft of HMac)