diff --git a/src/main/java/com/google/crypto/tink/subtle/AesSiv.java b/src/main/java/com/google/crypto/tink/subtle/AesSiv.java index 83f0df64..b7cb23a4 100644 --- a/src/main/java/com/google/crypto/tink/subtle/AesSiv.java +++ b/src/main/java/com/google/crypto/tink/subtle/AesSiv.java @@ -69,6 +69,18 @@ public static DeterministicAead create(AesSivKey key) throws GeneralSecurityExce key.getKeyBytes().toByteArray(InsecureSecretKeyAccess.get()), key.getOutputPrefix()); } + private static final ThreadLocal localAesCtrCipher = + new ThreadLocal() { + @Override + protected Cipher initialValue() { + try { + return EngineFactory.CIPHER.getInstance("AES/CTR/NoPadding"); + } catch (GeneralSecurityException ex) { + throw new IllegalStateException(ex); + } + } + }; + private AesSiv(final byte[] key, Bytes outputPrefix) throws GeneralSecurityException { if (!FIPS.isCompatible()) { throw new GeneralSecurityException( @@ -132,7 +144,7 @@ public byte[] encryptDeterministically(final byte[] plaintext, final byte[] asso throw new GeneralSecurityException("plaintext too long"); } - Cipher aesCtr = EngineFactory.CIPHER.getInstance("AES/CTR/NoPadding"); + Cipher aesCtr = localAesCtrCipher.get(); byte[] computedIv = s2v(associatedData, plaintext); byte[] ivForJavaCrypto = computedIv.clone(); ivForJavaCrypto[8] &= (byte) 0x7F; // 63th bit from the right @@ -158,7 +170,7 @@ public byte[] decryptDeterministically(final byte[] ciphertext, final byte[] ass throw new GeneralSecurityException("Decryption failed (OutputPrefix mismatch)."); } - Cipher aesCtr = EngineFactory.CIPHER.getInstance("AES/CTR/NoPadding"); + Cipher aesCtr = localAesCtrCipher.get(); byte[] expectedIv = Arrays.copyOfRange( diff --git a/src/main/java/com/google/crypto/tink/subtle/PrfAesCmac.java b/src/main/java/com/google/crypto/tink/subtle/PrfAesCmac.java index b92541a2..6a11d677 100644 --- a/src/main/java/com/google/crypto/tink/subtle/PrfAesCmac.java +++ b/src/main/java/com/google/crypto/tink/subtle/PrfAesCmac.java @@ -48,11 +48,23 @@ public final class PrfAesCmac implements Prf { @SuppressWarnings("Immutable") private byte[] subKey2; + private static final ThreadLocal localAesCipher = + new ThreadLocal() { + @Override + protected Cipher initialValue() { + try { + return EngineFactory.CIPHER.getInstance("AES/ECB/NoPadding"); + } catch (GeneralSecurityException ex) { + throw new IllegalStateException(ex); + } + } + }; + private static Cipher instance() throws GeneralSecurityException { if (!FIPS.isCompatible()) { throw new GeneralSecurityException("Can not use AES-CMAC in FIPS-mode."); } - return EngineFactory.CIPHER.getInstance("AES/ECB/NoPadding"); + return localAesCipher.get(); } public PrfAesCmac(final byte[] key) throws GeneralSecurityException {