Concealing keys (not even in NSS)

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Concealing keys (not even in NSS)

Rick van Rein (OpenFortress)
Hi,

I've looked into the mechanism for configurable crypto backends and in
particular the NSS backend, which is close to PKCS #11.

What I like about PKCS #11 is that it can conceal keys from the libkrb5
library, and thereby from the application's reachable memory.  This is
not how the NSS crypto backend is made, I found -- keys are imported
into NSS as (session) keys and used there.  If FIPS is enforced, it will
fake its patterns by unwrapping a key that was wrapped just for that sake.

This seems to me like a missed opportunity.  Am I mad to think that a
crypto backend could choose any krb5_keydata representation, and that a
pkcs11: URI [RFC7512] would be fine?  It looks like the surrounding
libkrb5 treats the keys as literals and always invoke krb5_k_decrypt()
and _encrypt() after expanding the key to an opaque krb5_key after
krb5_k_create_key() and before krb5_k_free_key(), right?

This does seem to be possible -- but how do others feel about this?


Cheers,
 -Rick
________________________________________________
Kerberos mailing list           [hidden email]
https://mailman.mit.edu/mailman/listinfo/kerberos
Reply | Threaded
Open this post in threaded view
|

Re: Concealing keys (not even in NSS)

Greg Hudson
On 09/20/2016 01:42 AM, Rick van Rein wrote:
> This seems to me like a missed opportunity.  Am I mad to think that a
> crypto backend could choose any krb5_keydata representation, and that a
> pkcs11: URI [RFC7512] would be fine?  It looks like the surrounding
> libkrb5 treats the keys as literals and always invoke krb5_k_decrypt()
> and _encrypt() after expanding the key to an opaque krb5_key after
> krb5_k_create_key() and before krb5_k_free_key(), right?
>
> This does seem to be possible -- but how do others feel about this?

It might be possible for some keys, and we'd like to get there
eventually.  But here are some obstacles to think about:

* Ephemeral keys (ticket session keys, initiator and acceptor subkeys)
are generated randomly by one party and sent to the other inside an
encrypted message.  Do we extend the protocol so that these keys can be
wrapped in parent keys within the encrypted messages, or do we decide
that the problem only applies to long-term keys?  Is it important to
solve the problem for ticket session keys, since they can remain valid
for hours or days?

* Server keys are shared between the KDC and the server keytab.  How can
these be provisioned so that both parties know them?  Is it okay for
these to pass through application memory when they are provisioned, if
they are hidden from application memory after that?

