/* Copyright (c) 2023, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

extern crate alloc;

use crate::{CSlice, CSliceMut};
use alloc::vec;
use alloc::vec::Vec;
use bssl_sys::EVP_CIPHER;
use core::ffi::c_int;
use core::marker::PhantomData;

/// AES-CTR stream cipher operations.
pub mod aes_ctr;

/// AES-CBC stream cipher operations.
pub mod aes_cbc;

/// Error returned in the event of an unsuccessful cipher operation.
#[derive(Debug)]
pub struct CipherError;

/// Synchronous stream cipher trait.
pub trait StreamCipher {
    /// The byte array key type which specifies the size of the key used to instantiate the cipher.
    type Key: AsRef<[u8]>;

    /// The byte array nonce type which specifies the size of the nonce used in the cipher
    /// operations.
    type Nonce: AsRef<[u8]>;

    /// Instantiate a new instance of a stream cipher from a `key` and `iv`.
    fn new(key: &Self::Key, iv: &Self::Nonce) -> Self;

    /// Applies the cipher keystream to `buffer` in place, returning CipherError on an unsuccessful
    /// operation.
    fn apply_keystream(&mut self, buffer: &mut [u8]) -> Result<(), CipherError>;
}

/// Synchronous block cipher trait.
pub trait BlockCipher {
    /// The byte array key type which specifies the size of the key used to instantiate the cipher.
    type Key: AsRef<[u8]>;

    /// The byte array nonce type which specifies the size of the nonce used in the cipher
    /// operations.
    type Nonce: AsRef<[u8]>;

    /// Instantiate a new instance of a block cipher for encryption from a `key` and `iv`.
    fn new_encrypt(key: &Self::Key, iv: &Self::Nonce) -> Self;

    /// Instantiate a new instance of a block cipher for decryption from a `key` and `iv`.
    fn new_decrypt(key: &Self::Key, iv: &Self::Nonce) -> Self;

    /// Encrypts the given data in `buffer`, and returns the result (with padding) in a newly
    /// allocated vector, or a [`CipherError`] if the operation was unsuccessful.
    fn encrypt_padded(self, buffer: &[u8]) -> Result<Vec<u8>, CipherError>;

    /// Decrypts the given data in a `buffer`, and returns the result (with padding removed) in a
    /// newly allocated vector, or a [`CipherError`] if the operation was unsuccessful.
    fn decrypt_padded(self, buffer: &[u8]) -> Result<Vec<u8>, CipherError>;
}

/// A cipher type, where `Key` is the size of the Key and `Nonce` is the size of the nonce or IV.
/// This must only be exposed publicly by types who ensure that `Key` is the correct size for the
/// given CipherType. This can be checked via `bssl_sys::EVP_CIPHER_key_length`.
trait EvpCipherType {
    type Key: AsRef<[u8]>;
    type Nonce: AsRef<[u8]>;
    fn evp_cipher() -> *const EVP_CIPHER;
}

struct EvpAes128Ctr;
impl EvpCipherType for EvpAes128Ctr {
    type Key = [u8; 16];
    type Nonce = [u8; 16];
    fn evp_cipher() -> *const EVP_CIPHER {
        // Safety:
        // - this just returns a constant value
        unsafe { bssl_sys::EVP_aes_128_ctr() }
    }
}

struct EvpAes256Ctr;
impl EvpCipherType for EvpAes256Ctr {
    type Key = [u8; 32];
    type Nonce = [u8; 16];
    fn evp_cipher() -> *const EVP_CIPHER {
        // Safety:
        // - this just returns a constant value
        unsafe { bssl_sys::EVP_aes_256_ctr() }
    }
}

struct EvpAes128Cbc;
impl EvpCipherType for EvpAes128Cbc {
    type Key = [u8; 16];
    type Nonce = [u8; 16];
    fn evp_cipher() -> *const EVP_CIPHER {
        // Safety:
        // - this just returns a constant value
        unsafe { bssl_sys::EVP_aes_128_cbc() }
    }
}

struct EvpAes256Cbc;
impl EvpCipherType for EvpAes256Cbc {
    type Key = [u8; 32];
    type Nonce = [u8; 16];
    fn evp_cipher() -> *const EVP_CIPHER {
        // Safety:
        // - this just returns a constant value
        unsafe { bssl_sys::EVP_aes_256_cbc() }
    }
}

enum CipherInitPurpose {
    Encrypt,
    Decrypt,
}

/// Internal cipher implementation which wraps `EVP_CIPHER_*`
struct Cipher<C: EvpCipherType> {
    ctx: *mut bssl_sys::EVP_CIPHER_CTX,
    _marker: PhantomData<C>,
}

impl<C: EvpCipherType> Cipher<C> {
    fn new(key: &C::Key, iv: &C::Nonce, purpose: CipherInitPurpose) -> Self {
        // Safety:
        // - Panics on allocation failure.
        let ctx = unsafe { bssl_sys::EVP_CIPHER_CTX_new() };
        assert!(!ctx.is_null());

        let key_cslice = CSlice::from(key.as_ref());
        let iv_cslice = CSlice::from(iv.as_ref());

        // Safety:
        // - Key size and iv size must be properly set by the higher level wrapper types.
        // - Panics on allocation failure.
        let result = match purpose {
            CipherInitPurpose::Encrypt => unsafe {
                bssl_sys::EVP_EncryptInit_ex(
                    ctx,
                    C::evp_cipher(),
                    core::ptr::null_mut(),
                    key_cslice.as_ptr(),
                    iv_cslice.as_ptr(),
                )
            },
            CipherInitPurpose::Decrypt => unsafe {
                bssl_sys::EVP_DecryptInit_ex(
                    ctx,
                    C::evp_cipher(),
                    core::ptr::null_mut(),
                    key_cslice.as_ptr(),
                    iv_cslice.as_ptr(),
                )
            },
        };
        assert_eq!(result, 1);

        Self {
            ctx,
            _marker: Default::default(),
        }
    }

    fn cipher_mode(&self) -> u32 {
        // Safety:
        // - The cipher context is initialized with EVP_EncryptInit_ex in `new`
        unsafe { bssl_sys::EVP_CIPHER_CTX_mode(self.ctx) }
    }

    fn apply_keystream_in_place(&mut self, buffer: &mut [u8]) -> Result<(), CipherError> {
        // WARNING: This is not safe to re-use for the CBC mode of operation since it is applying
        // the key stream in-place.
        assert_eq!(
            self.cipher_mode(),
            bssl_sys::EVP_CIPH_CTR_MODE as u32,
            "Cannot use apply_keystraem_in_place for non-CTR modes"
        );
        let mut cslice_buf_mut = CSliceMut::from(buffer);
        let mut out_len = 0;

        let buff_len_int = c_int::try_from(cslice_buf_mut.len()).map_err(|_| CipherError)?;

        // Safety:
        // - The output buffer provided is always large enough for an in-place operation.
        let result = unsafe {
            bssl_sys::EVP_EncryptUpdate(
                self.ctx,
                cslice_buf_mut.as_mut_ptr(),
                &mut out_len,
                cslice_buf_mut.as_mut_ptr(),
                buff_len_int,
            )
        };
        if result == 1 {
            assert_eq!(out_len as usize, cslice_buf_mut.len());
            Ok(())
        } else {
            Err(CipherError)
        }
    }

    #[allow(clippy::expect_used)]
    fn encrypt(self, buffer: &[u8]) -> Result<Vec<u8>, CipherError> {
        // Safety: self.ctx is initialized with a cipher in `new()`.
        let block_size_u32 = unsafe { bssl_sys::EVP_CIPHER_CTX_block_size(self.ctx) };
        let block_size: usize = block_size_u32
            .try_into()
            .expect("Block size should always fit in usize");
        // Allocate an output vec that is large enough for both EncryptUpdate and EncryptFinal
        // operations
        let max_encrypt_update_output_size = buffer.len() + block_size - 1;
        let max_encrypt_final_output_size = block_size;
        let mut output_vec =
            vec![0_u8; max_encrypt_update_output_size + max_encrypt_final_output_size];
        // EncryptUpdate block
        let update_out_len_usize = {
            let mut cslice_out_buf_mut = CSliceMut::from(&mut output_vec[..]);
            let mut update_out_len = 0;

            let cslice_in_buf = CSlice::from(buffer);
            let in_buff_len_int = c_int::try_from(cslice_in_buf.len()).map_err(|_| CipherError)?;

            // Safety:
            // - `EVP_EncryptUpdate` requires that "The number of output bytes may be up to `in_len`
            //   plus the block length minus one and `out` must have sufficient space". This is the
            //   `max_encrypt_update_output_size` part of the output_vec's capacity.
            let update_result = unsafe {
                bssl_sys::EVP_EncryptUpdate(
                    self.ctx,
                    cslice_out_buf_mut.as_mut_ptr(),
                    &mut update_out_len,
                    cslice_in_buf.as_ptr(),
                    in_buff_len_int,
                )
            };
            if update_result != 1 {
                return Err(CipherError);
            }
            update_out_len
                .try_into()
                .expect("Output length should always fit in usize")
        };

        // EncryptFinal block
        {
            // Slice indexing here will not panic because we ensured `output_vec` is larger than
            // what `EncryptUpdate` will write.
            #[allow(clippy::indexing_slicing)]
            let mut cslice_finalize_buf_mut =
                CSliceMut::from(&mut output_vec[update_out_len_usize..]);
            let mut final_out_len = 0;
            let final_result = unsafe {
                bssl_sys::EVP_EncryptFinal_ex(
                    self.ctx,
                    cslice_finalize_buf_mut.as_mut_ptr(),
                    &mut final_out_len,
                )
            };
            let final_put_len_usize =
                <usize>::try_from(final_out_len).expect("Output length should always fit in usize");
            if final_result == 1 {
                output_vec.truncate(update_out_len_usize + final_put_len_usize)
            } else {
                return Err(CipherError);
            }
        }
        Ok(output_vec)
    }

    #[allow(clippy::expect_used)]
    fn decrypt(self, in_buffer: &[u8]) -> Result<Vec<u8>, CipherError> {
        // Safety: self.ctx is initialized with a cipher in `new()`.
        let block_size_u32 = unsafe { bssl_sys::EVP_CIPHER_CTX_block_size(self.ctx) };
        let block_size: usize = block_size_u32
            .try_into()
            .expect("Block size should always fit in usize");
        // Allocate an output vec that is large enough for both DecryptUpdate and DecryptFinal
        // operations
        let max_decrypt_update_output_size = in_buffer.len() + block_size - 1;
        let max_decrypt_final_output_size = block_size;
        let mut output_vec =
            vec![0_u8; max_decrypt_update_output_size + max_decrypt_final_output_size];

        // DecryptUpdate block
        let update_out_len_usize = {
            let mut cslice_out_buf_mut = CSliceMut::from(&mut output_vec[..]);
            let mut update_out_len = 0;

            let cslice_in_buf = CSlice::from(in_buffer);
            let in_buff_len_int = c_int::try_from(cslice_in_buf.len()).map_err(|_| CipherError)?;

            // Safety:
            // - `EVP_DecryptUpdate` requires that "The number of output bytes may be up to `in_len`
            //   plus the block length minus one and `out` must have sufficient space". This is the
            //   `max_decrypt_update_output_size` part of the output_vec's capacity.
            let update_result = unsafe {
                bssl_sys::EVP_DecryptUpdate(
                    self.ctx,
                    cslice_out_buf_mut.as_mut_ptr(),
                    &mut update_out_len,
                    cslice_in_buf.as_ptr(),
                    in_buff_len_int,
                )
            };
            if update_result != 1 {
                return Err(CipherError);
            }
            update_out_len
                .try_into()
                .expect("Output length should always fit in usize")
        };

        // DecryptFinal block
        {
            // Slice indexing here will not panic because we ensured `output_vec` is larger than
            // what `DecryptUpdate` will write.
            #[allow(clippy::indexing_slicing)]
            let mut cslice_final_buf_mut = CSliceMut::from(&mut output_vec[update_out_len_usize..]);
            let mut final_out_len = 0;
            let final_result = unsafe {
                bssl_sys::EVP_DecryptFinal_ex(
                    self.ctx,
                    cslice_final_buf_mut.as_mut_ptr(),
                    &mut final_out_len,
                )
            };
            let final_put_len_usize =
                <usize>::try_from(final_out_len).expect("Output length should always fit in usize");

            if final_result == 1 {
                output_vec.truncate(update_out_len_usize + final_put_len_usize)
            } else {
                return Err(CipherError);
            }
        }
        Ok(output_vec)
    }
}

impl<C: EvpCipherType> Drop for Cipher<C> {
    fn drop(&mut self) {
        // Safety:
        // - `self.ctx` was allocated by `EVP_CIPHER_CTX_new` and has not yet been freed.
        unsafe { bssl_sys::EVP_CIPHER_CTX_free(self.ctx) }
    }
}

#[cfg(test)]
mod test {
    use crate::cipher::{CipherInitPurpose, EvpAes128Cbc, EvpAes128Ctr};

    use super::Cipher;

    #[test]
    fn test_cipher_mode() {
        assert_eq!(
            Cipher::<EvpAes128Ctr>::new(&[0; 16], &[0; 16], CipherInitPurpose::Encrypt)
                .cipher_mode(),
            bssl_sys::EVP_CIPH_CTR_MODE as u32
        );

        assert_eq!(
            Cipher::<EvpAes128Cbc>::new(&[0; 16], &[0; 16], CipherInitPurpose::Encrypt)
                .cipher_mode(),
            bssl_sys::EVP_CIPH_CBC_MODE as u32
        );
    }

    #[should_panic]
    #[test]
    fn test_apply_keystream_on_cbc() {
        let mut cipher =
            Cipher::<EvpAes128Cbc>::new(&[0; 16], &[0; 16], CipherInitPurpose::Encrypt);
        let mut buf = [0; 16];
        let _ = cipher.apply_keystream_in_place(&mut buf); // This should panic
    }
}
