Simplified the KDF implementation, since one iteration is enough.

We don't need to call HMAC-SHA-384 more than once to get 256 bits of key
material. The code will throw a RuntimeException if CIPHER_KEY_BYTES is
changed in future so that one iteration's no longer enough.
This commit is contained in:
akwizgran
2013-07-12 19:05:27 +01:00
parent a8d86a1b05
commit 95788cc1c6

View File

@@ -403,26 +403,26 @@ class CryptoComponentImpl implements CryptoComponent {
throw new IllegalArgumentException();
if(Arrays.equals(secret, BLANK_SECRET))
throw new IllegalArgumentException();
// The label must be null-terminated
if(label[label.length - 1] != '\0')
throw new IllegalArgumentException();
// Initialise the PRF
Mac prf = new HMac(new SHA384Digest());
KeyParameter k = new KeyParameter(secret);
prf.init(k);
int macLength = prf.getMacSize();
// The output of the PRF must be long enough to use as a key
if(macLength < CIPHER_KEY_BYTES) throw new RuntimeException();
byte[] mac = new byte[macLength], output = new byte[CIPHER_KEY_BYTES];
prf.update((byte) 0); // Counter
prf.update(label, 0, label.length); // Null-terminated
byte[] contextBytes = new byte[4];
ByteUtils.writeUint32(context, contextBytes, 0);
for(int i = 0; i * macLength < CIPHER_KEY_BYTES; i++) {
prf.update((byte) i); // Counter
prf.update(label, 0, label.length);
prf.update(contextBytes, 0, contextBytes.length);
prf.update((byte) CIPHER_KEY_BYTES); // Output length
prf.doFinal(mac, 0);
int bytesNeeded = CIPHER_KEY_BYTES - i * macLength;
int bytesToUse = Math.min(bytesNeeded, macLength);
System.arraycopy(mac, 0, output, i * macLength, bytesToUse);
ByteUtils.erase(mac);
}
prf.update(contextBytes, 0, contextBytes.length);
prf.update((byte) CIPHER_KEY_BYTES); // Output length
prf.doFinal(mac, 0);
System.arraycopy(mac, 0, output, 0, output.length);
ByteUtils.erase(mac);
ByteUtils.erase(k.getKey());
return output;
}