1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46:
47: import ;
48: import ;
49: import ;
50: import ;
51:
52:
56: public class UMacRandomSpi
57: extends SecureRandomSpi
58: {
59: private static final Logger log = Logger.getLogger(UMacRandomSpi.class.getName());
60:
61: private static final UMacGenerator prng;
62: static
63: {
64: prng = new UMacGenerator();
65: resetLocalPRNG();
66: }
67:
68: private static final String MSG = "Exception while setting up a "
69: + Registry.UMAC_PRNG + " SPI: ";
70: private static final String RETRY = "Retry...";
71:
72: private UMacGenerator adaptee = new UMacGenerator();
73:
74:
75:
76: private static void resetLocalPRNG()
77: {
78: HashMap attributes = new HashMap();
79: attributes.put(UMacGenerator.CIPHER, Registry.AES_CIPHER);
80: byte[] key = new byte[128 / 8];
81: Random rand = new Random(System.currentTimeMillis());
82: rand.nextBytes(key);
83: attributes.put(IBlockCipher.KEY_MATERIAL, key);
84: int index = rand.nextInt() & 0xFF;
85: attributes.put(UMacGenerator.INDEX, Integer.valueOf(index));
86: prng.setup(attributes);
87: }
88:
89: public byte[] engineGenerateSeed(int numBytes)
90: {
91: if (numBytes < 1)
92: return new byte[0];
93: byte[] result = new byte[numBytes];
94: this.engineNextBytes(result);
95: return result;
96: }
97:
98: public void engineNextBytes(byte[] bytes)
99: {
100: if (! adaptee.isInitialised())
101: this.engineSetSeed(new byte[0]);
102: while (true)
103: {
104: try
105: {
106: adaptee.nextBytes(bytes, 0, bytes.length);
107: break;
108: }
109: catch (LimitReachedException x)
110: {
111: resetLocalPRNG();
112: }
113: }
114: }
115:
116: public void engineSetSeed(byte[] seed)
117: {
118:
119: int materialLength = 0;
120: materialLength += 16;
121: materialLength++;
122: byte[] material = new byte[materialLength];
123:
124: int materialOffset = 0;
125: int materialLeft = material.length;
126: if (seed.length > 0)
127: {
128: int lenToCopy = Math.min(materialLength, seed.length);
129: System.arraycopy(seed, 0, material, 0, lenToCopy);
130: materialOffset += lenToCopy;
131: materialLeft -= lenToCopy;
132: }
133: if (materialOffset > 0)
134: {
135: while (true)
136: {
137: try
138: {
139: prng.nextBytes(material, materialOffset, materialLeft);
140: break;
141: }
142: catch (IllegalStateException x)
143: {
144: throw new InternalError(MSG + String.valueOf(x));
145: }
146: catch (LimitReachedException x)
147: {
148: if (Configuration.DEBUG)
149: {
150: log.fine(MSG + String.valueOf(x));
151: log.fine(RETRY);
152: }
153: }
154: }
155: }
156:
157: HashMap attributes = new HashMap();
158:
159: attributes.put(UMacGenerator.CIPHER, Registry.AES_CIPHER);
160:
161: byte[] key = new byte[16];
162: System.arraycopy(material, 0, key, 0, 16);
163: attributes.put(IBlockCipher.KEY_MATERIAL, key);
164:
165: attributes.put(UMacGenerator.INDEX, Integer.valueOf(material[16] & 0xFF));
166: adaptee.init(attributes);
167: }
168: }