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

[WIP]: switch to crypto-bigint for decryption #394

Draft
wants to merge 58 commits into
base: master
Choose a base branch
from

Conversation

dignifiedquire
Copy link
Member

@dignifiedquire dignifiedquire commented Nov 29, 2023

Very, very WIP

Uncomplete, unordered task list

  • switch internal storage for RsaPrivateKey
  • switch internal storage for RsaPublicKey
  • switch all code to use the new decrypt implementation
  • update public traits using BigUint to return owned versions
  • fix blinding implementation
  • switch decryption algorithm with precompute to use crypto-bigint ops
  • go through other algorithms and update what can be done without having primality checks implemented
  • review & update code for constant time operation
  • review & update code for performance
  • benchmarks

Tests

  • algorithms::pad::tests::test_left_pad
  • algorithms::pkcs1v15::tests::test_non_zero_bytes
  • algorithms::rsa::tests::recover_primes_works
  • key::tests::build_key_from_p_q
  • key::tests::build_key_from_primes
  • key::tests::invalid_coeff_private_key_regression
  • algorithms::generate::tests::key_generation_128
  • key::tests::key_generation_128
  • algorithms::generate::tests::test_impossible_keys
  • algorithms::generate::tests::key_generation_multi_3_256
  • algorithms::generate::tests::key_generation_multi_4_64
  • key::tests::key_generation_multi_4_64
  • key::tests::reject_oversized_private_key
  • key::tests::test_from_into
  • key::tests::key_generation_multi_3_256
  • key::tests::test_serde
  • oaep::decrypting_key::tests::test_serde
  • oaep::encrypting_key::tests::test_serde
  • oaep::tests::test_decrypt_oaep_invalid_hash
  • oaep::tests::test_decrypt_oaep_invalid_hash_traits
  • oaep::tests::test_encrypt_decrypt_oaep
  • oaep::tests::test_encrypt_decrypt_oaep_traits
  • pkcs1v15::decrypting_key::tests::test_serde
  • pkcs1v15::encrypting_key::tests::test_serde
  • pkcs1v15::signature::tests::test_serde
  • pkcs1v15::signing_key::tests::test_serde
  • pkcs1v15::tests::test_decrypt_pkcs1v15
  • pkcs1v15::tests::test_decrypt_pkcs1v15_traits
  • pkcs1v15::tests::test_encrypt_decrypt_pkcs1v15
  • pkcs1v15::tests::test_encrypt_decrypt_pkcs1v15_traits
  • pkcs1v15::tests::test_sign_pkcs1v15
  • pkcs1v15::tests::test_sign_pkcs1v15_digest_signer
  • pkcs1v15::tests::test_sign_pkcs1v15_signer
  • pkcs1v15::tests::test_sign_pkcs1v15_signer_sha2_256
  • pkcs1v15::tests::test_sign_pkcs1v15_signer_sha3_256
  • pkcs1v15::tests::test_unpadded_signature
  • pkcs1v15::tests::test_unpadded_signature_hazmat
  • pkcs1v15::tests::test_verify_pkcs1v15
  • pkcs1v15::tests::test_verify_pkcs1v15_digest_signer
  • pkcs1v15::tests::test_verify_pkcs1v15_signer
  • pkcs1v15::verifying_key::tests::test_serde
  • pss::blinded_signing_key::tests::test_serde
  • pss::signature::tests::test_serde
  • pss::signing_key::tests::test_serde
  • algorithms::generate::tests::key_generation_1024
  • pss::test::test_sign_and_verify_pss_blinded_hazmat
  • pss::test::test_sign_and_verify_pss_hazmat
  • pss::test::test_sign_and_verify_roundtrip
  • pss::test::test_sign_and_verify_roundtrip_blinded_digest_signer
  • pss::test::test_sign_and_verify_roundtrip_blinded_signer
  • pss::test::test_sign_and_verify_roundtrip_digest_signer
  • pss::test::test_sign_and_verify_roundtrip_signer
  • pss::test::test_sign_blinded_and_verify_roundtrip
  • pss::test::test_verify_pss
  • pss::test::test_verify_pss_digest_signer
  • pss::test::test_verify_pss_hazmat
  • pss::test::test_verify_pss_signer
  • algorithms::generate::tests::key_generation_multi_5_64
  • pss::verifying_key::tests::test_serde
  • key::tests::test_negative_decryption_value
  • key::tests::key_generation_multi_5_64
  • pss::test::test_sign_and_verify_2049bit_key
  • key::tests::key_generation_1024
  • algorithms::generate::tests::key_generation_multi_8_576
  • key::tests::key_generation_multi_8_576

src/algorithms/rsa.rs Outdated Show resolved Hide resolved
src/algorithms/rsa.rs Outdated Show resolved Hide resolved
@tarcieri
Copy link
Member

@dignifiedquire I think it'd be good to land a spike / PoC of this even if all the algorithms aren't yet implemented, since it would unblock splitting up the work on (re)implementing those

@gogo2464
Copy link

gogo2464 commented Aug 10, 2024

@tarcieri can I be assigned to the poc please? I would like to gain experience.

EDIT: I did not undertand the message yet. If the exploit is already made, yes I can read it. Just do not reinvent the whell. I was already working on.

EDIT2: Can you just provide me as much tools as possible please? I am currenyly reading the doc of marvin-tool

@gogo2464
Copy link

