socsvn commit: r255402 - in soc2013/def/crashdump-head/sys: amd64/conf kern sys

def at FreeBSD.org def at FreeBSD.org
Wed Jul 31 19:11:31 UTC 2013


Author: def
Date: Wed Jul 31 19:11:30 2013
New Revision: 255402
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=255402

Log:
  Encrypt 512-byte chunks in 4096-byte data units. Enable the encryption when ENCRYPT_CRASH option is added.

Modified:
  soc2013/def/crashdump-head/sys/amd64/conf/GENERIC
  soc2013/def/crashdump-head/sys/kern/kern_shutdown.c
  soc2013/def/crashdump-head/sys/sys/conf.h
  soc2013/def/crashdump-head/sys/sys/kerneldump.h

Modified: soc2013/def/crashdump-head/sys/amd64/conf/GENERIC
==============================================================================
--- soc2013/def/crashdump-head/sys/amd64/conf/GENERIC	Wed Jul 31 18:18:02 2013	(r255401)
+++ soc2013/def/crashdump-head/sys/amd64/conf/GENERIC	Wed Jul 31 19:11:30 2013	(r255402)
@@ -341,4 +341,4 @@
 device		virtio_balloon	# VirtIO Memory Balloon device
 
 # Unattended encrypted kernel crash dumps
-option		ENCRYPT_CRASH
+options		ENCRYPT_CRASH

Modified: soc2013/def/crashdump-head/sys/kern/kern_shutdown.c
==============================================================================
--- soc2013/def/crashdump-head/sys/kern/kern_shutdown.c	Wed Jul 31 18:18:02 2013	(r255401)
+++ soc2013/def/crashdump-head/sys/kern/kern_shutdown.c	Wed Jul 31 19:11:30 2013	(r255402)
@@ -42,6 +42,7 @@
 #include "opt_panic.h"
 #include "opt_sched.h"
 #include "opt_watchdog.h"
+#include "opt_crash.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -145,8 +146,10 @@
 int dumping;				/* system is dumping */
 int rebooting;				/* system is rebooting */
 static struct dumperinfo dumper;	/* our selected dumper */
+#ifdef ENCRYPT_CRASH
 static struct kerneldumpkey dumperkey;
 static struct kerneldumpbuffer dumperbuffer;
+#endif
 
 /* Context information for dump-debuggers. */
 static struct pcb dumppcb;		/* Registers. */
@@ -851,10 +854,12 @@
 	if (dumper.dumper != NULL)
 		return (EBUSY);
 	dumper = *di;
+
+#ifdef ENCRYPT_CRASH
 	dumper.kdk = &dumperkey;
 	dumper.kdb = &dumperbuffer;
-
 	kerneldump_crypto_init(&dumper);
