提交 33726188 编写于 作者: B Bernd Edlinger

Make err_clear_constant_time really constant time

[extended tests]
Reviewed-by: NPaul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/8542)

(cherry picked from commit 94dc53a3f7549040dd9e61a25485070c14b41c49)
上级 e3568508
...@@ -523,8 +523,24 @@ static unsigned long get_error_values(int inc, int top, const char **file, ...@@ -523,8 +523,24 @@ static unsigned long get_error_values(int inc, int top, const char **file,
return ERR_R_INTERNAL_ERROR; return ERR_R_INTERNAL_ERROR;
} }
while (es->bottom != es->top) {
if (es->err_flags[es->top] & ERR_FLAG_CLEAR) {
err_clear(es, es->top);
es->top = es->top > 0 ? es->top - 1 : ERR_NUM_ERRORS - 1;
continue;
}
i = (es->bottom + 1) % ERR_NUM_ERRORS;
if (es->err_flags[i] & ERR_FLAG_CLEAR) {
es->bottom = i;
err_clear(es, es->bottom);
continue;
}
break;
}
if (es->bottom == es->top) if (es->bottom == es->top)
return 0; return 0;
if (top) if (top)
i = es->top; /* last error */ i = es->top; /* last error */
else else
...@@ -913,25 +929,6 @@ int ERR_clear_last_mark(void) ...@@ -913,25 +929,6 @@ int ERR_clear_last_mark(void)
return 1; return 1;
} }
#ifdef UINTPTR_T
# undef UINTPTR_T
#endif
/*
* uintptr_t is the answer, but unfortunately C89, current "least common
* denominator" doesn't define it. Most legacy platforms typedef it anyway,
* so that attempt to fill the gaps means that one would have to identify
* that track these gaps, which would be undesirable. Macro it is...
*/
#if defined(__VMS) && __INITIAL_POINTER_SIZE==64
/*
* But we can't use size_t on VMS, because it adheres to sizeof(size_t)==4
* even in 64-bit builds, which means that it won't work as mask.
*/
# define UINTPTR_T unsigned long long
#else
# define UINTPTR_T size_t
#endif
void err_clear_last_constant_time(int clear) void err_clear_last_constant_time(int clear)
{ {
ERR_STATE *es; ERR_STATE *es;
...@@ -943,11 +940,11 @@ void err_clear_last_constant_time(int clear) ...@@ -943,11 +940,11 @@ void err_clear_last_constant_time(int clear)
top = es->top; top = es->top;
es->err_flags[top] &= ~(0 - clear); /*
es->err_buffer[top] &= ~(0UL - clear); * Flag error as cleared but remove it elsewhere to avoid two errors
es->err_file[top] = (const char *)((UINTPTR_T)es->err_file[top] & * accessing the same error stack location, revealing timing information.
~((UINTPTR_T)0 - clear)); */
es->err_line[top] |= 0 - clear; clear = constant_time_select_int(constant_time_eq_int(clear, 0),
0, ERR_FLAG_CLEAR);
es->top = (top + ERR_NUM_ERRORS - clear) % ERR_NUM_ERRORS; es->err_flags[top] |= clear;
} }
...@@ -479,7 +479,7 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, ...@@ -479,7 +479,7 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from,
goto err; goto err;
} }
RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_PADDING_CHECK_FAILED); RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_PADDING_CHECK_FAILED);
err_clear_last_constant_time(r >= 0); err_clear_last_constant_time(1 & ~constant_time_msb(r));
err: err:
BN_CTX_end(ctx); BN_CTX_end(ctx);
......
...@@ -37,6 +37,7 @@ extern "C" { ...@@ -37,6 +37,7 @@ extern "C" {
# define ERR_TXT_STRING 0x02 # define ERR_TXT_STRING 0x02
# define ERR_FLAG_MARK 0x01 # define ERR_FLAG_MARK 0x01
# define ERR_FLAG_CLEAR 0x02
# define ERR_NUM_ERRORS 16 # define ERR_NUM_ERRORS 16
typedef struct err_state_st { typedef struct err_state_st {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册