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

Add crypto module #175

Merged
merged 16 commits into from
Oct 16, 2023
Merged

Add crypto module #175

merged 16 commits into from
Oct 16, 2023

Conversation

parfeon
Copy link
Contributor

@parfeon parfeon commented Sep 21, 2023

feat(crypto): add crypto module

Update the crypto module structure and add enhanced AES-CBC cryptor.

Update crypto module structure and add enhanced AES-CBC cryptor.
@parfeon parfeon added priority: medium This PR should be reviewed after all high priority PRs. status: done This issue is considered resolved. type: feature This PR contains new feature. labels Sep 21, 2023
@parfeon parfeon self-assigned this Sep 21, 2023
Copy link
Contributor

@Xavrax Xavrax left a comment

Choose a reason for hiding this comment

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

great job!

examples/crypto.rs Outdated Show resolved Hide resolved
examples/crypto.rs Show resolved Hide resolved
src/core/crypto_provider.rs Show resolved Hide resolved
src/core/cryptor.rs Show resolved Hide resolved
src/lib.rs Outdated
Comment on lines 149 to 150
//! | `full` | Enables all non-conflicting features | Configuration, Publish, Subscribe, Access Manager, Parse Token, Presence |
//! | `default` | Enables default features: `publish`, `subscribe`, `serde`, `reqwest`, `aescbc`, `std` | Configuration, Publish, Subscribe |
//! | `default` | Enables default features: `publish`, `subscribe`, `serde`, `reqwest`, `crypto`, `std` | Configuration, Publish, Subscribe |
Copy link
Contributor

Choose a reason for hiding this comment

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

add crypto into full feature.

btw. do we want to have it as a default one?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Xavrax, I will add, however, regarding the issue of default, I do not possess a clear opinion. I would suspect that we enable everything by default, or no?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure if we should enable everything as default.
Imo we should have as small amount default features as possible but with taking to the account dx of our customers.

getrandom::getrandom(&mut random).ok();
random
} else {
*b"0123456789012345"
Copy link
Contributor

Choose a reason for hiding this comment

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

Wow, I didn't know that it is copiable. ;o

src/providers/crypto/cryptors/legacy.rs Outdated Show resolved Hide resolved
Co-authored-by: Mateusz Dahlke <39696234+Xavrax@users.noreply.github.com>
@Xavrax
Copy link
Contributor

Xavrax commented Sep 25, 2023

my bad. I see that data and initialization_vector has different types.
Probably they are arrays with different amount of entities.
Maybe revert that change then.

src/providers/crypto/cryptors/aes_cbc.rs Outdated Show resolved Hide resolved

fn initialization_vector(&self) -> [u8; 16] {
let mut random = [0u8; AES_BLOCK_SIZE];
getrandom::getrandom(&mut random).ok();
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm actually not sure about this. The getrandom crate's docs says this:

It is assumed that the system always provides high-quality cryptographically secure random data

Is it safe to make this assumption? On the other hand, even the rand crate, which explicitly says it provides cryptographically secure random number generators, says this:

A Rust library for random number generation, featuring secure seeding via the getrandom crate

So it isn't clear that using the rand crate would be any better. My best guess is that this will be fine for nearly all customers. However, there may be customers whose software runs in an environment (e.g. embedded hardware) that does not have access to cryptographically secure seeding. While it would be possible to allow customers to provide their own custom RNG in those cases, probably it's best that those customers just don't use this feature.

All of which is to say I am not recommending any change here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. It looks like all suitable (no_std) CSPRNGs from this list rely on getrandom when we need to create an instance of random number generator by requesting create it from entropy – this under the hood relies on the getrandom feature.

Currently, it is hard to say what is the best solution here. With future updates, maybe we will create some deviation (from other SDKs) in the interface to let user specify closure which will generate random data for IV (and salt when we will switch to KDF).

lib::alloc::{format, string::ToString, vec, vec::Vec},
};

type Encryptor = cbc::Encryptor<aes::Aes256>;
Copy link
Contributor

Choose a reason for hiding this comment

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

The docs for the aes crate say:

⚠️ Warning: Hazmat! This crate does not ensure ciphertexts are authentic (i.e. by using a MAC to verify ciphertext integrity), which can lead to serious vulnerabilities if used incorrectly! To avoid this, use an AEAD mode based on AES, such as AES-GCM or AES-GCM-SIV. USE AT YOUR OWN RISK!

Obviously this is not great. Solutions are to use AES-GCM, which would involve changing all the SDKs, find an AES crate which does not have this vulnerability (they exist, but they haven't been audited. At least the aes crate has been audited), or live with this issue. Another possibility would be to MAC the messages ourselves, but that's probably just as hard as switching to AES-GCM, and more error-prone.

I'm not sure what the level of vulnerability is here. We might need an actual cryptographer to weigh in.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Before we had were advised to use AES-GCM to protect against Padding Oracles, but all encryption and decryption happens on the device (end to end) so there is no Oracle (server) to exploit. If there were servers, then yes, AES-GCM with authentication tags would help here, but it is just not our case.

Copy link
Contributor

@josh-lubliner josh-lubliner Oct 6, 2023

Choose a reason for hiding this comment

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

After some consultation, I think you are basically correct. Perhaps a future GCM-based cryptor, but no changes here for now.

@parfeon
Copy link
Contributor Author

parfeon commented Oct 16, 2023

@pubnub-release-bot release

@parfeon parfeon merged commit f15bb75 into master Oct 16, 2023
9 checks passed
@parfeon parfeon deleted the feat/crypto-module branch October 16, 2023 14:40
@pubnub-release-bot
Copy link

🚀 Release successfully completed 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: medium This PR should be reviewed after all high priority PRs. status: done This issue is considered resolved. type: feature This PR contains new feature.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants