Adding secretstream push definition and neccessary changes

This commit is contained in:
Ugljesa Jovanovic 2020-08-14 16:00:30 +02:00
parent efe9661c30
commit 28995c065f
No known key found for this signature in database
GPG Key ID: 33A5F353387711A5
9 changed files with 195 additions and 31 deletions

View File

@ -85,6 +85,13 @@ class FunctionDefinition(
} }
} }
/**
*
* isActuallyAnOutputParam - drop this parameter from the generated param list and provide it as output. Param
* will be automatically generated inside function body block
* isStateType - provides special handling when type is a non-primitive state type
* dropParameterFromDefinition - don't show this parameter in method definition
*/
class ParameterDefinition( class ParameterDefinition(
val parameterName: String, val parameterName: String,
val parameterType: GeneralTypeDefinition, val parameterType: GeneralTypeDefinition,
@ -118,7 +125,8 @@ enum class TypeDefinition(override val typeName: TypeName) : GeneralTypeDefiniti
LONG(Long::class.asTypeName()), LONG(Long::class.asTypeName()),
INT(Int::class.asTypeName()), INT(Int::class.asTypeName()),
STRING(String::class.asTypeName()), STRING(String::class.asTypeName()),
UNIT(Unit::class.asTypeName()) UNIT(Unit::class.asTypeName()),
UBYTE(UByte::class.asTypeName())
} }
enum class TargetPlatform { enum class TargetPlatform {

View File

@ -10,7 +10,7 @@ fun ClassDefinition.defineSecretStreamFunctions() {
"SecretStreamState", "SecretStreamState",
"com.goterl.lazycode.lazysodium.interfaces.SecretStream.State", "com.goterl.lazycode.lazysodium.interfaces.SecretStream.State",
"SecretStreamState", "SecretStreamState",
"crypto_hash_sha256_state" "crypto_secretstream_xchacha20poly1305_state"
) )
+dataClassDef( +dataClassDef(
"SecretStreamStateAndHeader", "SecretStreamStateAndHeader",
@ -42,30 +42,35 @@ fun ClassDefinition.defineSecretStreamFunctions() {
val jvmSecretStreamInit = CodeBlockDefinition( val jvmSecretStreamInit = CodeBlockDefinition(
""" """
val header = UByteArray(24) val header = UByteArray(24)
val state = SecretStream.State() val state = SecretStream.State()
sodium.crypto_secretstream_xchacha20poly1305_init_push(state, header.asByteArray(), key.asByteArray()) sodium.crypto_secretstream_xchacha20poly1305_init_push(state, header.asByteArray(), key.asByteArray())
return SecretStreamStateAndHeader(state, header) return SecretStreamStateAndHeader(state, header)
""".trimIndent(), """.trimIndent(),
setOf(TargetPlatform.JVM) setOf(TargetPlatform.JVM)
) )
val nativeSecretStreamInit = CodeBlockDefinition( val nativeSecretStreamInit = CodeBlockDefinition(
""" """
val state = libsodium.sodium_malloc(libsodium.crypto_secretstream_xchacha20poly1305_state.size.convert())!! val pinnedKey = key.pin()
.reinterpret<libsodium.crypto_secretstream_xchacha20poly1305_state>() val state = sodium_malloc(libsodium.crypto_secretstream_xchacha20poly1305_state.size.convert())!!
.pointed .reinterpret<libsodium.crypto_secretstream_xchacha20poly1305_state>()
val header = UByteArray(crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt()) { 0U } .pointed
val pinnedHeader = header.pin() val header = UByteArray(libsodium.crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt()) { 0U }
libsodium.crypto_secretstream_xchacha20poly1305_init_push(state.ptr, pinnedHeader.addressOf(0), key.toCValues()) val pinnedHeader = header.pin()
pinnedHeader.unpin() libsodium.crypto_secretstream_xchacha20poly1305_init_push(state.ptr, pinnedHeader.addressOf(0), pinnedKey.addressOf(0))
return SecretStreamStateAndHeader(state, header) pinnedHeader.unpin()
pinnedKey.unpin()
return SecretStreamStateAndHeader(state, header)
""".trimIndent(), """.trimIndent(),
setOf(TargetPlatform.NATIVE) setOf(TargetPlatform.NATIVE)
) )
+funcDef( +funcDef(
"crypto_secretstream_xchacha20poly1305_init_push", "crypto_secretstream_xchacha20poly1305_init_push",
returnType = TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, codeDocumentation = """
Initialize a state and generate a random header. Both are returned inside `SecretStreamStateAndHeader` object
""".trimIndent(),
returnType = CustomTypeDefinition(withPackageName("SecretStreamStateAndHeader")),
dynamicJsReturn = true, dynamicJsReturn = true,
isStateCreationFunction = true, isStateCreationFunction = true,
customCodeBlockReplacesFunctionBody = listOf(jsSecretStreamInit, jvmSecretStreamInit, nativeSecretStreamInit) customCodeBlockReplacesFunctionBody = listOf(jsSecretStreamInit, jvmSecretStreamInit, nativeSecretStreamInit)
@ -76,5 +81,37 @@ fun ClassDefinition.defineSecretStreamFunctions() {
) )
} }
+funcDef(
name = "crypto_secretstream_xchacha20poly1305_push",
codeDocumentation = """
Encrypt next block of data using the previously initialized state. Returns encrypted block.
""".trimIndent(),
returnType = TypeDefinition.ARRAY_OF_UBYTES
) {
+ParameterDefinition(
"state",
CustomTypeDefinition(withPackageName("SecretStreamState"))
)
+ParameterDefinition(
"c",
TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE,
isActuallyAnOutputParam = true,
dropParameterFromDefinition = true
)
+ParameterDefinition(
"m",
TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE,
modifiesReturn = true
)
+ParameterDefinition(
"ad",
TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE
)
+ParameterDefinition(
"tag",
TypeDefinition.UBYTE
)
}
} }

View File

@ -77,7 +77,14 @@ object JsLibsodiumGenerator {
throw RuntimeException("Return modifier already found") throw RuntimeException("Return modifier already found")
} }
returnModifierFound = true returnModifierFound = true
returnModifierName = paramDefinition.parameterName when (paramDefinition.parameterType) {
TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> {
returnModifierName = "${paramDefinition.parameterName}.size"
}
TypeDefinition.INT -> {
returnModifierName = paramDefinition.parameterName
}
}
} }
if (paramDefinition.isActuallyAnOutputParam) { if (paramDefinition.isActuallyAnOutputParam) {
actualReturnTypeFound = true actualReturnTypeFound = true
@ -165,6 +172,9 @@ object JsLibsodiumGenerator {
TypeDefinition.STRING -> { TypeDefinition.STRING -> {
paramsBuilder.append(paramDefinition.parameterName + separator) paramsBuilder.append(paramDefinition.parameterName + separator)
} }
TypeDefinition.UBYTE -> {
paramsBuilder.append(paramDefinition.parameterName + separator)
}
} }
} }

