Add state cleanup for delegated and pure. There doesn't seem to be a easy way to clean js state

This commit is contained in:
Ugljesa Jovanovic 2020-07-10 22:08:08 +02:00 committed by Ugljesa Jovanovic
parent 1293b9ea75
commit 52b6a4ad8e
No known key found for this signature in database
GPG Key ID: 178E6DFCECCB0E0F
11 changed files with 51 additions and 6 deletions

View File

@ -76,10 +76,12 @@ class InvalidTagException : RuntimeException("Tag mismatch! Encrypted data is co
interface MultipartAuthenticatedDecryption { interface MultipartAuthenticatedDecryption {
fun decryptPartialData(data: EncryptedDataPart, additionalData: UByteArray = ubyteArrayOf()) : DecryptedDataPart fun decryptPartialData(data: EncryptedDataPart, additionalData: UByteArray = ubyteArrayOf()) : DecryptedDataPart
fun cleanup()
} }
interface MultipartAuthenticatedEncryption { interface MultipartAuthenticatedEncryption {
fun encryptPartialData(data: UByteArray, additionalData: UByteArray = ubyteArrayOf()) : EncryptedDataPart fun encryptPartialData(data: UByteArray, additionalData: UByteArray = ubyteArrayOf()) : EncryptedDataPart
fun startEncryption() : MultipartEncryptionHeader fun startEncryption() : MultipartEncryptionHeader
fun cleanup()
} }

View File

@ -189,6 +189,9 @@ class MultipartAuthenticatedEncryptor internal constructor(val key : SymmetricKe
return EncryptedDataPart(primitive.encrypt(data, additionalData)) return EncryptedDataPart(primitive.encrypt(data, additionalData))
} }
override fun cleanup() {
primitive.cleanup()
}
} }
@ -197,6 +200,10 @@ class MultipartAuthenticatedDecryptor internal constructor(val decryptor: XChaCh
return DecryptedDataPart(decryptor.decrypt(data.data, additionalData)) return DecryptedDataPart(decryptor.decrypt(data.data, additionalData))
} }
override fun cleanup() {
decryptor.cleanup()
}
} }
expect object Initializer { expect object Initializer {

View File

@ -16,6 +16,7 @@ expect class XChaCha20Poly1305Delegated internal constructor() {
fun initializeForDecryption(key: UByteArray, header: UByteArray) fun initializeForDecryption(key: UByteArray, header: UByteArray)
fun encrypt(data: UByteArray, additionalData: UByteArray = ubyteArrayOf()) : UByteArray fun encrypt(data: UByteArray, additionalData: UByteArray = ubyteArrayOf()) : UByteArray
fun decrypt(data: UByteArray, additionalData: UByteArray = ubyteArrayOf()) : UByteArray fun decrypt(data: UByteArray, additionalData: UByteArray = ubyteArrayOf()) : UByteArray
fun cleanup()
} }

View File

@ -40,6 +40,9 @@ class EncryptionTest {
assertTrue { assertTrue {
plaintext.contentEquals(combinedPlaintext) plaintext.contentEquals(combinedPlaintext)
} }
encryptor.cleanup()
decryptor.cleanup()

View File

@ -52,5 +52,9 @@ interface JsSodiumInterface {
fun crypto_secretstream_xchacha20poly1305_init_pull(header: Uint8Array, key: Uint8Array) : dynamic fun crypto_secretstream_xchacha20poly1305_init_pull(header: Uint8Array, key: Uint8Array) : dynamic
fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, additionalData: Uint8Array) : dynamic fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, additionalData: Uint8Array) : dynamic
//util
fun memzero(array: Uint8Array)
} }

View File

@ -121,6 +121,10 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() {
return decrypted.toUByteArray() return decrypted.toUByteArray()
} }
actual fun cleanup() {
//TODO JS cleanup
}
} }

View File

@ -131,6 +131,11 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() {
} }
actual fun cleanup() {
sodium.sodium_memzero(state.k, 32)
sodium.sodium_memzero(state.nonce, 12)
}

View File

