From d792e75f2c14757cfac9bba6690b5917873201a6 Mon Sep 17 00:00:00 2001 From: Nick Zitzmann Date: Thu, 16 Aug 2012 22:31:41 -0600 Subject: darwinssl: add TLS 1.1 and 1.2 support, replace deprecated functions In Mountain Lion, Apple added TLS 1.1 and 1.2, and deprecated a number of SecureTransport functions, some of which we were using. We now check to see if the replacement functions are present, and if so, we use them instead. The old functions are still present for users of older cats. Also fixed a build warning that started to appear under Mountain Lion --- lib/curl_darwinssl.c | 388 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 369 insertions(+), 19 deletions(-) diff --git a/lib/curl_darwinssl.c b/lib/curl_darwinssl.c index c848be746..1626b57e2 100644 --- a/lib/curl_darwinssl.c +++ b/lib/curl_darwinssl.c @@ -60,6 +60,16 @@ /* From MacTypes.h (which we can't include because it isn't present in iOS: */ #define ioErr -36 +/* In Mountain Lion and iOS 5, Apple made some changes to the API. They + added TLS 1.1 and 1.2 support, and deprecated and replaced some + functions. You need to build against the Mountain Lion or iOS 5 SDK + or later to get TLS 1.1 or 1.2 support working in cURL. We'll weak-link + to the newer functions and use them if present in the user's OS. + + Builders: If you want TLS 1.1 and 1.2 but still want to retain support + for older cats, don't forget to set the MACOSX_DEPLOYMENT_TARGET + environmental variable prior to building cURL. */ + /* The following two functions were ripped from Apple sample code, * with some modifications: */ static OSStatus SocketRead(SSLConnectionRef connection, @@ -166,8 +176,9 @@ static OSStatus SocketWrite(SSLConnectionRef connection, return ortn; } -CF_INLINE const char *CipherNameForNumber(SSLCipherSuite cipher) { +CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) { switch (cipher) { + /* SSL version 3.0 */ case SSL_RSA_WITH_NULL_MD5: return "SSL_RSA_WITH_NULL_MD5"; break; @@ -255,6 +266,26 @@ CF_INLINE const char *CipherNameForNumber(SSLCipherSuite cipher) { case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA: return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA"; break; + /* SSL version 2.0 */ + case SSL_RSA_WITH_RC2_CBC_MD5: + return "SSL_RSA_WITH_RC2_CBC_MD5"; + break; + case SSL_RSA_WITH_IDEA_CBC_MD5: + return "SSL_RSA_WITH_IDEA_CBC_MD5"; + break; + case SSL_RSA_WITH_DES_CBC_MD5: + return "SSL_RSA_WITH_DES_CBC_MD5"; + break; + case SSL_RSA_WITH_3DES_EDE_CBC_MD5: + return "SSL_RSA_WITH_3DES_EDE_CBC_MD5"; + break; + } + return "SSL_NULL_WITH_NULL_NULL"; +} + +CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) { + switch(cipher) { + /* TLS 1.0 with AES (RFC 3268) */ case TLS_RSA_WITH_AES_128_CBC_SHA: return "TLS_RSA_WITH_AES_128_CBC_SHA"; break; @@ -291,6 +322,7 @@ CF_INLINE const char *CipherNameForNumber(SSLCipherSuite cipher) { case TLS_DH_anon_WITH_AES_256_CBC_SHA: return "TLS_DH_anon_WITH_AES_256_CBC_SHA"; break; + /* TLS 1.0 with ECDSA (RFC 4492) */ case TLS_ECDH_ECDSA_WITH_NULL_SHA: return "TLS_ECDH_ECDSA_WITH_NULL_SHA"; break; @@ -366,20 +398,172 @@ CF_INLINE const char *CipherNameForNumber(SSLCipherSuite cipher) { case TLS_ECDH_anon_WITH_AES_256_CBC_SHA: return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"; break; - case SSL_RSA_WITH_RC2_CBC_MD5: - return "SSL_RSA_WITH_RC2_CBC_MD5"; +#if defined(__MAC_10_8) || defined(__IPHONE_5_0) + /* TLS 1.2 (RFC 5246) */ + case TLS_RSA_WITH_NULL_MD5: + return "TLS_RSA_WITH_NULL_MD5"; break; - case SSL_RSA_WITH_IDEA_CBC_MD5: - return "SSL_RSA_WITH_IDEA_CBC_MD5"; + case TLS_RSA_WITH_NULL_SHA: + return "TLS_RSA_WITH_NULL_SHA"; break; - case SSL_RSA_WITH_DES_CBC_MD5: - return "SSL_RSA_WITH_DES_CBC_MD5"; + case TLS_RSA_WITH_RC4_128_MD5: + return "TLS_RSA_WITH_RC4_128_MD5"; break; - case SSL_RSA_WITH_3DES_EDE_CBC_MD5: - return "SSL_RSA_WITH_3DES_EDE_CBC_MD5"; + case TLS_RSA_WITH_RC4_128_SHA: + return "TLS_RSA_WITH_RC4_128_SHA"; + break; + case TLS_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_RSA_WITH_NULL_SHA256: + return "TLS_RSA_WITH_NULL_SHA256"; + break; + case TLS_RSA_WITH_AES_128_CBC_SHA256: + return "TLS_RSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_RSA_WITH_AES_256_CBC_SHA256: + return "TLS_RSA_WITH_AES_256_CBC_SHA256"; + break; + case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: + return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DH_DSS_WITH_AES_128_CBC_SHA256: + return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DH_RSA_WITH_AES_128_CBC_SHA256: + return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DH_DSS_WITH_AES_256_CBC_SHA256: + return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"; + break; + case TLS_DH_RSA_WITH_AES_256_CBC_SHA256: + return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"; + break; + case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"; + break; + case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"; + break; + case TLS_DH_anon_WITH_RC4_128_MD5: + return "TLS_DH_anon_WITH_RC4_128_MD5"; + break; + case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA: + return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DH_anon_WITH_AES_128_CBC_SHA256: + return "TLS_DH_anon_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DH_anon_WITH_AES_256_CBC_SHA256: + return "TLS_DH_anon_WITH_AES_256_CBC_SHA256"; + break; + /* TLS 1.2 with AES GCM (RFC 5288) */ + case TLS_RSA_WITH_AES_128_GCM_SHA256: + return "TLS_RSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_RSA_WITH_AES_256_GCM_SHA384: + return "TLS_RSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DH_RSA_WITH_AES_128_GCM_SHA256: + return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DH_RSA_WITH_AES_256_GCM_SHA384: + return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DH_DSS_WITH_AES_128_GCM_SHA256: + return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DH_DSS_WITH_AES_256_GCM_SHA384: + return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DH_anon_WITH_AES_128_GCM_SHA256: + return "TLS_DH_anon_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DH_anon_WITH_AES_256_GCM_SHA384: + return "TLS_DH_anon_WITH_AES_256_GCM_SHA384"; + break; + /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */ + case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"; break; + case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"; + break; + case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"; + break; + case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"; + break; + case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"; + break; + case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_EMPTY_RENEGOTIATION_INFO_SCSV: + return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"; + break; +#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */ } - return "(NONE)"; + return "TLS_NULL_WITH_NULL_NULL"; } static CURLcode darwinssl_connect_step1(struct connectdata *conn, @@ -397,6 +581,18 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn, /*SSLConnectionRef ssl_connection;*/ OSStatus err = noErr; +#if defined(__MAC_10_8) || defined(__IPHONE_5_0) + if(SSLCreateContext != NULL) { /* use the newer API if avaialble */ + if(connssl->ssl_ctx) + CFRelease(connssl->ssl_ctx); + connssl->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType); + if(!connssl->ssl_ctx) { + failf(data, "SSL: couldn't create a context!"); + return CURLE_OUT_OF_MEMORY; + } + } + else { +#elif !defined(TARGET_OS_EMBEDDED) if(connssl->ssl_ctx) (void)SSLDisposeContext(connssl->ssl_ctx); err = SSLNewContext(false, &(connssl->ssl_ctx)); @@ -404,8 +600,77 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn, failf(data, "SSL: couldn't create a context: OSStatus %d", err); return CURLE_OUT_OF_MEMORY; } +#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */ +#if defined(__MAC_10_8) || defined(__IPHONE_5_0) + } +#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */ /* check to see if we've been told to use an explicit SSL/TLS version */ +#if defined(__MAC_10_8) || defined(__IPHONE_5_0) + if(SSLSetProtocolVersionMax != NULL) { + switch(data->set.ssl.version) { + case CURL_SSLVERSION_DEFAULT: default: + (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3); + (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12); + break; + case CURL_SSLVERSION_TLSv1: + (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1); + (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12); + break; + case CURL_SSLVERSION_SSLv3: + (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3); + (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3); + break; + case CURL_SSLVERSION_SSLv2: + (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2); + (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2); + } + } + else { +#if !defined(TARGET_OS_EMBEDDED) + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kSSLProtocolAll, + false); + switch (data->set.ssl.version) { + case CURL_SSLVERSION_DEFAULT: default: + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kSSLProtocol3, + true); + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kTLSProtocol1, + true); + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kTLSProtocol11, + true); + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kTLSProtocol12, + true); + break; + case CURL_SSLVERSION_TLSv1: + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kTLSProtocol1, + true); + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kTLSProtocol11, + true); + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kTLSProtocol12, + true); + break; + case CURL_SSLVERSION_SSLv3: + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kSSLProtocol3, + true); + break; + case CURL_SSLVERSION_SSLv2: + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kSSLProtocol2, + true); + break; + } +#endif /* TARGET_OS_EMBEDDED */ + } +#else (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false); switch(data->set.ssl.version) { default: @@ -433,6 +698,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn, true); break; } +#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */ /* No need to load certificates here. SecureTransport uses the Keychain * (which is also part of the Security framework) to evaluate trust. */ @@ -441,12 +707,28 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn, * fail to connect if the verification fails, or if it should continue * anyway. In the latter case the result of the verification is checked with * SSL_get_verify_result() below. */ +#if defined(__MAC_10_6) || defined(__IPHONE_5_0) + if(SSLSetSessionOption != NULL) { + err = SSLSetSessionOption(connssl->ssl_ctx, + kSSLSessionOptionBreakOnServerAuth, + data->set.ssl.verifypeer?false:true); + if(err != noErr) { + failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err); + return CURLE_SSL_CONNECT_ERROR; + } + } + else { +#elif !defined(TARGET_OS_EMBEDDED) err = SSLSetEnableCertVerify(connssl->ssl_ctx, data->set.ssl.verifypeer?true:false); if(err != noErr) { failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err); return CURLE_SSL_CONNECT_ERROR; } +#endif /* defined(__MAC_10_6) || defined(__IPHONE_5_0) */ +#if defined(__MAC_10_6) || defined(__IPHONE_5_0) + } +#endif /* defined(__MAC_10_6) || defined(__IPHONE_5_0) */ /* If this is a domain name and not an IP address, then configure SNI: */ if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) && @@ -492,6 +774,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex) struct ssl_connect_data *connssl = &conn->ssl[sockindex]; OSStatus err; SSLCipherSuite cipher; + SSLProtocol protocol = 0; DEBUGASSERT(ssl_connect_2 == connssl->connecting_state || ssl_connect_2_reading == connssl->connecting_state @@ -533,7 +816,34 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex) /* Informational message */ (void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher); - infof (data, "SSL connection using %s\n", CipherNameForNumber(cipher)); + (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol); + switch (protocol) { + case kSSLProtocol2: + infof(data, "SSL 2.0 connection using %s\n", + SSLCipherNameForNumber(cipher)); + break; + case kSSLProtocol3: + infof(data, "SSL 3.0 connection using %s\n", + SSLCipherNameForNumber(cipher)); + break; + case kTLSProtocol1: + infof(data, "TLS 1.0 connection using %s\n", + TLSCipherNameForNumber(cipher)); + break; +#if defined(__MAC_10_8) || defined(__IPHONE_5_0) + case kTLSProtocol11: + infof(data, "TLS 1.1 connection using %s\n", + TLSCipherNameForNumber(cipher)); + break; + case kTLSProtocol12: + infof(data, "TLS 1.2 connection using %s\n", + TLSCipherNameForNumber(cipher)); + break; +#endif + default: + infof(data, "Unknown protocol connection\n"); + break; + } return CURLE_OK; } @@ -551,10 +861,35 @@ darwinssl_connect_step3(struct connectdata *conn, SecCertificateRef server_cert; OSStatus err; CFIndex i, count; + SecTrustRef trust; /* There is no step 3! * Well, okay, if verbose mode is on, let's print the details of the * server certificates. */ +#if defined(__MAC_10_7) || defined(__IPHONE_5_0) + if(SecTrustGetCertificateCount != NULL) { +#pragma unused(server_certs) + err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust); + if(err == noErr) { + count = SecTrustGetCertificateCount(trust); + for(i = 0L ; i < count ; i++) { + server_cert = SecTrustGetCertificateAtIndex(trust, i); + server_cert_summary = SecCertificateCopySubjectSummary(server_cert); + memset(server_cert_summary_c, 0, 128); + if(CFStringGetCString(server_cert_summary, + server_cert_summary_c, + 128, + kCFStringEncodingUTF8)) { + infof(data, "Server certificate: %s\n", server_cert_summary_c); + } + CFRelease(server_cert_summary); + } + CFRelease(trust); + } + } + else { +#elif !defined(TARGET_OS_EMBEDDED) +#pragma unused(trust) err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs); if(err == noErr) { count = CFArrayGetCount(server_certs); @@ -573,6 +908,10 @@ darwinssl_connect_step3(struct connectdata *conn, } CFRelease(server_certs); } +#endif /* defined(__MAC_10_7) || defined(__IPHONE_5_0) */ +#if defined(__MAC_10_7) || defined(__IPHONE_5_0) + } +#endif /* defined(__MAC_10_7) || defined(__IPHONE_5_0) */ connssl->connecting_state = ssl_connect_done; return CURLE_OK; @@ -722,9 +1061,20 @@ void Curl_darwinssl_close(struct connectdata *conn, int sockindex) { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - (void)SSLClose(connssl->ssl_ctx); - (void)SSLDisposeContext(connssl->ssl_ctx); - connssl->ssl_ctx = NULL; + if(connssl->ssl_ctx) { + (void)SSLClose(connssl->ssl_ctx); +#if defined(__MAC_10_8) || defined(__IPHONE_5_0) + if(SSLCreateContext != NULL) + CFRelease(connssl->ssl_ctx); +#if !defined(TARGET_OS_EMBEDDED) + else + (void)SSLDisposeContext(connssl->ssl_ctx); +#endif /* !defined(TARGET_OS_EMBEDDED */ +#else + (void)SSLDisposeContext(connssl->ssl_ctx); +#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */ + connssl->ssl_ctx = NULL; + } connssl->ssl_sockfd = 0; } @@ -840,15 +1190,15 @@ void Curl_darwinssl_random(struct SessionHandle *data, /* arc4random_buf() isn't available on cats older than Lion, so let's do this manually for the benefit of the older cats. */ size_t i; - u_int32_t random = 0; + u_int32_t random_number = 0; for(i = 0 ; i < length ; i++) { if(i % sizeof(u_int32_t) == 0) - random = arc4random(); - entropy[i] = random & 0xFF; - random >>= 8; + random_number = arc4random(); + entropy[i] = random_number & 0xFF; + random_number >>= 8; } - i = random = 0; + i = random_number = 0; (void)data; } -- cgit v1.2.3