Discussion:
PKCS#11 vs OpenSSL (BIND Future Development Question)
Ondřej Surý
2018-06-04 08:33:20 UTC
Permalink
The PKCS#11 interface is very fragile, as the different vendors implement different parts of the
standard, and BIND needs to be compiled with a specific PKCS#11 provider defined at the
compile time. This is certainly suboptimal, and we are looking at ways how to improve that.
My understanding was that you had to choose at compile time wether you
needed PKCS#11 or OpenSSL, and that, even if you could link with a
specific provider during the build, you could opt-out and start named
with -E /path/to/engine.so. At least, it is the way it is done in the
FreeBSD ports tree.
That’s only sort of true, see lib/isc/include/pk11/README.site for more detailed description,
but there are some HSMs that need compile time flags in site.h, and the default is

/* Default is for Thales nCipher */
#ifndef PK11_FLAVOR
#define PK11_FLAVOR PK11_THALES_FLAVOR
#endif

#if PK11_FLAVOR == PK11_THALES_FLAVOR
#define PK11_DH_PKCS_PARAMETER_GEN_SKIP
/* doesn't work but supported #define PK11_DSA_PARAMETER_GEN_SKIP */
#define PK11_MD5_HMAC_REPLACE
#endif

So, even if you can specify a runtime PKCS#11 library, it doesn’t mean it will work
as expected.

To my best understanding, if we keep only the Public-Key crypto for PKCS#11,
there’s only one parameter that will need tuning PK11_RSA_PKCS_REPLACE
and we could either declare that the HSM must support EMSA-PKCS#1-v1.5
or turn that into runtime detection (as this would be the only workaround that
we would need to keep).

Ondrej
--
Ondřej Surý
***@isc.org

_______________________________________________
Please visit https://lists.isc.org/mailman/listinfo/bind-users to unsubscribe from this list

bind-users mailing list
bind-***@lists.isc.org
https://lists.isc.org/m
Timothe Litt
2018-06-03 13:13:15 UTC
Permalink
Hi all,
BIND 9 currently supports two major cryptography provider libraries - OpenSSL[1] and PKCS#11.
The PKCS#11 interface is very fragile, as the different vendors implement different parts of the
standard, and BIND needs to be compiled with a specific PKCS#11 provider defined at the
compile time. This is certainly suboptimal, and we are looking at ways how to improve that.
So, if you are running BIND with PKCS#11 HSM, or you are thinking about such setup,
1. What functions of PKCS#11 do you care
1a) getting entropy?
1b) message digests?
1c) HMAC?
1d) symmetric crypto (meaning AES)
1e) public-key cryptography (aka DNSSEC keys)
(Background: PKCS#11 as currently used in BIND uses PKCS#11 exclusively
for anything related to crypto.)
2. Would you be fine if BIND double linked with OpenSSL and PKCS#11?
(Background: if some of the answers to previous question were NO, BIND would
have to use OpenSSL as a provider for these functions and it would make
the code more slimmer, and easier to test.)
3. Would you care if BIND wouldn’t link directly to PKCS#11 library and used
OpenSSL engine: https://github.com/OpenSC/libp11#openssl-engines
(Background: the PKCS#11 is full of #ifdefs, for full picture see [1], and it
doesn’t really make sense to develop the same work-arounds at two different
places.)
~~~
1. Convert the PKCS#11 usage to OpenSSL PKCS#11 engine. That would
save us from most of the headaches with PKCS#11, but it might require some
configuration changes for existing deployments.
2. Convert the non public-key cryptography parts to OpenSSL. This would
allow people to keep the DNSSEC private keys inside the HSMs, but all
the other crypto would come from OpenSSL. (OpenSSL itself has FIPS
140-2 validation if that means anything to you.)
3. Keep the status quo
A. Improve the PKCS#11 handling to runtime detection of HSM capabilities
B. Support OpenSSL and PKCS#11 DNSSEC keys at the same time, say
to store KSKs in PKCS#11 and ZSK on disk...
The A is non-issue for 1., likely to happen with 2., and unlikely to happen with 3.
The B will happen with 1., likely to happen with 2., and impossible to happen with 3.
As usual, the goal is to balance the time we have to spend on improving BIND,
and our development resources are limited, so any resources saved by reducing
the code we need to maintain would free our hands to do something else (like A or B).
Also please note that this is not going to affect any previously released version of BIND,
just future releases.
1. https://gitlab.isc.org/isc-projects/bind9/blob/master/lib/isc/include/pk11/site.h
2. https://www.openssl.org/docs/fips.html#background
Ondrej
--
Ondřej SurÃœ
With the caveat that I don't currently use PKCS#11 with BIND:

#1 - use OpenSSL's engine seems the most reasonable.  Puts most of the
maintenance burden on them.
        Perhaps you can have a script that recommends the necessary
configuration changes - presumably
        this is a one-time thing.

It seems to me that the biggest pain for users is having to compile
against a specific provider. This makes life hard for packagers (and end
users who compile bind).  If nothing else, it would be useful to (I
guess this is option 4):
 a) specify the provider at runtime - e.g. load the right DLL
 b) be able to separately compile that (those) dll(s) for whatever
provider, generating a unique name.
      This would allow packagers to pre-compile whatever set of
providers their customers want, and
      allow specifying which one in the config file.  It would be
minimal change to your code - mostly Makefile
      magic.  Essentially, the BIND version of OpenSSL engines...

      Put another way: in configure one does something like
--build-pkcs11=(hsm1, hsm2, hsm3, softhsm, ...)
      and you get hsm1.so, hsm2.so, hsm3.so, softhsm.so ... and a BIND
that knows how to load/call whichever
      one is loaded, but no provider-dependent code.  Then the bind
config file has 'pkcs11-provider "hsm2";'

      The BIND code -with whatever ugliness - remains unchanged until,
and unless you decide to refactor it.
       That could be incremental - and transparent to users.

       In fact, one of the providers could be OpenSSL (or its engines)
under a BIND interface wrapper...

       Also, this is a static choice - not "runtime detection of
capabilities".  You could do that eventually, of course, as
       part of refactoring to consolidate some/all of the libraries. 
But the end user just configures one
       name for his/her provider.  The idea is to keep things simple -
for the user, and for development.

      On the other hand, if I have multiple machines with different
providers, I don't have to compile
      a unique BIND for each.  I build it once with (at least) the union
of all the required providers, and
      deploy the same image everywhere.  Better yet, with luck my
distribution ships with all the provider libraries that I need, and I
don't compile anything!  The config file is the only variant.

So, if you can switch to OpenSSL, it seems the best long-run option.  If
you can't, (or are encouraged not to by other customers), you could
solve a lot of the customer pain by making the provider loadable.

For entropy, I use a mixture of USB keys and CPU hardware generators. 
As I may have mentioned, I use EntropyBroker to distribute the entropy
securely - this keeps cost reasonable, especially with many VMs (some of
which don't naturally generate a lot of entropy...).  See
https://www.vanheusden.com/entropybroker/ &
https://github.com/flok99/entropybroker. 

Hope this helps.


Timothe Litt
ACM Distinguished Engineer
--------------------------
This communication may not represent the ACM or my employer's views,
if any, on the matters discussed.

Loading...