diff --git a/src/hashsum/Cargo.toml b/src/hashsum/Cargo.toml index f4728dd84..9f30881a6 100644 --- a/src/hashsum/Cargo.toml +++ b/src/hashsum/Cargo.toml @@ -8,12 +8,16 @@ name = "uu_hashsum" path = "hashsum.rs" [dependencies] +digest = "0.6.2" getopts = "0.2.14" libc = "0.2.26" +md5 = "0.3.5" regex = "0.2.2" regex-syntax = "0.4.1" -rust-crypto = "0.2.36" rustc-serialize = "0.3.24" +sha1 = "0.2.0" +sha2 = "0.6.0" +sha3 = "0.6.0" uucore = { path="../uucore" } [[bin]] diff --git a/src/hashsum/digest.rs b/src/hashsum/digest.rs index e4d8356ec..098d5abe4 100644 --- a/src/hashsum/digest.rs +++ b/src/hashsum/digest.rs @@ -1,13 +1,15 @@ -extern crate crypto; +extern crate digest; +extern crate md5; extern crate rustc_serialize; +extern crate sha1; +extern crate sha2; +extern crate sha3; -use crypto::md5::Md5; -use crypto::sha1::Sha1; -use crypto::sha2::{Sha224, Sha256, Sha384, Sha512}; -use crypto::sha3::Sha3; -use crypto::digest::Digest as CryptoDigest; +use sha2::Digest as Sha2Digest; +use digest::digest::{Input, ExtendableOutput, XofReader}; pub trait Digest { + fn new() -> Self where Self: Sized; fn input(&mut self, input: &[u8]); fn result(&mut self, out: &mut [u8]); fn reset(&mut self); @@ -24,114 +26,242 @@ pub trait Digest { } } -impl Digest for Md5 { +impl Digest for md5::Context { + fn new() -> Self { + md5::Context::new() + } + fn input(&mut self, input: &[u8]) { - CryptoDigest::input(self, input) + self.consume(input) } fn result(&mut self, out: &mut [u8]) { - CryptoDigest::result(self, out) + out.copy_from_slice(&*self.compute()); } fn reset(&mut self) { - CryptoDigest::reset(self) + *self = md5::Context::new(); } - fn output_bits(&self) -> usize { CryptoDigest::output_bits(self) } + fn output_bits(&self) -> usize { 128 } } -impl Digest for Sha1 { +impl Digest for sha1::Sha1 { + fn new() -> Self { + sha1::Sha1::new() + } + fn input(&mut self, input: &[u8]) { - CryptoDigest::input(self, input) + self.update(input); } fn result(&mut self, out: &mut [u8]) { - CryptoDigest::result(self, out) + out.copy_from_slice(&self.digest().bytes()); } fn reset(&mut self) { - CryptoDigest::reset(self) + self.reset(); } - fn output_bits(&self) -> usize { CryptoDigest::output_bits(self) } + fn output_bits(&self) -> usize { 160 } } -impl Digest for Sha224 { +impl Digest for sha2::Sha224 { + fn new() -> Self { + sha2::Sha224::default() + } + fn input(&mut self, input: &[u8]) { - CryptoDigest::input(self, input) + Sha2Digest::input(self, input); } fn result(&mut self, out: &mut [u8]) { - CryptoDigest::result(self, out) + out.copy_from_slice(Sha2Digest::result(*self).as_slice()); } fn reset(&mut self) { - CryptoDigest::reset(self) + *self = sha2::Sha224::default(); } - fn output_bits(&self) -> usize { CryptoDigest::output_bits(self) } + fn output_bits(&self) -> usize { 224 } } -impl Digest for Sha256 { +impl Digest for sha2::Sha256 { + fn new() -> Self { + sha2::Sha256::default() + } + fn input(&mut self, input: &[u8]) { - CryptoDigest::input(self, input) + Sha2Digest::input(self, input); } fn result(&mut self, out: &mut [u8]) { - CryptoDigest::result(self, out) + out.copy_from_slice(Sha2Digest::result(*self).as_slice()); } fn reset(&mut self) { - CryptoDigest::reset(self) + *self = sha2::Sha256::default(); } - fn output_bits(&self) -> usize { CryptoDigest::output_bits(self) } + fn output_bits(&self) -> usize { 256 } } -impl Digest for Sha384 { +impl Digest for sha2::Sha384 { + fn new() -> Self { + sha2::Sha384::default() + } + fn input(&mut self, input: &[u8]) { - CryptoDigest::input(self, input) + Sha2Digest::input(self, input) } fn result(&mut self, out: &mut [u8]) { - CryptoDigest::result(self, out) + out.copy_from_slice(Sha2Digest::result(*self).as_slice()); } fn reset(&mut self) { - CryptoDigest::reset(self) + *self = sha2::Sha384::default(); } - fn output_bits(&self) -> usize { CryptoDigest::output_bits(self) } + fn output_bits(&self) -> usize { 384 } } -impl Digest for Sha512 { +impl Digest for sha2::Sha512 { + fn new() -> Self { + sha2::Sha512::default() + } + fn input(&mut self, input: &[u8]) { - CryptoDigest::input(self, input) + Sha2Digest::input(self, input) } fn result(&mut self, out: &mut [u8]) { - CryptoDigest::result(self, out) + out.copy_from_slice(Sha2Digest::result(*self).as_slice()); } fn reset(&mut self) { - CryptoDigest::reset(self) + *self = sha2::Sha512::default(); } - fn output_bits(&self) -> usize { CryptoDigest::output_bits(self) } + fn output_bits(&self) -> usize { 512 } } -impl Digest for Sha3 { +impl Digest for sha3::Sha3_224 { + fn new() -> Self { + Self::default() + } + fn input(&mut self, input: &[u8]) { - CryptoDigest::input(self, input) + digest::Digest::input(self, input) } fn result(&mut self, out: &mut [u8]) { - CryptoDigest::result(self, out) + out.copy_from_slice(digest::Digest::result(*self).as_slice()); } fn reset(&mut self) { - CryptoDigest::reset(self) + *self = Self::default(); } - fn output_bits(&self) -> usize { CryptoDigest::output_bits(self) } + fn output_bits(&self) -> usize { 224 } +} + +impl Digest for sha3::Sha3_256 { + fn new() -> Self { + sha3::Sha3_256::default() + } + + fn input(&mut self, input: &[u8]) { + digest::Digest::input(self, input) + } + + fn result(&mut self, out: &mut [u8]) { + out.copy_from_slice(digest::Digest::result(*self).as_slice()); + } + + fn reset(&mut self) { + *self = sha3::Sha3_256::default(); + } + + fn output_bits(&self) -> usize { 256 } +} + +impl Digest for sha3::Sha3_384 { + fn new() -> Self { + sha3::Sha3_384::default() + } + + fn input(&mut self, input: &[u8]) { + digest::Digest::input(self, input) + } + + fn result(&mut self, out: &mut [u8]) { + out.copy_from_slice(digest::Digest::result(*self).as_slice()); + } + + fn reset(&mut self) { + *self = sha3::Sha3_384::default(); + } + + fn output_bits(&self) -> usize { 384 } +} + +impl Digest for sha3::Sha3_512 { + fn new() -> Self { + sha3::Sha3_512::default() + } + + fn input(&mut self, input: &[u8]) { + digest::Digest::input(self, input) + } + + fn result(&mut self, out: &mut [u8]) { + out.copy_from_slice(digest::Digest::result(*self).as_slice()); + } + + fn reset(&mut self) { + *self = sha3::Sha3_512::default(); + } + + fn output_bits(&self) -> usize { 512 } +} + +impl Digest for sha3::Shake128 { + fn new() -> Self { + sha3::Shake128::default() + } + + fn input(&mut self, input: &[u8]) { + self.process(input); + } + + fn result(&mut self, out: &mut [u8]) { + self.xof_result().read(out); + } + + fn reset(&mut self) { + *self = sha3::Shake128::default(); + } + + fn output_bits(&self) -> usize { 0 } +} + +impl Digest for sha3::Shake256 { + fn new() -> Self { + sha3::Shake256::default() + } + + fn input(&mut self, input: &[u8]) { + self.process(input); + } + + fn result(&mut self, out: &mut [u8]) { + self.xof_result().read(out); + } + + fn reset(&mut self) { + *self = sha3::Shake256::default(); + } + + fn output_bits(&self) -> usize { 0 } } diff --git a/src/hashsum/hashsum.rs b/src/hashsum/hashsum.rs index 8579a2ddb..d13f1dc02 100644 --- a/src/hashsum/hashsum.rs +++ b/src/hashsum/hashsum.rs @@ -11,11 +11,14 @@ * file that was distributed with this source code. */ -extern crate crypto; extern crate getopts; +extern crate md5; extern crate regex_syntax; extern crate regex; extern crate rustc_serialize as serialize; +extern crate sha1; +extern crate sha2; +extern crate sha3; #[macro_use] extern crate uucore; @@ -23,12 +26,12 @@ extern crate uucore; mod digest; use digest::Digest; -use crypto::md5::Md5; -use crypto::sha1::Sha1; -use crypto::sha2::{Sha224, Sha256, Sha384, Sha512}; -use crypto::sha3::{Sha3, Sha3Mode}; +use md5::Context as Md5; use regex::Regex; use serialize::hex::ToHex; +use sha1::Sha1; +use sha2::{Sha224, Sha256, Sha384, Sha512}; +use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512, Shake128, Shake256}; use std::ascii::AsciiExt; use std::fs::File; use std::io::{self, BufRead, BufReader, Read, stdin, Write}; @@ -64,24 +67,24 @@ fn detect_algo(program: &str, matches: &getopts::Matches) -> (&'static str, Box< "sha3sum" => { match matches.opt_str("bits") { Some(bits_str) => match usize::from_str_radix(&bits_str, 10) { - Ok(224) => ("SHA3-224", Box::new(Sha3::new(Sha3Mode::Sha3_224)) as Box, 224), - Ok(256) => ("SHA3-256", Box::new(Sha3::new(Sha3Mode::Sha3_256)) as Box, 256), - Ok(384) => ("SHA3-384", Box::new(Sha3::new(Sha3Mode::Sha3_384)) as Box, 384), - Ok(512) => ("SHA3-512", Box::new(Sha3::new(Sha3Mode::Sha3_512)) as Box, 512), + Ok(224) => ("SHA3-224", Box::new(Sha3_224::new()) as Box, 224), + Ok(256) => ("SHA3-256", Box::new(Sha3_256::new()) as Box, 256), + Ok(384) => ("SHA3-384", Box::new(Sha3_384::new()) as Box, 384), + Ok(512) => ("SHA3-512", Box::new(Sha3_512::new()) as Box, 512), Ok(_) => crash!(1, "Invalid output size for SHA3 (expected 224, 256, 384, or 512)"), Err(err) => crash!(1, "{}", err) }, None => crash!(1, "--bits required for SHA3") } } - "sha3-224sum" => ("SHA3-224", Box::new(Sha3::new(Sha3Mode::Sha3_224)) as Box, 224), - "sha3-256sum" => ("SHA3-256", Box::new(Sha3::new(Sha3Mode::Sha3_256)) as Box, 256), - "sha3-384sum" => ("SHA3-384", Box::new(Sha3::new(Sha3Mode::Sha3_384)) as Box, 384), - "sha3-512sum" => ("SHA3-512", Box::new(Sha3::new(Sha3Mode::Sha3_512)) as Box, 512), + "sha3-224sum" => ("SHA3-224", Box::new(Sha3_224::new()) as Box, 224), + "sha3-256sum" => ("SHA3-256", Box::new(Sha3_256::new()) as Box, 256), + "sha3-384sum" => ("SHA3-384", Box::new(Sha3_384::new()) as Box, 384), + "sha3-512sum" => ("SHA3-512", Box::new(Sha3_512::new()) as Box, 512), "shake128sum" => { match matches.opt_str("bits") { Some(bits_str) => match usize::from_str_radix(&bits_str, 10) { - Ok(bits) => ("SHAKE128", Box::new(Sha3::new(Sha3Mode::Shake128)) as Box, bits), + Ok(bits) => ("SHAKE128", Box::new(Shake128::new()) as Box, bits), Err(err) => crash!(1, "{}", err) }, None => crash!(1, "--bits required for SHAKE-128") @@ -90,7 +93,7 @@ fn detect_algo(program: &str, matches: &getopts::Matches) -> (&'static str, Box< "shake256sum" => { match matches.opt_str("bits") { Some(bits_str) => match usize::from_str_radix(&bits_str, 10) { - Ok(bits) => ("SHAKE256", Box::new(Sha3::new(Sha3Mode::Shake256)) as Box, bits), + Ok(bits) => ("SHAKE256", Box::new(Shake256::new()) as Box, bits), Err(err) => crash!(1, "{}", err) }, None => crash!(1, "--bits required for SHAKE-256") @@ -113,24 +116,24 @@ fn detect_algo(program: &str, matches: &getopts::Matches) -> (&'static str, Box< if matches.opt_present("sha3") { match matches.opt_str("bits") { Some(bits_str) => match usize::from_str_radix(&bits_str, 10) { - Ok(224) => set_or_crash("SHA3-224", Box::new(Sha3::new(Sha3Mode::Sha3_224)) as Box, 224), - Ok(256) => set_or_crash("SHA3-256", Box::new(Sha3::new(Sha3Mode::Sha3_256)) as Box, 256), - Ok(384) => set_or_crash("SHA3-384", Box::new(Sha3::new(Sha3Mode::Sha3_384)) as Box, 384), - Ok(512) => set_or_crash("SHA3-512", Box::new(Sha3::new(Sha3Mode::Sha3_512)) as Box, 512), + Ok(224) => set_or_crash("SHA3-224", Box::new(Sha3_224::new()) as Box, 224), + Ok(256) => set_or_crash("SHA3-256", Box::new(Sha3_256::new()) as Box, 256), + Ok(384) => set_or_crash("SHA3-384", Box::new(Sha3_384::new()) as Box, 384), + Ok(512) => set_or_crash("SHA3-512", Box::new(Sha3_512::new()) as Box, 512), Ok(_) => crash!(1, "Invalid output size for SHA3 (expected 224, 256, 384, or 512)"), Err(err) => crash!(1, "{}", err) }, None => crash!(1, "--bits required for SHA3") } } - if matches.opt_present("sha3-224") { set_or_crash("SHA3-224", Box::new(Sha3::new(Sha3Mode::Sha3_224)), 224) } - if matches.opt_present("sha3-256") { set_or_crash("SHA3-256", Box::new(Sha3::new(Sha3Mode::Sha3_256)), 256) } - if matches.opt_present("sha3-384") { set_or_crash("SHA3-384", Box::new(Sha3::new(Sha3Mode::Sha3_384)), 384) } - if matches.opt_present("sha3-512") { set_or_crash("SHA3-512", Box::new(Sha3::new(Sha3Mode::Sha3_512)), 512) } + if matches.opt_present("sha3-224") { set_or_crash("SHA3-224", Box::new(Sha3_224::new()), 224) } + if matches.opt_present("sha3-256") { set_or_crash("SHA3-256", Box::new(Sha3_256::new()), 256) } + if matches.opt_present("sha3-384") { set_or_crash("SHA3-384", Box::new(Sha3_384::new()), 384) } + if matches.opt_present("sha3-512") { set_or_crash("SHA3-512", Box::new(Sha3_512::new()), 512) } if matches.opt_present("shake128") { match matches.opt_str("bits") { Some(bits_str) => match usize::from_str_radix(&bits_str, 10) { - Ok(bits) => set_or_crash("SHAKE128", Box::new(Sha3::new(Sha3Mode::Shake128)), bits), + Ok(bits) => set_or_crash("SHAKE128", Box::new(Shake128::new()), bits), Err(err) => crash!(1, "{}", err) }, None => crash!(1, "--bits required for SHAKE-128") @@ -139,7 +142,7 @@ fn detect_algo(program: &str, matches: &getopts::Matches) -> (&'static str, Box< if matches.opt_present("shake256") { match matches.opt_str("bits") { Some(bits_str) => match usize::from_str_radix(&bits_str, 10) { - Ok(bits) => set_or_crash("SHAKE256", Box::new(Sha3::new(Sha3Mode::Shake256)), bits), + Ok(bits) => set_or_crash("SHAKE256", Box::new(Shake256::new()), bits), Err(err) => crash!(1, "{}", err) }, None => crash!(1, "--bits required for SHAKE-256")