RIPE 86 - Rotterdam Trip Notes
Five of us from ISC attended the RIPE 86 meeting in Rotterdam, May 22 - 26, 2023.Read post
The first time someone writes (or contributes to, so this does not apply only to first systems) an application using low-level cryptography, (s)he has a choice among two bad and two very bad solutions. This blog explains the reasons of this recurrent disaster and tries to give some suggestions to avoid it…
The worst possible solution is of course to build a new crypto implementation from scratch. Not only is it a very long task, but there are a lot of critical details which are not easily managed by newcomers; for instance, when generating RSA keys, it is not enough to get two prime numbers of the right size (e.g., if you get two consecutive primes, and there are an infinite number of such pairs, the two primes can be incredibly easily recovered from their product). Note this is specified in the relevant NIST document (and similar documents); it is just not enough to have a big integer library to build a good RSA implementation.
The second worst solution is to use a bad crypto library. Note here I am a bit high church about what I call bad; according to my personal criteria a crypto implementation is bad when it was not designed for a strong security usage. For instance:
So the choice is between a solution which supports crypto hardware (i.e., PKCS#11) or a solution which works well in software (i.e., OpenSSL):
What to do now? The software solution is a dead end unless one is sure no HSM will ever be used. There are at least 3 reasons to get crypto hardware someday: first, hardware is considered to be intrinsically more secure, so it will be required in some environments; second, there are situations where hardware is better, for instance random number generators (by definition a software random generator is a pseudo-random one) and key store protection; and finally, in some usages (and without a security risk analysis to support it) one believes a HSM is an essential part of the security.
So the right thing is to begin with PKCS#11. This adds some constraints (unique initialisation, sessions, separated sign/verify contexts, etc.) but IMHO most of these constraints could lead to better code. For instance, I believe a unified sign/verify context (vs. different context types for sign or verify) is a bad design; it ignores the difference between a public and a private key. The next step is to make the interface more generic so one can plug any crypto provider, PKCS#11, or software library (any library as soon as a good one is supported). A way to do this is to squeeze the PKCS#11 handling in the SoftHSMv2 implementation, so you finish with a code working with PKCS#11, or the Botan and OpenSSL backends of SoftHSMv2. Another benefit is that the code can be improved to accept a FIPS 140-2 certified crypto following the required Guidelines, so it can claim to use an embedded FIPS 140-2-validated cryptographic module running per FIPS 140-2 Implementation Guidance section X.Y guidelines.
What's New from ISC