01: package org.bouncycastle.crypto.generators;
02:
03: import org.bouncycastle.crypto.DataLengthException;
04: import org.bouncycastle.crypto.DerivationFunction;
05: import org.bouncycastle.crypto.DerivationParameters;
06: import org.bouncycastle.crypto.Digest;
07: import org.bouncycastle.crypto.params.MGFParameters;
08:
09: /**
10: * Generator for MGF1 as defined in PKCS 1v2
11: */
12: public class MGF1BytesGenerator implements DerivationFunction {
13: private Digest digest;
14: private byte[] seed;
15: private int hLen;
16:
17: /**
18: * @param digest the digest to be used as the source of generated bytes
19: */
20: public MGF1BytesGenerator(Digest digest) {
21: this .digest = digest;
22: this .hLen = digest.getDigestSize();
23: }
24:
25: public void init(DerivationParameters param) {
26: if (!(param instanceof MGFParameters)) {
27: throw new IllegalArgumentException(
28: "MGF parameters required for MGF1Generator");
29: }
30:
31: MGFParameters p = (MGFParameters) param;
32:
33: seed = p.getSeed();
34: }
35:
36: /**
37: * return the underlying digest.
38: */
39: public Digest getDigest() {
40: return digest;
41: }
42:
43: /**
44: * int to octet string.
45: */
46: private void ItoOSP(int i, byte[] sp) {
47: sp[0] = (byte) (i >>> 24);
48: sp[1] = (byte) (i >>> 16);
49: sp[2] = (byte) (i >>> 8);
50: sp[3] = (byte) (i >>> 0);
51: }
52:
53: /**
54: * fill len bytes of the output buffer with bytes generated from
55: * the derivation function.
56: *
57: * @throws DataLengthException if the out buffer is too small.
58: */
59: public int generateBytes(byte[] out, int outOff, int len)
60: throws DataLengthException, IllegalArgumentException {
61: if ((out.length - len) < outOff) {
62: throw new DataLengthException("output buffer too small");
63: }
64:
65: byte[] hashBuf = new byte[hLen];
66: byte[] C = new byte[4];
67: int counter = 0;
68:
69: digest.reset();
70:
71: if (len > hLen) {
72: do {
73: ItoOSP(counter, C);
74:
75: digest.update(seed, 0, seed.length);
76: digest.update(C, 0, C.length);
77: digest.doFinal(hashBuf, 0);
78:
79: System.arraycopy(hashBuf, 0, out, outOff + counter
80: * hLen, hLen);
81: } while (++counter < (len / hLen));
82: }
83:
84: if ((counter * hLen) < len) {
85: ItoOSP(counter, C);
86:
87: digest.update(seed, 0, seed.length);
88: digest.update(C, 0, C.length);
89: digest.doFinal(hashBuf, 0);
90:
91: System.arraycopy(hashBuf, 0, out, outOff + counter * hLen,
92: len - (counter * hLen));
93: }
94:
95: return len;
96: }
97: }
|