Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 15 Jul 2013 13:47:07 GMT
From:      def@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r254804 - in soc2013/def/crashdump-head/sys: kern sys
Message-ID:  <201307151347.r6FDl78N000956@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: def
Date: Mon Jul 15 13:47:07 2013
New Revision: 254804
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=254804

Log:
  Encrypt a crash dump with a constant AES key and make it suitable for savecore - the first version.

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

Modified: soc2013/def/crashdump-head/sys/kern/kern_shutdown.c
==============================================================================
--- soc2013/def/crashdump-head/sys/kern/kern_shutdown.c	Mon Jul 15 12:18:36 2013	(r254803)
+++ soc2013/def/crashdump-head/sys/kern/kern_shutdown.c	Mon Jul 15 13:47:07 2013	(r254804)
@@ -867,6 +867,8 @@
 dump_write(struct dumperinfo *di, void *virtual, vm_offset_t physical,
     off_t offset, size_t length)
 {
+	size_t resid;
+	int error;
 
 	if (length != 0 && (offset < di->mediaoffset ||
 	    offset - di->mediaoffset + length > di->mediasize)) {
@@ -876,7 +878,49 @@
 		    (uintmax_t)length, (intmax_t)di->mediasize);
 		return (ENOSPC);
 	}
-	return (di->dumper(di->priv, virtual, physical, offset, length));
+
+	/* Write kernel dump headers. */
+	if (di->offset == 0 || offset == di->kdhoffset) {
+		di->offset = 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, di->tweak_ctx, di->data_ctx,
+				di->offset, di->tweak, di->buf_used,
+				di->buf, di->buf);
+		return (di->dumper(di->priv, di->buf, physical, di->offset, di->buf_used));
+	}
+
+	offset = di->offset;
+
+	while (length + di->buf_used >= di->blocksize) {
+		resid = qmin(length, di->blocksize - di->buf_used);
+		memcpy(di->buf + di->buf_used, virtual, resid);
+		di->buf_used += resid;
+		xts_block_encrypt(&xts_alg_aes, di->tweak_ctx, di->data_ctx,
+				offset, di->tweak, di->blocksize,
+				di->buf, di->buf);
+		error = (di->dumper(di->priv, di->buf, physical, offset, di->buf_used));
+
+		if (error)
+			return (error);
+
+		virtual = (void *)((char *)virtual + resid);
+		offset += resid;
+		length -= resid;
+		di->buf_used = 0;
+		di->offset = offset;
+	}
+
+	/* We still have less than blocksize of data to dump. */
+	if (length > 0) {
+		memcpy(di->buf + di->buf_used, virtual, length);
+		di->buf_used += length;
+	}
+
+	return (0);
 }
 
 void
@@ -888,6 +932,9 @@
 	di->tweak = kerneldumptweak;
 	di->tweak_ctx = &dumper_tweak_ctx;
 	di->data_ctx = &dumper_data_ctx;
+	di->buf_used = 0;
+	di->offset = 0;
+	di->kdhoffset = 0;
 	rijndael_set_key(di->tweak_ctx, di->key, KERNELDUMP_KEY_SIZE << 3);
 	rijndael_set_key(di->data_ctx, di->key, KERNELDUMP_KEY_SIZE << 3);
 }
@@ -914,4 +961,6 @@
 	kdh->tweaksize = KERNELDUMP_TWEAK_SIZE;
 	strncpy(kdh->tweak, dumper.tweak, kdh->tweaksize);
 	kdh->parity = kerneldump_parity(kdh);
+
+	dumper.kdhoffset = dumper.mediaoffset + dumper.mediasize - sizeof(*kdh);
 }

Modified: soc2013/def/crashdump-head/sys/sys/conf.h
==============================================================================
--- soc2013/def/crashdump-head/sys/sys/conf.h	Mon Jul 15 12:18:36 2013	(r254803)
+++ soc2013/def/crashdump-head/sys/sys/conf.h	Mon Jul 15 13:47:07 2013	(r254804)
@@ -333,8 +333,12 @@
 	off_t   mediasize;	/* Space available in bytes. */
 	char	*key;		/* Key information. */
 	char	*tweak;		/* Tweak. */
-	void	*tweak_ctx;
-	void	*data_ctx;
+	void	*tweak_ctx;	/* Tweak context. */
+	void	*data_ctx;	/* Data context. */
+	uint8_t buf[512];	/* Raw data buffer. */
+	u_int	buf_used;	/* Number of bytes used in the buffer. */
+	off_t	offset;		/* Last used offset in a dump_write call. */
+	off_t	kdhoffset;	/* Offset of the second kernel dump header. */
 };
 
 int set_dumper(struct dumperinfo *, const char *_devname);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201307151347.r6FDl78N000956>