Subject: [openpgp] v5 in the crypto-refresh draft

From: Daniel Kahn Gillmor <[email-masked]>
Date: Fri, 04 Jun 2021 02:42:35 -0400

I've been reviewing the changes in draft-ietf-openpgp-crypto-refresh-03.
I have concerns about most of the "v5" features currently incorporated.

One of the reasons that we need to complete the crypto refresh for
OpenPGP is that SHA1 is baked into the spec in the v4 fingerprint format.

The v5 fingerprint uses SHA256, which resolves that problem.  I have no
problems with that part.

But there are several other parts of the current draft that are
specified as "v5" that have unclear (or even harmful) utility to me and
don't seem to be part of any sort of cryptographic update.  I list them
below, with explanation, but i want to ask the WG for a sense of what
folks think we should do about them (either individually or entirely).
I see three fairly simple outcomes, but i welcome other suggestions.

Possible Outcomes
-----------------

 a) WG consensus that all of these are appropriate: keep them as-is

 b) WG consensus that some of them are misfeatures, or otherwise
    inappropriate for the crypto-refresh: drop the unwanted parts from
    the specification of v5.

 c) WG consensus that some of them are misfeatures but due to
    pre-standardization deployment that produced existing artifacts, we
    can't claw them back: call the new OpenPGP version "v6" and just
    skip over v5 (like IP!)

Note that for both (b) and (c) it's possible that the new version is
basically just "v4 but with a SHA256 fingerprint instead of SHA1".  I
don't think that's necessarily a bad outcome!

Specific v5 changes
-------------------

Here are the outstanding parts of "v5" that differ from "v4" as of
draft-ietf-openpgp-crypto-refresh-03 as far as i could tell.  If you see
others, please reply to this thread!

 0) v5 public keys have a 4-octet scalar that is the size of the
    algorithm-specific fields. 

 1) v5 secret keys have the same scalar described in 0, plus two
    additional length fields: a one-octet scalar field for the length of
    the S2K metadata, and a four-octet scalar field one for the secret
    key material.

 2) v5 certifications ("key signatures") hash a four-octet length of the
    subject key; v4 certifications hash instead a two-octet subject key
    length.

 3) v5 data signatures over a literal data packet hash an additional 3
     fields (or 6 zero octets for a cleartext or detached signature):
      - the one-octet content format,
      - the file name as a string (one octet length, followed by the file name),
      - a four-octet number that indicates a date.

 4) v5 data signatures hash the trailing length value as an eight-octet
    scalar, where v4 uses a four-octet scalar.

Detailed Discussion
-------------------

(0) and (1) appear to be duplicative of information already known by a
parser: in particular the packet length itself.  This appears to be an
opportunity for error/inconsistency.  What should implementations do if
that value differs from the length remaining in the packet itself?
    
The textual justification for these changes appears to be:

>> Note that the version 5 packet format adds two count values to help
>> parsing packets with unknown S2K or public key algorithms.

If the implementation doesn't know the public key or S2K algorithm, its
only real recourse is to skip the packet anyway, so it's not clear what
advantages these length fields offer.

-----

(2) appears to prepare for keys larger than 65536 octets.  This looks
like post-quantum planning to me, but we are not including any PQ
schemes in the specification, and it's not clear that this change on its
own would be sufficient to support such a new scheme (especially because
there doesn't seem to be any CFRG consensus on what PQ scheme to endorse
yet).

-----

(3) looks like it's trying to protect metadata that has not historically
been protected by OpenPGP.  However, it's also not clear how these
fields will be used; presumably existing security-conscious
implementations treat these fields as only-advisory anyway right now
when trying to (for example) extract cleartext into the filesystem.  But
even if they're signed they might get ignored -- for example, just
because the filename is cryptographically verified as "/etc/passwd"
doesn't mean that an OpenPGP decryption utility should extract to that
sensitive location.

For tools that want to embed filesystem information into the signed
data, it's of course possible to sign a tarball.  In that approach,
existing v4 signatures end up already covering the same metadata (and
more).

