Replace crypto/bn/random.c with Rust code.
This commit is contained in:
parent
0f8fe6ef36
commit
f9528db33e
@ -158,7 +158,6 @@ include = [
|
||||
"crypto/bn/montgomery.c",
|
||||
"crypto/bn/montgomery_inv.c",
|
||||
"crypto/bn/mul.c",
|
||||
"crypto/bn/random.c",
|
||||
"crypto/bn/shift.c",
|
||||
"crypto/chacha/asm/chacha-armv4.pl",
|
||||
"crypto/chacha/asm/chacha-armv8.pl",
|
||||
|
1
build.rs
1
build.rs
@ -93,7 +93,6 @@ const RING_SRCS: &'static [(&'static [&'static str], &'static str)] = &[
|
||||
(&[], "crypto/bn/montgomery.c"),
|
||||
(&[], "crypto/bn/montgomery_inv.c"),
|
||||
(&[], "crypto/bn/mul.c"),
|
||||
(&[], "crypto/bn/random.c"),
|
||||
(&[], "crypto/bn/shift.c"),
|
||||
(&[], "crypto/cipher/e_aes.c"),
|
||||
(&[], "crypto/crypto.c"),
|
||||
|
@ -1,132 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com). */
|
||||
|
||||
#include <GFp/bn.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <GFp/err.h>
|
||||
|
||||
|
||||
int GFp_BN_rand_range_ex(BIGNUM *r, const BIGNUM *max_exclusive, RAND *rng) {
|
||||
assert(!GFp_BN_is_zero(max_exclusive));
|
||||
assert(!GFp_BN_is_one(max_exclusive));
|
||||
|
||||
if (!GFp_bn_wexpand(r, max_exclusive->top)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!GFp_rand_mod(r->d, max_exclusive->d, max_exclusive->top, rng)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
r->top = max_exclusive->top;
|
||||
GFp_bn_correct_top(r);
|
||||
|
||||
return 1;
|
||||
}
|
@ -269,18 +269,6 @@ OPENSSL_EXPORT int GFp_BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a,
|
||||
const BIGNUM *b, const BIGNUM *m);
|
||||
|
||||
|
||||
/* Random generation. */
|
||||
|
||||
|
||||
extern int GFp_rand_mod(BN_ULONG *dest, const BN_ULONG *max_exclusive,
|
||||
size_t num_limbs, RAND *rand);
|
||||
|
||||
/* GFp_BN_rand_range_ex sets |rnd| to a random value in [1..max_exclusive). It
|
||||
* returns one on success and zero otherwise. */
|
||||
OPENSSL_EXPORT int GFp_BN_rand_range_ex(BIGNUM *r, const BIGNUM *max_exclusive,
|
||||
RAND *rng);
|
||||
|
||||
|
||||
/* Number theory functions */
|
||||
|
||||
/* GFp_BN_mod_inverse_odd sets |out| equal to |a|^-1, mod |n|. |a| must be
|
||||
|
@ -159,12 +159,6 @@ pub mod rand;
|
||||
#[path = "rsa/rsa.rs"]
|
||||
mod rsa;
|
||||
|
||||
// Really a private method; only has public visibility so that C compilation
|
||||
// can see it.
|
||||
#[cfg(feature = "use_heap")]
|
||||
#[doc(hidden)]
|
||||
pub use rsa::GFp_rand_mod;
|
||||
|
||||
pub mod signature;
|
||||
|
||||
#[cfg(any(feature = "use_heap", test))]
|
||||
|
13
src/rand.rs
13
src/rand.rs
@ -286,19 +286,6 @@ mod darwin {
|
||||
}
|
||||
}
|
||||
|
||||
/// An adapter that lets the C code use `SecureRandom`.
|
||||
#[allow(non_snake_case)]
|
||||
#[doc(hidden)]
|
||||
pub struct RAND<'a> {
|
||||
pub rng: &'a SecureRandom,
|
||||
}
|
||||
|
||||
impl<'a> RAND<'a> {
|
||||
/// Wraps `rng` in a `RAND` so it can be passed to non-Rust code.
|
||||
pub fn new(rng: &'a SecureRandom) -> RAND<'a> { RAND { rng: rng } }
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use rand;
|
||||
|
@ -564,25 +564,26 @@ pub fn elem_exp_consttime<M>(
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
pub fn elem_randomize<M, E>(a: &mut Elem<M, E>, m: &Modulus<M>,
|
||||
rng: &rand::SecureRandom)
|
||||
-> Result<(), error::Unspecified> {
|
||||
a.value.randomize(m.value.as_ref(), rng)
|
||||
pub fn elem_randomize<E>(a: &mut Elem<super::N, E>, m: &Modulus<super::N>,
|
||||
rng: &rand::SecureRandom)
|
||||
-> Result<(), error::Unspecified> {
|
||||
a.value.randomize(m, rng)
|
||||
}
|
||||
|
||||
// r = 1/a (mod m), blinded with a random element.
|
||||
//
|
||||
// This relies on the invariants of `Modulus` that its value is odd and larger
|
||||
// than one.
|
||||
pub fn elem_set_to_inverse_blinded<M>(
|
||||
r: &mut Elem<M, R>, a: &Elem<M, Unencoded>, m: &Modulus<M>,
|
||||
rng: &rand::SecureRandom) -> Result<(), InversionError> {
|
||||
let mut blinding_factor = try!(Elem::<M, R>::zero());
|
||||
try!(blinding_factor.value.randomize(m.value.as_ref(), rng));
|
||||
pub fn elem_set_to_inverse_blinded(
|
||||
r: &mut Elem<super::N, R>, a: &Elem<super::N, Unencoded>,
|
||||
n: &Modulus<super::N>, rng: &rand::SecureRandom)
|
||||
-> Result<(), InversionError> {
|
||||
let mut blinding_factor = try!(Elem::<super::N, R>::zero());
|
||||
try!(elem_randomize(&mut blinding_factor, n, rng));
|
||||
let to_blind = try!(a.try_clone());
|
||||
let blinded = try!(elem_mul(&blinding_factor, to_blind, m));
|
||||
let blinded_inverse = try!(elem_inverse(blinded, m));
|
||||
try!(elem_set_to_product(r, &blinding_factor, &blinded_inverse, m));
|
||||
let blinded = try!(elem_mul(&blinding_factor, to_blind, n));
|
||||
let blinded_inverse = try!(elem_inverse(blinded, n));
|
||||
try!(elem_set_to_product(r, &blinding_factor, &blinded_inverse, n));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -794,11 +795,11 @@ impl Nonnegative {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn randomize(&mut self, m: &BIGNUM, rng: &rand::SecureRandom)
|
||||
fn randomize(&mut self, m: &Modulus<super::N>, rng: &rand::SecureRandom)
|
||||
-> Result<(), error::Unspecified> {
|
||||
let mut rand = rand::RAND::new(rng);
|
||||
bssl::map_result(unsafe {
|
||||
GFp_BN_rand_range_ex(self.as_mut_ref(), m, &mut rand)
|
||||
let m = (m.value.0).0.limbs();
|
||||
self.0.make_limbs(m.len(), |limbs| {
|
||||
super::random::set_to_rand_mod(limbs, m, rng)
|
||||
})
|
||||
}
|
||||
|
||||
@ -929,9 +930,26 @@ mod repr_c {
|
||||
self.top -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_limbs<F>(&mut self, num_limbs: usize, f: F)
|
||||
-> Result<(), error::Unspecified>
|
||||
where F: FnOnce(&mut [limb::Limb])
|
||||
-> Result<(), error::Unspecified> {
|
||||
let num_limbs = num_limbs as c::int; // XXX
|
||||
try!(bssl::map_result(unsafe {
|
||||
GFp_bn_wexpand(self, num_limbs)
|
||||
}));
|
||||
self.top = num_limbs;
|
||||
try!(f(self.limbs_mut()));
|
||||
unsafe {
|
||||
GFp_bn_correct_top(self)
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
extern {
|
||||
fn GFp_bn_correct_top(r: &mut BIGNUM);
|
||||
fn GFp_bn_wexpand(r: &mut BIGNUM, words: c::int) -> c::int;
|
||||
}
|
||||
}
|
||||
@ -975,12 +993,6 @@ extern {
|
||||
n0: &N0) -> c::int;
|
||||
}
|
||||
|
||||
#[allow(improper_ctypes)]
|
||||
extern {
|
||||
fn GFp_BN_rand_range_ex(r: &mut BIGNUM, max_exclusive: &BIGNUM,
|
||||
rng: &mut rand::RAND) -> c::int;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@ -1088,20 +1100,22 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_elem_set_to_inverse_blinded_invertible() {
|
||||
use super::super::N;
|
||||
|
||||
let rng = rand::SystemRandom::new();
|
||||
|
||||
test::from_file("src/rsa/bigint_elem_inverse_invertible_tests.txt",
|
||||
|section, test_case| {
|
||||
assert_eq!(section, "");
|
||||
|
||||
let m = consume_modulus::<M>(test_case, "M");
|
||||
let a = consume_elem(test_case, "A", &m);
|
||||
let expected_result = consume_elem(test_case, "R", &m);
|
||||
let mut actual_result = try!(Elem::<M, R>::zero());
|
||||
assert!(elem_set_to_inverse_blinded(&mut actual_result, &a, &m,
|
||||
let n = consume_modulus::<N>(test_case, "M");
|
||||
let a = consume_elem(test_case, "A", &n);
|
||||
let expected_result = consume_elem(test_case, "R", &n);
|
||||
let mut actual_result = try!(Elem::<N, R>::zero());
|
||||
assert!(elem_set_to_inverse_blinded(&mut actual_result, &a, &n,
|
||||
&rng).is_ok());
|
||||
let one: Elem<M, Unencoded> = try!(Elem::one());
|
||||
let actual_result = try!(elem_mul(&one, actual_result, &m));
|
||||
let one: Elem<N, Unencoded> = try!(Elem::one());
|
||||
let actual_result = try!(elem_mul(&one, actual_result, &n));
|
||||
assert_elem_eq(&actual_result, &expected_result);
|
||||
Ok(())
|
||||
})
|
||||
@ -1126,16 +1140,18 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_elem_set_to_inverse_blinded_noninvertible() {
|
||||
use super::super::N;
|
||||
|
||||
let rng = rand::SystemRandom::new();
|
||||
|
||||
test::from_file("src/rsa/bigint_elem_inverse_noninvertible_tests.txt",
|
||||
|section, test_case| {
|
||||
assert_eq!(section, "");
|
||||
|
||||
let m = consume_modulus::<M>(test_case, "M");
|
||||
let a = consume_elem(test_case, "A", &m);
|
||||
let mut actual_result = try!(Elem::<M, R>::zero());
|
||||
match elem_set_to_inverse_blinded(&mut actual_result, &a, &m, &rng) {
|
||||
let n = consume_modulus::<N>(test_case, "M");
|
||||
let a = consume_elem(test_case, "A", &n);
|
||||
let mut actual_result = try!(Elem::<N, R>::zero());
|
||||
match elem_set_to_inverse_blinded(&mut actual_result, &a, &n, &rng) {
|
||||
Err(InversionError::NoInverse) => (),
|
||||
Err(InversionError::Unspecified) => unreachable!("Unspecified"),
|
||||
Ok(..) => unreachable!("No error"),
|
||||
|
@ -16,35 +16,13 @@
|
||||
//! Generation of random field elements, in particular field elements in GFn
|
||||
//! where *n* is an RSA public modulus.
|
||||
|
||||
use {c, core, rand, error, rsa};
|
||||
use {rand, error, rsa};
|
||||
use limb::*;
|
||||
|
||||
/// Sets `out`, which has `num_limbs` limbs, to a random value in the range
|
||||
/// [1, `max_exclusive`), where `max_exclusive` also has `num_limbs` limbs.
|
||||
#[doc(hidden)]
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn GFp_rand_mod(out: *mut Limb, max_exclusive: *const Limb,
|
||||
num_limbs: c::size_t, rng: *mut rand::RAND)
|
||||
-> c::int {
|
||||
const ERR: c::int = 0;
|
||||
const SUCCESS: c::int = 1;
|
||||
|
||||
let max_exclusive = core::slice::from_raw_parts(max_exclusive, num_limbs);
|
||||
let mut out = core::slice::from_raw_parts_mut(out, num_limbs);
|
||||
|
||||
let result = set_to_rand_mod(&mut out, &max_exclusive, (*rng).rng);
|
||||
if result.is_err() {
|
||||
return ERR;
|
||||
}
|
||||
|
||||
SUCCESS
|
||||
}
|
||||
|
||||
/// Chooses a positive integer less than `max_exclusive` uniformly at random
|
||||
/// and stores it into `out`.
|
||||
fn set_to_rand_mod(out: &mut [Limb], max_exclusive: &[Limb],
|
||||
rng: &rand::SecureRandom)
|
||||
-> Result<(), error::Unspecified> {
|
||||
/// Sets `out` to a *uniformly* random value in the range [1, `max_exclusive`).
|
||||
pub fn set_to_rand_mod(out: &mut [Limb], max_exclusive: &[Limb],
|
||||
rng: &rand::SecureRandom)
|
||||
-> Result<(), error::Unspecified> {
|
||||
assert_eq!(out.len(), max_exclusive.len());
|
||||
assert!(out.len() >= 1);
|
||||
assert!(out.len() <= rsa::PRIVATE_KEY_PUBLIC_MODULUS_MAX_LIMBS);
|
||||
|
@ -148,8 +148,3 @@ mod bigint;
|
||||
mod blinding;
|
||||
|
||||
mod random;
|
||||
|
||||
// Really a private method; only has public visibility so that C compilation
|
||||
// can see it.
|
||||
#[doc(hidden)]
|
||||
pub use rsa::random::GFp_rand_mod;
|
||||
|
Loading…
x
Reference in New Issue
Block a user