Re: Comments on draft-ietf-bfd-secure-sequence-numbers-10

Jeffrey Haas <jhaas@pfrc.org> Tue, 21 March 2023 21:08 UTC

Return-Path: <jhaas@pfrc.org>
X-Original-To: rtg-bfd@ietfa.amsl.com
Delivered-To: rtg-bfd@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id E2D61C151532; Tue, 21 Mar 2023 14:08:03 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -6.9
X-Spam-Level:
X-Spam-Status: No, score=-6.9 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, RCVD_IN_ZEN_BLOCKED_OPENDNS=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([50.223.129.194]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id KhzS9zPRqG4N; Tue, 21 Mar 2023 14:08:02 -0700 (PDT)
Received: from slice.pfrc.org (slice.pfrc.org [67.207.130.108]) by ietfa.amsl.com (Postfix) with ESMTP id C0B88C14CF1E; Tue, 21 Mar 2023 14:07:54 -0700 (PDT)
Received: from smtpclient.apple (104-10-90-238.lightspeed.livnmi.sbcglobal.net [104.10.90.238]) by slice.pfrc.org (Postfix) with ESMTPSA id BF90C1E037; Tue, 21 Mar 2023 17:07:53 -0400 (EDT)
Content-Type: text/plain; charset="utf-8"
Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3696.120.41.1.1\))
Subject: Re: Comments on draft-ietf-bfd-secure-sequence-numbers-10
From: Jeffrey Haas <jhaas@pfrc.org>
In-Reply-To: <C4D01D2C-9C54-400E-925C-180A8EC72859@freeradius.org>
Date: Tue, 21 Mar 2023 17:07:53 -0400
Cc: draft-ietf-bfd-secure-sequence-numbers@ietf.org, rtg-bfd@ietf.org
Content-Transfer-Encoding: quoted-printable
Message-Id: <4B9B39A0-8F35-43E9-850B-4E0B42371410@pfrc.org>
References: <20230321181834.GB3114@pfrc.org> <C4D01D2C-9C54-400E-925C-180A8EC72859@freeradius.org>
To: Alan DeKok <aland@freeradius.org>
X-Mailer: Apple Mail (2.3696.120.41.1.1)
Archived-At: <https://mailarchive.ietf.org/arch/msg/rtg-bfd/odLWxfmT4OLa8vfNk7HJpQv31sk>
X-BeenThere: rtg-bfd@ietf.org
X-Mailman-Version: 2.1.39
Precedence: list
List-Id: "RTG Area: Bidirectional Forwarding Detection DT" <rtg-bfd.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/rtg-bfd>, <mailto:rtg-bfd-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/rtg-bfd/>
List-Post: <mailto:rtg-bfd@ietf.org>
List-Help: <mailto:rtg-bfd-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/rtg-bfd>, <mailto:rtg-bfd-request@ietf.org?subject=subscribe>
X-List-Received-Date: Tue, 21 Mar 2023 21:08:04 -0000

Alan,


> On Mar 21, 2023, at 3:41 PM, Alan DeKok <aland@freeradius.org> wrote:
>> If it is the case that the Sequence Number is intended to be a single continuous
>> space used by both the Meticulous Keyed ISAAC and the stronger authentication
>> while performing state changes, I think we know how this should work.
> 
>  I think we can't do that.  The issue is that the ISAAC method has a 1-1 correlation between sequence number and expected output.  The means that each end has to understand where to start from in the sequence.
> 
>  We have a few choices here:
> 
> * use new sequence numbers for ISAAC
>  * always start off at zero
>  * or, start off at some agreed-upon value, perhaps itself derived from ISAAC
> 
> * use sequence numbers taken from a previous auth method
>  * but what if there's no previous auth method, or auth-type==simple?

The "use sequence number taken from previous auth method" is what I had in mind.

A concrete example might explain my thinking.  Let's start with a mechanism that has has sequence numbers, such as md5.

The implementation uses md5 authentication in meticulous mode to bring up the session.  It reaches sequence number 20 before deciding it wants to switch to ISAAC mode.  Logically, one way to think about this is the state at this point is:
For a given session
- For the meticulous md5 auth type
- For a specific meticulous md5 auth key id
- There's a sequence number (bfd.XmitAuthSeq)

One headache is the authseq is permitted (encouraged) to be non-zero:
   bfd.XmitAuthSeq

      A 32-bit unsigned integer containing the next sequence number for
      Keyed MD5 or SHA1 Authentication to be transmitted.  This variable
      MUST be initialized to a random 32-bit value.