+#endif
 
 	wantcopy = strlcpy(dumpdevname, devname, sizeof(dumpdevname));
 	if (wantcopy >= sizeof(dumpdevname)) {
@@ -869,10 +874,13 @@
 dump_write(struct dumperinfo *di, void *virtual, vm_offset_t physical,
     off_t offset, size_t length)
 {
+#ifdef ENCRYPT_CRASH
 	struct kerneldumpkey *kdk;
 	struct kerneldumpbuffer *kdb;
-	size_t resid;
-	int error;
+	int error, len;
+	off_t sector_index, devblk_index;
+	char *ptr;
+#endif
 
 	if (length != 0 && (offset < di->mediaoffset ||
 	    offset - di->mediaoffset + length > di->mediasize)) {
@@ -883,54 +891,52 @@
 		return (ENOSPC);
 	}
 
+#ifdef ENCRYPT_CRASH
 	kdk = di->kdk;
 	kdb = di->kdb;
 
 	/* Write kernel dump headers. */
-	if (kdb->realoffset == 0 || offset == di->mediaoffset + di->mediasize -
+	if (kdb->kdhoffset == 0 || offset == di->mediaoffset + di->mediasize -
 		sizeof(struct kerneldumpheader)) {
-		kdb->realoffset = offset + length;
+		kdb->kdhoffset = offset + length;
 		return (di->dumper(di->priv, virtual, physical, offset, length));
 	}
 
-	/* The last dump_write call in the current crash. */
-	if (virtual == NULL && physical == 0 && offset == 0 && length == 0) {
-		xts_block_encrypt(&xts_alg_aes, &kdk->tweak_ctx, &kdk->data_ctx,
-				kdb->offset, kdk->tweak, kdb->used,
-				kdb->buf, kdb->buf);
-		return (di->dumper(di->priv, di->kdb->buf, physical, kdb->realoffset, kdb->used));
-	}
-
-	while (length + kdb->used >= KERNELDUMP_BUFFER_SIZE) {
-		resid = KERNELDUMP_BUFFER_SIZE - kdb->used;
-		memcpy(kdb->buf + kdb->used, virtual, resid);
-		kdb->used += resid;
-
-		xts_block_encrypt(&xts_alg_aes, &kdk->tweak_ctx, &kdk->data_ctx,
-				kdb->offset, kdk->tweak, KERNELDUMP_BUFFER_SIZE,
-				kdb->buf, kdb->buf);
+	sector_index = (offset - kdb->kdhoffset)/KERNELDUMP_SECTOR_SIZE;
+	devblk_index = (offset - kdb->kdhoffset - sector_index*KERNELDUMP_SECTOR_SIZE)/KERNELDUMP_DEVBLK_SIZE;
+
+	while (length > 0) {
+		memcpy(kdb->buf, virtual, KERNELDUMP_DEVBLK_SIZE);
 
-		error = (di->dumper(di->priv, kdb->buf, physical, kdb->realoffset, KERNELDUMP_BUFFER_SIZE));
+		if (devblk_index == 0)
+			xts_start(&xts_alg_aes, &kdk->tweak_ctx, kdb->tweak, offset, kdk->tweak);
+
+		ptr = kdb->buf;
+		len = KERNELDUMP_DEVBLK_SIZE;
+		while (len > 0) {
+			xts_fullblock(xts_alg_aes.pa_encrypt, &kdk->data_ctx, kdb->tweak, ptr, ptr);
+			ptr += XTS_BLK_BYTES;
+			len -= XTS_BLK_BYTES;
+		}
+
+		error = (di->dumper(di->priv, kdb->buf, physical, offset, KERNELDUMP_DEVBLK_SIZE));
 
 		if (error)
 			return (error);
 
-		virtual = (void *)((char *)virtual + resid);
-		length -= resid;
-		kdb->used = 0;
-		kdb->realoffset += resid;
-		kdb->offset += KERNELDUMP_BUFFER_SIZE;
-	}
-
-	/* We still have less than blocksize of data to dump. */
-	if (length > 0) {
-		memcpy(kdb->buf + kdb->used, virtual, length);
-		kdb->used += length;
+		virtual = (void *)((char *)virtual + KERNELDUMP_DEVBLK_SIZE);
+		length -= KERNELDUMP_DEVBLK_SIZE;
+		offset += KERNELDUMP_DEVBLK_SIZE;
+		devblk_index = (devblk_index+1)%(KERNELDUMP_SECTOR_SIZE/KERNELDUMP_DEVBLK_SIZE);
 	}
 
 	return (0);
+#else /* ENCRYPT_CRASH */
+	return (di->dumper(di->priv, virtual, physical, offset, length));
+#endif /* ENCRYPT_CRASH */
 }
 
+#ifdef ENCRYPT_CRASH
 static void
 kerneldump_hkdf_expand(struct xts_ctx *ctx, const uint8_t *masterkey, uint8_t *key,
 			int idx, const uint8_t *magic, size_t magicsize)
@@ -998,12 +1004,11 @@
 		return (NULL);
 	}
 
-	kdb->used = 0;
-	kdb->realoffset = 0;
-	kdb->offset = 0;
+	kdb->kdhoffset = 0;
 
 	return (kdb);
 }
+#endif /* ENCRYPT_CRASH */
 
 void
 mkdumpheader(struct kerneldumpheader *kdh, char *magic, uint32_t archver,
@@ -1022,8 +1027,10 @@
 	strncpy(kdh->versionstring, version, sizeof(kdh->versionstring));
 	if (panicstr != NULL)
 		strncpy(kdh->panicstring, panicstr, sizeof(kdh->panicstring));
+#ifdef ENCRYPT_CRASH
 	kdh->keysize = dumper.kdk->keysize;
 	strncpy(kdh->key, dumper.kdk->key, kdh->keysize);
 	strncpy(kdh->tweak, dumper.kdk->tweak, KERNELDUMP_TWEAK_SIZE);
+#endif
 	kdh->parity = kerneldump_parity(kdh);
 }

Modified: soc2013/def/crashdump-head/sys/sys/conf.h
==============================================================================
--- soc2013/def/crashdump-head/sys/sys/conf.h	Wed Jul 31 18:18:02 2013	(r255401)
+++ soc2013/def/crashdump-head/sys/sys/conf.h	Wed Jul 31 19:11:30 2013	(r255402)
@@ -323,8 +323,10 @@
 EVENTHANDLER_DECLARE(dev_clone, dev_clone_fn);
 
 /* Stuff relating to kernel-dump */
+#ifdef ENCRYPT_CRASH
 struct kerneldumpkey;
 struct kerneldumpbuffer;
+#endif
 
 struct dumperinfo {
 	dumper_t *dumper;		/* Dumping function. */
@@ -333,8 +335,10 @@
 	u_int	maxiosize;		/* Max size allowed for an individual I/O */
 	off_t   mediaoffset;		/* Initial offset in bytes. */
 	off_t   mediasize;		/* Space available in bytes. */
+#ifdef ENCRYPT_CRASH
 	struct kerneldumpkey *kdk;	/* Kernel dump key. */
 	struct kerneldumpbuffer	*kdb;	/* Kernel dump buffer. */
+#endif
 };
 
 int set_dumper(struct dumperinfo *, const char *_devname);

Modified: soc2013/def/crashdump-head/sys/sys/kerneldump.h
==============================================================================
--- soc2013/def/crashdump-head/sys/sys/kerneldump.h	Wed Jul 31 18:18:02 2013	(r255401)
+++ soc2013/def/crashdump-head/sys/sys/kerneldump.h	Wed Jul 31 19:11:30 2013	(r255402)
@@ -109,6 +109,7 @@
 }
 
 #ifdef _KERNEL
