Subject: [CGA-EXT] SEND checksum issue in current RFC 3791 - update needed

From: Sheng Jiang <[email-masked]>
Date: Thu, 17 Sep 2009 10:14:03 +0800

Hi, dear CSIer,

During our implementation of SEND & CGA, we discovered an issue in the
current RFC 3791, described as the following. An update is needed to solve
this issue.

Checksum issue in the current SEND definition RFC 3791.

In Section 5.2, RFC3791, digital signature is defined to sign data include
checksum fieds from ICMP header (bullet item 4), which should already be
calculated during the construction of message (the first step in Section
5.2.1). After RSA signature is attached, the original checksum value is no
longer valid. It should be recalsulated. However, this was not clearly
defined in RFC 3791. More importantly, the correspondent validation rule
must be defined on the receiver side too.

Best regards,

Sheng

---

From: [email-masked] (Arnaud Ebalard)
Date: Thu, 17 Sep 2009 08:01:42 +0200

Hi,

> must be defined on the receiver side too.

I already reported that same issue some time ago and the good way to
understand the spec is to compute the signature over the packet with the
checksum field to 0. Then, the checksum is computed over the whole
packet. But I agree that the spec is unclear on that.

See my post and Eric's reply here:

  http://www.ietf.org/mail-archive/web/cga-ext/current/msg00098.html

Cheers,

a+

---

From: Sheng Jiang <[email-masked]>
Date: Thu, 17 Sep 2009 15:42:12 +0800

Hi, Arnaud,

Yes, it is an issue must be clearly clarified in the specification.
Actually, there are two possibility here (which makes more important that
specification should be clearly follow only one of them):

A, if we would like to follow the drscription in Section 5.2.1 RFC 3791, the
input of RSA signature should be a checksum calculated without RSA signature
and it will be recalculated after signature attached. On the receiver side,
ICMP checksum should be validated, then signature validate, then maybe
checksum validate again.

B, more efficiently, on the sender side, as you said, the input of RSA
signature should be a checksum with all 0, and after signature attached, the
checksim is computed over the whole packet. However, this makes the
signature over checksum totally meaningless. Alternatively, we may take
checksum bits out from the RSA signature input.

Additionally, there are intercommunication issues if a sender use A
implementation and a receiver uses B implementation.

Sum up, an update over the current definition RFC 3791 is needed on this
issue.

Cheers,

Sheng

> -----Original Message-----
> From: Arnaud Ebalard [mailto:[email-masked]] 
> Sent: Thursday, September 17, 2009 2:02 PM
> To: Sheng Jiang
> Cc: [email-masked]; 'wdwang'
> Subject: Re: [CGA-EXT] SEND checksum issue in current RFC 
> 3791 - update needed
> 
> Hi,
> 
> > current RFC 3791, described as the following. An update is 
> needed to 
> > solve this issue.
> >
> > In Section 5.2, RFC3791, digital signature is defined to sign data 
> > include checksum fieds from ICMP header (bullet item 4), 
> which should 
> > already be calculated during the construction of message (the first 
> > step in Section 5.2.1). After RSA signature is attached, 
> the original 
> > checksum value is no longer valid. It should be 
> recalsulated. However, 
> > this was not clearly defined in RFC 3791. More importantly, the 
> > correspondent validation rule must be defined on the 
> receiver side too.
> 
> I already reported that same issue some time ago and the good 
> way to understand the spec is to compute the signature over 
> the packet with the checksum field to 0. Then, the checksum 
> is computed over the whole packet. But I agree that the spec 
> is unclear on that.
>

---

From: Eric Levy-Abegnoli <[email-masked]>
Date: Thu, 17 Sep 2009 09:55:00 +0200

Sheng,
Currently, I see onle one possibility, which is A. It is un-ambiguously specified in rfc3971. And it has been implemented by multiple vendors. Moving to B would not be backward compatible and would create inter-operability issues. 
Eric

Sheng Jiang a écrit :
>>> During our implementation of SEND & CGA, we discovered an 
>>>       
>> issue in the 
>>     
> _______________________________________________
> CGA-EXT mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/cga-ext
>
>

---

From: [email-masked] (Arnaud Ebalard)
Date: Thu, 17 Sep 2009 10:22:55 +0200

Hi,

Eric Levy-Abegnoli <[email-masked]> writes:

> Sheng,
> Currently, I see onle one possibility, which is A. It is
> un-ambiguously specified in rfc3971.

I respectfully disagree (not on the definitive solution). My previous
post in March 2008 and the one from Sheng just prove this is not
"un-ambiguously" specified. 

> And it has been implemented by multiple vendors.

I checked the code and NTT Docomo SEND daemon does 'A' (i should have
checked before my first reply to Sheng):

