/// Callback for an AES encryption implementation.
///
/// @param output buffer to be allocated and populated with the ciphertext
/// @param cipher specific cipher variant to use, either SG_CIPHER_AES_CTR_NOPADDING
/// or SG_CIPHER_AES_CBC_PKCS5
/// @param key the encryption key
/// @param key_len length of the encryption key
/// @param iv the initialization vector
/// @param iv_len length of the initialization vector
/// @param plaintext the plaintext to encrypt
/// @param plaintext_len length of the plaintext
/// @return 0 on success, negative on failure
Callback for an AES encryption implementation.
Callback for an AES encryption implementation .
extern "C" fn encrypt_func(
    output: *mut *mut signal_buffer,
    cipher: c_int,
    key: *const u8,
    key_len: usize,
    iv: *const u8,
    iv_len: usize,
    plaintext: *const u8,
    plaintext_len: usize,
    _user_data: *mut c_void,
) -> c_int {
    debug!(
        "encrypt_func key_len is {}, plaintext size is {}",
        key_len,
        plaintext_len
    );
    let ekey = unsafe { slice::from_raw_parts_mut(key as *mut u8, key_len) };
    let eiv = unsafe { slice::from_raw_parts_mut(iv as *mut u8, iv_len) };
    let eplain = unsafe { slice::from_raw_parts_mut(plaintext as *mut u8, plaintext_len) };
    if cipher == SG_CIPHER_AES_CBC_PKCS5 {
        let mut encryptor = cbc_encryptor(KeySize::KeySize256, ekey, eiv, PkcsPadding);
        let mut buffer = [0; 4096];
        let mut final_result = Vec::<u8>::new();
        let mut write_buffer = RefWriteBuffer::new(&mut buffer);
        let mut read_buffer = RefReadBuffer::new(eplain);
        loop {
            if let Ok(result) = encryptor.encrypt(&mut read_buffer, &mut write_buffer, true) {
                // "write_buffer.take_read_buffer().take_remaining()" means:
                // from the writable buffer, create a new readable buffer which
                // contains all data that has been written, and then access all
                // of that data as a slice.
                final_result.extend(
                    write_buffer
                        .take_read_buffer()
                        .take_remaining()
                        .iter()
                        .cloned(),
                );
                match result {
                    BufferResult::BufferUnderflow => break,
                    BufferResult::BufferOverflow => {}
                }
            } else {
                return -3; // TODO: figure out a better error code.
            }
        }
        // If we haven't returned early from Error, set the output to
        // the content of the buffer.
        // Create a signal buffer and copy the Rust slice into it.
        unsafe {
            *output = signal_buffer::from_slice(&final_result);
        }
    } else if cipher == SG_CIPHER_AES_CTR_NOPADDING {
        let mut encryptor = ctr(KeySize::KeySize256, ekey, eiv);
        let mut buffer = vec![];
        encryptor.process(eplain, &mut buffer);
        unsafe {
            *output = signal_buffer::from_slice(&buffer);
        }
    } else {
        error!("Unexpected cipher: {}", cipher);
        // TODO: check error return codes.
        return -1;
    }
    0
}
extern " " fn encrypt_func ( output : * mut * mut signal_buffer , cipher : c_int , key : * const u8 , key_len : usize , iv : * const u8 , iv_len : usize , plaintext : * const u8 , plaintext_len : usize , _user_data : * mut c_void , ) -> c_int { debug ! ( " " key_len plaintext_len ) ; let ekey = unsafe { slice :: from_raw_parts_mut ( key as * mut u8 , key_len ) } ; let eiv = unsafe { slice :: from_raw_parts_mut ( iv as * mut u8 , iv_len ) } ; let eplain = unsafe { slice :: from_raw_parts_mut ( plaintext as * mut u8 , plaintext_len ) } ; if cipher == SG_CIPHER_AES_CBC_PKCS5 { let mut encryptor = cbc_encryptor ( KeySize :: KeySize256 , ekey , eiv , PkcsPadding ) ; let mut buffer = [ 0 ; 4096 ] ; let mut final_result = Vec :: < u8 > :: new ( ) ; let mut write_buffer = RefWriteBuffer :: new ( & mut buffer ) ; let mut read_buffer = RefReadBuffer :: new ( eplain ) ; loop { if let Ok ( result ) = encryptor . encrypt ( & mut read_buffer , & mut write_buffer , true ) { // "write_buffer.take_read_buffer().take_remaining()" means: // from the writable buffer, create a new readable buffer which // contains all data that has been written, and then access all // of that data as a slice. final_result . extend ( write_buffer . take_read_buffer ( ) . take_remaining ( ) . iter ( ) . cloned ( ) , ) ; match result { BufferResult :: BufferUnderflow => break , BufferResult :: BufferOverflow => { } } } else { return - 3 ; // TODO: figure out a better error code. } } // If we haven't returned early from Error, set the output to // the content of the buffer. // Create a signal buffer and copy the Rust slice into it. unsafe { * output = signal_buffer :: from_slice ( & final_result ) ; } } else if cipher == SG_CIPHER_AES_CTR_NOPADDING { let mut encryptor = ctr ( KeySize :: KeySize256 , ekey , eiv ) ; let mut buffer = vec ! [ ] ; encryptor . process ( eplain , & mut buffer ) ; unsafe { * output = signal_buffer :: from_slice ( & buffer ) ; } } else { error ! ( " " cipher ) ; // TODO: check error return codes. return - 1 ; } 0 }
Callback for an AES encryption implementation.
Callback for an AES encryption implementation .
0 on success, negative on failure
0 on success negative on failure
output
*mut *mut signal_buffer
buffer to be allocated and populated with the ciphertext
buffer to be allocated and populated with the ciphertext
cipher
c_int
specific cipher variant to use, either SG_CIPHER_AES_CTR_NOPADDING
or SG_CIPHER_AES_CBC_PKCS5
specific cipher variant to use either SG_CIPHER_AES_CTR_NOPADDING or SG_CIPHER_AES_CBC_PKCS5
key
*const u8
the encryption key
the encryption key
key_len
usize
length of the encryption key
length of the encryption key
iv
*const u8
the initialization vector
the initialization vector
iv_len
usize
length of the initialization vector
length of the initialization vector
plaintext
*const u8
the plaintext to encrypt
the plaintext to encrypt
plaintext_len
usize
length of the plaintext
length of the plaintext
_user_data
*mut c_void