Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the Tx object zeroize itself on drop #2925

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

Make the Tx object zeroize itself on drop #2925

wants to merge 3 commits into from

Conversation

cbeck88
Copy link
Contributor

@cbeck88 cbeck88 commented Dec 5, 2022

This is an experimental change to improve hygeine of memory in the consensus enclave (but also in the clients)

This makes a bunch of objects derive Zeroize in transaction-core, and makes the Tx object zeroize itself on drop.

For examples of why this is a good change, consider that, in the mc-connection ThickClient crate, after we serialize a Tx to protobuf and encrypt it for the enclave, we zeroize the plaintext. However, before this change, we do not zeroize the Tx object (since it would not have been possible), so another copy of the data that we zeroized continues to exist in memory. After this change, the Tx will zeroize itself automatically as well.

The main reason not to do this would be if it hurts the performance of the consensus nodes, but I consider this unlikely, because, the untrusted side never actually sees Tx objects so SCP should not be meaningfully impacted by this, only the transaction validation handles the decrypted Tx. And the elliptic curve operations done to validate a Tx should be many orders of magnitude more expensive than a zeroizing operation. So I expect no measurable performance difference in the consensus network as a result of this change.

For similar reasons I don't expect any client to have a measurable perf impact either.

See github issue #2717

This is an experimental change to improve hygeine of memory in
the consensus enclave (but also in the clients)

This makes a bunch of objects derive `Zeroize` in transaction-core,
and makes the `Tx` object zeroize itself on drop.

For examples of why this is a good change, consider that, in the
`mc-connection` ThickClient crate, after we serialize a Tx to protobuf
and encrypt it for the enclave, we zeroize the plaintext. However,
before this change, we do not zeroize the `Tx` object (since it
would not have been possible), so another copy of the data that
we zeroized continues to exist in memory. After this change, the
`Tx` will zeroize itself automatically as well.

The main reason not to do this would be if it hurts the performance
of the consensus nodes, but I consider this unlikely, because,
the untrusted side never actually sees `Tx` objects so SCP should
not be meaningfully impacted by this, only the transaction validation
handles the decrypted `Tx`. And the elliptic curve operations done
to validate a Tx should be many orders of magnitude more expensive
than a zeroizing operation. So I expect no measurable performance
difference as a result of this change.

See github issue #2717
@@ -310,7 +310,7 @@ pub fn initialize_ledger(
);

let key_images = tx.key_images();
(tx.prefix.outputs, key_images)
(tx.prefix.outputs.clone(), key_images)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was needed because rustc says we cannot move out of Tx anymore since it is a Drop type now

@@ -103,7 +103,8 @@ impl fmt::Debug for TxHash {
}

/// A CryptoNote-style transaction.
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Message, Digestible)]
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Message, Digestible, Zeroize)]
#[zeroize(drop)]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the main change

Copy link
Collaborator

@nick-mobilecoin nick-mobilecoin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good sans the other instance that needs to clone

error[E0509]: cannot move out of type `Tx`, which implements the `Drop` trait
   --> consensus/enclave/mock/src/lib.rs:287:28
    |
287 |             outputs.extend(tx.prefix.outputs.into_iter());
    |                            ^^^^^^^^^^^^^^^^^
    |                            |
    |                            cannot move out of here
    |                            move occurs because `tx.prefix.outputs` has type `Vec<TxOut>`, which does not implement the `Copy` trait

For more information about this error, try `rustc --explain E0509`.

transaction/core/src/tx.rs Outdated Show resolved Hide resolved
@@ -103,7 +103,8 @@ impl fmt::Debug for TxHash {
}

/// A CryptoNote-style transaction.
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Message, Digestible)]
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Message, Digestible, Zeroize)]
#[zeroize(drop)]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ These docs are hard to parse.

Zeroing memory is hard
...
This crate has custom derive support for the Zeroize trait, gated under the zeroize crate’s zeroize_derive Cargo feature, which automatically calls zeroize() on all members of a struct or tuple struct.

The automatically calls gave me the impression this was during drop. In their defense they have examples after with comments saying ZeorizeOnDrop happens on drop.

Anyway should the ZeroizeOnDrop be added to more types in addition to the plain Zeroize?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, looks like we want both. That's what the Zeroize tests do: https://github.com/RustCrypto/utils/blob/master/zeroize/tests/zeroize_derive.rs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway should the ZeroizeOnDrop be added to more types in addition to the plain Zeroize?

I am not sure right now
I tried to make a list of things that should maybe be zeroized in #2717

I figured starting with Tx was a reasonable place to start, and I wrote a bunch of rationale in the code comments.

It is causing wierd rust compilation issues to make the type Drop when it wasn't previously, so I'd rather not do this to a lot of types in this PR. And the other thing is, zeroizing operations may have nontrivial overhead, so we either have to measure the impact carefully or have a very good reason why it shouldn't impact network performance (ideally both).

Copy link
Contributor

@iamalwaysuncomfortable iamalwaysuncomfortable left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any to stand this hypothesis up in one of the test networks?

@cbeck88 cbeck88 requested a review from a team December 6, 2022 20:50
@cbeck88
Copy link
Contributor Author

cbeck88 commented Dec 7, 2022

In this draft PR, I developed a benchmark which clones and drops a Tx with the ZeroizeOnDrop feature.

#2932

It looks that it takes about .14 milliseconds, which is a lot slower than I would have hoped for.

@cbeck88
Copy link
Contributor Author

cbeck88 commented Jan 6, 2023

See also this issue: RustCrypto/utils#743

@jcape
Copy link
Contributor

jcape commented Jan 27, 2023

@cbeck88 Is this still live, or can we close it?

@cbeck88
Copy link
Contributor Author

cbeck88 commented Jan 27, 2023

I plan to test this properly once we have slam working properly

@cbeck88
Copy link
Contributor Author

cbeck88 commented Jan 27, 2023

Idk, i mean, if slam looks the same before and after this change then i feel like it should be okay to go in, but feel free to tell me otherwise

@jcape
Copy link
Contributor

jcape commented Feb 28, 2023

@cbeck88 Ping on this now that we've got slam going...

@cbeck88
Copy link
Contributor Author

cbeck88 commented Feb 28, 2023

Yea lets try to slam it

I also opened a PR in zeroize crate, if they take that should also give us a good way to optimize this

@cbeck88
Copy link
Contributor Author

cbeck88 commented Feb 28, 2023

RustCrypto/utils#841

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Changes Requested
Development

Successfully merging this pull request may close these issues.

None yet

5 participants