aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pk_pad/eme_pkcs1
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_pkcs1
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_pkcs1')
-rw-r--r--src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp46
1 files changed, 32 insertions, 14 deletions
diff --git a/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp b/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp
index 65d29cd59..219e93251 100644
--- a/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp
+++ b/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp
@@ -1,11 +1,12 @@
/*
-* PKCS1 EME
-* (C) 1999-2007 Jack Lloyd
+* PKCS #1 v1.5 Type 2 (encryption) padding
+* (C) 1999-2007,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#include <botan/eme_pkcs.h>
+#include <botan/internal/ct_utils.h>
namespace Botan {
@@ -38,22 +39,39 @@ secure_vector<byte> EME_PKCS1v15::pad(const byte in[], size_t inlen,
* PKCS1 Unpad Operation
*/
secure_vector<byte> EME_PKCS1v15::unpad(const byte in[], size_t inlen,
- size_t key_len) const
+ size_t key_len) const
{
- if(inlen != key_len / 8 || inlen < 10 || in[0] != 0x02)
+ if(inlen != key_len / 8 || inlen < 10)
throw Decoding_Error("PKCS1::unpad");
- size_t separator = 0;
- for(size_t j = 0; j != inlen; ++j)
- if(in[j] == 0)
- {
- separator = j;
- break;
- }
- if(separator < 9)
- throw Decoding_Error("PKCS1::unpad");
+ BOTAN_CONST_TIME_POISON(in, inlen);
+
+ byte bad_input_m = 0;
+ byte seen_zero_m = 0;
+ size_t delim_idx = 0;
+
+ bad_input_m |= ~ct_is_equal_8(in[0], 2);
+
+ for(size_t i = 1; i != inlen; ++i)
+ {
+ const byte is_zero_m = ct_is_zero_8(in[i]);
+
+ delim_idx += ct_select_mask_8(~seen_zero_m, 1, 0);
+
+ bad_input_m |= is_zero_m & ct_expand_mask_8(i < 9);
+ seen_zero_m |= is_zero_m;
+ }
+
+ bad_input_m |= ~seen_zero_m;
+
+ BOTAN_CONST_TIME_UNPOISON(in, inlen);
+ BOTAN_CONST_TIME_UNPOISON(&bad_input_m, sizeof(bad_input_m));
+ BOTAN_CONST_TIME_UNPOISON(&delim_idx, sizeof(delim_idx));
+
+ if(bad_input_m)
+ throw Decoding_Error("Invalid PKCS #1 v1.5 encryption padding");
- return secure_vector<byte>(&in[separator + 1], &in[inlen]);
+ return secure_vector<byte>(&in[delim_idx + 1], &in[inlen]);
}
/*