Skip to content

Commit 90b8cb6

Browse files
Added alternative CTR mode from JCE for faster computation.
1 parent 620a9ad commit 90b8cb6

File tree

2 files changed

+53
-8
lines changed

2 files changed

+53
-8
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package org.cryptomator.siv;
2+
3+
import javax.crypto.BadPaddingException;
4+
import javax.crypto.Cipher;
5+
import javax.crypto.IllegalBlockSizeException;
6+
import javax.crypto.NoSuchPaddingException;
7+
import javax.crypto.spec.IvParameterSpec;
8+
import javax.crypto.spec.SecretKeySpec;
9+
import java.security.InvalidAlgorithmParameterException;
10+
import java.security.InvalidKeyException;
11+
import java.security.NoSuchAlgorithmException;
12+
import java.security.Provider;
13+
14+
/**
15+
* Performs CTR Mode computations facilitating a cipher returned by JCE's <code>Cipher.getInstance("AES/CTR/NoPadding")</code>.
16+
*/
17+
final class JceAesCtrComputer implements SivMode.CtrComputer {
18+
19+
private final ThreadLocal<Cipher> threadLocalCipher;
20+
21+
public JceAesCtrComputer(final Provider jceSecurityProvider) {
22+
this.threadLocalCipher = new ThreadLocal<Cipher>(){
23+
@Override
24+
protected Cipher initialValue() {
25+
try {
26+
if (jceSecurityProvider == null) {
27+
return Cipher.getInstance("AES/CTR/NoPadding");
28+
} else {
29+
return Cipher.getInstance("AES/CTR/NoPadding", jceSecurityProvider);
30+
}
31+
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
32+
throw new IllegalStateException("AES/CTR/NoPadding not available on this platform.", e);
33+
}
34+
}
35+
};
36+
}
37+
38+
@Override
39+
public byte[] computeCtr(byte[] input, byte[] key, final byte[] iv) {
40+
try {
41+
Cipher cipher = threadLocalCipher.get();
42+
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv));
43+
return cipher.doFinal(input);
44+
} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
45+
throw new IllegalArgumentException("Key or IV invalid.");
46+
} catch (BadPaddingException e) {
47+
throw new IllegalStateException("Cipher doesn't require padding.", e);
48+
} catch (IllegalBlockSizeException e) {
49+
throw new IllegalStateException("Block size irrelevant for stream ciphers.", e);
50+
}
51+
}
52+
}

src/main/java/org/cryptomator/siv/SivMode.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,7 @@ public SivMode() {
5252
* @see #SivMode(BlockCipherFactory)
5353
*/
5454
public SivMode(final Provider jceSecurityProvider) {
55-
this(new BlockCipherFactory() {
56-
57-
@Override
58-
public BlockCipher create() {
59-
return new JceAesBlockCipher(jceSecurityProvider);
60-
}
61-
62-
});
55+
this(ThreadLocal.withInitial(() -> new JceAesBlockCipher(jceSecurityProvider)), new JceAesCtrComputer(jceSecurityProvider));
6356
}
6457

6558
/**

0 commit comments

Comments
 (0)