[gnutls-devel] session ticket key rotation

Nikos Mavrogiannopoulos nmav at gnutls.org
Mon Nov 14 17:47:03 CET 2016


On Mon, Nov 14, 2016 at 3:57 PM, Daniel Kahn Gillmor
<dkg at fifthhorseman.net> wrote:
> Hi Nikos--
>> The tricky part would be making the rotate function semantics easy to
>> use, even in multi-threaded environments, and allow efficient access
>> to keys at the same time. You wouldn't want a multi-threaded server to
>> hold a lock in order to access a ticket key.
>
> Is the problem the expense of taking a read lock itself, or is the
> problem a risk of uninitialized memory access?
>
>> That's not an easy goal to achieve; something similar using atomic
>> variables of C11 (with fallback) was done in gnutls_rnd() (see
>> random.c and  _gnutls_rnd_init).
>
>  Is it possible that it doesn't matter?  Consider the following (very
>  rough) implementation (error checking omitted for concision):
>
>      1     typedef char[SESTKTKEYLEN] _session_ticket_key;
>      2
>      3     struct gnutls_ticket_key_pool_int {
>      4            int numkeys;
>      5            _session_ticket_key *keys;
>      6            int current_key;
>      7     }
>      8
>      9     int gnutls_ticket_key_pool_init(gnutls_ticket_key_pool_t *pool, int numkeys) {
>     10         *pool = malloc(sizeof(gnutls_ticket_key_pool_int));
>     11         (*pool)->numkeys = numkeys;
>     12         (*pool)->keys = malloc(sizeof(_session_ticket_key) * numkeys);
>     13         (*pool)->current_key = 0;
>     14         gnutls_rnd(GNUTLS_RND_KEY, (*pool)->keys, sizeof(_session_ticket_key) * numkeys);
>     15
>     16     }
>     17     int gnutls_ticket_key_pool_rotate(gnutls_ticket_key_pool_t pool) {
>     18        _session_ticket_key newkey;
>     19        gnutls_rnd(GNUTLS_RND_KEY, newkey, sizeof(newkey));
>     20        int newkeyidx = (pool->current_key + 1)%pool->numkeys;
>     21        memcpy(pool->keys[newkeyidx], newkey, sizeof(newkey));
>     22        pool->current_key = newkeyidx;
>     23     }

One question is whether we would like the key_pool_rotate to protect
from parallel calls of the same function, or from calls with small
time difference.

> if someone offers a session ticket that belongs to the oldest keyslot
> (the one that's about to be overwritten), and the crypto code that
> accesses it to decrypt the ticket is in use during the memcpy on line
> 21, what's the worst that could happen?

What about CPUs where writing to a memory location is not an atomic
operation... i.e., if on line 22, some reader instead of getting the
old or the new value of pool->current_key, gets some intermediate
value? Are these of a concern?

>> The change in semantics by that would be that the credentials
>> structure would no longer hold only read-only data. However, if the
>> rotation is transparent for all types of applications, I have no
>> objection on that.
> What different kind of application types should i be concerned about
> that might behave differently?

I cannot think of any.

regards,
Nikos



More information about the Gnutls-devel mailing list