From owner-svn-soc-all@FreeBSD.ORG Wed Jul 31 19:11:31 2013 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id ECEDC173 for ; Wed, 31 Jul 2013 19:11:30 +0000 (UTC) (envelope-from def@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id CB4A52356 for ; Wed, 31 Jul 2013 19:11:30 +0000 (UTC) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.14.7/8.14.7) with ESMTP id r6VJBU9Y034625 for ; Wed, 31 Jul 2013 19:11:30 GMT (envelope-from def@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.7/8.14.6/Submit) id r6VJBUPV034620 for svn-soc-all@FreeBSD.org; Wed, 31 Jul 2013 19:11:30 GMT (envelope-from def@FreeBSD.org) Date: Wed, 31 Jul 2013 19:11:30 GMT Message-Id: <201307311911.r6VJBUPV034620@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to def@FreeBSD.org using -f From: def@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r255402 - in soc2013/def/crashdump-head/sys: amd64/conf kern sys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 31 Jul 2013 19:11:31 -0000 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 #include @@ -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);