Skip to content
2 changes: 1 addition & 1 deletion .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ jobs:

misc_checks:
name: miscellaneous
runs-on: ubuntu-latest
runs-on: macos-latest
steps:
- uses: Avarok-Cybersecurity/gh-actions-deps@master
# - name: Install Valgrind
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ enum_primitive = { default-features = false, version = "0.1.1" }
aes-gcm = { version = "0.10.3", default-features = false }
chacha20poly1305 = { version = "0.10.1", default-features = false }
log = { default-features = false, version = "0.4.17" }
strum = { version = "0.26.2", default-features = false }
strum = { version = "0.27.1", default-features = false }
strum_macros = { version = "0.27.1", default-features = false }
sha3 = { version = "0.10", default-features = false }
kyber-pke = { version = "0.5.0", default-features = false }
packed_struct = { version = "0.10.1" }
Expand Down
20 changes: 5 additions & 15 deletions Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,23 +80,13 @@ command = "choco"
args = ["install", "-y", "llvm", "openssl", "cmake"]

[tasks.docs]
script_runner = "@rust"
env = { "CARGO_MAKE_RUST_SCRIPT_PROVIDER" = "cargo-script" }
script_runner = "@duckscript"
dependencies = ["docs-html"]
script = '''
//! ```cargo
fn main() {
std::fs::copy(
"./resources/avarok.png",
"./target/doc/citadel_sdk/avarok.png",
)
.expect("Failed to copy crate logo when building documentation.");
std::fs::copy(
"./resources/favicon.png",
"./target/doc/citadel_sdk/favicon.png",
)
.expect("Failed to copy crate favicon when building documentation.");
}
# Copy logo
cp ./resources/avarok.png ./target/doc/citadel_sdk/avarok.png
# Copy favicon
cp ./resources/favicon.png ./target/doc/citadel_sdk/favicon.png
'''

[tasks.install-llvm-tools]
Expand Down
7 changes: 5 additions & 2 deletions citadel_crypt/src/scramble/crypt_splitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ where

debug_assert_ne!(cfg.last_plaintext_wave_length, 0);