This change also has a consequence that it's not possible to transform
an embedded/inline signature into a detached or cleartext signature, or
vice versa, because detached or cleartext signatures have no place to
store the content byte, filename, or timestamp.  I've seen several use
cases where translating a signature between inline/embedded format and
detached or cleartext formats can be concretely useful.  In one example,
Debian's apt repository's Release, Release.gpg, and InRelease files
contain the same data and should be able to share cryptographic
signatures.

Furthermore, it's not clear how these fields should be populated in the
event that the signed "OpenPGP Message" is anything other than a
"Literal Data Packet".  For example, if the signature is made over a
Compressed Data Packet, and that Compressed Data Packet contains a
Literal Data Packet, how should those fields be populated when
generating or verifying the signature.

If we want a way to embed this kind of format/filesystem metadata into a
signature, it would be trivial to define a subpacket including this
information and include it in the Hashed Subpackets region of a
signature, which would retain the ability to translate between
detached/cleartext and inline/embedded signatures.

----

(4) appears to be an accomodation for signing data larger than 4GiB.  v4
keys can of course currently still sign data larger than 4GiB.  But as
the current draft clarifies, v4 signatures can still be made over data
larger than 4GiB because "The four-octet big-endian number is considered
to be an unsigned integer modulo 2^32."  It's not clear to me how this
existing approach with v4 could be practically abused; why not just
leave it?

Conclusion
----------

Open questions for the WG:

 - Did I miss any other currently-adopted v5 changes?

 - Are there deployed systems/artifacts that use these fields that we
   need to worry about interoperability with?

 - Are there concrete reasons to keep any of the specific changes
   mentioned above, despite the counterindications described above?

Regards,

        --dkg

---

From: Daniel Huigens <[email-masked]>
Date: Fri, 04 Jun 2021 17:12:08 +0000

Just as one data point, we (OpenPGP.js) have fully implemented v5 from
rfc4880bis, but always behind a flag with a stern warning that using it
may break compatibility in the future. So we are in principle fine with
doing so and changing the meaning of v5, indeed.

As an alternative option, if the only goal is to fix SHA1 fingerprints,
one thing that we have started doing internally at ProtonMail is giving
keys "SHA256 fingerprints", defined simply as calculating the
fingerprint but using SHA256 instead of SHA1. Obviously, for v5 keys
this is equivalent, but if we want, we could introduce this as a concept
for v4 keys in the crypto-refresh, and reserve v5 for a later spec.

We might then also want an "Issuer SHA256 Fingerprint" subpacket, and
allow it to be used for v4 keys as well. Similarly, we might want a
version 2 of the KDF parameters, indicating that SHA256 is to be used
for the fingerprint in the KDF. This would require modifying the public
key, somewhat diminishing the benefits, but at least the primary key
could remain the same. (I also don't think either of these are really
security-critical, compared to the main use case of identifying keys,
but I might be missing something.)

Obviously, there's then additional work to be done in the public APIs of
libraries, to expose SHA256 fingerprints, and making sure that people
(and applications) use that instead of the SHA1 fingerprint wherever
possible. Whether that is more or less work than transitioning from v4
to v5 keys, I'll leave up for debate :)

(If we want to give them a more user friendly name, we could call them
"long fingerprints", in contrast to "short key IDs" etc.)

Best,
Daniel

---

From: Michael Richardson <[email-masked]>
Date: Fri, 04 Jun 2021 14:10:36 -0400

Daniel Kahn Gillmor <[email-masked]> wrote:
    >  2) v5 certifications ("key signatures") hash a four-octet length of
    > the subject key; v4 certifications hash instead a two-octet subject key
    > length.

    > schemes in the specification, and it's not clear that this change on
    > its own would be sufficient to support such a new scheme (especially
    > because there doesn't seem to be any CFRG consensus on what PQ scheme
    > to endorse yet).

Sure, but wouldn't it help a v5 implementation to more intelligently skip
such a thing?  I don't know if we can support multiple signatures with
different algorithms.

    > detached or cleartext formats can be concretely useful.  In one
    > example, Debian's apt repository's Release, Release.gpg, and InRelease
    > files contain the same data and should be able to share cryptographic
    > signatures.

I think that your use case is reasonable.
I also was thinking that with the Executive Order wrt Supply Chain security,
and the number of systems which are debian based, and thus use Release.gpg at
the top, that having v5 sooner rather than later is probably important.

