public abstract class OpenPgpCfbBlockMechanism extends BlockMechanism
The OpenPGPCFB block mode is a variant of the standard
CFB
mode. The main difference with the OpenPGP variant is that a plaintext
initialization vector is not used, and a random prefix is encrypted prior to
encrypting the plaintext (and decrypted prior to decrypting the ciphertext).
The random prefix is always two bytes larger than the cipher block size and
the last two bytes of the random prefix are identical to the previous two
bytes (two repeated bytes). The intention with this random prefix was to
permit a quick check at decryption time of whether or not the proper key was
being used. This implementation does not employ this check because doing so
permits an attack on the cipher as described by Serge Mister and Robert
Zuccheratto in An Attack on CFB
Mode Encryption As Used By OpenPGP. OpenPGPCFB mode is defined as
follows:
b be the block size of the underlying cipher.0 be the b-byte all zero block.[X]i,j be the ith and
jth bytes of the block X.[X]i..j be the ith through
jth bytes of X.|| represent the concatenation operation.CIPHK represent encryption with the symmetric
key K by the underlying block cipher.xor represent the bitwise exclusive-or operationP represent a plaintext block and C
represent ciphertext block, both of which are b bytes in
length.PR represent the random prefix and CR
represent the encrypted random prefix, both of which are b + 2
bytes in length.
OpenPGPCFB Encryption:
[CR]1..b = CIPHK(0) xor [PR]1..b
[CR]b+1,b+2 = [CIPHK([CR]1..b)]1,2 xor [PR]b+1,b+2
C1 = CIPHK([CR]3..b+2) xor P1
Cj = CIPHK(Cj-1) xor Pj for j = 2..n-1
Cn = [(CIPHK(Cn-1))]1..u xor Pn
ciphertext = CR || C1 || C2 || ... || Cn
OpenPGPCFB Decryption:
[PR]1..b = CIPHK(0) xor [CR]1..b
[PR]b+1,b+2 = [CIPHK([PR]1..b)]1,2 xor [CR]b+1,b+2
P1 = CIPHK([PR]3..b+2) xor C1
Pj = CIPHK(Pj-1) xor Cj for j = 2..n-1
Pn = [(CIPHK(Pn-1))]1..u xor Cn
random prefix = PR
plaintext = P1 || P2 || ... || Pn
During encryption, before the any plaintext is processed, a random prefix is automatically generated and processed. Processing of the random prefix consists of encrypting it, which is done in two steps. First, an all zero block is processed using the forward cipher function. The output from this operation is then exclusive-ORed with the first block of the random prefix, which produces the first block of the encrypted random prefix. Then, the first block of the encrypted random prefix is processed using the forward cipher function. The first two bytes of output from this operation are exclusive-ORed with the remaining two bytes of the random prefix, which produces the final two bytes of the encrypted random prefix.
Once the random prefix has been processed, processing of the plaintext can
begin. Generation of the first block of ciphertext is slightly different than
all following blocks. The first block of ciphertext is generated by
processing the least significant b bytes of the encrypted random
prefix using the forward cipher function, then exclusive-ORing that result
with the first block of plaintext. All remaining blocks of ciphertext are
generated by processing the previous ciphertext block using the forward
cipher function, then exclusive-ORing that result with the current block of
plaintext. For the last plaintext block, which may be a partial block of
u bytes, only the most significant u bytes of the
forward cipher function output are used for the exclusive-OR operation; the
remaining b-u bits are discarded.
When encrypting using this block mechanism, the random prefix is
automatically generated internally; it MUST NOT be generated externally and
passed in prefixed to the input, otherwise this block mechanism will not
operate as intended. The encrypted random prefix is returned as the first
b + 2 bytes of output; it is part of the resulting ciphertext.
During decryption, the random prefix is automatically processed and discarded. Processing the random prefix consists of decrypting it, which is done in two steps. First, an all zero block is processed using the forward cipher function. The output from this operation is then exclusive-ORed with the first block of the encrypted random prefix, which produces the first block of the random prefix. Then, the first block of the random prefix is processed using the forward cipher function. The first two bytes of output from this operation are exclusive-ORed with the remaining two bytes of the encrypted random prefix, which produces the final two bytes of the random prefix. Once the random prefix has been decrypted and recovered, it is simply discarded (an integrity check is NOT done).
Once the random prefix has been processed, the remaining bytes of ciphertext
can be processed. Generation of the first block of plaintext is slightly
different than all following blocks. The first block of plaintext is
generated by processing the least significant b bytes of the
random prefix using the forward cipher function, then exclusive-ORing that
result with the current block of ciphertext (block following the encrypted
random prefix). All remaining blocks of plaintext are generated by processing
the previous plaintext block using the forward cipher function, then
exclusive-ORing that* result with the current block of ciphertext. For the
last ciphertext block, which may be a partial block of u bytes,
only the most significant u bytes of the forward cipher function
output are used for the exclusive-OR operation; the remaining
b-u bits are discarded.
When decrypting using this block mechanism, the encrypted random prefix is automatically removed internally; it MUST be passed in prefixed to the input otherwise this block mechanism will not operate as intended. The random prefix is discarded internally and NOT returned as part of the resulting plaintext.
For OpenPGPCFB it is not required that the plaintext be a sequence of one or
more complete blocks. Thus, padding is not required by OpenPGPCFB mode;
however, padding can still be used with OpenPGPCFB mode. When using padding,
the total number of bits in the plaintext becomes a positive multiple of the
block size (b) by appending some extra bits to the trailing end
of the data string as the last step in the formatting of the plaintext. The
padding bits must then be removed unambiguously by the receiver following
decryption of the ciphertext to arrive at the original message. In Entrust's
symmetric cipher architecture, this is accomplished by using a
PaddingMechanism in conjunction with the symmetric cipher operating in
OpenPGPCFB mode.