Revert "RT3425: constant-time evp_enc"
authorEmilia Kasper <emilia@openssl.org>
Wed, 17 Dec 2014 11:08:27 +0000 (12:08 +0100)
committerEmilia Kasper <emilia@openssl.org>
Wed, 17 Dec 2014 13:54:17 +0000 (14:54 +0100)
Causes more problems than it fixes: even though error codes
are not part of the stable API, several users rely on the
specific error code, and the change breaks them. Conversely,
we don't have any concrete use-cases for constant-time behaviour here.

This reverts commit 4aac102f75b517bdb56b1bcfd0a856052d559f6e.

Reviewed-by: Andy Polyakov <appro@openssl.org>
crypto/evp/Makefile
crypto/evp/evp_enc.c

index 1062afc4a3d96d0a39b347210135f227e84a113e..fd5727dd455acb7e929f8e313620c69fe5973c3d 100644 (file)
@@ -406,7 +406,7 @@ evp_enc.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
 evp_enc.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 evp_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 evp_enc.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-evp_enc.o: ../constant_time_locl.h ../cryptlib.h evp_enc.c evp_locl.h
+evp_enc.o: ../cryptlib.h evp_enc.c evp_locl.h
 evp_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 evp_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 evp_err.o: ../../include/openssl/err.h ../../include/openssl/evp.h
index 2f121ff9cb67313b9d351ae6aac074f042bb1b45..4314b43719f4954ddba0322932f211d771da2cbc 100644 (file)
@@ -64,7 +64,6 @@
 #ifndef OPENSSL_NO_ENGINE
 #include <openssl/engine.h>
 #endif
-#include "constant_time_locl.h"
 #include "evp_locl.h"
 
 const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT;
@@ -492,21 +491,21 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
 
 int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
        {
-       unsigned int i, b;
-        unsigned char pad, padding_good;
+       int i,n;
+       unsigned int b;
        *outl=0;
 
        if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
                {
-               int ret = ctx->cipher->do_cipher(ctx, out, NULL, 0);
-               if (ret < 0)
+               i = ctx->cipher->do_cipher(ctx, out, NULL, 0);
+               if (i < 0)
                        return 0;
                else
-                       *outl = ret;
+                       *outl = i;
                return 1;
                }
 
-       b=(unsigned int)(ctx->cipher->block_size);
+       b=ctx->cipher->block_size;
        if (ctx->flags & EVP_CIPH_NO_PADDING)
                {
                if(ctx->buf_len)
@@ -525,34 +524,28 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
                        return(0);
                        }
                OPENSSL_assert(b <= sizeof ctx->final);
-               pad=ctx->final[b-1];
-
-               padding_good = (unsigned char)(~constant_time_is_zero_8(pad));
-               padding_good &= constant_time_ge_8(b, pad);
-
-                for (i = 1; i < b; ++i)
+               n=ctx->final[b-1];
+               if (n == 0 || n > (int)b)
                        {
-                       unsigned char is_pad_index = constant_time_lt_8(i, pad);
-                       unsigned char pad_byte_good = constant_time_eq_8(ctx->final[b-i-1], pad);
-                       padding_good &= constant_time_select_8(is_pad_index, pad_byte_good, 0xff);
+                       EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
+                       return(0);
                        }
-
-               /*
-                * At least 1 byte is always padding, so we always write b - 1
-                * bytes to avoid a timing leak. The caller is required to have |b|
-                * bytes space in |out| by the API contract.
-                */
-               for (i = 0; i < b - 1; ++i)
-                       out[i] = ctx->final[i] & padding_good;
-               /* Safe cast: for a good padding, EVP_MAX_IV_LENGTH >= b >= pad */
-               *outl = padding_good & ((unsigned char)(b - pad));
-               return padding_good & 1;
+               for (i=0; i<n; i++)
+                       {
+                       if (ctx->final[--b] != n)
+                               {
+                               EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
+                               return(0);
+                               }
+                       }
+               n=ctx->cipher->block_size-n;
+               for (i=0; i<n; i++)
+                       out[i]=ctx->final[i];
+               *outl=n;
                }
        else
-               {
-               *outl = 0;
-               return 1;
-               }
+               *outl=0;
+       return(1);
        }
 
 void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)