Linking OpenSSL for the iOS Simulator (1.0.2a)

Intro§

I've been doing some work with a fair amount of crypto for an my upcoming application. Now as you all probably know, the go-to for doing any crypto is with OpenSSL. I'm not much of a hipster, so I immediately went with that.

The Good§

x2on's OpenSSL-for-iPhone is an excellent tool of convenience. It downloads the latest version of OpenSSL, builds both libssl and libcrypto for all available architectures and glues all slices into one universal library each. It even comes with a script to generate openssl.framework from the resulting libraries.

The Bad§

The resulting framework runs great on any device, sadly, the linker just didn't want to link for the simulator. The linker spewing:

Undefined symbols for architecture x86_64:
  "_OPENSSL_ia32cap_P", referenced from:
      _AES_cbc_encrypt in openssl(aes-x86_64.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I was at a complete loss, as I hadn't referenced anything of the like. In my code at least. But a bit more digging revealed the culprit.

And the de-uglyfied§

It turns out this is a bug in the generated code for x86_84. The linker doesn't know that the _OPENSSL_ia32cap_P external symbol needs to be linked in from x86_64cpuid.o.

We can force this by referencing another method that's in x86_64cpuid.o, like OPENSSL_cleanse(void *, size_t). I did like so:

#if TARGET_IPHONE_SIMULATOR
    // this is just so openssl links properly.
    extern int OPENSSL_cleanse(void *ptr, size_t len);
    OPENSSL_cleanse(nil, 0);
#endif

Pasting the following anywhere in your code (that won't be discarded by compiler optimizations) should work.

The End?§

I'm hoping that this will get resolved in the future. If not as a mainline release, then at least as a publicly available patch. But until then, I guess we're stuck with this.


Comments