From cf09a09dc801f3e50bd0f29313577d713f49777d Mon Sep 17 00:00:00 2001 From: Aria Wisp Date: Sun, 7 Sep 2025 12:42:04 -0600 Subject: [PATCH] Fix constant-offset signature copying; correct CMAC slice update; urandom FD check - ECDSA/signature: copyFrom=0 when writing into destination with offset to avoid truncated/garbled output (JDK, Apple, OpenSSL3) - JDK SignatureGenerator: same fix for signIntoByteArray - OpenSSL3 CMAC: use startIndex/endIndex slice in EVP_MAC_update instead of whole array - Linux URandom: consider fd<0 as error (fd==0 is valid) Build: jvmMainClasses and jvmTest for JDK provider pass; metadata compilation for Apple/OpenSSL3 OK. --- .../apple/src/commonMain/kotlin/algorithms/SecEcdsa.kt | 2 +- .../src/commonMain/kotlin/internal/SecSignature.kt | 2 +- .../jdk/src/jvmMain/kotlin/algorithms/JdkEcdsa.kt | 3 ++- .../jvmMain/kotlin/operations/JdkSignatureGenerator.kt | 2 +- .../commonMain/kotlin/algorithms/Openssl3AesCmac.kt | 10 +++++----- .../src/commonMain/kotlin/algorithms/Openssl3Ecdsa.kt | 2 +- .../operations/Openssl3DigestSignatureGenerator.kt | 2 +- .../src/linuxAndAndroidNativeMain/kotlin/URandom.kt | 3 ++- 8 files changed, 14 insertions(+), 12 deletions(-) diff --git a/cryptography-providers/apple/src/commonMain/kotlin/algorithms/SecEcdsa.kt b/cryptography-providers/apple/src/commonMain/kotlin/algorithms/SecEcdsa.kt index d1efb6b7..59f829fb 100644 --- a/cryptography-providers/apple/src/commonMain/kotlin/algorithms/SecEcdsa.kt +++ b/cryptography-providers/apple/src/commonMain/kotlin/algorithms/SecEcdsa.kt @@ -261,7 +261,7 @@ private class EcdsaRawSignatureGenerator( override fun signIntoByteArray(destination: ByteArray, destinationOffset: Int): Int { val signature = signToByteArray() checkBounds(destination.size, destinationOffset, destinationOffset + signature.size) - signature.copyInto(destination, destinationOffset, destinationOffset) + signature.copyInto(destination, destinationOffset, 0, signature.size) return signature.size } diff --git a/cryptography-providers/apple/src/commonMain/kotlin/internal/SecSignature.kt b/cryptography-providers/apple/src/commonMain/kotlin/internal/SecSignature.kt index e11ab12a..1c6a32a0 100644 --- a/cryptography-providers/apple/src/commonMain/kotlin/internal/SecSignature.kt +++ b/cryptography-providers/apple/src/commonMain/kotlin/internal/SecSignature.kt @@ -107,7 +107,7 @@ private class SecSignFunction( override fun signIntoByteArray(destination: ByteArray, destinationOffset: Int): Int { val signature = signToByteArray() checkBounds(destination.size, destinationOffset, destinationOffset + signature.size) - signature.copyInto(destination, destinationOffset, destinationOffset) + signature.copyInto(destination, destinationOffset, 0, signature.size) return signature.size } diff --git a/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEcdsa.kt b/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEcdsa.kt index 62fda107..133df1c4 100644 --- a/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEcdsa.kt +++ b/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEcdsa.kt @@ -70,7 +70,8 @@ private class EcdsaRawSignatureGenerator( override fun signIntoByteArray(destination: ByteArray, destinationOffset: Int): Int { val signature = signToByteArray() checkBounds(destination.size, destinationOffset, destinationOffset + signature.size) - signature.copyInto(destination, destinationOffset, destinationOffset) + // Copy the whole signature into destination at the given offset + signature.copyInto(destination, destinationOffset, 0, signature.size) return signature.size } diff --git a/cryptography-providers/jdk/src/jvmMain/kotlin/operations/JdkSignatureGenerator.kt b/cryptography-providers/jdk/src/jvmMain/kotlin/operations/JdkSignatureGenerator.kt index a754b057..43505664 100644 --- a/cryptography-providers/jdk/src/jvmMain/kotlin/operations/JdkSignatureGenerator.kt +++ b/cryptography-providers/jdk/src/jvmMain/kotlin/operations/JdkSignatureGenerator.kt @@ -38,7 +38,7 @@ private class JdkSignFunction( override fun signIntoByteArray(destination: ByteArray, destinationOffset: Int): Int { val signature = signToByteArray() checkBounds(destination.size, destinationOffset, destinationOffset + signature.size) - signature.copyInto(destination, destinationOffset, destinationOffset) + signature.copyInto(destination, destinationOffset, 0, signature.size) return signature.size } diff --git a/cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3AesCmac.kt b/cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3AesCmac.kt index c2896896..20656a0d 100644 --- a/cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3AesCmac.kt +++ b/cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3AesCmac.kt @@ -65,15 +65,15 @@ private class AesCmacSignature( @OptIn(UnsafeNumber::class) override fun update(source: ByteArray, startIndex: Int, endIndex: Int) { - // Implementation for updating the CMAC with the provided data + // Update CMAC using the requested slice [startIndex, endIndex) checkBounds(source.size, startIndex, endIndex) val context = context.access() source.usePinned { checkError( EVP_MAC_update( ctx = context, - data = it.safeAddressOf(0).reinterpret(), - datalen = source.size.convert() + data = it.safeAddressOf(startIndex).reinterpret(), + datalen = (endIndex - startIndex).convert() ) ) } @@ -82,7 +82,7 @@ private class AesCmacSignature( override fun signIntoByteArray(destination: ByteArray, destinationOffset: Int): Int { val signature = signToByteArray() checkBounds(destination.size, destinationOffset, destinationOffset + signature.size) - signature.copyInto(destination, destinationOffset, destinationOffset) + signature.copyInto(destination, destinationOffset, 0, signature.size) return signature.size } @@ -139,4 +139,4 @@ private class AesCmacSignature( } } } -} \ No newline at end of file +} diff --git a/cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3Ecdsa.kt b/cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3Ecdsa.kt index a8527387..a1de279c 100644 --- a/cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3Ecdsa.kt +++ b/cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3Ecdsa.kt @@ -174,7 +174,7 @@ private class EcdsaRawSignatureGenerator( override fun signIntoByteArray(destination: ByteArray, destinationOffset: Int): Int { val signature = signToByteArray() checkBounds(destination.size, destinationOffset, destinationOffset + signature.size) - signature.copyInto(destination, destinationOffset, destinationOffset) + signature.copyInto(destination, destinationOffset, 0, signature.size) return signature.size } diff --git a/cryptography-providers/openssl3/api/src/commonMain/kotlin/operations/Openssl3DigestSignatureGenerator.kt b/cryptography-providers/openssl3/api/src/commonMain/kotlin/operations/Openssl3DigestSignatureGenerator.kt index 13336192..07a1f6c6 100644 --- a/cryptography-providers/openssl3/api/src/commonMain/kotlin/operations/Openssl3DigestSignatureGenerator.kt +++ b/cryptography-providers/openssl3/api/src/commonMain/kotlin/operations/Openssl3DigestSignatureGenerator.kt @@ -46,7 +46,7 @@ internal abstract class Openssl3DigestSignatureGenerator( override fun signIntoByteArray(destination: ByteArray, destinationOffset: Int): Int { val signature = signToByteArray() checkBounds(destination.size, destinationOffset, destinationOffset + signature.size) - signature.copyInto(destination, destinationOffset, destinationOffset) + signature.copyInto(destination, destinationOffset, 0, signature.size) return signature.size } diff --git a/cryptography-random/src/linuxAndAndroidNativeMain/kotlin/URandom.kt b/cryptography-random/src/linuxAndAndroidNativeMain/kotlin/URandom.kt index ef2f56b2..f09bb009 100644 --- a/cryptography-random/src/linuxAndAndroidNativeMain/kotlin/URandom.kt +++ b/cryptography-random/src/linuxAndAndroidNativeMain/kotlin/URandom.kt @@ -51,6 +51,7 @@ private fun awaitURandomReady() { private fun open(path: String): Int { val fd = open(path, O_RDONLY, null) - if (fd <= 0) errnoCheck() + // According to POSIX, open returns -1 on error; 0 is a valid descriptor + if (fd < 0) errnoCheck() return fd }