* For traditional password-based AS-REQs, client keys are generated by
string-to-key on the password.  How can this be done without making
either the password or the resulting key visible to kinit?  (For PKINIT,
PKCS #11 can already be used for the certificate private keys.)

* Should the KDC store every long-term key as a reference to a PKCS #11
device?  Should it store wrapped keys in the regular database?  Is it
sufficient for just the master key to be behind a PKCS #11 device, so
that the existing database format can be preserved at the cost of
letting long-term keys pass through KDC application memory?  How does
propagation of keys work across multiple KDCs within a realm?  How does
master key rollover work?

All of those concerns are on top of the historical APIs and data formats
(ccaches, keytabs) which assume that keys are just bit strings.  Changes
to the crypto library would comprise only a tiny part of the solution.
________________________________________________
Kerberos mailing list           [hidden email]
https://mailman.mit.edu/mailman/listinfo/kerberos
Reply | Threaded
Open this post in threaded view
|

Re: Concealing keys (not even in NSS)

Michael Ströder
Greg Hudson wrote:
> Is it sufficient for just the master key to be behind a PKCS #11 device, so
> that the existing database format can be preserved at the cost of letting
> long-term keys pass through KDC application memory?

IMO yes.

Ciao, Michael.


________________________________________________
Kerberos mailing list           [hidden email]
https://mailman.mit.edu/mailman/listinfo/kerberos

smime.p7s (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Concealing keys (not even in NSS)

Rick van Rein (OpenFortress)
In reply to this post by Greg Hudson
Hi Greg,

You're as thorough as always :)

> * Ephemeral keys (ticket session keys, initiator and acceptor subkeys)
> are generated randomly by one party and sent to the other inside an
> encrypted message. Do we extend the protocol so that these keys can be
> wrapped in parent keys within the encrypted messages, or do we decide
> that the problem only applies to long-term keys? Is it important to
> solve the problem for ticket session keys, since they can remain valid
> for hours or days?
>
Long-term keys are definately the most important; but one might argue that
any (derived) krbtgt is pretty powerful and could/should be protected.  I
suppose things get unpractical below that, and could crowd out tokens [1].
Session keys could be used, or the keys for service tickets might be
treated as they are now.

If we were thinking of PKCS #11 we would probably have to specify new
CKM_KRB5_xxx methods.  These would incorporate the key usage number as a
parameter, with a number of benefits:
 1. we can clearly see where the cut-off is going to be
 2. we could do a some sanity checking on the plaintext data
 3. we can use plain symmetric keys, possible annotated with CKA_KRB5_xxx
 4. we cannot use non-Kerberos CKM_ mechanisms and get the same results
 5. we might store a new key handle in a pointer of a method parameter

This would imply extending PKCS #11; this might not be impossible,
especially
if we started with a vendor-specific extension.  An initial implementation
in SoftHSMv2 is a way to get started with this.  Wrap a remote-PKCS #11
mechanism around that and you've got isolation between application and keys.

> * Server keys are shared between the KDC and the server keytab. How can
> these be provisioned so that both parties know them? Is it okay for
> these to pass through application memory when they are provisioned, if
> they are hidden from application memory after that?
>
One of my reasons for looking into this is to get an understanding of places
where we need ECDH for Kerberos itself :)

In terms of PKCS #11 we might also think about wrapping and unwrapping keys.
This is usually how keys are shared between replicated HSMs, for instance.

> * For traditional password-based AS-REQs, client keys are generated by
> string-to-key on the password. How can this be done without making
> either the password or the resulting key visible to kinit? (For PKINIT,
> PKCS #11 can already be used for the certificate private keys.)
>
I suppose when the initial key isn't on PKCS #11, the keys derived could
all stay outside of it?  I suppose another way around it is to generate a
key on PKCS #11 [share it through wrap/unwrap] and have all the AS handling
done inside of PKCS #11 -- which I why I was so bold to think of our own
CKM_KRB5_xxx mechanisms.

> * Should the KDC store every long-term key as a reference to a PKCS #11
> device? Should it store wrapped keys in the regular database? Is it
> sufficient for just the master key to be behind a PKCS #11 device, so
> that the existing database format can be preserved at the cost of
> letting long-term keys pass through KDC application memory? How does
> propagation of keys work across multiple KDCs within a realm? How does
> master key rollover work?
>
IMHO, I don't really care for the KDC.  It is a well-protected, trimmed-down
machine, and even beats PKCS #11 in being more aware of the application.
Storing the KDC-side keys in PKCS #11 does not seem as important to me as
on the client.

As for key propagation, my naive thinking is to use the same mechanisms as
client's KDC-REP handling?  Meaning, whenever a response is encrypted with
a PKCS #11 protected key, it would ask PKCS #11 to decrypt, annotated with
the key usage number and so retrieving whatever PKCS #11 deems proper -- be
it a key in plain sight or a reference to another key protected by PKCS #11
-- and that mechanism could also work between KDCs?

> All of those concerns are on top of the historical APIs and data formats
> (ccaches, keytabs) which assume that keys are just bit strings. Changes
> to the crypto library would comprise only a tiny part of the solution.

This is what I've been looking into, and it would be difficult indeed.  One
approach might be to introduce a special magic number of krb5_keyblock to
signal that the contents are really a reference to something like PKCS #11
(through a PKCS #11 URI) instead of the usual literal key.

I had the impression that all the hard work was done in the crypto backends,
and that they key itself was not actually handled in other places, but at
best copied.  Is that not true?  Even the credential caches appear to just
handle literal data that the _store_ and _cursor_ through?


I realise this is a big one... and I cannot really estimate how many
assumptions are twined into the code -- the design is generally very nice
and orthogonal, so I was hoping it might be doable.

FWIW, I've already had a bit of success extending PKCS #11 locally, and
got the chances embedded in SoftHSMv2, from which I hope it will spread,
http://openfortress.nl/doc/spec/pgp-in-pkcs11/
and I wouldn't mind writing up another one of those for Kerberos.


Sorry to stir up a hornet's nest ;-)

-Rick


[1] It is not uncommon for USB tokens to store only 32 kB of keys;
    it is not uncommon for high-end HSMs to be very slow doing
    C_FindObjectsXXX() on hundreds of keys.  Both could be resolved
    with off-chip storage using C_WrapKey() and C_UnwrapKey().

________________________________________________
Kerberos mailing list           [hidden email]
https://mailman.mit.edu/mailman/listinfo/kerberos