Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.
Status
The first post of this thread is a WikiPost and can be edited by anyone with the appropiate permissions. Your edits will be public.
So partial progress for SL. TLS1.2 is negotiated:

Code:
libsecurity_ssl.dylib                                                                                     100%  180KB   7.3MB/s   00:00   
=== Step 1: Verify patched dylib install_name ===
/tmp/libsecurity_ssl_tls12.dylib:
    /tmp/libsecurity_ssl_tls12.dylib (compatibility version 0.0.0, current version 0.0.0)
    /System/Library/Frameworks/Security.framework/Versions/A/Security (compatibility version 1.0.0, current version 55002.0.0)

=== Step 2: Compile ssltest (direct link + system Security baseline) ===
ssltest.c                                                                                                 100% 8093     3.1MB/s   00:00   
stock: OK
direct: OK

======================================================
STOCK (system Security.framework)
======================================================

--- stock      tls10.badssl.com             prot=default ---
TCP connected to tls10.badssl.com:443
Enabled cipher count: 46
Starting TLS handshake (verbose I/O: no)...
Negotiated protocol: TLS 1.0 (enum=4)
Negotiated cipher:   0xC013
reads=0  writes=0
HTTP response:       HTTP/1.1 421 Misdirected Request

FALLBACK: TLS 1.0 negotiated

--- stock      www.howsmyssl.com            prot=default ---
TCP connected to www.howsmyssl.com:443
Enabled cipher count: 46
Starting TLS handshake (verbose I/O: no)...
Negotiated protocol: TLS 1.0 (enum=4)
Negotiated cipher:   0x002F
reads=0  writes=0
HTTP response:       H

FALLBACK: TLS 1.0 negotiated

======================================================
PATCHED (our libsecurity_ssl_tls12.dylib)
======================================================

--- TLS 1.0 forced (enum=4, regression test) ---

--- patched    tls10.badssl.com             prot=4    ---
TCP connected to tls10.badssl.com:443
Enabled cipher count: 9
Forcing max protocol to enum 4
Starting TLS handshake (verbose I/O: no)...
Negotiated protocol: TLS 1.0 (enum=4)
Negotiated cipher:   0x002F
reads=0  writes=0
HTTP response:       HTTP/1.1 421 Misdirected Request

FALLBACK: TLS 1.0 negotiated

--- TLS 1.2 (default, howsmyssl) ---

--- patched    www.howsmyssl.com            prot=default ---
TCP connected to www.howsmyssl.com:443
Enabled cipher count: 9
Starting TLS handshake (verbose I/O: no)...
Negotiated protocol: TLS 1.2 (enum=8)
Negotiated cipher:   0x002F
reads=0  writes=0

SUCCESS: TLS 1.2 negotiated

--- TLS 1.2 (default, tls12.badssl.com) ---

--- patched    tls12.badssl.com             prot=default ---
TCP connected to tls12.badssl.com:443
Enabled cipher count: 9
Starting TLS handshake (verbose I/O: no)...
Negotiated protocol: TLS 1.2 (enum=8)
Negotiated cipher:   0x003C
reads=0  writes=0

SUCCESS: TLS 1.2 negotiated

--- TLS 1.0 forced against howsmyssl (should downgrade) ---

--- patched    www.howsmyssl.com            prot=4    ---
TCP connected to www.howsmyssl.com:443
Enabled cipher count: 9
Forcing max protocol to enum 4
Starting TLS handshake (verbose I/O: no)...
Negotiated protocol: TLS 1.0 (enum=4)
Negotiated cipher:   0x002F
reads=0  writes=0
HTTP response:       H

FALLBACK: TLS 1.0 negotiated
 
@internetzel I got now:
  • Snow Leopard dyld does not load LC_LOAD_WEAK_DYLIB from dependent libraries (only from the main executable)
  • Direct binary patching with trampolines to external dylib requires the dylib to be loaded first — chicken-and-egg problem
  • Inline code injection requires restructuring the binary (growing __TEXT or finding cave space)
  • DYLD_FORCE_FLAT_NAMESPACE system-wide breaks the OS