@ -4,7 +4,6 @@ import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint
import com.ionspin.kotlin.crypto.InvalidTagException import com.ionspin.kotlin.crypto.InvalidTagException
import kotlinx.cinterop.* import kotlinx.cinterop.*
import libsodium.* import libsodium.*
import platform.posix.malloc
/** /**
* Created by Ugljesa Jovanovic * Created by Ugljesa Jovanovic
@ -63,10 +62,9 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() {
} }
var state = var state =
malloc(crypto_secretstream_xchacha20poly1305_state.size.convert())!! sodium_malloc(crypto_secretstream_xchacha20poly1305_state.size.convert())!!
.reinterpret<crypto_secretstream_xchacha20poly1305_state>() .reinterpret<crypto_secretstream_xchacha20poly1305_state>()
.pointed .pointed
val header = UByteArray(crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt()) { 0U } val header = UByteArray(crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt()) { 0U }
var isInitialized = false var isInitialized = false
@ -155,6 +153,10 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() {
return plaintext return plaintext
} }
actual fun cleanup() {
sodium_free(state.ptr)
}

View File

@ -18,7 +18,7 @@ actual class Sha256Delegated : Sha256 {
val state : crypto_hash_sha256_state val state : crypto_hash_sha256_state
init { init {
val allocated = malloc(crypto_hash_sha256_state.size.convert())!! val allocated = sodium_malloc(crypto_hash_sha256_state.size.convert())!!
state = allocated.reinterpret<crypto_hash_sha256_state>().pointed state = allocated.reinterpret<crypto_hash_sha256_state>().pointed
crypto_hash_sha256_init(state.ptr) crypto_hash_sha256_init(state.ptr)
} }
@ -33,7 +33,7 @@ actual class Sha256Delegated : Sha256 {
val hashResult = UByteArray(Sha256Properties.MAX_HASH_BYTES) val hashResult = UByteArray(Sha256Properties.MAX_HASH_BYTES)
val hashResultPinned = hashResult.pin() val hashResultPinned = hashResult.pin()
crypto_hash_sha256_final(state.ptr, hashResultPinned.addressOf(0)) crypto_hash_sha256_final(state.ptr, hashResultPinned.addressOf(0))
free(state.ptr) sodium_free(state.ptr)
return hashResult return hashResult
} }

View File

@ -137,6 +137,10 @@ class MultipartAuthenticatedEncryptor internal constructor(val key : SymmetricKe
override fun startEncryption(): MultipartEncryptionHeader { override fun startEncryption(): MultipartEncryptionHeader {
return header return header
} }
override fun cleanup() {
primitive.cleanup()
}
} }
class MultipartAuthenticatedDecryptor internal constructor(val decryptor: XChaCha20Poly1305Pure) : MultipartAuthenticatedDecryption { class MultipartAuthenticatedDecryptor internal constructor(val decryptor: XChaCha20Poly1305Pure) : MultipartAuthenticatedDecryption {
@ -144,4 +148,8 @@ class MultipartAuthenticatedDecryptor internal constructor(val decryptor: XChaCh
return DecryptedDataPart(decryptor.streamDecrypt(data.data, additionalData, 0U)) return DecryptedDataPart(decryptor.streamDecrypt(data.data, additionalData, 0U))
} }
override fun cleanup() {
decryptor.cleanup()
}
} }

View File

@ -84,6 +84,8 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) {
calcNonce[1] = 0U calcNonce[1] = 0U
calcNonce[2] = 0U calcNonce[2] = 0U
calcNonce[3] = 0U calcNonce[3] = 0U
key.overwriteWithZeroes()
nonce.overwriteWithZeroes()
println("Calckey-------=") println("Calckey-------=")
calcKey.hexColumsPrint() calcKey.hexColumsPrint()
println("Calckey-------=") println("Calckey-------=")
@ -184,6 +186,13 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) {
return plaintext return plaintext
} }
fun cleanup() {
key.overwriteWithZeroes()
nonce.overwriteWithZeroes()
calcKey.overwriteWithZeroes()
calcNonce.overwriteWithZeroes()
}
private fun processPolyBytes(updateableMacPrimitive: Poly1305, data: UByteArray) { private fun processPolyBytes(updateableMacPrimitive: Poly1305, data: UByteArray) {