Fix for #42, add check for values returned by libsodium that signal failure, reintroduce xChaCha20 stream API since iosArm32 is not supported any more, use forked resource loader that deletes tmp folders properly

This commit is contained in:
Ugljesa Jovanovic 2024-04-06 11:46:28 +02:00
parent bd988cc493
commit 59c5f958ca
No known key found for this signature in database
GPG Key ID: 5884AC34A0EC67DB
43 changed files with 388 additions and 339 deletions

View File

@ -27,7 +27,9 @@ object Versions {
val ktor = "1.3.2"
val timber = "4.7.1"
val kodeinVersion = "7.1.0"
val resourceLoader = "2.0.2"
// Fork that deletes temporary folders resource loader creates
// https://github.com/ionspin/resource-loader/tree/delete-temp-folder
val resourceLoader = "2.0.3-SNAPSHOT"

View File

@ -45,6 +45,7 @@ val sonatypeUsernameEnv: String? = System.getenv()["SONATYPE_USERNAME"]
repositories {
mavenCentral()
mavenLocal()
maven {
url = uri("https://oss.sonatype.org/content/repositories/snapshots")
}

View File

@ -0,0 +1,11 @@
package com.ionspin.kotlin.crypto
class GeneralLibsodiumException : RuntimeException("Libsodium reported error! Returned value was -1") {
companion object {
fun Int.ensureLibsodiumSuccess() {
if (this == -1) {
throw GeneralLibsodiumException()
}
}
}
}

View File

@ -15,9 +15,6 @@ expect class Sha512State
expect object Hash {
//Not present in LazySodium
//fun hash(data: UByteArray) : UByteArray
fun sha256(data: UByteArray) : UByteArray
fun sha256Init() : Sha256State
fun sha256Update(state: Sha256State, data : UByteArray)

View File

@ -23,8 +23,8 @@ expect object Stream {
fun chacha20IetfXor(message : UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray
fun chacha20IetfXorIc(message: UByteArray, nonce: UByteArray, initialCounter: UInt, key: UByteArray) : UByteArray
// fun xChacha20Keygen() : UByteArray
//
// fun xChacha20Xor(message : UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray
// fun xChacha20XorIc(message : UByteArray, nonce: UByteArray, initialCounter: ULong, key: UByteArray) : UByteArray
fun xChacha20Keygen() : UByteArray
fun xChacha20Xor(message : UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray
fun xChacha20XorIc(message : UByteArray, nonce: UByteArray, initialCounter: ULong, key: UByteArray) : UByteArray
}

View File

@ -67,25 +67,25 @@ class StreamTest {
}
}
// @Test
// fun testXChaCha20IetfStream() = runTest {
// LibsodiumInitializer.initializeWithCallback {
// val message = "This is a cha cha message".encodeToUByteArray()
// val nonce = LibsodiumRandom.bufDeterministic(crypto_stream_xchacha20_NONCEBYTES, seed)
// val key = Stream.xChacha20Keygen()
// val encryptedUsingLibsodium = Stream.xChacha20Xor(message, nonce, key)
// val encryptedUsingLibsodiumWithInitialCounter = Stream.xChacha20XorIc(message, nonce, 0U, key)
// println(encryptedUsingLibsodium.toHexString())
// println(encryptedUsingLibsodiumWithInitialCounter.toHexString())
// assertTrue {
// encryptedUsingLibsodium.contentEquals(encryptedUsingLibsodiumWithInitialCounter)
// }
// val decryptedUsingLibsodium = Stream.xChacha20Xor(encryptedUsingLibsodium, nonce, key)
// println(message.toHexString())
// println(decryptedUsingLibsodium.toHexString())
// assertTrue {
// decryptedUsingLibsodium.contentEquals(message)
// }
// }
// }
@Test
fun testXChaCha20IetfStream() = runTest {
LibsodiumInitializer.initializeWithCallback {
val message = "This is a cha cha message".encodeToUByteArray()
val nonce = LibsodiumRandom.bufDeterministic(crypto_stream_xchacha20_NONCEBYTES, seed)
val key = Stream.xChacha20Keygen()
val encryptedUsingLibsodium = Stream.xChacha20Xor(message, nonce, key)
val encryptedUsingLibsodiumWithInitialCounter = Stream.xChacha20XorIc(message, nonce, 0U, key)
println(encryptedUsingLibsodium.toHexString())
println(encryptedUsingLibsodiumWithInitialCounter.toHexString())
assertTrue {
encryptedUsingLibsodium.contentEquals(encryptedUsingLibsodiumWithInitialCounter)
}
val decryptedUsingLibsodium = Stream.xChacha20Xor(encryptedUsingLibsodium, nonce, key)
println(message.toHexString())
println(decryptedUsingLibsodium.toHexString())
assertTrue {
decryptedUsingLibsodium.contentEquals(message)
}
}
}
}

View File

@ -1,7 +1,13 @@
package ext.libsodium.com.ionspin.kotlin.crypto
import com.ionspin.kotlin.crypto.*
import ext.libsodium.*
import com.ionspin.kotlin.crypto.getSodiumLoaded
import com.ionspin.kotlin.crypto.sodiumLoaded
import ext.libsodium._libsodiumPromise
import ext.libsodium.crypto_generichash
import ext.libsodium.crypto_hash_sha256
import ext.libsodium.crypto_hash_sha256_init
import ext.libsodium.crypto_hash_sha512
import ext.libsodium.sodium_init
import kotlin.coroutines.suspendCoroutine
/**

View File

@ -9,8 +9,6 @@ actual typealias Sha512State = Any
actual object Hash {
//Not present in LazySodium
//fun hash(data: UByteArray) : UByteArray
actual fun sha256(data: UByteArray): UByteArray {
return getSodium().crypto_hash_sha256(data.toUInt8Array()).toUByteArray()
}

View File

@ -82,41 +82,41 @@ actual object Stream {
return result.toUByteArray()
}
// actual fun xChacha20Keygen(): UByteArray {
// val result = getSodium().crypto_stream_xchacha20_keygen()
//
// return result.toUByteArray()
// }
//
// actual fun xChacha20Xor(
// message: UByteArray,
// nonce: UByteArray,
// key: UByteArray
// ): UByteArray {
// val result = getSodium().crypto_stream_xchacha20_xor(
// message.toUInt8Array(),
// nonce.toUInt8Array(),
// key.toUInt8Array()
// )
//
// return result.toUByteArray()
// }
//
// actual fun xChacha20XorIc(
// message: UByteArray,
// nonce: UByteArray,
// initialCounter: ULong,
// key: UByteArray
// ): UByteArray {
// val result = getSodium().crypto_stream_xchacha20_xor_ic(
// message.toUInt8Array(),
// nonce.toUInt8Array(),
// initialCounter.toUInt(),
// key.toUInt8Array()
// )
//
// return result.toUByteArray()
// }
actual fun xChacha20Keygen(): UByteArray {
val result = getSodium().crypto_stream_xchacha20_keygen()
return result.toUByteArray()
}
actual fun xChacha20Xor(
message: UByteArray,
nonce: UByteArray,
key: UByteArray
): UByteArray {
val result = getSodium().crypto_stream_xchacha20_xor(
message.toUInt8Array(),
nonce.toUInt8Array(),
key.toUInt8Array()
)
return result.toUByteArray()
}
actual fun xChacha20XorIc(
message: UByteArray,
nonce: UByteArray,
initialCounter: ULong,
key: UByteArray
): UByteArray {
val result = getSodium().crypto_stream_xchacha20_xor_ic(
message.toUInt8Array(),
nonce.toUInt8Array(),
initialCounter.toUInt(),
key.toUInt8Array()
)
return result.toUByteArray()
}
}

View File

@ -82,6 +82,8 @@ interface JnaLibsodiumInterface : Library {
// ---- Utils ----
fun sodium_version_string(): String
// void
// randombytes_buf(void * const buf, const size_t size)
fun randombytes_buf(buffer: ByteArray, bufferSize: Int)
// void randombytes_buf_deterministic(void * const buf, const size_t size,
@ -147,7 +149,7 @@ interface JnaLibsodiumInterface : Library {
buffer: ByteArray,
paddedBufferLength: Int,
blockSize: Int
)
) : Int
// char *sodium_bin2base64(char * const b64, const size_t b64_maxlen,
@ -431,7 +433,7 @@ interface JnaLibsodiumInterface : Library {
nsec: ByteArray?,
npub: ByteArray,
key: ByteArray
)
) : Int
// int crypto_aead_chacha20poly1305_ietf_decrypt(
// unsigned char *m,
@ -809,7 +811,7 @@ interface JnaLibsodiumInterface : Library {
// // ---- Box ----
//
// int crypto_box_keypair(unsigned char *pk, unsigned char *sk)
fun crypto_box_keypair(publicKey: ByteArray, secretKey: ByteArray)
fun crypto_box_keypair(publicKey: ByteArray, secretKey: ByteArray): Int
// int crypto_box_seed_keypair(unsigned char *pk, unsigned char *sk,
// const unsigned char *seed)
@ -1037,7 +1039,7 @@ interface JnaLibsodiumInterface : Library {
// int crypto_sign_keypair(unsigned char *pk, unsigned char *sk)
fun crypto_sign_keypair(
publicKey: ByteArray, secretKey: ByteArray
)
): Int
// int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk,
// const unsigned char *seed)
@ -1066,7 +1068,7 @@ interface JnaLibsodiumInterface : Library {
subkeyId: Long,
context: ByteArray,
key: ByteArray
)
): Int
// void crypto_kdf_keygen(unsigned char k[crypto_kdf_KEYBYTES])
fun crypto_kdf_keygen(
@ -1135,7 +1137,7 @@ interface JnaLibsodiumInterface : Library {
fun crypto_kx_keypair(
publicKey: ByteArray,
secretKey: ByteArray
)
): Int
// int crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
@ -1145,7 +1147,7 @@ interface JnaLibsodiumInterface : Library {
publicKey: ByteArray,
secretKey: ByteArray,
seed: ByteArray
)
): Int
// int crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
// unsigned char tx[crypto_kx_SESSIONKEYBYTES],
// const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES],
@ -1157,7 +1159,7 @@ interface JnaLibsodiumInterface : Library {
clientPublicKey: ByteArray,
clientSecretKey: ByteArray,
serverPublicKey: ByteArray
)
): Int
// int crypto_kx_server_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
// unsigned char tx[crypto_kx_SESSIONKEYBYTES],
// const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES],
@ -1169,7 +1171,7 @@ interface JnaLibsodiumInterface : Library {
serverPublicKey: ByteArray,
serverSecretKey: ByteArray,
clientPublicKey: ByteArray
)
): Int
//
// // ---- Key exchange end ----
@ -1286,9 +1288,9 @@ interface JnaLibsodiumInterface : Library {
//
// int crypto_scalarmult(unsigned char *q, const unsigned char *n,
// const unsigned char *p)
fun crypto_scalarmult(q: ByteArray, n: ByteArray, p: ByteArray)
fun crypto_scalarmult(q: ByteArray, n: ByteArray, p: ByteArray): Int
// int crypto_scalarmult_base(unsigned char *q, const unsigned char *n)
fun crypto_scalarmult_base(q: ByteArray, b: ByteArray)
fun crypto_scalarmult_base(q: ByteArray, b: ByteArray): Int
//
// // ---- Scalar multiplication end ----
}

View File

@ -1,6 +1,7 @@
package com.ionspin.kotlin.crypto
import com.goterl.resourceloader.SharedLibraryLoader
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.sun.jna.Native
import com.sun.jna.Platform
import java.io.File
@ -49,13 +50,13 @@ actual object LibsodiumInitializer {
lateinit var sodiumJna : JnaLibsodiumInterface
actual suspend fun initialize() {
sodiumJna = loadLibrary()
sodiumJna.sodium_init()
sodiumJna.sodium_init().ensureLibsodiumSuccess()
isPlatformInitialized = true
}
actual fun initializeWithCallback(done: () -> Unit) {
sodiumJna = loadLibrary()
sodiumJna.sodium_init()
sodiumJna.sodium_init().ensureLibsodiumSuccess()
isPlatformInitialized = true
done()
}

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.aead
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
actual object AuthenticatedEncryptionWithAssociatedData {
@ -24,7 +25,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
null,
nonce.asByteArray(),
key.asByteArray(),
)
).ensureLibsodiumSuccess()
return ciphertext
}
@ -71,7 +72,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
null,
nonce.asByteArray(),
key.asByteArray(),
)
).ensureLibsodiumSuccess()
return AeadEncryptedDataAndTag(ciphertext, authenticationTag)
}
@ -117,7 +118,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
null,
nonce.asByteArray(),
key.asByteArray(),
)
).ensureLibsodiumSuccess()
return ciphertext
}
@ -164,7 +165,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
null,
nonce.asByteArray(),
key.asByteArray(),
)
).ensureLibsodiumSuccess()
return AeadEncryptedDataAndTag(ciphertext, authenticationTag)
}
@ -210,7 +211,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
null,
nonce.asByteArray(),
key.asByteArray(),
)
).ensureLibsodiumSuccess()
return ciphertext
}
@ -257,7 +258,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
null,
nonce.asByteArray(),
key.asByteArray(),
)
).ensureLibsodiumSuccess()
return AeadEncryptedDataAndTag(ciphertext, authenticationTag)
}

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.auth
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
actual object Auth {
@ -16,7 +17,7 @@ actual object Auth {
message.asByteArray(),
message.size.toLong(),
key.asByteArray()
)
).ensureLibsodiumSuccess()
return mac
}
@ -42,7 +43,7 @@ actual object Auth {
message.asByteArray(),
message.size.toLong(),
key.asByteArray()
)
).ensureLibsodiumSuccess()
return mac
}
@ -72,7 +73,7 @@ actual object Auth {
message.asByteArray(),
message.size.toLong(),
key.asByteArray()
)
).ensureLibsodiumSuccess()
return mac
}

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.box
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
actual object Box {
@ -11,7 +12,7 @@ actual object Box {
actual fun keypair(): BoxKeyPair {
val publicKey = UByteArray(crypto_box_PUBLICKEYBYTES)
val secretKey = UByteArray(crypto_box_SECRETKEYBYTES)
sodiumJna.crypto_box_keypair(publicKey.asByteArray(), secretKey.asByteArray())
sodiumJna.crypto_box_keypair(publicKey.asByteArray(), secretKey.asByteArray()).ensureLibsodiumSuccess()
return BoxKeyPair(publicKey, secretKey)
}
@ -21,7 +22,7 @@ actual object Box {
actual fun seedKeypair(seed: UByteArray): BoxKeyPair {
val publicKey = UByteArray(crypto_box_PUBLICKEYBYTES)
val secretKey = UByteArray(crypto_box_SECRETKEYBYTES)
sodiumJna.crypto_box_seed_keypair(publicKey.asByteArray(), secretKey.asByteArray(), seed.asByteArray())
sodiumJna.crypto_box_seed_keypair(publicKey.asByteArray(), secretKey.asByteArray(), seed.asByteArray()).ensureLibsodiumSuccess()
return BoxKeyPair(publicKey, secretKey)
}
@ -46,7 +47,7 @@ actual object Box {
nonce.asByteArray(),
recipientsPublicKey.asByteArray(),
sendersSecretKey.asByteArray()
)
).ensureLibsodiumSuccess()
return ciphertext
}
@ -85,7 +86,7 @@ actual object Box {
*/
actual fun beforeNM(publicKey: UByteArray, secretKey: UByteArray): UByteArray {
val sessionKey = UByteArray(crypto_box_BEFORENMBYTES)
sodiumJna.crypto_box_beforenm(sessionKey.asByteArray(), publicKey.asByteArray(), secretKey.asByteArray())
sodiumJna.crypto_box_beforenm(sessionKey.asByteArray(), publicKey.asByteArray(), secretKey.asByteArray()).ensureLibsodiumSuccess()
return sessionKey
}
@ -105,7 +106,7 @@ actual object Box {
message.size.toLong(),
nonce.asByteArray(),
precomputedKey.asByteArray()
)
).ensureLibsodiumSuccess()
return ciphertext
}
@ -157,7 +158,7 @@ actual object Box {
nonce.asByteArray(),
recipientsPublicKey.asByteArray(),
sendersSecretKey.asByteArray()
)
).ensureLibsodiumSuccess()
return BoxEncryptedDataAndTag(ciphertext, tag)
}
@ -201,7 +202,7 @@ actual object Box {
message.asByteArray(),
message.size.toLong(),
recipientsPublicKey.asByteArray()
)
).ensureLibsodiumSuccess()
return ciphertextWithPublicKey
}