What does work:

  • DYLD_INSERT_LIBRARIES + DYLD_FORCE_FLAT_NAMESPACE for individual processes
  • Direct linking (ssltest_direct)
@joevt Any thoughts?

Progress so far:​

libsecurity_ssl_tls12.dylib at /usr/local/lib/ contains the full TLS 1.2 SSL implementation (patched from Apple's libsecurity_ssl-55002 source) plus a __attribute__((constructor)) in tls12_patcher.c

When loaded into a process via DYLD_INSERT_LIBRARIES, the constructor runs after Security.framework is loaded, uses vm_protect to make Security's __TEXT pages writable, and writes 14-byte FF 25 absolute JMP trampolines at the entry of 31 SSL functions, redirecting them to the implementations.

1781735154710.png


Code:
tls12.badssl.com         
example.com              SSLHandshake failed: -9800 (errSSLProtocol)
www.apple.com            Negotiated cipher:   0xC02F SUCCESS: TLS 1.2 negotiated
www.ebay.com             SSLHandshake failed: -9800 (errSSLProtocol)
www.nytimes.com          Negotiated cipher:   0xC02F SUCCESS: TLS 1.2 negotiated
www.bbc.com              Negotiated cipher:   0xC02F SUCCESS: TLS 1.2 negotiated
www.npr.org              SSLHandshake failed: -9800 (errSSLProtocol)
www.cnet.com             Negotiated cipher:   0xC02F SUCCESS: TLS 1.2 negotiated
www.espn.com             Negotiated cipher:   0xC02F SUCCESS: TLS 1.2 negotiated
www.latimes.com          Negotiated cipher:   0xC02F SUCCESS: TLS 1.2 negotiated
www.usatoday.com         Negotiated cipher:   0xC02F SUCCESS: TLS 1.2 negotiated
www.google.com           SSLHandshake failed: -9824 (errSSLPeerHandshakeFail)
www.youtube.com          SSLHandshake failed: -9824 (errSSLPeerHandshakeFail)
www.wikipedia.org        SSLHandshake failed: -9824 (errSSLPeerHandshakeFail)
www.flickr.com           Negotiated cipher:   0xC02F SUCCESS: TLS 1.2 negotiated
www.expedia.com          SSLHandshake failed: -9824 (errSSLPeerHandshakeFail)
www.orbitz.com           SSLHandshake failed: -9824 (errSSLPeerHandshakeFail)
www.cnn.com              SSLHandshake failed: -9824 (errSSLPeerHandshakeFail)
www.amazon.com           Negotiated cipher:   0xC02F SUCCESS: TLS 1.2 negotiated
www.facebook.com         Negotiated cipher:   0xC02F SUCCESS: TLS 1.2 negotiated
www.disney.com           SSLHandshake failed: -9800 (errSSLProtocol)
 
Last edited:
@internetzel I got now:
  • Snow Leopard dyld does not load LC_LOAD_WEAK_DYLIB from dependent libraries (only from the main executable)
  • Direct binary patching with trampolines to external dylib requires the dylib to be loaded first — chicken-and-egg problem
  • Inline code injection requires restructuring the binary (growing __TEXT or finding cave space)
  • DYLD_FORCE_FLAT_NAMESPACE system-wide breaks the OS
What does work:

  • DYLD_INSERT_LIBRARIES + DYLD_FORCE_FLAT_NAMESPACE for individual processes
  • Direct linking (ssltest_direct)
@joevt Any thoughts?

Progress so far:​

libsecurity_ssl_tls12.dylib at /usr/local/lib/ contains the full TLS 1.2 SSL implementation (patched from Apple's libsecurity_ssl-55002 source) plus a __attribute__((constructor)) in tls12_patcher.c

When loaded into a process via DYLD_INSERT_LIBRARIES, the constructor runs after Security.framework is loaded, uses vm_protect to make Security's __TEXT pages writable, and writes 14-byte FF 25 absolute JMP trampolines at the entry of 31 SSL functions, redirecting them to the implementations.
Very nice!
Unfortunately, I do not remember those linking details, but you should look at the relinking script from Leopard WebKit and its Safari launcher as well; both apply some magic in order to launch with/relink against the updated Security framework.
But I remember there were some very interesting dyld mechanisms which were not yet supported in Leopard but maybe in Snow Leopard.
 
I would need to know the base versions of quite some Apple open source projects (mostly all those with "security" or "Security" in their name).
In the end it would not be necessary to "sneak" in the patched framework, but it could directly be provided with the "SnowLeopard-PowerPC distribution", right?
But maybe that sneaking would still be necessary ... all those nasty hacks needed for getting this to work ... basically the SSL/TLS levels need to be remapped to later versions because the API doesn't know the later versions ... and at least in Leopard the updated framework used to break the system keychain, that's why it had be sneaked in only where actually needed (Safari, Mail, ...)

Mostly everything of Frameworks in our 10.6.8 ppc should be from the actual 10.6.8 release (i.e. identical to whatever Apple Releases has), with exception of OpenGL, some part of CoreGraphics and perhaps WiFi/Bluetooth.

But I can verify whatever needed, of course.
 
Mostly everything of Frameworks in our 10.6.8 ppc should be from the actual 10.6.8 release (i.e. identical to whatever Apple Releases has), with exception of OpenGL, some part of CoreGraphics and perhaps WiFi/Bluetooth.

But I can verify whatever needed, of course.
Just for clarification on the project I work:

0.1a Architecture scope: x86_64 only — no PPC slice, no fat binary (and why “Snow-Leopard-on-PPC” doesn’t change that)​

A recurring question: can the patched libsecurity_ssl be built as a fat binary including a PowerPC slice, e.g. to target the community “Snow Leopard on unsupported PowerPC Macs” project? Short answer: no — not as one fat binary, and not against Security-55002. The reasons are structural, not a missing build flag.

1. There is no PPC Security-55002 to merge into. Retail 10.6.0–10.6.8 — the lineage Security-55002 belongs to — descends from the Intel-only Golden Master (Build 10A432). Apple did ship PowerPC-bootable Snow Leopard, but only as the 2008 Developer Previews(Build 10A96 / Darwin 10.0.0d1, and 10A190 / 10.0.0d2), whose kernels were compiled tri-architecture (i386 / x86_64 / ppc) with Universal-Binary userland carried over from Leopard 10.5.3. By Build 10A222 the Cocoa Finder went Intel-only; by 10A261 PPC booting was gone; the GM and everything after are Intel-only. So the PPC-capable Snow Leopard that exists runs a 2008-DP / Leopard-era Security, not the 55002 framework this worksheet targets. A ppc + x86_64 fat libsecurity_ssl.dylib would have a PPC half with no matching 55002 framework constellation (securityd / CDSA / keychain) to load against. (Source: the MacRumors “Clouded Leopard” WikiPost, thread 2232031.)

2. Snow Leopard itself is Intel-only at retail (§0.1). The whole merge is binary-confirmed against a live 10.6.8 x86_64 system (Security 55002.0.0). There is no retail PPC 10.6 to make a fat binary for.

3. This code is x86_64-specific in two concrete, already-in-tree ways — a PPC slice would miscompile or misbehave even if the toolchain produced one:

  • Hard-coded 64-bit libcrypto struct offsets. The RSA encrypt fallback in sslKeyExchange.c reaches into OpenSSL 0.9.8’s rsa_stat RSA_OFFSET_N = 32 / RSA_OFFSET_E = 40 — those are 64-bit-pointer offsets. On 32-bit PPC (all G4, and G5 in practice) the pointers are 4 bytes and the field layout differs, so those writes land wrong and corrupt the struct. The GCM AES bridge similarly hard-sizes the “244-byte 0.9.8 AES_KEY.” These dlsym-and-reach-into-internals hacks (RSA encrypt, ECDH, ECDSA verify) would each need offsets re-derived for the target’s actual libcrypto.
  • Little-endian-validated GCM core. sslGcm.c’s GHASH / counter-block / AAD byte assembly was KAT-checked (NIST SP 800-38D) on little-endian x86_64. PPC is big-endian, so that byte handling needs an endianness audit before the vectors pass.
What a real PPC TLS-1.2 port would be. Not -arch ppc on this build, but a sibling port: target 10.4/10.5 (or the 10A96/10A190 DP userland), merge against the Leopard Security sources (§0.2 — the Leopard-WebKit effort already produced a TLS-1.2 Security.framework for 10.5, which is precisely not binary-compatible with 10.6), replace the libcrypto offset hacks with proper API calls or re-derived 32-bit offsets, and re-validate GCM big-endian. “One framework for my Intel and my PPC vintage Macs” is therefore two builds for two OSes, not one fat binary — because the OSes don’t overlap on architecture.
 
Just for clarification on the project I work:

This first part is just wrong. It is true that 10.6.8 release cannot boot on powerpc, but completely irrelevant to the matter. The kernel which is used now (by us) is that of 10.6.8 release, and this holds for most of the system (arguably everything relevant to the context: Finder is not).

The second part seems speculative. OpenSSL worked and works on 32-bit ppc. Also, it is hardly the case that anything important in SL could not work on 32-bit, since it natively supports i386. Finally, it is certainly possible either to adjust offsets, if they are wrong, or take them into account so that the code works.

The only hard blocker would be an irreplaceable closed-source component without ppc slice.
 
This first part is just wrong. It is true that 10.6.8 release cannot boot on powerpc, but completely irrelevant to the matter. The kernel which is used now (by us) is that of 10.6.8 release, and this holds for most of the system (arguably everything relevant to the context: Finder is not).

The second part seems speculative. OpenSSL worked and works on 32-bit ppc. Also, it is hardly the case that anything important in SL could not work on 32-bit, since it natively supports i386. Finally, it is certainly possible either to adjust offsets, if they are wrong, or take them into account so that the code works.

The only hard blocker would be an irreplaceable closed-source component without ppc slice.
Does the "Snow Leopard on PPC" target actually run the 55002-era Security userland (securityd/CDSA/keychain) on its PPC kernel?
 
Does the "Snow Leopard on PPC" target actually run the 55002-era Security userland (securityd/CDSA/keychain) on its PPC kernel?

Ok, I checked, on my SL the Security framework itself is from 10.6.3 (36910). Or at least that’s what version says.

55002 shows up only in 10.6.8 release (10.6.7 has 37594).

10.5.8 has 36371.

So no, we do not have 55002 at the moment, but we do have a version matching 10.6.3.

Specific components need to be checked. If everything is open source, it should be rebuildable. I don’t know out of my head why exactly 10.6.3 one was picked over, say, 10.6.7 or 10.6.8.
 
Ok, I checked, on my SL the Security framework itself is from 10.6.3 (36910). Or at least that’s what version says.

55002 shows up only in 10.6.8 release (10.6.7 has 37594).

10.5.8 has 36371.

So no, we do not have 55002 at the moment, but we do have a version matching 10.6.3.

Specific components need to be checked. If everything is open source, it should be rebuildable. I don’t know out of my head why exactly 10.6.3 one was picked over, say, 10.6.7 or 10.6.8.
Beyond re-merging the SSL source changes against 36910:

  1. Re-derive the libcrypto struct offsets. This project hard-codes 64-bit-x86 values (RSA_OFFSET_N = 32, RSA_OFFSET_E = 40; the 244-byte 0.9.8 AES_KEY). On 32-bit PPC the pointer sizes and field layout differ, so those offsets are wrong and must be re-derived for the target's libcrypto. (Cleaner still: let the compiler compute them from the real struct definition rather than hard-coding numbers.)
  2. Endianness audit of the GCM core. GHASH / counter-block / AAD byte assembly was KAT-validated (NIST SP 800-38D) on little-endian x86_64. PPC is big-endian; the byte handling needs an endianness pass before the vectors pass. ("SL supports i386" does not address this — i386 is also little-endian; PPC is the only big-endian target in scope.)
  3. The monolith would be Security-36910, so the system-default relink spec captured for this project (the 4446-symbol parity set, the subproject set, install name / version 55002.0.0) is 55002-specific and would differ for 36910.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.