I can see difference but I would like a tool or a procedure to analyze the time spent. I am currently working with callgrind and kcachegrind.

@dignifiedquire
Copy link
Member Author

@tarcieri most things are working now 🎉

I would appreciate some help with debugging the last failures, seems the proptests are discovering some roundtrip issues in the encoding/decoding and the last regular test that is a problem is dealign with a 2049bit key

@dignifiedquire
Copy link
Member Author

and also feel free to start to review the code/fix up anything you think needs improving

@kjvalencik
Copy link

This is awesome! I'm excited to see this PR progressing so much.

seems the proptests are discovering some roundtrip issues in the encoding/decoding and the last regular test that is a problem is dealign with a 2049bit key

I looked into this for a few minutes and these two appear to be different cases of the same problem. crypto-bigint uses 64-bit limbs, which requires it to round higher on number of bytes. For example, with a 2049-bit key it's 264 instead of 257; leading to more padding in the serialized version. This may be the same thing causing round-trip problems.

pub d: BigUint,
pub primes: Vec<BigUint>,
pub n: Odd<BoxedUint>,
pub e: u64,
Copy link

Choose a reason for hiding this comment

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

I don't think it's good to limit e to 64 bits. See RFC 8017 Section 3.1:

In a valid RSA public key, the RSA modulus n is a product of u distinct odd primes r_i, i = 1, 2, ..., u, where u >= 2, and the RSA public exponent e is an integer between 3 and n - 1 satisfying GCD(e,\lambda(n)) = 1, where \lambda(n) = LCM(r_1 - 1, ..., r_u - 1). By convention, the first two primes r_1 and r_2 may also be denoted p and q, respectively.

And FIPS 186-4 page 52

The exponent e shall be an odd positive integer such that:
2¹⁶ < e < 2²⁵⁶.

It should still be BoxedUint.

Copy link
Member Author

Choose a reason for hiding this comment

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

thanks for pointing this out, our default safe constants restricting it, but you are right, it should be possible for larger exponents. this is now fixed

@zeerooth
Copy link

I tried testing this PR in a no_std environment, but it doesn't compile, as RSA pulls getrandom via crypto-bigint even if I disable default features.

rsa = { git = "https://github.com/RustCrypto/RSA.git", branch = "const-crypto-biguint", default-features = false }
    rsa v0.10.0-pre.2 (https://github.com/RustCrypto/RSA.git?branch=const-crypto-biguint#74d31971)
    ├── const-oid v0.10.0-rc.0
    ├── crypto-bigint v0.6.0-rc.5
    │   ├── num-traits v0.2.19
    │   │   [build-dependencies]
    │   │   └── autocfg v1.4.0
    │   ├── rand_core v0.6.4
    │   │   └── getrandom v0.2.15
    │   │       └── cfg-if v1.0.0
    │   ├── subtle v2.6.1
    │   └── zeroize v1.8.1
error: target is not supported, for more information see: https://docs.rs/getrandom/#unsupported-targets
   --> /home/----/.cargo/registry/src/index.crates.io-6f17d22bba15001f/getrandom-0.2.15/src/lib.rs:347:9
    |
347 | /         compile_error!("target is not supported, for more information see: \
348 | |                         https://docs.rs/getrandom/#unsupported-targets");
    | |________________________________________________________________________^

@tarcieri tarcieri mentioned this pull request Oct 7, 2024
@@ -1,10 +1,8 @@
//! Generate prime components for the RSA Private Key

use alloc::vec::Vec;
use num_bigint::{BigUint, RandPrime};
#[allow(unused_imports)]
use num_traits::Float;
Copy link
Member

Choose a reason for hiding this comment

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

Float::ln was used to provide support for f64::ln on non-std (used line 45).

@mepi262
Copy link

mepi262 commented Nov 5, 2024

@dignifiedquire
Any update on this pull request?

@dignifiedquire
Copy link
Member Author

@dignifiedquire Any update on this pull request?

no, haven't had time to fix the afformentioned issues yet

@mepi262
Copy link

mepi262 commented Nov 5, 2024

@dignifiedquire
Thank you for your response !
I hope your another project will be succeed and become be able to concentrate on this pull request.

@dignifiedquire
Copy link
Member Author

@tarcieri current benchmarks

# crypto-bigint

# macbook m1
test bench_rsa_2048_pkcsv1_decrypt      ... bench:   7,184,387.50 ns/iter (+/- 425,598.69)
test bench_rsa_2048_pkcsv1_sign_blinded ... bench:  13,453,579.10 ns/iter (+/- 686,276.31)

# AMD
test bench_rsa_2048_pkcsv1_decrypt      ... bench:   9,260,832.80 ns/iter (+/- 30,013.38)
test bench_rsa_2048_pkcsv1_sign_blinded ... bench:  16,610,079.40 ns/iter (+/- 251,292.53)

# master

# macbook m1
test bench_rsa_2048_pkcsv1_decrypt      ... bench:   1,117,479.15 ns/iter (+/- 31,334.30)
test bench_rsa_2048_pkcsv1_sign_blinded ... bench:   1,337,437.55 ns/iter (+/- 88,624.39)

# AMD
test bench_rsa_2048_pkcsv1_decrypt      ... bench:   1,414,348.80 ns/iter (+/- 12,585.71)
test bench_rsa_2048_pkcsv1_sign_blinded ... bench:   1,685,650.00 ns/iter (+/- 11,105.71)

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.