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

Encrypt metadata impl #4204

Closed
wants to merge 33 commits into from

Conversation

paweljakubas
Copy link
Contributor

@paweljakubas paweljakubas commented Nov 3, 2023

  • adding cryptographic primitives
  • support for shelley
  • integration tests for shelley
  • support for shared with integration tests

Comments

spec and api defined in #4176

Issue Number

adp-322

@paweljakubas paweljakubas self-assigned this Nov 3, 2023
@paweljakubas paweljakubas force-pushed the paweljakubas/adp-322/encrypt-metadata-impl branch 2 times, most recently from 367e64b to c412cf1 Compare November 9, 2023 15:05
@paweljakubas paweljakubas marked this pull request as ready for review November 9, 2023 15:10
@paweljakubas paweljakubas force-pushed the paweljakubas/adp-322/encrypt-metadata-impl branch 4 times, most recently from ad14d04 to c3a2d7f Compare November 16, 2023 11:21
Comment on lines 40 to 45
:: ByteString
-- ^ Symmetric key / passphrase, 32-byte long
-> ByteString
-- ^ Nonce, 12-byte long
-> ByteString
-- ^ Payload to be encrypted
Copy link
Contributor

Choose a reason for hiding this comment

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

I suggest to use newtypes or Tagged to distinguish parameters on the type level.

-- | The caller must ensure that the passphrase length is 32 bytes and
-- | nonce is 12 bytes
encryptPayload
:: ByteString
Copy link
Contributor

Choose a reason for hiding this comment

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

unsafeSerialize =
CBOR.toStrictByteString . CBOR.encodeBytes . useInvariant
-- Encryption fails if the key is the wrong size, but that won't happen
-- if the key was created with 'toSymmetricKey'.
Copy link
Contributor

@Unisay Unisay Nov 16, 2023

Choose a reason for hiding this comment

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

Another upside of using newtypes is that you can enforce this invariant avoiding partiality.

Comment on lines 85 to 87
toSymmetricKey
:: ByteString
-> ByteString
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
toSymmetricKey
:: ByteString
-> ByteString
toSymmetricKey :: ByteString -> ByteString

:: ByteString
-> ByteString
toSymmetricKey rawKey =
PBKDF2.generate
Copy link
Contributor

Choose a reason for hiding this comment

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

Argon2 was specifically crafted to fix the inherent flaws of compute bounded key derivation functions like pbkdf2. With pbkdf2, you can double your iterations, which will double the time you have to wait to unlock your vault, but also double the time an attacker will take to crack your password (if they have your masterpasswordhash). In contrast to this, argon2 is not just compute-bounded but also memory bounded. This means that - for the same unlock time for you - password cracking will be significantly slower for an attacker attempting to crack your password on a GPU or ASIC, because an attacker cannot run as many instances of argon2 in parallel on a GPU, as they could with PBKDF2 due to memory limitations. This means that for the same unlock time for the user, password cracking becomes orders of magnitude slower compared to pbkdf2.

OWASP recommends Argon2

(PBKDF2.prfHMAC SHA512)
(PBKDF2.Parameters 500 32)
rawKey
("metadata-encryption" :: ByteString)
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the point of this bytestring?

@@ -3013,6 +3028,90 @@ constructTransaction api argGenChange knownPools poolStatus apiWalletId body = d
. Map.toList
. foldr (uncurry (Map.insertWith (<>))) Map.empty

encryptionNonce :: ByteString
encryptionNonce = "encrypt-data"
Copy link
Contributor

@Unisay Unisay Nov 16, 2023

Choose a reason for hiding this comment

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

Nonce means "number used once". Here I see that this encryptionNonce will be reused.

According to this doc, nonce has to be 12 random bytes.

🇨🇳

toMetadata =
Cardano.TxMetadata .
Map.fromList .
zipWith (,) [0..] .
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
zipWith (,) [0..] .
zip [0..] .

@@ -3330,3 +3357,143 @@ spec = describe "SHARED_TRANSACTIONS" $ do
(#balance . #available . #getQuantity)
(`shouldBe` amt)
]

checkMetadataEncrytion
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo:

Suggested change
checkMetadataEncrytion
checkMetadataEncryption

@@ -50,7 +50,7 @@ data TxMetadataWithSchema = TxMetadataWithSchema
{ -- | How to codec the metadata into json
txMetadataWithSchema_schema :: TxMetadataSchema
, -- | The metadata
txMetadataWithSchema_metadata :: TxMetadata
txMetadataWithSchema_metadata :: TxMetadata
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
txMetadataWithSchema_metadata :: TxMetadata
txMetadataWithSchema_metadata :: TxMetadata

toMetadataEncryptedKey apiEncrypt =
toSymmetricKey (BA.convert $ unPassphrase passphrase)
where
(ApiEncryptMetadata (ApiT passphrase)) = apiEncrypt
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
(ApiEncryptMetadata (ApiT passphrase)) = apiEncrypt
ApiEncryptMetadata (ApiT passphrase) = apiEncrypt

Comment on lines 3043 to 3095
toMetadataEncrypted
:: ApiEncryptMetadata
-> TxMetadataWithSchema
-> Cardano.TxMetadata
Copy link
Contributor

Choose a reason for hiding this comment

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

Metadata encryption is not a HTTP API concern, and therefore shouldn't be placed in the lib/wallet/api/http/**.

@paweljakubas paweljakubas force-pushed the paweljakubas/adp-322/encrypt-metadata-impl branch 2 times, most recently from 936a644 to a212ebe Compare November 29, 2023 16:42
@paweljakubas paweljakubas force-pushed the paweljakubas/adp-322/encrypt-metadata-impl branch 3 times, most recently from 73a474f to e752ce8 Compare December 8, 2023 11:59
@paweljakubas paweljakubas force-pushed the paweljakubas/adp-322/encrypt-metadata-impl branch from e6887f4 to 4223ba6 Compare January 15, 2024 15:31
@paweljakubas
Copy link
Contributor Author

closing in favor of #4667

@paweljakubas paweljakubas deleted the paweljakubas/adp-322/encrypt-metadata-impl branch July 31, 2024 11:57
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.

2 participants