[Ndn-interest] Interest Signature

Mosko, Marc <mmosko@parc.com> mmosko at parc.com
Tue Jan 15 10:52:16 PST 2019


Junxiao,

Thank you for the detailed reply, it helps me understand the construction better.

>>> Since Parameters TL and SignatureInfo TL are included, the only case of confusion due to lack of delimiter is between "having Parameters" and "TLV-TYPE of last name component equals Parameters, but no Parameters". I know about this case but thought it's insignificant.
However, as I said, I could agree with including Name TL and zero-ed SignedInterestSha256DigestComponent.

Because the SignedInfo parameter is required, it will have a TL prefix, so that one is ok.  As you point out, the discrepancy happens if the original had a Parameters and the fake uses a name with the Parameters value in that field and omits Parameters field.  I think you could either include a Parameters TL (with 0 length) in the digest if it is missing or use the 0-padded name approach.

FYI, Re-reading the text under "Signed Interest processing", it does not explicitly say that one removes the SignedInterestSha256DigestComponent before verifying the signature.

If I wanted to exploit this Parameters ambiguity I would stick the Parameters field after the last name component and before SignedInterestSha256DigestComponent.

Although I do not now of a specific attack -- it would likely be application level and depend on how someone parases the name -- it does seem wrong to admit a case where two different interests can have the same signature.  If they were properly formed, they would have different SignedInterestSha256DigestComponent (one has Parameters and one does not).


>>> SignedInterestSha256DigestComponent covers InterestSignatureValue to ensure proper operation of network forwarders, and in particular PIT aggregation. Under NDN Packet Format v0.3, PIT aggregation uses Name+CanBePrefix+MustBeFresh as index key. If SignedInterestSha256DigestComponent does not cover InterestSignatureValue, a signed Interest with a good signature can be aggregated into a signed Interest with a bad signature, and this scenario remains undetectable by the network. Covering InterestSignatureValue enables a network forwarder to detect such scenario: a forwarder can occasionally compute the digest and compare it to SignedInterestSha256DigestComponent, and block a malicious consumer if the digest does not match.

Ok, I understand the reasoning for this.

Because the SignatureInfo includes a nonce and timestamp (which are both required for a signed interest), it seems very unlikely that Interests from two different sources could have the same SignedInterestSha256DigestComponent even if it excluded the signature value.  It would require that a bad actor actually see the good interest first and generate a fake or flood a zillion interests guessing the next nonce and timestamp.  But I understand that doing it with the signature value makes a self-verifying system if a forwarder were to actually verify the digests.

It would be helpful in the document to give your explanation here about why the SignedInterestSha256DigestComponent has its particular structure.

Marc

________________________________________
From: Junxiao Shi <shijunxiao at email.arizona.edu>
Sent: Monday, January 14, 2019 3:55:41 PM
To: Mosko, Marc <mmosko at parc.com>
Cc: Zhiyi Zhang; ndn-interest at lists.cs.ucla.edu
Subject: Re: [Ndn-interest] Interest Signature

Hi Marc
(continuing this thread on ndn-interest only; removing mini-ndn mailing list as this is becoming a protocol discussion)

I noticed at the end of the code review comments there is the statement "The signature should not cover Name-TYPE and Name-Length."  I did not see it in the comments, but I assume you are applying the same logic to the Parameters and SignatureInfo fields?

>>> Actually not. The reason why we don't include Name's T and L is because after generating the signature value, we need to append a SignedInterestSha256Digest component to the end of the current name, thus changing the Name's L.
This cuase extra overhead when verifying the signature -- receiver needs to calculate and modify the L before signature verification.

Might I suggest that you pre-append a zero-ed component and adjust the L, then do the signature.  The receiver would then need to zero the field to compare signatures.  That would allow keeping the Name T & L so the digest is over properly delimited fields.  Otherwise, I would try to find some other way of delimiting the name value to avoid attacks on the multiple fields.  One example would be to just include a length in the digest before the Name of the name length you're digesting.  It could just be a simple uint32 and does not need to be fancy.

As Zhiyi already answered, Parameters TL and SignatureInfo TL are included, but Name TL are excluded because it's not yet generated.
I agree that reserving a zero-ed SignedInterestSha256DigestComponent is a good solution. The same approach has been adopted by UDP checksum.

I think that is not correct.  When computing a digest over multiple fields, you need to delimit those fields somehow (a special character or length encoding, etc.).  Otherwise, you could have a first field with the values of the later fields and the later fields empty and get the same digest and thus the same signature.  For example, if my digest is over fields A and B, if I do not delimit them, I could have A="abc" and B="def" or A="abcdef" and B="" and they would look the same.

Since Parameters TL and SignatureInfo TL are included, the only case of confusion due to lack of delimiter is between "having Parameters" and "TLV-TYPE of last name component equals Parameters, but no Parameters". I know about this case but thought it's insignificant.
However, as I said, I could agree with including Name TL and zero-ed SignedInterestSha256DigestComponent.

So it appears that the signature is only on the tuple (Name \  ParametersSha256Digest, Parameters, SignatureInfo).  Usually one would makes those contiguous memory to simplify the digest calculation, so I would have expected the BNF to have Parameters and SignatureInfo directly after Name, assuming that the BNF implies normal ordering.

It's unnecessary to have contiguous memory. Last time I checked, every good crypto library supports incremental SHA256 computation.
It's more important to place elements that a network forwarder cares about early in the packet, and this means Name, CanBePrefix, MustBeFresh, ForwardingHint, and HopLimit. This allows the network forwarder to stop decoding as soon as encountering Parameters.

I was not clear on why the SignedInterestSha256Digest included the InterestSignatureValue -- that is to make the name uniquely correlated to the signer?  It is not clear to me what security value this adds compared to having SignedInterestSha256Digest = Digest(Parameters, SignedInfo).  This is because you're already binding SignedInterestSha256Digest to the KeyId and using the KeyId to verify the signature over a larger body.  If it is possible to remove InterestSignatureValue from SignedInterestSha256Digest it greatly simplified operation.  I think it would be worth reviewing why it is there and what increased assurance it adds.

SignedInterestSha256DigestComponent covers InterestSignatureValue to ensure proper operation of network forwarders, and in particular PIT aggregation. Under NDN Packet Format v0.3, PIT aggregation uses Name+CanBePrefix+MustBeFresh as index key. If SignedInterestSha256DigestComponent does not cover InterestSignatureValue, a signed Interest with a good signature can be aggregated into a signed Interest with a bad signature, and this scenario remains undetectable by the network. Covering InterestSignatureValue enables a network forwarder to detect such scenario: a forwarder can occasionally compute the digest and compare it to SignedInterestSha256DigestComponent, and block a malicious consumer if the digest does not match.

Yours, Junxiao







More information about the Ndn-interest mailing list