-- 
]               Never tell me the odds!                 | ipv6 mesh networks [ 
]   Michael Richardson, Sandelman Software Works        | network architect  [ 
]     [email-masked]  http://www.sandelman.ca/        |   ruby on rails    [

---

From: Peter Gutmann <[email-masked]>
Date: Sat, 5 Jun 2021 11:20:48 +0000

>As an alternative option, if the only goal is to fix SHA1 fingerprints,

The first thing to do when "fixing" SHA1 fingerprints, meaning breaking all
existing fingerprints on the planet, is to define what properties they need to
have.  I can't think of anything for which SHA-256 is OK but SHA-1 isn't, so
before arbitrarily throwing SHA-256 in there we'd need to define what's needed
for a fingerprint algorithm to see why -1 doesn't meet the requirements, and
whether -256 does.

To pre-empt the inevitable response, collision-resistance isn't a property
that I can see is needed, given that X.509 and S/MIME have been using static
text strings as IDs since before PGP existed without anyone finding
vulnerabilities with them.  A fingerprint algorithm is just a way of mapping a
key to a fixed-length identifier, for which almost anything will do.

Peter.

---

From: Peter Gutmann <[email-masked]>
Date: Sat, 5 Jun 2021 12:22:38 +0000

>Specific v5 changes

Another thing I'd like to see changed in v5 is the incredibly annoying way
OpenPGP handles its PRF.  For every PRF use on the planet except OpenPGP, you
specify the number of iterations of the PRF to be applied.  For OpenPGP you
specify the number of bytes to output and then have to work backwards through
the PRF to figure out how many iterations this amounts to.  Making things even
worse, the count is encoded in a weirdo fixed-point format that can't be
passed as an integer count parameter to anything because it's not, or
alternatively that if passed as an integer has to then be converted back into
its oddball fixed-point format when written.  So:

  Replace the S2K 'count' value with a 32-bit integer specifying the number of
  PRF iterations to apply.

Peter.

---

From: Daniel Kahn Gillmor <[email-masked]>
Date: Sat, 05 Jun 2021 13:41:27 -0400

> such a thing?  I don't know if we can support multiple signatures with

Would it?  In what context?  The change for (2) has to do with how to
structure data fed into a hash algorithm for a certification ("key
signature") but isn't anything on the wire.

Honestly, i find (2) the least problematic of the changes listed -- it
doesn't affect the wire format, and it's just a slight change to the
hashing algorithm which already needs a special case for the bytes
hashed (0x99 for v4 vs 0x9a for v5).  If the WG decides that the change
in (2) is worth keeping because it just might come in handy for some
as-yet-unspecified scheme, that's a plausible argument to me, but i
don't see how it helps anyone skip over anything.  Can you explain more?

    --dkg

---

From: Daniel Kahn Gillmor <[email-masked]>
Date: Sat, 05 Jun 2021 13:37:10 -0400

>   Replace the S2K 'count' value with a 32-bit integer specifying the number of

I don't think the S2K updates for v5 have made it into the
crypto-refresh draft yet.  So i appreciate this comment but i hope we
can delay it until we address new forms of S2K (see e.g. commit
6337518cd35ee416129959982a10df85548b2117 in the step-by-step branch,
which is not yet merged).

    --dkg

---

From: Daniel Kahn Gillmor <[email-masked]>
Date: Sat, 05 Jun 2021 13:54:54 -0400

On Sat 2021-06-05 11:20:48 +0000, Peter Gutmann wrote:
> existing fingerprints on the planet,

The draft as it stands doesn't "break all existing fingerprints on the
planet" -- it just says "when you're making a new OpenPGP key, make it
v5 and you and your peers won't have to think about SHA-1 any more when
using this key".  By using a v5 key an implementation would also be
effectively signalling its compatibilty with any updated MTI choices
(which we haven't gotten to yet, because we're still wallowing here).

This is a change that, granted, should have been made a decade ago so
that we could have some deployment by now.  But better late than never.

> is to define what properties they need to have.  I can't think of
> anything for which SHA-256 is OK but SHA-1 isn't, so before
> arbitrarily throwing SHA-256 in there we'd need to define what's
> needed for a fingerprint algorithm to see why -1 doesn't meet the
> requirements, and whether -256 does.

We've been over this ground before in the WG, and i don't think anyone
who thinks about it deeply will disagree with you re: collision
resistance.

Nonetheless, fingerprints show up in many places, and many
implementations use them as unique identifiers, and can display
weird/broken behavior when encountering collisions, even if they're
sourced from the same (potentially malicious) actor.  Do we want to
encourage that kind of booby trap?  Furthermore, having to constantly
defend the use of SHA-1 when it is known to be deprecated *in other
contexts* is a tiresome exercise, and i think it'd be great if the
OpenPGP community could move past it.

We settled in the past iteration of this WG on SHA-256 as a
non-controverisal replacement, which is why it was re-merged into the
crypto-refresh draft.  If folks really want to re-litigate it, i suppose
that's possible, but i think we have bigger fish to fry (can we get to
those MTI changes, for example?) and I hope folks will think clearly
about whether such a detour is worthwhile.

     --dkg

