@@ -40,34 +40,38 @@ internal class ChaCha20CipherProvider(
40
40
41
41
private val cipherPool = SingletonCipherPoolProvider .getChaCha20CipherPool()
42
42
43
- override fun encrypt (plaintext : ByteArray ): ByteArray {
44
- val iv = if (deterministic) {
45
- MessageDigest .getInstance(DIGEST_SHA256 ).digest(plaintext).copyOf(IV_SIZE )
46
- } else {
47
- SecureRandomProvider .generate(IV_SIZE )
48
- }
49
- val paramSpec = AEADParameterSpec (iv, MAC_SIZE_BITS )
50
- val key = keyProvider.getOrCreateKey()
51
- val encrypted = cipherPool.withCipher { cipher ->
52
- cipher.init (Cipher .ENCRYPT_MODE , key, paramSpec)
53
- cipher.doFinal(plaintext)
43
+ private val cipherLock = Any ()
44
+
45
+ override fun encrypt (plaintext : ByteArray ): ByteArray =
46
+ synchronized(cipherLock) {
47
+ val iv = if (deterministic) {
48
+ MessageDigest .getInstance(DIGEST_SHA256 ).digest(plaintext).copyOf(IV_SIZE )
49
+ } else {
50
+ SecureRandomProvider .generate(IV_SIZE )
51
+ }
52
+ val paramSpec = AEADParameterSpec (iv, MAC_SIZE_BITS )
53
+ val key = keyProvider.getOrCreateKey()
54
+ val encrypted = cipherPool.withCipher { cipher ->
55
+ cipher.init (Cipher .ENCRYPT_MODE , key, paramSpec)
56
+ cipher.doFinal(plaintext)
57
+ }
58
+ (key as ? SafeSecretKey )?.releaseHeapCopy()
59
+ iv + encrypted
54
60
}
55
- (key as ? SafeSecretKey )?.releaseHeapCopy()
56
- return iv + encrypted
57
- }
58
61
59
- override fun decrypt (ciphertext : ByteArray ): ByteArray {
60
- val iv = ciphertext.copyOfRange(0 , IV_SIZE )
61
- val actual = ciphertext.copyOfRange(IV_SIZE , ciphertext.size)
62
- val paramSpec = AEADParameterSpec (iv, MAC_SIZE_BITS )
63
- val key = keyProvider.getOrCreateKey()
64
- val plaintext = cipherPool.withCipher { cipher ->
65
- cipher.init (Cipher .DECRYPT_MODE , key, paramSpec)
66
- cipher.doFinal(actual)
62
+ override fun decrypt (ciphertext : ByteArray ): ByteArray =
63
+ synchronized(cipherLock) {
64
+ val iv = ciphertext.copyOfRange(0 , IV_SIZE )
65
+ val actual = ciphertext.copyOfRange(IV_SIZE , ciphertext.size)
66
+ val paramSpec = AEADParameterSpec (iv, MAC_SIZE_BITS )
67
+ val key = keyProvider.getOrCreateKey()
68
+ val plaintext = cipherPool.withCipher { cipher ->
69
+ cipher.init (Cipher .DECRYPT_MODE , key, paramSpec)
70
+ cipher.doFinal(actual)
71
+ }
72
+ (key as ? SafeSecretKey )?.releaseHeapCopy()
73
+ plaintext
67
74
}
68
- (key as ? SafeSecretKey )?.releaseHeapCopy()
69
- return plaintext
70
- }
71
75
72
76
override fun destroyKey () {
73
77
keyProvider.destroyKey()
0 commit comments