Reformat based on suggestions from rustfmt.
This is a first step toward fully-automated formatting. A custom format is used, primarily to tell rustfmt to wrap at column 80(-ish) instead of column 100(-ish), and to use more compact styles. Many rustfmt suggestions for rewrapping function calls were ignored because they did not result in the minimum number of lines and/or because I'm still unsure the best way to format a long chain. Some suggestions for reformatting macros were ignored because they ruined the indention. Some other suggestions were ignored because they seemed like bugs and/or seemed to make things clearly worse. Further work is planned, in order to make the formatting fully automatic.
This commit is contained in:
parent
f5be9c34b1
commit
279bd0a2e9
8
rustfmt.toml
Normal file
8
rustfmt.toml
Normal file
@ -0,0 +1,8 @@
|
||||
max_width = 80
|
||||
ideal_width = 80
|
||||
fn_call_width = 80
|
||||
force_explicit_abi = false
|
||||
fn_single_line = true
|
||||
fn_args_density = "Compressed"
|
||||
match_block_trailing_comma = true
|
||||
normalize_comments = false
|
@ -51,7 +51,8 @@ impl OpeningKey {
|
||||
/// C analogs: `EVP_AEAD_CTX_init_with_direction` with direction
|
||||
/// `evp_aead_open`, `EVP_AEAD_CTX_init`.
|
||||
///
|
||||
/// Go analog: [`crypto.aes.NewCipher`](https://golang.org/pkg/crypto/aes/#NewCipher)
|
||||
/// Go analog:
|
||||
/// [`crypto.aes.NewCipher`](https://golang.org/pkg/crypto/aes/#NewCipher)
|
||||
/// + [`crypto.cipher.NewGCM`](https://golang.org/pkg/crypto/cipher/#NewGCM)
|
||||
#[inline]
|
||||
pub fn new(algorithm: &'static Algorithm, key_bytes: &[u8])
|
||||
@ -59,8 +60,8 @@ impl OpeningKey {
|
||||
let mut key = OpeningKey {
|
||||
key: Key {
|
||||
algorithm: algorithm,
|
||||
ctx_buf: [0; KEY_CTX_BUF_ELEMS]
|
||||
}
|
||||
ctx_buf: [0; KEY_CTX_BUF_ELEMS],
|
||||
},
|
||||
};
|
||||
try!(key.key.init(key_bytes));
|
||||
Ok(key)
|
||||
@ -121,7 +122,8 @@ impl SealingKey {
|
||||
/// C analogs: `EVP_AEAD_CTX_init_with_direction` with direction
|
||||
/// `evp_aead_seal`, `EVP_AEAD_CTX_init`.
|
||||
///
|
||||
/// Go analog: [`crypto.aes.NewCipher`](https://golang.org/pkg/crypto/aes/#NewCipher)
|
||||
/// Go analog:
|
||||
/// [`crypto.aes.NewCipher`](https://golang.org/pkg/crypto/aes/#NewCipher)
|
||||
/// + [`crypto.cipher.NewGCM`](https://golang.org/pkg/crypto/cipher/#NewGCM)
|
||||
#[inline]
|
||||
pub fn new(algorithm: &'static Algorithm, key_bytes: &[u8])
|
||||
@ -130,7 +132,7 @@ impl SealingKey {
|
||||
key: Key {
|
||||
algorithm: algorithm,
|
||||
ctx_buf: [0; KEY_CTX_BUF_ELEMS],
|
||||
}
|
||||
},
|
||||
};
|
||||
try!(key.key.init(key_bytes));
|
||||
Ok(key)
|
||||
@ -221,7 +223,8 @@ impl Key {
|
||||
///
|
||||
/// C analog: `EVP_AEAD`
|
||||
///
|
||||
/// Go analog: [`crypto.cipher.AEAD`](https://golang.org/pkg/crypto/cipher/#AEAD)
|
||||
/// Go analog:
|
||||
/// [`crypto.cipher.AEAD`](https://golang.org/pkg/crypto/cipher/#AEAD)
|
||||
pub struct Algorithm {
|
||||
init: fn(ctx_buf: &mut [u8], key: &[u8]) -> Result<(), error::Unspecified>,
|
||||
|
||||
@ -249,7 +252,7 @@ impl Algorithm {
|
||||
/// C analog: `EVP_AEAD_max_overhead`
|
||||
///
|
||||
/// Go analog:
|
||||
/// [`crypto.cipher.AEAD.Overhead`](https://golang.org/pkg/crypto/cipher/#AEAD)
|
||||
/// [`crypto.cipher.AEAD.Overhead`](https://golang.org/pkg/crypto/cipher/#AEAD)
|
||||
#[inline(always)]
|
||||
pub fn max_overhead_len(&self) -> usize { TAG_LEN }
|
||||
|
||||
@ -258,7 +261,7 @@ impl Algorithm {
|
||||
/// C analog: `EVP_AEAD_nonce_length`
|
||||
///
|
||||
/// Go analog:
|
||||
/// [`crypto.cipher.AEAD.NonceSize`](https://golang.org/pkg/crypto/cipher/#AEAD)
|
||||
/// [`crypto.cipher.AEAD.NonceSize`](https://golang.org/pkg/crypto/cipher/#AEAD)
|
||||
#[inline(always)]
|
||||
pub fn nonce_len(&self) -> usize { NONCE_LEN }
|
||||
}
|
||||
@ -279,7 +282,7 @@ const NONCE_LEN: usize = 96 / 8;
|
||||
fn check_per_nonce_max_bytes(in_out_len: usize)
|
||||
-> Result<(), error::Unspecified> {
|
||||
if polyfill::u64_from_usize(in_out_len) >= (1u64 << 32) * 64 - 64 {
|
||||
return Err(error::Unspecified)
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -411,7 +414,8 @@ mod tests {
|
||||
assert_eq!(Ok(ct.len()), s_result);
|
||||
assert_eq!(&ct[..], &s_in_out[..ct.len()]);
|
||||
assert_eq!(Ok(plaintext.len()), o_result);
|
||||
assert_eq!(&plaintext[..], &o_in_out[..plaintext.len()]);
|
||||
assert_eq!(&plaintext[..],
|
||||
&o_in_out[..plaintext.len()]);
|
||||
},
|
||||
Some(ref error) if error == "WRONG_NONCE_LENGTH" => {
|
||||
assert_eq!(Err(error::Unspecified), s_result);
|
||||
@ -419,7 +423,7 @@ mod tests {
|
||||
},
|
||||
Some(error) => {
|
||||
unreachable!("Unexpected error test case: {}", error);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@ -432,10 +436,8 @@ mod tests {
|
||||
let key_data = vec![0u8; key_len * 2];
|
||||
|
||||
// Key is the right size.
|
||||
assert!(aead::OpeningKey::new(aead_alg, &key_data[..key_len])
|
||||
.is_ok());
|
||||
assert!(aead::SealingKey::new(aead_alg, &key_data[..key_len])
|
||||
.is_ok());
|
||||
assert!(aead::OpeningKey::new(aead_alg, &key_data[..key_len]).is_ok());
|
||||
assert!(aead::SealingKey::new(aead_alg, &key_data[..key_len]).is_ok());
|
||||
|
||||
// Key is one byte too small.
|
||||
assert!(aead::OpeningKey::new(aead_alg, &key_data[..(key_len - 1)])
|
||||
@ -486,10 +488,8 @@ mod tests {
|
||||
-> Result<(), error::Unspecified> {
|
||||
let key_len = aead_alg.key_len;
|
||||
let key_data = vec![0u8; key_len];
|
||||
let o_key =
|
||||
try!(aead::OpeningKey::new(aead_alg, &key_data[..key_len]));
|
||||
let s_key =
|
||||
try!(aead::SealingKey::new(aead_alg, &key_data[..key_len]));
|
||||
let o_key = try!(aead::OpeningKey::new(aead_alg, &key_data[..key_len]));
|
||||
let s_key = try!(aead::SealingKey::new(aead_alg, &key_data[..key_len]));
|
||||
|
||||
let nonce_len = aead_alg.nonce_len();
|
||||
|
||||
|
@ -50,14 +50,13 @@ fn chacha20_poly1305_open(ctx: &[u64; aead::KEY_CTX_BUF_ELEMS],
|
||||
ad)
|
||||
}
|
||||
|
||||
fn chacha20_poly1305_update(state: &mut [u8; POLY1305_STATE_LEN],
|
||||
ad: &[u8], ciphertext: &[u8]) {
|
||||
fn chacha20_poly1305_update(state: &mut [u8; POLY1305_STATE_LEN], ad: &[u8],
|
||||
ciphertext: &[u8]) {
|
||||
fn update_padded_16(state: &mut [u8; POLY1305_STATE_LEN], data: &[u8]) {
|
||||
poly1305_update(state, data);
|
||||
if data.len() % 16 != 0 {
|
||||
static PADDING: [u8; 16] = [0u8; 16];
|
||||
poly1305_update(state,
|
||||
&PADDING[..PADDING.len() - (data.len() % 16)])
|
||||
poly1305_update(state, &PADDING[..PADDING.len() - (data.len() % 16)])
|
||||
}
|
||||
}
|
||||
update_padded_16(state, ad);
|
||||
@ -157,7 +156,8 @@ fn open(update: UpdateFn, ctx: &[u64; aead::KEY_CTX_BUF_ELEMS],
|
||||
in_prefix_len != 0 {
|
||||
ChaCha20_ctr32(in_out[in_prefix_len..].as_mut_ptr(),
|
||||
in_out[in_prefix_len..].as_ptr(),
|
||||
in_out.len() - in_prefix_len, chacha20_key, &counter);
|
||||
in_out.len() - in_prefix_len, chacha20_key,
|
||||
&counter);
|
||||
core::ptr::copy(in_out[in_prefix_len..].as_ptr(),
|
||||
in_out.as_mut_ptr(), in_out.len() - in_prefix_len);
|
||||
} else {
|
||||
@ -221,26 +221,20 @@ fn poly1305_update_length(ctx: &mut [u8; POLY1305_STATE_LEN], len: usize) {
|
||||
#[inline(always)]
|
||||
fn poly1305_init(state: &mut [u8; POLY1305_STATE_LEN],
|
||||
key: &[u8; POLY1305_KEY_LEN]) {
|
||||
unsafe {
|
||||
CRYPTO_poly1305_init(state, key)
|
||||
}
|
||||
unsafe { CRYPTO_poly1305_init(state, key) }
|
||||
}
|
||||
|
||||
/// Safe wrapper around |CRYPTO_poly1305_finish|.
|
||||
#[inline(always)]
|
||||
fn poly1305_finish(state: &mut [u8; POLY1305_STATE_LEN],
|
||||
tag_out: &mut [u8; aead::TAG_LEN]) {
|
||||
unsafe {
|
||||
CRYPTO_poly1305_finish(state, tag_out)
|
||||
}
|
||||
unsafe { CRYPTO_poly1305_finish(state, tag_out) }
|
||||
}
|
||||
|
||||
/// Safe wrapper around |CRYPTO_poly1305_update|.
|
||||
#[inline(always)]
|
||||
fn poly1305_update(state: &mut [u8; POLY1305_STATE_LEN], in_: &[u8]) {
|
||||
unsafe {
|
||||
CRYPTO_poly1305_update(state, in_.as_ptr(), in_.len())
|
||||
}
|
||||
unsafe { CRYPTO_poly1305_update(state, in_.as_ptr(), in_.len()) }
|
||||
}
|
||||
|
||||
extern {
|
||||
@ -276,7 +270,7 @@ mod tests {
|
||||
#[test]
|
||||
pub fn test_poly1305_state_len() {
|
||||
assert_eq!((super::POLY1305_STATE_LEN + 255) / 256,
|
||||
(CRYPTO_POLY1305_STATE_LEN + 255) / 256);
|
||||
(CRYPTO_POLY1305_STATE_LEN + 255) / 256);
|
||||
}
|
||||
|
||||
// This verifies the encryption functionality provided by ChaCha20_ctr32
|
||||
|
@ -72,7 +72,8 @@
|
||||
//! # fn main() { x25519_agreement_example().unwrap() }
|
||||
//! ```
|
||||
|
||||
// The "NSA Guide" steps here are from from section 3.1, "Ephemeral Unified Model."
|
||||
// The "NSA Guide" steps here are from from section 3.1, "Ephemeral Unified
|
||||
// Model."
|
||||
|
||||
|
||||
|
||||
@ -105,7 +106,7 @@ pub struct EphemeralPrivateKey {
|
||||
alg: &'static Algorithm,
|
||||
}
|
||||
|
||||
impl <'a> EphemeralPrivateKey {
|
||||
impl<'a> EphemeralPrivateKey {
|
||||
/// Generate a new ephemeral private key for the given algorithm.
|
||||
///
|
||||
/// C analog: `EC_KEY_new_by_curve_name` + `EC_KEY_generate_key`.
|
||||
@ -116,8 +117,7 @@ impl <'a> EphemeralPrivateKey {
|
||||
// This only handles the key generation part of step 1. The rest of
|
||||
// step one is done by `compute_public_key()`.
|
||||
Ok(EphemeralPrivateKey {
|
||||
private_key:
|
||||
try!(ec::PrivateKey::generate(&alg.i, rng)),
|
||||
private_key: try!(ec::PrivateKey::generate(&alg.i, rng)),
|
||||
alg: alg,
|
||||
})
|
||||
}
|
||||
@ -151,9 +151,7 @@ impl <'a> EphemeralPrivateKey {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn bytes(&'a self) -> &'a [u8] {
|
||||
self.private_key.bytes()
|
||||
}
|
||||
pub fn bytes(&'a self) -> &'a [u8] { self.private_key.bytes() }
|
||||
}
|
||||
|
||||
/// Performs a key agreement with an ephemeral private key and the given public
|
||||
|
@ -17,7 +17,7 @@ use {c, error};
|
||||
pub fn map_result(bssl_result: c::int) -> Result<(), error::Unspecified> {
|
||||
match bssl_result {
|
||||
1 => Ok(()),
|
||||
_ => Err(error::Unspecified)
|
||||
_ => Err(error::Unspecified),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,12 +27,10 @@ pub fn verify_slices_are_equal(a: &[u8], b: &[u8])
|
||||
if a.len() != b.len() {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
let result = unsafe {
|
||||
CRYPTO_memcmp(a.as_ptr(), b.as_ptr(), a.len())
|
||||
};
|
||||
let result = unsafe { CRYPTO_memcmp(a.as_ptr(), b.as_ptr(), a.len()) };
|
||||
match result {
|
||||
0 => Ok(()),
|
||||
_ => Err(error::Unspecified)
|
||||
_ => Err(error::Unspecified),
|
||||
}
|
||||
}
|
||||
|
||||
|
71
src/der.rs
71
src/der.rs
@ -19,8 +19,8 @@
|
||||
use untrusted;
|
||||
use error;
|
||||
|
||||
pub const CONSTRUCTED : u8 = 1 << 5;
|
||||
pub const CONTEXT_SPECIFIC : u8 = 2 << 6;
|
||||
pub const CONSTRUCTED: u8 = 1 << 5;
|
||||
pub const CONTEXT_SPECIFIC: u8 = 2 << 6;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
#[repr(u8)]
|
||||
@ -82,7 +82,7 @@ pub fn read_tag_and_get_value<'a>(input: &mut untrusted::Reader<'a>)
|
||||
},
|
||||
_ => {
|
||||
return Err(error::Unspecified); // We don't support longer lengths.
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
let inner = try!(input.skip_and_get_input(length));
|
||||
@ -200,44 +200,41 @@ mod tests {
|
||||
static ZERO_INTEGER: &'static [u8] = &[0x02, 0x01, 0x00];
|
||||
|
||||
static GOOD_POSITIVE_INTEGERS: &'static [(&'static [u8], u8)] =
|
||||
&[
|
||||
(&[0x02, 0x01, 0x01], 0x01),
|
||||
(&[0x02, 0x01, 0x02], 0x02),
|
||||
(&[0x02, 0x01, 0x7e], 0x7e),
|
||||
(&[0x02, 0x01, 0x7f], 0x7f),
|
||||
&[(&[0x02, 0x01, 0x01], 0x01),
|
||||
(&[0x02, 0x01, 0x02], 0x02),
|
||||
(&[0x02, 0x01, 0x7e], 0x7e),
|
||||
(&[0x02, 0x01, 0x7f], 0x7f),
|
||||
|
||||
// Values that need to have an 0x00 prefix to disambiguate them from
|
||||
// them from negative values.
|
||||
(&[0x02, 0x02, 0x00, 0x80], 0x80),
|
||||
(&[0x02, 0x02, 0x00, 0x81], 0x81),
|
||||
(&[0x02, 0x02, 0x00, 0xfe], 0xfe),
|
||||
(&[0x02, 0x02, 0x00, 0xff], 0xff),
|
||||
];
|
||||
// Values that need to have an 0x00 prefix to disambiguate them from
|
||||
// them from negative values.
|
||||
(&[0x02, 0x02, 0x00, 0x80], 0x80),
|
||||
(&[0x02, 0x02, 0x00, 0x81], 0x81),
|
||||
(&[0x02, 0x02, 0x00, 0xfe], 0xfe),
|
||||
(&[0x02, 0x02, 0x00, 0xff], 0xff)];
|
||||
|
||||
static BAD_NONNEGATIVE_INTEGERS: &'static [&'static [u8]] = &[
|
||||
&[], // At end of input
|
||||
&[0x02], // Tag only
|
||||
&[0x02, 0x00], // Empty value
|
||||
static BAD_NONNEGATIVE_INTEGERS: &'static [&'static [u8]] =
|
||||
&[&[], // At end of input
|
||||
&[0x02], // Tag only
|
||||
&[0x02, 0x00], // Empty value
|
||||
|
||||
// Length mismatch
|
||||
&[0x02, 0x00, 0x01],
|
||||
&[0x02, 0x01],
|
||||
&[0x02, 0x01, 0x00, 0x01],
|
||||
&[0x02, 0x01, 0x01, 0x00], // Would be valid if last byte is ignored.
|
||||
&[0x02, 0x02, 0x01],
|
||||
// Length mismatch
|
||||
&[0x02, 0x00, 0x01],
|
||||
&[0x02, 0x01],
|
||||
&[0x02, 0x01, 0x00, 0x01],
|
||||
&[0x02, 0x01, 0x01, 0x00], // Would be valid if last byte is ignored.
|
||||
&[0x02, 0x02, 0x01],
|
||||
|
||||
// Negative values
|
||||
&[0x02, 0x01, 0x80],
|
||||
&[0x02, 0x01, 0xfe],
|
||||
&[0x02, 0x01, 0xff],
|
||||
// Negative values
|
||||
&[0x02, 0x01, 0x80],
|
||||
&[0x02, 0x01, 0xfe],
|
||||
&[0x02, 0x01, 0xff],
|
||||
|
||||
// Values that have an unnecessary leading 0x00
|
||||
&[0x02, 0x02, 0x00, 0x00],
|
||||
&[0x02, 0x02, 0x00, 0x01],
|
||||
&[0x02, 0x02, 0x00, 0x02],
|
||||
&[0x02, 0x02, 0x00, 0x7e],
|
||||
&[0x02, 0x02, 0x00, 0x7f],
|
||||
];
|
||||
// Values that have an unnecessary leading 0x00
|
||||
&[0x02, 0x02, 0x00, 0x00],
|
||||
&[0x02, 0x02, 0x00, 0x01],
|
||||
&[0x02, 0x02, 0x00, 0x02],
|
||||
&[0x02, 0x02, 0x00, 0x7e],
|
||||
&[0x02, 0x02, 0x00, 0x7f]];
|
||||
|
||||
#[test]
|
||||
fn test_small_nonnegative_integer() {
|
||||
@ -269,7 +266,7 @@ mod tests {
|
||||
with_good_i(test_in, |input| {
|
||||
let test_out = [test_out];
|
||||
assert_eq!(try!(positive_integer(input)),
|
||||
untrusted::Input::from(&test_out[..]));
|
||||
untrusted::Input::from(&test_out[..]));
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
|
@ -203,15 +203,15 @@ impl Context {
|
||||
// XXX: This should just be `#[derive(Clone)]` but that doesn't work because
|
||||
// `[u8; 128]` doesn't implement `Clone`.
|
||||
impl Clone for Context {
|
||||
fn clone(&self) -> Context {
|
||||
fn clone(&self) -> Context {
|
||||
Context {
|
||||
state: self.state,
|
||||
pending: self.pending,
|
||||
completed_data_blocks: self.completed_data_blocks,
|
||||
num_pending: self.num_pending,
|
||||
algorithm: self.algorithm
|
||||
algorithm: self.algorithm,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the digest of `data` using the given digest algorithm.
|
||||
@ -225,7 +225,8 @@ impl Clone for Context {
|
||||
/// # fn main() {
|
||||
/// use ring::{digest, test};
|
||||
///
|
||||
/// let expected_hex = "09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b";
|
||||
/// let expected_hex =
|
||||
/// "09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b";
|
||||
/// let expected: Vec<u8> = test::from_hex(expected_hex).unwrap();
|
||||
/// let actual = digest::digest(&digest::SHA256, b"hello, world");
|
||||
///
|
||||
@ -295,8 +296,8 @@ pub struct Algorithm {
|
||||
|
||||
block_data_order: unsafe extern fn(state: &mut [u64; MAX_CHAINING_LEN / 8],
|
||||
data: *const u8, num: c::size_t),
|
||||
format_output: fn (input: &[u64; MAX_CHAINING_LEN / 8]) ->
|
||||
[u64; MAX_OUTPUT_LEN / 8],
|
||||
format_output: fn(input: &[u64; MAX_CHAINING_LEN / 8])
|
||||
-> [u64; MAX_OUTPUT_LEN / 8],
|
||||
|
||||
initial_state: [u64; MAX_CHAINING_LEN / 8],
|
||||
}
|
||||
@ -305,7 +306,11 @@ impl core::fmt::Debug for Algorithm {
|
||||
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
// This would have to change if/when we add other algorithms with the
|
||||
// same output lengths.
|
||||
let n = if self.output_len == 20 { 1 } else { self.output_len * 8 };
|
||||
let n = if self.output_len == 20 {
|
||||
1
|
||||
} else {
|
||||
self.output_len * 8
|
||||
};
|
||||
write!(fmt, "SHA-{:?}", n)
|
||||
}
|
||||
}
|
||||
@ -409,30 +414,26 @@ pub const MAX_CHAINING_LEN: usize = MAX_OUTPUT_LEN;
|
||||
fn sha256_format_output(input: &[u64; MAX_CHAINING_LEN / 8])
|
||||
-> [u64; MAX_OUTPUT_LEN / 8] {
|
||||
let in32 = &polyfill::slice::u64_as_u32(input)[..8];
|
||||
[
|
||||
u32x2!(in32[0].to_be(), in32[1].to_be()),
|
||||
u32x2!(in32[2].to_be(), in32[3].to_be()),
|
||||
u32x2!(in32[4].to_be(), in32[5].to_be()),
|
||||
u32x2!(in32[6].to_be(), in32[7].to_be()),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
]
|
||||
[u32x2!(in32[0].to_be(), in32[1].to_be()),
|
||||
u32x2!(in32[2].to_be(), in32[3].to_be()),
|
||||
u32x2!(in32[4].to_be(), in32[5].to_be()),
|
||||
u32x2!(in32[6].to_be(), in32[7].to_be()),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0]
|
||||
}
|
||||
|
||||
fn sha512_format_output(input: &[u64; MAX_CHAINING_LEN / 8])
|
||||
-> [u64; MAX_OUTPUT_LEN / 8] {
|
||||
[
|
||||
input[0].to_be(),
|
||||
input[1].to_be(),
|
||||
input[2].to_be(),
|
||||
input[3].to_be(),
|
||||
input[4].to_be(),
|
||||
input[5].to_be(),
|
||||
input[6].to_be(),
|
||||
input[7].to_be(),
|
||||
]
|
||||
[input[0].to_be(),
|
||||
input[1].to_be(),
|
||||
input[2].to_be(),
|
||||
input[3].to_be(),
|
||||
input[4].to_be(),
|
||||
input[5].to_be(),
|
||||
input[6].to_be(),
|
||||
input[7].to_be()]
|
||||
}
|
||||
|
||||
/// Calculates the SHA-512 digest of the concatenation of |part1| through
|
||||
@ -554,7 +555,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn run_known_answer_test(digest_alg: &'static digest::Algorithm,
|
||||
file_name: &str, ) {
|
||||
file_name: &str) {
|
||||
let section_name = &format!("L = {}", digest_alg.output_len);
|
||||
test::from_file(file_name, |section, test_case| {
|
||||
assert_eq!(section_name, section);
|
||||
|
@ -24,9 +24,14 @@ const CHAINING_WORDS: usize = CHAINING_LEN / 4;
|
||||
|
||||
type W32 = Wrapping<u32>;
|
||||
|
||||
#[inline] fn ch(x: W32, y: W32, z: W32) -> W32 { (x & y) | (!x & z) }
|
||||
#[inline] fn parity(x: W32, y: W32, z: W32) -> W32 { x ^ y ^ z }
|
||||
#[inline] fn maj(x: W32, y: W32, z: W32) -> W32 { (x & y) | (x & z) | (y & z) }
|
||||
#[inline]
|
||||
fn ch(x: W32, y: W32, z: W32) -> W32 { (x & y) | (!x & z) }
|
||||
|
||||
#[inline]
|
||||
fn parity(x: W32, y: W32, z: W32) -> W32 { x ^ y ^ z }
|
||||
|
||||
#[inline]
|
||||
fn maj(x: W32, y: W32, z: W32) -> W32 { (x & y) | (x & z) | (y & z) }
|
||||
|
||||
/// The main purpose in retaining this is to support legacy protocols and OCSP,
|
||||
/// none of which need a fast SHA-1 implementation.
|
||||
@ -34,8 +39,7 @@ type W32 = Wrapping<u32>;
|
||||
/// Unlike SHA-256, SHA-384, and SHA-512,
|
||||
/// there is no assembly language implementation.
|
||||
pub unsafe extern fn block_data_order(state: &mut [u64; MAX_CHAINING_LEN / 8],
|
||||
data: *const u8,
|
||||
num: c::size_t) {
|
||||
data: *const u8, num: c::size_t) {
|
||||
let data = data as *const [u8; BLOCK_LEN];
|
||||
let blocks = core::slice::from_raw_parts(data, num);
|
||||
block_data_order_safe(state, blocks)
|
||||
@ -71,7 +75,7 @@ fn block_data_order_safe(state: &mut [u64; MAX_CHAINING_LEN / 8],
|
||||
20...39 => (0x6ed9eba1, parity(b, c, d)),
|
||||
40...59 => (0x8f1bbcdc, maj(b, c, d)),
|
||||
60...79 => (0xca62c1d6, parity(b, c, d)),
|
||||
_ => unreachable!()
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let tt = polyfill::wrapping_rotate_left_u32(a, 5) + f + e +
|
||||
Wrapping(k) + w[t];
|
||||
|
29
src/ec/ec.rs
29
src/ec/ec.rs
@ -23,24 +23,22 @@ pub struct AgreementAlgorithmImpl {
|
||||
|
||||
pub nid: c::int,
|
||||
|
||||
generate_private_key:
|
||||
fn(rng: &rand::SecureRandom) -> Result<PrivateKey, error::Unspecified>,
|
||||
generate_private_key: fn(rng: &rand::SecureRandom)
|
||||
-> Result<PrivateKey, error::Unspecified>,
|
||||
|
||||
public_from_private:
|
||||
fn(public_out: &mut [u8], private_key: &PrivateKey)
|
||||
-> Result<(), error::Unspecified>,
|
||||
public_from_private: fn(public_out: &mut [u8], private_key: &PrivateKey)
|
||||
-> Result<(), error::Unspecified>,
|
||||
|
||||
pub ecdh:
|
||||
fn(out: &mut [u8], private_key: &PrivateKey,
|
||||
peer_public_key: untrusted::Input)
|
||||
-> Result<(), error::Unspecified>,
|
||||
pub ecdh: fn(out: &mut [u8], private_key: &PrivateKey,
|
||||
peer_public_key: untrusted::Input)
|
||||
-> Result<(), error::Unspecified>,
|
||||
}
|
||||
|
||||
pub struct PrivateKey {
|
||||
bytes: [u8; SCALAR_MAX_BYTES],
|
||||
}
|
||||
|
||||
impl <'a> PrivateKey {
|
||||
impl<'a> PrivateKey {
|
||||
pub fn generate(alg: &AgreementAlgorithmImpl, rng: &rand::SecureRandom)
|
||||
-> Result<PrivateKey, error::Unspecified> {
|
||||
init::init_once();
|
||||
@ -51,12 +49,9 @@ impl <'a> PrivateKey {
|
||||
pub fn from_test_vector(alg: &AgreementAlgorithmImpl, test_vector: &[u8])
|
||||
-> PrivateKey {
|
||||
init::init_once();
|
||||
let mut result = PrivateKey {
|
||||
bytes: [0; SCALAR_MAX_BYTES],
|
||||
};
|
||||
let mut result = PrivateKey { bytes: [0; SCALAR_MAX_BYTES] };
|
||||
{
|
||||
let private_key_bytes =
|
||||
&mut result.bytes[..alg.elem_and_scalar_len];
|
||||
let private_key_bytes = &mut result.bytes[..alg.elem_and_scalar_len];
|
||||
assert_eq!(test_vector.len(), private_key_bytes.len());
|
||||
for i in 0..private_key_bytes.len() {
|
||||
private_key_bytes[i] = test_vector[i];
|
||||
@ -66,9 +61,7 @@ impl <'a> PrivateKey {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn bytes(&'a self) -> &'a [u8] {
|
||||
&self.bytes[..]
|
||||
}
|
||||
pub fn bytes(&'a self) -> &'a [u8] { &self.bytes[..] }
|
||||
|
||||
#[inline(always)]
|
||||
pub fn compute_public_key(&self, alg: &AgreementAlgorithmImpl,
|
||||
|
@ -42,8 +42,7 @@ impl<'a> Ed25519KeyPair {
|
||||
/// future use then use `generate_serializable()` instead.
|
||||
pub fn generate(rng: &rand::SecureRandom)
|
||||
-> Result<Ed25519KeyPair, error::Unspecified> {
|
||||
Ed25519KeyPair::generate_serializable(rng)
|
||||
.map(|(key_pair, _)| key_pair)
|
||||
Ed25519KeyPair::generate_serializable(rng).map(|(key_pair, _)| key_pair)
|
||||
}
|
||||
|
||||
/// Generates a new key pair and returns the key pair as both an
|
||||
@ -81,8 +80,8 @@ impl<'a> Ed25519KeyPair {
|
||||
/// corruption that might have occurred during storage of the key pair.
|
||||
pub fn from_bytes(private_key: &[u8], public_key: &[u8])
|
||||
-> Result<Ed25519KeyPair, error::Unspecified> {
|
||||
let pair =
|
||||
try!(Ed25519KeyPair::from_bytes_unchecked(private_key, public_key));
|
||||
let pair = try!(Ed25519KeyPair::from_bytes_unchecked(private_key,
|
||||
public_key));
|
||||
let mut public_key_check = [0; 32];
|
||||
unsafe {
|
||||
GFp_ed25519_public_from_private(public_key_check.as_mut_ptr(),
|
||||
@ -111,9 +110,7 @@ impl<'a> Ed25519KeyPair {
|
||||
}
|
||||
|
||||
/// Returns a reference to the little-endian-encoded public key bytes.
|
||||
pub fn public_key_bytes(&'a self) -> &'a [u8] {
|
||||
&self.private_public[32..]
|
||||
}
|
||||
pub fn public_key_bytes(&'a self) -> &'a [u8] { &self.private_public[32..] }
|
||||
|
||||
/// Returns the signature of the message `msg`.
|
||||
pub fn sign(&self, msg: &[u8]) -> signature::Signature {
|
||||
@ -132,7 +129,7 @@ impl<'a> Ed25519KeyPair {
|
||||
/// Ed25519 uses SHA-512 as the digest algorithm.
|
||||
///
|
||||
/// [Ed25519]: https://ed25519.cr.yp.to/
|
||||
pub static ED25519: EdDSAParameters = EdDSAParameters { };
|
||||
pub static ED25519: EdDSAParameters = EdDSAParameters {};
|
||||
|
||||
impl signature::VerificationAlgorithm for EdDSAParameters {
|
||||
fn verify(&self, public_key: untrusted::Input, msg: untrusted::Input,
|
||||
@ -150,7 +147,7 @@ impl signature::VerificationAlgorithm for EdDSAParameters {
|
||||
}
|
||||
}
|
||||
|
||||
impl private::Private for EdDSAParameters { }
|
||||
impl private::Private for EdDSAParameters {}
|
||||
|
||||
|
||||
extern {
|
||||
@ -203,8 +200,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_ed25519_from_bytes_misuse() {
|
||||
let rng = rand::SystemRandom::new();
|
||||
let (_, bytes) =
|
||||
Ed25519KeyPair::generate_serializable(&rng).unwrap();
|
||||
let (_, bytes) = Ed25519KeyPair::generate_serializable(&rng).unwrap();
|
||||
|
||||
assert!(Ed25519KeyPair::from_bytes(&bytes.private_key,
|
||||
&bytes.public_key).is_ok());
|
||||
|
@ -100,8 +100,8 @@ fn ecdh(private_key_ops: &PrivateKeyOps, public_key_ops: &PublicKeyOps,
|
||||
// `parse_uncompressed_point` verifies that the point is not at infinity
|
||||
// and that it is on the curve, using the Partial Public-Key Validation
|
||||
// Routine.
|
||||
let peer_public_key =
|
||||
try!(parse_uncompressed_point(public_key_ops, peer_public_key));
|
||||
let peer_public_key = try!(parse_uncompressed_point(public_key_ops,
|
||||
peer_public_key));
|
||||
|
||||
// NIST SP 800-56Ar2 Step 1.
|
||||
// NSA Guide Step 3 (except point at infinity check).
|
||||
|
@ -54,8 +54,7 @@ impl signature::VerificationAlgorithm for ECDSAParameters {
|
||||
// NSA Guide Step 1: "If r and s are not both integers in the interval
|
||||
// [1, n − 1], output INVALID."
|
||||
let (r, s) = try!(signature.read_all(error::Unspecified, |input| {
|
||||
der::nested(input, der::Tag::Sequence, error::Unspecified,
|
||||
|input| {
|
||||
der::nested(input, der::Tag::Sequence, error::Unspecified, |input| {
|
||||
let r = try!(self.ops.scalar_parse(input));
|
||||
let s = try!(self.ops.scalar_parse(input));
|
||||
Ok((r, s))
|
||||
@ -80,8 +79,8 @@ impl signature::VerificationAlgorithm for ECDSAParameters {
|
||||
// NSA Guide Step 6: "Compute the elliptic curve point
|
||||
// R = (xR, yR) = u1*G + u2*Q, using EC scalar multiplication and EC
|
||||
// addition. If R is equal to the point at infinity, output INVALID."
|
||||
let product = twin_mul(self.ops.private_key_ops, &u1, &u2,
|
||||
&peer_pub_key);
|
||||
let product =
|
||||
twin_mul(self.ops.private_key_ops, &u1, &u2, &peer_pub_key);
|
||||
|
||||
// Verify that the point we computed is on the curve; see
|
||||
// `verify_affine_point_is_on_the_curve_scaled` for details on why. It
|
||||
@ -124,7 +123,7 @@ impl signature::VerificationAlgorithm for ECDSAParameters {
|
||||
}
|
||||
}
|
||||
|
||||
impl private::Private for ECDSAParameters { }
|
||||
impl private::Private for ECDSAParameters {}
|
||||
|
||||
|
||||
/// Calculate the digest of `msg` using the digest algorithm `digest_alg`. Then
|
||||
@ -178,10 +177,9 @@ fn digest_scalar_(ops: &PublicScalarOps, digest: &[u8]) -> Scalar {
|
||||
if !limbs_less_than_limbs(&limbs[..num_limbs], n) {
|
||||
let mut carried_bit = 0;
|
||||
for i in 0..num_limbs {
|
||||
let next_carried_bit =
|
||||
limbs[num_limbs - i - 1] << (LIMB_BITS - 1);
|
||||
limbs[num_limbs - i - 1] =
|
||||
(limbs[num_limbs - i - 1] >> 1) | carried_bit;
|
||||
let next_carried_bit = limbs[num_limbs - i - 1] << (LIMB_BITS - 1);
|
||||
limbs[num_limbs - i - 1] = (limbs[num_limbs - i - 1] >> 1) |
|
||||
carried_bit;
|
||||
carried_bit = next_carried_bit;
|
||||
}
|
||||
debug_assert!(limbs_less_than_limbs(&limbs[..num_limbs], &n));
|
||||
@ -261,7 +259,7 @@ mod tests {
|
||||
#[test]
|
||||
fn signature_ecdsa_verify_test() {
|
||||
test::from_file("src/ec/suite_b/ecdsa_verify_tests.txt",
|
||||
|section, test_case| {
|
||||
|section, test_case| {
|
||||
assert_eq!(section, "");
|
||||
|
||||
let curve_name = test_case.consume_string("Curve");
|
||||
@ -278,8 +276,8 @@ mod tests {
|
||||
|
||||
let expected_result = test_case.consume_string("Result");
|
||||
|
||||
let (alg, _, _) =
|
||||
alg_from_curve_and_digest(&curve_name, &digest_name);
|
||||
let (alg, _, _) = alg_from_curve_and_digest(&curve_name,
|
||||
&digest_name);
|
||||
|
||||
let actual_result = signature::verify(alg, public_key, msg, sig);
|
||||
assert_eq!(actual_result.is_ok(), expected_result == "P (0 )");
|
||||
@ -291,7 +289,7 @@ mod tests {
|
||||
#[test]
|
||||
fn ecdsa_digest_scalar_test() {
|
||||
test::from_file("src/ec/suite_b/ecdsa_digest_scalar_tests.txt",
|
||||
|section, test_case| {
|
||||
|section, test_case| {
|
||||
assert_eq!(section, "");
|
||||
|
||||
let curve_name = test_case.consume_string("Curve");
|
||||
@ -301,8 +299,8 @@ mod tests {
|
||||
|
||||
let output = test_case.consume_bytes("Output");
|
||||
|
||||
let (_, ops, digest_alg) =
|
||||
alg_from_curve_and_digest(&curve_name, &digest_name);
|
||||
let (_, ops, digest_alg) = alg_from_curve_and_digest(&curve_name,
|
||||
&digest_name);
|
||||
|
||||
let num_limbs = ops.public_key_ops.common.num_limbs;
|
||||
assert_eq!(input.len(), digest_alg.output_len);
|
||||
|
@ -40,15 +40,11 @@ pub struct ElemUnreduced {
|
||||
}
|
||||
|
||||
impl ElemUnreduced {
|
||||
fn zero() -> ElemUnreduced {
|
||||
ElemUnreduced { limbs: [0; MAX_LIMBS] }
|
||||
}
|
||||
fn zero() -> ElemUnreduced { ElemUnreduced { limbs: [0; MAX_LIMBS] } }
|
||||
}
|
||||
|
||||
impl <'a> From<&'a Elem> for ElemUnreduced {
|
||||
fn from(a: &Elem) -> ElemUnreduced {
|
||||
ElemUnreduced { limbs: a.limbs }
|
||||
}
|
||||
impl<'a> From<&'a Elem> for ElemUnreduced {
|
||||
fn from(a: &Elem) -> ElemUnreduced { ElemUnreduced { limbs: a.limbs } }
|
||||
}
|
||||
|
||||
|
||||
@ -84,21 +80,16 @@ pub struct Point {
|
||||
}
|
||||
|
||||
impl Point {
|
||||
pub fn new_at_infinity() -> Point {
|
||||
Point { xyz: [0; 3 * MAX_LIMBS] }
|
||||
}
|
||||
pub fn new_at_infinity() -> Point { Point { xyz: [0; 3 * MAX_LIMBS] } }
|
||||
}
|
||||
|
||||
// Cannot be derived because `xyz` is too large on 32-bit platforms to have a
|
||||
// built-in implementation of `Clone`.
|
||||
impl Clone for Point {
|
||||
fn clone(&self) -> Self {
|
||||
Point { xyz: self.xyz }
|
||||
}
|
||||
fn clone(&self) -> Self { Point { xyz: self.xyz } }
|
||||
}
|
||||
|
||||
impl Copy for Point {
|
||||
}
|
||||
impl Copy for Point {}
|
||||
|
||||
#[cfg(all(target_pointer_width = "32", target_endian = "little"))]
|
||||
macro_rules! limbs {
|
||||
@ -127,9 +118,8 @@ macro_rules! limbs {
|
||||
|
||||
pub const MAX_LIMBS: usize = (384 + (LIMB_BITS - 1)) / LIMB_BITS;
|
||||
|
||||
static ONE: ElemDecoded = ElemDecoded {
|
||||
limbs: limbs![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
|
||||
};
|
||||
static ONE: ElemDecoded =
|
||||
ElemDecoded { limbs: limbs![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] };
|
||||
|
||||
|
||||
/// Operations and values needed by all curve operations.
|
||||
@ -182,7 +172,7 @@ impl CommonOps {
|
||||
|
||||
#[inline]
|
||||
pub fn elem_mul_mixed(&self, a: &ElemUnreduced, b: &ElemDecoded)
|
||||
-> ElemDecoded {
|
||||
-> ElemDecoded {
|
||||
let unreduced = rab(self.elem_mul_mont, &a.limbs, &b.limbs);
|
||||
ElemDecoded { limbs: self.reduced_limbs(&unreduced, &self.q.p) }
|
||||
}
|
||||
@ -404,7 +394,7 @@ impl PublicScalarOps {
|
||||
-> ElemDecoded {
|
||||
ElemDecoded {
|
||||
limbs: rab(self.public_key_ops.common.elem_add_impl, &a.limbs,
|
||||
&b.limbs)
|
||||
&b.limbs),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -445,8 +435,8 @@ fn elem_sqr_mul(ops: &CommonOps, a: &ElemUnreduced, squarings: usize,
|
||||
}
|
||||
|
||||
// Sets `acc` = (`acc` squared `squarings` times) * `b`.
|
||||
fn elem_sqr_mul_acc(ops: &CommonOps, acc: &mut ElemUnreduced, squarings: usize,
|
||||
b: &ElemUnreduced) {
|
||||
fn elem_sqr_mul_acc(ops: &CommonOps, acc: &mut ElemUnreduced,
|
||||
squarings: usize, b: &ElemUnreduced) {
|
||||
debug_assert!(squarings >= 1);
|
||||
for _ in 0..squarings {
|
||||
ops.elem_square(acc);
|
||||
@ -460,9 +450,7 @@ fn elem_sqr_mul_acc(ops: &CommonOps, acc: &mut ElemUnreduced, squarings: usize,
|
||||
fn rab(f: unsafe extern fn(r: *mut Limb, a: *const Limb, b: *const Limb),
|
||||
a: &[Limb; MAX_LIMBS], b: &[Limb; MAX_LIMBS]) -> [Limb; MAX_LIMBS] {
|
||||
let mut r = [0; MAX_LIMBS];
|
||||
unsafe {
|
||||
f(r.as_mut_ptr(), a.as_ptr(), b.as_ptr())
|
||||
}
|
||||
unsafe { f(r.as_mut_ptr(), a.as_ptr(), b.as_ptr()) }
|
||||
r
|
||||
}
|
||||
|
||||
@ -471,28 +459,22 @@ fn rab(f: unsafe extern fn(r: *mut Limb, a: *const Limb, b: *const Limb),
|
||||
#[inline]
|
||||
fn a_assign(f: unsafe extern fn(r: *mut Limb, a: *const Limb),
|
||||
a: &mut [Limb; MAX_LIMBS]) {
|
||||
unsafe {
|
||||
f(a.as_mut_ptr(), a.as_ptr())
|
||||
}
|
||||
unsafe { f(a.as_mut_ptr(), a.as_ptr()) }
|
||||
}
|
||||
|
||||
// a = f(a, b);
|
||||
#[inline]
|
||||
fn ab_assign(f: unsafe extern fn(r: *mut Limb, a: *const Limb, b: *const Limb),
|
||||
a: &mut [Limb; MAX_LIMBS], b: &[Limb; MAX_LIMBS]) {
|
||||
unsafe {
|
||||
f(a.as_mut_ptr(), a.as_ptr(), b.as_ptr())
|
||||
}
|
||||
unsafe { f(a.as_mut_ptr(), a.as_ptr(), b.as_ptr()) }
|
||||
}
|
||||
|
||||
// let r = f(a); return r;
|
||||
#[inline]
|
||||
fn ra(f: unsafe extern fn(r: *mut Limb, a: *const Limb),
|
||||
a: &[Limb; MAX_LIMBS]) -> [Limb; MAX_LIMBS] {
|
||||
fn ra(f: unsafe extern fn(r: *mut Limb, a: *const Limb), a: &[Limb; MAX_LIMBS])
|
||||
-> [Limb; MAX_LIMBS] {
|
||||
let mut r = [0; MAX_LIMBS];
|
||||
unsafe {
|
||||
f(r.as_mut_ptr(), a.as_ptr())
|
||||
}
|
||||
unsafe { f(r.as_mut_ptr(), a.as_ptr()) }
|
||||
r
|
||||
}
|
||||
|
||||
@ -546,8 +528,8 @@ pub fn limbs_less_than_limbs(a: &[Limb], b: &[Limb]) -> bool {
|
||||
core::cmp::Ordering::Less => {
|
||||
return true;
|
||||
},
|
||||
core::cmp::Ordering::Equal => { }, // keep going
|
||||
core::cmp::Ordering::Greater => { break; }
|
||||
core::cmp::Ordering::Equal => {}, // keep going
|
||||
core::cmp::Ordering::Greater => { break; },
|
||||
}
|
||||
}
|
||||
false
|
||||
@ -569,14 +551,10 @@ mod tests {
|
||||
use untrusted;
|
||||
|
||||
#[test]
|
||||
fn p256_elem_reduced_test() {
|
||||
test_elem_reduced(&p256::COMMON_OPS);
|
||||
}
|
||||
fn p256_elem_reduced_test() { test_elem_reduced(&p256::COMMON_OPS); }
|
||||
|
||||
#[test]
|
||||
fn p384_elem_reduced_test() {
|
||||
test_elem_reduced(&p384::COMMON_OPS);
|
||||
}
|
||||
fn p384_elem_reduced_test() { test_elem_reduced(&p384::COMMON_OPS); }
|
||||
|
||||
fn test_elem_reduced(ops: &CommonOps) {
|
||||
let zero = ElemUnreduced::zero();
|
||||
@ -640,13 +618,11 @@ mod tests {
|
||||
|
||||
let mut actual_sum = a.clone();
|
||||
ops.public_key_ops.common.elem_add(&mut actual_sum, &b);
|
||||
assert_limbs_are_equal(cops, &actual_sum.limbs,
|
||||
&expected_sum.limbs);
|
||||
assert_limbs_are_equal(cops, &actual_sum.limbs, &expected_sum.limbs);
|
||||
|
||||
let mut actual_sum = b.clone();
|
||||
ops.public_key_ops.common.elem_add(&mut actual_sum, &a);
|
||||
assert_limbs_are_equal(cops, &actual_sum.limbs,
|
||||
&expected_sum.limbs);
|
||||
assert_limbs_are_equal(cops, &actual_sum.limbs, &expected_sum.limbs);
|
||||
|
||||
Ok(())
|
||||
})
|
||||
@ -798,30 +774,28 @@ mod tests {
|
||||
let inp = [0xbe, 0xef, 0xf0, 0x0d];
|
||||
let inp = untrusted::Input::from(&inp);
|
||||
assert_eq!(parse_big_endian_value(inp, MAX_LIMBS),
|
||||
Ok(limbs![0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0xbeeff00d]));
|
||||
Ok(limbs![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xbeeff00d]));
|
||||
|
||||
// A whole number of limbs (2 for 32-bit, 1 for 64-bit).
|
||||
let inp = [0xfe, 0xed, 0xde, 0xad, 0xbe, 0xef, 0xf0, 0x0d];
|
||||
let inp = untrusted::Input::from(&inp);
|
||||
assert_eq!(parse_big_endian_value(inp, MAX_LIMBS),
|
||||
Ok(limbs![0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0xfeeddead, 0xbeeff00d]));
|
||||
Ok(limbs![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xfeeddead,
|
||||
0xbeeff00d]));
|
||||
|
||||
// One limb - 1 for 32-bit.
|
||||
let inp = [0xef, 0xf0, 0x0d];
|
||||
let inp = untrusted::Input::from(&inp);
|
||||
assert_eq!(parse_big_endian_value(inp, MAX_LIMBS),
|
||||
Ok(limbs![0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0xeff00d]));
|
||||
Ok(limbs![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xeff00d]));
|
||||
|
||||
// Two limbs - 1 for 64-bit, four limbs - 1 for 32-bit.
|
||||
let inp = [ 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8,
|
||||
0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0];
|
||||
let inp = untrusted::Input::from(&inp);
|
||||
assert_eq!(parse_big_endian_value(inp, MAX_LIMBS),
|
||||
Ok(limbs![0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0x000e0d0c, 0x0b0a0908, 0x07060504, 0x03020100]));
|
||||
Ok(limbs![0, 0, 0, 0, 0, 0, 0, 0, 0x000e0d0c, 0x0b0a0908,
|
||||
0x07060504, 0x03020100]));
|
||||
|
||||
// One limb + 1 for for 32-bit, half a limb + 1 for 64-bit.
|
||||
let inp = [0x4, 0x3, 0x2, 0x1, 0x0];
|
||||
@ -832,16 +806,16 @@ mod tests {
|
||||
// A whole number of limbs + 1.
|
||||
let inp = [0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00];
|
||||
let inp = untrusted::Input::from(&inp);
|
||||
let out = limbs![0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0x88, 0x77665544, 0x33221100];
|
||||
let out = limbs![0, 0, 0, 0, 0, 0, 0, 0, 0, 0x88, 0x77665544,
|
||||
0x33221100];
|
||||
assert_eq!(parse_big_endian_value(inp, 3), Ok(out));
|
||||
|
||||
// The input is longer than will fit in the given number of limbs.
|
||||
assert_eq!(parse_big_endian_value(inp, 2),
|
||||
if cfg!(target_pointer_width = "64") {
|
||||
Ok(out)
|
||||
Ok(out)
|
||||
} else {
|
||||
Err(error::Unspecified)
|
||||
Err(error::Unspecified)
|
||||
});
|
||||
assert_eq!(parse_big_endian_value(inp, 1), Err(error::Unspecified));
|
||||
}
|
||||
@ -859,7 +833,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn point_sum_test(ops: &PrivateKeyOps, file_path: &str) {
|
||||
test::from_file(file_path, |section, test_case| {
|
||||
test::from_file(file_path, |section, test_case| {
|
||||
assert_eq!(section, "");
|
||||
|
||||
let a = consume_jacobian_point(ops, test_case, "a");
|
||||
@ -893,7 +867,7 @@ mod tests {
|
||||
TestPoint::Infinity => {
|
||||
panic!("can't be inf.");
|
||||
},
|
||||
TestPoint::Affine(x, y) => (x, y)
|
||||
TestPoint::Affine(x, y) => (x, y),
|
||||
};
|
||||
let expected_result = consume_point(ops, test_case, "r");
|
||||
let actual_result = ops.point_mul(&p_scalar, &(x, y));
|
||||
@ -905,16 +879,14 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn p256_point_mul_base_test() {
|
||||
point_mul_base_tests(
|
||||
&p256::PRIVATE_KEY_OPS,
|
||||
"src/ec/suite_b/ops/p256_point_mul_base_tests.txt");
|
||||
point_mul_base_tests(&p256::PRIVATE_KEY_OPS,
|
||||
"src/ec/suite_b/ops/p256_point_mul_base_tests.txt");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn p384_point_mul_base_test() {
|
||||
point_mul_base_tests(
|
||||
&p384::PRIVATE_KEY_OPS,
|
||||
"src/ec/suite_b/ops/p384_point_mul_base_tests.txt");
|
||||
point_mul_base_tests(&p384::PRIVATE_KEY_OPS,
|
||||
"src/ec/suite_b/ops/p384_point_mul_base_tests.txt");
|
||||
}
|
||||
|
||||
fn point_mul_base_tests(ops: &PrivateKeyOps, file_path: &str) {
|
||||
@ -956,7 +928,7 @@ mod tests {
|
||||
cops.elem_reduced(&cops.elem_product(&actual_y, &zzz_inv));
|
||||
assert!(cops.elems_are_equal(&x_aff, &expected_x));
|
||||
assert!(cops.elems_are_equal(&y_aff, &expected_y));
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -1019,9 +991,8 @@ mod tests {
|
||||
if actual[i] != expected[i] {
|
||||
let mut s = std::string::String::new();
|
||||
for j in 0..ops.num_limbs {
|
||||
let formatted =
|
||||
format!("{:016x}",
|
||||
actual[ops.num_limbs - j - 1]);
|
||||
let formatted = format!("{:016x}",
|
||||
actual[ops.num_limbs - j - 1]);
|
||||
s.push_str(&formatted);
|
||||
}
|
||||
print!("\n");
|
||||
@ -1035,7 +1006,7 @@ mod tests {
|
||||
let bytes = test_case.consume_bytes(name);
|
||||
let bytes = untrusted::Input::from(&bytes);
|
||||
ElemUnreduced {
|
||||
limbs: parse_big_endian_value(bytes, ops.num_limbs).unwrap()
|
||||
limbs: parse_big_endian_value(bytes, ops.num_limbs).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,8 +14,7 @@
|
||||
|
||||
use c;
|
||||
use super::*;
|
||||
use super::{Mont, elem_sqr_mul, elem_sqr_mul_acc, ab_assign, ra,
|
||||
rab};
|
||||
use super::{Mont, elem_sqr_mul, elem_sqr_mul_acc, ab_assign, ra, rab};
|
||||
|
||||
macro_rules! p256_limbs {
|
||||
[$limb_7:expr, $limb_6:expr, $limb_5:expr, $limb_4:expr,
|
||||
@ -127,9 +126,7 @@ fn p256_point_mul_base_impl(g_scalar: &Scalar) -> Point {
|
||||
}
|
||||
|
||||
|
||||
pub static PUBLIC_KEY_OPS: PublicKeyOps = PublicKeyOps {
|
||||
common: &COMMON_OPS,
|
||||
};
|
||||
pub static PUBLIC_KEY_OPS: PublicKeyOps = PublicKeyOps { common: &COMMON_OPS };
|
||||
|
||||
|
||||
pub static PUBLIC_SCALAR_OPS: PublicScalarOps = PublicScalarOps {
|
||||
@ -137,8 +134,8 @@ pub static PUBLIC_SCALAR_OPS: PublicScalarOps = PublicScalarOps {
|
||||
private_key_ops: &PRIVATE_KEY_OPS,
|
||||
|
||||
q_minus_n: ElemDecoded {
|
||||
limbs: p256_limbs![0, 0, 0, 0,
|
||||
0x43190553, 0x58e8617b, 0x0c46353d, 0x039cdaae],
|
||||
limbs: p256_limbs![0, 0, 0, 0, 0x43190553, 0x58e8617b, 0x0c46353d,
|
||||
0x039cdaae],
|
||||
},
|
||||
|
||||
scalar_inv_to_mont_impl: p256_scalar_inv_to_mont,
|
||||
|
@ -34,7 +34,7 @@ pub static COMMON_OPS: CommonOps = CommonOps {
|
||||
p: p384_limbs![0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe,
|
||||
0xffffffff, 0x00000000, 0x00000000, 0xffffffff],
|
||||
rr: limbs![0, 0, 0, 1, 2, 0, 0xfffffffe, 0, 2, 0, 0xfffffffe, 1 ],
|
||||
rr: limbs![0, 0, 0, 1, 2, 0, 0xfffffffe, 0, 2, 0, 0xfffffffe, 1],
|
||||
},
|
||||
|
||||
n: ElemDecoded {
|
||||
@ -87,8 +87,7 @@ fn p384_elem_inv(a: &ElemUnreduced) -> ElemUnreduced {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn sqr_mul_acc(a: &mut ElemUnreduced, squarings: usize,
|
||||
b: &ElemUnreduced) {
|
||||
fn sqr_mul_acc(a: &mut ElemUnreduced, squarings: usize, b: &ElemUnreduced) {
|
||||
elem_sqr_mul_acc(&COMMON_OPS, a, squarings, b)
|
||||
}
|
||||
|
||||
@ -156,9 +155,7 @@ fn p384_point_mul_base_impl(a: &Scalar) -> Point {
|
||||
}
|
||||
|
||||
|
||||
pub static PUBLIC_KEY_OPS: PublicKeyOps = PublicKeyOps {
|
||||
common: &COMMON_OPS,
|
||||
};
|
||||
pub static PUBLIC_KEY_OPS: PublicKeyOps = PublicKeyOps { common: &COMMON_OPS };
|
||||
|
||||
|
||||
pub static PUBLIC_SCALAR_OPS: PublicScalarOps = PublicScalarOps {
|
||||
@ -166,8 +163,7 @@ pub static PUBLIC_SCALAR_OPS: PublicScalarOps = PublicScalarOps {
|
||||
private_key_ops: &PRIVATE_KEY_OPS,
|
||||
|
||||
q_minus_n: ElemDecoded {
|
||||
limbs: p384_limbs![0, 0, 0, 0,
|
||||
0, 0, 0x389cb27e, 0x0bc8d21f,
|
||||
limbs: p384_limbs![0, 0, 0, 0, 0, 0, 0x389cb27e, 0x0bc8d21f,
|
||||
0x1313e696, 0x333ad68c, 0xa7e5f24c, 0xb74f5885],
|
||||
},
|
||||
|
||||
@ -204,8 +200,7 @@ fn p384_scalar_inv_to_mont(a: &Scalar) -> ScalarMont {
|
||||
}
|
||||
|
||||
// Returns (`a` squared `squarings` times) * `b`.
|
||||
fn sqr_mul(a: &ScalarMont, squarings: usize, b: &ScalarMont)
|
||||
-> ScalarMont {
|
||||
fn sqr_mul(a: &ScalarMont, squarings: usize, b: &ScalarMont) -> ScalarMont {
|
||||
debug_assert!(squarings >= 1);
|
||||
let mut tmp = sqr(a);
|
||||
for _ in 1..squarings {
|
||||
@ -331,8 +326,8 @@ fn p384_scalar_inv_to_mont(a: &Scalar) -> ScalarMont {
|
||||
unsafe extern fn GFp_p384_elem_sqr_mont(
|
||||
r: *mut Limb/*[COMMON_OPS.num_limbs]*/,
|
||||
a: *const Limb/*[COMMON_OPS.num_limbs]*/) {
|
||||
// XXX: Inefficient. TODO: Make a dedicated squaring routine.
|
||||
GFp_p384_elem_mul_mont(r, a, a);
|
||||
// XXX: Inefficient. TODO: Make a dedicated squaring routine.
|
||||
GFp_p384_elem_mul_mont(r, a, a);
|
||||
}
|
||||
|
||||
|
||||
|
@ -43,9 +43,8 @@ pub fn generate_private_key(ops: &PrivateKeyOps, rng: &rand::SecureRandom)
|
||||
// XXX: The value 100 was chosen to match OpenSSL due to uncertainty of
|
||||
// what specific value would be better, but it seems bad to try 100 times.
|
||||
for _ in 0..100 {
|
||||
let mut candidate_private_key = ec::PrivateKey {
|
||||
bytes: [0; ec::SCALAR_MAX_BYTES],
|
||||
};
|
||||
let mut candidate_private_key =
|
||||
ec::PrivateKey { bytes: [0; ec::SCALAR_MAX_BYTES] };
|
||||
|
||||
// NSA Guide Steps 1, 2, and 3.
|
||||
//
|
||||
@ -91,8 +90,8 @@ pub fn generate_private_key(ops: &PrivateKeyOps, rng: &rand::SecureRandom)
|
||||
// private key that way, which means we have to convert it to a Scalar whenever
|
||||
// we need to use it.
|
||||
#[inline]
|
||||
pub fn private_key_as_scalar(ops: &PrivateKeyOps, private_key: &ec::PrivateKey)
|
||||
-> Scalar {
|
||||
pub fn private_key_as_scalar(ops: &PrivateKeyOps,
|
||||
private_key: &ec::PrivateKey) -> Scalar {
|
||||
let num_limbs = ops.common.num_limbs;
|
||||
let range = Range::from_max_exclusive(&ops.common.n.limbs[..num_limbs]);
|
||||
|
||||
@ -112,7 +111,7 @@ fn private_key_as_scalar_(ops: &PrivateKeyOps, private_key: &ec::PrivateKey)
|
||||
let mut limb = 0;
|
||||
for j in 0..LIMB_BYTES {
|
||||
limb = (limb << 8) |
|
||||
(bytes[((num_limbs - i - 1) * LIMB_BYTES) + j] as Limb);
|
||||
(bytes[((num_limbs - i - 1) * LIMB_BYTES) + j] as Limb);
|
||||
}
|
||||
limbs[i] = limb;
|
||||
}
|
||||
@ -120,8 +119,8 @@ fn private_key_as_scalar_(ops: &PrivateKeyOps, private_key: &ec::PrivateKey)
|
||||
}
|
||||
|
||||
pub fn public_from_private(ops: &PrivateKeyOps, public_out: &mut [u8],
|
||||
my_private_key: &ec::PrivateKey)
|
||||
-> Result<(), error::Unspecified> {
|
||||
my_private_key: &ec::PrivateKey)
|
||||
-> Result<(), error::Unspecified> {
|
||||
let elem_and_scalar_bytes = ops.common.num_limbs * LIMB_BYTES;
|
||||
debug_assert_eq!(public_out.len(), 1 + (2 * elem_and_scalar_bytes));
|
||||
let my_private_key = private_key_as_scalar(ops, my_private_key);
|
||||
@ -182,8 +181,8 @@ fn big_endian_from_limbs(out: &mut [u8], limbs: &[Limb]) {
|
||||
for i in 0..num_limbs {
|
||||
let mut limb = limbs[i];
|
||||
for j in 0..LIMB_BYTES {
|
||||
out[((num_limbs - i - 1) * LIMB_BYTES) + (LIMB_BYTES - j - 1)]
|
||||
= (limb & 0xff) as u8;
|
||||
out[((num_limbs - i - 1) * LIMB_BYTES) + (LIMB_BYTES - j - 1)] =
|
||||
(limb & 0xff) as u8;
|
||||
limb >>= 8;
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn parse_uncompressed_point_test() {
|
||||
test::from_file("src/ec/suite_b/suite_b_public_key_tests.txt",
|
||||
test::from_file("src/ec/suite_b/suite_b_public_key_tests.txt",
|
||||
|section, test_case| {
|
||||
assert_eq!(section, "");
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2016 Brian Smith.
|
||||
// Copyright 2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -95,8 +95,8 @@ mod tests {
|
||||
|
||||
fn expect_iterated_x25519(expected_result: &str,
|
||||
range: std::ops::Range<usize>,
|
||||
k: &mut std::vec::Vec<u8>, u:
|
||||
&mut std::vec::Vec<u8>) {
|
||||
k: &mut std::vec::Vec<u8>,
|
||||
u: &mut std::vec::Vec<u8>) {
|
||||
for _ in range {
|
||||
let new_k = x25519(k, u);
|
||||
*u = k.clone();
|
||||
@ -133,8 +133,8 @@ mod tests {
|
||||
fn x25519_(private_key: &[u8], public_key: &[u8])
|
||||
-> Result<std::vec::Vec<u8>, error::Unspecified> {
|
||||
let private_key =
|
||||
agreement::EphemeralPrivateKey::from_test_vector(
|
||||
&agreement::X25519, private_key);
|
||||
agreement::EphemeralPrivateKey::from_test_vector(&agreement::X25519,
|
||||
private_key);
|
||||
let public_key = untrusted::Input::from(public_key);
|
||||
agreement::agree_ephemeral(private_key, &agreement::X25519, public_key,
|
||||
error::Unspecified, |agreed_value| {
|
||||
@ -147,7 +147,7 @@ mod tests {
|
||||
Ok(v) => v,
|
||||
Err(msg) => {
|
||||
panic!("{} in {}", msg, s);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,8 +51,8 @@ use hmac;
|
||||
/// # Panics
|
||||
///
|
||||
/// `extract_and_expand` panics if `expand` panics.
|
||||
pub fn extract_and_expand(salt: &hmac::SigningKey, secret: &[u8], info: &[u8],
|
||||
out: &mut [u8]) {
|
||||
pub fn extract_and_expand(salt: &hmac::SigningKey, secret: &[u8],
|
||||
info: &[u8], out: &mut [u8]) {
|
||||
let prk = extract(salt, secret);
|
||||
expand(&prk, info, out)
|
||||
}
|
||||
@ -137,7 +137,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
pub fn hkdf_tests() {
|
||||
test::from_file("src/hkdf_tests.txt",|section, test_case| {
|
||||
test::from_file("src/hkdf_tests.txt", |section, test_case| {
|
||||
assert_eq!(section, "");
|
||||
let digest_alg =
|
||||
try!(test_case.consume_digest_alg("Hash")
|
||||
|
12
src/hmac.rs
12
src/hmac.rs
@ -201,7 +201,7 @@ impl SigningKey {
|
||||
let mut key = SigningKey {
|
||||
ctx_prototype: SigningContext {
|
||||
inner: digest::Context::new(digest_alg),
|
||||
outer: digest::Context::new(digest_alg)
|
||||
outer: digest::Context::new(digest_alg),
|
||||
},
|
||||
};
|
||||
|
||||
@ -263,9 +263,7 @@ impl SigningContext {
|
||||
/// zero or more times until `finish` is called.
|
||||
///
|
||||
/// C analog: `HMAC_Update`
|
||||
pub fn update(&mut self, data: &[u8]) {
|
||||
self.inner.update(data);
|
||||
}
|
||||
pub fn update(&mut self, data: &[u8]) { self.inner.update(data); }
|
||||
|
||||
/// Finalizes the HMAC calculation and returns the HMAC value. `sign`
|
||||
/// consumes the context so it cannot be (mis-)used after `sign` has been
|
||||
@ -300,7 +298,7 @@ pub fn sign(key: &SigningKey, data: &[u8]) -> digest::Digest {
|
||||
|
||||
/// A key to use for HMAC authentication.
|
||||
pub struct VerificationKey {
|
||||
wrapped: SigningKey
|
||||
wrapped: SigningKey,
|
||||
}
|
||||
|
||||
impl VerificationKey {
|
||||
@ -356,7 +354,7 @@ mod tests {
|
||||
let mut rng = rand::SystemRandom::new();
|
||||
|
||||
const HELLO_WORLD_GOOD: &'static [u8] = b"hello, world";
|
||||
const HELLO_WORLD_BAD: &'static [u8] = b"hello, worle";
|
||||
const HELLO_WORLD_BAD: &'static [u8] = b"hello, worle";
|
||||
|
||||
for d in &digest::test_util::ALL_ALGORITHMS {
|
||||
let key = hmac::SigningKey::generate(d, &mut rng).unwrap();
|
||||
@ -379,7 +377,7 @@ mod tests {
|
||||
|
||||
let digest_alg = match digest_alg {
|
||||
Some(digest_alg) => digest_alg,
|
||||
None => { return Ok(()); } // Unsupported digest algorithm
|
||||
None => { return Ok(()); }, // Unsupported digest algorithm
|
||||
};
|
||||
|
||||
try!(hmac_test_case_inner(digest_alg, &key_value[..], &input[..],
|
||||
|
@ -27,5 +27,4 @@ extern {
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "aarch64", target_os = "ios"))]
|
||||
pub fn init_once() {
|
||||
}
|
||||
pub fn init_once() {}
|
||||
|
21
src/lib.rs
21
src/lib.rs
@ -108,10 +108,15 @@ extern crate std;
|
||||
|
||||
extern crate untrusted;
|
||||
|
||||
#[macro_use] mod bssl;
|
||||
#[macro_use] mod polyfill;
|
||||
#[macro_use]
|
||||
mod bssl;
|
||||
|
||||
#[macro_use]
|
||||
mod polyfill;
|
||||
|
||||
#[path = "aead/aead.rs"]
|
||||
pub mod aead;
|
||||
|
||||
#[path = "aead/aead.rs"] pub mod aead;
|
||||
pub mod agreement;
|
||||
mod c;
|
||||
pub mod constant_time;
|
||||
@ -121,8 +126,12 @@ pub mod der;
|
||||
|
||||
pub mod error;
|
||||
|
||||
#[path = "digest/digest.rs"] pub mod digest;
|
||||
#[path = "ec/ec.rs"] mod ec;
|
||||
#[path = "digest/digest.rs"]
|
||||
pub mod digest;
|
||||
|
||||
#[path = "ec/ec.rs"]
|
||||
mod ec;
|
||||
|
||||
pub mod hkdf;
|
||||
pub mod hmac;
|
||||
mod init;
|
||||
@ -158,7 +167,7 @@ mod private {
|
||||
//
|
||||
// impl private::Private for MyType { }
|
||||
// ```
|
||||
pub trait Private { }
|
||||
pub trait Private {}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
38
src/limb.rs
38
src/limb.rs
@ -54,15 +54,13 @@ pub struct Range<'a> {
|
||||
pub max_exclusive: &'a [Limb],
|
||||
}
|
||||
|
||||
impl <'a> Range<'a> {
|
||||
impl<'a> Range<'a> {
|
||||
pub fn from_max_exclusive(max_exclusive: &[Limb]) -> Range {
|
||||
debug_assert_eq!(limbs_are_zero_constant_time(max_exclusive),
|
||||
LimbMask::False);
|
||||
debug_assert!(max_exclusive[max_exclusive.len() - 1] > 0);
|
||||
|
||||
Range {
|
||||
max_exclusive: max_exclusive
|
||||
}
|
||||
Range { max_exclusive: max_exclusive }
|
||||
}
|
||||
|
||||
/// Are these little-endian limbs within the range?
|
||||
@ -72,8 +70,8 @@ impl <'a> Range<'a> {
|
||||
assert_eq!(self.max_exclusive.len(), limbs.len());
|
||||
|
||||
let is_zero = limbs_are_zero_constant_time(limbs);
|
||||
let is_lt_max =
|
||||
limbs_less_than_limbs_constant_time(limbs, self.max_exclusive);
|
||||
let is_lt_max = limbs_less_than_limbs_constant_time(limbs,
|
||||
self.max_exclusive);
|
||||
|
||||
is_zero == LimbMask::False && is_lt_max == LimbMask::True
|
||||
}
|
||||
@ -145,8 +143,9 @@ pub unsafe extern fn GFp_rand_mod(dest: *mut Limb, max_exclusive: *const Limb,
|
||||
const ERR: c::int = 0;
|
||||
const SUCCESS: c::int = 1;
|
||||
|
||||
let range = Range::from_max_exclusive(
|
||||
core::slice::from_raw_parts(max_exclusive, num_limbs));
|
||||
let range =
|
||||
Range::from_max_exclusive(core::slice::from_raw_parts(max_exclusive,
|
||||
num_limbs));
|
||||
let mut dest = core::slice::from_raw_parts_mut(dest, num_limbs);
|
||||
|
||||
let result = range.sample_into_limbs(&mut dest, (*rng).rng);
|
||||
@ -180,20 +179,15 @@ fn limbs_as_bytes_mut<'a>(src: &'a mut [Limb]) -> &'a mut [u8] {
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
#[inline]
|
||||
pub fn limbs_less_than_limbs_constant_time(a: &[Limb], b: &[Limb])
|
||||
-> LimbMask {
|
||||
pub fn limbs_less_than_limbs_constant_time(a: &[Limb], b: &[Limb]) -> LimbMask {
|
||||
assert_eq!(a.len(), b.len());
|
||||
unsafe {
|
||||
GFp_constant_time_limbs_lt_limbs(a.as_ptr(), b.as_ptr(), b.len())
|
||||
}
|
||||
unsafe { GFp_constant_time_limbs_lt_limbs(a.as_ptr(), b.as_ptr(), b.len()) }
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
#[inline]
|
||||
pub fn limbs_are_zero_constant_time(limbs: &[Limb]) -> LimbMask {
|
||||
unsafe {
|
||||
GFp_constant_time_limbs_are_zero(limbs.as_ptr(), limbs.len())
|
||||
}
|
||||
unsafe { GFp_constant_time_limbs_are_zero(limbs.as_ptr(), limbs.len()) }
|
||||
}
|
||||
|
||||
extern {
|
||||
@ -216,7 +210,7 @@ mod tests {
|
||||
assert_eq!(0, most_significant_limb_mask_variable_time(0));
|
||||
|
||||
for i in 0..LIMB_BITS {
|
||||
let x = 1 << i;
|
||||
let x = 1 << i;
|
||||
let expected = if i == LIMB_BITS - 1 {
|
||||
Limb::max_value()
|
||||
} else {
|
||||
@ -280,13 +274,13 @@ mod tests {
|
||||
let limbs = &[Limb::max_value(), Limb::max_value()];
|
||||
let range = Range::from_max_exclusive(limbs);
|
||||
assert!(range.sample_into_limbs(&mut dest, &rng).is_ok());
|
||||
assert!(dest.iter().any( |b| *b > 0 ));
|
||||
assert!(dest.iter().any(|b| *b > 0));
|
||||
|
||||
let mut dest: [Limb; 2] = [0; 2];
|
||||
let limbs = &[0xdeadbeef, 0xdeadbeef];
|
||||
let range = Range::from_max_exclusive(limbs);
|
||||
assert!(range.sample_into_limbs(&mut dest, &rng).is_ok());
|
||||
assert!(dest.iter().any( |b| *b > 0 ));
|
||||
assert!(dest.iter().any(|b| *b > 0));
|
||||
|
||||
let mut dest: [Limb; 1] = [0; 1];
|
||||
let limbs = &[2];
|
||||
@ -298,7 +292,7 @@ mod tests {
|
||||
let limbs = &[1 << (LIMB_BITS - 1)];
|
||||
let range = Range::from_max_exclusive(limbs);
|
||||
assert!(range.sample_into_limbs(&mut dest, &rng).is_ok());
|
||||
assert!(dest.iter().any( |b| *b > 0 ));
|
||||
assert!(dest.iter().any(|b| *b > 0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -336,7 +330,7 @@ mod tests {
|
||||
let max_exclusive_bytes = limbs_as_bytes(&max_exclusive);
|
||||
{
|
||||
let rng = rand::test_util::FixedSliceRandom {
|
||||
bytes: &max_exclusive_bytes
|
||||
bytes: &max_exclusive_bytes,
|
||||
};
|
||||
let mut result = [0, 0];
|
||||
assert!(range.sample_into_limbs(&mut result, &rng).is_err());
|
||||
@ -350,7 +344,7 @@ mod tests {
|
||||
limbs_as_bytes(&max_exclusive_minus_1);
|
||||
{
|
||||
let rng = rand::test_util::FixedSliceRandom {
|
||||
bytes: max_exclusive_minus_1_bytes
|
||||
bytes: max_exclusive_minus_1_bytes,
|
||||
};
|
||||
let mut result = [0, 0];
|
||||
range.sample_into_limbs(&mut result, &rng).unwrap();
|
||||
|
@ -139,8 +139,8 @@ use {constant_time, digest, error, hmac, polyfill};
|
||||
///
|
||||
/// `derive` panics if `out.len()` is larger than (2**32 - 1) * the PRF digest
|
||||
/// length, per the PBKDF2 specification.
|
||||
pub fn derive(prf: &'static PRF, iterations: usize, salt: &[u8], secret: &[u8],
|
||||
out: &mut [u8]) {
|
||||
pub fn derive(prf: &'static PRF, iterations: usize, salt: &[u8],
|
||||
secret: &[u8], out: &mut [u8]) {
|
||||
assert!(iterations >= 1);
|
||||
|
||||
let output_len = prf.digest_alg.output_len;
|
||||
@ -163,12 +163,8 @@ pub fn derive(prf: &'static PRF, iterations: usize, salt: &[u8], secret: &[u8],
|
||||
}
|
||||
}
|
||||
|
||||
fn derive_block(
|
||||
secret: &hmac::SigningKey,
|
||||
iterations: usize,
|
||||
salt: &[u8],
|
||||
idx: u32,
|
||||
out: &mut [u8]) {
|
||||
fn derive_block(secret: &hmac::SigningKey, iterations: usize, salt: &[u8],
|
||||
idx: u32, out: &mut [u8]) {
|
||||
let mut ctx = hmac::SigningContext::with_key(secret);
|
||||
ctx.update(salt);
|
||||
ctx.update(&polyfill::slice::be_u8_from_u32(idx));
|
||||
@ -214,8 +210,9 @@ fn derive_block(
|
||||
///
|
||||
/// `derive` panics if `out.len()` is larger than (2**32 - 1) * the PRF digest
|
||||
/// length, per the PBKDF2 specification.
|
||||
pub fn verify(prf: &'static PRF, iterations: usize, salt: &[u8], secret: &[u8],
|
||||
previously_derived: &[u8]) -> Result<(), error::Unspecified> {
|
||||
pub fn verify(prf: &'static PRF, iterations: usize, salt: &[u8],
|
||||
secret: &[u8], previously_derived: &[u8])
|
||||
-> Result<(), error::Unspecified> {
|
||||
if previously_derived.len() == 0 {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
@ -261,14 +258,10 @@ pub struct PRF {
|
||||
}
|
||||
|
||||
/// HMAC-SHA256.
|
||||
pub static HMAC_SHA256: PRF = PRF {
|
||||
digest_alg: &digest::SHA256,
|
||||
};
|
||||
pub static HMAC_SHA256: PRF = PRF { digest_alg: &digest::SHA256 };
|
||||
|
||||
/// HMAC-SHA512.
|
||||
pub static HMAC_SHA512: PRF = PRF {
|
||||
digest_alg: &digest::SHA512,
|
||||
};
|
||||
pub static HMAC_SHA512: PRF = PRF { digest_alg: &digest::SHA512 };
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
@ -289,11 +282,12 @@ mod tests {
|
||||
let salt = test_case.consume_bytes("S");
|
||||
let dk = test_case.consume_bytes("DK");
|
||||
let verify_expected_result = test_case.consume_string("Verify");
|
||||
let verify_expected_result = match verify_expected_result.as_str() {
|
||||
"OK" => Ok(()),
|
||||
"Err" => Err(error::Unspecified),
|
||||
_ => panic!("Unsupported value of \"Verify\"")
|
||||
};
|
||||
let verify_expected_result =
|
||||
match verify_expected_result.as_str() {
|
||||
"OK" => Ok(()),
|
||||
"Err" => Err(error::Unspecified),
|
||||
_ => panic!("Unsupported value of \"Verify\""),
|
||||
};
|
||||
|
||||
{
|
||||
let mut out = vec![0u8; dk.len()];
|
||||
|
@ -20,16 +20,14 @@
|
||||
use core;
|
||||
|
||||
#[inline(always)]
|
||||
pub fn u64_from_usize(x: usize) -> u64 {
|
||||
x as u64
|
||||
}
|
||||
pub fn u64_from_usize(x: usize) -> u64 { x as u64 }
|
||||
|
||||
/// `core::num::Wrapping` doesn't support `rotate_left`.
|
||||
/// There is no usable trait for `rotate_left`, so this polyfill just hard-codes u32.
|
||||
/// https://github.com/rust-lang/rust/issues/32463
|
||||
/// There is no usable trait for `rotate_left`, so this polyfill just
|
||||
/// hard-codes u32. https://github.com/rust-lang/rust/issues/32463
|
||||
#[inline(always)]
|
||||
pub fn wrapping_rotate_left_u32(x: core::num::Wrapping<u32>, n: u32)
|
||||
-> core::num::Wrapping<u32> {
|
||||
-> core::num::Wrapping<u32> {
|
||||
core::num::Wrapping(x.0.rotate_left(n))
|
||||
}
|
||||
|
||||
@ -85,7 +83,8 @@ pub mod slice {
|
||||
#[inline(always)]
|
||||
pub fn u64_as_u8(src: &[u64]) -> &[u8] {
|
||||
unsafe {
|
||||
core::slice::from_raw_parts(src.as_ptr() as *const u8, src.len() * 8)
|
||||
core::slice::from_raw_parts(src.as_ptr() as *const u8,
|
||||
src.len() * 8)
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,7 +92,8 @@ pub mod slice {
|
||||
#[inline(always)]
|
||||
pub fn u64_as_u8_mut(src: &mut [u64]) -> &mut [u8] {
|
||||
unsafe {
|
||||
core::slice::from_raw_parts_mut(src.as_mut_ptr() as *mut u8, src.len() * 8)
|
||||
core::slice::from_raw_parts_mut(src.as_mut_ptr() as *mut u8,
|
||||
src.len() * 8)
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,7 +111,8 @@ pub mod slice {
|
||||
#[allow(dead_code)] // Only used on 32-bit builds currently
|
||||
pub fn u32_as_u8_mut<'a>(src: &'a mut [u32]) -> &'a mut [u8] {
|
||||
unsafe {
|
||||
core::slice::from_raw_parts_mut(src.as_mut_ptr() as *mut u8, src.len() * 4)
|
||||
core::slice::from_raw_parts_mut(src.as_mut_ptr() as *mut u8,
|
||||
src.len() * 4)
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,7 +120,8 @@ pub mod slice {
|
||||
#[inline(always)]
|
||||
pub fn u64_as_u32(src: &[u64]) -> &[u32] {
|
||||
unsafe {
|
||||
core::slice::from_raw_parts(src.as_ptr() as *const u32, src.len() * 2)
|
||||
core::slice::from_raw_parts(src.as_ptr() as *const u32,
|
||||
src.len() * 2)
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,7 +129,8 @@ pub mod slice {
|
||||
#[inline(always)]
|
||||
pub fn u64_as_u32_mut(src: &mut [u64]) -> &mut [u32] {
|
||||
unsafe {
|
||||
core::slice::from_raw_parts_mut(src.as_mut_ptr() as *mut u32, src.len() * 2)
|
||||
core::slice::from_raw_parts_mut(src.as_mut_ptr() as *mut u32,
|
||||
src.len() * 2)
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,8 +138,7 @@ pub mod slice {
|
||||
pub fn as_wrapping_mut<T>(src: &mut [T]) -> &mut [core::num::Wrapping<T>] {
|
||||
unsafe {
|
||||
core::slice::from_raw_parts_mut(
|
||||
src.as_mut_ptr() as *mut core::num::Wrapping<T>,
|
||||
src.len())
|
||||
src.as_mut_ptr() as *mut core::num::Wrapping<T>, src.len())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
19
src/rand.rs
19
src/rand.rs
@ -124,8 +124,7 @@ mod sysrand {
|
||||
use {bssl, error};
|
||||
|
||||
pub fn fill(dest: &mut [u8]) -> Result<(), error::Unspecified> {
|
||||
for mut chunk in
|
||||
dest.chunks_mut(super::CRYPTO_sysrand_chunk_max_len) {
|
||||
for mut chunk in dest.chunks_mut(super::CRYPTO_sysrand_chunk_max_len) {
|
||||
try!(bssl::map_result(unsafe {
|
||||
super::CRYPTO_sysrand_chunk(chunk.as_mut_ptr(), chunk.len())
|
||||
}));
|
||||
@ -197,11 +196,9 @@ pub struct RAND<'a> {
|
||||
pub rng: &'a SecureRandom,
|
||||
}
|
||||
|
||||
impl <'a> RAND<'a> {
|
||||
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 }
|
||||
}
|
||||
pub fn new(rng: &'a SecureRandom) -> RAND<'a> { RAND { rng: rng } }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -214,7 +211,7 @@ pub unsafe extern fn RAND_bytes(rng: *mut RAND, dest: *mut u8,
|
||||
|
||||
match (*(*rng).rng).fill(dest) {
|
||||
Ok(()) => 1,
|
||||
_ => 0
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,7 +232,7 @@ pub mod test_util {
|
||||
/// An implementation of `SecureRandom` that always fills the output slice
|
||||
/// with the given byte.
|
||||
pub struct FixedByteRandom {
|
||||
pub byte: u8
|
||||
pub byte: u8,
|
||||
}
|
||||
|
||||
impl SecureRandom for FixedByteRandom {
|
||||
@ -254,7 +251,7 @@ pub mod test_util {
|
||||
pub bytes: &'a [u8],
|
||||
}
|
||||
|
||||
impl <'a> SecureRandom for FixedSliceRandom<'a> {
|
||||
impl<'a> SecureRandom for FixedSliceRandom<'a> {
|
||||
fn fill(&self, dest: &mut [u8]) -> Result<(), error::Unspecified> {
|
||||
assert_eq!(dest.len(), self.bytes.len());
|
||||
for i in 0..self.bytes.len() {
|
||||
@ -276,7 +273,7 @@ pub mod test_util {
|
||||
pub current: core::cell::UnsafeCell<usize>,
|
||||
}
|
||||
|
||||
impl <'a> SecureRandom for FixedSliceSequenceRandom<'a> {
|
||||
impl<'a> SecureRandom for FixedSliceSequenceRandom<'a> {
|
||||
fn fill(&self, dest: &mut [u8]) -> Result<(), error::Unspecified> {
|
||||
let current = unsafe { *self.current.get() };
|
||||
let bytes = self.bytes[current];
|
||||
@ -291,7 +288,7 @@ pub mod test_util {
|
||||
}
|
||||
}
|
||||
|
||||
impl <'a> Drop for FixedSliceSequenceRandom<'a> {
|
||||
impl<'a> Drop for FixedSliceSequenceRandom<'a> {
|
||||
fn drop(&mut self) {
|
||||
// Ensure that `fill()` was called exactly the right number of
|
||||
// times.
|
||||
|
@ -101,8 +101,8 @@ pub struct RSAParameters {
|
||||
min_bits: usize,
|
||||
}
|
||||
|
||||
fn parse_public_key(input: untrusted::Input) ->
|
||||
Result<(&[u8], &[u8]), error::Unspecified> {
|
||||
fn parse_public_key(input: untrusted::Input)
|
||||
-> Result<(&[u8], &[u8]), error::Unspecified> {
|
||||
input.read_all(error::Unspecified, |input| {
|
||||
der::nested(input, der::Tag::Sequence, error::Unspecified, |input| {
|
||||
let n = try!(der::positive_integer(input));
|
||||
@ -133,9 +133,7 @@ impl PositiveInteger {
|
||||
Ok(PositiveInteger { value: Some(res) })
|
||||
}
|
||||
|
||||
unsafe fn as_ref<'a>(&'a self) -> &'a BIGNUM {
|
||||
&*self.value.unwrap()
|
||||
}
|
||||
unsafe fn as_ref<'a>(&'a self) -> &'a BIGNUM { &*self.value.unwrap() }
|
||||
|
||||
fn into_raw(&mut self) -> *mut BIGNUM {
|
||||
let res = self.value.unwrap();
|
||||
@ -149,8 +147,10 @@ impl PositiveInteger {
|
||||
impl Drop for PositiveInteger {
|
||||
fn drop(&mut self) {
|
||||
match self.value {
|
||||
Some(val) => unsafe { BN_free(val); },
|
||||
None => { },
|
||||
Some(val) => unsafe {
|
||||
BN_free(val);
|
||||
},
|
||||
None => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,8 +35,8 @@ impl RSAPadding {
|
||||
// https://tools.ietf.org/html/rfc3447#section-9.2.
|
||||
fn pad(&self, msg: &[u8], out: &mut [u8])
|
||||
-> Result<(), error::Unspecified> {
|
||||
let digest_len =
|
||||
self.digestinfo_prefix.len() + self.digest_alg.output_len;
|
||||
let digest_len = self.digestinfo_prefix.len() +
|
||||
self.digest_alg.output_len;
|
||||
|
||||
// Require at least 8 bytes of padding. Since we disallow keys smaller
|
||||
// than 2048 bits, this should never happen anyway.
|
||||
@ -104,8 +104,7 @@ impl RSAKeyPair {
|
||||
pub fn from_der(input: untrusted::Input)
|
||||
-> Result<RSAKeyPair, error::Unspecified> {
|
||||
input.read_all(error::Unspecified, |input| {
|
||||
der::nested(input, der::Tag::Sequence, error::Unspecified,
|
||||
|input| {
|
||||
der::nested(input, der::Tag::Sequence, error::Unspecified, |input| {
|
||||
let version = try!(der::small_nonnegative_integer(input));
|
||||
if version != 0 {
|
||||
return Err(error::Unspecified);
|
||||
@ -139,9 +138,7 @@ impl RSAKeyPair {
|
||||
/// Returns the length in bytes of the key pair's public modulus.
|
||||
///
|
||||
/// A signature has the same length as the public modulus.
|
||||
pub fn public_modulus_len(&self) -> usize {
|
||||
unsafe { RSA_size(&self.rsa) }
|
||||
}
|
||||
pub fn public_modulus_len(&self) -> usize { unsafe { RSA_size(&self.rsa) } }
|
||||
}
|
||||
|
||||
impl Drop for RSAKeyPair {
|
||||
@ -161,8 +158,8 @@ impl Drop for RSAKeyPair {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for RSAKeyPair { }
|
||||
unsafe impl Sync for RSAKeyPair { }
|
||||
unsafe impl Send for RSAKeyPair {}
|
||||
unsafe impl Sync for RSAKeyPair {}
|
||||
|
||||
/// Needs to be kept in sync with `struct rsa_st` (in `include/openssl/rsa.h`).
|
||||
#[repr(C)]
|
||||
@ -269,12 +266,10 @@ struct Blinding {
|
||||
}
|
||||
|
||||
impl Drop for Blinding {
|
||||
fn drop(&mut self) {
|
||||
unsafe { BN_BLINDING_free(self.blinding) }
|
||||
}
|
||||
fn drop(&mut self) { unsafe { BN_BLINDING_free(self.blinding) } }
|
||||
}
|
||||
|
||||
unsafe impl Send for Blinding { }
|
||||
unsafe impl Send for Blinding {}
|
||||
|
||||
/// Needs to be kept in sync with `bn_blinding_st` in `crypto/rsa/blinding.c`.
|
||||
#[allow(non_camel_case_types)]
|
||||
@ -312,7 +307,9 @@ mod tests {
|
||||
use super::super::{RSA_PKCS1_SHA256, RSA_PKCS1_SHA384, RSA_PKCS1_SHA512};
|
||||
use untrusted;
|
||||
|
||||
extern { static GFp_BN_BLINDING_COUNTER: u32; }
|
||||
extern {
|
||||
static GFp_BN_BLINDING_COUNTER: u32;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_signature_rsa_pkcs1_sign() {
|
||||
@ -349,7 +346,7 @@ mod tests {
|
||||
// TODO: re-enable these tests on Android ARM.
|
||||
if section == "Skipped on Android ARM due to Travis CI Timeouts" &&
|
||||
cfg!(all(target_os = "android", target_arch = "arm")) {
|
||||
return Ok(());
|
||||
return Ok(());
|
||||
}
|
||||
let mut signing_state = RSASigningState::new(key_pair).unwrap();
|
||||
let mut actual: std::vec::Vec<u8> =
|
||||
@ -413,17 +410,13 @@ mod tests {
|
||||
|
||||
let mut signing_state = RSASigningState::new(key_pair).unwrap();
|
||||
|
||||
for _ in 0 .. GFp_BN_BLINDING_COUNTER + 1 {
|
||||
let prev_counter = unsafe {
|
||||
(*signing_state.blinding.blinding).counter
|
||||
};
|
||||
for _ in 0..(GFp_BN_BLINDING_COUNTER + 1) {
|
||||
let prev_counter =
|
||||
unsafe { (*signing_state.blinding.blinding).counter };
|
||||
|
||||
let _ = signing_state.sign(&RSA_PKCS1_SHA256, &rng, MESSAGE,
|
||||
&mut signature);
|
||||
let _ = signing_state.sign(&RSA_PKCS1_SHA256, &rng, MESSAGE, &mut signature);
|
||||
|
||||
let counter = unsafe {
|
||||
(*signing_state.blinding.blinding).counter
|
||||
};
|
||||
let counter = unsafe { (*signing_state.blinding.blinding).counter };
|
||||
|
||||
assert_eq!(counter, (prev_counter + 1) % GFp_BN_BLINDING_COUNTER);
|
||||
}
|
||||
@ -449,8 +442,8 @@ mod tests {
|
||||
let mut signing_state = RSASigningState::new(key_pair).unwrap();
|
||||
let mut signature =
|
||||
vec![0; signing_state.key_pair().public_modulus_len()];
|
||||
let result = signing_state.sign(&RSA_PKCS1_SHA256, &rng, MESSAGE,
|
||||
&mut signature);
|
||||
let result =
|
||||
signing_state.sign(&RSA_PKCS1_SHA256, &rng, MESSAGE, &mut signature);
|
||||
|
||||
assert!(result.is_err());
|
||||
}
|
||||
@ -464,7 +457,7 @@ mod tests {
|
||||
let key_pair = std::sync::Arc::new(key_pair);
|
||||
|
||||
let _: &Send = &key_pair;
|
||||
let _: &Sync = &key_pair;
|
||||
let _: &Sync = &key_pair;
|
||||
|
||||
let signing_state = RSASigningState::new(key_pair).unwrap();
|
||||
let _: &Send = &signing_state;
|
||||
|
@ -41,26 +41,34 @@ impl signature::VerificationAlgorithm for RSAParameters {
|
||||
self.min_bits, MAX_BITS)
|
||||
}));
|
||||
|
||||
untrusted::Input::from(decoded).read_all(error::Unspecified, |decoded| {
|
||||
if try!(decoded.read_byte()) != 0 ||
|
||||
try!(decoded.read_byte()) != 1 {
|
||||
untrusted::Input::from(decoded).read_all(error::Unspecified,
|
||||
|decoded| {
|
||||
if try!(decoded.read_byte()) != 0 {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
if try!(decoded.read_byte()) != 1 {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
|
||||
let mut ps_len = 0;
|
||||
loop {
|
||||
match try!(decoded.read_byte()) {
|
||||
0xff => { ps_len += 1; },
|
||||
0x00 => { break; },
|
||||
_ => { return Err(error::Unspecified); }
|
||||
0xff => {
|
||||
ps_len += 1;
|
||||
},
|
||||
0x00 => {
|
||||
break;
|
||||
},
|
||||
_ => {
|
||||
return Err(error::Unspecified);
|
||||
},
|
||||
}
|
||||
}
|
||||
if ps_len < 8 {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
|
||||
let decoded_digestinfo_prefix =
|
||||
try!(decoded.skip_and_get_input(
|
||||
let decoded_digestinfo_prefix = try!(decoded.skip_and_get_input(
|
||||
self.padding_alg.digestinfo_prefix.len()));
|
||||
if decoded_digestinfo_prefix != self.padding_alg.digestinfo_prefix {
|
||||
return Err(error::Unspecified);
|
||||
@ -79,7 +87,7 @@ impl signature::VerificationAlgorithm for RSAParameters {
|
||||
}
|
||||
}
|
||||
|
||||
impl private::Private for RSAParameters { }
|
||||
impl private::Private for RSAParameters {}
|
||||
|
||||
macro_rules! rsa_pkcs1 {
|
||||
( $VERIFY_ALGORITHM:ident, $min_bits:expr, $PADDING_ALGORITHM:expr,
|
||||
@ -117,9 +125,9 @@ extern {
|
||||
public_key_n_len: c::size_t,
|
||||
public_key_e: *const u8,
|
||||
public_key_e_len: c::size_t,
|
||||
ciphertext: *const u8, ciphertext_len: c::size_t,
|
||||
min_bits: c::size_t, max_bits: c::size_t)
|
||||
-> c::int;
|
||||
ciphertext: *const u8,
|
||||
ciphertext_len: c::size_t, min_bits: c::size_t,
|
||||
max_bits: c::size_t) -> c::int;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -206,13 +206,11 @@ impl<'a> Signature {
|
||||
}
|
||||
|
||||
/// Returns a reference to the signature's encoded value.
|
||||
pub fn as_slice(&'a self) -> &'a [u8] {
|
||||
&self.value[..]
|
||||
}
|
||||
pub fn as_slice(&'a self) -> &'a [u8] { &self.value[..] }
|
||||
}
|
||||
|
||||
/// A signature verification algorithm.
|
||||
pub trait VerificationAlgorithm : Sync + private::Private {
|
||||
pub trait VerificationAlgorithm: Sync + private::Private {
|
||||
/// Verify the signature `signature` of message `msg` with the public key
|
||||
/// `public_key`.
|
||||
fn verify(&self, public_key: untrusted::Input, msg: untrusted::Input,
|
||||
|
66
src/test.rs
66
src/test.rs
@ -144,7 +144,7 @@ impl TestCase {
|
||||
"SHA256" => Some(&digest::SHA256),
|
||||
"SHA384" => Some(&digest::SHA384),
|
||||
"SHA512" => Some(&digest::SHA512),
|
||||
_ => panic!("Unsupported digest algorithm: {}", name)
|
||||
_ => panic!("Unsupported digest algorithm: {}", name),
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,7 +168,7 @@ impl TestCase {
|
||||
Ok(s) => s,
|
||||
Err(ref err_str) => {
|
||||
panic!("{} in {}", err_str, s);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -190,7 +190,8 @@ impl TestCase {
|
||||
/// Like `consume_string()` except it returns `None` if the test case
|
||||
/// doesn't have the attribute.
|
||||
pub fn consume_optional_string(&mut self, key: &str) -> Option<String> {
|
||||
for &mut (ref name, ref value, ref mut consumed) in &mut self.attributes {
|
||||
for &mut (ref name, ref value, ref mut consumed) in
|
||||
&mut self.attributes {
|
||||
if key == name {
|
||||
if *consumed {
|
||||
panic!("Attribute {} was already consumed", key);
|
||||
@ -220,9 +221,10 @@ pub fn from_file<F>(test_data_relative_file_path: &str, mut f: F)
|
||||
|
||||
while let Some(mut test_case) = parse_test_case(&mut current_section,
|
||||
&mut lines) {
|
||||
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
|
||||
f(¤t_section, &mut test_case)
|
||||
}));
|
||||
let result =
|
||||
std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
|
||||
f(¤t_section, &mut test_case)
|
||||
}));
|
||||
let result = match result {
|
||||
Ok(Ok(())) => {
|
||||
if !test_case.attributes.iter().any(
|
||||
@ -284,8 +286,8 @@ pub fn from_hex(hex_str: &str) -> Result<Vec<u8>, String> {
|
||||
|
||||
type FileLines<'a> = std::io::Lines<std::io::BufReader<&'a std::fs::File>>;
|
||||
|
||||
fn parse_test_case(current_section: &mut String,
|
||||
lines: &mut FileLines) -> Option<TestCase> {
|
||||
fn parse_test_case(current_section: &mut String, lines: &mut FileLines)
|
||||
-> Option<TestCase> {
|
||||
let mut attributes = Vec::new();
|
||||
|
||||
let mut is_first_line = true;
|
||||
@ -310,23 +312,19 @@ fn parse_test_case(current_section: &mut String,
|
||||
|
||||
// End of the file on a non-empty test cases ends the test case.
|
||||
None => {
|
||||
return Some(TestCase {
|
||||
attributes: attributes,
|
||||
});
|
||||
return Some(TestCase { attributes: attributes });
|
||||
},
|
||||
|
||||
// A blank line ends a test case if the test case isn't empty.
|
||||
Some(ref line) if line.is_empty() => {
|
||||
if !is_first_line {
|
||||
return Some(TestCase {
|
||||
attributes: attributes,
|
||||
});
|
||||
return Some(TestCase { attributes: attributes });
|
||||
}
|
||||
// Ignore leading blank lines.
|
||||
},
|
||||
|
||||
// Comments start with '#'; ignore them.
|
||||
Some(ref line) if line.starts_with('#') => { },
|
||||
Some(ref line) if line.starts_with('#') => {},
|
||||
|
||||
Some(ref line) if line.starts_with('[') => {
|
||||
assert!(is_first_line);
|
||||
@ -354,7 +352,7 @@ fn parse_test_case(current_section: &mut String,
|
||||
|
||||
// Checking is_none() ensures we don't accept duplicate keys.
|
||||
attributes.push((String::from(key), String::from(value), false));
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -390,9 +388,17 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[test] #[should_panic(expected = "Test failed.")] fn first_err() { err_one(0) }
|
||||
#[test] #[should_panic(expected = "Test failed.")] fn middle_err() { err_one(1) }
|
||||
#[test] #[should_panic(expected = "Test failed.")] fn last_err() { err_one(2) }
|
||||
#[test]
|
||||
#[should_panic(expected = "Test failed.")]
|
||||
fn first_err() { err_one(0) }
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "Test failed.")]
|
||||
fn middle_err() { err_one(1) }
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "Test failed.")]
|
||||
fn last_err() { err_one(2) }
|
||||
|
||||
fn err_one(test_to_fail: usize) {
|
||||
let mut n = 0;
|
||||
@ -408,9 +414,17 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[test] #[should_panic(expected = "Test failed.")] fn first_panic() { panic_one(0) }
|
||||
#[test] #[should_panic(expected = "Test failed.")] fn middle_panic() { panic_one(1) }
|
||||
#[test] #[should_panic(expected = "Test failed.")] fn last_panic() { panic_one(2) }
|
||||
#[test]
|
||||
#[should_panic(expected = "Test failed.")]
|
||||
fn first_panic() { panic_one(0) }
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "Test failed.")]
|
||||
fn middle_panic() { panic_one(1) }
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "Test failed.")]
|
||||
fn last_panic() { panic_one(2) }
|
||||
|
||||
fn panic_one(test_to_fail: usize) {
|
||||
let mut n = 0;
|
||||
@ -427,16 +441,12 @@ mod tests {
|
||||
#[test]
|
||||
#[should_panic(expected = "Syntax error: Expected Key = Value.")]
|
||||
fn syntax_error() {
|
||||
test::from_file("src/test_1_syntax_error_tests.txt", |_, _| {
|
||||
Ok(())
|
||||
});
|
||||
test::from_file("src/test_1_syntax_error_tests.txt", |_, _| Ok(()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn file_not_found() {
|
||||
test::from_file("src/test_file_not_found_tests.txt", |_, _| {
|
||||
Ok(())
|
||||
});
|
||||
test::from_file("src/test_file_not_found_tests.txt", |_, _| Ok(()));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user