diff --git a/Cargo.toml b/Cargo.toml index 2979798..b38ab72 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,6 @@ std = [] [dependencies] aead = "0.5" aes-gcm = "0.10" -byteorder = { version = "1.4", default-features = false } chacha20poly1305 = "0.10" generic-array = { version = "0.14", default-features = false } digest = "0.10" diff --git a/src/aead.rs b/src/aead.rs index 2f3d76d..3f0958d 100644 --- a/src/aead.rs +++ b/src/aead.rs @@ -4,14 +4,13 @@ use crate::{ kdf::{Kdf as KdfTrait, LabeledExpand, SimpleHkdf}, kem::Kem as KemTrait, setup::ExporterSecret, - util::{enforce_equal_len, enforce_outbuf_len, full_suite_id, FullSuiteId}, + util::{enforce_equal_len, enforce_outbuf_len, full_suite_id, write_u64_be, FullSuiteId}, Deserializable, HpkeError, Serializable, }; use core::{default::Default, marker::PhantomData}; use aead::{AeadCore as BaseAeadCore, AeadInPlace as BaseAeadInPlace, KeyInit as BaseKeyInit}; -use byteorder::{BigEndian, ByteOrder}; use generic_array::GenericArray; use zeroize::Zeroize; @@ -113,7 +112,7 @@ fn mix_nonce(base_nonce: &AeadNonce, seq: &Seq) -> AeadNonce { // because this is a big-endian number. let seq_size = core::mem::size_of::(); let nonce_size = base_nonce.0.len(); - BigEndian::write_u64(&mut seq_buf.0[nonce_size - seq_size..], seq.0); + write_u64_be(&mut seq_buf.0[nonce_size - seq_size..], seq.0); // XOR the base nonce bytes with the sequence bytes let new_nonce_iter = base_nonce diff --git a/src/kdf.rs b/src/kdf.rs index 2309f2a..e10ecd1 100644 --- a/src/kdf.rs +++ b/src/kdf.rs @@ -1,6 +1,7 @@ //! Traits and structs for key derivation functions -use byteorder::{BigEndian, ByteOrder}; +use crate::util::write_u16_be; + use digest::{core_api::BlockSizeUser, Digest, OutputSizeUser}; use generic_array::GenericArray; use hmac::SimpleHmac; @@ -154,7 +155,7 @@ where // Encode the output length in the info string let mut len_buf = [0u8; 2]; - BigEndian::write_u16(&mut len_buf, out.len() as u16); + write_u16_be(&mut len_buf, out.len() as u16); // Call HKDF-Expand() with the info string set to the concatenation of all of the above let labeled_info = [&len_buf, VERSION_LABEL, suite_id, label, info]; diff --git a/src/util.rs b/src/util.rs index 6c3abe4..30957d7 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,7 +1,5 @@ use crate::{aead::Aead, kdf::Kdf as KdfTrait, kem::Kem as KemTrait, HpkeError, Serializable}; -use byteorder::{BigEndian, ByteOrder}; - /// Represents a ciphersuite context. That's "KEMXX", where `XX` is the KEM ID pub(crate) type KemSuiteId = [u8; 5]; @@ -9,6 +7,28 @@ pub(crate) type KemSuiteId = [u8; 5]; /// KDF ID, and `ZZ` is the AEAD ID pub(crate) type FullSuiteId = [u8; 10]; +/// Writes a u16 to a bytestring in big-endian order. `buf.len()` MUST be 2 +#[rustfmt::skip] +pub(crate) fn write_u16_be(buf: &mut [u8], n: u16) { + assert_eq!(buf.len(), 2); + buf[0] = ((n & 0xff00) >> 8) as u8; + buf[1] = (n & 0x00ff) as u8; +} + +/// Writes a u64 to a bytestring in big-endian order. `buf.len()` MUST be 8 +#[rustfmt::skip] +pub(crate) fn write_u64_be(buf: &mut [u8], n: u64) { + assert_eq!(buf.len(), 8); + buf[0] = ((n & 0xff00000000000000) >> 56) as u8; + buf[1] = ((n & 0x00ff000000000000) >> 48) as u8; + buf[2] = ((n & 0x0000ff0000000000) >> 40) as u8; + buf[3] = ((n & 0x000000ff00000000) >> 32) as u8; + buf[4] = ((n & 0x00000000ff000000) >> 24) as u8; + buf[5] = ((n & 0x0000000000ff0000) >> 16) as u8; + buf[6] = ((n & 0x000000000000ff00) >> 8) as u8; + buf[7] = (n & 0x00000000000000ff) as u8; +} + // RFC 9180 ยง5.1 // suite_id = concat( // "HPKE", @@ -28,9 +48,9 @@ where let mut suite_id = *b"HPKEXXYYZZ"; // Write the ciphersuite identifiers to the buffer. Forgive the explicit indexing. - BigEndian::write_u16(&mut suite_id[4..6], Kem::KEM_ID); - BigEndian::write_u16(&mut suite_id[6..8], Kdf::KDF_ID); - BigEndian::write_u16(&mut suite_id[8..10], A::AEAD_ID); + write_u16_be(&mut suite_id[4..6], Kem::KEM_ID); + write_u16_be(&mut suite_id[6..8], Kdf::KDF_ID); + write_u16_be(&mut suite_id[8..10], A::AEAD_ID); suite_id } @@ -44,7 +64,7 @@ pub(crate) fn kem_suite_id() -> KemSuiteId { let mut suite_id = *b"KEMXX"; // Write the KEM ID to the buffer. Forgive the explicit indexing. - BigEndian::write_u16(&mut suite_id[3..5], Kem::KEM_ID); + write_u16_be(&mut suite_id[3..5], Kem::KEM_ID); suite_id }