+#ifdef ENCRYPT_CRASH
 /*
  * Constant key for kernel crash dumps.
  */
@@ -129,16 +130,17 @@
 };
 
 struct kerneldumpbuffer {
-#define	KERNELDUMP_BUFFER_SIZE	4096
-	uint8_t buf[KERNELDUMP_BUFFER_SIZE];	/* Raw data buffer. */
-	u_int	used;				/* Number of bytes used in the buffer. */
-	off_t	offset;				/* Last used offset in a xts_block_encrypt call. */
-	off_t	realoffset;			/* Last used offset in a dump_write call. */
+#define	KERNELDUMP_DEVBLK_SIZE	512
+#define	KERNELDUMP_SECTOR_SIZE	4096
+	uint8_t		buf[KERNELDUMP_DEVBLK_SIZE];	/* Raw data buffer. */
+	uint64_t	tweak[XTS_BLK_BYTES / 8];	/* Tweak value used in XTS. */
+	off_t		kdhoffset;			/* Offset value of the first kdh. */
 };
 
 void kerneldump_crypto_init(struct dumperinfo *di);
 struct kerneldumpkey *kerneldump_set_key(struct kerneldumpkey *kdk, int keysize, char *key, char *tweak);
 struct kerneldumpbuffer *kerneldump_set_buffer(struct kerneldumpbuffer *kdb);
+#endif /* ENCRYPT_CRASH */
 
 void mkdumpheader(struct kerneldumpheader *kdh, char *magic, uint32_t archver,
     uint64_t dumplen, uint32_t blksz);


More information about the svn-soc-all mailing list