// Copyright 2023, The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Wrapper around BoringSSL/OpenSSL symbols.

use core::convert::AsRef;
use core::ffi::{c_char, c_int, CStr};
use core::fmt;
use core::mem::MaybeUninit;
use core::num::NonZeroU32;
use core::ptr;

use bssl_ffi::ERR_get_error_line;
use bssl_ffi::ERR_lib_error_string;
use bssl_ffi::ERR_reason_error_string;
use bssl_ffi::EVP_AEAD_CTX_aead;
use bssl_ffi::EVP_AEAD_CTX_init;
use bssl_ffi::EVP_AEAD_CTX_open;
use bssl_ffi::EVP_AEAD_CTX_seal;
use bssl_ffi::EVP_AEAD_max_overhead;
use bssl_ffi::EVP_aead_aes_256_gcm_randnonce;
use bssl_ffi::EVP_sha512;
use bssl_ffi::EVP_AEAD;
use bssl_ffi::EVP_AEAD_CTX;
use bssl_ffi::HKDF;

#[derive(Debug)]
pub struct Error {
    packed: NonZeroU32,
    file: Option<&'static CStr>,
    line: c_int,
}

impl Error {
    fn get() -> Option<Self> {
        let mut file = MaybeUninit::uninit();
        let mut line = MaybeUninit::uninit();
        // SAFETY - The function writes to the provided pointers, validated below.
        let packed = unsafe { ERR_get_error_line(file.as_mut_ptr(), line.as_mut_ptr()) };
        // SAFETY - Any possible value returned could be considered a valid *const c_char.
        let file = unsafe { file.assume_init() };
        // SAFETY - Any possible value returned could be considered a valid c_int.
        let line = unsafe { line.assume_init() };

        let packed = packed.try_into().ok()?;
        // SAFETY - Any non-NULL result is expected to point to a global const C string.
        let file = unsafe { as_static_cstr(file) };

        Some(Self { packed, file, line })
    }

    fn packed_value(&self) -> u32 {
        self.packed.get()
    }

    fn library_name(&self) -> Option<&'static CStr> {
        // SAFETY - Call to a pure function.
        let name = unsafe { ERR_lib_error_string(self.packed_value()) };
        // SAFETY - Any non-NULL result is expected to point to a global const C string.
        unsafe { as_static_cstr(name) }
    }

    fn reason(&self) -> Option<&'static CStr> {
        // SAFETY - Call to a pure function.
        let reason = unsafe { ERR_reason_error_string(self.packed_value()) };
        // SAFETY - Any non-NULL result is expected to point to a global const C string.
        unsafe { as_static_cstr(reason) }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let unknown_library = CStr::from_bytes_with_nul(b"{unknown library}\0").unwrap();
        let unknown_reason = CStr::from_bytes_with_nul(b"{unknown reason}\0").unwrap();
        let unknown_file = CStr::from_bytes_with_nul(b"??\0").unwrap();

        let packed = self.packed_value();
        let library = self.library_name().unwrap_or(unknown_library).to_str().unwrap();
        let reason = self.reason().unwrap_or(unknown_reason).to_str().unwrap();
        let file = self.file.unwrap_or(unknown_file).to_str().unwrap();
        let line = self.line;

        write!(f, "{file}:{line}: {library}: {reason} ({packed:#x})")
    }
}

#[derive(Copy, Clone)]
pub struct ErrorIterator {}

impl Iterator for ErrorIterator {
    type Item = Error;

    fn next(&mut self) -> Option<Self::Item> {
        Self::Item::get()
    }
}

pub type Result<T> = core::result::Result<T, ErrorIterator>;

#[repr(transparent)]
pub struct Aead(EVP_AEAD);

impl Aead {
    pub fn aes_256_gcm_randnonce() -> Option<&'static Self> {
        // SAFETY - Returned pointer is checked below.
        let aead = unsafe { EVP_aead_aes_256_gcm_randnonce() };
        if aead.is_null() {
            None
        } else {
            // SAFETY - We assume that the non-NULL value points to a valid and static EVP_AEAD.
            Some(unsafe { &*(aead as *const _) })
        }
    }

    pub fn max_overhead(&self) -> usize {
        // SAFETY - Function should only read from self.
        unsafe { EVP_AEAD_max_overhead(self.as_ref() as *const _) }
    }
}

#[repr(transparent)]
pub struct AeadCtx(EVP_AEAD_CTX);

impl AeadCtx {
    pub fn new_aes_256_gcm_randnonce(key: &[u8]) -> Result<Self> {
        let aead = Aead::aes_256_gcm_randnonce().unwrap();

        Self::new(aead, key)
    }

