ietf-openpgp
[Top] [All Lists]

Re: Conventional Encryption Keys, 5.3 - more notes

1998-03-26 22:15:12
On Thu, 26 Mar 1998, Hal Finney wrote:

tzeruch(_at_)ceddec(_dot_)com writes:
1. There are actually two forms of the SKESK.  The first is when the key
is derived from the passphrase (old style) described by the paragraph "If
the encrypted session key is not present...".  If this type is present, it
should be the only SKESK present (and no PKESK).

Yes, this is true.

Technically you could have a single one of these and use the result to
create SKESK and PKESK blocks, but this is only for backwards
compatibility.

2. The S2K structure also contains a byte describing a symmetric
algorithm.  For form in 1. above, it MUST be the same as what is used to
encrypt the message.  This should also match the second octet in the
SKESK body.

No, it doesn't.  The S2K object has a hash algorithm but no encryption
algorithm specifier.  So there is no matching involved here.

OOPS, When I wrote the routine (long before the spec, and before the
source to PGP5.0 was finished scanning), I had the cipher type byte just
before the salt and hash type.  When I was figuring out the structure I
always assumed the cipher type was prepended.  And it is in this case, but
isn't part of the S2K.  But it keeps sticking in my mind as if it is. 
Apologies. 

There are two "layers" of encryption being used in this case.  The
message is encrypted with a (random) SK, using a conventional encryption
algorithm.  Then the SK is concatenated with the algorithm ID, encrypted
with the hashed passphrase and stored at the end of the SKESK block.
That second layer of encryption can use a different encryption algorithm.

The algorithm for that second layer is in the SKESK block, 2nd octet.
The algorithm for the message encryption is then revealed when the SK
is decrypted.

OK, that makes sense.  It seemed that it might work this way (but I had
trouble with my stuck memory as I explained above).

5. For form 2, the only check is the match between the 2nd octet of the
SKESK body and the first of the decrypted session key.  Multiple SKESKs
can produce multiple possible keys and each will have to be tried to see
if the 10 byte check will work (since there is no checksum).

There is no match check.  You have to try the passphrase against each
SKESK, and then do a test decryption of the first 10 bytes of the message
to see if it works.  You are right that a checksum would help here,
although it causes me backwards compatibility problems if we change it.
(If we do change it, we should add an IV for the SK encryption layer.)

Lots of things can cause backwards compatibility problems, but maybe not
this format extension.  If the cipher type is known (the first byte), the
length of the key material is also known, so if the packet ends at the
right point there is no checksum (and depending on how you wrote the code
the checksum should be discarded since only the first N bytes are plugged
into the key routine - this is how my code reacts - you can send it 1000
bytes of key material, but it will only use 16 for IDEA and CAST, and 24
for 3DES - it isn't passed the array size). 

If PGP 5.x ignores trailing bytes after the used key material, you could
add a checksum (or CRC - the one for the ascii armor is hanging around, or
something else).

So Opgp might be able to add a few check bytes to discard bad SKESKs,
while PGP 5.x would simply still try each one.

6. Do I scan the PKESKs first, and if one works ignore the SKESKs, or do I
ask for a passphrase anytime I encounter a SKESK?  If there was a rule of
the form "PKESKs MUST come before SKESKs"  this would be easier. 

You have the same problem if there are multiple PKESKs and you have the
private key for more than one of them.  We scan them all.

Maybe, but with all the checksumming and other verification going on, it
is 99.99% likely that the first successful PKESK will contain a correct
key.  And then you don't need to check the rest.

7. Without padding or something similar just checksums aren't really that
good since N random bytes will tend to coalesce around 127.5*N.  With
padding, the first zero byte must occur N+3 bytes before the end, the
following byte must be the valid ciphertype, and the checksum much match. 

Yes, when we redo this from scratch it would probably be better to do
something better than a simple checksum.

Which is what the PKESKs have (and I check for all this - that is what I
describe in #7, and reject anything failing), and what the SKESKs don't
have, so I must try each such key in the lock to see if it turns. 

--- reply to tzeruch - at - ceddec - dot - com ---


<Prev in Thread] Current Thread [Next in Thread>