View File

@ -1,6 +1,7 @@
package com.ionspin.kotlin.crypto.generichash
import com.ionspin.kotlin.crypto.Blake2bState
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
/**
@ -24,7 +25,7 @@ actual object GenericHash {
message.size.toLong(),
key?.asByteArray() ?: ByteArray(0),
(key?.size ?: 0)
)
).ensureLibsodiumSuccess()
return hash
}
@ -33,7 +34,7 @@ actual object GenericHash {
key: UByteArray?
): GenericHashState {
val state = GenericHashStateInternal()
sodiumJna.crypto_generichash_init(state, key?.asByteArray() ?: ByteArray(0), key?.size ?: 0, requestedHashLength)
sodiumJna.crypto_generichash_init(state, key?.asByteArray() ?: ByteArray(0), key?.size ?: 0, requestedHashLength).ensureLibsodiumSuccess()
return GenericHashState(requestedHashLength, state)
}
@ -41,12 +42,12 @@ actual object GenericHash {
state: GenericHashState,
messagePart: UByteArray
) {
sodiumJna.crypto_generichash_update(state.internalState, messagePart.asByteArray(), messagePart.size.toLong())
sodiumJna.crypto_generichash_update(state.internalState, messagePart.asByteArray(), messagePart.size.toLong()).ensureLibsodiumSuccess()
}
actual fun genericHashFinal(state: GenericHashState): UByteArray {
val hashResult = ByteArray(state.hashLength)
sodiumJna.crypto_generichash_final(state.internalState, hashResult, state.hashLength)
sodiumJna.crypto_generichash_final(state.internalState, hashResult, state.hashLength).ensureLibsodiumSuccess()
return hashResult.asUByteArray()
}

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.hash
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.Hash256State
import com.ionspin.kotlin.crypto.Hash512State
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
@ -11,45 +12,45 @@ actual object Hash {
actual fun sha256(data: UByteArray): UByteArray {
val resultHash = UByteArray(crypto_hash_sha256_BYTES)
sodiumJna.crypto_hash_sha256(resultHash.asByteArray(), data.asByteArray(), data.size.toLong())
sodiumJna.crypto_hash_sha256(resultHash.asByteArray(), data.asByteArray(), data.size.toLong()).ensureLibsodiumSuccess()
return resultHash
}
actual fun sha256Init(): Sha256State {
val state = Hash256State()
sodiumJna.crypto_hash_sha256_init(state)
sodiumJna.crypto_hash_sha256_init(state).ensureLibsodiumSuccess()
return state
}
actual fun sha256Update(state: Sha256State, data: UByteArray) {
sodiumJna.crypto_hash_sha256_update(state, data.asByteArray(), data.size.toLong())
sodiumJna.crypto_hash_sha256_update(state, data.asByteArray(), data.size.toLong()).ensureLibsodiumSuccess()
}
actual fun sha256Final(state: Sha256State): UByteArray {
val resultHash = UByteArray(crypto_hash_sha256_BYTES)
sodiumJna.crypto_hash_sha256_final(state, resultHash.asByteArray())
sodiumJna.crypto_hash_sha256_final(state, resultHash.asByteArray()).ensureLibsodiumSuccess()
return resultHash
}
actual fun sha512(data: UByteArray): UByteArray {
val resultHash = UByteArray(crypto_hash_sha512_BYTES)
sodiumJna.crypto_hash_sha512(resultHash.asByteArray(), data.asByteArray(), data.size.toLong())
sodiumJna.crypto_hash_sha512(resultHash.asByteArray(), data.asByteArray(), data.size.toLong()).ensureLibsodiumSuccess()
return resultHash
}
actual fun sha512Init(): Sha512State {
val state = Hash512State()
sodiumJna.crypto_hash_sha512_init(state)
sodiumJna.crypto_hash_sha512_init(state).ensureLibsodiumSuccess()
return state
}
actual fun sha512Update(state: Sha512State, data: UByteArray) {
sodiumJna.crypto_hash_sha512_update(state, data.asByteArray(), data.size.toLong())
sodiumJna.crypto_hash_sha512_update(state, data.asByteArray(), data.size.toLong()).ensureLibsodiumSuccess()
}
actual fun sha512Final(state: Sha512State): UByteArray {
val resultHash = UByteArray(crypto_hash_sha512_BYTES)
sodiumJna.crypto_hash_sha512_final(state, resultHash.asByteArray())
sodiumJna.crypto_hash_sha512_final(state, resultHash.asByteArray()).ensureLibsodiumSuccess()
return resultHash
}

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.kdf
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
actual object Kdf {
@ -32,7 +33,7 @@ actual object Kdf {
subkeyId.toLong(),
contextEncoded,
masterKey.asByteArray()
)
).ensureLibsodiumSuccess()
return subkey
}

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.keyexchange
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
actual object KeyExchange {
@ -13,7 +14,7 @@ actual object KeyExchange {
clientPublicKey.asByteArray(),
clientSecretKey.asByteArray(),
serverPublicKey.asByteArray()
)
).ensureLibsodiumSuccess()
@ -25,7 +26,7 @@ actual object KeyExchange {
val secretKey = UByteArray(crypto_kx_SECRETKEYBYTES)
sodiumJna.crypto_kx_keypair(publicKey.asByteArray(), secretKey.asByteArray())
sodiumJna.crypto_kx_keypair(publicKey.asByteArray(), secretKey.asByteArray()).ensureLibsodiumSuccess()
return KeyExchangeKeyPair(publicKey, secretKey)
@ -35,7 +36,7 @@ actual object KeyExchange {
val publicKey = UByteArray(crypto_kx_PUBLICKEYBYTES)
val secretKey = UByteArray(crypto_kx_SECRETKEYBYTES)
sodiumJna.crypto_kx_seed_keypair(publicKey.asByteArray(), secretKey.asByteArray(), seed.asByteArray())
sodiumJna.crypto_kx_seed_keypair(publicKey.asByteArray(), secretKey.asByteArray(), seed.asByteArray()).ensureLibsodiumSuccess()
return KeyExchangeKeyPair(publicKey, secretKey)
}
@ -50,7 +51,7 @@ actual object KeyExchange {
serverPublicKey.asByteArray(),
serverSecretKey.asByteArray(),
clientPublicKey.asByteArray()
)
).ensureLibsodiumSuccess()
return KeyExchangeSessionKeyPair(receiveKey, sendKey)
}

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.pwhash
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
actual object PasswordHash {
@ -30,7 +31,7 @@ actual object PasswordHash {
opsLimit.toLong(),
memLimit.toLong(),
algorithm
)
).ensureLibsodiumSuccess()
return hashedPassword
}
@ -53,7 +54,7 @@ actual object PasswordHash {
password.length.toLong(),
opslimit.toLong(),
memlimit.toLong()
)
).ensureLibsodiumSuccess()
return output.decodeToString()
}

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.scalarmult
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
actual object ScalarMultiplication {
@ -18,7 +19,7 @@ actual object ScalarMultiplication {
actual fun scalarMultiplication(secretKeyN: UByteArray, publicKeyP: UByteArray): UByteArray {
val result = UByteArray(crypto_scalarmult_BYTES)
sodiumJna.crypto_scalarmult(result.asByteArray(), secretKeyN.asByteArray(), publicKeyP.asByteArray())
sodiumJna.crypto_scalarmult(result.asByteArray(), secretKeyN.asByteArray(), publicKeyP.asByteArray()).ensureLibsodiumSuccess()
return result
@ -35,7 +36,7 @@ actual object ScalarMultiplication {
): UByteArray {
val result = UByteArray(crypto_scalarmult_BYTES)
sodiumJna.crypto_scalarmult_base(result.asByteArray(), secretKeyN.asByteArray())
sodiumJna.crypto_scalarmult_base(result.asByteArray(), secretKeyN.asByteArray()).ensureLibsodiumSuccess()
return result
}

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.secretbox
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
actual object SecretBox {
@ -11,7 +12,7 @@ actual object SecretBox {
message.size.toLong(),
nonce.asByteArray(),
key.asByteArray()
)
).ensureLibsodiumSuccess()
return ciphertext
}
@ -48,7 +49,7 @@ actual object SecretBox {
message.size.toLong(),
nonce.asByteArray(),
key.asByteArray()
)
).ensureLibsodiumSuccess()
return SecretBoxEncryptedDataAndTag(ciphertext, authenticationTag)
}

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.secretstream
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
import com.ionspin.kotlin.crypto.SecretStreamXChaCha20Poly1305State
@ -9,7 +10,7 @@ actual object SecretStream {
actual fun xChaCha20Poly1305InitPush(key: UByteArray): SecretStreamStateAndHeader {
val state = SecretStreamState()
val header = UByteArray(sodiumJna.crypto_secretstream_xchacha20poly1305_headerbytes())
sodiumJna.crypto_secretstream_xchacha20poly1305_init_push(state, header.asByteArray(), key.asByteArray())
sodiumJna.crypto_secretstream_xchacha20poly1305_init_push(state, header.asByteArray(), key.asByteArray()).ensureLibsodiumSuccess()
return SecretStreamStateAndHeader(state, header)
}
@ -29,7 +30,7 @@ actual object SecretStream {
associatedData.asByteArray(),
associatedData.size.toLong(),
tag.toByte()
)
).ensureLibsodiumSuccess()
return ciphertext
}
@ -38,7 +39,7 @@ actual object SecretStream {
header: UByteArray
): SecretStreamStateAndHeader {
val state = SecretStreamState()
sodiumJna.crypto_secretstream_xchacha20poly1305_init_pull(state, header.asByteArray(), key.asByteArray())
sodiumJna.crypto_secretstream_xchacha20poly1305_init_pull(state, header.asByteArray(), key.asByteArray()).ensureLibsodiumSuccess()
return SecretStreamStateAndHeader(state, header)
}

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.shortinputhash
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
import com.sun.jna.NativeLong
@ -13,13 +14,13 @@ import com.sun.jna.NativeLong
actual object ShortHash {
actual fun shortHash(data: UByteArray, key: UByteArray): UByteArray {
val hashResult = UByteArray(crypto_shorthash_BYTES)
sodiumJna.crypto_shorthash(hashResult.asByteArray(), data.asByteArray(), data.size.toLong(), key.asByteArray())
sodiumJna.crypto_shorthash(hashResult.asByteArray(), data.asByteArray(), data.size.toLong(), key.asByteArray()).ensureLibsodiumSuccess()
return hashResult
}
actual fun shortHashKeygen(): UByteArray {
val key = UByteArray(crypto_shorthash_KEYBYTES)
sodiumJna.crypto_shorthash_keygen(key.asByteArray())
sodiumJna.crypto_shorthash_keygen(key.asByteArray()).ensureLibsodiumSuccess()
return key
}

View File

@ -1,6 +1,7 @@
package com.ionspin.kotlin.crypto.signature
import com.ionspin.kotlin.crypto.Ed25519SignatureState
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
actual typealias SignatureState = Ed25519SignatureState
@ -11,7 +12,7 @@ actual object Signature {
}
actual fun update(state: SignatureState, data: UByteArray) {
sodiumJna.crypto_sign_update(state, data.asByteArray(), data.size.toLong())
sodiumJna.crypto_sign_update(state, data.asByteArray(), data.size.toLong()).ensureLibsodiumSuccess()
}
actual fun finalCreate(
@ -24,7 +25,7 @@ actual object Signature {
signature.asByteArray(),
null,
secretKey.asByteArray()
)
).ensureLibsodiumSuccess()
return signature
}
@ -53,7 +54,7 @@ actual object Signature {
sodiumJna.crypto_sign_keypair(
publicKey.asByteArray(),
secretKey.asByteArray(),
)
).ensureLibsodiumSuccess()
return SignatureKeyPair(publicKey, secretKey)
}
@ -71,7 +72,7 @@ actual object Signature {
publicKey.asByteArray(),
secretKey.asByteArray(),
seed.asByteArray()
)
).ensureLibsodiumSuccess()
return SignatureKeyPair(publicKey, secretKey)
}
@ -88,7 +89,7 @@ actual object Signature {
message.asByteArray(),
message.size.toLong(),
secretKey.asByteArray()
)
).ensureLibsodiumSuccess()
return signedMessage
}
@ -127,7 +128,7 @@ actual object Signature {
message.asByteArray(),
message.size.toLong(),
secretKey.asByteArray()
)
).ensureLibsodiumSuccess()
return signature
}
@ -162,7 +163,7 @@ actual object Signature {
sodiumJna.crypto_sign_ed25519_pk_to_curve25519(
x25519PublicKey.asByteArray(),
ed25519PublicKey.asByteArray()
)
).ensureLibsodiumSuccess()
return x25519PublicKey
}
@ -171,7 +172,7 @@ actual object Signature {
sodiumJna.crypto_sign_ed25519_sk_to_curve25519(
x25519SecretKey.asByteArray(),
ed25519SecretKey.asByteArray()
)
).ensureLibsodiumSuccess()
return x25519SecretKey
}
@ -185,7 +186,7 @@ actual object Signature {
sodiumJna.crypto_sign_ed25519_sk_to_seed(
seed.asByteArray(),
secretKey.asByteArray()
)
).ensureLibsodiumSuccess()
return seed
@ -201,7 +202,7 @@ actual object Signature {
sodiumJna.crypto_sign_ed25519_sk_to_pk(
publicKey.asByteArray(),
secretKey.asByteArray()
)
).ensureLibsodiumSuccess()
return publicKey
}

View File

@ -1,12 +1,13 @@
package com.ionspin.kotlin.crypto.stream
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
actual object Stream {
actual fun chacha20(clen: Int, nonce: UByteArray, key: UByteArray): UByteArray {
val result = UByteArray(clen)
sodiumJna.crypto_stream_chacha20(result.asByteArray(), clen.toLong(), nonce.asByteArray(), key.asByteArray())
sodiumJna.crypto_stream_chacha20(result.asByteArray(), clen.toLong(), nonce.asByteArray(), key.asByteArray()).ensureLibsodiumSuccess()
return result
}
@ -24,7 +25,7 @@ actual object Stream {
message.size.toLong(),
nonce.asByteArray(),
key.asByteArray()
)
).ensureLibsodiumSuccess()
return result
}
@ -44,7 +45,7 @@ actual object Stream {
nonce.asByteArray(),
initialCounter.toInt(),
key.asByteArray()
)
).ensureLibsodiumSuccess()
return result
}
@ -70,7 +71,7 @@ actual object Stream {
message.size.toLong(),
nonce.asByteArray(),
key.asByteArray()
)
).ensureLibsodiumSuccess()
return result
}
@ -90,55 +91,55 @@ actual object Stream {
nonce.asByteArray(),
initialCounter.toLong(),
key.asByteArray()
)
).ensureLibsodiumSuccess()
return result
}
// actual fun xChacha20Keygen(): UByteArray {
// val result = UByteArray(crypto_stream_chacha20_KEYBYTES)
//
// sodiumJna.crypto_stream_xchacha20_keygen(result.asByteArray())
//
// return result
// }
//
// actual fun xChacha20Xor(
// message: UByteArray,
// nonce: UByteArray,
// key: UByteArray
// ): UByteArray {
// val result = UByteArray(message.size)
//
// sodiumJna.crypto_stream_xchacha20_xor(
// result.asByteArray(),
// message.asByteArray(),
// message.size.toLong(),
// nonce.asByteArray(),
// key.asByteArray()
// )
//
// return result
// }
//
// actual fun xChacha20XorIc(
// message: UByteArray,
// nonce: UByteArray,
// initialCounter: ULong,
// key: UByteArray
// ): UByteArray {
// val result = UByteArray(message.size)
//
// sodiumJna.crypto_stream_xchacha20_xor_ic(
// result.asByteArray(),
// message.asByteArray(),
// message.size.toLong(),
// nonce.asByteArray(),
// initialCounter.toLong(),
// key.asByteArray()
// )
//
// return result
// }
actual fun xChacha20Keygen(): UByteArray {
val result = UByteArray(crypto_stream_chacha20_KEYBYTES)
sodiumJna.crypto_stream_xchacha20_keygen(result.asByteArray())
return result
}
actual fun xChacha20Xor(
message: UByteArray,
nonce: UByteArray,
key: UByteArray
): UByteArray {
val result = UByteArray(message.size)
sodiumJna.crypto_stream_xchacha20_xor(
result.asByteArray(),
message.asByteArray(),
message.size.toLong(),
nonce.asByteArray(),
key.asByteArray()
).ensureLibsodiumSuccess()
return result
}
actual fun xChacha20XorIc(
message: UByteArray,
nonce: UByteArray,
initialCounter: ULong,
key: UByteArray
): UByteArray {
val result = UByteArray(message.size)
sodiumJna.crypto_stream_xchacha20_xor_ic(
result.asByteArray(),
message.asByteArray(),
message.size.toLong(),
nonce.asByteArray(),
initialCounter.toLong(),
key.asByteArray()
).ensureLibsodiumSuccess()
return result
}
}

View File

@ -1,9 +1,8 @@
package com.ionspin.kotlin.crypto.util
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
import com.sun.jna.ptr.IntByReference
import java.lang.RuntimeException
import java.util.*
actual object LibsodiumUtil {
actual fun memcmp(first: UByteArray, second: UByteArray): Boolean {
@ -53,7 +52,7 @@ actual object LibsodiumUtil {
paddedDataCopy,
paddedData.size,
blocksize
)
).ensureLibsodiumSuccess()
val unpadded = paddedDataCopy.sliceArray(0 until unpaddedSize.value).asUByteArray()
@ -72,7 +71,7 @@ actual object LibsodiumUtil {
data.asByteArray(),
data.size,
variant.value
)
).ensureLibsodiumSuccess()
//Drop terminating char \0
return String(result.sliceArray(0 until result.size - 1))
}

View File

@ -2,6 +2,7 @@
package com.ionspin.kotlin.crypto
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import libsodium.sodium_init
import kotlin.native.concurrent.AtomicInt
@ -11,7 +12,7 @@ actual object LibsodiumInitializer {
actual suspend fun initialize() {
if (isPlatformInitialized.compareAndSet(0, 1)) {
sodium_init()
sodium_init().ensureLibsodiumSuccess()
}
@ -19,7 +20,7 @@ actual object LibsodiumInitializer {
actual fun initializeWithCallback(done: () -> Unit) {
if (isPlatformInitialized.compareAndSet(0, 1)) {
sodium_init()
sodium_init().ensureLibsodiumSuccess()
}
done()
}

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.aead
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.convert
import kotlinx.cinterop.pin
@ -48,8 +49,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
null, // nsec not used in this construct
noncePinned.toPtr(),
keyPinned.toPtr()
)
).ensureLibsodiumSuccess()
ciphertextPinned.unpin()
@ -129,8 +129,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
null, // nsec not used in this construct
noncePinned.toPtr(),
keyPinned.toPtr()
)
).ensureLibsodiumSuccess()
ciphertextPinned.unpin()
@ -209,8 +208,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
null, // nsec not used in this construct
noncePinned.toPtr(),
keyPinned.toPtr()
)
).ensureLibsodiumSuccess()
ciphertextPinned.unpin()
@ -290,8 +288,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
null, // nsec not used in this construct
noncePinned.toPtr(),
keyPinned.toPtr()
)
).ensureLibsodiumSuccess()
ciphertextPinned.unpin()
@ -370,8 +367,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
null, // nsec not used in this construct
noncePinned.toPtr(),
keyPinned.toPtr()
)
).ensureLibsodiumSuccess()
ciphertextPinned.unpin()
@ -451,8 +447,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
null, // nsec not used in this construct
noncePinned.toPtr(),
keyPinned.toPtr()
)
).ensureLibsodiumSuccess()
ciphertextPinned.unpin()

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.auth
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.convert
import kotlinx.cinterop.pin
@ -34,7 +35,7 @@ actual object Auth {
messagePinned.toPtr(),
message.size.convert(),
keyPinned.toPtr()
)
).ensureLibsodiumSuccess()
macPinned.unpin()
messagePinned.unpin()
@ -80,7 +81,7 @@ actual object Auth {
messagePinned.toPtr(),
message.size.convert(),
keyPinned.toPtr()
)
).ensureLibsodiumSuccess()
macPinned.unpin()
messagePinned.unpin()
@ -131,7 +132,7 @@ actual object Auth {
messagePinned.toPtr(),
message.size.convert(),
keyPinned.toPtr()
)
).ensureLibsodiumSuccess()
macPinned.unpin()
messagePinned.unpin()

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.box
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.convert
import kotlinx.cinterop.pin
@ -26,7 +27,7 @@ actual object Box {
val secretKey = UByteArray(crypto_box_SECRETKEYBYTES)
val publicKeyPinned = publicKey.pin()
val secretKeyPinned = secretKey.pin()
crypto_box_keypair(publicKeyPinned.toPtr(), secretKeyPinned.toPtr())
crypto_box_keypair(publicKeyPinned.toPtr(), secretKeyPinned.toPtr()).ensureLibsodiumSuccess()
publicKeyPinned.unpin()
secretKeyPinned.unpin()
return BoxKeyPair(publicKey, secretKey)
@ -41,7 +42,7 @@ actual object Box {
val publicKeyPinned = publicKey.pin()
val secretKeyPinned = secretKey.pin()
val seedPinned = seed.pin()
crypto_box_seed_keypair(publicKeyPinned.toPtr(), secretKeyPinned.toPtr(), seedPinned.toPtr())
crypto_box_seed_keypair(publicKeyPinned.toPtr(), secretKeyPinned.toPtr(), seedPinned.toPtr()).ensureLibsodiumSuccess()
publicKeyPinned.unpin()
secretKeyPinned.unpin()
seedPinned.unpin()
@ -76,7 +77,7 @@ actual object Box {
noncePinned.toPtr(),
recipientsPublicKeyPinned.toPtr(),
sendersSecretKeyPinned.toPtr()
)
).ensureLibsodiumSuccess()
ciphertextPinned.unpin()
messagePinned.unpin()
@ -141,7 +142,7 @@ actual object Box {
val publicKeyPinned = publicKey.pin()
val secretKeyPinned = secretKey.pin()
crypto_box_beforenm(sessionKeyPinned.toPtr(), publicKeyPinned.toPtr(), secretKeyPinned.toPtr())
crypto_box_beforenm(sessionKeyPinned.toPtr(), publicKeyPinned.toPtr(), secretKeyPinned.toPtr()).ensureLibsodiumSuccess()
sessionKeyPinned.unpin()
publicKeyPinned.unpin()
@ -171,7 +172,7 @@ actual object Box {
message.size.convert(),
noncePinned.toPtr(),
precomputedKeyPinned.toPtr()
)
).ensureLibsodiumSuccess()
ciphertextPinned.unpin()
messagePinned.unpin()
@ -249,7 +250,7 @@ actual object Box {
noncePinned.toPtr(),
recipientsPublicKeyPinned.toPtr(),
sendersSecretKeyPinned.toPtr()
)
).ensureLibsodiumSuccess()
ciphertextPinned.unpin()
tagPinned.unpin()
@ -319,7 +320,7 @@ actual object Box {
messagePinned.toPtr(),
message.size.convert(),
recipientsPublicKeyPinned.toPtr()
)
).ensureLibsodiumSuccess()
ciphertextWithPublicKeyPinned.unpin()
messagePinned.unpin()

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.generichash
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.addressOf
import kotlinx.cinterop.convert
@ -40,7 +41,7 @@ actual object GenericHash {
message.size.convert(),
pinnedKey?.toPtr(),
(key?.size ?: 0).convert()
)
).ensureLibsodiumSuccess()
pinnedHash.unpin()
pinnedKey?.unpin()
pinnedMessage.unpin()
@ -59,7 +60,7 @@ actual object GenericHash {
pinnedKey?.toPtr(),
(key?.size ?: 0).convert(),
requestedHashLength.convert()
)
).ensureLibsodiumSuccess()
pinnedKey?.unpin()
return GenericHashState(requestedHashLength, statePointed)
}
@ -73,7 +74,7 @@ actual object GenericHash {
state.internalState.ptr,
pinnedMessage.toPtr(),
messagePart.size.convert()
)
).ensureLibsodiumSuccess()
pinnedMessage.unpin()
}
@ -84,7 +85,7 @@ actual object GenericHash {
state.internalState.ptr,
hashResultPinned.toPtr(),
state.hashLength.convert()
)
).ensureLibsodiumSuccess()
hashResultPinned.unpin()
return hashResult
}

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.hash
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.convert
import kotlinx.cinterop.pin
@ -23,23 +24,12 @@ actual typealias Sha256State = crypto_hash_sha256_state
actual typealias Sha512State = crypto_hash_sha512_state
actual object Hash {
//Not present in Lazy Sodium
// actual fun hash(data: UByteArray): UByteArray {
// val hashResult = UByteArray(crypto_hash_BYTES)
// val hashResultPinned = hashResult.pin()
// val dataPinned = data.pin()
// crypto_hash(hashResultPinned.toPtr(), dataPinned.toPtr(), data.size.convert())
// hashResultPinned.unpin()
// dataPinned.unpin()
//
// return hashResult
// }
actual fun sha256(data: UByteArray): UByteArray {
val hashResult = UByteArray(crypto_hash_sha256_BYTES)
val hashResultPinned = hashResult.pin()
val dataPinned = data.pin()
crypto_hash_sha256(hashResultPinned.toPtr(), dataPinned.toPtr(), data.size.convert())
crypto_hash_sha256(hashResultPinned.toPtr(), dataPinned.toPtr(), data.size.convert()).ensureLibsodiumSuccess()
hashResultPinned.unpin()
dataPinned.unpin()
@ -49,7 +39,7 @@ actual object Hash {
actual fun sha256Init(): Sha256State {
val stateAllocated = malloc(Sha256State.size.convert())
val statePointed = stateAllocated!!.reinterpret<Sha256State>().pointed
crypto_hash_sha256_init(statePointed.ptr)
crypto_hash_sha256_init(statePointed.ptr).ensureLibsodiumSuccess()
return statePointed
}
@ -61,7 +51,7 @@ actual object Hash {
actual fun sha256Final(state: Sha256State): UByteArray {
val hashResult = UByteArray(crypto_hash_sha256_BYTES)
val hashResultPinned = hashResult.pin()
crypto_hash_sha256_final(state.ptr, hashResultPinned.toPtr())
crypto_hash_sha256_final(state.ptr, hashResultPinned.toPtr()).ensureLibsodiumSuccess()
return hashResult
}
@ -69,7 +59,7 @@ actual object Hash {
val hashResult = UByteArray(crypto_hash_sha512_BYTES)
val hashResultPinned = hashResult.pin()
val dataPinned = data.pin()
crypto_hash_sha512(hashResultPinned.toPtr(), dataPinned.toPtr(), data.size.convert())
crypto_hash_sha512(hashResultPinned.toPtr(), dataPinned.toPtr(), data.size.convert()).ensureLibsodiumSuccess()
hashResultPinned.unpin()
dataPinned.unpin()
@ -79,19 +69,19 @@ actual object Hash {
actual fun sha512Init(): Sha512State {
val stateAllocated = malloc(Sha512State.size.convert())
val statePointed = stateAllocated!!.reinterpret<Sha512State>().pointed
crypto_hash_sha512_init(statePointed.ptr)
crypto_hash_sha512_init(statePointed.ptr).ensureLibsodiumSuccess()
return statePointed
}
actual fun sha512Update(state: Sha512State, data: UByteArray) {
val dataPinned = data.pin()
crypto_hash_sha512_update(state.ptr, dataPinned.toPtr(), data.size.convert())
crypto_hash_sha512_update(state.ptr, dataPinned.toPtr(), data.size.convert()).ensureLibsodiumSuccess()
}
actual fun sha512Final(state: Sha512State): UByteArray {
val hashResult = UByteArray(crypto_hash_sha512_BYTES)
val hashResultPinned = hashResult.pin()
crypto_hash_sha512_final(state.ptr, hashResultPinned.toPtr())
crypto_hash_sha512_final(state.ptr, hashResultPinned.toPtr()).ensureLibsodiumSuccess()
return hashResult
}

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.kdf
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.encodeToUByteArray
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.addressOf
@ -41,7 +42,7 @@ actual object Kdf {
subkeyId.convert(),
contextEncodedAndPinned.addressOf(0),
masterKeyPinned.toPtr()
)
).ensureLibsodiumSuccess()
contextEncodedAndPinned.unpin()
masterKeyPinned.unpin()

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.keyexchange
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.pin
import libsodium.crypto_kx_client_session_keys
@ -29,7 +30,7 @@ actual object KeyExchange {
clientPublicKeyPinned.toPtr(),
clientSecretKeyPinned.toPtr(),
serverPublicKeyPinned.toPtr()
)
).ensureLibsodiumSuccess()
clientPublicKeyPinned.unpin()
clientSecretKeyPinned.unpin()
@ -46,7 +47,7 @@ actual object KeyExchange {
val publicKeyPinned = publicKey.pin()
val secretKeyPinned = secretKey.pin()
crypto_kx_keypair(publicKeyPinned.toPtr(), secretKeyPinned.toPtr())
crypto_kx_keypair(publicKeyPinned.toPtr(), secretKeyPinned.toPtr()).ensureLibsodiumSuccess()
publicKeyPinned.unpin()
secretKeyPinned.unpin()
@ -61,7 +62,7 @@ actual object KeyExchange {
val publicKeyPinned = publicKey.pin()
val secretKeyPinned = secretKey.pin()
crypto_kx_seed_keypair(publicKeyPinned.toPtr(), secretKeyPinned.toPtr(), seedPinned.toPtr())
crypto_kx_seed_keypair(publicKeyPinned.toPtr(), secretKeyPinned.toPtr(), seedPinned.toPtr()).ensureLibsodiumSuccess()
publicKeyPinned.unpin()
secretKeyPinned.unpin()
@ -86,7 +87,7 @@ actual object KeyExchange {
serverPublicKeyPinned.toPtr(),
serverSecretKeyPinned.toPtr(),
clientPublicKeyPinned.toPtr()
)
).ensureLibsodiumSuccess()
serverPublicKeyPinned.unpin()
serverSecretKeyPinned.unpin()

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.pwhash
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.addressOf
import kotlinx.cinterop.convert
@ -69,7 +70,7 @@ actual object PasswordHash {
password.length.convert(),
opslimit,
memlimit.convert()
)
).ensureLibsodiumSuccess()
outputPinned.unpin()
return output.decodeToString()

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.scalarmult
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.pin
import libsodium.crypto_scalarmult
@ -25,7 +26,7 @@ actual object ScalarMultiplication {
val secretKeyNPinned = secretKeyN.pin()
val publicKeyPPinned = publicKeyP.pin()
crypto_scalarmult(resultPinned.toPtr(), secretKeyNPinned.toPtr(), publicKeyPPinned.toPtr())
crypto_scalarmult(resultPinned.toPtr(), secretKeyNPinned.toPtr(), publicKeyPPinned.toPtr()).ensureLibsodiumSuccess()
resultPinned.unpin()
secretKeyNPinned.unpin()
@ -47,7 +48,7 @@ actual object ScalarMultiplication {
val resultPinned = result.pin()
val secretKeyNPinned = secretKeyN.pin()
crypto_scalarmult_base(resultPinned.toPtr(), secretKeyNPinned.toPtr())
crypto_scalarmult_base(resultPinned.toPtr(), secretKeyNPinned.toPtr()).ensureLibsodiumSuccess()
resultPinned.unpin()
secretKeyNPinned.unpin()

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.secretbox
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.convert
import kotlinx.cinterop.pin
@ -76,7 +77,7 @@ actual object SecretBox {
message.size.convert(),
noncePinned.toPtr(),
keyPinned.toPtr()
)
).ensureLibsodiumSuccess()
ciphertextPinned.unpin()
authenticationTagPinned.unpin()
messagePinned.unpin()

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.secretstream
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.convert
import kotlinx.cinterop.pin
@ -30,7 +31,7 @@ actual object SecretStream {
statePointed.ptr,
headerPinned.toPtr(),
keyPinned.toPtr()
)
).ensureLibsodiumSuccess()
headerPinned.unpin()
keyPinned.unpin()
return SecretStreamStateAndHeader(statePointed, header)
@ -60,7 +61,7 @@ actual object SecretStream {
associatedDataPinned?.toPtr(),
associatedData.size.convert(),
tag
)
).ensureLibsodiumSuccess()
ciphertextPinned.unpin()
messagePinned.unpin()
@ -80,7 +81,7 @@ actual object SecretStream {
statePointed.ptr,
headerPinned.toPtr(),
keyPinned.toPtr()
)
).ensureLibsodiumSuccess()
headerPinned.unpin()
keyPinned.unpin()
return SecretStreamStateAndHeader(statePointed, header)

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.shortinputhash
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.convert
import kotlinx.cinterop.pin
@ -17,7 +18,7 @@ actual object ShortHash {
val hashResultPinned = hashResult.pin()
val dataPinned = data.pin()
val keyPinned = key.pin()
crypto_shorthash(hashResultPinned.toPtr(), dataPinned.toPtr(), data.size.convert(), keyPinned.toPtr())
crypto_shorthash(hashResultPinned.toPtr(), dataPinned.toPtr(), data.size.convert(), keyPinned.toPtr()).ensureLibsodiumSuccess()
hashResultPinned.unpin()
dataPinned.unpin()
keyPinned.unpin()

View File

@ -1,8 +1,27 @@
package com.ionspin.kotlin.crypto.signature
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.*
import libsodium.*
import kotlinx.cinterop.convert
import kotlinx.cinterop.pin
import kotlinx.cinterop.pointed
import kotlinx.cinterop.ptr
import kotlinx.cinterop.reinterpret
import libsodium.crypto_sign
import libsodium.crypto_sign_detached
import libsodium.crypto_sign_ed25519_pk_to_curve25519
import libsodium.crypto_sign_ed25519_sk_to_curve25519
import libsodium.crypto_sign_ed25519_sk_to_pk
import libsodium.crypto_sign_ed25519_sk_to_seed
import libsodium.crypto_sign_ed25519ph_state
import libsodium.crypto_sign_final_create
import libsodium.crypto_sign_final_verify
import libsodium.crypto_sign_init
import libsodium.crypto_sign_keypair
import libsodium.crypto_sign_open
import libsodium.crypto_sign_seed_keypair
import libsodium.crypto_sign_update
import libsodium.crypto_sign_verify_detached
import platform.posix.malloc
actual typealias SignatureState = crypto_sign_ed25519ph_state
@ -11,13 +30,13 @@ actual object Signature {
actual fun init(): SignatureState {
val stateAllocated = malloc(SignatureState.size.convert())
val statePointed = stateAllocated!!.reinterpret<SignatureState>().pointed
crypto_sign_init(statePointed.ptr)
crypto_sign_init(statePointed.ptr).ensureLibsodiumSuccess()
return statePointed
}
actual fun update(state: SignatureState, data: UByteArray) {
val dataPinned = data.pin()
crypto_sign_update(state.ptr, dataPinned.toPtr(), data.size.convert())
crypto_sign_update(state.ptr, dataPinned.toPtr(), data.size.convert()).ensureLibsodiumSuccess()
dataPinned.unpin()
}
@ -33,7 +52,7 @@ actual object Signature {
signaturePinned.toPtr(),
null,
secretKeyPinned.toPtr()
)
).ensureLibsodiumSuccess()
secretKeyPinned.unpin()
signaturePinned.unpin()
return signature
@ -72,7 +91,7 @@ actual object Signature {
crypto_sign_keypair(
publicKeyPinned.toPtr(),
secretKeyPinned.toPtr(),
)
).ensureLibsodiumSuccess()
publicKeyPinned.unpin()
secretKeyPinned.unpin()
return SignatureKeyPair(publicKey, secretKey)
@ -93,7 +112,7 @@ actual object Signature {
publicKeyPinned.toPtr(),
secretKeyPinned.toPtr(),
seedPinned.toPtr()
)
).ensureLibsodiumSuccess()
seedPinned.unpin()
publicKeyPinned.unpin()
secretKeyPinned.unpin()
@ -115,7 +134,7 @@ actual object Signature {
messagePinned.toPtr(),
message.size.convert(),
secretKeyPinned.toPtr()
)
).ensureLibsodiumSuccess()
signedMessagePinned.unpin()
messagePinned.unpin()
secretKeyPinned.unpin()
@ -165,7 +184,7 @@ actual object Signature {
messagePinned.toPtr(),
message.size.convert(),
secretKeyPinned.toPtr()
)
).ensureLibsodiumSuccess()
signaturePinned.unpin()
messagePinned.unpin()
secretKeyPinned.unpin()
@ -210,7 +229,7 @@ actual object Signature {
crypto_sign_ed25519_pk_to_curve25519(
x25519PublicKeyPinned.toPtr(),
ed25519PublicKeyPinned.toPtr()
)
).ensureLibsodiumSuccess()
x25519PublicKeyPinned.unpin()
ed25519PublicKeyPinned.unpin()
return x25519PublicKey
@ -223,7 +242,7 @@ actual object Signature {
crypto_sign_ed25519_sk_to_curve25519(
x25519SecretKeyPinned.toPtr(),
ed25519SecretKeyPinned.toPtr()
)
).ensureLibsodiumSuccess()
x25519SecretKeyPinned.unpin()
ed25519SecretKeyPinned.unpin()
return x25519SecretKey
@ -242,7 +261,7 @@ actual object Signature {
crypto_sign_ed25519_sk_to_seed(
seedPinned.toPtr(),
secretKeyPinned.toPtr()
)
).ensureLibsodiumSuccess()
secretKeyPinned.unpin()
seedPinned.unpin()
@ -264,7 +283,7 @@ actual object Signature {
crypto_sign_ed25519_sk_to_pk(
publicKeyPinned.toPtr(),
secretKeyPinned.toPtr()
)
).ensureLibsodiumSuccess()
secretKeyPinned.unpin()
publicKeyPinned.unpin()

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.stream
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.convert
import kotlinx.cinterop.pin
@ -10,9 +11,9 @@ import libsodium.crypto_stream_chacha20_keygen
import libsodium.crypto_stream_chacha20_xor
import libsodium.crypto_stream_chacha20_xor_ic
//import libsodium.crypto_stream_xchacha20_keygen
//import libsodium.crypto_stream_xchacha20_xor
//import libsodium.crypto_stream_xchacha20_xor_ic
import libsodium.crypto_stream_xchacha20_keygen
import libsodium.crypto_stream_xchacha20_xor
import libsodium.crypto_stream_xchacha20_xor_ic
actual object Stream {
actual fun chacha20(clen: Int, nonce: UByteArray, key: UByteArray): UByteArray {
@ -21,7 +22,7 @@ actual object Stream {
val noncePinned = nonce.pin()
val keyPinned = key.pin()
crypto_stream_chacha20(resultPinned.toPtr(), clen.convert(), noncePinned.toPtr(), keyPinned.toPtr())
crypto_stream_chacha20(resultPinned.toPtr(), clen.convert(), noncePinned.toPtr(), keyPinned.toPtr()).ensureLibsodiumSuccess()
resultPinned.unpin()
noncePinned.unpin()
@ -47,7 +48,7 @@ actual object Stream {
message.size.convert(),
noncePinned.toPtr(),
keyPinned.toPtr()
)
).ensureLibsodiumSuccess()
messagePinned.unpin()
resultPinned.unpin()
@ -76,7 +77,7 @@ actual object Stream {
noncePinned.toPtr(),
initialCounter.convert(),
keyPinned.toPtr()
)
).ensureLibsodiumSuccess()
messagePinned.unpin()
resultPinned.unpin()
@ -114,7 +115,7 @@ actual object Stream {
message.size.convert(),
noncePinned.toPtr(),
keyPinned.toPtr()
)
).ensureLibsodiumSuccess()
messagePinned.unpin()
resultPinned.unpin()
@ -143,7 +144,7 @@ actual object Stream {
noncePinned.toPtr(),
initialCounter.convert(),
keyPinned.toPtr()
)
).ensureLibsodiumSuccess()
messagePinned.unpin()
resultPinned.unpin()
@ -153,70 +154,70 @@ actual object Stream {
return result
}
// actual fun xChacha20Keygen(): UByteArray {
// val result = UByteArray(crypto_stream_xchacha20_KEYBYTES)
// val resultPinned = result.pin()
//
// crypto_stream_xchacha20_keygen(resultPinned.toPtr())
//
// resultPinned.unpin()
//
// return result
// }
//
// actual fun xChacha20Xor(
// message: UByteArray,
// nonce: UByteArray,
// key: UByteArray
// ): UByteArray {
// val result = UByteArray(message.size)
// val messagePinned = message.pin()
// val resultPinned = result.pin()
// val noncePinned = nonce.pin()
// val keyPinned = key.pin()
//
// crypto_stream_xchacha20_xor(
// resultPinned.toPtr(),
// messagePinned.toPtr(),
// message.size.convert(),
// noncePinned.toPtr(),
// keyPinned.toPtr()
// )
//
// messagePinned.unpin()
// resultPinned.unpin()
// noncePinned.unpin()
// keyPinned.unpin()
//
// return result
// }
//
// actual fun xChacha20XorIc(
// message: UByteArray,
// nonce: UByteArray,
// initialCounter: ULong,
// key: UByteArray
// ): UByteArray {
// val result = UByteArray(message.size)
// val messagePinned = message.pin()
// val resultPinned = result.pin()
// val noncePinned = nonce.pin()
// val keyPinned = key.pin()
//
// crypto_stream_xchacha20_xor_ic(
// resultPinned.toPtr(),
// messagePinned.toPtr(),
// message.size.convert(),
// noncePinned.toPtr(),
// initialCounter.convert(),
// keyPinned.toPtr()
// )
//
// messagePinned.unpin()
// resultPinned.unpin()
// noncePinned.unpin()
// keyPinned.unpin()
//
// return result
// }
actual fun xChacha20Keygen(): UByteArray {
val result = UByteArray(crypto_stream_xchacha20_KEYBYTES)
val resultPinned = result.pin()
crypto_stream_xchacha20_keygen(resultPinned.toPtr())
resultPinned.unpin()
return result
}
actual fun xChacha20Xor(
message: UByteArray,
nonce: UByteArray,
key: UByteArray
): UByteArray {
val result = UByteArray(message.size)
val messagePinned = message.pin()
val resultPinned = result.pin()
val noncePinned = nonce.pin()
val keyPinned = key.pin()
crypto_stream_xchacha20_xor(
resultPinned.toPtr(),
messagePinned.toPtr(),
message.size.convert(),
noncePinned.toPtr(),
keyPinned.toPtr()
).ensureLibsodiumSuccess()
messagePinned.unpin()
resultPinned.unpin()
noncePinned.unpin()
keyPinned.unpin()
return result
}
actual fun xChacha20XorIc(
message: UByteArray,
nonce: UByteArray,
initialCounter: ULong,
key: UByteArray
): UByteArray {
val result = UByteArray(message.size)
val messagePinned = message.pin()
val resultPinned = result.pin()
val noncePinned = nonce.pin()
val keyPinned = key.pin()
crypto_stream_xchacha20_xor_ic(
resultPinned.toPtr(),
messagePinned.toPtr(),
message.size.convert(),
noncePinned.toPtr(),
initialCounter.convert(),
keyPinned.toPtr()
).ensureLibsodiumSuccess()
messagePinned.unpin()
resultPinned.unpin()
noncePinned.unpin()
keyPinned.unpin()
return result
}
}

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.util
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import kotlinx.cinterop.addressOf
import kotlinx.cinterop.convert
import kotlinx.cinterop.pin
@ -53,7 +54,7 @@ actual object LibsodiumUtil {
unpaddedData.size.convert(),
blocksize.convert(),
resultingSize.convert()
)
).ensureLibsodiumSuccess()
paddedDataPinned.unpin()
return paddedData
}
@ -68,7 +69,7 @@ actual object LibsodiumUtil {
paddedDataCopyPinned.toPtr(),
paddedData.size.convert(),
blocksize.convert()
)
).ensureLibsodiumSuccess()
val unpaddedSize = newSizeULong[0]
if (unpaddedSize > Int.MAX_VALUE.toULong()) {
throw RuntimeException("Unsupported array size (larger than Integer max value) $unpaddedSize")
@ -131,7 +132,7 @@ actual object LibsodiumUtil {
null,
variant.value
)
).ensureLibsodiumSuccess()
binLenPinned.unpin()
intermediaryResultPinned.unpin()
@ -154,7 +155,7 @@ actual object LibsodiumUtil {
null,
null,
null
)
).ensureLibsodiumSuccess()
resultPinned.unpin()
return result
}

View File

@ -38,6 +38,7 @@ val sonatypeSnapshots = "https://oss.sonatype.org/content/repositories/snapshots
repositories {
mavenCentral()
mavenLocal()
maven("https://oss.sonatype.org/content/repositories/snapshots/")
}