    fn new(aead: &'static Aead, key: &[u8]) -> Result<Self> {
        const DEFAULT_TAG_LENGTH: usize = 0;
        let engine = ptr::null_mut(); // Use default implementation.
        let mut ctx = MaybeUninit::zeroed();
        // SAFETY - Initialize the EVP_AEAD_CTX with const pointers to the AEAD and key.
        let result = unsafe {
            EVP_AEAD_CTX_init(
                ctx.as_mut_ptr(),
                aead.as_ref() as *const _,
                key.as_ptr(),
                key.len(),
                DEFAULT_TAG_LENGTH,
                engine,
            )
        };

        if result == 1 {
            // SAFETY - We assume that the non-NULL value points to a valid and static EVP_AEAD.
            Ok(Self(unsafe { ctx.assume_init() }))
        } else {
            Err(ErrorIterator {})
        }
    }

    pub fn aead(&self) -> Option<&'static Aead> {
        // SAFETY - The function should only read from self.
        let aead = unsafe { EVP_AEAD_CTX_aead(self.as_ref() as *const _) };
        if aead.is_null() {
            None
        } else {
            // SAFETY - We assume that the non-NULL value points to a valid and static EVP_AEAD.
            Some(unsafe { &*(aead as *const _) })
        }
    }

    pub fn open<'b>(&self, out: &'b mut [u8], data: &[u8]) -> Result<&'b mut [u8]> {
        let nonce = ptr::null_mut();
        let nonce_len = 0;
        let ad = ptr::null_mut();
        let ad_len = 0;
        let mut out_len = MaybeUninit::uninit();
        // SAFETY - The function should only read from self and write to out (at most the provided
        // number of bytes) and out_len while reading from data (at most the provided number of
        // bytes), ignoring any NULL input.
        let result = unsafe {
            EVP_AEAD_CTX_open(
                self.as_ref() as *const _,
                out.as_mut_ptr(),
                out_len.as_mut_ptr(),
                out.len(),
                nonce,
                nonce_len,
                data.as_ptr(),
                data.len(),
                ad,
                ad_len,
            )
        };

        if result == 1 {
            // SAFETY - Any value written to out_len could be a valid usize. The value itself is
            // validated as being a proper slice length by panicking in the following indexing
            // otherwise.
            let out_len = unsafe { out_len.assume_init() };
            Ok(&mut out[..out_len])
        } else {
            Err(ErrorIterator {})
        }
    }

    pub fn seal<'b>(&self, out: &'b mut [u8], data: &[u8]) -> Result<&'b mut [u8]> {
        let nonce = ptr::null_mut();
        let nonce_len = 0;
        let ad = ptr::null_mut();
        let ad_len = 0;
        let mut out_len = MaybeUninit::uninit();
        // SAFETY - The function should only read from self and write to out (at most the provided
        // number of bytes) while reading from data (at most the provided number of bytes),
        // ignoring any NULL input.
        let result = unsafe {
            EVP_AEAD_CTX_seal(
                self.as_ref() as *const _,
                out.as_mut_ptr(),
                out_len.as_mut_ptr(),
                out.len(),
                nonce,
                nonce_len,
                data.as_ptr(),
                data.len(),
                ad,
                ad_len,
            )
        };

        if result == 1 {
            // SAFETY - Any value written to out_len could be a valid usize. The value itself is
            // validated as being a proper slice length by panicking in the following indexing
            // otherwise.
            let out_len = unsafe { out_len.assume_init() };
            Ok(&mut out[..out_len])
        } else {
            Err(ErrorIterator {})
        }
    }
}

/// Cast a C string pointer to a static non-mutable reference.
///
/// # Safety
///
/// The caller needs to ensure that the pointer points to a valid C string and that the C lifetime
/// of the string is compatible with a static Rust lifetime.
unsafe fn as_static_cstr(p: *const c_char) -> Option<&'static CStr> {
    if p.is_null() {
        None
    } else {
        Some(CStr::from_ptr(p))
    }
}

impl AsRef<EVP_AEAD> for Aead {
    fn as_ref(&self) -> &EVP_AEAD {
        &self.0
    }
}

impl AsRef<EVP_AEAD_CTX> for AeadCtx {
    fn as_ref(&self) -> &EVP_AEAD_CTX {
        &self.0
    }
}

pub fn hkdf_sh512<const N: usize>(secret: &[u8], salt: &[u8], info: &[u8]) -> Result<[u8; N]> {
    let mut key = [0; N];
    // SAFETY - The function shouldn't access any Rust variable and the returned value is accepted
    // as a potentially NULL pointer.
    let digest = unsafe { EVP_sha512() };

    assert!(!digest.is_null());
    // SAFETY - Only reads from/writes to the provided slices and supports digest was checked not
    // be NULL.
    let result = unsafe {
        HKDF(
            key.as_mut_ptr(),
            key.len(),
            digest,
            secret.as_ptr(),
            secret.len(),
            salt.as_ptr(),
            salt.len(),
            info.as_ptr(),
            info.len(),
        )
    };

    if result == 1 {
        Ok(key)
    } else {
        Err(ErrorIterator {})
    }
}
