Skip to content

Commit

Permalink
Merge pull request #4429 from Rohde-Schwarz/fix/tpm2_rsa_sca
Browse files Browse the repository at this point in the history
Enhance Side Channel resistance of TPM2 RSA Decryption Wrapper
  • Loading branch information
atreiber94 authored Nov 8, 2024
2 parents 679ca89 + 1d082c7 commit d35b793
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 10 deletions.
26 changes: 19 additions & 7 deletions src/lib/prov/tpm2/tpm2_rsa/tpm2_rsa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,13 +340,25 @@ class RSA_Decryption_Operation final : public PK_Ops::Decryption {
&label,
out_ptr(plaintext)));

valid_mask = CT::Mask<uint8_t>::is_equal(rc, TPM2_RC_SUCCESS).value();
if(rc == TPM2_RC_SUCCESS) {
BOTAN_ASSERT_NONNULL(plaintext);
return copy_into<secure_vector<uint8_t>>(*plaintext);
} else {
return {};
}
const auto success = CT::Mask<decltype(rc)>::is_equal(rc, TPM2_RC_SUCCESS).as_choice();
valid_mask = CT::Mask<uint8_t>::from_choice(success).value();

// A "typical" payload size for RSA encryption, assuming that we usually
// encrypt some symmetric key of a hybrid encryption scheme.
constexpr size_t default_plaintext_length = 32;

// When Esys_RSA_Decrypt fails to decrypt the ciphertext (e.g. because
// of a PKCS#1.5 padding failure), the `plaintext` pointer will be nullptr.
// This behaviour in itself is likely exposing a timing side channel already.
// Nevertheless, we do our best to mitigate any oracles by always copying a
// dummy plaintext value in this case.
auto dummy_plaintext = init_with_size<TPM2B_PUBLIC_KEY_RSA>(default_plaintext_length);
auto* out = &dummy_plaintext;
auto* maybe_plaintext = plaintext.get();
CT::conditional_swap_ptr(success.as_bool(), out, maybe_plaintext);

BOTAN_ASSERT_NONNULL(out);
return copy_into<secure_vector<uint8_t>>(*out);
}

size_t plaintext_length(size_t /* ciphertext_length */) const override {
Expand Down
14 changes: 11 additions & 3 deletions src/lib/prov/tpm2/tpm2_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,22 @@ constexpr OutT copy_into(const tpm2_buffer auto& data) {
return result;
}

/// Create an empty TPM2 buffer of the given type.
/// Create a TPM2 buffer of a given type and @p length.
template <tpm2_buffer T>
constexpr T init_empty() {
constexpr T init_with_size(size_t length) {
T result;
result.size = 0;
BOTAN_ASSERT_NOMSG(length <= sizeof(result.buffer));
result.size = length;
clear_bytes(result.buffer, length);
return result;
}

/// Create an empty TPM2 buffer of the given type.
template <tpm2_buffer T>
constexpr T init_empty() {
return init_with_size<T>(0);
}

struct esys_liberator {
void operator()(void* handle) { Esys_Free(handle); }
};
Expand Down

0 comments on commit d35b793

Please sign in to comment.