diff --git a/common/src/main/java/org/conscrypt/OpenSSLMac.java b/common/src/main/java/org/conscrypt/OpenSSLMac.java index b8f529632..601670fdf 100644 --- a/common/src/main/java/org/conscrypt/OpenSSLMac.java +++ b/common/src/main/java/org/conscrypt/OpenSSLMac.java @@ -141,7 +141,7 @@ protected byte[] engineDoFinal() { protected abstract byte[] doFinal(); @Override - protected void engineReset() { + protected synchronized void engineReset() { if (!initialized) { return; } @@ -163,36 +163,35 @@ public Hmac(long evpMd, int size) { } @Override - protected void initContext(byte[] keyBytes) { + protected synchronized void initContext(byte[] keyBytes) { NativeRef.HMAC_CTX ctxLocal = new NativeRef.HMAC_CTX(NativeCrypto.HMAC_CTX_new()); NativeCrypto.HMAC_Init_ex(ctxLocal, keyBytes, evpMd); this.ctx = ctxLocal; } @Override - protected void resetContext() { + protected synchronized void resetContext() { final NativeRef.HMAC_CTX ctxLocal = ctx; NativeCrypto.HMAC_Reset(ctxLocal); } @Override - protected void engineUpdate(byte[] input, int offset, int len) { + protected synchronized void engineUpdate(byte[] input, int offset, int len) { final NativeRef.HMAC_CTX ctxLocal = ctx; NativeCrypto.HMAC_Update(ctxLocal, input, offset, len); } @Override - protected void updateDirect(long ptr, int len) { + protected synchronized void updateDirect(long ptr, int len) { final NativeRef.HMAC_CTX ctxLocal = ctx; NativeCrypto.HMAC_UpdateDirect(ctxLocal, ptr, len); } @Override - protected byte[] doFinal() { + protected synchronized byte[] doFinal() { final NativeRef.HMAC_CTX ctxLocal = ctx; return NativeCrypto.HMAC_Final(ctxLocal); } - } public static final class HmacMD5 extends Hmac { @@ -239,32 +238,32 @@ public AesCmac() { } @Override - protected void initContext(byte[] keyBytes) { + protected synchronized void initContext(byte[] keyBytes) { NativeRef.CMAC_CTX ctxLocal = new NativeRef.CMAC_CTX(NativeCrypto.CMAC_CTX_new()); NativeCrypto.CMAC_Init(ctxLocal, keyBytes); this.ctx = ctxLocal; } @Override - protected void resetContext() { + protected synchronized void resetContext() { final NativeRef.CMAC_CTX ctxLocal = ctx; NativeCrypto.CMAC_Reset(ctxLocal); } @Override - protected void updateDirect(long ptr, int len) { + protected synchronized void updateDirect(long ptr, int len) { final NativeRef.CMAC_CTX ctxLocal = ctx; NativeCrypto.CMAC_UpdateDirect(ctxLocal, ptr, len); } @Override - protected byte[] doFinal() { + protected synchronized byte[] doFinal() { final NativeRef.CMAC_CTX ctxLocal = ctx; return NativeCrypto.CMAC_Final(ctxLocal); } @Override - protected void engineUpdate(byte[] input, int offset, int len) { + protected synchronized void engineUpdate(byte[] input, int offset, int len) { final NativeRef.CMAC_CTX ctxLocal = ctx; NativeCrypto.CMAC_Update(ctxLocal, input, offset, len); } diff --git a/common/src/test/java/org/conscrypt/MacTest.java b/common/src/test/java/org/conscrypt/MacTest.java index 7dd52c8b3..51e1ec290 100644 --- a/common/src/test/java/org/conscrypt/MacTest.java +++ b/common/src/test/java/org/conscrypt/MacTest.java @@ -195,6 +195,27 @@ public void test(final Provider provider, final String algorithm) throws Excepti }); } + @Test + public void threadAbuse() { + newMacServiceTester().run((provider, algorithm) -> { + final byte[] b1 = new byte[2048]; + final byte[] b2 = new byte[2048]; + final byte[] b3 = new byte[2048]; + final Mac mac = Mac.getInstance(algorithm, provider); + final SecretKeySpec key = findAnyKey(algorithm); + + if (key != null) { + TestUtils.stressTest(32, 32, () -> { + mac.init(key); + mac.update(b1); + mac.update(b2); + mac.update(b3); + mac.reset(); + }); + } + }); + } + @Test public void invalidCmacKeySizeThrows() throws Exception { // TODO(prb): extend to other Macs, deal with inconsistencies between providers.