Subject: V3 secret keys

From: Ben Laurie <[email-masked]>
Date: Thu, 02 Feb 2006 13:48:38 +0000

in 5.5.3 it says:

"Furthermore, the CFB state is resynchronized at the beginning of each
new MPI value,  so that the CFB block boundary is aligned with the start
of the MPI data."

I can't find anywhere a precise (or even an imprecise) definition of
"resynchronized". What exactly does it mean?

Does it mean that the IV is reset to whatever it was at the start of the
current block? Does it mean that we use the partially-updated IV, but
set the position back to the beginning? Does it mean we reset the IV to
the initial value and start again? Or what?

Cheers,

Ben.

-- 
http://www.apache-ssl.org/ben.html       http://www.thebunker.net/

"There is no limit to what a man can do or how far he can go if he
doesn't mind who gets the credit." - Robert Woodruff

---

From: [email-masked] (Daniel A. Nagy)
Date: Thu, 2 Feb 2006 15:06:12 +0100

> the initial value and start again? Or what?

It means the usual CFB synchronization with outputting a partial block and
shifting the IV.

-- 
Daniel

---

From: Ben Laurie <[email-masked]>
Date: Thu, 02 Feb 2006 17:10:32 +0000

> It means the usual CFB synchronization with outputting a partial block and

If that means anything at all, you appear to be describing standard CFB
when applied to a partial block, which I assume the above is not.

---

From: Adam Back <[email-masked]>
Date: Thu, 2 Feb 2006 13:46:01 -0500

The pgp263 docs say (not much better):

| One unusual point about the way encryption is done.  Using the IDEA
| cipher in CFB mode, the first 10 bytes are decrypted normally, but
| bytes 10 to 17, the first 8 bytes of the data proper, are encrypted
| using bytes 2 to 9 (the last 8 bytes of the key check prefix) as the
| IV.  This is essentially using CFB-16 for one part of the
| encryption, while CFB-64 is used elsewhere.

So actually (I implemented this funky thing at some point to get
compat with some parts of pgp) what it means is you encrypt normally
with CFB-64 (encrypt previous 8 bytes, xor with plaintext).  When you
get to one of these sync points, it may be part way thru a block, so
you encrypt the short block as normal.  Then you take the previous 8
bytes of ciphertext and use it as the IV and continue.

So it I think really is standard partial block encryption, but to
resume after the block you take the last 8 bytes from the end of the
previous ciphertext chunk and use as the IV for the next chunk.

I agree what is written is pretty unclear.

Adam

---

From: Wim Lewis <[email-masked]>
Date: Thu, 2 Feb 2006 11:57:50 -0800 (PST)

On Thu, 2 Feb 2006, Adam Back wrote:
> compat with some parts of pgp)

Likewise :-) I had to go examine the pgp2.6.2 source to be sure I was
doing it right, IIRC.

> previous ciphertext chunk and use as the IV for the next chunk.

As I understand it (it's been a while...), normal CFB has no concept of 
partial block encryption except at the end of the stream. Even there, one 
could argue, you're just padding the stream to a block boundary, then 
truncating the output back to the original length, and taking advantage of 
the property that the last block's worth of bits are independent
(no mixing / avalanche).

So one way to describe PGP's operation is to say that each field is
encrypted independently using CFB, and the results are concatenated;
the fields after the first use an IV equal to the last eight bytes of
the output so far. (If the total ciphertext at that point is 
still too short, then bytes from the original IV are used as if they
preceded the cipher stream.)

For fields which are a multiple of the block length, this is the same
as normal CFB; for short fields, some of the ciphertext gets used as
key material for more than one invocation of the block cipher: once
for the last block of a field, and again (mixed with new ciphertext)
for the first block of the next field.

What I've written above is very much not the way that pgp2.6.2 thinks of 
the operation, but I'm pretty sure it's equivalent.

IIRC, there are only two places in PGP where the odd feedback mode
comes into play: the check bytes at the beginning of an encrypted
file, and encrypted MPIs in the secret key packet.

> I agree what is written is pretty unclear.

There's a comment in pgp2.6.2's idea.c which explains it reasonably well,
I think.

>> when applied to a partial block, which I assume the above is not.

From the comment in 2.6.2:

  * Phil invented a unique way of doing CFB that's sensitive to semantic
  * boundaries within the data being encrypted.
[... detailed explanation snipped ... ]
  *                                    This is equivalent to using a
  * shorter feedback length (if you're familiar with the general CFB
  * technique) briefly, and doesn't weaken the cipher any (using shorter
  * CFB lengths makes it stronger, actually), it just makes it a bit unusual.

