]> www.wagner.pp.ru Git - openssl-gost/engine.git/commitdiff
gost_crypt: process full available block in CFB and CNT mode openssl_1_1_0
authorAlexei A. Smekalkine <ikle@ikle.ru>
Mon, 30 Nov 2020 21:20:59 +0000 (00:20 +0300)
committerDmitry Belyavskiy <beldmit@users.noreply.github.com>
Sun, 6 Dec 2020 15:46:42 +0000 (16:46 +0100)
If at the input of the encryption function in the CFB mode we have
an integer number of blocks, then in the main loop all blocks will be
processed, except for the last one due to an incorrect border check.
The last block will be fully processed as a "partial" remainder, but
the initialization vector will not be updated. And, thus, the value
of IV will always be incorrect in this case.

This breaks stateless protocols due to an invalid initialization vector:
all messages except the first cannot be decrypted. (Naturally, we are
talking about a case with disabled key meshing, which does not allow
context recovery due to an erroneous implementation.)

It is worth noting here that the code for processing partial blocks
(both at the input of the encryption functions and at the output) is
a historically unnecessary artifact, since we do not set the
EVP_CIPH_FLAG_CUSTOM_CIPHER flag and, as a result, OpenSSL processes
partial blocks for us.

This patch corrects the checking of the main loop boundary.

A similar error is present in the code for the CNT mode, but there it
does not manifest itself in any way, because the restoration of the
state in this mode is impossible: even after disabling key meshing, we
still have the state-dependent transformation of the IV.

As an extra result of this fix, the code for processing partial blocks
can be completely removed now.

gost_crypt.c

index c7c8caaeaa70b96166f2d9762a7e804f176b98f1..08a82a9e58a7e1bd8177f0e009bf908de2c9eb41 100644 (file)
@@ -549,7 +549,7 @@ int gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
         }
     }
 
-    for (; i + 8 < inl; i += 8, in_ptr += 8, out_ptr += 8) {
+    for (; (inl - i) >= 8; i += 8, in_ptr += 8, out_ptr += 8) {
         /*
          * block cipher current iv
          */
@@ -610,7 +610,7 @@ static int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out,
         }
     }
 
-    for (; i + 8 < inl; i += 8, in_ptr += 8, out_ptr += 8) {
+    for (; (inl - i) >= 8; i += 8, in_ptr += 8, out_ptr += 8) {
         /*
          * block cipher current iv
          */