View File

@ -72,7 +72,14 @@ object JvmLibsodiumGenerator {
throw RuntimeException("Return modifier already found") throw RuntimeException("Return modifier already found")
} }
returnModifierFound = true returnModifierFound = true
returnModifierName = paramDefinition.parameterName when (paramDefinition.parameterType) {
TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> {
returnModifierName = "${paramDefinition.parameterName}.size"
}
TypeDefinition.INT -> {
returnModifierName = paramDefinition.parameterName
}
}
} }
if (paramDefinition.isActuallyAnOutputParam) { if (paramDefinition.isActuallyAnOutputParam) {
actualReturnParameterDefinition = paramDefinition actualReturnParameterDefinition = paramDefinition
@ -114,7 +121,7 @@ object JvmLibsodiumGenerator {
constructJvmCall.append("sodium.${methodDefinition.nativeName}") constructJvmCall.append("sodium.${methodDefinition.nativeName}")
constructJvmCall.append(paramsToString(methodDefinition)) constructJvmCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructJvmCall.toString()) methodBuilder.addStatement(constructJvmCall.toString())
methodBuilder.addStatement("return out") methodBuilder.addStatement("return ${actualReturnParameterDefinition.parameterName}")
} else { } else {
when (methodDefinition.returnType) { when (methodDefinition.returnType) {
TypeDefinition.ARRAY_OF_UBYTES -> { TypeDefinition.ARRAY_OF_UBYTES -> {
@ -155,7 +162,7 @@ object JvmLibsodiumGenerator {
*/ */
when (outputParam.parameterType) { when (outputParam.parameterType) {
TypeDefinition.ARRAY_OF_UBYTES, TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { TypeDefinition.ARRAY_OF_UBYTES, TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> {
methodBuilder.addStatement("val out = UByteArray($length)") methodBuilder.addStatement("val ${outputParam.parameterName} = UByteArray($length)")
} }
else -> { else -> {
throw RuntimeException("Unhandled native output param type: ${outputParam.parameterType.typeName}") throw RuntimeException("Unhandled native output param type: ${outputParam.parameterType.typeName}")
@ -205,6 +212,9 @@ object JvmLibsodiumGenerator {
TypeDefinition.STRING -> { TypeDefinition.STRING -> {
paramsBuilder.append(paramDefinition.parameterName + separator) paramsBuilder.append(paramDefinition.parameterName + separator)
} }
TypeDefinition.UBYTE -> {
paramsBuilder.append(paramDefinition.parameterName + separator)
}
} }
} }

View File

@ -87,7 +87,15 @@ object NativeLibsodiumGenerator {
throw RuntimeException("Return modifier already found") throw RuntimeException("Return modifier already found")
} }
returnModifierFound = true returnModifierFound = true
returnModifierName = paramDefinition.parameterName when (paramDefinition.parameterType) {
TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> {
returnModifierName = "${paramDefinition.parameterName}.size"
}
TypeDefinition.INT -> {
returnModifierName = paramDefinition.parameterName
}
}
} }
if (paramDefinition.isActuallyAnOutputParam) { if (paramDefinition.isActuallyAnOutputParam) {
actualReturnParameterDefinition = paramDefinition actualReturnParameterDefinition = paramDefinition
@ -105,7 +113,6 @@ object NativeLibsodiumGenerator {
} }
} }
methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")")
pinParams(methodDefinition, methodBuilder)
val constructNativeCall = StringBuilder() val constructNativeCall = StringBuilder()
if (methodDefinition.customCodeBlockReplacesFunctionBody != null) { if (methodDefinition.customCodeBlockReplacesFunctionBody != null) {
for (codeBlock in methodDefinition.customCodeBlockReplacesFunctionBody.filter { it.applyOnTargets.contains(TargetPlatform.NATIVE) }) { for (codeBlock in methodDefinition.customCodeBlockReplacesFunctionBody.filter { it.applyOnTargets.contains(TargetPlatform.NATIVE) }) {
@ -113,6 +120,7 @@ object NativeLibsodiumGenerator {
methodBuilder.addStatement(constructNativeCall.toString()) methodBuilder.addStatement(constructNativeCall.toString())
} }
} else { } else {
pinParams(methodDefinition, methodBuilder)
if (methodDefinition.isStateCreationFunction) { if (methodDefinition.isStateCreationFunction) {
constructNativeCall.append("libsodium.${methodDefinition.nativeName}") constructNativeCall.append("libsodium.${methodDefinition.nativeName}")
constructNativeCall.append(paramsToString(methodDefinition)) constructNativeCall.append(paramsToString(methodDefinition))
@ -124,7 +132,7 @@ object NativeLibsodiumGenerator {
constructNativeCall.append(paramsToString(methodDefinition)) constructNativeCall.append(paramsToString(methodDefinition))
methodBuilder.addStatement(constructNativeCall.toString()) methodBuilder.addStatement(constructNativeCall.toString())
unpinParams(methodDefinition, methodBuilder) unpinParams(methodDefinition, methodBuilder)
methodBuilder.addStatement("return out") methodBuilder.addStatement("return ${actualReturnParameterDefinition.parameterName}")
} else { } else {
when (methodDefinition.returnType) { when (methodDefinition.returnType) {
TypeDefinition.ARRAY_OF_UBYTES -> { TypeDefinition.ARRAY_OF_UBYTES -> {
@ -184,7 +192,7 @@ object NativeLibsodiumGenerator {
*/ */
when (outputParam.parameterType) { when (outputParam.parameterType) {
TypeDefinition.ARRAY_OF_UBYTES, TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { TypeDefinition.ARRAY_OF_UBYTES, TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> {
methodBuilder.addStatement("val out = UByteArray($length)") methodBuilder.addStatement("val ${outputParam.parameterName} = UByteArray($length)")
} }
else -> { else -> {
throw RuntimeException("Unhandled native output param type: ${outputParam.parameterType.typeName}") throw RuntimeException("Unhandled native output param type: ${outputParam.parameterType.typeName}")
@ -282,6 +290,9 @@ object NativeLibsodiumGenerator {
TypeDefinition.STRING -> { TypeDefinition.STRING -> {
paramsBuilder.append(paramDefinition.parameterName + separator) paramsBuilder.append(paramDefinition.parameterName + separator)
} }
TypeDefinition.UBYTE -> {
paramsBuilder.append(paramDefinition.parameterName + separator)
}
} }
} }

View File

@ -1,6 +1,7 @@
package debug.test package debug.test
import kotlin.Int import kotlin.Int
import kotlin.UByte
import kotlin.UByteArray import kotlin.UByteArray
expect class Sha256State expect class Sha256State
@ -35,5 +36,19 @@ expect class Crypto internal constructor() {
fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState
fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray /**
* Initialize a state and generate a random header. Both are returned inside
* `SecretStreamStateAndHeader` object
*/
fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): SecretStreamStateAndHeader
/**
* Encrypt next block of data using the previously initialized state. Returns encrypted block.
*/
fun crypto_secretstream_xchacha20poly1305_push(
state: SecretStreamState,
m: UByteArray,
ad: UByteArray,
tag: UByte
): UByteArray
} }

View File

@ -5,6 +5,7 @@ import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
import kotlin.Any import kotlin.Any
import kotlin.Int import kotlin.Int
import kotlin.UByte
import kotlin.UByteArray import kotlin.UByteArray
import org.khronos.webgl.Uint8Array import org.khronos.webgl.Uint8Array
@ -58,6 +59,10 @@ actual class Crypto internal actual constructor() {
return getSodium().crypto_generichash_init(key.toUInt8Array(), outlen) return getSodium().crypto_generichash_init(key.toUInt8Array(), outlen)
} }
/**
* Initialize a state and generate a random header. Both are returned inside
* `SecretStreamStateAndHeader` object
*/
actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): dynamic { actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): dynamic {
println("Debug crypto_secretstream_xchacha20poly1305_init_push") println("Debug crypto_secretstream_xchacha20poly1305_init_push")
val stateAndHeader = val stateAndHeader =
@ -66,4 +71,18 @@ actual class Crypto internal actual constructor() {
val header = (stateAndHeader.header as Uint8Array).toUByteArray() val header = (stateAndHeader.header as Uint8Array).toUByteArray()
return SecretStreamStateAndHeader(state, header) return SecretStreamStateAndHeader(state, header)
} }
/**
* Encrypt next block of data using the previously initialized state. Returns encrypted block.
*/
actual fun crypto_secretstream_xchacha20poly1305_push(
state: SecretStreamState,
m: UByteArray,
ad: UByteArray,
tag: UByte
): UByteArray {
println("Debug crypto_secretstream_xchacha20poly1305_push")
return getSodium().crypto_secretstream_xchacha20poly1305_push(state, m.toUInt8Array(), ,
ad.toUInt8Array(), , tag).toUByteArray()
}
} }

View File

@ -5,6 +5,7 @@ import com.goterl.lazycode.lazysodium.interfaces.Hash
import com.goterl.lazycode.lazysodium.interfaces.SecretStream import com.goterl.lazycode.lazysodium.interfaces.SecretStream
import kotlin.ByteArray import kotlin.ByteArray
import kotlin.Int import kotlin.Int
import kotlin.UByte
import kotlin.UByteArray import kotlin.UByteArray
val sodium: SodiumJava = SodiumJava() val sodium: SodiumJava = SodiumJava()
@ -67,7 +68,12 @@ actual class Crypto internal actual constructor() {
return state return state
} }
actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray { /**
* Initialize a state and generate a random header. Both are returned inside
* `SecretStreamStateAndHeader` object
*/
actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray):
SecretStreamStateAndHeader {
println("Debug crypto_secretstream_xchacha20poly1305_init_push") println("Debug crypto_secretstream_xchacha20poly1305_init_push")
val header = UByteArray(24) val header = UByteArray(24)
val state = SecretStream.State() val state = SecretStream.State()
@ -75,4 +81,20 @@ actual class Crypto internal actual constructor() {
key.asByteArray()) key.asByteArray())
return SecretStreamStateAndHeader(state, header) return SecretStreamStateAndHeader(state, header)
} }
/**
* Encrypt next block of data using the previously initialized state. Returns encrypted block.
*/
actual fun crypto_secretstream_xchacha20poly1305_push(
state: SecretStreamState,
m: UByteArray,
ad: UByteArray,
tag: UByte
): UByteArray {
val c = UByteArray(m.size)
println("Debug crypto_secretstream_xchacha20poly1305_push")
sodium.crypto_secretstream_xchacha20poly1305_push(state, c.asByteArray(), c.size.toLong(),
m.asByteArray(), m.size.toLong(), ad.asByteArray(), ad.size.toLong(), tag)
return c
}
} }

View File

@ -3,6 +3,7 @@ package debug.test
import kotlin.Byte import kotlin.Byte
import kotlin.ByteArray import kotlin.ByteArray
import kotlin.Int import kotlin.Int
import kotlin.UByte
import kotlin.UByteArray import kotlin.UByteArray
import kotlinx.cinterop.addressOf import kotlinx.cinterop.addressOf
import kotlinx.cinterop.convert import kotlinx.cinterop.convert
@ -14,6 +15,7 @@ import kotlinx.cinterop.toCValues
import libsodium.crypto_generichash_blake2b_state import libsodium.crypto_generichash_blake2b_state
import libsodium.crypto_hash_sha256_state import libsodium.crypto_hash_sha256_state
import libsodium.crypto_hash_sha512_state import libsodium.crypto_hash_sha512_state
import libsodium.crypto_secretstream_xchacha20poly1305_state
import libsodium.sodium_malloc import libsodium.sodium_malloc
actual typealias Sha256State = crypto_hash_sha256_state actual typealias Sha256State = crypto_hash_sha256_state
@ -22,7 +24,7 @@ actual typealias Sha512State = crypto_hash_sha512_state
actual typealias GenericHashState = crypto_generichash_blake2b_state actual typealias GenericHashState = crypto_generichash_blake2b_state
actual typealias SecretStreamState = crypto_hash_sha256_state actual typealias SecretStreamState = crypto_secretstream_xchacha20poly1305_state
actual class Crypto internal actual constructor() { actual class Crypto internal actual constructor() {
val _emitByte: Byte = 0 val _emitByte: Byte = 0
@ -92,18 +94,48 @@ actual class Crypto internal actual constructor() {
return state return state
} }
actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray { /**
* Initialize a state and generate a random header. Both are returned inside
* `SecretStreamStateAndHeader` object
*/
actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray):
SecretStreamStateAndHeader {
println("Debug crypto_secretstream_xchacha20poly1305_init_push") println("Debug crypto_secretstream_xchacha20poly1305_init_push")
val pinnedKey = key.pin() val pinnedKey = key.pin()
val state = val state =
libsodium.sodium_malloc(libsodium.crypto_secretstream_xchacha20poly1305_state.size.convert())!! sodium_malloc(libsodium.crypto_secretstream_xchacha20poly1305_state.size.convert())!!
.reinterpret<libsodium.crypto_secretstream_xchacha20poly1305_state>() .reinterpret<libsodium.crypto_secretstream_xchacha20poly1305_state>()
.pointed .pointed
val header = UByteArray(crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt()) { 0U } val header = UByteArray(libsodium.crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt())
{ 0U }
val pinnedHeader = header.pin() val pinnedHeader = header.pin()
libsodium.crypto_secretstream_xchacha20poly1305_init_push(state.ptr, libsodium.crypto_secretstream_xchacha20poly1305_init_push(state.ptr,
pinnedHeader.addressOf(0), key.toCValues()) pinnedHeader.addressOf(0), pinnedKey.addressOf(0))
pinnedHeader.unpin() pinnedHeader.unpin()
pinnedKey.unpin()
return SecretStreamStateAndHeader(state, header) return SecretStreamStateAndHeader(state, header)
} }
/**
* Encrypt next block of data using the previously initialized state. Returns encrypted block.
*/
actual fun crypto_secretstream_xchacha20poly1305_push(
state: SecretStreamState,
m: UByteArray,
ad: UByteArray,
tag: UByte
): UByteArray {
val c = UByteArray(m.size)
println("Debug crypto_secretstream_xchacha20poly1305_push")
val pinnedC = c.pin()
val pinnedM = m.pin()
val pinnedAd = ad.pin()
libsodium.crypto_secretstream_xchacha20poly1305_push(state.ptr, pinnedC.addressOf(0),
c.size.convert(), pinnedM.addressOf(0), m.size.convert(), pinnedAd.addressOf(0),
ad.size.convert(), tag)
pinnedC.unpin()
pinnedM.unpin()
pinnedAd.unpin()
return c
}
} }