return retval;
}
-int get_filename_hash(ext2_filsys fs, int encrypted, int version,
- const char *name, int len, ext2_dirhash_t *ret_hash,
- ext2_dirhash_t *ret_minor_hash)
-{
- char buf[2*EXT2FS_DIGEST_SIZE];
- int buf_len;
-
- if (!encrypted)
- return ext2fs_dirhash(version, name, len,
- fs->super->s_hash_seed,
- ret_hash, ret_minor_hash);
-
- if (len <= EXT2FS_DIGEST_SIZE)
- buf_len = ext2fs_digest_encode(name, len, buf);
- else {
- ext2fs_sha256(name, len, buf + EXT2FS_DIGEST_SIZE);
- buf[0] = 'I';
- buf_len = ext2fs_digest_encode(buf + EXT2FS_DIGEST_SIZE,
- EXT2FS_DIGEST_SIZE, buf + 1);
- buf_len++;
- }
- return ext2fs_dirhash(version, buf, buf_len,
- fs->super->s_hash_seed,
- ret_hash, ret_minor_hash);
-}
-
static int check_dir_block2(ext2_filsys fs,
struct ext2_db_entry2 *db,
void *priv_data)
#ifdef ENABLE_HTREE
if (dx_db) {
- get_filename_hash(fs, encrypted, dx_dir->hashversion,
- dirent->name,
- ext2fs_dirent_name_len(dirent),
- &hash, 0);
+ ext2fs_dirhash(dx_dir->hashversion, dirent->name,
+ ext2fs_dirent_name_len(dirent),
+ fs->super->s_hash_seed, &hash, 0);
if (hash < dx_db->min_hash)
dx_db->min_hash = hash;
if (hash > dx_db->max_hash)
char *dir;
unsigned int offset, dir_offset, rec_len, name_len;
int hash_alg;
- int encrypted = 0;
- char processed_filename[2*EXT2FS_DIGEST_SIZE];
- int processed_filename_len;
if (blockcnt < 0)
return 0;
return BLOCK_ABORT;
}
- /* Determine if the directory is encrypted */
- if (fd->ctx->encrypted_dirs)
- encrypted = ext2fs_u32_list_test(fd->ctx->encrypted_dirs,
- fd->ino);
-
dir = (fd->buf+offset);
if (*block_nr == 0) {
memset(dir, 0, fs->blocksize);
if (fd->compress)
ent->hash = ent->minor_hash = 0;
else {
- fd->err = get_filename_hash(fs, encrypted,
- hash_alg, dirent->name,
- ext2fs_dirent_name_len(dirent),
- &ent->hash, &ent->minor_hash);
+ fd->err = ext2fs_dirhash(hash_alg, dirent->name,
+ name_len,
+ fs->super->s_hash_seed,
+ &ent->hash, &ent->minor_hash);
if (fd->err)
return BLOCK_ABORT;
}
char new_name[256];
unsigned int new_len;
int hash_alg;
- int encrypted = 0;
- char processed_filename[2*EXT2FS_DIGEST_SIZE];
- int processed_filename_len;
clear_problem_context(&pctx);
pctx.ino = ino;
(fs->super->s_flags & EXT2_FLAGS_UNSIGNED_HASH))
hash_alg += 3;
- /* Determine if the directory is encrypted */
- if (fd->ctx->encrypted_dirs)
- encrypted = ext2fs_u32_list_test(fd->ctx->encrypted_dirs,
- fd->ino);
for (i=1; i < fd->num_array; i++) {
ent = fd->harray + i;
prev = ent - 1;
if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
memcpy(ent->dir->name, new_name, new_len);
ext2fs_dirent_set_name_len(ent->dir, new_len);
- get_filename_hash(fs, encrypted,
- hash_alg, new_name, new_len,
- &ent->hash, &ent->minor_hash);
+ ext2fs_dirhash(hash_alg, new_name, new_len,
+ fs->super->s_hash_seed,
+ &ent->hash, &ent->minor_hash);
fixed++;
}
}
csum.o \
dblist.o \
dblist_dir.o \
- digest_encode.o \
dirblock.o \
dirhash.o \
dir_iterate.o \
read_bb_file.o \
res_gdt.o \
rw_bitmaps.o \
- sha256.o \
sha512.o \
swapfs.o \
symlink.o \
#endif
#include "ext2fs.h"
+static const char *lookup_table =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
+
/**
* ext2fs_digest_encode() -
*
* Encodes the input digest using characters from the set [a-zA-Z0-9_+].
* The encoded string is roughly 4/3 times the size of the input string.
*/
-int ext2fs_digest_encode(const char *src, unsigned long len, char *dst)
+int ext2fs_digest_encode(const char *src, int len, char *dst)
{
- static const char *lookup_table =
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+";
- unsigned num_chunks, i;
- char tmp_buf[3];
- unsigned c0, c1, c2, c3;
+ int i = 0, bits = 0, ac = 0;
+ char *cp = dst;
- num_chunks = len/3;
- for (i = 0; i < num_chunks; i++) {
- c0 = src[3*i] & 0x3f;
- c1 = (((src[3*i]>>6)&0x3) | ((src[3*i+1] & 0xf)<<2)) & 0x3f;
- c2 = (((src[3*i+1]>>4)&0xf) | ((src[3*i+2] & 0x3)<<4)) & 0x3f;
- c3 = (src[3*i+2]>>2) & 0x3f;
- dst[4*i] = lookup_table[c0];
- dst[4*i+1] = lookup_table[c1];
- dst[4*i+2] = lookup_table[c2];
- dst[4*i+3] = lookup_table[c3];
+ while (i < len) {
+ ac += (((unsigned char) src[i]) << bits);
+ bits += 8;
+ do {
+ *cp++ = lookup_table[ac & 0x3f];
+ ac >>= 6;
+ bits -= 6;
+ } while (bits >= 6);
+ i++;
}
- if (i*3 < len) {
- memset(tmp_buf, 0, 3);
- memcpy(tmp_buf, &src[3*i], len-3*i);
- c0 = tmp_buf[0] & 0x3f;
- c1 = (((tmp_buf[0]>>6)&0x3) | ((tmp_buf[1] & 0xf)<<2)) & 0x3f;
- c2 = (((tmp_buf[1]>>4)&0xf) | ((tmp_buf[2] & 0x3)<<4)) & 0x3f;
- c3 = (tmp_buf[2]>>2) & 0x3f;
- dst[4*i] = lookup_table[c0];
- dst[4*i+1] = lookup_table[c1];
- dst[4*i+2] = lookup_table[c2];
- dst[4*i+3] = lookup_table[c3];
+ if (bits)
+ *cp++ = lookup_table[ac & 0x3f];
+ return cp - dst;
+}
+
+int ext2fs_digest_decode(const char *src, int len, char *dst)
+{
+ int i = 0, bits = 0, ac = 0;
+ const char *p;
+ char *cp = dst;
+
+ while (i < len) {
+ p = strchr(lookup_table, src[i]);
+ if (p == NULL || src[i] == 0)
+ return -1;
+ ac += (p - lookup_table) << bits;
+ bits += 6;
+ if (bits >= 8) {
+ *cp++ = ac & 0xff;
+ ac >>= 8;
+ bits -= 8;
+ }
i++;
}
- return (i * 4);
+ if (ac)
+ return -1;
+ return cp - dst;
}
+
#ifdef UNITTEST
static const struct {
unsigned char d[32];
0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 }, 32,
- "JdlXcHj+CqHM7tpYz_wUKCIRbrozBojtKwzMBGNu4wfa"
+ "jDLxChJ,cQhm7TPyZ+WukcirBROZbOJTkWZmbgnU4WF"
},
{ { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad }, 32,
- "6INf+_yapREqbbK3D5QiJa7aHnQLxOhN0cX+Hjpav0ka"
+ "6inF,+YAPreQBBk3d5qIjA7AhNqlXoHn0Cx,hJPAV0K"
},
{ { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 }, 32,
- "K0OAHjTb4GB5aBYKm4dy5mkpKNfz+hYz2ZE7uNX2gema"
+ "k0oahJtB4gb5AbykM4DY5MKPknFZ,HyZ2ze7Unx2GEM"
},
{ { 0x00, }, 1,
- "aaaa"
+ "AA"
},
{ { 0x01, }, 1,
- "baaa"
+ "BA"
},
{ { 0x01, 0x02 }, 2,
- "biaa"
+ "BIA"
},
{ { 0x01, 0x02, 0x03 }, 3,
- "biWa"
+ "BIwA"
},
{ { 0x01, 0x02, 0x03, 0x04 }, 4,
- "biWaeaaa"
+ "BIwAEA"
},
{ { 0x01, 0x02, 0x03, 0x04, 0xff }, 5,
- "biWae8pa"
+ "BIwAE8P"
},
{ { 0x01, 0x02, 0x03, 0x04, 0xff, 0xfe }, 6,
- "biWae8V+"
+ "BIwAE8v,"
},
{ { 0x01, 0x02, 0x03, 0x04, 0xff, 0xfe, 0xfd }, 7,
- "biWae8V+9daa"
+ "BIwAE8v,9D"
},
};
int main(int argc, char **argv)
{
- int i, ret, len;
+ int i, ret, len, len2;
int errors = 0;
- unsigned char tmp[1024];
+ unsigned char tmp[1024], tmp2[1024];
+ if (argc == 3 && !strcmp(argv[1], "encode")) {
+ memset(tmp, 0, sizeof(tmp));
+ ext2fs_digest_encode(argv[2], strlen(argv[2]), tmp);
+ puts(tmp);
+ exit(0);
+ }
+ if (argc == 3 && !strcmp(argv[1], "decode")) {
+ memset(tmp, 0, sizeof(tmp));
+ ret = ext2fs_digest_decode(argv[2], strlen(argv[2]), tmp);
+ puts(tmp);
+ fprintf(stderr, "returned %d\n", ret);
+ exit(0);
+ }
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
memset(tmp, 0, sizeof(tmp));
ret = ext2fs_digest_encode(tests[i].d, tests[i].len, tmp);
printf("FAILED returned %d, string length was %d\n",
ret, len);
errors++;
- } else if (memcmp(tmp, tests[i].ed, ret) != 0) {
+ continue;
+ } else if (strcmp(tmp, tests[i].ed) != 0) {
printf("FAILED: got %s, expected %s\n", tmp,
tests[i].ed);
errors++;
- } else
- printf("OK\n");
+ continue;
+ }
+ ret = ext2fs_digest_decode(tmp, len, tmp2);
+ if (ret != tests[i].len) {
+ printf("FAILED decode returned %d, expected %d\n",
+ ret, tests[i].len);
+ errors++;
+ continue;
+ }
+ if (memcmp(tmp2, tests[i].d, ret) != 0) {
+ puts("FAILED: decode mismatched");
+ errors++;
+ continue;
+ }
+ printf("OK\n");
}
for (i = 1; i < argc; i++) {
memset(tmp, 0, sizeof(tmp));
char version;
char contents_encryption_mode;
char filenames_encryption_mode;
+ char flags;
char master_key_descriptor[EXT4_KEY_DESCRIPTOR_SIZE];
} __attribute__((__packed__));
void *priv_data),
void *priv_data);
+#if 0
/* digest_encode.c */
#define EXT2FS_DIGEST_SIZE EXT2FS_SHA256_LENGTH
-extern int ext2fs_digest_encode(const char *src, unsigned long len, char *dst);
+extern int ext2fs_digest_encode(const char *src, int len, char *dst);
+extern int ext2fs_digest_decode(const char *src, int len, char *dst);
+#endif
/* dirblock.c */
extern errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
/* res_gdt.c */
extern errcode_t ext2fs_create_resize_inode(ext2_filsys fs);
+#if 0
/*sha256.c */
#define EXT2FS_SHA256_LENGTH 32
extern void ext2fs_sha256(const unsigned char *in, unsigned long in_size,
unsigned char out[EXT2FS_SHA256_LENGTH]);
+#endif
/* sha512.c */
#define EXT2FS_SHA512_LENGTH 64
#define EXT4_IOC_SET_ENCRYPTION_POLICY _IOR('f', 19, struct ext4_encryption_policy)
#define EXT4_IOC_GET_ENCRYPTION_POLICY _IOW('f', 21, struct ext4_encryption_policy)
+static int int_log2(int arg)
+{
+ int l = 0;
+
+ arg >>= 1;
+ while (arg) {
+ l++;
+ arg >>= 1;
+ }
+ return l;
+}
+
static void validate_paths(int argc, char *argv[], int path_start_index)
{
int x;
add_salt(salt_buf, salt_len);
}
-static void set_policy(struct salt *set_salt,
+static void set_policy(struct salt *set_salt, int pad,
int argc, char *argv[], int path_start_index)
{
struct salt *salt;
int x;
int rc;
+ if ((pad != 4) && (pad != 8) &&
+ (pad != 16) && (pad != 32)) {
+ fprintf(stderr, "Invalid padding %d\n", pad);
+ exit(1);
+ }
+
for (x = path_start_index; x < argc; x++) {
fd = open(argv[x], O_DIRECTORY);
if (fd == -1) {
EXT4_ENCRYPTION_MODE_AES_256_XTS;
policy.filenames_encryption_mode =
EXT4_ENCRYPTION_MODE_AES_256_CTS;
+ policy.flags = int_log2(pad >> 2);
memcpy(policy.master_key_descriptor, salt->key_desc,
EXT4_KEY_DESCRIPTOR_SIZE);
rc = ioctl(fd, EXT4_IOC_SET_ENCRYPTION_POLICY, &policy);
{
struct salt *salt;
char *keyring = NULL;
- int i, opt;
+ int i, opt, pad = 4;
- while ((opt = getopt(argc, argv, "k:S:vq")) != -1) {
+ while ((opt = getopt(argc, argv, "k:S:p:vq")) != -1) {
switch (opt) {
case 'k':
/* Specify a keyring. */
keyring = optarg;
break;
+ case 'p':
+ pad = atoi(optarg);
+ break;
case 'S':
/* Salt value for passphrase. */
parse_salt(optarg, 0);
insert_key_into_keyring(keyring, salt);
}
if (optind != argc)
- set_policy(NULL, argc, argv, optind);
+ set_policy(NULL, pad, argc, argv, optind);
clear_secrets();
exit(0);
}
char *key_ref_str = NULL;
char *keyring = NULL;
int add_passphrase = 0;
- int i, opt;
+ int i, c, opt, pad = 4;
- if (argc < 3) {
+ while ((c = getopt (argc, argv, "p:")) != EOF) {
+ switch (c) {
+ case 'p':
+ pad = atoi(optarg);
+ break;
+ }
+ }
+
+ if (argc < optind + 2) {
fprintf(stderr, "Missing required argument(s).\n\n");
fputs("USAGE:\n ", stderr);
fputs(cmd->cmd_help, stderr);
exit(1);
}
- strcpy(saltbuf.key_ref_str, argv[1]);
- if ((strlen(argv[1]) != (EXT4_KEY_DESCRIPTOR_SIZE * 2)) ||
- hex2byte(argv[1], (EXT4_KEY_DESCRIPTOR_SIZE * 2),
+ printf("arg %s\n", argv[optind]);
+ exit(0);
+
+ strcpy(saltbuf.key_ref_str, argv[optind]);
+ if ((strlen(argv[optind]) != (EXT4_KEY_DESCRIPTOR_SIZE * 2)) ||
+ hex2byte(argv[optind], (EXT4_KEY_DESCRIPTOR_SIZE * 2),
saltbuf.key_desc, EXT4_KEY_DESCRIPTOR_SIZE)) {
printf("Invalid key descriptor [%s]. Valid characters "
"are 0-9 and a-f, lower case. "
"Length must be %d.\n",
- argv[1], (EXT4_KEY_DESCRIPTOR_SIZE * 2));
+ argv[optind], (EXT4_KEY_DESCRIPTOR_SIZE * 2));
exit(1);
}
- validate_paths(argc, argv, 2);
- set_policy(&saltbuf, argc, argv, 2);
+ validate_paths(argc, argv, optind+1);
+ set_policy(&saltbuf, pad, argc, argv, optind+1);
exit(0);
}