Skip to content

Commit 69c16d9

Browse files
authored
Replace SecRandomCopyBytes with CCRandomGenerateBytes (#33)
1 parent b094ab0 commit 69c16d9

File tree

5 files changed

+25
-23
lines changed

5 files changed

+25
-23
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
![badge-support-js-ir]
2222
![badge-support-linux-arm]
2323

24-
A Kotlin Multiplatform library for obtaining cryptographically secure random data.
24+
A Kotlin Multiplatform library for procuring cryptographically secure random data.
2525

2626
The Linux/AndroidNative implementation was heavily inspired by [rust-random/getrandom][url-rust-random].
2727

library/crypto-rand/src/commonMain/kotlin/org/kotlincrypto/random/CryptoRand.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,10 @@ public abstract class CryptoRand @DelicateCryptoRandApi protected constructor()
4949
* - Node: [Crypto.randomFillSync()](https://nodejs.org/api/crypto.html#cryptorandomfillsyncbuffer-offset-size)
5050
* - WasmWasi: [random_get](https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/docs.md#random_get)
5151
* - Native:
52-
* - Android Native targets: [getrandom(2)](https://www.man7.org/linux/man-pages/man2/getrandom.2.html). If unavailable, `/dev/urandom` is used.
53-
* - Linux targets: [getrandom(2)](https://www.man7.org/linux/man-pages/man2/getrandom.2.html). If unavailable, `/dev/urandom` is used.
54-
* - Apple targets: [SecRandomCopyBytes](https://developer.apple.com/documentation/security/1399291-secrandomcopybytes)
52+
* - Linux & Android Native targets: [getrandom(2)](https://www.man7.org/linux/man-pages/man2/getrandom.2.html)
53+
* when available (GLIBC 2.25+ & Android API 23+), with a fallback to reading from `/dev/urandom` after polling
54+
* `/dev/random` once (per process lifetime) to ensure appropriate levels of system entropy are had.
55+
* - Apple targets: [CCRandomGenerateBytes](https://github.com/apple-oss-distributions/CommonCrypto/blob/main/include/CommonRandom.h)
5556
* - Windows targets: [BCryptGenRandom](https://learn.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom)
5657
* */
5758
public companion object Default: CryptoRand() {

library/crypto-rand/src/commonTest/kotlin/org/kotlincrypto/random/CryptoRandUnitTest.kt

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,31 +23,33 @@ open class CryptoRandUnitTest {
2323

2424
protected open val cryptoRand: CryptoRand = CryptoRand.Default
2525

26+
private companion object {
27+
private const val LIMIT_LINUX = 256
28+
private const val LIMIT_WEB = 65536
29+
}
30+
2631
// https://github.com/briansmith/ring/blob/main/tests/rand_tests.rs
2732
@Test
2833
fun givenArray_whenNextBytes_thenIsFilledWithData() {
29-
val linuxLimit = 256
30-
val webLimit = 65536
31-
3234
listOf(
3335
1,
3436
2,
3537
3,
3638
96,
37-
linuxLimit - 1,
38-
linuxLimit,
39-
linuxLimit + 1,
40-
linuxLimit * 2,
39+
LIMIT_LINUX - 1,
40+
LIMIT_LINUX,
41+
LIMIT_LINUX + 1,
42+
LIMIT_LINUX * 2,
4143
511,
4244
512,
4345
513,
4446
4096,
45-
webLimit - 1,
46-
webLimit,
47-
webLimit + 1,
48-
webLimit * 2,
47+
LIMIT_WEB - 1,
48+
LIMIT_WEB,
49+
LIMIT_WEB + 1,
50+
LIMIT_WEB * 2,
4951
// To ensure remainder logic is working properly for JS/WasmJS
50-
(webLimit * 2) + 6_000,
52+
(LIMIT_WEB * 2) + 6_000,
5153
).forEach { size ->
5254
val zeroCount = cryptoRand.nextBytes(buf = ByteArray(size)).count { it == 0.toByte() }
5355

library/crypto-rand/src/darwinMain/kotlin/org/kotlincrypto/random/internal/DarwinPlatform.kt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,17 @@
1818
package org.kotlincrypto.random.internal
1919

2020
import kotlinx.cinterop.*
21-
import platform.Security.SecRandomCopyBytes
22-
import platform.Security.kSecRandomDefault
2321
import org.kotlincrypto.random.RandomnessProcurementException
22+
import platform.CoreCrypto.CCRandomGenerateBytes
23+
import platform.CoreCrypto.kCCSuccess
2424

2525
@Throws(RandomnessProcurementException::class)
2626
internal actual fun ByteArray.cryptoRandFill() {
2727
@OptIn(ExperimentalForeignApi::class, UnsafeNumber::class)
2828
val status = usePinned { pinned ->
29-
// kSecRandomDefault is synonymous to NULL
30-
SecRandomCopyBytes(kSecRandomDefault, size.toUInt().convert(), pinned.addressOf(0))
29+
CCRandomGenerateBytes(pinned.addressOf(0), size.toUInt().convert())
3130
}
3231

33-
if (status == 0) return
34-
throw RandomnessProcurementException("Failed to obtain bytes from [SecRandomCopyBytes]. Code: $status")
32+
if (status == kCCSuccess) return
33+
throw RandomnessProcurementException("Failed to obtain bytes from [CCRandomGenerateBytes]. kCCStatus: $status")
3534
}

library/crypto-rand/src/linuxAndroidMain/kotlin/org/kotlincrypto/random/internal/LinuxAndroidPlatform.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ private inline fun getrandom2(buf: CPointer<ByteVar>, buflen: size_t, flags: u_i
3434
return syscall(SYS_getrandom.convert(), buf, buflen, flags).convert()
3535
}
3636

37-
// getrandom(2) available on Linux LIBC 3.17+, and Android Native API 28+
37+
// getrandom(2) available for Linux Kernel 3.17+ (Android API 23+)
3838
@OptIn(ExperimentalForeignApi::class, UnsafeNumber::class)
3939
internal val HAS_GET_RANDOM: Boolean by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
4040
val buf = ByteArray(1)

0 commit comments

Comments
 (0)