Can different algorithm be used in Realm encryption(other than AES-256)? - xamarin

There is default support for AES-256 in Realm but can we change encryption algorithm to other than AES-256??

Short Answer: No, it is not a dynamically pluggable system.
The AES Encryption is baked into realm-core, the shared C++ library, at compile time and uses the various platform crypto features available (OS / hardware-based). It is open source, so in theory you could write a different provider and handle changes to methods like realm::util::encryption_read_barrier and realm::util::encryption_write_barrier as needed... or possibly do a paid contract with Realm based upon your custom encryption requirements.
Re: https://github.com/realm/realm-core/blob/master/src/realm/util/aes_cryptor.hpp
class AESCryptor {
public:
AESCryptor(const uint8_t* key);
~AESCryptor() noexcept;
void set_file_size(off_t new_size);
bool read(FileDesc fd, off_t pos, char* dst, size_t size);
void write(FileDesc fd, off_t pos, const char* src, size_t size) noexcept;
private:
enum EncryptionMode {
#if REALM_PLATFORM_APPLE
mode_Encrypt = kCCEncrypt,
mode_Decrypt = kCCDecrypt
#elif defined(_WIN32)
mode_Encrypt = 0,
mode_Decrypt = 1
#else
mode_Encrypt = AES_ENCRYPT,
mode_Decrypt = AES_DECRYPT
#endif
};
#if REALM_PLATFORM_APPLE
CCCryptorRef m_encr;
CCCryptorRef m_decr;
#elif defined(_WIN32)
BCRYPT_KEY_HANDLE m_aes_key_handle;
#else
AES_KEY m_ectx;
AES_KEY m_dctx;
#endif
uint8_t m_hmacKey[32];
std::vector<iv_table> m_iv_buffer;
std::unique_ptr<char[]> m_rw_buffer;
std::unique_ptr<char[]> m_dst_buffer;
void calc_hmac(const void* src, size_t len, uint8_t* dst, const uint8_t* key) const;
bool check_hmac(const void* data, size_t len, const uint8_t* hmac) const;
void crypt(EncryptionMode mode, off_t pos, char* dst, const char* src, const char* stored_iv) noexcept;
iv_table& get_iv_table(FileDesc fd, off_t data_pos) noexcept;
};

Related

Boost Serialization: Serialize/Export derived class without default constructor