if msg_pqc.params.encryption_algorithm != EncryptionAlgorithm::Kyber
if msg_pqc.params.encryption_algorithm != EncryptionAlgorithm::KyberHybrid
&& matches!(&transfer_type, TransferType::FileTransfer)
{
debug_assert_eq!(cfg.packets_needed, packets.len() as _);
Expand Down Expand Up @@ -430,6 +430,7 @@ pub struct GroupReceiver {
packets_received_order: BitVec,
waves_received: BitVec,
packets_needed: usize,
packets_received: usize,
last_packet_recv_time: Instant,
max_payload_size: usize,
/// All packets will necessarily be the same size, except for the last packet (although, it is possible for it to be the same size)
Expand Down Expand Up @@ -623,6 +624,7 @@ impl GroupReceiver {
unified_plaintext_slab,
temp_wave_store,
packets_received_order,
packets_received: 0,
packets_needed: cfg.packets_needed as usize,
last_packet_recv_time,
max_payload_size: cfg.max_payload_size as usize,
Expand Down Expand Up @@ -658,6 +660,8 @@ impl GroupReceiver {
};

if !is_received {
self.packets_received += 1;
log::trace!(target: "citadel", "[FILE TRANSFER] Packet {}/{} received", self.packets_received, self.packets_needed);
// Now, take the ciphertext and place it into the buffer
let wave_store = self.temp_wave_store.get_mut(&wave_id);

Expand Down Expand Up @@ -847,7 +851,6 @@ impl GroupReceiver {
plaintext: &[u8],
max_plaintext_wave_length: usize,
) -> Range<usize> {
// TODO!!!!! remove unwrap
let plaintext_length = plaintext.len();
let start_idx = wave_id as usize * max_plaintext_wave_length;
let end_idx = start_idx + plaintext_length;
Expand Down
16 changes: 8 additions & 8 deletions citadel_crypt/tests/primary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ mod tests {
SigAlgorithm::None
)]
#[case(
EncryptionAlgorithm::Kyber,
EncryptionAlgorithm::KyberHybrid,
KemAlgorithm::Kyber,
SigAlgorithm::Falcon1024
)]
Expand Down Expand Up @@ -524,7 +524,7 @@ mod tests {
SigAlgorithm::None
)]
#[case(
EncryptionAlgorithm::Kyber,
EncryptionAlgorithm::KyberHybrid,
KemAlgorithm::Kyber,
SigAlgorithm::Falcon1024
)]
Expand Down Expand Up @@ -618,7 +618,7 @@ mod tests {
SigAlgorithm::None
)]
#[case(
EncryptionAlgorithm::Kyber,
EncryptionAlgorithm::KyberHybrid,
KemAlgorithm::Kyber,
SigAlgorithm::Falcon1024
)]
Expand Down Expand Up @@ -660,7 +660,7 @@ mod tests {
SigAlgorithm::None
)]
#[case(
EncryptionAlgorithm::Kyber,
EncryptionAlgorithm::KyberHybrid,
KemAlgorithm::Kyber,
SigAlgorithm::Falcon1024
)]
Expand Down Expand Up @@ -810,7 +810,7 @@ mod tests {
SigAlgorithm::None
)]
#[case(
EncryptionAlgorithm::Kyber,
EncryptionAlgorithm::KyberHybrid,
KemAlgorithm::Kyber,
SigAlgorithm::Falcon1024
)]
Expand Down Expand Up @@ -852,7 +852,7 @@ mod tests {
SigAlgorithm::None
)]
#[case(
EncryptionAlgorithm::Kyber,
EncryptionAlgorithm::KyberHybrid,
KemAlgorithm::Kyber,
SigAlgorithm::Falcon1024
)]
Expand Down Expand Up @@ -1000,7 +1000,7 @@ mod tests {
SigAlgorithm::None
)]
#[case(
EncryptionAlgorithm::Kyber,
EncryptionAlgorithm::KyberHybrid,
KemAlgorithm::Kyber,
SigAlgorithm::Falcon1024
)]
Expand Down Expand Up @@ -1059,7 +1059,7 @@ mod tests {
SigAlgorithm::None
)]
#[case(
EncryptionAlgorithm::Kyber,
EncryptionAlgorithm::KyberHybrid,
KemAlgorithm::Kyber,
SigAlgorithm::Falcon1024
)]
Expand Down
2 changes: 1 addition & 1 deletion citadel_pqcrypto/src/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ pub(crate) fn keys_to_aead_store(
)
}

