1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.crypto.generators;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.CipherParameters;
4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.Digest;
5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.ExtendedDigest;
6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.PBEParametersGenerator;
7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.params.KeyParameter;
8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.params.ParametersWithIV;
9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/**
11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Generator for PBE derived keys and ivs as defined by PKCS 12 V1.0.
12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * <p>
13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * The document this implementation is based on can be found at
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * <a href=http://www.rsasecurity.com/rsalabs/pkcs/pkcs-12/index.html>
15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * RSA's PKCS12 Page</a>
16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */
17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class PKCS12ParametersGenerator
18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    extends PBEParametersGenerator
19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static final int KEY_MATERIAL = 1;
21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static final int IV_MATERIAL  = 2;
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static final int MAC_MATERIAL = 3;
23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private Digest digest;
25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private int     u;
27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private int     v;
28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Construct a PKCS 12 Parameters generator. This constructor will
31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * accept any digest which also implements ExtendedDigest.
32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param digest the digest to be used as the source of derived keys.
34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @exception IllegalArgumentException if an unknown digest is passed in.
35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public PKCS12ParametersGenerator(
37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Digest  digest)
38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.digest = digest;
40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (digest instanceof ExtendedDigest)
41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            u = digest.getDigestSize();
43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            v = ((ExtendedDigest)digest).getByteLength();
44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else
46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw new IllegalArgumentException("Digest " + digest.getAlgorithmName() + " unsupported");
48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * add a + b + 1, returning the result in a. The a value is treated
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * as a BigInteger of length (b.length * 8) bits. The result is
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * modulo 2^b.length in case of overflow.
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private void adjust(
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  a,
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int     aOff,
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  b)
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int  x = (b[b.length - 1] & 0xff) + (a[aOff + b.length - 1] & 0xff) + 1;
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        a[aOff + b.length - 1] = (byte)x;
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        x >>>= 8;
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        for (int i = b.length - 2; i >= 0; i--)
67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            x += (b[i] & 0xff) + (a[aOff + i] & 0xff);
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            a[aOff + i] = (byte)x;
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            x >>>= 8;
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * generation of a derived key ala PKCS12 V1.0.
76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private byte[] generateDerivedKey(
78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int idByte,
79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int n)
80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  D = new byte[v];
82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  dKey = new byte[n];
83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        for (int i = 0; i != D.length; i++)
85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            D[i] = (byte)idByte;
87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  S;
90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if ((salt != null) && (salt.length != 0))
92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            S = new byte[v * ((salt.length + v - 1) / v)];
94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            for (int i = 0; i != S.length; i++)
96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                S[i] = salt[i % salt.length];
98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else
101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            S = new byte[0];
103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  P;
106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if ((password != null) && (password.length != 0))
108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            P = new byte[v * ((password.length + v - 1) / v)];
110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            for (int i = 0; i != P.length; i++)
112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                P[i] = password[i % password.length];
114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else
117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            P = new byte[0];
119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  I = new byte[S.length + P.length];
122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        System.arraycopy(S, 0, I, 0, S.length);
124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        System.arraycopy(P, 0, I, S.length, P.length);
125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  B = new byte[v];
127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int     c = (n + u - 1) / u;
128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        for (int i = 1; i <= c; i++)
130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            byte[]  A = new byte[u];
132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            digest.update(D, 0, D.length);
134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            digest.update(I, 0, I.length);
135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            digest.doFinal(A, 0);
1364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            for (int j = 1; j < iterationCount; j++)
137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                digest.update(A, 0, A.length);
139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                digest.doFinal(A, 0);
140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            for (int j = 0; j != B.length; j++)
143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                B[j] = A[j % A.length];
145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            for (int j = 0; j != I.length / v; j++)
148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                adjust(I, j * v, B);
150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (i == c)
153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                System.arraycopy(A, 0, dKey, (i - 1) * u, dKey.length - ((i - 1) * u));
155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            else
157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                System.arraycopy(A, 0, dKey, (i - 1) * u, A.length);
159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return dKey;
163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
166b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Generate a key parameter derived from the password, salt, and iteration
167b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * count we are currently initialised with.
168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param keySize the size of the key we want (in bits)
170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return a KeyParameter object.
171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public CipherParameters generateDerivedParameters(
173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int keySize)
174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        keySize = keySize / 8;
176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
177b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  dKey = generateDerivedKey(KEY_MATERIAL, keySize);
178b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
179b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return new KeyParameter(dKey, 0, keySize);
180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
181b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
182b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Generate a key with initialisation vector parameter derived from
184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * the password, salt, and iteration count we are currently initialised
185b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * with.
186b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
187b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param keySize the size of the key we want (in bits)
188b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param ivSize the size of the iv we want (in bits)
189b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return a ParametersWithIV object.
190b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
191b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public CipherParameters generateDerivedParameters(
192b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int     keySize,
193b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int     ivSize)
194b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
195b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        keySize = keySize / 8;
196b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ivSize = ivSize / 8;
197b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
198b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  dKey = generateDerivedKey(KEY_MATERIAL, keySize);
199b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
200b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  iv = generateDerivedKey(IV_MATERIAL, ivSize);
201b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
202b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), iv, 0, ivSize);
203b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
204b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
205b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
206b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Generate a key parameter for use with a MAC derived from the password,
207b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * salt, and iteration count we are currently initialised with.
208b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
209b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param keySize the size of the key we want (in bits)
210b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return a KeyParameter object.
211b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
212b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public CipherParameters generateDerivedMacParameters(
213b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int keySize)
214b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
215b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        keySize = keySize / 8;
216b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
217b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  dKey = generateDerivedKey(MAC_MATERIAL, keySize);
218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
219b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return new KeyParameter(dKey, 0, keySize);
220b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
221b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
222