It computes the checksum on current ICMPv6 message before the Signature
computation, uses that during the signature step and then recomputes the
checksum after the signature option has been added to the message.

> Moving to B would not be backward compatible and would create
> inter-operability issues.

Clarifying the spec would help in all cases.

Cheers,

a+

---

From: Eric Levy-Abegnoli <[email-masked]>
Date: Thu, 17 Sep 2009 10:44:49 +0200

Hi Arnaud,
> "un-ambiguously" specified. 
complicated, or not detailed enough does not mean it is ambiguous. I read:

  Digital Signature
      A variable-length field containing a PKCS#1 v1.5 signature,
      constructed by using the sender's private key over the following
      sequence of octets:

[snip]

      4. The 8-bit Type, 8-bit Code, and 16-bit Checksum fields from the
         ICMP header.

...
It does not say "0", it says checksum from the icmp header. How could 
"0" be the checksum of the icmp header?
I agree clarification would be useful, given that several implementors 
are asking for it. No question on that.
I disagree that there are several ways of interpreting it. Basically, 
you have a well-formed icmp message, which include a valid checksum, and 
you build a pseudo message by taking a number of fields out of it, 
including the checksum, and then you sign it.Once you have added your 
RSA option, another specification (icmp) mandate that you fix the 
checksum to make it correct.

> checksum after the signature option has been added to the message.
So does the Juniper, Cisco (and a few others) implementations. 
Otherwise, they would not inter-operate.
Eric

---

From: [email-masked] (Arnaud Ebalard)
Date: Thu, 17 Sep 2009 11:00:50 +0200

Hi,

>> specification should be clearly follow only one of them):

Not arguing on the fact that "A" will be kept because it is the
"implemented" solution (Docomo implementation, Cisco, probably Juniper
too).

>> ICMP checksum should be validated, then signature validate, then maybe

For the records (correction welcome if I missed sth),

Signature computation:

  - Create ICMPv6 message w/o RSA Signature option
  - Compute ICMPv6 checksum as usual using the pseudo-header (current length,
    i.e. w/o the RSA Signature option)
  - Set that checksum in checksum field of the ICMPv6 header
  - Compute RSA Sig as described in section 5.2 of RFC 3971
  - Add RSA Signature Option at the end of the ICMPv6 message
  - Update ICMPv6 packet length to include RSA Sig option
  - Update IPv6 payload length to reflect addition of RSA Sig option
  - Update ICMPv6 checksum using updated pseudo-header for the
    computation (length value modified + addition of RSA Signature
    Option) 

Signature verification:

  - Verify ICMPv6 checksum as usual on received message (obviously,
    including RSA Signature option)
  - Remove RSA Signature option from the packet
  - Update IPv6 length field to reflect previous removal
  - Recompute the checksum on the packet based on the new values (and
    w/o the RSA Sig Opt in the message)
  - Verify RSA Signature as described in RFC 3971

>> checksum bits out from the RSA signature input.

Performing the signature over the given layout with the null checksum
prevents useless copies: you zero the field, pass the whole buffer to
your signature function w/o the need to copy things to create a
different layout. But I guess this does not matter anymore.

Cheers,

a+

---

From: [email-masked] (Arnaud Ebalard)
Date: Thu, 17 Sep 2009 11:18:57 +0200

Hi,

> "0" be the checksum of the icmp header?

Just for the discussion: Usually, the checksuming is done at the end of
option inclusion. Meanwhile (at least in most C implementations, i
guess, the checksum field is null in the structure due to an initial
memset(,0,)). But I guess one can say that "The message is constructed
in its entirety, without the RSA Signature option" must be understood as
"The message is constructed in its entirety, with the checksum field set
but without the RSA Signature"

IMHO, Changing the list in 5.2.1 to: 

   A node sending a message with the RSA Signature option MUST construct
   the message as follows:

   o  The message is constructed in its entirety, without the RSA
      Signature option. This includes usual checksum computation over
      current layout.

   o  The RSA Signature option is added as the last option in the
      message.

   o  The data to be signed is constructed as explained in Section 5.2,
      under the description of the Digital Signature field.

   o  The message, in the form defined above, is signed by using the
      configured private key, and the resulting PKCS#1 v1.5 signature is
      put in the Digital Signature field.

   o As described in [RFC2463], ICMPv6 checksum field is updated to
     reflect the addition of the RSA Signature Option.

make things clear.

> are asking for it. No question on that.

yes.

BTW, while I am at it, was I the only one to read the description of the
Timestamp field multiple times (in 5.3.1. "Timestamp Option") to be sure
my code would work for various arch (endianness)?

Cheers,

a+

---

From: Sheng Jiang <[email-masked]>
Date: Thu, 17 Sep 2009 17:40:57 +0800

Eric,

I agree that we should stick on A. However, it is that obvious from the
current RFC 3791. Clarification/update will help on this.

