OpenSSL on Oracle Solaris 11.2
By Misaki Miyashita -Oracle on May 06, 2014
I'm sure you all wonder which version of OpenSSL is delivered with Oracle Solaris 11.2?
The answer is the latest and greatest OpenSSL 1.0.1h!
Now that I answered 80% of the questions you may have with regard to OpenSSL, I would like to announce three major features added to the Oracle Solaris 11.2 which I'm sure you'll all be excited to hear :-)
Inlined T4/T4+ instructions support and Engines
Background: S11.1 and earlierYears and years ago, I worked on the SPARC T2/T3 crypto drivers. On the SPARC T2/T3 processors, the crypto instructions are privileged; and therefore, the drivers are needed to access those instructions. Thus, to make use of T2/T3 crypto hardware, OpenSSL had to use pkcs11 engine which adds lots of cycles going through the thick PKCS#11 session/object management layer, Solaris kernel layer, hypervisor layer to the hardware, and all the way back. However, on SPARC T4/T4+ processors, crypto instructions are no longer privileged; and therefore, you can access them directly without drivers. Valerie Fenwick has a nice article explaining the lower level specifics of the T4 hardware.
What does that means to you? Much improved performance! No more PKCS#11 layer, no more copy-in/copy-out of the data from the userland to the kernel space, no more scheduling, no more hypervisor, NADA! As much as I enjoyed working on the crypto drivers, I'm happy to see this driver-less transition! ;-)
Dan Anderson has a great blog entry describing the difference between the T3 and T4 based hardware. As he described, on Solaris 11 and 11.1, we made the T4 instructions available to OpenSSL via OpenSSL engine mechanism. It was great for the time being, but to make T4 instruction support available directly from the OpenSSL website and to even bypass the engine layer all together, I was assigned to assassinate the t4 engine (Sorry, Dan) and make T4 instructions embedded to the OpenSSL's internal crypto module (a.k.a adding inlined T4 instruction support).
S11.2 and beyond
As I was learning how OpenSSL development worked, I learned OpenSSL
upstream engineers had already committed the inlined T4 instruction
support to the OpenSSL 1.0.2 branch. (Thanks for making my life easier,
OpenSSL team!) I was job-less for a second, but since OpenSSL 1.0.2 won't be available in time for Solaris 11.2 delivery, we decided to patch the
inlined T4 instruction support to our OpenSSL 1.0.1g delivery bundled
with Solaris 11.2.
With this change, you'll get the T4/T4+ instruction support without engines; and therefore, you get as great performance as the t4 engine and even better performance for some algorithms (i.e. SHA-1, MD5) by default.
Oracle Solaris 11.2 killed not only the t4 engine, but also the aesni engine and the devcrypto engine. The story for the aesni engine is pretty much similar to the one for the t4 engine. It was introduced in Solaris 11 as Dan Anderson described in his article, and killed in Solaris 11.2. AES-NI instruction support is now embedded in the OpenSSL upstream implementation (OpenSSL 1.0.1); and therefore, the separate engine is no longer needed. The devcrypto engine was removed simply due to the lack of use.
With all this change, Oracle Solaris 11.2 OpenSSL is left with the one and only pkcs11 engine. pkcs11 engine is still necessary on the T2/T3 platforms and on any platform with the hardware keystore (i.e. SCA 6000). However, be sure to leave the pkcs11 engine disabled on T4/T4+ if you want max performance. Again, I would like to emphasize that the OpenSSL performance on T4/T4+ platforms are looking MUCH better compared to the one on T2/T3 platforms! It's time to move onto T4/T4+ platform, Y'all!!
OpenSSL FIPS-140 version support
It is important for many federal and financial service customers to have their cryptographic products being FIPS-140 validated. Oracle Solaris Cryptographic Framework recently achieved a FIPS 140-2 validation(yay!!), and it was very important to deliver the FIPS-140 validated OpenSSL with Solaris 11.2.
At the time Solaris 11 was released, OpenSSL 1.0.0 was the latest OpenSSL version available, and since OpenSSL 1.0.0 was not FIPS-140 validated, we only delivered non-FIPS-140 version of OpenSSL with Solaris 11.
Thanks to the OpenSSL upstream team (again), the best and greatest OpenSSL 1.0.1 can be compiled with a FIPS-140 validated module, and we are now delivering the FIPS-140 version of OpenSSL in addition to the non-FIPS-140 version of OpenSSL with Solaris 11.2.
When do you want to use FIPS-140 version of OpenSSL?
It's probably important to mention that the FIPS-140 version of OpenSSL is not for everybody. The FIPS-140 validated version of cryptographic products come with a price tag. Enabling FIPS-140 mode adds a lot of cycles to satisfy the FIPS-140 verification requirement (i.e. POST, pair-wise consistency test, contiguous RNG test, etc) at run time. In addition, inlined T4/T4+ instruction support is not available in the FIPS-140 version of OpenSSL, and you won't get the best performance when the FIPS-140 mode is enabled.
That said, I would recommend you to enable FIPS-140 mode *only if* you need to. The good news is that you will get the FIPS-140 compatible implementation even when the FIPS-140 mode is disabled. It's just that it runs much faster!
That's one of the reasons why non-FIPS-140 version of OpenSSL is activated by default.
How to enable FIPS-140 version of OpenSSL
If you decided to enable FIPS-140 mode, here is how you can switch to the FIPS-140 version of OpenSSL.
Make sure you have the FIPS-140 version of the OpenSSL installed on the system.
# pkg mediator -a openssl
MEDIATOR VER. SRC. VERSION IMPL. SRC. IMPLEMENTATION
openssl vendor vendor default
openssl system system fips-140
To activate the fips-140 implementation
# pkg set-mediator -I fips-140 openssl
To check the currently activated OpenSSL implementation
# pkg mediator openssl
To change back to the default (non-FIPS-140) implementation
# pkg set-mediator -I default openssl
OpenSSL Thread and Fork Safety
OpenSSL provides an interface CRYPTO_set_locking_callback() for you (any application or library) to set your own locking callback function with the mutexes of your choice.
That sounds reasonable if the OpenSSL library is used only by applications. However, when the OpenSSL library is used by another library, such design is asking for trouble.
We've seen a case where an OpenSSL application used a library which set a locking callback function, and the library got unloaded while the application continued using the OpenSSL library. The application got a segfault because OpenSSL tried to reference the invalid locking callback function set by the unloaded library. Whose fault is this?
You can argue that the library should have set the locking callback to NULL when it was unloaded.
Well, not quite. Once the locking callback is set to NULL, the application is no longer thread-safe.
OpenSSL needed some changes to make applications and libraries thread and fork safe.
To fix this issue, the OpenSSL library (libcrypto.so) delivered with Solaris 11.2 sets up mutexes and a locking callback internally, and it ignores an attempt to set/change the locking callback.
What does that mean to you?
OpenSSL is now thread and fork safe by default. You don't need to make any modification to your application nor library. You can relax and have a margarita or two.
That's all I have for now.
Note: The version number delivered with Solaris 11.2 was updated from 1.0.1g to 1.0.1h on Jun 05, 2014. OpenSSL version 1.0.1g was delivered with Solaris 11.2 Beta.