I need to serialize all the options on my CommunicationLayer, which is basically a wrapper around serial port, which I will use in an initialization file of sorts.
This class doesn't have a default constructor, but implements a pure virtual class. When I first ran this I got the exception that I didn't register/export the derived class. So I did that. But when I added the export I got the exception that it couldn't find a save/load function:
no matching function for call to ‘save(boost_1_69_0::archive::xml_oarchive&, const amp::communication::RS485CommunicationLayer&, const boost_1_69_0::serialization::version_type&)’
save(ar, t, v);
This is true! But I can't use the save/load and use save_construct_data and load_construct_data, because the absence of a default constructor. How do I tell boost/serde to use these instead?? Is it the SPLIT_FREE macro?
I'm trying to work myself through the documentation, but it's really hard to find everything.
Following are the base and derived classes, I tried to shorten the derived class as much as possible.
//BASE
class ICommunicationLayer {
friend class boost::serialization::access;
template<class Archive>
inline void serialize(Archive & ar, const unsigned int file_version) {};
public:
virtual ~ICommunicationLayer();
virtual std::size_t write(const char* const buffer, std::size_t buffSize) = 0;
virtual std::size_t readUntil(std::vector<char>& buffer, char delim, std::chrono::microseconds timeout) = 0;
};
// DERIVED
#include "ICommunicationLayer.h"
#include <boost/asio.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/nvp.hpp>
namespace amp {
namespace communication {
class RS485CommunicationLayer final : public ICommunicationLayer {
public:
RS485CommunicationLayer(
const std::string& path,
unsigned int baud_rate,
// other options
);
~RS485CommunicationLayer();
std::size_t write(const char* const buffer, const size_t size) override;
std::size_t readUntil(std::vector<char>& buffer, char delim,std::chrono::microseconds timeout) override;
std::string getPath() const;
private:
friend class boost::serialization::access;
std::string path;
// rest of impl
};
} /* namespace communication */
} /* namespace amp */
BOOST_SERIALIZATION_SPLIT_FREE(amp::communication::RS485CommunicationLayer)
BOOST_CLASS_EXPORT(amp::communication::RS485CommunicationLayer)
namespace boost_1_69_0 {
namespace serialization {
template<class Archive>
inline void save_construct_data(Archive& ar, const amp::communication::RS485CommunicationLayer* comLayer, const unsigned int version) {
ar << boost::serialization::make_nvp(
BOOST_PP_STRINGIZE(amp::communication::ICommunicationLayer),
boost::serialization::base_object<amp::communication::ICommunicationLayer>(*comLayer)
);
ar << boost::serialization::make_nvp("path", const_cast<std::string>(comLayer->getPath());
// other options
}
template<class Archive>
inline void load_construct_data(Archive& ar, amp::communication::RS485CommunicationLayer* comLayer, const unsigned int version) {
ar >> boost::serialization::base_object<amp::communication::ICommunicationLayer>(*comLayer);
std::string path;
ar >> path;
// other options
new(comLayer) amp::communication::RS485CommunicationLayer(path, baudrate, /* other options */);
}
}
}
The construct data is an addition to regular serialization. You still need to serialize. As a matter of fact, serializing base_object needs to be in the constructed-object serialize implementation.
Also keep in mind that you need to EXPORT after including the relevant archive type(s).
You have a number of spots with redundant top-level const (even a const-cast). Top-level const on return type/arguments isn't part of the function signature.
Finally, I don't know what namespace boost_1_69_0 is, but that should not work. Use namespace boost. If you're playing with macros to define it like that, I'd suggest to stop doing that. Instead consider putting the overloads in the ADL-associated namespace for your types!
Here's the whole thing made self-contained and working:
Live On Coliru
#include <boost/serialization/access.hpp>
#include <boost/serialization/assume_abstract.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <chrono>
// BASE
namespace amp::communication {
using duration = std::chrono::steady_clock::duration;
class ICommunicationLayer {
friend class boost::serialization::access;
template <class Archive> inline void serialize(Archive&, unsigned){}
public:
virtual ~ICommunicationLayer();
virtual size_t write(char const* const buffer, size_t buffSize) = 0;
virtual size_t readUntil(std::vector<char>& buffer, char delim, duration timeout) = 0;
};
} // namespace amp::communication
// DERIVED
//#include "ICommunicationLayer.h"
#include <boost/asio.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/split_free.hpp>
namespace amp { namespace communication {
class RS485CommunicationLayer final : public ICommunicationLayer {
public:
RS485CommunicationLayer(std::string const& path, unsigned baud_rate)
: path(path)
, baud_rate(baud_rate) {}
~RS485CommunicationLayer();
size_t write(char const* const buffer, const size_t size) override;
size_t readUntil(std::vector<char>& buffer, char delim, duration timeout) override;
std::string getPath() const { return path; }
unsigned getBaudrate() const { return baud_rate; }
private:
friend class boost::serialization::access;
template <typename Ar> void serialize(Ar& ar, unsigned) {
ar& boost::make_nvp("ICommunicationLayer",
boost::serialization::base_object<ICommunicationLayer>(*this));
}
std::string path;
unsigned baud_rate;
// rest of impl
};
// ADL resolved overloads
template <class Archive>
inline void save_construct_data(Archive& ar, RS485CommunicationLayer const* p, unsigned) {
auto path = p->getPath();
unsigned baud_rate = p->getBaudrate();
ar& BOOST_NVP(path) & BOOST_NVP(baud_rate);
}
template <class Archive>
inline void load_construct_data(Archive& ar, RS485CommunicationLayer* p, unsigned) {
std::string path;
unsigned baud_rate;
ar >> BOOST_NVP(path) >> BOOST_NVP(baud_rate);
new (p) RS485CommunicationLayer(path, baud_rate);
}
}} // namespace amp::communication
BOOST_SERIALIZATION_ASSUME_ABSTRACT(amp::communication::ICommunicationLayer)
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <iostream>
#include <sstream>
BOOST_CLASS_EXPORT(amp::communication::ICommunicationLayer)
BOOST_CLASS_EXPORT(amp::communication::RS485CommunicationLayer)
int main() {
using namespace amp::communication;
using Ptr = std::shared_ptr<ICommunicationLayer>;
std::vector<Ptr> ptrs{nullptr, std::make_shared<RS485CommunicationLayer>("hello", 115'200)}, roundtrip;
ptrs.push_back(ptrs.back()); // one duplicate for testing purposes
std::stringstream xml;
{
boost::archive::xml_oarchive oa(xml);
oa << boost::make_nvp("root", ptrs);
}
std::cout << xml.str();
{
boost::archive::xml_iarchive ia(xml);
ia >> boost::make_nvp("root", roundtrip);
}
bool verify = roundtrip.size() == ptrs.size();
verify &= (roundtrip.at(0) == nullptr);
verify &= (roundtrip.at(1) == roundtrip.at(2));
std::cout << "Roundtrip verify " << (verify?"OK":"FAILED") << std::endl;
}
// to satisfy linker
namespace amp { namespace communication {
ICommunicationLayer::~ICommunicationLayer() = default;
RS485CommunicationLayer::~RS485CommunicationLayer() = default;
size_t RS485CommunicationLayer::write(char const*, size_t) { return 0; }
size_t RS485CommunicationLayer::readUntil(std::vector<char>&, char, duration) { return 0; }
}} // namespace amp::communication
Prints
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="19">
<root class_id="0" tracking_level="0" version="0">
<count>3</count>
<item_version>1</item_version>
<item class_id="1" tracking_level="0" version="1">
<px class_id="-1"></px>
</item>
<item>
<px class_id="2" class_name="amp::communication::RS485CommunicationLayer" tracking_level="1" version="0" object_id="_0">
<path>hello</path>
<baud_rate>115200</baud_rate>
<ICommunicationLayer class_id="3" tracking_level="0" version="0"></ICommunicationLayer>
</px>
</item>
<item>
<px class_id_reference="2" object_id_reference="_0"></px>
</item>
</root>
</boost_serialization>
Roundtrip verify OK
Afterthought
Perhaps the best location for load/save construct data is as hidden friends. That way you don't even need public accessors for every bit of construct-data:
Live On Coliru
class RS485CommunicationLayer final : public ICommunicationLayer {
public:
RS485CommunicationLayer(std::string const& path, unsigned baud_rate)
: path(path)
, baud_rate(baud_rate) {}
~RS485CommunicationLayer() override;
size_t write(char const* const buffer, const size_t size) override;
size_t readUntil(std::vector<char>& buffer, char delim, duration timeout) override;
private:
std::string path;
unsigned baud_rate;
// rest of impl
template <class Archive>
friend void save_construct_data(Archive& ar, RS485CommunicationLayer const* p, unsigned) {
auto path = p->path;
unsigned baud_rate = p->baud_rate;
ar& BOOST_NVP(path) & BOOST_NVP(baud_rate);
}
template <class Archive>
friend void load_construct_data(Archive& ar, RS485CommunicationLayer* p, unsigned) {
std::string path;
unsigned baud_rate;
ar >> BOOST_NVP(path) >> BOOST_NVP(baud_rate);
new (p) RS485CommunicationLayer(path, baud_rate);
}
friend class boost::serialization::access;
template <typename Ar> void serialize(Ar& ar, unsigned) {
ar& boost::make_nvp("ICommunicationLayer",
boost::serialization::base_object<ICommunicationLayer>(*this));
}
};

How to migrate atadenoise in ffmpeg to my own project?

This is the entrance to the atadenoise filter:
libavfilter/vf_atadenoise.c
static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
{
...
}
which is used to call
s->dsp.filter_row[p](src, dst, srcf, w, mid, size, thra, thrb, weights);
Therefore, the specific noise reduction method is selected according to the configured parameters:
static void fweight_row##name(const uint8_t *ssrc, uint8_t *ddst, \
const uint8_t *ssrcf[SIZE], \
int w, int mid, int size, \
int thra, int thrb, const float *weights) \
...
static void fweight_row##name##_serial(const uint8_t *ssrc, uint8_t *ddst, \
const uint8_t *ssrcf[SIZE], \
int w, int mid, int size, \
int thra, int thrb, \
const float *weights) \
.....
I call atadenoise function with the example code:
doc/examples/filtering_video.c
// const char *filter_descr = "scale=78:24,transpose=cclock";
const char *filter_descr =
"atadenoise=0a=0.2:1a=0.2:2a=0.2:0b=0.3:1b=0.3:2b=0.3";
/* other way:
scale=78:24 [scl]; [scl] transpose=cclock // assumes "[in]" and "[out]" to be input output pads respectively
*/
......
int main(int argc, char **argv)
{
int ret;
AVPacket packet;
AVFrame *frame;
AVFrame *filt_frame;
if (argc != 2) {
fprintf(stderr, "Usage: %s file\n", argv[0]);
exit(1);
}
......
configuring const char *filter_descr in this way to call atadenoise:
const char *filter_descr =
"atadenoise=0a=0.2:1a=0.2:2a=0.2:0b=0.3:1b=0.3:2b=0.3";
If I want to connect atadenoise to my project, I should start from filter_slice. But I don't know how to feed parameters to it.
Currently I use Xcode to set break point in atadenoise, but that's not stable. And now I cannot break in to it. Maybe I have accidentally changed some configuration.

ffmpeg c++/cli wrapper for using in c# . AccessViolationException after call dll function by it's pointer

My target is to write a c++/cli wrap arount ffmpeg library, using by importing ffmpeg functions from dll-modules.
Later I will use this interface in c#.
This is my challenge, don't ask me why))
So i've implemented Wrap class, which is listed below:
namespace FFMpegWrapLib
{
public class Wrap
{
private:
public:
//wstring libavcodecDllName = "avcodec-56.dll";
//wstring libavformatDllName = "avformat-56.dll";
//wstring libswscaleDllName = "swscale-3.dll";
//wstring libavutilDllName = "avutil-54.dll";
HMODULE libavcodecDLL;
HMODULE libavformatDLL;
HMODULE libswsscaleDLL;
HMODULE libavutilDLL;
AVFormatContext **pFormatCtx = nullptr;
AVCodecContext *pCodecCtxOrig = nullptr;
AVCodecContext *pCodecCtx = nullptr;
AVCodec **pCodec = nullptr;
AVFrame **pFrame = nullptr;
AVFrame **pFrameRGB = nullptr;
AVPacket *packet = nullptr;
int *frameFinished;
int numBytes;
uint8_t *buffer = nullptr;
struct SwsContext *sws_ctx = nullptr;
void Init();
void AVRegisterAll();
void Release();
bool SaveFrame(const char *pFileName, AVFrame * frame, int w, int h);
bool GetStreamInfo();
int FindVideoStream();
bool OpenInput(const char* file);
AVCodec* FindDecoder();
AVCodecContext* AllocContext3();
bool CopyContext();
bool OpenCodec2();
AVFrame* AllocFrame();
int PictureGetSize();
void* Alloc(size_t size);
int PictureFill(AVPicture *, const uint8_t *, enum AVPixelFormat, int, int);
SwsContext* GetSwsContext(int, int, enum AVPixelFormat, int, int, enum AVPixelFormat, int, SwsFilter *, SwsFilter *, const double *);
int ReadFrame(AVFormatContext *s, AVPacket *pkt);
int DecodeVideo2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, const AVPacket *avpkt);
int SwsScale(struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]);
void PacketFree(AVPacket *pkt);
void BufferFree(void *ptr);
void FrameFree(AVFrame **frame);
int CodecClose(AVCodecContext *);
void CloseInput(AVFormatContext **);
bool SeekFrame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags);
Wrap();
~Wrap();
bool GetVideoFrame(char* str_in_file, char* str_out_img, uint64_t time);
};
public ref class managedWrap
{
public:
managedWrap(){}
~managedWrap(){ delete unmanagedWrap; }
bool GetVideoFrameToFile(char* str_in_file, char* str_out_img, uint64_t time)
{
return unmanagedWrap->GetVideoFrame(str_in_file, str_out_img, time);
}
static Wrap* unmanagedWrap = new Wrap();
};
}
So the imports to libavcodec and etc. are succesful.
The problem is in AccessViolationException during calling dll func, for example, in OpenInput (i.e. av_open_input in native ffmpeg library)
The OpenInput func code is below:
bool FFMpegWrapLib::Wrap::OpenInput(const char* file)
{
typedef int avformat_open_input(AVFormatContext **, const char *, AVInputFormat *, AVDictionary **);
avformat_open_input* pavformat_open_input = (avformat_open_input *)GetProcAddress(libavformatDLL, "avformat_open_input");
if (pavformat_open_input == nullptr)
{
throw exception("Unable to find avformat_open_input function address in libavformat module");
return false;
}
//pin_ptr<AVFormatContext *> pinFormatContext = &(new interior_ptr<AVFormatContext *>(pCodecCtx));
pFormatCtx = new AVFormatContext*;
//*pFormatCtx = new AVFormatContext;
int ret = pavformat_open_input(pFormatCtx, file, NULL, NULL); // here it fails
return ret == 0;
}
So the problem, i think, is that class-fields of Wrap class are in secure memory. And ffmpeg works with native memory, initialising pFormatCtx variable by it's address.
Can I avoid this, or it is impossible?
Got the same problem, you need to initialise AVFormatContext object.
Good Example:
AVFormatContext *pFormatCtx = avformat_alloc_context();
Bad example:
AVFormatContext *pFormatCtx = NULL;

