Skip to content
This repository has been archived by the owner on Jul 27, 2022. It is now read-only.

Commit

Permalink
Merge #580 #588
Browse files Browse the repository at this point in the history
580: Bump unicase from 2.5.1 to 2.6.0 r=tomtau a=dependabot-preview[bot]

Bumps [unicase](https://github.com/seanmonstar/unicase) from 2.5.1 to 2.6.0.
<details>
<summary>Release notes</summary>

*Sourced from [unicase's releases](https://github.com/seanmonstar/unicase/releases).*

> ## v2.6.0
> - Fix `UniCase::eq` in Unicode mode so that it doesn't equal a substring of the other.
> - Make crate `no_std`.
</details>
<details>
<summary>Commits</summary>

- [`7b116bc`](seanmonstar/unicase@7b116bc) v2.6.0
- [`c14856b`](seanmonstar/unicase@c14856b) Fix Unicode::eq to not equal when one side is a substring of the other ([#39](https://github-redirect.dependabot.com/seanmonstar/unicase/issues/39))
- [`4788cba`](seanmonstar/unicase@4788cba) update version_check
- [`fbab380`](seanmonstar/unicase@fbab380) Implement no_std support ([#34](https://github-redirect.dependabot.com/seanmonstar/unicase/issues/34))
- See full diff in [compare view](seanmonstar/unicase@v2.5.1...v2.6.0)
</details>
<br />

[![Dependabot compatibility score](https://api.dependabot.com/badges/compatibility_score?dependency-name=unicase&package-manager=cargo&previous-version=2.5.1&new-version=2.6.0)](https://dependabot.com/compatibility-score.html?dependency-name=unicase&package-manager=cargo&previous-version=2.5.1&new-version=2.6.0)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
- `@dependabot use these labels` will set the current labels as the default for future PRs for this repo and language
- `@dependabot use these reviewers` will set the current reviewers as the default for future PRs for this repo and language
- `@dependabot use these assignees` will set the current assignees as the default for future PRs for this repo and language
- `@dependabot use this milestone` will set the current milestone as the default for future PRs for this repo and language
- `@dependabot badge me` will comment on this PR with code to add a "Dependabot enabled" badge to your readme

Additionally, you can set the following in your Dependabot [dashboard](https://app.dependabot.com):
- Update frequency (including time of day and day of week)
- Pull request limits (per update run and/or open at any time)
- Out-of-range updates (receive only lockfile updates, if desired)
- Security updates (receive only security updates, if desired)



</details>

588: Problem: (CRO-392) Outdated dependencies in client's storage encryption r=tomtau a=devashishdxt

Solution: Use `aes-gcm-siv` for encryption/decryption

Note: Turns out that the root cause of timeouts was password hashing using `rust-argon2` which, as far as I know, is only useful when we want to store passwords in a database. Adding cache for wallet details is still a good idea and can be done in a different task.

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Devashish Dixit <devashish@crypto.com>
  • Loading branch information
3 people authored Nov 14, 2019
3 parents 227325b + 6cc7ee4 + 4999873 commit 1e7e99f
Show file tree
Hide file tree
Showing 12 changed files with 142 additions and 201 deletions.
4 changes: 2 additions & 2 deletions .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ steps:
pull: never
commands:
- export RUST_BACKTRACE=1
- export RUSTFLAGS=-Ctarget-feature=+aes,+ssse3
- export RUSTFLAGS=-Ctarget-feature=+aes,+sse2,+sse4.1,+ssse3
- export LD_LIBRARY_PATH=$HOME/lib
- export LIBRARY_PATH=$HOME/lib
- export PATH=$HOME/.cargo/bin:$HOME/.local/bin:$PATH
Expand Down Expand Up @@ -114,7 +114,7 @@ steps:
from_secret: dev_ias_key
commands:
- export RUST_BACKTRACE=1
- export RUSTFLAGS=-Ctarget-feature=+aes,+ssse3
- export RUSTFLAGS=-Ctarget-feature=+aes,+sse2,+sse4.1,+ssse3
- export SGX_MODE=HW
- export NETWORK_ID=ab
- export RUST_LOG=info
Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ rust: &rust
- rm -rf $HOME/.cargo/registry/src
env:
- RUST_BACKTRACE=1
- RUSTFLAGS=-Ctarget-feature=+aes,+ssse3
- RUSTFLAGS=-Ctarget-feature=+aes,+sse2,+sse4.1,+ssse3
- PATH=$HOME/.local/bin:$PATH
- LD_LIBRARY_PATH=$HOME/lib
- PKG_CONFIG_PATH=$HOME/lib/pkgconfig
Expand Down
210 changes: 80 additions & 130 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ Crypto.com chain requires the following to be installed before build.
After all dependencies are installed, add the following lines to `~/.cargo/config` to enable generating instructions for Streaming SIMD Extensions 3 and Advanced Vector Extensions on build:
```
[build]
rustflags = ["-Ctarget-feature=+aes,+ssse3"]
rustflags = ["-Ctarget-feature=+aes,+sse2,+sse4.1,+ssse3"]
```
(TODO: In the future, the build tooling may be migrated to Bazel / Nix etc. for reproducible builds.)
Expand Down
2 changes: 1 addition & 1 deletion ci-scripts/drone.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ stdenv.mkDerivation {
];
shellHook = ''
export RUST_BACKTRACE=1
export RUSTFLAGS=-Ctarget-feature=+aes,+ssse3
export RUSTFLAGS=-Ctarget-feature=+aes,+sse2,+sse4.1,+ssse3
export PATH="$PWD/node_modules/.bin/:$PATH"
export OPENSSL_DIR="${openssl.dev}"
export OPENSSL_LIB_DIR="${openssl.out}/lib"
Expand Down
2 changes: 1 addition & 1 deletion client-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ structopt = "0.3"
quest = "0.3"
secstr = { version = "0.3.2", features = ["serde"] }
hex = "0.4"
unicase = "2.5"
unicase = "2.6"
chrono = "0.4"
pbr = "1.0"
log = "0.4.8"
Expand Down
2 changes: 1 addition & 1 deletion client-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ chain-tx-filter = { path = "../chain-tx-filter" }
secp256k1zkp = { git = "https://github.com/crypto-com/rust-secp256k1-zkp.git", rev = "8b9a38b870a7759fcdbd4a5d435b5ba873c70afd", features = ["serde", "zeroize", "rand", "recovery", "endomorphism", "musig"] }
rand = "0.7"
log = "0.4"
miscreant = "0.4"
aes-gcm-siv = "0.2"
blake2 = "0.8"
hex = "0.4"
base64 = "0.11"
Expand Down
3 changes: 3 additions & 0 deletions client-common/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ pub enum ErrorKind {
StorageError,
/// Random number generation error
RngError,
/// Encryption error
EncryptionError,
/// Decryption error
DecryptionError,
/// Serialization error
Expand Down Expand Up @@ -120,6 +122,7 @@ impl fmt::Display for ErrorKind {
ErrorKind::ConnectionError => write!(f, "Connection error"),
ErrorKind::StorageError => write!(f, "Storage error"),
ErrorKind::RngError => write!(f, "Random number generation error"),
ErrorKind::EncryptionError => write!(f, "Encryption error"),
ErrorKind::DecryptionError => write!(f, "Decryption error"),
ErrorKind::SerializationError => write!(f, "Serialization error"),
ErrorKind::DeserializationError => write!(f, "Deserialization error"),
Expand Down
110 changes: 49 additions & 61 deletions client-common/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,18 @@ pub use memory_storage::MemoryStorage;
pub use sled_storage::SledStorage;
pub use unauthorized_storage::UnauthorizedStorage;

use aes_gcm_siv::aead::generic_array::GenericArray;
use aes_gcm_siv::aead::{Aead, NewAead};
use aes_gcm_siv::Aes256GcmSiv;
use blake2::{Blake2s, Digest};
use miscreant::{Aead, Aes128PmacSivAead};
use rand::rngs::OsRng;
use rand::Rng;
use secstr::SecUtf8;

use crate::{ErrorKind, Result, ResultExt};
use crate::{Error, ErrorKind, Result, ResultExt};

/// Nonce size in bytes
const NONCE_SIZE: usize = 8;
const NONCE_SIZE: usize = 12;

/// Interface for a generic key-value storage
pub trait Storage: Send + Sync {
Expand Down Expand Up @@ -104,19 +106,7 @@ where
passphrase: &SecUtf8,
) -> Result<Option<Vec<u8>>> {
self.get(keyspace, &key)?
.map(|value| {
let nonce_index = value.len() - NONCE_SIZE;
let mut algo = get_algo(passphrase);

Ok(algo
.open(&value[nonce_index..], key.as_ref(), &value[..nonce_index])
.chain(|| {
(
ErrorKind::DecryptionError,
"Incorrect passphrase: Unable to unlock stored values",
)
})?)
})
.map(|value| decrypt_bytes(passphrase, &value))
.transpose()
}

Expand All @@ -129,14 +119,7 @@ where
) -> Result<Option<Vec<u8>>> {
let old_value = self.get_secure(&keyspace, &key, passphrase)?;

let mut algo = get_algo(passphrase);

let mut nonce = [0u8; NONCE_SIZE];
OsRng.fill(&mut nonce);

let mut cipher = algo.seal(&nonce, key.as_ref(), &value);
cipher.extend(&nonce[..]);

let cipher = encrypt_bytes(passphrase, &value)?;
self.set(keyspace, key, cipher)?;

Ok(old_value)
Expand All @@ -155,17 +138,8 @@ where
F: Fn(Option<&[u8]>) -> Result<Option<Vec<u8>>>,
{
self.fetch_and_update(keyspace, &key, |current| {
let mut algo = get_algo(passphrase);
let opened = current
.map(|current| {
let nonce_index = current.len() - NONCE_SIZE;

algo.open(
&current[nonce_index..],
key.as_ref(),
&current[..nonce_index],
)
})
.map(|current| decrypt_bytes(passphrase, current))
.transpose()
.chain(|| {
(
Expand All @@ -176,39 +150,53 @@ where

let next = f(opened.as_ref().map(AsRef::as_ref))?;

next.map(|next| {
let mut nonce = [0u8; NONCE_SIZE];
OsRng.fill(&mut nonce);

let mut sealed = algo.seal(&nonce, key.as_ref(), &next);
sealed.extend(&nonce[..]);

Ok(sealed)
})
.transpose()
next.as_ref()
.map(|next| encrypt_bytes(passphrase, next))
.transpose()
})
}
}

/// Decrypts bytes with given key and passphrase
pub fn decrypt_bytes<K>(key: K, passphrase: &SecUtf8, bytes: &[u8]) -> Result<Vec<u8>>
where
K: AsRef<[u8]>,
{
let mut algo = get_algo(passphrase);
let nonce_index = bytes.len() - NONCE_SIZE;

algo.open(&bytes[nonce_index..], key.as_ref(), &bytes[..nonce_index])
.chain(|| {
(
ErrorKind::DecryptionError,
"Incorrect passphrase: Unable to unlock stored values",
)
})
/// Encrypts bytes with given passphrase
pub fn encrypt_bytes(passphrase: &SecUtf8, bytes: &[u8]) -> Result<Vec<u8>> {
let mut nonce = [0; NONCE_SIZE];

OsRng.fill(&mut nonce);

let algo = get_algo(passphrase)?;

let mut cipher = Vec::new();
cipher.extend_from_slice(&nonce[..]);

cipher.append(
&mut algo
.encrypt(GenericArray::from_slice(&nonce), bytes)
.map_err(|_| Error::new(ErrorKind::EncryptionError, "Unable to encrypt bytes"))?,
);

Ok(cipher)
}

fn get_algo(passphrase: &SecUtf8) -> Aes128PmacSivAead {
/// Decrypts bytes with given passphrase
pub fn decrypt_bytes(passphrase: &SecUtf8, bytes: &[u8]) -> Result<Vec<u8>> {
let algo = get_algo(passphrase)?;

algo.decrypt(
GenericArray::from_slice(&bytes[..NONCE_SIZE]),
&bytes[NONCE_SIZE..],
)
.map_err(|_| {
Error::new(
ErrorKind::DecryptionError,
"Incorrect passphrase: Unable to unlock stored values",
)
})
}

fn get_algo(passphrase: &SecUtf8) -> Result<Aes256GcmSiv> {
let mut hasher = Blake2s::new();
hasher.input(passphrase.unsecure());
Aes128PmacSivAead::new(&hasher.result_reset())

let key = GenericArray::clone_from_slice(&hasher.result_reset());
Ok(Aes256GcmSiv::new(key))
}
2 changes: 1 addition & 1 deletion client-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ log ="0.4.8"
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "0.1.22", default-features = false, features = ["rt-full"] }
tiny-bip39 = { version = "0.6", default-features = false }
unicase = "2.5.1"
unicase = "2.6.0"
lazy_static = "1.4.0"
ring = "0.16.9"

Expand Down
2 changes: 1 addition & 1 deletion client-core/src/service/hd_key_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ where
)
})?;

let hd_key_bytes = decrypt_bytes(name, passphrase, &bytes)?;
let hd_key_bytes = decrypt_bytes(passphrase, &bytes)?;

let hd_key = HdKey::decode(&mut hd_key_bytes.as_slice()).chain(|| {
(
Expand Down
2 changes: 1 addition & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM rust:1.38.0 AS builder
LABEL maintainer="calvin@crypto.com"

ENV RUSTFLAGS "-Ctarget-feature=+aes,+ssse3"
ENV RUSTFLAGS "-Ctarget-feature=+aes,+sse2,+sse4.1,+ssse3"

RUN apt-get update -y && \
apt-get install cmake libgflags-dev libzmq3-dev pkg-config -y
Expand Down

0 comments on commit 1e7e99f

Please sign in to comment.