* Pad luks header to 512 sector size. We need read/write in whole
sector anyway and space is unused (wiped in luksFormat) so there is
no need for read/seek/write exercise.
* Rework read/write blockwise to not split operation to many pieces.
thanks to Sebastian Andrzej Siewior:
The buffer has to be aligned due to the O_DIRECT in open(). Currently a small
blocksize buffer is allocated and everything is read in multiple reads and
copied back to the original buffer. In my case AFEKSize gets computed to 64000
which results in 125 reads with 512 bytes each.
This patch changes this behavior to a single operation where the majority is
read()/write() plus an optional fixup in case the request is not modulo block
size.
* Use posix_memalign and check for alignment if available.
Othewise use old align functions. Add autoconf to detect posix_memalign.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@74
36d66b0a-2a48-0410-832c-
cd162a569da5
+2009-07-28 Milan Broz <mbroz@redhat.com>
+ * Pad luks header to 512 sector size.
+ * Rework read/write blockwise to not split operation to many pieces.
+ * Use posix_memalign if available.
+
2009-07-22 Milan Broz <mbroz@redhat.com>
* Fix segfault if provided slot in luksKillslot is invalid.
* Remove unneeded timeout when remove of temporary device succeeded.
2009-07-22 Milan Broz <mbroz@redhat.com>
* Fix segfault if provided slot in luksKillslot is invalid.
* Remove unneeded timeout when remove of temporary device succeeded.
AC_PREREQ(2.57)
AC_INIT(cryptsetup,1.0.7)
AC_CONFIG_SRCDIR(src/cryptsetup.c)
AC_PREREQ(2.57)
AC_INIT(cryptsetup,1.0.7)
AC_CONFIG_SRCDIR(src/cryptsetup.c)
+AC_CONFIG_MACRO_DIR([m4])
AM_CONFIG_HEADER([config.h:config.h.in])
AM_INIT_AUTOMAKE(dist-bzip2)
AM_CONFIG_HEADER([config.h:config.h.in])
AM_INIT_AUTOMAKE(dist-bzip2)
AM_CONDITIONAL(BUILD_LIBDEVMAPPER, test x$build_static = xyes)
AM_CONDITIONAL(SHARED_LIBDEVMAPPER, test x$build_shared = xyes)
AM_CONDITIONAL(BUILD_LIBDEVMAPPER, test x$build_static = xyes)
AM_CONDITIONAL(SHARED_LIBDEVMAPPER, test x$build_shared = xyes)
+AC_CHECK_FUNCS([posix_memalign])
dnl ==========================================================================
AM_CONDITIONAL(STATIC_CRYPTSETUP, test x$enable_static = xyes)
dnl ==========================================================================
AM_CONDITIONAL(STATIC_CRYPTSETUP, test x$enable_static = xyes)
#define SECTOR_SHIFT 9
#define SECTOR_SIZE (1 << SECTOR_SHIFT)
#define SECTOR_SHIFT 9
#define SECTOR_SIZE (1 << SECTOR_SHIFT)
+#define DEFAULT_ALIGNMENT 4096
/* private struct crypt_options flags */
/* private struct crypt_options flags */
-/* Credits go to Michal's padlock patches for this alignment code */
+static int get_alignment(int fd)
+{
+ int alignment = DEFAULT_ALIGNMENT;
+
+#ifdef _PC_REC_XFER_ALIGN
+ alignment = fpathconf(fd, _PC_REC_XFER_ALIGN);
+ if (alignment < 0)
+ alignment = DEFAULT_ALIGNMENT;
+#endif
+ return alignment;
+}
-static void *aligned_malloc(char **base, int size, int alignment)
+static void *aligned_malloc(void **base, int size, int alignment)
+#ifdef HAVE_POSIX_MEMALIGN
+ return posix_memalign(base, alignment, size) ? NULL : *base;
+#else
+/* Credits go to Michal's padlock patches for this alignment code */
char *ptr;
ptr = malloc(size + alignment);
char *ptr;
ptr = malloc(size + alignment);
ptr += alignment - ((long)(ptr) & (alignment - 1));
}
return ptr;
ptr += alignment - ((long)(ptr) & (alignment - 1));
}
return ptr;
static int sector_size(int fd)
{
int bsize;
static int sector_size(int fd)
{
int bsize;
-ssize_t write_blockwise(int fd, const void *orig_buf, size_t count)
+ssize_t write_blockwise(int fd, const void *orig_buf, size_t count)
- char *padbuf; char *padbuf_base;
- char *buf = (char *)orig_buf;
- int r = 0;
- int hangover; int solid; int bsize;
+ void *hangover_buf, *hangover_buf_base = NULL;
+ void *buf, *buf_base = NULL;
+ int r, hangover, solid, bsize, alignment;
+ ssize_t ret = -1;
if ((bsize = sector_size(fd)) < 0)
return bsize;
hangover = count % bsize;
solid = count - hangover;
if ((bsize = sector_size(fd)) < 0)
return bsize;
hangover = count % bsize;
solid = count - hangover;
+ alignment = get_alignment(fd);
+
+ if ((long)orig_buf & (alignment - 1)) {
+ buf = aligned_malloc(&buf_base, count, alignment);
+ if (!buf)
+ goto out;
+ memcpy(buf, orig_buf, count);
+ } else
+ buf = (void *)orig_buf;
- padbuf = aligned_malloc(&padbuf_base, bsize, bsize);
- if(padbuf == NULL) return -ENOMEM;
+ r = write(fd, buf, solid);
+ if (r < 0 || r != solid)
+ goto out;
- while(solid) {
- memcpy(padbuf, buf, bsize);
- r = write(fd, padbuf, bsize);
- if(r < 0 || r != bsize) goto out;
+ if (hangover) {
+ hangover_buf = aligned_malloc(&hangover_buf_base, bsize, alignment);
+ if (!hangover_buf)
+ goto out;
- solid -= bsize;
- buf += bsize;
- }
- if(hangover) {
- r = read(fd,padbuf,bsize);
+ r = read(fd, hangover_buf, bsize);
if(r < 0 || r != bsize) goto out;
if(r < 0 || r != bsize) goto out;
- lseek(fd,-bsize,SEEK_CUR);
- memcpy(padbuf,buf,hangover);
+ r = lseek(fd, -bsize, SEEK_CUR);
+ if (r < 0)
+ goto out;
+ memcpy(hangover_buf, buf + solid, hangover);
- r = write(fd,padbuf, bsize);
+ r = write(fd, hangover_buf, bsize);
if(r < 0 || r != bsize) goto out;
if(r < 0 || r != bsize) goto out;
+ free(hangover_buf_base);
- free(padbuf_base);
- return (buf-(char *)orig_buf)?(buf-(char *)orig_buf):r;
-
+ if (buf != orig_buf)
+ free(buf_base);
+ return ret;
}
ssize_t read_blockwise(int fd, void *orig_buf, size_t count) {
}
ssize_t read_blockwise(int fd, void *orig_buf, size_t count) {
- char *padbuf; char *padbuf_base;
- char *buf = (char *)orig_buf;
- int r = 0;
- int step;
- int bsize;
+ void *hangover_buf, *hangover_buf_base;
+ void *buf, *buf_base = NULL;
+ int r, hangover, solid, bsize, alignment;
+ ssize_t ret = -1;
if ((bsize = sector_size(fd)) < 0)
return bsize;
if ((bsize = sector_size(fd)) < 0)
return bsize;
- padbuf = aligned_malloc(&padbuf_base, bsize, bsize);
- if(padbuf == NULL) return -ENOMEM;
+ hangover = count % bsize;
+ solid = count - hangover;
+ alignment = get_alignment(fd);
- while(count) {
- r = read(fd,padbuf,bsize);
- if(r < 0 || r != bsize) {
- set_error("read failed in read_blockwise.\n");
+ if ((long)orig_buf & (alignment - 1)) {
+ buf = aligned_malloc(&buf_base, count, alignment);
+ if (!buf)
- }
- step = count<bsize?count:bsize;
- memcpy(buf,padbuf,step);
- buf += step;
- count -= step;
+ } else
+ buf = orig_buf;
+
+ r = read(fd, buf, solid);
+ if(r < 0 || r != solid) {
+ set_error("read failed in read_blockwise.\n");
+ goto out;
+
+ if (hangover) {
+ hangover_buf = aligned_malloc(&hangover_buf_base, bsize, alignment);
+ if (!hangover_buf)
+ goto out;
+ r = read(fd, hangover_buf, bsize);
+ if (r < 0 || r != bsize)
+ goto out;
+
+ memcpy(buf + solid, hangover_buf, hangover);
+ free(hangover_buf_base);
+ }
+ ret = count;
- free(padbuf_base);
- return (buf-(char *)orig_buf)?(buf-(char *)orig_buf):r;
+ if (buf != orig_buf) {
+ memcpy(orig_buf, buf, count);
+ free(buf_base);
+ }
+ return ret;
}
memcpy(&convHdr, hdr, sizeof(struct luks_phdr));
}
memcpy(&convHdr, hdr, sizeof(struct luks_phdr));
+ memset(&convHdr._padding, 0, sizeof(convHdr._padding));
/* Convert every uint16/32_t item to network byte order */
convHdr.version = htons(hdr->version);
/* Convert every uint16/32_t item to network byte order */
convHdr.version = htons(hdr->version);
struct {
uint32_t active;
struct {
uint32_t active;
/* parameters used for password processing */
uint32_t passwordIterations;
char passwordSalt[LUKS_SALTSIZE];
/* parameters used for password processing */
uint32_t passwordIterations;
char passwordSalt[LUKS_SALTSIZE];
-
- /* parameters used for AF store/load */
+
+ /* parameters used for AF store/load */
uint32_t keyMaterialOffset;
uint32_t keyMaterialOffset;
} keyblock[LUKS_NUMKEYS];
} keyblock[LUKS_NUMKEYS];
+
+ /* Align it to 512 sector size */
+ char _padding[432];
};
struct luks_masterkey {
};
struct luks_masterkey {