ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/src/vendor-crypto/openssl/dist/crypto/evp/evp_enc.c
(Generate patch)

Comparing vendor-crypto/openssl/dist/crypto/evp/evp_enc.c (file contents):
Revision 6894 by laffer1, Sun Oct 12 20:29:54 2014 UTC vs.
Revision 6895 by laffer1, Tue Oct 28 11:51:38 2014 UTC

# Line 64 | Line 64
64   #ifndef OPENSSL_NO_ENGINE
65   #include <openssl/engine.h>
66   #endif
67 + #include "../constant_time_locl.h"
68   #include "evp_locl.h"
69  
70   #ifdef OPENSSL_FIPS
# Line 301 | Line 302 | int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned cha
302  
303   int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
304          {
305 <        int i,n;
306 <        unsigned int b;
305 >        unsigned int i, b;
306 >        unsigned char pad, padding_good;
307  
308          *outl=0;
309 <        b=ctx->cipher->block_size;
309 >        b=(unsigned int)(ctx->cipher->block_size);
310          if (ctx->flags & EVP_CIPH_NO_PADDING)
311                  {
312                  if(ctx->buf_len)
# Line 324 | Line 325 | int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned
325                          return(0);
326                          }
327                  OPENSSL_assert(b <= sizeof ctx->final);
328 <                n=ctx->final[b-1];
329 <                if (n == 0 || n > (int)b)
328 >                pad=ctx->final[b-1];
329 >
330 >                padding_good = (unsigned char)(~constant_time_is_zero_8(pad));
331 >                padding_good &= constant_time_ge_8(b, pad);
332 >
333 >                for (i = 1; i < b; ++i)
334                          {
335 <                        EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
336 <                        return(0);
335 >                        unsigned char is_pad_index = constant_time_lt_8(i, pad);
336 >                        unsigned char pad_byte_good = constant_time_eq_8(ctx->final[b-i-1], pad);
337 >                        padding_good &= constant_time_select_8(is_pad_index, pad_byte_good, 0xff);
338                          }
339 <                for (i=0; i<n; i++)
340 <                        {
341 <                        if (ctx->final[--b] != n)
342 <                                {
343 <                                EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
344 <                                return(0);
345 <                                }
346 <                        }
347 <                n=ctx->cipher->block_size-n;
348 <                for (i=0; i<n; i++)
349 <                        out[i]=ctx->final[i];
344 <                *outl=n;
339 >
340 >                /*
341 >                 * At least 1 byte is always padding, so we always write b - 1
342 >                 * bytes to avoid a timing leak. The caller is required to have |b|
343 >                 * bytes space in |out| by the API contract.
344 >                 */
345 >                for (i = 0; i < b - 1; ++i)
346 >                        out[i] = ctx->final[i] & padding_good;
347 >                /* Safe cast: for a good padding, EVP_MAX_IV_LENGTH >= b >= pad */
348 >                *outl = padding_good & ((unsigned char)(b - pad));
349 >                return padding_good & 1;
350                  }
351          else
352 <                *outl=0;
353 <        return(1);
352 >                {
353 >                *outl = 0;
354 >                return 1;
355 >                }
356          }
357  
358   void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines