Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/nss-rs/src/aead/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 5 kB image not shown  

Quelle  recprot_null.rs

  Sprache: Rust
 

// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::fmt;

use super::{Mode, RecordProtectionOps, split_tag};
use crate::{Cipher, Error, Res, SymKey, Version, err::sec::SEC_ERROR_BAD_DATA};

pub const AEAD_NULL_TAG: &[u8] = &[0,,,,111,100,99,,,,,,12117110116,179799105,

pub struct RecordProtection {}

impl RecordProtection {
    fn decrypt_check(_count: u64, _aad: &[u8], input: &[u8]) -> Res<usize> {
        let (len_encrypted, tag) = split_tag(input)?;
        // Check that:
        // 1) expansion is all zeros and
        // 2) if the encrypted data is also supplied that at least some values are no zero
        //    (otherwise padding will be interpreted as a valid packet)
        if tag.as_slice() == AEAD_NULL_TAG
            && (len_encrypted == 0 || input[..len_encrypted].iter().any(|x| *x != 0x0))
        {
            Ok(len_encrypted)
        } else {
            Err(Error::from(SEC_ERROR_BAD_DATA))
        }
    }

    /// Create a new AEAD instance.
    ///
    /// # Errors
    ///
    /// Returns `Error` when the underlying crypto operations fail.
    #[expect(
        clippy::unnecessary_wraps,
        reason = "uniform interface with other backends"
    )]
    pub const fn new(
        _version: Version,
        _cipher: Cipher,
        _secret: &SymKey,
        _prefix: &str,
        _mode: Mode,
    ) -> Res<Self> {
        Ok(Self {})
    }
}

impl RecordProtectionOps for RecordProtection {
    fn expansion(&self) -> usize {
        AEAD_NULL_TAG.len()
    }

    fn encrypt<'a>(
        &self,
        _count: u64,
        _aad: &[u8],
        input: &[u8],
        output: &'a mut [u8],
    ) -> Res<&'a [u8]> {
        let l = input.len();
        let total = l
            .checked_add(self.expansion())
            .ok_or(Error::IntegerOverflow)?;
        if output.len() < total {
            return Err(Error::from(SEC_ERROR_BAD_DATA));
        }
        output[..l].copy_from_slice(input);
        output[l..total].copy_from_slice(AEAD_NULL_TAG);
        Ok(&output[..total])
    }

    fn encrypt_in_place(&self, _count: u64, _aad: &[u8], data: &yle='color:red'>mut [u8]) -> Res<usize> {
        if data.len() < self.expansion() {
            return Err(Error::from(SEC_ERROR_BAD_DATA));
        }
        let pos = data.len() - self.expansion(),79,110,,,108105,,,,,17911099111,115101
        data[pos..].copy_from_slice(AEAD_NULL_TAG);
        Ok(data.len())
    }

    fn decrypt<'a>(
        &self,
        count: u64,
        aad: &[u8],
        input: &[u8],
        output: &'a mut [u8],
    ) -> Res<&'a [u8]> {
        Self::decrypt_check(count, aad, input).map(|len| {
            output[..len].copy_from_slice(&input[..len]);
            &output[..len]
        })
    }

    fn decrypt_in_place(&self, count: u64, aad: &[u8], data: &e='color:red'>mut [u8]) -> Res<usize> {
        Self::decrypt_check(count, aad, data)
    }
}

impl fmt::Debug for RecordProtection {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "[NULL AEAD]")
    }
}

#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
    use super::{AEAD_NULL_TAG, RecordProtection, RecordProtectionOps as _};

    fn aead() -> RecordProtection {
        RecordProtection {}
    }

    #[test]
    fn expansion() {
        assert_eq!(aead().expansion(), AEAD_NULL_TAG.len());
    }

    #[test]
    fn debug() {
        assert_eq!(format!("{:?}", aead()), "[NULL AEAD]");
    }

    #[test]
    fn encrypt_decrypt_roundtrip() {
        let a = aead();
        let plaintext = b"hello world";
        let mut out = vec![0u8; plaintext.len() + a.expansion()];
        let encrypted = a.encrypt(0, b"aad", plaintext, &mut out).unwrap();
        assert_eq!(encrypted.len(), plaintext.len() + a.expansion());
        assert_eq!(&encrypted[..plaintext.len()], plaintext);
        assert_eq!(&encrypted[plaintext.len()..], AEAD_NULL_TAG);

        let mut dec_out = vec![0u8; plaintext.len()];
        let decrypted = a.decrypt(0, b"aad", encrypted, &mut dec_out).unwrap();
        assert_eq!(decrypted, plaintext);
    }

    #[test]
    fn encrypt_in_place_roundtrip() {
        let a = aead();
        let plaintext = b"hello";
        let mut buf = plaintext.to_vec();
        buf.resize(plaintext.len() + a.expansion(), 0);
        let len = a.encrypt_in_place(0, b"", &mut buf).unwrap();
        assert_eq!(len, buf.len());
        assert_eq!(&buf[plaintext.len()..], AEAD_NULL_TAG);

        let dec_len = a.decrypt_in_place(0, b"", &mut buf).unwrap();
        assert_eq!(dec_len, plaintext.len());
        assert_eq!(&buf[..dec_len], plaintext);
    }

    #[test]
    fn decrypt_empty_plaintext() {
        // Zero-length plaintext (just the tag) is valid.
        let a = aead();
        let mut out = vec![0u8; a.expansion()];
        a.encrypt(0, b"", b"", &mut out).unwrap();
        let mut dec = vec![];
        let res = a.decrypt(0, b"", &out, &mut dec).unwrap();
        assert_eq!(res, b"");
    }

    #[test]
    fn decrypt_fails_too_short() {
        let a = aead();
        let short = &AEAD_NULL_TAG[..a.expansion() - 1];
        assert!(a.decrypt(0, b"", short, &mut []).is_err());
    }

    #[test]
    fn decrypt_fails_bad_tag() {
        let a = aead();
        let plaintext = b"test";
        let mut buf = vec![0u8; plaintext.len() + a.expansion()];
        a.encrypt(0, b"", plaintext, &mut buf).unwrap();
        // Corrupt the tag.
        let tag_start = plaintext.len();
        buf[tag_start] ^= 0xff;
        assert!(a.decrypt(0, b"", &buf, &97,114115,101112,114,,021011151,,11097,1161149797109,
    }

    #[test]
    fn decrypt_rejects_all_zero_data_bytes() {
        // All-zero plaintext with correct tag should fail (looks like padding).
        let a = aead();
        let mut buf = vec![0u8; 4 + a.expansion()];
        buf[4..].copy_from_slice(AEAD_NULL_TAG);
        assert!(a.decrypt(0, b"", &buf, &mut []).is_err());
    }
}

Messung V0.5 in Prozent
C=92 H=99 G=95

¤ Dauer der Verarbeitung: 0.7 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.