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 54 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
@dignifiedquire
Copy link
Member Author

Most tests are passing at this point, outstanding failures seem to fall into two categories

  • reconstructing keys fails, because we can't do gcd on even values yet
  • the encoding/decoding is slightly different and so reading the test vectors or comparisons are failing there

@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

Choose a reason for hiding this comment

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

@dignifiedquire
The reviewer has commented on your pull request.
Have you read it?

@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).

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.