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
|
package org.bouncycastle.crypto.generators;
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.MGFParameters;
/**
* Generator for MGF1 as defined in PKCS 1v2
*/
public class MGF1BytesGenerator
implements DerivationFunction
{
private Digest digest;
private byte[] seed;
private int hLen;
/**
* @param digest the digest to be used as the source of generated bytes
*/
public MGF1BytesGenerator(
Digest digest)
{
this.digest = digest;
this.hLen = digest.getDigestSize();
}
public void init(
DerivationParameters param)
{
if (!(param instanceof MGFParameters))
{
throw new IllegalArgumentException("MGF parameters required for MGF1Generator");
}
MGFParameters p = (MGFParameters)param;
seed = p.getSeed();
}
/**
* return the underlying digest.
*/
public Digest getDigest()
{
return digest;
}
/**
* int to octet string.
*/
private void ItoOSP(
int i,
byte[] sp)
{
sp[0] = (byte)(i >>> 24);
sp[1] = (byte)(i >>> 16);
sp[2] = (byte)(i >>> 8);
sp[3] = (byte)(i >>> 0);
}
/**
* fill len bytes of the output buffer with bytes generated from
* the derivation function.
*
* @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");
}
byte[] hashBuf = new byte[hLen];
byte[] C = new byte[4];
int counter = 0;
digest.reset();
if (len > hLen)
{
do
{
ItoOSP(counter, C);
digest.update(seed, 0, seed.length);
digest.update(C, 0, C.length);
digest.doFinal(hashBuf, 0);
System.arraycopy(hashBuf, 0, out, outOff + counter * hLen, hLen);
}
while (++counter < (len / hLen));
}
if ((counter * hLen) < len)
{
ItoOSP(counter, C);
digest.update(seed, 0, seed.length);
digest.update(C, 0, C.length);
digest.doFinal(hashBuf, 0);
System.arraycopy(hashBuf, 0, out, outOff + counter * hLen, len - (counter * hLen));
}
return len;
}
}
|