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

fix: wallet database encryption does not bind to field keys #4137 #4340

Merged
merged 19 commits into from
Aug 3, 2022

Conversation

agubarev
Copy link
Contributor

Description

Added source_key to encrypt_bytes_integral_nonce() and decrypt_bytes_integral_nonce() which are used to encrypt and decrypt values in the storage backend. Also, encrypted values are now suffixed with a MAC.

Motivation and Context

#4137
Wallet database field key-value entries are secured in place: AES-GCM is used to encrypt values, with keys left in the clear. However, the value encryption does not bind this operation to the field key. An attacker could replace these values with other encrypted values taken from elsewhere in the database (or otherwise encrypted using the same AES-GCM key) without detection.

One mitigation is to use the field key as associated data passed to the encryption and decryption operations.

How Has This Been Tested?

unit test

@agubarev agubarev changed the title fix: Wallet database encryption does not bind to field keys #4137 fix: wallet database encryption does not bind to field keys #4137 Jul 22, 2022
@agubarev agubarev marked this pull request as draft July 22, 2022 20:10
@agubarev agubarev force-pushed the issue-4137 branch 5 times, most recently from 24959e7 to 8bd5226 Compare July 25, 2022 09:57
@agubarev agubarev marked this pull request as ready for review July 25, 2022 12:45
Copy link
Collaborator

@stringhandler stringhandler 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. Sorry for the terseness in the comments. This is a very important area, and my intention is not to be mean but to be clear.

Looks like you are on the right track. Here are some suggestions:

I would suggest creating a struct or mod with constants that wraps all the keys in a crate in one place so that we don't create the same key twice and have spelling errors.

The name "source_key" is a little confusing since there are other keys (e.g. spending_key) in the wallet. Perhaps a better name is source_field or full_field_name.

nit: Please remove package-lock.json from the commit set

@agubarev agubarev force-pushed the issue-4137 branch 2 times, most recently from dee5e05 to 44ed3cb Compare July 28, 2022 13:26
…`decrypt_bytes_integral_nonce()`.

tari-project#4137
Signed-off-by: Andrei Gubarev <agubarev@users.noreply.github.com>
…or encryption/decryption

Signed-off-by: Andrei Gubarev <agubarev@users.noreply.github.com>
…d OutputSql due to later transition without re-encryption

Signed-off-by: Andrei Gubarev <agubarev@users.noreply.github.com>
Signed-off-by: Andrei Gubarev <agubarev@users.noreply.github.com>
`decrypt_bytes_integral_nonce()` is now decrypting a message only if appended and expected MACs match
moved domain prefixes `Encryptable` as constants
replaced `.join(&0)` with `.concat()` in `Encryptable.domain()` implementations
removed package-lock.json

Signed-off-by: Andrei Gubarev <agubarev@users.noreply.github.com>
Signed-off-by: Andrei Gubarev <agubarev@users.noreply.github.com>
Signed-off-by: Andrei Gubarev <agubarev@users.noreply.github.com>
Signed-off-by: Andrei Gubarev <agubarev@users.noreply.github.com>
Signed-off-by: Andrei Gubarev <agubarev@users.noreply.github.com>
agubarev and others added 9 commits July 29, 2022 09:06
Signed-off-by: Andrei Gubarev <agubarev@users.noreply.github.com>
Signed-off-by: Andrei Gubarev <agubarev@users.noreply.github.com>
Signed-off-by: Andrei Gubarev <agubarev@users.noreply.github.com>
# Conflicts:
#	base_layer/wallet/src/storage/sqlite_db/wallet.rs
Signed-off-by: Andrei Gubarev <agubarev@users.noreply.github.com>
@aviator-app aviator-app bot merged commit 32184b5 into tari-project:development Aug 3, 2022
@agubarev agubarev deleted the issue-4137 branch August 3, 2022 15:14
sdbondi added a commit to sdbondi/tari that referenced this pull request Aug 4, 2022
* development:
  fix: wallet database encryption does not bind to field keys tari-project#4137 (tari-project#4340)
  fix: use SafePassword struct instead of String for passwords (tari-project#4320)
  feat(dan): template macro handles component state (tari-project#4380)
  fix(dht)!: add message padding for message decryption, to reduce message length leaks (fixes tari-project#4140) (tari-project#4362)
  fix(wallet): update seed words for output manager tests (tari-project#4379)
stringhandler pushed a commit that referenced this pull request Aug 29, 2022
Description
---
This replaces AES-GCM, which is used for encrypted storage, with XChaCha20-Poly1305. It gets rid of a superfluous MAC. It updates tests to account for more failure modes.

This is an updated and cleaner version of [PR 4529](#4529) (which used ChaCha20-Poly1305) that should be easier to review.

Motivation and Context
---
The work in [PR 4340](#4340) binds field data into a MAC that is included with AES-GCM ciphertext. This binding is important and useful, but is done in the wrong place; AES-GCM already includes an authentication tag that is built in to the ciphertext and parsed automatically on decryption.

This work adds the field binding directly into the authenticated encryption as associated data, which is the standard way to include public context. It means the existing additional MAC is no longer needed, since malleated field data will fail the authentication phase of decryption.

Separately, the use of AES-GCM for authenticated encryption is suboptimal. Its nonce length is short enough that the use of random nonces can be risky if enough data is encrypted under a common key; if a nonce is ever reused, an attacker can use the resulting ciphertext to forge messages on arbitrary (even unused) nonces and the same key. While this seems unlikely to occur in the use cases of interest, there really isn't any good reason to use AES-GCM unless you have hardware support for it and speed is critical.

The XChaCha20-Poly1305 authenticated encryption construction uses longer nonces, and it is considered safe to generate them randomly. While this construction has not yet been standardized (an existing draft standard has expired), it is common. Its cryptographic sibling ChaCha20-Poly1305 uses the same nonce length as AES-GCM, and while nonce reuse is "somewhat less worse" than in AES-GCM, it would still be unsafe in this context if it occurred (forgeries are limited to existing nonces).

How Has This Been Tested?
---
Existing tests pass. New tests are included.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants