Z-Botan-0.4.0.0: cbits/hs_botan_streamcipher.cpp
#include <botan/ffi.h>
#include <botan/internal/ffi_util.h>
#include <botan/stream_cipher.h>
#include <HsFFI.h>
#include <string.h>
extern "C" {
using namespace Botan_FFI;
// Stream cipher
BOTAN_FFI_DECLARE_STRUCT(botan_stream_cipher_struct, Botan::StreamCipher, 0x9F5B7D34);
typedef struct botan_stream_cipher_struct* botan_stream_cipher_t;
int botan_stream_cipher_init(botan_stream_cipher_t* stream_cipher, const char* stream_cipher_name)
{
return ffi_guard_thunk(__func__, [=]() -> int {
if(stream_cipher == nullptr || stream_cipher_name == nullptr || *stream_cipher_name == 0)
return BOTAN_FFI_ERROR_NULL_POINTER;
std::unique_ptr<Botan::StreamCipher> s = Botan::StreamCipher::create(stream_cipher_name);
if(s == nullptr)
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
*stream_cipher = new botan_stream_cipher_struct(s.release());
return BOTAN_FFI_SUCCESS;
});
}
int botan_stream_cipher_destroy(botan_stream_cipher_t stream_cipher)
{
return BOTAN_FFI_CHECKED_DELETE(stream_cipher);
}
int botan_stream_cipher_seek(botan_stream_cipher_t stream_cipher, size_t offset)
{
return BOTAN_FFI_DO(Botan::StreamCipher, stream_cipher, c, { c.seek(offset); });
}
int botan_stream_cipher_clear(botan_stream_cipher_t stream_cipher)
{
return BOTAN_FFI_DO(Botan::StreamCipher, stream_cipher, c, { c.clear(); });
}
int botan_stream_cipher_query_keylen(botan_stream_cipher_t stream_cipher,
size_t* out_minimum_keylength,
size_t* out_maximum_keylength)
{
return BOTAN_FFI_DO(Botan::StreamCipher, stream_cipher, c, {
*out_minimum_keylength = c.key_spec().minimum_keylength();
*out_maximum_keylength = c.key_spec().maximum_keylength();
});
}
int botan_stream_cipher_get_keyspec(botan_stream_cipher_t stream_cipher,
size_t* out_minimum_keylength,
size_t* out_maximum_keylength,
size_t* out_keylength_modulo)
{
return BOTAN_FFI_DO(Botan::StreamCipher, stream_cipher, c, {
if(out_minimum_keylength)
*out_minimum_keylength = c.key_spec().minimum_keylength();
if(out_maximum_keylength)
*out_maximum_keylength = c.key_spec().maximum_keylength();
if(out_keylength_modulo)
*out_keylength_modulo = c.key_spec().keylength_multiple();
});
}
int botan_stream_cipher_set_key(botan_stream_cipher_t stream_cipher,
const uint8_t* key, size_t key_len)
{
return BOTAN_FFI_DO(Botan::StreamCipher, stream_cipher, c, { c.set_key(key, key_len); });
}
int botan_stream_cipher_set_iv(botan_stream_cipher_t stream_cipher,
const uint8_t* iv, size_t iv_len)
{
return BOTAN_FFI_DO(Botan::StreamCipher, stream_cipher, c, { c.set_iv(iv, iv_len); });
}
int hs_botan_stream_cipher_set_iv(botan_stream_cipher_t stream_cipher,
const uint8_t* iv, HsInt off, HsInt iv_len)
{
return botan_stream_cipher_set_iv(stream_cipher, iv+off, iv_len);
}
int botan_stream_cipher_cipher(botan_stream_cipher_t stream_cipher,
const uint8_t input[],
uint8_t output[],
size_t len)
{
return BOTAN_FFI_DO(Botan::StreamCipher, stream_cipher, c, { c.cipher(input, output, len); });
}
int hs_botan_stream_cipher_cipher(botan_stream_cipher_t stream_cipher,
uint8_t output[],
const uint8_t input[],
HsInt off,
HsInt len)
{
return botan_stream_cipher_cipher(stream_cipher, input+off, output, len);
}
int botan_stream_cipher_write_keystream(botan_stream_cipher_t stream_cipher,
uint8_t output[],
size_t len)
{
return BOTAN_FFI_DO(Botan::StreamCipher, stream_cipher, c, { c.write_keystream(output, len); });
}
int botan_stream_cipher_valid_iv_length(botan_stream_cipher_t stream_cipher, size_t nl)
{
return BOTAN_FFI_RETURNING(Botan::StreamCipher, stream_cipher, c, {
return c.valid_iv_length(nl) ? 1 : 0;
});
}
int botan_stream_cipher_get_default_iv_length(botan_stream_cipher_t stream_cipher, size_t* nl)
{
return BOTAN_FFI_DO(Botan::StreamCipher, stream_cipher, c, { *nl = c.default_iv_length(); });
}
int botan_stream_cipher_name(botan_stream_cipher_t stream_cipher, char* name, size_t* name_len)
{
return BOTAN_FFI_DO(Botan::StreamCipher, stream_cipher, c, {
return write_str_output(name, name_len, c.name()); });
}
}