Subject: Re: [Suit] draft-housley-suit-cose-hash-sig

From: Russ Housley <[email-masked]>
Date: Sun, 1 Jul 2018 14:01:44 -0400

Tony:

Thanks for taking the time to do a review.  Sorry it has taken me so long to respond.

> Some further comments on your draft suit-cose-hash-sig:
>  
> In a number of places, starting in section 3, you limit this specification
> to using SHA-256. As far as I can see, if a new RFC were issued updating
> [HASHSIG} and using a different hash function, this specification would
> not change due to the self-describing nature of the signature. So while
> the restriction applies to [HASHSIG}, which is defining actual signatures,
> I believe it does not apply to this draft, which is defining a way to
> transport signatures.

If [HASHSIG] were extended to use hash functions beyond SHA-256, then additional values would need to be registered.  IANA registries are set up by [HASHSIG] to allow for those future registrations.

I'll try to come up with some working that embraces this flexibility.

>  Section 3.1: "Each signed public key is represented by the hash value at
> the root of the tree": it also contains information about the tree
> structure (type and otstype) and the identity I; but perhaps this detail
> is not needed.

I suggest:

   Each signed public key is represented by the hash value at the root
   of the tree, and it also contains information about the tree
   structure.  The signature over the public key is an LMS signature as
   described in Section 3.2.

>  End of section 3.1: I find the text "lms_signature_on_public_key[0]"
> (and so on) misleading because the signature is actually on public_key[1].
> I feel it would be better to be a bit more verbose, and define:
>   signature[k-1] = lms_signature_on_public_key_k_using_private_key[k-1]
>   signed_public_key[k] = signature[k-1] || public_key[k]
> Then the overall tree is just
>   u32str(Nspk) ||
>   signed_public_key[1] ||
>   signed_public_key[2] ||
>      ...
>   signed_public_key[Nspk-1] ||
>   signed_public_key[Nspk] ||
>   lms_signature_on_message_using_private_key[Nspk]

I see that I did not achieve the desired alignment with the format used in Section 7 of [HASHSIG], which uses this structure:

   /* hierarchical signature system (hss)  */

   struct hss_public_key {
     unsigned int L;
     lms_public_key pub;
   };

   struct signed_public_key {
     lms_signature sig;
     lms_public_key pub;
   }

   struct hss_signature {
     signed_public_key signed_keys<7>;
     lms_signature sig_of_message;
   };

How about the following?

   The elements of the HSS signature value for a tree with Nspk levels
   can be summarized as:

      u32str(Nspk) ||
      signed_public_key[1] ||
      signed_public_key[2] ||
         ...
      signed_public_key[Nspk-1] ||
      signed_public_key[Nspk] ||
      lms_signature  /* signature of message */

   where, as defined in Section 7 of [HASHSIG], a signed_public_key is
   the lms_signature over the public key followed by the public key
   itself.

> Section 3.2, third paragraph: I suggest putting the elements in the same
> order that they appear in the signature, namely:
>   "An LMS signature consists of four elements: the number of the leaf
>    associated with the LM-OTS signature, an LM-OTS signature as described
>    in Section 3.3, a typecode indicating the particular LMS algorithm,
>    and an array of values that is associated with the path through the
>    tree from the leaf associated with the LM-OTS signature to the root."
> It is probably worth noting here that the LM-OTS signature starts with
> an ots-typecode, so that the signature can be easily parsed.

I agree.  Fixed.

> Section 3.3, last line: I suggest replacing the first element with
> u32str(otstype) for clarity. It should be clear from context, but I think
> it's worth emphasising.

I agree.  Done.

> Section 4, second paragraph: "The first four bytes of each LMS signature
> value contains type code" is not correct. I suggest being less specific
> and say something like "the LMS signature value is self-describing", as
> parsing is a little more difficult to explain. Alternatively, reverse the
> order of describing the parts, to that the self-parsing of the OTS
> signature has already been explained before coming to the LMS signature.

This text was correct for a previous version of [HASHSIG].  As you say, the previous sections cover this point already.  Perhaps it would be better to simply say:

   The signature value is a large byte string.  The byte string is
   designed for easy parsing, and it includes a counter and type codes
   that indirectly provide all of the information that is needed to
   parse the byte string during signature validation.

> Section 4: There is no mention of which kid to use. This may be a matter
> of convention between sender and receiver, but if public keys are used
> as trust anchors then the identity I of the public key could be sent in
> the kid field. I think this should be mentioned at least as a MAY, to
> facilitate interoperability.

RFC 8152 says:

   kid:  This parameter identifies one piece of data that can be used as
      input to find the needed cryptographic key.  The value of this
      parameter can be matched against the 'kid' member in a COSE_Key
      structure.  Other methods of key distribution can define an
      equivalent field to be matched.  Applications MUST NOT assume that
      'kid' values are unique.  There may be more than one key with the
      same 'kid' value, so all of the keys associated with this 'kid'
      may need to be checked.  The internal structure of 'kid' values is
      not defined and cannot be relied on by applications.  Key
      identifier values are hints about which key to use.  This is not a
      security-critical field.  For this reason, it can be placed in the
      unprotected headers bucket.

Since applications MUST NOT assume that the kid is unique, I am not sure that the kid should be called out here.  At most, I could say:

      o  If the 'kid' field is present, and it MAY be used to identify the intended public key.

> Section 5.1, last paragraph: The generation of signatures also relies on
> random numbers. Their generation is much less sensitive than the generation
> of private keys, so don't lump them together in the same paragraph, but
> it is worth a mention. As an aside, is there any investigation into a
> deterministic signature, e.g. by setting C to a hash of all the private
> keys?

I am not aware of any investigation into deterministic hash-based signatures.

I suggest:

   The generation of hash-based signatures also depends on random
   numbers.  While the consequences of an inadequate pseudo-random
   number generator (PRNGs) to generate these values is much less severe
   than the generation of private keys, the guidance in [RFC4086]
   remains important.

> Section 6: Some more idle speculation on my part. In software update,
> the signed bundle *should* have a unique version number. If there were
> a way to map version number to LMS node, this would provide a different
> way to ensure that the same key was never reused. But I agree that such
> a discussion doesn't belong in this document.

That would also make it difficult to roll from one trust anchor to another.  This needs more thought.

> Section 7.1/7.2: Please update the "Description" to be more specific,
> such as:
>   "Description:  Hash-based digital signatures using HSS/LMS" and
>   "Description: Public key of HSS/LMS hash-based digital signature"

Good idea.  Done.

Russ