EncryptionAlgorithm::Kyber => {
EncryptionAlgorithm::KyberHybrid => {
let kem_alg = params.kem_algorithm;
let sig_alg = params.sig_algorithm;

Expand Down
8 changes: 4 additions & 4 deletions citadel_pqcrypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ impl PostQuantumContainer {
}

fn get_decryption_key(&self) -> Option<&dyn AeadModule> {
if let EncryptionAlgorithm::Kyber = self.params.encryption_algorithm {
if let EncryptionAlgorithm::KyberHybrid = self.params.encryption_algorithm {
// use multi-modal asymmetric + symmetric ratcheted encryption
// alice's key is in alice, bob's key is in bob. Thus, use encryption key
self.get_encryption_key()
Expand Down Expand Up @@ -1145,7 +1145,7 @@ impl EncryptionAlgorithmExt for EncryptionAlgorithm {
match self {
Self::AES_GCM_256 => AES_GCM_NONCE_LENGTH_BYTES,
Self::ChaCha20Poly_1305 => CHA_CHA_NONCE_LENGTH_BYTES,
Self::Kyber => KYBER_NONCE_LENGTH_BYTES,
Self::KyberHybrid => KYBER_NONCE_LENGTH_BYTES,
Self::Ascon80pq => ASCON_NONCE_LENGTH_BYTES,
}
}
Expand All @@ -1159,7 +1159,7 @@ impl EncryptionAlgorithmExt for EncryptionAlgorithm {
Self::ChaCha20Poly_1305 => plaintext_length + SYMMETRIC_CIPHER_OVERHEAD,
Self::Ascon80pq => plaintext_length + SYMMETRIC_CIPHER_OVERHEAD,
// Add 32 for internal apendees
Self::Kyber => {
Self::KyberHybrid => {
const LENGTH_FIELD: usize = 8;
let signature_len = functions::signature_bytes();

Expand All @@ -1183,7 +1183,7 @@ impl EncryptionAlgorithmExt for EncryptionAlgorithm {
Self::AES_GCM_256 => Some(ciphertext.len() - 16),
Self::ChaCha20Poly_1305 => Some(ciphertext.len() - 16),
Self::Ascon80pq => Some(ciphertext.len() - 16),
Self::Kyber => kyber_pke::plaintext_len(ciphertext),
Self::KyberHybrid => kyber_pke::plaintext_len(ciphertext),
}
}
}
8 changes: 4 additions & 4 deletions citadel_pqcrypto/tests/primary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ mod tests {
const HEADER_LEN: usize = 50;

let kem_algorithm = KemAlgorithm::Kyber;
let encryption_algorithm = EncryptionAlgorithm::Kyber;
let encryption_algorithm = EncryptionAlgorithm::KyberHybrid;
let signature_algorithm = SigAlgorithm::Falcon1024;

let (alice_container, bob_container) = gen(
Expand Down Expand Up @@ -415,7 +415,7 @@ mod tests {
if algorithm == KemAlgorithm::Kyber {
run::<Vec<u8>>(
algorithm.as_u8(),
EncryptionAlgorithm::Kyber,
EncryptionAlgorithm::KyberHybrid,
SigAlgorithm::Falcon1024,
&PRE_SHARED_KEYS,
&PRE_SHARED_KEYS,
Expand All @@ -430,7 +430,7 @@ mod tests {
citadel_logging::setup_log();
run::<Vec<u8>>(
KemAlgorithm::Kyber.as_u8(),
EncryptionAlgorithm::Kyber,
EncryptionAlgorithm::KyberHybrid,
SigAlgorithm::Falcon1024,
&PRE_SHARED_KEYS,
&PRE_SHARED_KEYS,
Expand Down Expand Up @@ -572,7 +572,7 @@ mod tests {

#[test]
fn test_bad_crypto_params() {
let bad_params = EncryptionAlgorithm::Kyber + KemAlgorithm::Kyber;
let bad_params = EncryptionAlgorithm::KyberHybrid + KemAlgorithm::Kyber;
assert!(validate_crypto_params(&bad_params).is_err());
}
}
8 changes: 8 additions & 0 deletions citadel_proto/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

use crate::prelude::NodeRequest;
use citadel_crypt::misc::CryptError;
use citadel_crypt::ratchets::Ratchet;
use citadel_io::tokio::sync::mpsc::error::SendError;
use citadel_user::misc::AccountError;
use std::error::Error;
Expand Down Expand Up @@ -131,6 +132,13 @@ impl<T> From<citadel_io::tokio::sync::mpsc::error::SendError<T>> for NetworkErro
}
}

// Specific implementation for Box<SendError<NodeResult<R>>>
impl<R: Ratchet + 'static> From<Box<SendError<crate::proto::node_result::NodeResult<R>>>> for NetworkError {
fn from(err: Box<SendError<crate::proto::node_result::NodeResult<R>>>) -> Self {
NetworkError::Generic(err.to_string())
}
}

impl From<AccountError> for NetworkError {
fn from(err: AccountError) -> Self {
NetworkError::Generic(err.into_string())
Expand Down
27 changes: 19 additions & 8 deletions citadel_proto/src/proto/misc/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ pub fn safe_split_stream<S: AsyncWrite + AsyncRead + Unpin + ContextRequirements
#[allow(variant_size_differences)]
pub enum GenericNetworkStream {
Tcp(TcpStream),
Tls(citadel_wire::exports::tokio_rustls::TlsStream<TcpStream>),
Tls(Box<citadel_wire::exports::tokio_rustls::TlsStream<TcpStream>>),
// local addr is first addr, remote addr is final addr
Quic(
SendStream,
Expand Down Expand Up @@ -307,14 +307,25 @@ impl GenericNetworkListener {

let future = async move {
loop {
let (stream, addr) = listener
let next_connection = listener
.next()
.await
.ok_or_else(|| generic_error("TLS listener died"))??;
log::trace!(target: "citadel", "Received raw TLS stream from {:?}: {:?}", addr, stream);
send.send(Ok((GenericNetworkStream::Tls(stream.into()), addr)))
.await
.map_err(|err| generic_error(err.to_string()))?;
.ok_or_else(|| generic_error("TLS listener died"))?;

match next_connection {
Ok((stream, addr)) => {
log::trace!(target: "citadel", "Received raw TLS stream from {:?}: {:?}", addr, stream);
if let Err(err) = send
.send(Ok((GenericNetworkStream::Tls(Box::new(citadel_wire::exports::tokio_rustls::TlsStream::Server(stream))), addr)))
.await
{
log::error!(target: "citadel", "Failed to send TLS handshake packet: {err:?}");
}
}
Err(err) => {
log::debug!(target: "citadel", "TLS Stream died: {err:?}")
}
}
}
};

Expand Down Expand Up @@ -485,7 +496,7 @@ impl QuicListener {
log::trace!(target: "citadel", "RECV {:?} from {:?}", &conn, addr);
send.send(Ok((conn, tx, rx, addr, endpoint.clone())))
.await
.map_err(|err| generic_error(err.to_string()))
.map_err(generic_error)
})
.await?;
}
Expand Down
2 changes: 1 addition & 1 deletion citadel_proto/src/proto/misc/udp_internal_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ impl QuicUdpSocketConnector {
yield conn_stream.read_datagram()
.await
.map(|packet| (BytesMut::from(&packet[..]), addr))
.map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err.to_string()))?;
.map_err(|err| std::io::Error::other(err.to_string()))?;
}
});

Expand Down
5 changes: 2 additions & 3 deletions citadel_proto/src/proto/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,8 +375,7 @@ impl<R: Ratchet> CitadelNode<R> {
match underlying_proto {
ServerUnderlyingProtocol::Tcp(Some(listener)) => {
let listener = listener.lock().take().ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::Other,
std::io::Error::other(
"TCP listener already taken",
)
})?;
Expand Down Expand Up @@ -566,7 +565,7 @@ impl<R: Ratchet> CitadelNode<R> {
)
.await
.map_err(|err| io::Error::new(io::ErrorKind::ConnectionRefused, err))?;
Ok((GenericNetworkStream::Tls(stream.into()), None))
Ok((GenericNetworkStream::Tls(Box::new(citadel_wire::exports::tokio_rustls::TlsStream::Client(stream))), None))
}
FirstPacket::Quic {
domain,
Expand Down
33 changes: 1 addition & 32 deletions citadel_proto/src/proto/node_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,10 @@ use crate::auth::AuthenticationRequest;
use crate::prelude::{GroupBroadcast, PeerSignal, VirtualTargetType};
use crate::proto::state_container::VirtualConnectionType;
use citadel_crypt::scramble::streaming_crypt_scrambler::ObjectSource;
use citadel_types::crypto::SecurityLevel;
use citadel_types::crypto::{PreSharedKey, SecurityLevel};
use citadel_types::proto::TransferType;
use citadel_types::proto::{ConnectMode, SessionSecuritySettings, UdpMode};
use citadel_user::auth::proposed_credentials::ProposedCredentials;
use serde::{Deserialize, Serialize};
use sha3::Digest;
use std::fmt::{Debug, Formatter};
use std::net::SocketAddr;
use std::path::PathBuf;
Expand Down Expand Up @@ -160,32 +158,3 @@ impl Debug for NodeRequest {
write!(f, "NodeRequest")
}
}

#[derive(Default, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
pub struct PreSharedKey {
passwords: Vec<Vec<u8>>,
}

impl PreSharedKey {
/// Adds a password to the session password list. Both connecting nodes
/// must have matching passwords in order to establish a connection.
/// Note: The password is hashed using SHA-256 before being added to the list to increase security.
pub fn add_password<T: AsRef<[u8]>>(mut self, password: T) -> Self {
let mut hasher = sha3::Sha3_256::default();
hasher.update(password.as_ref());
self.passwords.push(hasher.finalize().to_vec());
self
}
}

impl AsRef<[Vec<u8>]> for PreSharedKey {
fn as_ref(&self) -> &[Vec<u8>] {
&self.passwords
}
}

impl<T: AsRef<[u8]>> From<T> for PreSharedKey {
fn from(password: T) -> Self {
PreSharedKey::default().add_password(password)
}
}
Loading
Loading