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 |
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) |
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) |