From bf34b4af70cc7e149f17a8ec8f422ede88b2fd4a Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sun, 8 Mar 2015 18:15:47 -0400 Subject: [PATCH] libext2fs: add ext2fs_digest_encode() Signed-off-by: Theodore Ts'o --- lib/ext2fs/Makefile.in | 14 ++++++ lib/ext2fs/digest_encode.c | 106 +++++++++++++++++++++++++++++++++++++++++++++ lib/ext2fs/ext2fs.h | 4 ++ 3 files changed, 124 insertions(+) create mode 100644 lib/ext2fs/digest_encode.c diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in index 30a393c2..63aab464 100644 --- a/lib/ext2fs/Makefile.in +++ b/lib/ext2fs/Makefile.in @@ -73,6 +73,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \ csum.o \ dblist.o \ dblist_dir.o \ + digest_encode.o \ dirblock.o \ dirhash.o \ dir_iterate.o \ @@ -149,6 +150,7 @@ SRCS= ext2_err.c \ $(srcdir)/csum.c \ $(srcdir)/dblist.c \ $(srcdir)/dblist_dir.c \ + $(srcdir)/digest_encode.c \ $(srcdir)/dirblock.c \ $(srcdir)/dirhash.c \ $(srcdir)/dir_iterate.c \ @@ -271,6 +273,11 @@ tst_badblocks: tst_badblocks.o $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR) $(Q) $(CC) -o tst_badblocks tst_badblocks.o $(ALL_LDFLAGS) \ $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) $(SYSLIBS) +tst_digest_encode: $(srcdir)/digest_encode.c $(srcdir)/ext2_fs.h + $(E) " CC $@" + $(Q) $(CC) $(ALL_LDFLAGS) $(ALL_CFLAGS) -o tst_digest_encode \ + $(srcdir)/sha256.c -DUNITTEST $(SYSLIBS) + tst_icount: $(srcdir)/icount.c $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR) $(E) " LD $@" $(Q) $(CC) -o tst_icount $(srcdir)/icount.c -DDEBUG \ @@ -572,6 +579,7 @@ clean:: tst_bitops tst_types tst_icount tst_super_size tst_csum \ tst_bitmaps tst_bitmaps_out tst_extents tst_inline \ tst_inline_data tst_inode_size tst_bitmaps_cmd.c \ + tst_digest_encode \ ext2_tdbtool mkjournal debug_cmds.c tst_cmds.c extent_cmds.c \ ../libext2fs.a ../libext2fs_p.a ../libext2fs_chk.a \ crc32c_table.h gen_crc32ctable tst_crc32c tst_libext2fs \ @@ -733,6 +741,12 @@ dblist_dir.o: $(srcdir)/dblist_dir.c $(top_builddir)/lib/config.h \ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \ $(srcdir)/bitops.h +digest_encode.o: $(srcdir)/digest_encode.c $(top_builddir)/lib/config.h \ + $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2fs.h \ + $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2_fs.h \ + $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \ + $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \ + $(srcdir)/bitops.h dirblock.o: $(srcdir)/dirblock.c $(top_builddir)/lib/config.h \ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \ diff --git a/lib/ext2fs/digest_encode.c b/lib/ext2fs/digest_encode.c new file mode 100644 index 00000000..85e7128b --- /dev/null +++ b/lib/ext2fs/digest_encode.c @@ -0,0 +1,106 @@ +/* + * lib/ext2fs/digest_encode.c + * + * A function to encode a digest using 64 characters that are valid in a + * filename per ext2fs rules. + * + * Written by Uday Savagaonkar, 2014. + * + * Copyright 2014 Google Inc. All Rights Reserved. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Library + * General Public License, version 2. + * %End-Header% + */ + +#include "config.h" +#if HAVE_SYS_TYPES_H +#include +#endif +#include "ext2fs.h" + +/** + * 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) +{ + static const char *lookup_table = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+"; + unsigned num_chunks, i; + char tmp_buf[3]; + unsigned c0, c1, c2, c3; + + 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]; + } + 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]; + } + return 4*(i+1); +} + +#ifdef UNITTEST +static const struct { + unsigned char d[32]; + const unsigned char *ed; +} tests[] = { + { { 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, + 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, + 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, + 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 }, + "JdlXcHj+CqHM7tpYz_wUKCIRbrozBojtKwzMBGNu4wfa" + }, + { { 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 }, + "6INf+_yapREqbbK3D5QiJa7aHnQLxOhN0cX+Hjpav0ka" + }, + { { 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 }, + "K0OAHjTb4GB5aBYKm4dy5mkpKNfz+hYz2ZE7uNX2gema" + }, +}; + +int main(int argc, char **argv) +{ + int i; + int errors = 0; + unsigned char tmp[44]; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + ext2fs_digest_encode(tmp, tests[i].d, 32); + printf("Test Digest %d: ", i); + if (memcmp(tmp, tests[i].ed, 44) != 0) { + printf("FAILED\n"); + errors++; + } else + printf("OK\n"); + } + return errors; +} + +#endif /* UNITTEST */ diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index 82c09d89..e9d91983 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -1085,6 +1085,10 @@ extern errcode_t void *priv_data), void *priv_data); +/* digest_encode.c */ +#define EXT2FS_DIGEST_SIZE EXT2FS_SHA256_LENGTH +extern int ext2fs_digest_encode(const char *src, unsigned long len, char *dst); + /* dirblock.c */ extern errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block, void *buf); -- 2.11.0