Subject: [ntpwg] Authentication issues for control messages

From: "Ulrich Windl" <[email-masked]>
Date: Fri, 17 Feb 2017 11:30:49 +0100

Hello!

I had written a tool (in Perl) to query ntpd via mode 6 control requests (and mode 3 client requests) when I decided to implement authentication (MAC).
The first issue is the lack of proper specification of the MAC. I wanted to implement symmetric MD5 keys only, but even that showed to be poorly specified:
>From the specification there is no limit on the key length. In NTPv3 the key type was DES (64 bits for secret and digest it seems), but with MD5 keys the length of the secret seems variable, while the digest is 16 octets. It seems the documentation for ntp.keys mixes key sizes and digest sizes, because it claims "The key is 1 to 16 printable characters" for MD5. Likewise, RFC5095 talks about "designate a secret 128-bit MD5 key". The algorithm however seems to handle any secret size (although practical reasons forbid huge sizes). Looking at the source of ntpd, it seems the key size is limited by the internal representation of the keychain.

Anyway, my code tho check the MAC finally came out as this:

sub check_MAC($$$)
{
    my ($self, $MAC, $data) = @_;
    my $result = 0;
    my $keyid = $self->MAC_KeyID($MAC);
    my $key = $self->ID($keyid);

    if ($key && $key->Type() == AuthKey::KT_MD5) {
        my $keyval = $key->Value();
        my $ctx = Digest::MD5->new;

        $ctx->add($keyval, $data);
        $result = $ctx->digest() eq MAC_Digest($MAC);
    } elsif ($keyid == 0 && length(MAC_Digest($MAC)) == 0) {
        # 'crypto-NAK'
        $result = 1;
    } else {
        # "Unknown MAC KeyID $keyid" unless zero
    }
    return $result;
}

And the code to create a MAC is this:

sub MAC($$$)
{
    my ($self, $keyid, $data) = @_;
    my $key = $self->ID($keyid);
    my $result = '';

    if ($key && $key->Type() == AuthKey::KT_MD5) {
        my $keyval = $key->Value();
        my $ctx = Digest::MD5->new;

        $ctx->add($keyval, $data);
        $result = pack('N', $key->ID()) . $ctx->digest();
    } elsif ($key) {
        # 'Unsupported key type', $key->Type(), 'for ID', $keyid
    } else {
        # "Missing key for ID $keyid"
    }
    return $result;
}

What I tried next was to query ntpd 4.2.8p9 using request packets with a MAC. The result was from confusing to inconsistent (the documentation is _very_ vague on these issues). For example RFC5095 just says: " While the NTPv3 symmetric key authentication scheme described in this document has been carried over from NTPv3, the Autokey public key authentication scheme new to NTPv4 is described in [RFC5906]."

My expectation was that authenticated requests were answered by authenticated responses, and (possibly) that non-authentic requests (unknown keyID od bad Digest) were ignored by ntpd. Obviously that is not the case:

A mode=6 op=2 request (read variables) never had a MAC, independent of the request having an unknown key, an untriusted key or a trusted key in use.
A mode=6 op=1 request (read status)  however attached a crypto-NAK for an unknown key, for an untrusted key, and for a trusted key. I was surprised that it happened for a trusted key also (assuming that my code to create the MAC is OK).
A mode=3 query returned the expected results: crypto-NAK for unkown keyID and untrusted key; a valid MAC for a trusted key, and no MAC for requests without a MAC.

What I'd like to see for a future NTP version is these:

Bring control packets in line with time queries, that is: Send authenticated responses to authenticated requests, and allow to discard non-authenticated requests. Whenever responding to unauthenticated requests, the response should add a crypto-NAK. This may requre the control messages to know of two types of keys instead of one type (similar to SNMP's read and write communities): A set of keys to trust for requesting information (read), and a set of keys to trust for changing the configuration (write).

At the moment there is no guarantee that a response to a control packet is really from the server, because ntpd denies any request to authenticate responses, it seems.

Comments and pointers to (non-contradicting) specifications welcome!

Regards,
Ulrich Windl

_______________________________________________
ntpwg mailing list
[email-masked]
http://lists.ntp.org/listinfo/ntpwg