aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pk_pad/eme_oaep
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2015-10-16 17:39:43 -0400
committerJack Lloyd <[email protected]>2015-10-16 17:39:43 -0400
commitea07110c86c7ae2601e71dd3c1134873ccfd721f (patch)
tree1ccbb775a624d8a977f21a37b2d60a619fc0824f /src/lib/pk_pad/eme_oaep
parentf257cb324614adb5f9266ca185ab2bfeb64b1dd4 (diff)
Make PKCS #1 and OAEP decoding constant time to avoid oracle attacks
via timing channels. Add annotations for checking constant-time code using ctgrind to PKCS #1 and OAEP, as well as IDEA and Curve25519 which were already written as constant time code.
Diffstat (limited to 'src/lib/pk_pad/eme_oaep')
-rw-r--r--src/lib/pk_pad/eme_oaep/oaep.cpp32
1 files changed, 16 insertions, 16 deletions
diff --git a/src/lib/pk_pad/eme_oaep/oaep.cpp b/src/lib/pk_pad/eme_oaep/oaep.cpp
index f214c25d2..48a9b5c63 100644
--- a/src/lib/pk_pad/eme_oaep/oaep.cpp
+++ b/src/lib/pk_pad/eme_oaep/oaep.cpp
@@ -1,13 +1,13 @@
/*
* OAEP
-* (C) 1999-2010 Jack Lloyd
+* (C) 1999-2010,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#include <botan/oaep.h>
#include <botan/mgf1.h>
-#include <botan/mem_ops.h>
+#include <botan/internal/ct_utils.h>
namespace Botan {
@@ -92,33 +92,33 @@ secure_vector<byte> OAEP::unpad(const byte in[], size_t in_length,
input.data(), m_Phash.size(),
&input[m_Phash.size()], input.size() - m_Phash.size());
- bool waiting_for_delim = true;
- bool bad_input = false;
+ BOTAN_CONST_TIME_POISON(input.data(), input.size());
+
size_t delim_idx = 2 * m_Phash.size();
+ byte waiting_for_delim = 0xFF;
+ byte bad_input = 0;
- /*
- * GCC 4.5 on x86-64 compiles this in a way that is still vunerable
- * to timing analysis. Other compilers, or GCC on other platforms,
- * may or may not.
- */
for(size_t i = delim_idx; i < input.size(); ++i)
{
- const bool zero_p = !input[i];
- const bool one_p = input[i] == 0x01;
+ const byte zero_m = ct_is_zero_8(input[i]);
+ const byte one_m = ct_is_equal_8(input[i], 1);
- const bool add_1 = waiting_for_delim && zero_p;
+ const byte add_m = waiting_for_delim & zero_m;
- bad_input |= waiting_for_delim && !(zero_p || one_p);
+ bad_input |= waiting_for_delim & ~(zero_m | one_m);
- delim_idx += add_1;
+ delim_idx += ct_select_mask_8(add_m, 1, 0);
- waiting_for_delim &= zero_p;
+ waiting_for_delim &= zero_m;
}
// If we never saw any non-zero byte, then it's not valid input
bad_input |= waiting_for_delim;
+ bad_input |= ct_expand_mask_8(!same_mem(&input[m_Phash.size()], m_Phash.data(), m_Phash.size()));
- bad_input |= !same_mem(&input[m_Phash.size()], m_Phash.data(), m_Phash.size());
+ BOTAN_CONST_TIME_UNPOISON(input.data(), input.size());
+ BOTAN_CONST_TIME_UNPOISON(&bad_input, sizeof(bad_input));
+ BOTAN_CONST_TIME_UNPOISON(&delim_idx, sizeof(delim_idx));
if(bad_input)
throw Decoding_Error("Invalid OAEP encoding");