[tcpm] RFC 5925 SNE algorithm concern
juhamatk@gmail.com Thu, 30 April 2020 07:31 UTC
Return-Path: <juhamatk@gmail.com>
X-Original-To: tcpm@ietfa.amsl.com
Delivered-To: tcpm@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 4B1EA3A0A53 for <tcpm@ietfa.amsl.com>; Thu, 30 Apr 2020 00:31:48 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.099
X-Spam-Level:
X-Spam-Status: No, score=-2.099 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.com
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Sj087CF84puX for <tcpm@ietfa.amsl.com>; Thu, 30 Apr 2020 00:31:46 -0700 (PDT)
Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [IPv6:2a00:1450:4864:20::333]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 82EBB3A0A51 for <tcpm@ietf.org>; Thu, 30 Apr 2020 00:31:46 -0700 (PDT)
Received: by mail-wm1-x333.google.com with SMTP id v8so6739980wma.0 for <tcpm@ietf.org>; Thu, 30 Apr 2020 00:31:46 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=TAnCH2lJjnSeUmZqzXPvYSyKLMV5YIEiioXv5VjcflE=; b=dH7IetMgOjDJ5Yb5AiqNAQlMiE4egfD8SbiNhH5YIDrrpColokk3Qjq9IOgyErr/0e caFcrjOpk/yKkonSojYC4GhPKjzS4knGviwSgkAPMZU5g3OEmbgd27mWHjiqDJOZu9CI 499O4cyGUehweEJ7fojlcUQ6IdaCJtie7j923KZ5HgUMlb+WALwkx3z7JtYxcnjhtXry 3PO4sDOLA+9TeH8JSdNVkENFRqWJAcIapnGY27eTMcU2MvKXASa+DCE3mymyg2/ifbhA 0CzWXAMc69dIG7vF0wDiAs5i2I6MTOvBQo1Z5NVkA/KREGVqff3PmA5/SHrM9uJ2liaW hw/Q==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=TAnCH2lJjnSeUmZqzXPvYSyKLMV5YIEiioXv5VjcflE=; b=qWYJdRY06g2suRBZZkV0Aul+OEFOaSQTFE2jOJmucynl/npLnvZ+eO3CT7hOdmuSc8 j8pgjl/iIJYvMdzqgQwwPdosIWNvr8ealjShXDC2nCsfu96yHNiYcLamKjVRWgA+8yYK 6Bxq/XjCAzKauJRpieFsSi7uTADCq3mbFhQr2DW7Fv+ledjNwS7X5YawgJg+0mkZQPdH pQ/MKL0aOzgXv6w7aLeGoNl3QesnQhGxMH1iUZcq15zO8ALjNsoqkiBehEftDoHzn7SF PrriOC969rqzB/vjwW9LMFD2OudfHdqj1hGen/lUrfjgTrQc9I9OpDBqaVCG1B9CG+zP n0cg==
X-Gm-Message-State: AGi0Pube1vCCP/5kiJW25j9FGsG1+jwfUgAGKvy6FWxJwAviyMZpc+S5 YD370GzhduFtpugWjot7A2hLlOtWxGdj+UYuMJT3mktIt+Y=
X-Google-Smtp-Source: APiQypL4D1KyjyTkF9W6NfWU35OkALEhmZxKxnykLdm+gEBOBl+OsqHzsWhUzRBPcgGyVqHKYOxfo4LznQEnIOZkLyM=
X-Received: by 2002:a05:600c:225a:: with SMTP id a26mr1441955wmm.104.1588231904409; Thu, 30 Apr 2020 00:31:44 -0700 (PDT)
MIME-Version: 1.0
From: juhamatk@gmail.com
Date: Thu, 30 Apr 2020 10:31:32 +0300
Message-ID: <CACS3ZpBLAO2=O6Vf2Vx766qAGqmY2yD_yiLag-K7C3sYFjH9hw@mail.gmail.com>
To: tcpm@ietf.org
Content-Type: text/plain; charset="UTF-8"
Archived-At: <https://mailarchive.ietf.org/arch/msg/tcpm/cNlPjIs2Ql-__QpSrq8M2G-Irjw>
Subject: [tcpm] RFC 5925 SNE algorithm concern
X-BeenThere: tcpm@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: TCP Maintenance and Minor Extensions Working Group <tcpm.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/tcpm>, <mailto:tcpm-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/tcpm/>
List-Post: <mailto:tcpm@ietf.org>
List-Help: <mailto:tcpm-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/tcpm>, <mailto:tcpm-request@ietf.org?subject=subscribe>
X-List-Received-Date: Thu, 30 Apr 2020 07:31:49 -0000
Hello all, While working with RFC 5925, I have been checking the details of example SNE algorithm. I have a slight concern with the example algorithm proposed by the RFC. The idea of SNE is to simulate 64-bit sequence number with 32-bit sequences to prevent replay attacks. RFC 5925 proposes the following algorithm to implement 64-bit sequence numbering: Original algorithm pseudo-code in the RFC 5925 + errata: /* set the flag when the SEG.SEQ first rolls over */ if ((RCV.SNE_FLAG == 0) && (RCV.PREV_SEQ > 0x7fffffff) && (SEG.SEQ < 0x7fffffff)) { RCV.SNE = RCV.SNE + 1; RCV.SNE_FLAG = 1; } /* decide which SNE to use after incremented */ if ((RCV.SNE_FLAG == 1) && (SEG.SEQ > 0x7fffffff)) { SNE = RCV.SNE - 1; # use the pre-increment value } else { SNE = RCV.SNE; # use the current value } /* reset the flag in the *middle* of the window */ if ((RCV.PREV_SEQ < 0x7fffffff) && (SEG.SEQ > 0x7fffffff)) { RCV.SNE_FLAG = 0; } /* save the current SEQ for the next time through the code */ RCV.PREV_SEQ = SEG.SEQ; When looking into this in detail, to me it looks like there might be an issue when 32-bit sequence wraps back to the beginning and a retransmission occurs with the high sequence range. Then SNE is increased unexpectedly and does not follow proper sequencing. A test case below: State: PREV_SEQ = 0xffffffe RCV.SNE = 0 RCV.SNE_FLAG = 0 New frame: SEG.SEQ = 0x0 RCV.SNE => 1 RCV.SNE_FLAG => 1 PREV_SEQ => 0 Retransmit: SEG.SEQ = 0xfffffffd RCV.SNE_FLAG => 0 - incorrectly updated PREV_SEQ => 0xfffffffd - incorrectly updated New frame: SEG.SEQ = 0x2 RCV.SNE => 2 - incorrect value, should be 1 based on sequencing RCV.SNE_FLAG => 1 PREV_SEQ => 0x2 I could not figure out any reason why the above sequence would not be valid. Even though it is mentioned in the RFC that the algorithm is just an example, the sequencing mismatch is unfortunate as mismatching SNEs on different sides will bring the authenticated TCP session down and cause data loss through timeout. Thus, for interoperability, it is crucial that correct sequencing is used on both ends. If above is really a real problem, then perhaps an improved algorithm could be as follows: Improved algorithm suggestion pseudo-code: PRE = 0; // set the flag when the SEG.SEQ first rolls over if ((RCV.SNE_FLAG == 0) && (RCV.PREV_SEQ > 0x7fffffff) && (SEG.SEQ < 0x7fffffff)) { RCV.SNE = RCV.SNE + 1; RCV.SNE_FLAG = 1; } // decide which SNE to use after incremented, // pre-increment is used for retransmits if ((RCV.SNE_FLAG == 1) && (SEG.SEQ > 0x7fffffff)) { SNE = RCV.SNE - 1; # use the pre-increment value PRE = 1; } else { SNE = RCV.SNE; # use the current value } // reset the flag in the *middle* of the window, // include SEG.SEQ equals half so that we do not miss // that edge case if (PRE == 0) { if(RCV.SNE_FLAG == 1 && RCV.PREV_SEQ < 0x7fffffff) && (SEG.SEQ >= 0x7fffffff)) { RCV.SNE_FLAG = 0; } // save the current SEQ for the next time through the code, // if we are not retransmitting RCV.PREV_SEQ = SEG.SEQ; } This passes the problematic case (and bunch of others I have tested). This also includes a small additional fix in the middle window handling where SEG.SEQ was missing one edge value (SEG.SEQ > 0x7fffffff => SEG.SEQ >= 0x7fffffff). I hope I have not missed anything else, but it is certainly possible, so comments are welcome. So, what do you think, is this a real concern? If it is a real issue, what would be the best way to handle this, perhaps an errata with an improved algorithm after throughout review of the new algorithm? Thank you, -- Juhamatti
- [tcpm] RFC 5925 SNE algorithm concern juhamatk
- Re: [tcpm] RFC 5925 SNE algorithm concern Joseph Touch
- Re: [tcpm] RFC 5925 SNE algorithm concern juhamatk
- Re: [tcpm] RFC 5925 SNE algorithm concern juhamatk
- Re: [tcpm] RFC 5925 SNE algorithm concern Joseph Touch
- Re: [tcpm] RFC 5925 SNE algorithm concern Joseph Touch
- Re: [tcpm] RFC 5925 SNE algorithm concern Joseph Touch
- Re: [tcpm] RFC 5925 SNE algorithm concern juhamatk