Skip to content

Commit

Permalink
Complements to #389 (#415)
Browse files Browse the repository at this point in the history
* Copyright and test module

* Cosmetic changes

* Put back static constraint in mplex (in case it might be needed in other crates).

* 2018, Send on box.
  • Loading branch information
cheme authored and gnunicorn committed Aug 15, 2018
1 parent bd73f60 commit 5b712e5
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 27 deletions.
4 changes: 2 additions & 2 deletions secio/src/codec/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use ring::hmac;
///
/// Also implements `Sink` for convenience.
pub struct DecoderMiddleware<S> {
cipher_state: Box<StreamCipher>,
cipher_state: StreamCipher,
hmac_key: hmac::VerificationKey,
// TODO: when a new version of ring is released, we can use `hmac_key.digest_algorithm().output_len` instead
hmac_num_bytes: usize,
Expand All @@ -51,7 +51,7 @@ impl<S> DecoderMiddleware<S> {
#[inline]
pub fn new(
raw_stream: S,
cipher: Box<StreamCipher>,
cipher: StreamCipher,
hmac_key: hmac::VerificationKey,
hmac_num_bytes: usize, // TODO: remove this parameter
) -> DecoderMiddleware<S> {
Expand Down
7 changes: 3 additions & 4 deletions secio/src/codec/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ use ring::hmac;
///
/// Also implements `Stream` for convenience.
pub struct EncoderMiddleware<S> {
cipher_state: Box<StreamCipher>,
cipher_state: StreamCipher,
hmac_key: hmac::SigningKey,
raw_sink: S,
}

impl<S> EncoderMiddleware<S> {
pub fn new(
raw_sink: S,
cipher: Box<StreamCipher>,
cipher: StreamCipher,
hmac_key: hmac::SigningKey,
) -> EncoderMiddleware<S> {
EncoderMiddleware {
Expand All @@ -62,9 +62,8 @@ where
type SinkItem = BytesMut;
type SinkError = S::SinkError;

fn start_send(&mut self, item: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> {
fn start_send(&mut self, mut data_buf: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> {

let mut data_buf = item;
// TODO if SinkError gets refactor to SecioError,
// then use try_apply_keystream
self.cipher_state.apply_keystream(&mut data_buf[..]);
Expand Down
6 changes: 3 additions & 3 deletions secio/src/codec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ mod encode;
/// Type returned by `full_codec`.
pub type FullCodec<S> = DecoderMiddleware<EncoderMiddleware<length_delimited::Framed<S>>>;

pub type StreamCipher = StreamCipherCore;
pub type StreamCipher = Box<dyn StreamCipherCore + Send>;


/// Takes control of `socket`. Returns an object that implements `future::Sink` and
Expand All @@ -45,9 +45,9 @@ pub type StreamCipher = StreamCipherCore;
/// hash algorithm (which are generally decided during the handshake).
pub fn full_codec<S>(
socket: length_delimited::Framed<S>,
cipher_encoding: Box<StreamCipher>,
cipher_encoding: StreamCipher,
encoding_hmac: hmac::SigningKey,
cipher_decoder: Box<StreamCipher>,
cipher_decoder: StreamCipher,
decoding_hmac: hmac::VerificationKey,
) -> FullCodec<S>
where
Expand Down
62 changes: 44 additions & 18 deletions secio/src/stream_cipher.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,26 @@
// Copyright 2018 Parity Technologies (UK) Ltd.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

use super::codec::StreamCipher;
use aes_ctr::stream_cipher::generic_array::GenericArray;
use aes_ctr::stream_cipher::{NewFixStreamCipher, StreamCipherCore};
use aes_ctr::stream_cipher::NewFixStreamCipher;
use aes_ctr::{Aes128Ctr, Aes256Ctr};

#[derive(Clone, Copy)]
Expand All @@ -11,13 +31,13 @@ pub enum KeySize {

/// Returns your stream cipher depending on `KeySize`.
#[cfg(not(all(feature = "aes-all", any(target_arch = "x86_64", target_arch = "x86"))))]
pub(crate) fn ctr(key_size: KeySize, key: &[u8], iv: &[u8]) -> Box<StreamCipherCore + 'static> {
pub fn ctr(key_size: KeySize, key: &[u8], iv: &[u8]) -> StreamCipher {
ctr_int(key_size, key, iv)
}

/// Returns your stream cipher depending on `KeySize`.
#[cfg(all(feature = "aes-all", any(target_arch = "x86_64", target_arch = "x86")))]
pub(crate) fn ctr(key_size: KeySize, key: &[u8], iv: &[u8]) -> Box<StreamCipherCore + 'static> {
pub fn ctr(key_size: KeySize, key: &[u8], iv: &[u8]) -> StreamCipher {
if *aes_alt::AES_NI {
aes_alt::ctr_alt(key_size, key, iv)
} else {
Expand All @@ -30,9 +50,10 @@ pub(crate) fn ctr(key_size: KeySize, key: &[u8], iv: &[u8]) -> Box<StreamCipherC
mod aes_alt {
extern crate ctr;
extern crate aesni;
use ::codec::StreamCipher;
use self::ctr::Ctr128;
use self::aesni::{Aes128, Aes256};
use self::ctr::stream_cipher::{NewFixStreamCipher, StreamCipherCore};
use self::ctr::stream_cipher::NewFixStreamCipher;
use self::ctr::stream_cipher::generic_array::GenericArray;
use super::KeySize;

Expand All @@ -49,7 +70,7 @@ mod aes_alt {
pub type Aes256Ctr = Ctr128<Aes256>;
/// Returns alternate stream cipher if target functionalities does not allow standard one.
/// Eg : aes without sse
pub fn ctr_alt(key_size: KeySize, key: &[u8], iv: &[u8]) -> Box<StreamCipherCore + 'static> {
pub fn ctr_alt(key_size: KeySize, key: &[u8], iv: &[u8]) -> StreamCipher {
match key_size {
KeySize::KeySize128 => Box::new(Aes128Ctr::new(
GenericArray::from_slice(key),
Expand All @@ -65,7 +86,7 @@ mod aes_alt {
}

#[inline]
fn ctr_int(key_size: KeySize, key: &[u8], iv: &[u8]) -> Box<StreamCipherCore + 'static> {
fn ctr_int(key_size: KeySize, key: &[u8], iv: &[u8]) -> StreamCipher {
match key_size {
KeySize::KeySize128 => Box::new(Aes128Ctr::new(
GenericArray::from_slice(key),
Expand All @@ -79,20 +100,25 @@ fn ctr_int(key_size: KeySize, key: &[u8], iv: &[u8]) -> Box<StreamCipherCore + '
}

#[cfg(all(
feature = "aes-all",
any(target_arch = "x86_64", target_arch = "x86"),
feature = "aes-all",
any(target_arch = "x86_64", target_arch = "x86"),
))]
#[test]
fn assert_non_native_run() {
// this test is for asserting aes unsuported opcode does not break on old cpu
let key = [0;16];
let iv = [0;16];

let mut aes = ctr(KeySize::KeySize128, &key, &iv);
let mut content = [0;16];
assert!(aes
.try_apply_keystream(&mut content).is_ok());
#[cfg(test)]
mod tests {
use super::{KeySize, ctr};

#[test]
fn assert_non_native_run() {
// this test is for asserting aes unsuported opcode does not break on old cpu
let key = [0;16];
let iv = [0;16];

let mut aes = ctr(KeySize::KeySize128, &key, &iv);
let mut content = [0;16];
assert!(aes
.try_apply_keystream(&mut content).is_ok());

}
}

// aesni compile check for aes-all (aes-all import aesni through aes_ctr only if those checks pass)
Expand Down

0 comments on commit 5b712e5

Please sign in to comment.