Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.amazonaws.encryptionsdk.exception.BadCiphertextException;
import java.security.GeneralSecurityException;
import java.security.spec.AlgorithmParameterSpec;
import java.util.concurrent.ArrayBlockingQueue;
import javax.annotation.concurrent.NotThreadSafe;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
Expand All @@ -33,10 +34,12 @@
*/
@NotThreadSafe
class CipherHandler {
//TODO how to sze this, or allow it to be configured externally
private static final CipherPool CIPHER_POOL = new CipherPool(32);

private final int cipherMode_;
private final SecretKey key_;
private final CryptoAlgorithm cryptoAlgorithm_;
private final Cipher cipher_;

/**
* Process data through the cipher.
Expand All @@ -62,16 +65,19 @@ public byte[] cipherData(
final AlgorithmParameterSpec spec =
new GCMParameterSpec(cryptoAlgorithm_.getTagLen() * 8, nonce, 0, nonce.length);

final Cipher cipher = CIPHER_POOL.borrowCipher();
try {
cipher_.init(cipherMode_, key_, spec);
cipher.init(cipherMode_, key_, spec);
if (contentAad != null) {
cipher_.updateAAD(contentAad);
cipher.updateAAD(contentAad);
}
} catch (final GeneralSecurityException gsx) {
throw new AwsCryptoException(gsx);
}
try {
return cipher_.doFinal(content, off, len);
byte[] bytes = cipher.doFinal(content, off, len);
CIPHER_POOL.returnCipher(cipher);
return bytes;
} catch (final GeneralSecurityException gsx) {
throw new BadCiphertextException(gsx);
}
Expand All @@ -90,15 +96,30 @@ public byte[] cipherData(
this.cipherMode_ = cipherMode;
this.key_ = key;
this.cryptoAlgorithm_ = cryptoAlgorithm;
this.cipher_ = buildCipherObject(cryptoAlgorithm);
}

private static Cipher buildCipherObject(final CryptoAlgorithm alg) {
try {
// Right now, just GCM is supported
return Cipher.getInstance("AES/GCM/NoPadding");
} catch (final GeneralSecurityException ex) {
throw new IllegalStateException("Java does not support the requested algorithm", ex);
private static class CipherPool {
private final ArrayBlockingQueue<Cipher> pool;

CipherPool(int size) {
this.pool = new ArrayBlockingQueue<>(size);
}

Cipher borrowCipher() {
Cipher cipher = pool.poll();
if (cipher == null) {
try {
// Right now, just GCM is supported
cipher = Cipher.getInstance("AES/GCM/NoPadding");
} catch (final GeneralSecurityException ex) {
throw new IllegalStateException("Java does not support the requested algorithm", ex);
}
}
return cipher;
}

void returnCipher(Cipher cipher) {
pool.offer(cipher);
}
}
}