The unusual aspect is the varying feedback length, where the feedback
length depends on the presence of a semantic boundary in the plaintext.
Normally CFB operates on an undifferentiated stream-of-bytes, and field
boundaries are not preserved nor significant.

---

From: [email-masked] (Daniel A. Nagy)
Date: Thu, 2 Feb 2006 21:43:04 +0100

On Thu, Feb 02, 2006 at 11:57:50AM -0800, Wim Lewis wrote:

> partial block encryption except at the end of the stream.

Yes it does. The whole point of CFB is that it can encrypt arbitrary block
lengths up to the block size of the used block cipher. That is why it is
used in interactive applications.

> the operation, but I'm pretty sure it's equivalent.

Right, your description is equivalent, but different from the traditional
view of CFB. I implemented CFB resynchronization based on the description in
Bruce Schneier's "Applied Cryptography", without looking into any
implementations. The result was interoperable at first attempt.

>  * CFB lengths makes it stronger, actually), it just makes it a bit unusual.

I somewhat disagree. Following semantics with block length may indeed be
PZ's innovation, but variable block length is one of the reasons why CFB has
been invented in the first place.
 
-- 
Daniel

---

From: Ben Laurie <[email-masked]>
Date: Fri, 03 Feb 2006 15:22:21 +0000

Wim Lewis wrote:
> partial block encryption except at the end of the stream. Even there,
> one could argue, you're just padding the stream to a block boundary,
> then truncating the output back to the original length, and taking
> advantage of the property that the last block's worth of bits are
> independent
> (no mixing / avalanche).
> 
> the output so far. (If the total ciphertext at that point is still too
> short, then bytes from the original IV are used as if they

Yes, this is what OpenSSL implements, and it definitely works with
OpenPGP (not surprisingly, because this is really equivalent to
decrypting the whole thing using CFB and then slicing it up afterwards).

> for the first block of the next field.

No, this I don't agree with.

> the operation, but I'm pretty sure it's equivalent.

I think not.

> file, and encrypted MPIs in the secret key packet.

I do not know what you mean by the "odd feedback mode".

> boundaries are not preserved nor significant.

I don't believe this is an accurate description of what's going on.

At least, not with v4 secret keys, which allegedly are nearly the same
(apart from "resynchronisation" - which I still am in the dark about).

Cheers,

Ben.

---

From: Ben Laurie <[email-masked]>
Date: Fri, 03 Feb 2006 15:14:52 +0000

> previous ciphertext chunk and use as the IV for the next chunk.

OK, but this is how CFB works normally (at least, as implemented in
OpenSSL), so what you appear to be saying is that in v3 mode you carry
on as if the two plaintext bytes (the MPI length field) weren't there.
Right?

---

From: Ben Laurie <[email-masked]>
Date: Fri, 03 Feb 2006 15:29:25 +0000

> implementations. The result was interoperable at first attempt.

I (reluctantly) dug out my copy of "Applied Cryptography" and I see no
mention of "resynchronisation".

---

From: [email-masked] (Daniel A. Nagy)
Date: Sat, 4 Feb 2006 10:58:58 +0100

> mention of "resynchronisation".

Figure 9.9 (in Section 9.6) shows the encryption and decryption of a partial
block. Resynchronization is making the current block partial (ending it
at the current position) and starting a new one.

-- 
Daniel