From 71b2c441bb236fd43a1695e80af68ef750cddd0c Mon Sep 17 00:00:00 2001 From: Jim Huang Date: Fri, 25 Jun 2021 10:09:19 +0800 Subject: [PATCH 1/2] CI: Update the macOS image to version 10.15 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index aeb2908b..65ceb30b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -115,7 +115,7 @@ jobs: displayName: macOS pool: vmImage: - macOS-10.14 + macOS-10.15 strategy: matrix: Debug: From c4947c887903ab216589a763013d2b22cf6457ac Mon Sep 17 00:00:00 2001 From: Jim Huang Date: Sat, 24 Apr 2021 06:24:06 +0800 Subject: [PATCH 2/2] 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 --- src/random.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/random.c b/src/random.c index 255bede4..910a3e89 100644 --- a/src/random.c +++ b/src/random.c @@ -156,7 +156,8 @@ uintptr_t _mi_random_next(mi_random_ctx_t* ctx) { /* ---------------------------------------------------------------------------- To initialize a fresh random context we rely on the OS: - Windows : BCryptGenRandom (or RtlGenRandom) -- osX,bsd,wasi: arc4random_buf +- macOS : CCRandomGenerateBytes +- bsd,wasi : arc4random_buf - Linux : getrandom,/dev/urandom If we cannot get good randomness, we fall back to weak randomness based on a timer and ASLR. -----------------------------------------------------------------------------*/ @@ -186,7 +187,36 @@ static bool os_random_buf(void* buf, size_t buf_len) { } #endif -#elif defined(ANDROID) || defined(XP_DARWIN) || defined(__APPLE__) || defined(__DragonFly__) || \ +#elif defined(__APPLE__) +#include +#if defined(MAC_OS_X_VERSION_10_10) && \ + MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_10 +#include +#endif +static bool os_random_buf(void* buf, size_t buf_len) { + /* The implementation of arc4random_buf(3) differs from its documentation. + * It is documented as "always successful, and no return value is reserved + * to indicate an error." However, the actual implementation invokes the + * function "ccrng_generate" without validating the error cases. It might + * fail silently, which leads to unexpected source of entropy. + * See: + * https://opensource.apple.com/source/Libc/Libc-1439.40.11/gen/FreeBSD/arc4random.c.auto.html + * + * CCRandomGenerateBytes(), on the contrary, returns cryptographically strong + * random bits with explicit status code. + */ +#if defined(MAC_OS_X_VERSION_10_15) && \ + MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_15 + return CCRandomGenerateBytes(buf, buf_len) == kCCSuccess; +#else + /* Prior to macOS 10.15, CCRandomGenerateBytes() might take a bit longer time + * to complete, so failback to arc4random_buf(). + */ + arc4random_buf(buf, buf_len); + return true; +#endif +} +#elif defined(ANDROID) || defined(__DragonFly__) || \ defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ defined(__sun) || defined(__wasi__) #include