summaryrefslogtreecommitdiffstats
path: root/third_party/rust/neqo-crypto/src/aead.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /third_party/rust/neqo-crypto/src/aead.rs
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/neqo-crypto/src/aead.rs')
-rw-r--r--third_party/rust/neqo-crypto/src/aead.rs175
1 files changed, 175 insertions, 0 deletions
diff --git a/third_party/rust/neqo-crypto/src/aead.rs b/third_party/rust/neqo-crypto/src/aead.rs
new file mode 100644
index 0000000000..a2f009a403
--- /dev/null
+++ b/third_party/rust/neqo-crypto/src/aead.rs
@@ -0,0 +1,175 @@
+// 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::{
+ convert::{TryFrom, TryInto},
+ fmt,
+ ops::{Deref, DerefMut},
+ os::raw::{c_char, c_uint},
+ ptr::null_mut,
+};
+
+use crate::{
+ constants::{Cipher, Version},
+ err::Res,
+ experimental_api,
+ p11::{PK11SymKey, SymKey},
+ scoped_ptr,
+ ssl::{self, PRUint16, PRUint64, PRUint8, SSLAeadContext},
+};
+
+experimental_api!(SSL_MakeAead(
+ version: PRUint16,
+ cipher: PRUint16,
+ secret: *mut PK11SymKey,
+ label_prefix: *const c_char,
+ label_prefix_len: c_uint,
+ ctx: *mut *mut SSLAeadContext,
+));
+experimental_api!(SSL_AeadEncrypt(
+ ctx: *const SSLAeadContext,
+ counter: PRUint64,
+ aad: *const PRUint8,
+ aad_len: c_uint,
+ input: *const PRUint8,
+ input_len: c_uint,
+ output: *const PRUint8,
+ output_len: *mut c_uint,
+ max_output: c_uint
+));
+experimental_api!(SSL_AeadDecrypt(
+ ctx: *const SSLAeadContext,
+ counter: PRUint64,
+ aad: *const PRUint8,
+ aad_len: c_uint,
+ input: *const PRUint8,
+ input_len: c_uint,
+ output: *const PRUint8,
+ output_len: *mut c_uint,
+ max_output: c_uint
+));
+experimental_api!(SSL_DestroyAead(ctx: *mut SSLAeadContext));
+scoped_ptr!(AeadContext, SSLAeadContext, SSL_DestroyAead);
+
+pub struct RealAead {
+ ctx: AeadContext,
+}
+
+impl RealAead {
+ /// Create a new AEAD based on the indicated TLS version and cipher suite.
+ ///
+ /// # Errors
+ ///
+ /// Returns `Error` when the supporting NSS functions fail.
+ pub fn new(
+ _fuzzing: bool,
+ version: Version,
+ cipher: Cipher,
+ secret: &SymKey,
+ prefix: &str,
+ ) -> Res<Self> {
+ let s: *mut PK11SymKey = **secret;
+ unsafe { Self::from_raw(version, cipher, s, prefix) }
+ }
+
+ #[must_use]
+ #[allow(clippy::unused_self)]
+ pub fn expansion(&self) -> usize {
+ 16
+ }
+
+ unsafe fn from_raw(
+ version: Version,
+ cipher: Cipher,
+ secret: *mut PK11SymKey,
+ prefix: &str,
+ ) -> Res<Self> {
+ let p = prefix.as_bytes();
+ let mut ctx: *mut ssl::SSLAeadContext = null_mut();
+ SSL_MakeAead(
+ version,
+ cipher,
+ secret,
+ p.as_ptr().cast(),
+ c_uint::try_from(p.len())?,
+ &mut ctx,
+ )?;
+ Ok(Self {
+ ctx: AeadContext::from_ptr(ctx)?,
+ })
+ }
+
+ /// Encrypt a plaintext.
+ ///
+ /// The space provided in `output` needs to be larger than `input` by
+ /// the value provided in `Aead::expansion`.
+ ///
+ /// # Errors
+ ///
+ /// If the input can't be protected or any input is too large for NSS.
+ pub fn encrypt<'a>(
+ &self,
+ count: u64,
+ aad: &[u8],
+ input: &[u8],
+ output: &'a mut [u8],
+ ) -> Res<&'a [u8]> {
+ let mut l: c_uint = 0;
+ unsafe {
+ SSL_AeadEncrypt(
+ *self.ctx,
+ count,
+ aad.as_ptr(),
+ c_uint::try_from(aad.len())?,
+ input.as_ptr(),
+ c_uint::try_from(input.len())?,
+ output.as_mut_ptr(),
+ &mut l,
+ c_uint::try_from(output.len())?,
+ )
+ }?;
+ Ok(&output[0..(l.try_into()?)])
+ }
+
+ /// Decrypt a ciphertext.
+ ///
+ /// Note that NSS insists upon having extra space available for decryption, so
+ /// the buffer for `output` should be the same length as `input`, even though
+ /// the final result will be shorter.
+ ///
+ /// # Errors
+ ///
+ /// If the input isn't authenticated or any input is too large for NSS.
+ pub fn decrypt<'a>(
+ &self,
+ count: u64,
+ aad: &[u8],
+ input: &[u8],
+ output: &'a mut [u8],
+ ) -> Res<&'a [u8]> {
+ let mut l: c_uint = 0;
+ unsafe {
+ SSL_AeadDecrypt(
+ *self.ctx,
+ count,
+ aad.as_ptr(),
+ c_uint::try_from(aad.len())?,
+ input.as_ptr(),
+ c_uint::try_from(input.len())?,
+ output.as_mut_ptr(),
+ &mut l,
+ c_uint::try_from(output.len())?,
+ )
+ }?;
+ Ok(&output[0..(l.try_into()?)])
+ }
+}
+
+impl fmt::Debug for RealAead {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "[AEAD Context]")
+ }
+}