Skip to content

Commit 078ecc9

Browse files
committed
Use secure random generator on macOS
The implementation of arc4random_buf differs from its documentation. It is documented as "always successful, and no return value is reserved to indicate an error" for the sake of FreeBSD compatibility [1]. However, the actual implementation on macOS invokes function "ccrng_generate" [2] without validating the error cases. It might fail silently[3], which leads to unexpected source of entropy. The original arc4random used the RC4 a.k.a. ARC4 algorithm, and ChaCha20 based implementation was introduced in FreeBSD 12.0. Since macOS 10.12, it was replaced with the NIST-approved AES cipher, and it may be replaced again in the future as cryptographic techniques advance. Therefore, we should not assume that arc4random never fails. On the contrary, CCRandomGenerateBytes(), part of Cryptographic Services [4], returns cryptographically strong random bits with explicit status code. This patch properly calls CCRandomGenerateBytes() and checks the status. [1] https://www.freebsd.org/cgi/man.cgi?query=arc4random_buf [2] https://opensource.apple.com/source/CommonCrypto/CommonCrypto-60178.40.2/lib/CommonRandom.c.auto.html [3] https://opensource.apple.com/source/Libc/Libc-1439.40.11/gen/FreeBSD/arc4random.c.auto.html [4] https://developer.apple.com/documentation/security
1 parent ceee32c commit 078ecc9

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

random.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/*
2+
* Copyright (C) 2023 National Cheng Kung University, Taiwan.
23
* Copyright (c) 2017 Daan Sprenkels <[email protected]>
34
*
45
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -253,10 +254,27 @@ static int randombytes_linux_randombytes_urandom(void *buf, size_t n)
253254
#endif /* defined(__linux__) && !defined(SYS_getrandom) */
254255

255256
#if defined(BSD)
257+
#if defined(__APPLE__)
258+
#include <AvailabilityMacros.h>
259+
#if defined(MAC_OS_X_VERSION_10_10) && \
260+
MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_10
261+
#include <CommonCrypto/CommonCryptoError.h>
262+
#include <CommonCrypto/CommonRandom.h>
263+
#endif
264+
#endif
256265
static int randombytes_bsd_randombytes(void *buf, size_t n)
257266
{
267+
#if defined(MAC_OS_X_VERSION_10_15) && \
268+
MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_15
269+
/* We prefere CCRandomGenerateBytes as it returns an error code while
270+
* arc4random_buf may fail silently on macOS. See PR #390, and
271+
* <https://opensource.apple.com/source/Libc/Libc-1439.40.11/gen/FreeBSD/arc4random.c.auto.html>
272+
*/
273+
return (CCRandomGenerateBytes(buf, n) == kCCSuccess);
274+
#else
258275
arc4random_buf(buf, n);
259276
return 0;
277+
#endif
260278
}
261279
#endif
262280

@@ -274,7 +292,6 @@ int randombytes(uint8_t *buf, size_t n)
274292
return randombytes_linux_randombytes_urandom(buf, n);
275293
#endif
276294
#elif defined(BSD)
277-
/* Use arc4random system call */
278295
return randombytes_bsd_randombytes(buf, n);
279296
#else
280297
#error "randombytes(...) is not supported on this platform"

0 commit comments

Comments
 (0)