diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt index d783e82..eefbc4d 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt @@ -16,9 +16,8 @@ object NativeLibsodiumGenerator { fileBuilder.addImport("kotlinx.cinterop", "toCValues") fileBuilder.addImport("kotlinx.cinterop", "convert") fileBuilder.addImport("kotlinx.cinterop", "ptr") -// val sodiumProperty = PropertySpec.builder("sodium", ClassName.bestGuess("com.goterl.lazycode.lazysodium.SodiumJava")) -// sodiumProperty.initializer(CodeBlock.of("SodiumJava()")) -// fileBuilder.addProperty(sodiumProperty.build()) + fileBuilder.addImport("kotlinx.cinterop", "pin") + fileBuilder.addImport("kotlinx.cinterop", "addressOf") for (commonClassDefinition in fileDefinition.commonClassList) { //Create type-aliases commonClassDefinition.innerClasses.forEach { @@ -66,6 +65,8 @@ object NativeLibsodiumGenerator { } } + pinParams(methodDefinition, methodBuilder) + if (methodDefinition.returnType == TypeDefinition.ARRAY_OF_UBYTES) { methodBuilder.addStatement("println(\"Debug\")") val constructJvmCall = StringBuilder() @@ -85,12 +86,12 @@ object NativeLibsodiumGenerator { } if (methodDefinition.returnType == TypeDefinition.UNIT) { - methodBuilder.addStatement("println(\"Debug\")") - val constructJvmCall = StringBuilder() - constructJvmCall.append("libsodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) + val constructNativeCall = StringBuilder() + constructNativeCall.append("libsodium.${methodDefinition.nativeName}") + constructNativeCall.append(paramsToString(methodDefinition)) + + methodBuilder.addStatement(constructNativeCall.toString()) } if (methodDefinition.returnType is CustomTypeDefinition) { @@ -102,10 +103,68 @@ object NativeLibsodiumGenerator { methodBuilder.addStatement(constructJvmCall.toString()) } + unpinParams(methodDefinition, methodBuilder) + methodBuilder.returns(methodDefinition.returnType.typeName) return methodBuilder.build() } + fun pinParams(methodDefinition: FunctionDefinition, methodBuilder: FunSpec.Builder) { + methodDefinition.parameterList.forEachIndexed { index, paramDefinition -> + if (paramDefinition.parameterType is TypeDefinition) { + when (paramDefinition.parameterType) { + TypeDefinition.ARRAY_OF_UBYTES -> { + methodBuilder.addStatement("val pinned${paramDefinition.parameterName.capitalize()} = ${paramDefinition.parameterName}.pin()") + } + TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { + methodBuilder.addStatement("val pinned${paramDefinition.parameterName.capitalize()} = ${paramDefinition.parameterName}.pin()") + } + TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE -> { + methodBuilder.addStatement("val pinned${paramDefinition.parameterName.capitalize()} = ${paramDefinition.parameterName}.pin()") + } + TypeDefinition.LONG -> { + + } + TypeDefinition.INT -> { + + } + TypeDefinition.STRING -> { + + } + } + } + + } + } + + fun unpinParams(methodDefinition: FunctionDefinition, methodBuilder: FunSpec.Builder) { + methodDefinition.parameterList.forEachIndexed { index, paramDefinition -> + if (paramDefinition.parameterType is TypeDefinition) { + when (paramDefinition.parameterType) { + TypeDefinition.ARRAY_OF_UBYTES -> { + methodBuilder.addStatement("pinned${paramDefinition.parameterName.capitalize()}.unpin()") + } + TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { + methodBuilder.addStatement("pinned${paramDefinition.parameterName.capitalize()}.unpin()") + } + TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE -> { + methodBuilder.addStatement("pinned${paramDefinition.parameterName.capitalize()}.unpin()") + } + TypeDefinition.LONG -> { + + } + TypeDefinition.INT -> { + + } + TypeDefinition.STRING -> { + + } + } + } + + } + } + fun paramsToString(methodDefinition: FunctionDefinition): String { val paramsBuilder = StringBuilder() paramsBuilder.append("(") @@ -121,13 +180,13 @@ object NativeLibsodiumGenerator { if (paramDefinition.parameterType is TypeDefinition) { when (paramDefinition.parameterType) { TypeDefinition.ARRAY_OF_UBYTES -> { - paramsBuilder.append(paramDefinition.parameterName + ".toCValues(), " + paramDefinition.parameterName + ".size.convert()" + separator) + paramsBuilder.append("pinned" + paramDefinition.parameterName.capitalize() + ".addressOf(0), "+ paramDefinition.parameterName + ".size.convert()" + separator) } TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - paramsBuilder.append(paramDefinition.parameterName + ".toCValues(), " + paramDefinition.parameterName + ".size.convert()" + separator) + paramsBuilder.append("pinned" + paramDefinition.parameterName.capitalize() + ".addressOf(0), "+ paramDefinition.parameterName + ".size.convert()" + separator) } TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE -> { - paramsBuilder.append(paramDefinition.parameterName + ".toCValues()" + separator) + paramsBuilder.append("pinned" + paramDefinition.parameterName.capitalize() + ".addressOf(0)" + separator) } TypeDefinition.LONG -> { paramsBuilder.append(paramDefinition.parameterName + ".convert()" + separator) diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt index 5788b13..0d8d97e 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt @@ -2,7 +2,9 @@ package debug.test import kotlin.Int import kotlin.UByteArray +import kotlinx.cinterop.addressOf import kotlinx.cinterop.convert +import kotlinx.cinterop.pin import kotlinx.cinterop.ptr import kotlinx.cinterop.toCValues import libsodium.crypto_generichash_blake2b_state @@ -22,13 +24,15 @@ actual class Crypto { } actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { - println("Debug") - libsodium.crypto_hash_sha256_update(state.ptr, input.toCValues(), input.size.convert()) + val pinnedInput = input.pin() + libsodium.crypto_hash_sha256_update(state.ptr, pinnedInput.addressOf(0), input.size.convert()) + pinnedInput.unpin() } actual fun crypto_hash_sha256_final(state: Sha256State, out: UByteArray) { - println("Debug") - libsodium.crypto_hash_sha256_final(state.ptr, out.toCValues()) + val pinnedOut = out.pin() + libsodium.crypto_hash_sha256_final(state.ptr, pinnedOut.addressOf(0)) + pinnedOut.unpin() } actual fun crypto_hash_sha512_init(state: Sha512State): Int { @@ -37,13 +41,15 @@ actual class Crypto { } actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { - println("Debug") - libsodium.crypto_hash_sha512_update(state.ptr, input.toCValues(), input.size.convert()) + val pinnedInput = input.pin() + libsodium.crypto_hash_sha512_update(state.ptr, pinnedInput.addressOf(0), input.size.convert()) + pinnedInput.unpin() } actual fun crypto_hash_sha512_final(state: Sha512State, out: UByteArray) { - println("Debug") - libsodium.crypto_hash_sha512_final(state.ptr, out.toCValues()) + val pinnedOut = out.pin() + libsodium.crypto_hash_sha512_final(state.ptr, pinnedOut.addressOf(0)) + pinnedOut.unpin() } actual fun crypto_generichash_init( @@ -51,8 +57,10 @@ actual class Crypto { key: UByteArray, outlen: Int ): Int { + val pinnedKey = key.pin() println("Debug") - return libsodium.crypto_generichash_init(state.ptr, key.toCValues(), key.size.convert(), + return libsodium.crypto_generichash_init(state.ptr, pinnedKey.addressOf(0), key.size.convert(), outlen.convert()) + pinnedKey.unpin() } }