noxtls-platform 0.2.10

Internal implementation crate for noxtls: time, RNG, and storage abstractions.
Documentation
// Copyright (c) 2019-2026, Argenox Technologies LLC
// All rights reserved.
//
// SPDX-License-Identifier: GPL-2.0-only OR LicenseRef-Argenox-Commercial-License

#![cfg_attr(not(feature = "std"), no_std)]
#![forbid(unsafe_code)]

//! Portable hooks for wall time, monotonic timers, and entropy suitable for embedded TLS stacks.

#[cfg(not(feature = "std"))]
extern crate alloc;

pub mod entropy;
pub mod time;

#[cfg(feature = "rand-core")]
pub use entropy::RandCoreEntropy;
#[cfg(feature = "std")]
pub use entropy::StdEntropy;
pub use entropy::{EntropySource, TestEntropySource};
#[cfg(feature = "std")]
pub use time::StdTimeSource;
pub use time::{noxtls_format_unix_secs_as_generalized_time, StaticTimeSource, TimeSource};

/// Millisecond-resolution opaque timestamp used by DTLS flight and retransmit timers.
pub type MonotonicMillis = u64;

/// PKIX GeneralizedTime string (`YYYYMMDDhhmmssZ`).
#[cfg(feature = "std")]
pub type GeneralizedTimeString = std::string::String;
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub type GeneralizedTimeString = alloc::string::String;
#[cfg(not(any(feature = "std", feature = "alloc")))]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct GeneralizedTimeString([u8; 15]);

#[cfg(not(any(feature = "std", feature = "alloc")))]
impl GeneralizedTimeString {
    #[must_use]
    pub(crate) fn from_bytes(bytes: [u8; 15]) -> Self {
        Self(bytes)
    }

    #[must_use]
    pub fn as_str(&self) -> &str {
        core::str::from_utf8(&self.0).expect("GeneralizedTimeString contains only ASCII digits")
    }
}

#[cfg(not(any(feature = "std", feature = "alloc")))]
impl AsRef<str> for GeneralizedTimeString {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

#[cfg(not(any(feature = "std", feature = "alloc")))]
impl core::fmt::Display for GeneralizedTimeString {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        f.write_str(self.as_str())
    }
}

/// Reads whole seconds since the Unix epoch using the system clock when `std` is enabled.
#[cfg(feature = "std")]
#[must_use]
pub fn noxtls_unix_timestamp_secs() -> u64 {
    use std::time::{SystemTime, UNIX_EPOCH};
    SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .map_or(0, |d| d.as_secs())
}