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 |