---

From: Paul Wouters <[email-masked]>
Date: Sat, 5 Jun 2021 14:16:11 -0400 (EDT)

On Sat, 5 Jun 2021, Daniel Kahn Gillmor wrote:

> Furthermore, having to constantly

This is the main argument for me. Crypto libraries are trying to phase
out and disable SHA-1. Some crypto libraries have API's that allow
the caller to say "yes I know, you can trust my use of it" but not
all libraries have that. So it is useful to just move from SHA-1 to
SHA2 for this reason alone.

Paul

---

From: Michael Richardson <[email-masked]>
Date: Sat, 05 Jun 2021 16:29:07 -0400

> signature") but isn't anything on the wire.

Assume in the future that we have keys larger than 64K octets.  We are doing
that, not because there has been a quantum event, but because we are preparing for it.
We may still not even be sure which PQ scheme is the right one.

(There are multiple keys present, and possibly multiple signatures over both
end-user-data, and over keys)

A v5-capable tool, which does not speak these new formats can still process
the packets.  It could also verify that these large keys are signed by our
legacy algorithms.

--
Michael Richardson <[email-masked]>   . o O ( IPv6 IøT consulting )
           Sandelman Software Works Inc, Ottawa and Worldwide

---

From: Daniel Kahn Gillmor <[email-masked]>
Date: Sun, 06 Jun 2021 11:01:08 -0400

> We may still not even be sure which PQ scheme is the right one.

I think these are the right assumptions.

> end-user-data, and over keys)

Each "key signature" (certification) is its own OpenPGP packet, right?
and the context we're talking about here is a hash context that is used
to calculate a key signature.

While there is some zoomed-out view that might well have multiple
signatures, and there might be other data signatures that happen over
collections of information that do include keys, those contexts aren't
relevant for this specific calculation.

