Base class for dual-dar crypto implementation. More...
#include <ddar.h>
Public Member Functions | |
virtual bool | prepare (context *context, metadata *md)=0 |
Callback to initialize ephemeral cache. | |
virtual bool | encrypt (metadata *md, void *pt, void *ct, unsigned long page_offset, int page_len)=0 |
Callback when a file is currently being written to the disk. | |
virtual bool | decrypt (metadata *md, void *ct, unsigned long page_offset, int page_len)=0 |
Callback when a file is currently being read from the disk. |
Base class for dual-dar crypto implementation.
A derived class must override all the public virtual functions. Crypto module must have an entry symbol DDAR_ABSTRACT_CRYPTO_SYM with a type of abstract_crypto then the system daemon can dynamically load the derived class at device boot up
MyTestCrypto.cpp MyTestCrypto DDAR_ABSTRACT_CRYPTO_SYM;
When abstract_crypto callbacks are invoked?
Data lock state: When Android framework decides to trigger user state transition into data lock state, it executes as follows
Declaring library version: Crypto library shall declare library version by defining a symbol DDAR_ABSTRACT_CRYPTO_VERSION This version string is exposed to Java interface DualDARPlatformInfo.clientLibVersion.
MyTestCrypto.cpp const unsigned char *DDAR_ABSTRACT_CRYPTO_VERSION = "1.0.1"; // <major>.<minor>.<patch>
virtual bool ddar::abstract_crypto::decrypt | ( | metadata * | md, |
void * | ct, | ||
unsigned long | page_offset, | ||
int | page_len | ||
) | [pure virtual] |
Callback when a file is currently being read from the disk.
The source and destination pages are same, sub classes are expected to implement an inplace decryption
bool MyTestCrypto::decrypt(ddar::metadata *md, void *ct, unsigned long page_offset, int page_len) { struct my_metadata *my_md = (struct my_metadata *) md->ephemeral_addr;
if(mSSL.decrypt((unsigned char *)ct, page_len, (unsigned char *)my_md->fek, NULL, (unsigned char *)ct) > 0) // implement crypto inplace return true; return false; }
ct | source and destination page of kernel memory that contains cipher text from the disk |
virtual bool ddar::abstract_crypto::encrypt | ( | metadata * | md, |
void * | pt, | ||
void * | ct, | ||
unsigned long | page_offset, | ||
int | page_len | ||
) | [pure virtual] |
Callback when a file is currently being written to the disk.
bool MyTestCrypto::encrypt(ddar::metadata *md, void *pt, void *ct, unsigned long page_offset, int page_len) { struct my_metadata *my_md = (struct my_metadata *) md->ephemeral_addr;
if(mSSL.encrypt((unsigned char *)pt, page_len, (unsigned char *)my_md->fek, NULL, (unsigned char *)ct) > 0) return true; return false; }
pt | source filesystem page cache that contains plain text from user program |
ct | destination page of kernel memory that is being written to the disk |
page_offset | page into the associated file |
virtual bool ddar::abstract_crypto::prepare | ( | context * | context, |
metadata * | md | ||
) | [pure virtual] |
Callback to initialize ephemeral cache.
This is called when first encryption/decryption after inode object allocation
bool MyTestCrypto::prepare(ddar::context *context, ddar::metadata *md) { ddar::secret *sec = context->get_secret("my_master_key_alias"); # vendor client app defined struct my_metadata *my_md = (struct my_metadata *) md->ephemeral_addr;
char *iv = NULL; char efek[FEK_KEYLEN];
int rc = md->persistent_get(ALIAS_EFEK, efek); if (rc <= 0) { // No FEK associate with the file, create new mSSL.rand_bytes(my_md->fek, FEK_KEYLEN); rc = mSSL.encrypt((unsigned char *)my_md->fek, FEK_KEYLEN, (unsigned char *)sec->data, (unsigned char *)iv, (unsigned char *)efek); if (rc < 0) return false; // failed to encrypt efek
md->persistent_set(ALIAS_EFEK, efek, FEK_KEYLEN); // store efek } else { mSSL.decrypt((unsigned char *)efek, rc, (unsigned char *)sec->data, (unsigned char *)iv, (unsigned char *)my_md->fek); }
context | access user-wide global info |
md | metadata to access per-file info |