diff --git a/Cargo.lock b/Cargo.lock index d525aec..10c2806 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,6 +39,17 @@ dependencies = [ "cpufeatures 0.2.17", ] +[[package]] +name = "aes" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66bd29a732b644c0431c6140f370d097879203d79b80c94a6747ba0872adaef8" +dependencies = [ + "cipher 0.5.1", + "cpubits", + "cpufeatures 0.3.0", +] + [[package]] name = "aes-gcm-siv" version = "0.11.1" @@ -46,9 +57,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae0784134ba9375416d469ec31e7c5f9fa94405049cf08c5ce5b4698be673e0d" dependencies = [ "aead", - "aes", + "aes 0.8.4", "cipher 0.4.4", - "ctr", + "ctr 0.9.2", "polyval", "subtle", "zeroize", @@ -2104,6 +2115,12 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "cpubits" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -2227,6 +2244,15 @@ dependencies = [ "cipher 0.4.4", ] +[[package]] +name = "ctr" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17469f8eb9bdbfad10f71f4cfddfd38b01143520c0e717d8796ccb4d44d44e42" +dependencies = [ + "cipher 0.5.1", +] + [[package]] name = "ctrlc" version = "3.5.2" @@ -2741,8 +2767,8 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" dependencies = [ - "aes", - "ctr", + "aes 0.8.4", + "ctr 0.9.2", "digest 0.10.7", "hex", "hmac 0.12.1", @@ -4774,7 +4800,7 @@ dependencies = [ name = "purl-lib" version = "0.2.6" dependencies = [ - "aes", + "aes 0.9.0", "alloy", "alloy-signer", "alloy-signer-local", @@ -4782,7 +4808,7 @@ dependencies = [ "base64 0.22.1", "bincode", "bs58", - "ctr", + "ctr 0.10.0", "dirs", "eth-keystore", "hex", diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 3ace772..aae3587 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -57,8 +57,8 @@ tokio.workspace = true async-trait.workspace = true # Cryptography for Solana keystore encryption -aes = "0.8" -ctr = "0.9" +aes09 = { package = "aes", version = "0.9" } +ctr = "0.10" scrypt = "0.12" sha3.workspace = true diff --git a/lib/src/keystore/encrypt.rs b/lib/src/keystore/encrypt.rs index c134e2c..bd4deeb 100644 --- a/lib/src/keystore/encrypt.rs +++ b/lib/src/keystore/encrypt.rs @@ -176,7 +176,8 @@ pub fn decrypt_keystore(keystore_path: &Path, password: Option<&str>) -> Result< /// Uses the same encryption scheme as EVM keystores (scrypt + AES-128-CTR) /// but stores the full 64-byte Solana keypair. pub fn create_solana_keystore(keypair_b58: &str, password: &str, name: &str) -> Result { - use aes::cipher::{KeyIvInit, StreamCipher}; + use aes09::Aes128; + use ctr::cipher::{KeyIvInit, StreamCipher}; use ctr::Ctr128BE; use rand::RngCore; use scrypt::{scrypt, Params}; @@ -216,7 +217,8 @@ pub fn create_solana_keystore(keypair_b58: &str, password: &str, name: &str) -> // Encrypt keypair with AES-128-CTR using first 16 bytes of derived key let mut ciphertext = keypair_bytes.clone(); - let mut cipher = Ctr128BE::::new(derived_key[..16].into(), iv.as_slice().into()); + let mut cipher = Ctr128BE::::new_from_slices(&derived_key[..16], &iv) + .map_err(|e| PurlError::ConfigMissing(format!("Failed to initialize cipher: {e}")))?; cipher.apply_keystream(&mut ciphertext); // Create MAC using Keccak256 over (derived_key[16..32] || ciphertext) @@ -273,7 +275,8 @@ pub fn create_solana_keystore(keypair_b58: &str, password: &str, name: &str) -> /// * `keystore_path` - Path to the Solana keystore file /// * `password` - Optional password. If None, prompts the user with retry on failure. pub fn decrypt_solana_keystore(keystore_path: &Path, password: Option<&str>) -> Result> { - use aes::cipher::{KeyIvInit, StreamCipher}; + use aes09::Aes128; + use ctr::cipher::{KeyIvInit, StreamCipher}; use ctr::Ctr128BE; use scrypt::{scrypt, Params}; use sha3::{Digest, Keccak256}; @@ -373,7 +376,7 @@ pub fn decrypt_solana_keystore(keystore_path: &Path, password: Option<&str>) -> // Decrypt let mut plaintext = ciphertext.clone(); let mut cipher = - Ctr128BE::::new(derived_key[..16].into(), iv.as_slice().into()); + Ctr128BE::::new_from_slices(&derived_key[..16], &iv).map_err(|_| ())?; cipher.apply_keystream(&mut plaintext); Ok(plaintext) };