If the concern is how to "skip over" an artifact from an algorithm that
you don't understand, i don't think this increased size field is
relevant, because any implementation can just "skip over" the signature
by skipping to the end of the signature packet (whose length is already
known; this field doesn't appear on the wire), or not calculating the
digest itself at all.

> the packets.  It could also verify that these large keys are signed by our

yes, i agree with this, though it is not "skipping over" -- it's
"preparing for certifications of larger keys".  We still don't know
whether this is *sufficient* for dealing with whatever eventual PQ
algorithm arises, but i agree with you that it seems to be *necessary*
to handle them.

It might be worth including change (2) as a precautionary gamble, since
it doesn't appear to have any downside other than a slightly tweaked
codepath during certification creation and verification.

What do other folks in the WG think?

            --dkg

---

From: Nickolay Olshevsky <[email-masked]>
Date: Mon, 7 Jun 2021 13:13:50 +0300

Hi,

It's slightly out of the original questions, but still related to the v5 
keys/sigs.

Basically, given that year 2038 will come in 17 years, and previous RFC 
4880 is already 14 years old without any replacement (yet), why v5 keys 
and signatures still have 32-bit creation time?

Or did I miss some discussion regarding this?

On 04.06.2021 09:42, Daniel Kahn Gillmor wrote:
> ...
> _______________________________________________
> openpgp mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/openpgp

-- 
   Best regards,
   Nickolay Olshevsky
   [email-masked]

---

From: Peter Pentchev <[email-masked]>
Date: Mon, 7 Jun 2021 13:22:24 +0300

On Mon, Jun 07, 2021 at 01:13:50PM +0300, Nickolay Olshevsky wrote:
> Basically, given that year 2038 will come in 17 years, and previous RFC 4880
> is already 14 years old without any replacement (yet), why v5 keys and
> signatures still have 32-bit creation time?
> 

Obviously not speaking for any of the people who actually work on this,
but you need to keep in mind that the time field is defined as
an *unsigned* 32-bit number, so we'll have another 68 years after the
year 2038 to take care of that.

G'luck,
Peter

-- 
Peter Pentchev  [email-masked] [email-masked] [email-masked]
PGP key:        http://people.FreeBSD.org/~roam/roam.key.asc
Key fingerprint 2EE7 A7A5 17FC 124C F115  C354 651E EFB0 2527 DF13

---

From: Peter Gutmann <[email-masked]>
Date: Mon, 7 Jun 2021 11:33:54 +0000

Peter Pentchev <[email-masked]> writes:

>Obviously not speaking for any of the people who actually work on this, but
>you need to keep in mind that the time field is defined as an *unsigned* 32-
>bit number, so we'll have another 68 years after the year 2038 to take care
>of that.

Except that time_t is signed so it's going to cause breakage if you just
assign a 32-bit OpenPGP time to a 32-bit time_t.  Making it 64 bits would both
prevent this and signal to 32-bit time_t users that they need to take special
care with time values.

Peter.

---

From: Peter Pentchev <[email-masked]>
Date: Mon, 7 Jun 2021 14:46:11 +0300

> prevent this and signal to 32-bit time_t users that they need to take special

Well, if any implementation still uses a signed 32-bit time_t C type in
the year 2038, it will not be able to do anything anyway. ICBW, but is
the point of the standard not to define the wire format, and not
implementation-specific details? An unsigned 32-bit value for the wire
format should be fine for this century.

But maybe I'll just shut up and let the people who have already
discussed modifications to the standard (like you, so yeah, sorry)
say whether anybody has ever raised this before and whether it has been
discussed.

G'luck,
Peter

---

From: Michael Richardson <[email-masked]>
Date: Mon, 07 Jun 2021 08:23:46 -0400

> to calculate a key signature.

yes, but I'm assuming that we might sign these new keys using legacy signatures.
(and vv)

    > "preparing for certifications of larger keys".

Agreed.

---

From: Daniel Kahn Gillmor <[email-masked]>
Date: Mon, 07 Jun 2021 09:46:20 -0400

> format should be fine for this century.

The standard is good until 2106, barring implementation failures like
what you describe.

I've opened
https://gitlab.com/sequoia-pgp/openpgp-interoperability-test-suite/-/issues/55
to suggest some possible tests that would try to identify such
implementation failures.

> say whether anybody has ever raised this before and whether it has been

this came up back in 2016 here:

    https://mailarchive.ietf.org/arch/msg/openpgp/cb32QpGl5-PP02s_dYsTkl3rVK0/

At that time, there was no clear consensus, and (different) reasonable
people advocated for:

 - leaving the timestamps in the standard untouched
 - using a 40-bit timestamp (measured in seconds since the epoch)
 - using a signed 64-bit timestamp (measured in seconds since the epoch)
 - using a signed 64-bit timestamp (measured in 100ns units since the epoch)
 - using ISO 8601 timestamp representations

I'd prefer to not focus on that question right now: aside from not
having consensus, i'd argue it's outside the scope of our current
charter, which is for cryptographic refresh, and we're behind on getting
the crypto refresh done.

    --dkg

---

From: Justus Winter <[email-masked]>
Date: Tue, 08 Jun 2021 09:17:14 +0200

> Possible Outcomes

My preferred outcome is b, but c may be more practical.

We (Sequoia) have partially implemented proposed changes from
RFC4880bis, but starting with our first stable release we decided not to
emit any artifacts that use new packet versions.

Justus