Sheng

> From: Eric Levy-Abegnoli [mailto:[email-masked]] 
> Sent: Thursday, September 17, 2009 3:55 PM
> To: Sheng Jiang
> Cc: 'Arnaud Ebalard'; 'wdwang'; [email-masked]
> un-ambiguously specified in rfc3971. And it has been 
> implemented by multiple vendors. Moving to B would not be 
> backward compatible and would create inter-operability issues. 
> Eric
> 
> Sheng Jiang a écrit :
> > Hi, Arnaud,
> >
> > Actually, there are two possibility here (which makes more 
> important 
> > that specification should be clearly follow only one of them):
> >
> > A, if we would like to follow the drscription in Section 5.2.1 RFC 
> > 3791, the input of RSA signature should be a checksum calculated 
> > without RSA signature and it will be recalculated after signature 
> > attached. On the receiver side, ICMP checksum should be validated, 
> > then signature validate, then maybe checksum validate again.
> >
> > signature should be a checksum with all 0, and after signature 
> > attached, the checksim is computed over the whole packet. However, 
> > this makes the signature over checksum totally meaningless. 
> > Alternatively, we may take checksum bits out from the RSA 
> signature input.
> >
> > Sum up, an update over the current definition RFC 3791 is needed on 
> > this issue.
> >
> > Cheers,
> >
> > Sheng
> >
> >   
> >> understand the spec is to compute the signature over the 
> packet with 
> >> the checksum field to 0. Then, the checksum is computed over the 
> >> whole packet. But I agree that the spec is unclear on that.
> >>

---

From: Sheng Jiang <[email-masked]>
Date: Thu, 17 Sep 2009 18:01:09 +0800

> It does not say "0", it says checksum from the icmp header. 
> How could "0" be the checksum of the icmp header?
> I agree clarification would be useful, given that several 
> implementors are asking for it. No question on that.
> I disagree that there are several ways of interpreting it. 
> Basically, you have a well-formed icmp message, which include 
> a valid checksum, and you build a pseudo message by taking a 
> number of fields out of it, including the checksum, and then 
> you sign it.Once you have added your RSA option, another 
> specification (icmp) mandate that you fix the checksum to 
> make it correct.

For me, it seems clear from the definition that the input checksum should be
already calculated without signature option. The unclear part is that the
checksum should be recalculated after signature option attached. The current
definition does not say so! And calculating checksum twice is an unusaul
procedure. If this is not clarified, people won't get it right at the first
shoot.

For implementors, this is not a difficult bug to fix. Calculating checksum
only once would obviously break ICMP. Then, implementor found out there
should be checksum calculation once again. I guess that's why all the
current implementation, including ours, have getten this right and have no
inter-op issues happen. However, this IS a bug for standard document not to
mention it. It is something we should fix it in the standard document.

Cheers,

Sheng

---

From: Sheng Jiang <[email-masked]>
Date: Thu, 17 Sep 2009 19:09:36 +0800

> Sent: Thursday, September 17, 2009 5:01 PM
> To: Eric Levy-Abegnoli
> Cc: Sheng Jiang; 'wdwang'; [email-masked]
> Not arguing on the fact that "A" will be kept because it is 
> the "implemented" solution (Docomo implementation, Cisco, 
> probably Juniper too).
> 

This is right if we try to follow the current specification. This
supplemented clarification is compliant with the current RFC 3971.
 
> >> B, more efficiently, on the sender side, as you said, the input of 
> >> RSA signature should be a checksum with all 0, and after signature 
> Performing the signature over the given layout with the null 
> checksum prevents useless copies: you zero the field, pass 
> the whole buffer to your signature function w/o the need to 
> copy things to create a different layout. But I guess this 
> does not matter anymore.

Agree. If this is the initial design, it should be more efficient. However,
if we need to follow what is already in current specification, try to keep
consistent and compliant, don't break the existing implementations, then A
is the only choice.

Cheers,

Sheng

---

From: gx su <[email-masked]>
Date: Thu, 17 Sep 2009 20:08:51 +0800

Hi,

We've been implementing the SEND for the last couple of months.

>From the sender side both way might have the same efficiency,
since most implementations of SEND might be a layer over NDP,
and NDP would compute the cksum before SEND could intercept
the packet; but A would need to recover the cksum before verifying
the signature, while B simply setting the field to 0.

Given the computation power of current PCs, I think efficiency would
not be a great concern; it is consistency that matters. Therefore I
prefer A -- after all, it would be the 1st solution that pops out to
implementors when they encounter the problem.

I agree that some kind of clarification is needed, this would w/o the
bug from happening.

---

From: [email-masked] (Arnaud Ebalard)
Date: Thu, 17 Sep 2009 14:10:07 +0200

> consistent and compliant, don't break the existing implementations, then A

sadly, yes.