device_create(...) argument 'void * drvdata'

The function
struct device * device_create ( struct class * class,
struct device * parent,
dev_t devt,
void * drvdata,
const char * fmt,
...);
[link to documentation] takes an argument "void * drvdata". It is described as "the data to be added to the device for callbacks". What callbacks exactly are meant here? The file-operation-functions?
SysFS is one example of where this could be useful: whenever userspace communicates with the driver using SysFS (see "Reading/Writing Attribute Data" in the documentation), the kernel calls the corresponding callbacks. The void * drvdata pointer supplied during device_create can then be obtained by calling dev_get_drvdata(dev). The pointer could be used to refer to a structure containing driver's state for example.
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
#include <linux/device.h>
#include <linux/err.h>
MODULE_LICENSE("GPL");
static ssize_t show_period(struct device *dev, struct device_attribute *attr, char *buf);
static ssize_t set_period(struct device* dev,
struct device_attribute* attr,
const char* buf,
size_t count);
static DEVICE_ATTR(period, S_IWUSR | S_IRUSR, show_period, set_period);
static struct device *s_pDeviceObject;
static struct class *s_pDeviceClass;
static struct pwm_device_state
{
int m_Period;
} s_DeviceState;
static int __init pwmdriver_init(void)
{
int result;
s_pDeviceClass = class_create(THIS_MODULE, "pwmdriver");
BUG_ON(IS_ERR(s_pDeviceClass));
s_pDeviceObject = device_create(s_pDeviceClass, NULL, 0, &s_DeviceState, "channel");
result = device_create_file(s_pDeviceObject, &dev_attr_period);
BUG_ON(result < 0);
return result;
}
static ssize_t show_period(struct device *dev, struct device_attribute *attr, char *buf)
{
struct pwm_device_state *pwm_device_data;
pwm_device_data = dev_get_drvdata(dev);
return scnprintf(buf, PAGE_SIZE, "%d\n", pwm_device_data->m_Period);
}
static ssize_t set_period(struct device* dev,
struct device_attribute* attr,
const char* buf,
size_t count)
{
long period_value = 0;
struct pwm_device_state *pwm_device_data;
if (kstrtol(buf, 10, &period_value) < 0)
return -EINVAL;
if (period_value < 10) //Safety check
return -EINVAL;
pwm_device_data = dev_get_drvdata(dev);
pwm_device_data->m_Period = period_value;
return count;
}
static void __exit pwmdriver_exit(void)
{
device_remove_file(s_pDeviceObject, &dev_attr_period);
device_destroy(s_pDeviceClass, 0);
class_destroy(s_pDeviceClass);
}
module_init(pwmdriver_init);
module_exit(pwmdriver_exit);

Swig unsigned char* to short[]

%apply (char* STRING,size_t LENGTH)
{
(char* dataBuffer, int size)
};
This is used for convert char* to byte[].
But I need to convert unsigned char* to short[]
%apply (unsigned char* STRING,size_t LENGTH)
{
(unsigned char* dataBuffer, int size)
};
This apply isn't working?
How can I fix it?

Resources