char *real_blk_name, char *crypto_blk_name, const char *name)
{
char buffer[DM_CRYPT_BUF_SIZE];
- char master_key_ascii[129]; /* Large enough to hold 512 bit key and null */
- char *crypt_params;
struct dm_ioctl *io;
- struct dm_target_spec *tgt;
unsigned int minor;
- int fd;
+ int fd=0;
- int i;
int retval = -1;
int version[3];
char *extra_params;
return -1;
}
+/**
+ * Test if key is part of the multi-entry (field, index) sequence. Return non-zero if key is in the
+ * sequence and its index is greater than or equal to index. Return 0 otherwise.
+ */
+static int match_multi_entry(const char *key, const char *field, unsigned index) {
+ unsigned int i;
+ unsigned int field_len;
+ unsigned int key_index;
+ field_len = strlen(field);
+
+ if (index == 0) {
+ // The first key in a multi-entry field is just the filedname itself.
+ if (!strcmp(key, field)) {
+ return 1;
+ }
+ }
+ // Match key against "%s_%d" % (field, index)
+ if (strlen(key) < field_len + 1 + 1) {
+ // Need at least a '_' and a digit.
+ return 0;
+ }
+ if (strncmp(key, field, field_len)) {
+ // If the key does not begin with field, it's not a match.
+ return 0;
+ }
+ if (1 != sscanf(&key[field_len],"_%d", &key_index)) {
+ return 0;
+ }
+ return key_index >= index;
+}
+
+/*
+ * Delete entry/entries from persist_data. If the entries are part of a multi-segment field, all
+ * remaining entries starting from index will be deleted.
+ * returns PERSIST_DEL_KEY_OK if deletion succeeds,
+ * PERSIST_DEL_KEY_ERROR_NO_FIELD if the field does not exist,
+ * and PERSIST_DEL_KEY_ERROR_OTHER if error occurs.
+ *
+ */
+static int persist_del_keys(const char *fieldname, unsigned index)
+{
+ unsigned int i;
+ unsigned int j;
+ unsigned int num;
+
+ if (persist_data == NULL) {
+ return PERSIST_DEL_KEY_ERROR_OTHER;
+ }
+
+ num = persist_data->persist_valid_entries;
+
+ j = 0; // points to the end of non-deleted entries.
+ // Filter out to-be-deleted entries in place.
+ for (i = 0; i < num; i++) {
+ if (!match_multi_entry(persist_data->persist_entry[i].key, fieldname, index)) {
+ persist_data->persist_entry[j] = persist_data->persist_entry[i];
+ j++;
+ }
+ }
+
+ if (j < num) {
+ persist_data->persist_valid_entries = j;
+ // Zeroise the remaining entries
+ memset(&persist_data->persist_entry[j], 0, (num - j) * sizeof(struct crypt_persist_entry));
+ return PERSIST_DEL_KEY_OK;
+ } else {
+ // Did not find an entry matching the given fieldname
+ return PERSIST_DEL_KEY_ERROR_NO_FIELD;
+ }
+}
+
+static int persist_count_keys(const char *fieldname)
+{
+ unsigned int i;
+ unsigned int count;
+
+ if (persist_data == NULL) {
+ return -1;
+ }
+
+ count = 0;
+ for (i = 0; i < persist_data->persist_valid_entries; i++) {
+ if (match_multi_entry(persist_data->persist_entry[i].key, fieldname, 0)) {
+ count++;
+ }
+ }
+
+ return count;
+}
+
/* Return the value of the specified field. */
-int cryptfs_getfield(char *fieldname, char *value, int len)
+int cryptfs_getfield(const char *fieldname, char *value, int len)
{
char temp_value[PROPERTY_VALUE_MAX];
- char real_blkdev[MAXPATHLEN];
- /* 0 is success, 1 is not encrypted,
- * -1 is value not set, -2 is any other error
+ /* CRYPTO_GETFIELD_OK is success,
+ * CRYPTO_GETFIELD_ERROR_NO_FIELD is value not set,
+ * CRYPTO_GETFIELD_ERROR_BUF_TOO_SMALL is buffer (as given by len) too small,
+ * CRYPTO_GETFIELD_ERROR_OTHER is any other error
*/
- int rc = -2;
+ int rc = CRYPTO_GETFIELD_ERROR_OTHER;
+ int i;
+ char temp_field[PROPERTY_KEY_MAX];
if (persist_data == NULL) {
load_persistent_data();
}
/* Set the value of the specified field. */
-int cryptfs_setfield(char *fieldname, char *value)
+int cryptfs_setfield(const char *fieldname, const char *value)
{
- struct crypt_persist_data stored_pdata;
- struct crypt_persist_data *pdata_p;
- struct crypt_mnt_ftr crypt_ftr;
char encrypted_state[PROPERTY_VALUE_MAX];
- /* 0 is success, -1 is an error */
- int rc = -1;
+ /* 0 is success, negative values are error */
+ int rc = CRYPTO_SETFIELD_ERROR_OTHER;
int encrypted = 0;
+ unsigned int field_id;
+ char temp_field[PROPERTY_KEY_MAX];
+ unsigned int num_entries;
+ unsigned int max_keylen;
if (persist_data == NULL) {
load_persistent_data();