diff --git a/Cargo.lock b/Cargo.lock index 2b9adcc0..a4b94cb6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -556,7 +556,7 @@ checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" dependencies = [ "getrandom 0.2.15", "instant", - "rand", + "rand 0.8.5", ] [[package]] @@ -838,6 +838,20 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" +[[package]] +name = "crc-fast" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf0ab672ed7761a44410115d2e0e5ccd86b987ba186a78a4148fb02bb302a774" +dependencies = [ + "cc", + "crc", + "digest", + "libc", + "rand 0.9.1", + "regex", +] + [[package]] name = "crc32c" version = "0.6.8" @@ -896,7 +910,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.4", "typenum", ] @@ -1211,7 +1225,7 @@ dependencies = [ "bytes", "bytesize", "chrono", - "crc32fast", + "crc-fast", "format_table", "futures", "garage_api_admin", @@ -1292,9 +1306,7 @@ dependencies = [ "base64 0.21.7", "bytes", "chrono", - "crc32c", - "crc32fast", - "crc64fast-nvme", + "crc-fast", "crypto-common", "err-derive", "futures", @@ -1353,9 +1365,7 @@ dependencies = [ "base64 0.21.7", "bytes", "chrono", - "crc32c", - "crc32fast", - "crc64fast-nvme", + "crc-fast", "err-derive", "form_urlencoded", "futures", @@ -1407,7 +1417,7 @@ dependencies = [ "garage_util", "hex", "opentelemetry", - "rand", + "rand 0.8.5", "serde", "tokio", "tokio-util 0.7.14", @@ -1448,7 +1458,7 @@ dependencies = [ "hex", "http 1.3.1", "parse_duration", - "rand", + "rand 0.8.5", "serde", "serde_bytes", "tokio", @@ -1473,7 +1483,7 @@ dependencies = [ "opentelemetry-contrib", "pin-project", "pretty_env_logger", - "rand", + "rand 0.8.5", "rmp-serde", "serde", "tokio", @@ -1503,7 +1513,7 @@ dependencies = [ "nix", "opentelemetry", "pnet_datalink", - "rand", + "rand 0.8.5", "reqwest", "schemars", "serde", @@ -1527,7 +1537,7 @@ dependencies = [ "hex", "hexdump", "opentelemetry", - "rand", + "rand 0.8.5", "serde", "serde_bytes", "tokio", @@ -1554,7 +1564,7 @@ dependencies = [ "lazy_static", "mktemp", "opentelemetry", - "rand", + "rand 0.8.5", "rmp-serde", "rustc_version", "serde", @@ -2868,7 +2878,7 @@ dependencies = [ "lazy_static", "percent-encoding", "pin-project", - "rand", + "rand 0.8.5", "thiserror 1.0.69", "tokio", "tokio-stream", @@ -3010,7 +3020,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" dependencies = [ "base64ct", - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -3359,8 +3369,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", ] [[package]] @@ -3370,7 +3390,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", ] [[package]] @@ -3382,6 +3412,15 @@ dependencies = [ "getrandom 0.2.15", ] +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.2", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -4465,7 +4504,7 @@ dependencies = [ "indexmap 1.9.3", "pin-project", "pin-project-lite", - "rand", + "rand 0.8.5", "slab", "tokio", "tokio-util 0.7.14", @@ -4717,7 +4756,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" dependencies = [ "getrandom 0.2.15", - "rand", + "rand 0.8.5", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index a7e3e225..004472f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,9 +49,7 @@ bytes = "1.0" bytesize = "1.1" cfg-if = "1.0" chrono = { version = "0.4", features = ["serde"] } -crc32fast = "1.4" -crc32c = "0.6" -crc64fast-nvme = "1.2" +crc-fast = "1.1" crypto-common = "0.1" err-derive = "0.3" gethostname = "0.4" diff --git a/src/api/common/Cargo.toml b/src/api/common/Cargo.toml index 672df030..75838148 100644 --- a/src/api/common/Cargo.toml +++ b/src/api/common/Cargo.toml @@ -21,9 +21,7 @@ garage_util.workspace = true base64.workspace = true bytes.workspace = true chrono.workspace = true -crc32fast.workspace = true -crc32c.workspace = true -crc64fast-nvme.workspace = true +crc-fast.workspace = true crypto-common.workspace = true err-derive.workspace = true hex.workspace = true diff --git a/src/api/common/signature/checksum.rs b/src/api/common/signature/checksum.rs index 2d7a1389..464fdc75 100644 --- a/src/api/common/signature/checksum.rs +++ b/src/api/common/signature/checksum.rs @@ -1,10 +1,7 @@ -use std::convert::{TryFrom, TryInto}; -use std::hash::Hasher; +use std::convert::TryInto; use base64::prelude::*; -use crc32c::Crc32cHasher as Crc32c; -use crc32fast::Hasher as Crc32; -use crc64fast_nvme::Digest as Crc64Nvme; +use crc_fast::{CrcAlgorithm, Digest as CrcDigest}; use md5::{Digest, Md5}; use sha1::Sha1; use sha2::Sha256; @@ -41,6 +38,21 @@ pub type Md5Checksum = [u8; 16]; pub type Sha1Checksum = [u8; 20]; pub type Sha256Checksum = [u8; 32]; +// -- MAP OF CRC ALGORITHMS : +// CRC32 -> CrcAlgorithm::Crc32IsoHdlc +// CRC32C -> CrcAlgorithm::Crc32Iscsi +// CRC64NVME -> CrcAlgorithm::Crc64Nvme + +pub fn new_crc32() -> CrcDigest { + CrcDigest::new(CrcAlgorithm::Crc32IsoHdlc) +} +pub fn new_crc32c() -> CrcDigest { + CrcDigest::new(CrcAlgorithm::Crc32Iscsi) +} +pub fn new_crc64nvme() -> CrcDigest { + CrcDigest::new(CrcAlgorithm::Crc64Nvme) +} + #[derive(Debug, Default, Clone)] pub struct ExpectedChecksums { // base64-encoded md5 (content-md5 header) @@ -52,9 +64,9 @@ pub struct ExpectedChecksums { } pub struct Checksummer { - pub crc32: Option, - pub crc32c: Option, - pub crc64nvme: Option, + pub crc32: Option, + pub crc32c: Option, + pub crc64nvme: Option, pub md5: Option, pub sha1: Option, pub sha256: Option, @@ -103,13 +115,13 @@ impl Checksummer { self.sha256 = Some(Sha256::new()); } if matches!(&expected.extra, Some(ChecksumValue::Crc32(_))) { - self.crc32 = Some(Crc32::new()); + self.crc32 = Some(new_crc32()); } if matches!(&expected.extra, Some(ChecksumValue::Crc32c(_))) { - self.crc32c = Some(Crc32c::default()); + self.crc32c = Some(new_crc32c()); } if matches!(&expected.extra, Some(ChecksumValue::Crc64Nvme(_))) { - self.crc64nvme = Some(Crc64Nvme::default()); + self.crc64nvme = Some(new_crc64nvme()); } if matches!(&expected.extra, Some(ChecksumValue::Sha1(_))) { self.sha1 = Some(Sha1::new()); @@ -119,13 +131,13 @@ impl Checksummer { pub fn add(mut self, algo: Option) -> Self { match algo { Some(ChecksumAlgorithm::Crc32) => { - self.crc32 = Some(Crc32::new()); + self.crc32 = Some(new_crc32()); } Some(ChecksumAlgorithm::Crc32c) => { - self.crc32c = Some(Crc32c::default()); + self.crc32c = Some(new_crc32c()); } Some(ChecksumAlgorithm::Crc64Nvme) => { - self.crc64nvme = Some(Crc64Nvme::default()); + self.crc64nvme = Some(new_crc64nvme()); } Some(ChecksumAlgorithm::Sha1) => { self.sha1 = Some(Sha1::new()); @@ -143,10 +155,10 @@ impl Checksummer { crc32.update(bytes); } if let Some(crc32c) = &mut self.crc32c { - crc32c.write(bytes); + crc32c.update(bytes); } if let Some(crc64nvme) = &mut self.crc64nvme { - crc64nvme.write(bytes); + crc64nvme.update(bytes); } if let Some(md5) = &mut self.md5 { md5.update(bytes); @@ -161,11 +173,9 @@ impl Checksummer { pub fn finalize(self) -> Checksums { Checksums { - crc32: self.crc32.map(|x| u32::to_be_bytes(x.finalize())), - crc32c: self - .crc32c - .map(|x| u32::to_be_bytes(u32::try_from(x.finish()).unwrap())), - crc64nvme: self.crc64nvme.map(|x| u64::to_be_bytes(x.sum64())), + crc32: self.crc32.map(|x| u32::to_be_bytes(x.finalize() as u32)), + crc32c: self.crc32c.map(|x| u32::to_be_bytes(x.finalize() as u32)), + crc64nvme: self.crc64nvme.map(|x| u64::to_be_bytes(x.finalize())), md5: self.md5.map(|x| x.finalize()[..].try_into().unwrap()), sha1: self.sha1.map(|x| x.finalize()[..].try_into().unwrap()), sha256: self.sha256.map(|x| x.finalize()[..].try_into().unwrap()), @@ -197,10 +207,11 @@ impl Checksums { } if let Some(extra) = expected.extra { let algo = extra.algorithm(); - if self.extract(Some(algo)) != Some(extra) { + let calculated = self.extract(Some(algo)); + if calculated != Some(extra) { return Err(Error::InvalidDigest(format!( - "Failed to validate checksum for algorithm {:?}", - algo + "Failed to validate checksum for algorithm {:?}: calculated {:?}, expected {:?}", + algo, calculated, extra ))); } } diff --git a/src/api/s3/Cargo.toml b/src/api/s3/Cargo.toml index 02866c35..2d11761f 100644 --- a/src/api/s3/Cargo.toml +++ b/src/api/s3/Cargo.toml @@ -27,9 +27,7 @@ async-compression.workspace = true base64.workspace = true bytes.workspace = true chrono.workspace = true -crc32fast.workspace = true -crc32c.workspace = true -crc64fast-nvme.workspace = true +crc-fast.workspace = true err-derive.workspace = true hex.workspace = true hmac.workspace = true diff --git a/src/api/s3/list.rs b/src/api/s3/list.rs index 797fdec0..f86dd7c1 100644 --- a/src/api/s3/list.rs +++ b/src/api/s3/list.rs @@ -1002,9 +1002,11 @@ mod tests { inner: ObjectVersionMetaInner { headers: vec![], checksum: None, + checksum_type: None, }, }, checksum_algorithm: None, + checksum_type: None, }, } } diff --git a/src/api/s3/multipart.rs b/src/api/s3/multipart.rs index b946fd3d..336872cd 100644 --- a/src/api/s3/multipart.rs +++ b/src/api/s3/multipart.rs @@ -1,12 +1,9 @@ use std::collections::HashMap; -use std::convert::{TryFrom, TryInto}; -use std::hash::Hasher; +use std::convert::TryInto; use std::sync::Arc; use base64::prelude::*; -use crc32c::Crc32cHasher as Crc32c; -use crc32fast::Hasher as Crc32; -use crc64fast_nvme::Digest as Crc64Nvme; +use crc_fast::{CrcAlgorithm, Digest as CrcDigest}; use futures::prelude::*; use hyper::{header::HeaderValue, HeaderMap, Request, Response}; use md5::{Digest, Md5}; @@ -410,7 +407,11 @@ pub async fn handle_complete_multipart_upload( // https://teppen.io/2018/06/23/aws_s3_etags/ let mut checksummer = MultipartChecksummer::init(checksum_algorithm, checksum_type); for part in parts.iter() { - checksummer.update(part.etag.as_ref().unwrap(), part.checksum)?; + checksummer.update( + part.etag.as_ref().unwrap(), + part.checksum, + part.size.unwrap(), + )?; } let (checksum_md5, checksum_extra) = checksummer.finalize(); @@ -693,36 +694,14 @@ pub(crate) struct MultipartChecksummer { pub extra: Option, } -pub(crate) enum MultipartExtraChecksummer { - Crc32(Crc32), - Crc32c(Crc32c), - Crc64Nvme(Crc64Nvme), - Sha1(Sha1), - Sha256(Sha256), -} - impl MultipartChecksummer { pub(crate) fn init(algo: Option, cktype: Option) -> Self { - if cktype == Some(ChecksumType::FullObject) { - todo!() - } Self { md5: Md5::new(), - extra: match algo { - None => None, - Some(ChecksumAlgorithm::Crc32) => { - Some(MultipartExtraChecksummer::Crc32(Crc32::new())) - } - Some(ChecksumAlgorithm::Crc32c) => { - Some(MultipartExtraChecksummer::Crc32c(Crc32c::default())) - } - Some(ChecksumAlgorithm::Crc64Nvme) => { - Some(MultipartExtraChecksummer::Crc64Nvme(Crc64Nvme::default())) - } - Some(ChecksumAlgorithm::Sha1) => Some(MultipartExtraChecksummer::Sha1(Sha1::new())), - Some(ChecksumAlgorithm::Sha256) => { - Some(MultipartExtraChecksummer::Sha256(Sha256::new())) - } + extra: match (algo, cktype) { + (None, None) => None, + (Some(algo), Some(cktype)) => Some(MultipartExtraChecksummer::init(algo, cktype)), + _ => unreachable!(), }, } } @@ -731,68 +710,130 @@ impl MultipartChecksummer { &mut self, etag: &str, checksum: Option, + part_len: u64, ) -> Result<(), Error> { self.md5 .update(&hex::decode(&etag).ok_or_message("invalid etag hex")?); - match (&mut self.extra, checksum) { - (None, _) => (), - ( - Some(MultipartExtraChecksummer::Crc32(ref mut crc32)), - Some(ChecksumValue::Crc32(x)), - ) => { - crc32.update(&x); - } - ( - Some(MultipartExtraChecksummer::Crc32c(ref mut crc32c)), - Some(ChecksumValue::Crc32c(x)), - ) => { - crc32c.write(&x); - } - ( - Some(MultipartExtraChecksummer::Crc64Nvme(ref mut crc64nvme)), - Some(ChecksumValue::Crc64Nvme(x)), - ) => { - crc64nvme.write(&x); - } - (Some(MultipartExtraChecksummer::Sha1(ref mut sha1)), Some(ChecksumValue::Sha1(x))) => { - sha1.update(&x); - } - ( - Some(MultipartExtraChecksummer::Sha256(ref mut sha256)), - Some(ChecksumValue::Sha256(x)), - ) => { - sha256.update(&x); - } - (Some(_), b) => { - return Err(Error::internal_error(format!( - "part checksum was not computed correctly, got: {:?}", - b - ))) - } + if let Some(extra) = &mut self.extra { + extra.update(checksum, part_len)?; } Ok(()) } pub(crate) fn finalize(self) -> (Md5Checksum, Option) { let md5 = self.md5.finalize()[..].try_into().unwrap(); - let extra = match self.extra { - None => None, - Some(MultipartExtraChecksummer::Crc32(crc32)) => { - Some(ChecksumValue::Crc32(u32::to_be_bytes(crc32.finalize()))) - } - Some(MultipartExtraChecksummer::Crc32c(crc32c)) => Some(ChecksumValue::Crc32c( - u32::to_be_bytes(u32::try_from(crc32c.finish()).unwrap()), - )), - Some(MultipartExtraChecksummer::Crc64Nvme(crc64nvme)) => Some( - ChecksumValue::Crc64Nvme(u64::to_be_bytes(crc64nvme.sum64())), - ), - Some(MultipartExtraChecksummer::Sha1(sha1)) => { - Some(ChecksumValue::Sha1(sha1.finalize()[..].try_into().unwrap())) - } - Some(MultipartExtraChecksummer::Sha256(sha256)) => Some(ChecksumValue::Sha256( - sha256.finalize()[..].try_into().unwrap(), - )), - }; + let extra = self.extra.map(|c| c.finalize()); (md5, extra) } } + +pub(crate) enum MultipartExtraChecksummer { + FullObjectCrc(CrcAlgorithm, Option), + CompositeCrc(ChecksumAlgorithm, CrcDigest), + CompositeSha1(Sha1), + CompositeSha256(Sha256), +} + +impl MultipartExtraChecksummer { + fn init(algo: ChecksumAlgorithm, cktype: ChecksumType) -> Self { + match (algo, cktype) { + (algo, ChecksumType::FullObject) => { + let crc_type = match algo { + ChecksumAlgorithm::Crc32 => CrcAlgorithm::Crc32IsoHdlc, + ChecksumAlgorithm::Crc32c => CrcAlgorithm::Crc32Iscsi, + ChecksumAlgorithm::Crc64Nvme => CrcAlgorithm::Crc64Nvme, + _ => unreachable!(), + }; + Self::FullObjectCrc(crc_type, None) + } + (ChecksumAlgorithm::Crc32, ChecksumType::Composite) => { + Self::CompositeCrc(ChecksumAlgorithm::Crc32, new_crc32()) + } + (ChecksumAlgorithm::Crc32c, ChecksumType::Composite) => { + Self::CompositeCrc(ChecksumAlgorithm::Crc32c, new_crc32c()) + } + (ChecksumAlgorithm::Sha1, ChecksumType::Composite) => Self::CompositeSha1(Sha1::new()), + (ChecksumAlgorithm::Sha256, ChecksumType::Composite) => { + Self::CompositeSha256(Sha256::new()) + } + _ => unreachable!(), + } + } + + fn update(&mut self, checksum: Option, part_len: u64) -> Result<(), Error> { + match (self, checksum) { + (Self::FullObjectCrc(crc_algo, crc_value), Some(ck)) => { + let ck_u64 = match ck { + ChecksumValue::Crc32(x) => u32::from_be_bytes(x) as u64, + ChecksumValue::Crc32c(x) => u32::from_be_bytes(x) as u64, + ChecksumValue::Crc64Nvme(x) => u64::from_be_bytes(x), + _ => { + return Err(Error::internal_error(format!( + "part checksum was not computed correctly, got: {:?}", + ck + ))) + } + }; + *crc_value = match *crc_value { + None => Some(ck_u64), + Some(prev) => Some(crc_fast::checksum_combine( + *crc_algo, prev, ck_u64, part_len, + )), + }; + } + (Self::CompositeCrc(_, digest), Some(ck)) => match ck { + ChecksumValue::Crc32(x) => digest.update(&x), + ChecksumValue::Crc32c(x) => digest.update(&x), + ChecksumValue::Crc64Nvme(x) => digest.update(&x), + _ => { + return Err(Error::internal_error(format!( + "part checksum was not computed correctly, got: {:?}", + ck + ))) + } + }, + (Self::CompositeSha1(sha1), Some(ChecksumValue::Sha1(x))) => { + sha1.update(&x); + } + (Self::CompositeSha256(sha256), Some(ChecksumValue::Sha256(x))) => { + sha256.update(&x); + } + _ => { + return Err(Error::internal_error(format!( + "part checksum was not computed correctly, got: {:?}", + checksum + ))) + } + } + Ok(()) + } + fn finalize(self) -> ChecksumValue { + match self { + Self::FullObjectCrc(algo, value) => match (algo, value) { + (CrcAlgorithm::Crc32IsoHdlc, Some(v)) => { + ChecksumValue::Crc32(u32::to_be_bytes(v as u32)) + } + (CrcAlgorithm::Crc32Iscsi, Some(v)) => { + ChecksumValue::Crc32c(u32::to_be_bytes(v as u32)) + } + (CrcAlgorithm::Crc64Nvme, Some(v)) => ChecksumValue::Crc64Nvme(u64::to_be_bytes(v)), + _ => unreachable!(), + }, + Self::CompositeCrc(algo, crc) => match algo { + ChecksumAlgorithm::Crc32 => { + ChecksumValue::Crc32(u32::to_be_bytes(crc.finalize() as u32)) + } + ChecksumAlgorithm::Crc32c => { + ChecksumValue::Crc32c(u32::to_be_bytes(crc.finalize() as u32)) + } + _ => unreachable!(), + }, + Self::CompositeSha1(sha1) => { + ChecksumValue::Sha1(sha1.finalize()[..].try_into().unwrap()) + } + Self::CompositeSha256(sha256) => { + ChecksumValue::Sha256(sha256.finalize()[..].try_into().unwrap()) + } + } + } +} diff --git a/src/garage/Cargo.toml b/src/garage/Cargo.toml index 3d0734b4..5bcb2cd2 100644 --- a/src/garage/Cargo.toml +++ b/src/garage/Cargo.toml @@ -79,7 +79,7 @@ static_init.workspace = true assert-json-diff.workspace = true serde_json.workspace = true base64.workspace = true -crc32fast.workspace = true +crc-fast.workspace = true k2v-client.workspace = true diff --git a/src/garage/tests/s3/streaming_signature.rs b/src/garage/tests/s3/streaming_signature.rs index a86feefc..abd4f1ec 100644 --- a/src/garage/tests/s3/streaming_signature.rs +++ b/src/garage/tests/s3/streaming_signature.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use base64::prelude::*; -use crc32fast::Hasher as Crc32; +use crc_fast::{checksum as crc_checksum, CrcAlgorithm}; use crate::common; use crate::common::ext::CommandExt; @@ -69,9 +69,8 @@ async fn test_putobject_streaming() { { let etag = "\"46cf18a9b447991b450cad3facf5937e\""; - let mut crc32 = Crc32::new(); - crc32.update(&BODY[..]); - let crc32 = BASE64_STANDARD.encode(&u32::to_be_bytes(crc32.finalize())[..]); + let crc32 = crc_checksum(CrcAlgorithm::Crc32IsoHdlc, &BODY[..]) as u32; + let crc32 = BASE64_STANDARD.encode(&u32::to_be_bytes(crc32)[..]); let mut headers = HashMap::new(); headers.insert("x-amz-checksum-crc32".to_owned(), crc32.clone()); @@ -129,7 +128,8 @@ async fn test_putobject_streaming_unsigned_trailer() { let mut headers = HashMap::new(); headers.insert("content-type".to_owned(), content_type.to_owned()); - let empty_crc32 = BASE64_STANDARD.encode(&u32::to_be_bytes(Crc32::new().finalize())[..]); + let empty_crc32 = crc_checksum(CrcAlgorithm::Crc32IsoHdlc, &[]) as u32; + let empty_crc32 = BASE64_STANDARD.encode(&u32::to_be_bytes(empty_crc32)[..]); let res = ctx .custom_request @@ -180,9 +180,8 @@ async fn test_putobject_streaming_unsigned_trailer() { { let etag = "\"46cf18a9b447991b450cad3facf5937e\""; - let mut crc32 = Crc32::new(); - crc32.update(&BODY[..]); - let crc32 = BASE64_STANDARD.encode(&u32::to_be_bytes(crc32.finalize())[..]); + let crc32 = crc_checksum(CrcAlgorithm::Crc32IsoHdlc, &BODY[..]) as u32; + let crc32 = BASE64_STANDARD.encode(&u32::to_be_bytes(crc32)[..]); // try sending with wrong crc32, check that it fails let err_res = ctx