Welcome to mirror list, hosted at ThFree Co, Russian Federation.

BrokenKDF2BytesGenerator.java « provider « jce « bouncycastle « org « java « main « src « prov - gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: e6186f674c92038927ce4790b019a28b5e867340 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package org.bouncycastle.jce.provider;

import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.DerivationFunction;
import org.bouncycastle.crypto.DerivationParameters;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.params.KDFParameters;

/**
 * Generator for PBE derived keys and ivs as defined by IEEE P1363a
 * <br>
 * This implementation is based on draft 9 of IEEE P1363a. <b>Note:</b>
 * as this is still a draft the output of this generator may change, don't
 * use it for anything that might be subject to long term storage.
 */
public class BrokenKDF2BytesGenerator
    implements DerivationFunction
{
    private Digest  digest;
    private byte[]  shared;
    private byte[]  iv;

    /**
     * Construct a KDF2 Parameters generator. Generates key material
     * according to IEEE P1363a - if you want orthodox results you should
     * use a digest specified in the standard.
     * <p>
     * <b>Note:</b> IEEE P1363a standard is still a draft standard, if the standard
     * changes this function, the output of this function will change as well.
     * Don't use this routine for anything subject to long term storage.
     *
     * @param digest the digest to be used as the source of derived keys.
     */
    public BrokenKDF2BytesGenerator(
        Digest  digest)
    {
        this.digest = digest;
    }

    public void init(
        DerivationParameters    param)
    {
        if (!(param instanceof KDFParameters))
        {
            throw new IllegalArgumentException("KDF parameters required for KDF2Generator");
        }

        KDFParameters   p = (KDFParameters)param;

        shared = p.getSharedSecret();
        iv = p.getIV();
    }

    /**
     * return the underlying digest.
     */
    public Digest getDigest()
    {
        return digest;
    }

    /**
     * fill len bytes of the output buffer with bytes generated from
     * the derivation function.
     *
     * @throws IllegalArgumentException if the size of the request will cause an overflow.
     * @throws DataLengthException if the out buffer is too small.
     */
    public int generateBytes(
        byte[]  out,
        int     outOff,
        int     len)
        throws DataLengthException, IllegalArgumentException
    {
        if ((out.length - len) < outOff)
        {
            throw new DataLengthException("output buffer too small");
        }

        long    oBits = len * 8;

        //
        // this is at odds with the standard implementation, the
        // maximum value should be hBits * (2^23 - 1) where hBits
        // is the digest output size in bits. We can't have an
        // array with a long index at the moment...
        //
        if (oBits > (digest.getDigestSize() * 8 * (2L^32 - 1)))
        {
            new IllegalArgumentException("Output length to large");
        }
    
        int cThreshold = (int)(oBits / digest.getDigestSize());

        byte[] dig = null;

        dig = new byte[digest.getDigestSize()];

        for (int counter = 1; counter <= cThreshold; counter++)
        {
            digest.update(shared, 0, shared.length);

            digest.update((byte)(counter & 0xff));
            digest.update((byte)((counter >> 8) & 0xff));
            digest.update((byte)((counter >> 16) & 0xff));
            digest.update((byte)((counter >> 24) & 0xff));

            digest.update(iv, 0, iv.length);

            digest.doFinal(dig, 0);

            if ((len - outOff) > dig.length)
            {
                System.arraycopy(dig, 0, out, outOff, dig.length);
                outOff += dig.length;
            }
            else
            {
                System.arraycopy(dig, 0, out, outOff, len - outOff);
            }
        }
    
        digest.reset();

        return len;
    }
}