(RFC 5880, §6.8.1)

Existing BFD procedures aren't terribly well written when authentication needs to change.  (One of our headaches for the optimizing authentication draft.)  RFC 5880 §6.7.1 handwaves a lot of the detail in enabling and disabling authentication and is pretty much silent about changing stuff in the middle.  So, we're partially making decisions about how such things behave.

If the state we're keeping isn't only the simple boring scalar variable that's in the document (bfd.XmitAuthSeq) and is rather the per-session, per-type, we can envision maintaining  sequence numbers separately for each method.  That's pretty straight forward.  This makes our state for ISAAC:

For a given session
- For the meticulous ISAAC auth type
- For a specific meticulous ISAAC auth key id
- For a specific seed
- There's a sequence number (bfd.XmitAuthSeq)


However, if we do so, this means that our packet acceptance criteria gains complexity.  We're expected to verify that our received authseq is within the expected range allowing for dropped packets. (RFC 5880, §6.7.3)  It's still easy to envision we keep that acceptable window per auth method.  Keeping track of those windows and whether we're missing a packet or not based on authentication method is doable, but gets messier.  This impacts the draft-ietf-bfd-stability draft a bit.

None of these things are impossible.  It does, however, mean we need more text covering that detail.  (It's just text.)

By contrast, if we used a single shared authseq, we change none of the above protocol complexity.  If the number is 20 for md5 and the next packet is ISAAC with sequence number 21 and seed-x, the implementation still computes the ISAAC table and indexes into 21.  Basically, it has skipped 0..20.

Where this gets ugly is if the protocol runs without ISAAC for some time.  Let's say that we got to 513.  We'd need to know that last page we computed for ISAAC was 0..255, compute the next two iteratively, then index into the 513 entry.  Still possibly "cheap" given the compute time for pages, but clearly the setup for a far uglier case where the skip is so far out that we don't compute the page in time to catch packets before they drop.

So, the tension here is simplicity vs. the majority of the existing procedure and burning unexpected time for ISAAC.

I'm fine with either answer, and I suspect your inclination is keeping the separate sequence number spaces and updating the rest of the procedure to clarify for that.  It'd be good to hear from the other authors as well on this point.

>> 
>> Since Meticulous Keyed ISAAC is only expected to be done in the Up state after
>> the optimized procedures, the sequence number should be non-zero.
> 
>  What if there's no auth method, or auth-type==simple?

Another argument for a separate numbering space.


>> Clearly the mechanism won't work great if so great a time passes that the
>> sequence numbers have turned through multiple pages.  This isn't the expected or
>> desired behavior since optimizing authentication procedures are there solely for
>> securing state changes.  However, those consequences should likely be mentioned.
> 
>  I think all of this can be avoided if we just restart the sequence numbers for ISAAC at zero.  The first "page" of generated ISAAC numbers is 256 elements, so it's possible to do O(1) seeking within that page.  Which means that we can lose 256 packets before we need to check another page.
> 
>  But... if we lose 256 packets, I suspect that the session will transition to "down".   From RFC 5880:

The scenario in this case isn't lost packets, it's a different auth mechanism is active.

>  If we start ISAAC sequences at some non-zero value, then that needs to be somehow.  Since the sequences increment ad infinitum) and wrap, there's no way to know *where* in the sequence we are.

One example is similar to TCP sequence numbering.  It doesn't start at zero, but you need to know where you started.


>> 248	   The Sequence Number can increment without bounds, though it can wrap
>> 249	   once it reaches the limit of the 32-bit counter field.  ISAAC has a
>> 250	   cycle length of 2^8287, so there is no issue with using more than
>> 251	   2^32 values from it.
>> 
>> For the case where the sequence number wraps, what's the expected ISAAC
>> behavior?
> 
>  It just keeps going.  The sequence number isn't used to derive the 32-bit Auth-Keys taken from ISAAC.  So wrapping doesn't matter to it.

I may be confused here.

The current sequence number is 2^32 -1, we're on page X for ISAAC.
The sequence number wraps to 0 next round.  ISAAC would normally generate another page.
The index into that page is 0 rather than 2^32 at the API level.

Is the presumption here that this is a modulus operation and it's unimportant that the next number is 0 rather than 2^32?

> 
>  Alan DeKok.

-- Jeff