From owner-svn-soc-all@FreeBSD.ORG Mon Jul 29 18:21:26 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 D6B355AD for ; Mon, 29 Jul 2013 18:21:26 +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 C18AF26F3 for ; Mon, 29 Jul 2013 18:21:26 +0000 (UTC) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.14.7/8.14.7) with ESMTP id r6TILQcw075990 for ; Mon, 29 Jul 2013 18:21:26 GMT (envelope-from def@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.7/8.14.6/Submit) id r6TILQGS075957 for svn-soc-all@FreeBSD.org; Mon, 29 Jul 2013 18:21:26 GMT (envelope-from def@FreeBSD.org) Date: Mon, 29 Jul 2013 18:21:26 GMT Message-Id: <201307291821.r6TILQGS075957@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: r255309 - in soc2013/def/crashdump-head: sbin/savecore sys/conf sys/crypto sys/crypto/hmac sys/kern sys/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: Mon, 29 Jul 2013 18:21:27 -0000 Author: def Date: Mon Jul 29 18:21:26 2013 New Revision: 255309 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=255309 Log: Import pefs' key derivation function. Assume a constant size of tweak. Added: soc2013/def/crashdump-head/sys/crypto/hmac/ soc2013/def/crashdump-head/sys/crypto/hmac/hmac.c soc2013/def/crashdump-head/sys/crypto/hmac/hmac.h Modified: soc2013/def/crashdump-head/sbin/savecore/Makefile soc2013/def/crashdump-head/sbin/savecore/decryptfile.c soc2013/def/crashdump-head/sbin/savecore/decryptfile.h soc2013/def/crashdump-head/sbin/savecore/savecore.c soc2013/def/crashdump-head/sys/conf/files soc2013/def/crashdump-head/sys/crypto/xts.h 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/sbin/savecore/Makefile ============================================================================== --- soc2013/def/crashdump-head/sbin/savecore/Makefile Mon Jul 29 18:02:29 2013 (r255308) +++ soc2013/def/crashdump-head/sbin/savecore/Makefile Mon Jul 29 18:21:26 2013 (r255309) @@ -1,12 +1,14 @@ # $FreeBSD$ SYS= ${.CURDIR}/../../sys -.PATH: ${SYS}/crypto/camellia ${SYS}/crypto/rijndael ${SYS}/crypto +.PATH: ${SYS}/crypto/camellia ${SYS}/crypto/rijndael +.PATH: ${SYS}/crypto/hmac ${SYS}/crypto/sha2 ${SYS}/crypto PROG= savecore SRCS= ${PROG}.c decryptfile.c SRCS+= rijndael-api.c rijndael-api-fst.c rijndael-alg-fst.c SRCS+= camellia.c +SRCS+= hmac.c sha2.c SRCS+= xts.c DPADD= ${LIBZ} LDADD= -lz Modified: soc2013/def/crashdump-head/sbin/savecore/decryptfile.c ============================================================================== --- soc2013/def/crashdump-head/sbin/savecore/decryptfile.c Mon Jul 29 18:02:29 2013 (r255308) +++ soc2013/def/crashdump-head/sbin/savecore/decryptfile.c Mon Jul 29 18:21:26 2013 (r255309) @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include "decryptfile.h" int @@ -40,9 +42,25 @@ return (saved); } +void +hkdf_expand(struct xts_ctx *ctx, const uint8_t *masterkey, uint8_t *key, + int idx, const uint8_t *magic, size_t magicsize) +{ + uint8_t byte_idx = idx; + + hmac_init(&ctx->o.pctx_hmac, CRYPTO_SHA2_512_HMAC, + masterkey, KERNELDUMP_KEY_SIZE); + hmac_update(&ctx->o.pctx_hmac, key, KERNELDUMP_KEY_SIZE); + hmac_update(&ctx->o.pctx_hmac, magic, magicsize); + hmac_update(&ctx->o.pctx_hmac, &byte_idx, sizeof(byte_idx)); + hmac_final(&ctx->o.pctx_hmac, key, KERNELDUMP_KEY_SIZE); +} + FILE * dopen(const char *fname, const char *mode, const struct kerneldumpheader *h) { + uint8_t key[KERNELDUMP_KEY_SIZE]; + struct xts_ctx ctx; decFile *fd; FILE *fp; @@ -57,16 +75,26 @@ fd = (decFile *)malloc(sizeof(decFile)); fd->fp = fp; + fd->keysize = h->keysize; - memcpy(fd->key, h->key, KERNELDUMP_KEY_SIZE); - fd->tweaksize = h->tweaksize; + memcpy(fd->key, h->key, fd->keysize); memcpy(fd->tweak, h->tweak, KERNELDUMP_TWEAK_SIZE); + bzero(&fd->tweak_ctx, sizeof(fd->tweak_ctx)); + bzero(&fd->data_ctx, sizeof(fd->data_ctx)); + bzero(key, KERNELDUMP_KEY_SIZE); + + hkdf_expand(&ctx, fd->key, key, 1, kerneldump_magic, sizeof(kerneldump_magic)); + xts_alg_aes.pa_keysetup(&fd->data_ctx, key, fd->keysize << 3); + + hkdf_expand(&ctx, fd->key, key, 2, kerneldump_magic, sizeof(kerneldump_magic)); + xts_alg_aes.pa_keysetup(&fd->tweak_ctx, key, fd->keysize << 3); + + bzero(&ctx, sizeof(ctx)); + bzero(key, KERNELDUMP_KEY_SIZE); + fd->offset = 0; fd->buf_used = 0; - rijndael_set_key(&fd->tweak_ctx, fd->key, fd->keysize << 3); - rijndael_set_key(&fd->data_ctx, fd->key, fd->keysize << 3); - return (funopen(fd, NULL, dwrite, NULL, dclose)); } Modified: soc2013/def/crashdump-head/sbin/savecore/decryptfile.h ============================================================================== --- soc2013/def/crashdump-head/sbin/savecore/decryptfile.h Mon Jul 29 18:02:29 2013 (r255308) +++ soc2013/def/crashdump-head/sbin/savecore/decryptfile.h Mon Jul 29 18:21:26 2013 (r255309) @@ -8,10 +8,9 @@ FILE *fp; int keysize; char key[KERNELDUMP_KEY_SIZE]; - int tweaksize; char tweak[KERNELDUMP_TWEAK_SIZE]; - rijndael_ctx tweak_ctx; - rijndael_ctx data_ctx; + struct xts_ctx tweak_ctx; + struct xts_ctx data_ctx; off_t offset; #define PEFS_SECTOR_SIZE 4096 char buf[PEFS_SECTOR_SIZE]; Modified: soc2013/def/crashdump-head/sbin/savecore/savecore.c ============================================================================== --- soc2013/def/crashdump-head/sbin/savecore/savecore.c Mon Jul 29 18:02:29 2013 (r255308) +++ soc2013/def/crashdump-head/sbin/savecore/savecore.c Mon Jul 29 18:21:26 2013 (r255309) @@ -123,7 +123,6 @@ fprintf(f, " Dump Parity: %u\n", h->parity); fprintf(f, " Bounds: %d\n", bounds); fprintf(f, " Key length: %d bits\n", h->keysize << 3); - fprintf(f, " Tweak length: %d bits\n", h->tweaksize << 3); switch(status) { case STATUS_BAD: Modified: soc2013/def/crashdump-head/sys/conf/files ============================================================================== --- soc2013/def/crashdump-head/sys/conf/files Mon Jul 29 18:02:29 2013 (r255308) +++ soc2013/def/crashdump-head/sys/conf/files Mon Jul 29 18:21:26 2013 (r255309) @@ -537,6 +537,7 @@ crypto/camellia/camellia-api.c optional crypto | ipsec crypto/des/des_ecb.c optional crypto | ipsec crypto/des/des_setkey.c optional crypto | ipsec +crypto/hmac/hmac.c optional crypto | encrypt_crash crypto/rc4/rc4.c optional netgraph_mppc_encryption | kgssapi crypto/rijndael/rijndael-alg-fst.c optional crypto | geom_bde | \ ipsec | random | wlan_ccmp Added: soc2013/def/crashdump-head/sys/crypto/hmac/hmac.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2013/def/crashdump-head/sys/crypto/hmac/hmac.c Mon Jul 29 18:21:26 2013 (r255309) @@ -0,0 +1,179 @@ +/*- + * Copyright (c) 2005-2010 Pawel Jakub Dawidek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#ifdef _KERNEL +#include +#include +#else +#include +#include +#include +#endif + +#include + +#include + +#ifndef _KERNEL +#define panic(...) do { \ + fprintf(stderr, __VA_ARGS__); \ + abort(); \ +} while (0) +#endif + +typedef void hmac_hash_init_t(union hmac_hash_ctx *ctx); +typedef void hmac_hash_update_t(union hmac_hash_ctx *ctx, const uint8_t *, + size_t); +typedef void hmac_hash_final_t(uint8_t *, union hmac_hash_ctx *ctx); + +struct hmac_hash { + u_int block_len; + u_int digest_len; + hmac_hash_init_t *init; + hmac_hash_update_t *update; + hmac_hash_final_t *final; +}; + +static const struct hmac_hash hmac_hash_sha256 = { + .block_len = SHA256_BLOCK_LENGTH, + .digest_len = SHA256_DIGEST_LENGTH, + .init = (hmac_hash_init_t *)&SHA256_Init, + .update = (hmac_hash_update_t *)&SHA256_Update, + .final = (hmac_hash_final_t *)&SHA256_Final, +}; + +static const struct hmac_hash hmac_hash_sha384 = { + .block_len = SHA384_BLOCK_LENGTH, + .digest_len = SHA384_DIGEST_LENGTH, + .init = (hmac_hash_init_t *)&SHA384_Init, + .update = (hmac_hash_update_t *)&SHA384_Update, + .final = (hmac_hash_final_t *)&SHA384_Final, +}; + +static const struct hmac_hash hmac_hash_sha512 = { + .block_len = SHA512_BLOCK_LENGTH, + .digest_len = SHA512_DIGEST_LENGTH, + .init = (hmac_hash_init_t *)&SHA512_Init, + .update = (hmac_hash_update_t *)&SHA512_Update, + .final = (hmac_hash_final_t *)&SHA512_Final, +}; + +void +hmac_init(struct hmac_ctx *ctx, int algo, const uint8_t *hkey, size_t hkeylen) +{ + const struct hmac_hash *hash; + u_int i; + + switch (algo) { + case CRYPTO_SHA2_256_HMAC: + hash = &hmac_hash_sha256; + break; + case CRYPTO_SHA2_384_HMAC: + hash = &hmac_hash_sha384; + break; + case CRYPTO_SHA2_512_HMAC: + hash = &hmac_hash_sha512; + break; + default: + panic("HMAC: invalid alorithm: %d.", algo); + return; + } + + ctx->hash = hash; + bzero(ctx->k_opad, hash->block_len); + if (hkeylen == 0) + ; /* do nothing */ + else if (hkeylen <= hash->block_len) + bcopy(hkey, ctx->k_opad, hkeylen); + else { + /* + * If key is longer than HMAC_BLOCK_LENGTH_MAX bytes + * reset it to key = HASH(key). + */ + hash->init(&ctx->hash_ctx); + hash->update(&ctx->hash_ctx, hkey, hkeylen); + hash->final(ctx->k_opad, &ctx->hash_ctx); + } + + /* Perform inner SHA512. */ + hash->init(&ctx->hash_ctx); + /* XOR key ipad value. */ + for (i = 0; i < hash->block_len; i++) + ctx->k_opad[i] ^= 0x36; + hash->update(&ctx->hash_ctx, ctx->k_opad, hash->block_len); + /* XOR key opad value. */ + for (i = 0; i < hash->block_len; i++) + ctx->k_opad[i] ^= 0x36 ^ 0x5c; +} + +void +hmac_update(struct hmac_ctx *ctx, const uint8_t *data, + size_t datasize) +{ + + ctx->hash->update(&ctx->hash_ctx, data, datasize); +} + +void +hmac_final(struct hmac_ctx *ctx, uint8_t *md, size_t mdsize) +{ + const struct hmac_hash *hash = ctx->hash; + u_char digest[HMAC_DIGEST_LENGTH_MAX]; + + if (mdsize == 0 || mdsize > hash->digest_len) { + panic("HMAC: invalid digest buffer size: %zu (digest length %u).", + mdsize, hash->digest_len); + return; + } + + hash->final(digest, &ctx->hash_ctx); + /* Perform outer SHA512. */ + hash->init(&ctx->hash_ctx); + hash->update(&ctx->hash_ctx, ctx->k_opad, hash->block_len); + hash->update(&ctx->hash_ctx, digest, sizeof(digest)); + hash->final(digest, &ctx->hash_ctx); + bzero(ctx, sizeof(*ctx)); + + bcopy(digest, md, mdsize); +} + +void +hmac(int algo, const uint8_t *hkey, size_t hkeysize, const uint8_t *data, + size_t datasize, uint8_t *md, size_t mdsize) +{ + struct hmac_ctx ctx; + + hmac_init(&ctx, algo, hkey, hkeysize); + hmac_update(&ctx, data, datasize); + /* mdsize == 0 means "Give me the whole hash!" */ + if (mdsize == 0) + mdsize = ctx.hash->digest_len; + hmac_final(&ctx, md, mdsize); +} Added: soc2013/def/crashdump-head/sys/crypto/hmac/hmac.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2013/def/crashdump-head/sys/crypto/hmac/hmac.h Mon Jul 29 18:21:26 2013 (r255309) @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 2005-2011 Pawel Jakub Dawidek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SYS_CRYPTO_HMAC_H +#define _SYS_CRYPTO_HMAC_H + +#include + +#define HMAC_BLOCK_LENGTH_MAX SHA512_BLOCK_LENGTH +#define HMAC_DIGEST_LENGTH_MAX SHA512_DIGEST_LENGTH + +struct hmac_hash; + +struct hmac_ctx { + const struct hmac_hash *hash; + union hmac_hash_ctx { + SHA256_CTX sha256_ctx; + SHA384_CTX sha384_ctx; + SHA512_CTX sha512_ctx; + } hash_ctx; + u_char k_opad[HMAC_BLOCK_LENGTH_MAX]; +}; + +void hmac_init(struct hmac_ctx *ctx, int algo, const uint8_t *hkey, + size_t hkeylen); +void hmac_update(struct hmac_ctx *ctx, const uint8_t *data, + size_t datasize); +void hmac_final(struct hmac_ctx *ctx, uint8_t *md, size_t mdsize); +void hmac(int algo, const uint8_t *hkey, size_t hkeysize, + const uint8_t *data, size_t datasize, uint8_t *md, size_t mdsize); + +#endif /* _SYS_CRYPTO_HMAC_H */ Modified: soc2013/def/crashdump-head/sys/crypto/xts.h ============================================================================== --- soc2013/def/crashdump-head/sys/crypto/xts.h Mon Jul 29 18:02:29 2013 (r255308) +++ soc2013/def/crashdump-head/sys/crypto/xts.h Mon Jul 29 18:21:26 2013 (r255309) @@ -31,6 +31,7 @@ #include #include +#include #define XTS_BLK_BYTES 16 #define XTS_BLK_MASK (XTS_BLK_BYTES - 1) @@ -42,6 +43,7 @@ union { camellia_ctx pctx_camellia; rijndael_ctx pctx_aes; + struct hmac_ctx pctx_hmac; } o; } __aligned(CACHE_LINE_SIZE); Modified: soc2013/def/crashdump-head/sys/kern/kern_shutdown.c ============================================================================== --- soc2013/def/crashdump-head/sys/kern/kern_shutdown.c Mon Jul 29 18:02:29 2013 (r255308) +++ soc2013/def/crashdump-head/sys/kern/kern_shutdown.c Mon Jul 29 18:21:26 2013 (r255309) @@ -86,7 +86,7 @@ #include -#include +#include #ifndef PANIC_REBOOT_WAIT_TIME #define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */ @@ -145,8 +145,8 @@ int dumping; /* system is dumping */ int rebooting; /* system is rebooting */ static struct dumperinfo dumper; /* our selected dumper */ -static rijndael_ctx dumper_tweak_ctx; -static rijndael_ctx dumper_data_ctx; +static struct kerneldumpkey dumperkey; +static struct kerneldumpbuffer dumperbuffer; /* Context information for dump-debuggers. */ static struct pcb dumppcb; /* Registers. */ @@ -851,6 +851,8 @@ if (dumper.dumper != NULL) return (EBUSY); dumper = *di; + dumper.kdk = &dumperkey; + dumper.kdb = &dumperbuffer; kerneldump_crypto_init(&dumper); @@ -867,6 +869,8 @@ dump_write(struct dumperinfo *di, void *virtual, vm_offset_t physical, off_t offset, size_t length) { + struct kerneldumpkey *kdk; + struct kerneldumpbuffer *kdb; size_t resid; int error; @@ -879,65 +883,126 @@ return (ENOSPC); } + kdk = di->kdk; + kdb = di->kdb; + /* Write kernel dump headers. */ - if (di->realoffset == 0 || offset == di->mediaoffset + di->mediasize - + if (kdb->realoffset == 0 || offset == di->mediaoffset + di->mediasize - sizeof(struct kerneldumpheader)) { - di->realoffset = offset + length; + kdb->realoffset = 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->realoffset, di->buf_used)); - } - - while (length + di->buf_used >= DUMPER_BUFSIZE) { - resid = DUMPER_BUFSIZE - 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, - di->offset, di->tweak, DUMPER_BUFSIZE, - di->buf, di->buf); + 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); - error = (di->dumper(di->priv, di->buf, physical, di->realoffset, DUMPER_BUFSIZE)); + error = (di->dumper(di->priv, kdb->buf, physical, kdb->realoffset, KERNELDUMP_BUFFER_SIZE)); if (error) return (error); virtual = (void *)((char *)virtual + resid); length -= resid; - di->buf_used = 0; - di->realoffset += resid; - di->offset += DUMPER_BUFSIZE; + 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(di->buf + di->buf_used, virtual, length); - di->buf_used += length; + memcpy(kdb->buf + kdb->used, virtual, length); + kdb->used += length; } return (0); } +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) +{ + uint8_t byte_idx = idx; + + hmac_init(&ctx->o.pctx_hmac, CRYPTO_SHA2_512_HMAC, + masterkey, KERNELDUMP_KEY_SIZE); + hmac_update(&ctx->o.pctx_hmac, key, KERNELDUMP_KEY_SIZE); + hmac_update(&ctx->o.pctx_hmac, magic, magicsize); + hmac_update(&ctx->o.pctx_hmac, &byte_idx, sizeof(byte_idx)); + hmac_final(&ctx->o.pctx_hmac, key, KERNELDUMP_KEY_SIZE); +} + void kerneldump_crypto_init(struct dumperinfo *di) { + if (di->kdk == NULL || di->kdb == NULL) { + printf("Attempt to initialize a non-existing kernel dump key and buffer."); + return; + } + /* In the future the tweak will be set via sysctl. */ - arc4rand(kerneldumptweak, KERNELDUMP_TWEAK_SIZE, 0); - di->key = (char *)kerneldumpkey; - di->tweak = kerneldumptweak; - di->tweak_ctx = &dumper_tweak_ctx; - di->data_ctx = &dumper_data_ctx; - di->buf_used = 0; - di->realoffset = 0; - di->offset = 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); + arc4rand(kerneldump_tweak, KERNELDUMP_TWEAK_SIZE, 0); + + di->kdk = kerneldump_set_key(di->kdk, KERNELDUMP_KEY_SIZE, kerneldump_key, kerneldump_tweak); + di->kdb = kerneldump_set_buffer(di->kdb); +} + +struct kerneldumpkey * +kerneldump_set_key(struct kerneldumpkey *kdk, int keysize, char *masterkey, char *tweak) +{ + uint8_t key[KERNELDUMP_KEY_SIZE]; + struct xts_ctx ctx; + + if (kdk == NULL) { + printf("Cannot initialize kernel dump key."); + return (NULL); + } + + kdk->keysize = keysize; + memcpy(kdk->key, masterkey, kdk->keysize); + memcpy(kdk->tweak, tweak, KERNELDUMP_TWEAK_SIZE); + bzero(&kdk->tweak_ctx, sizeof(kdk->tweak_ctx)); + bzero(&kdk->data_ctx, sizeof(kdk->data_ctx)); + bzero(key, KERNELDUMP_KEY_SIZE); + + kerneldump_hkdf_expand(&ctx, kdk->key, key, 1, kerneldump_magic, sizeof(kerneldump_magic)); + xts_alg_aes.pa_keysetup(&kdk->data_ctx, key, kdk->keysize << 3); + + kerneldump_hkdf_expand(&ctx, kdk->key, key, 2, kerneldump_magic, sizeof(kerneldump_magic)); + xts_alg_aes.pa_keysetup(&kdk->tweak_ctx, key, kdk->keysize << 3); + + bzero(&ctx, sizeof(ctx)); + bzero(key, KERNELDUMP_KEY_SIZE); + + return (kdk); +} + +struct kerneldumpbuffer * +kerneldump_set_buffer(struct kerneldumpbuffer *kdb) +{ + if (kdb == NULL) { + printf("Cannot initialize kernel dump buffer."); + return (NULL); + } + + kdb->used = 0; + kdb->realoffset = 0; + kdb->offset = 0; + + return (kdb); } void @@ -957,9 +1022,8 @@ strncpy(kdh->versionstring, version, sizeof(kdh->versionstring)); if (panicstr != NULL) strncpy(kdh->panicstring, panicstr, sizeof(kdh->panicstring)); - kdh->keysize = KERNELDUMP_KEY_SIZE; - strncpy(kdh->key, dumper.key, kdh->keysize); - kdh->tweaksize = KERNELDUMP_TWEAK_SIZE; - strncpy(kdh->tweak, dumper.tweak, kdh->tweaksize); + kdh->keysize = dumper.kdk->keysize; + strncpy(kdh->key, dumper.kdk->key, kdh->keysize); + strncpy(kdh->tweak, dumper.kdk->tweak, KERNELDUMP_TWEAK_SIZE); kdh->parity = kerneldump_parity(kdh); } Modified: soc2013/def/crashdump-head/sys/sys/conf.h ============================================================================== --- soc2013/def/crashdump-head/sys/sys/conf.h Mon Jul 29 18:02:29 2013 (r255308) +++ soc2013/def/crashdump-head/sys/sys/conf.h Mon Jul 29 18:21:26 2013 (r255309) @@ -323,7 +323,8 @@ EVENTHANDLER_DECLARE(dev_clone, dev_clone_fn); /* Stuff relating to kernel-dump */ -#define DUMPER_BUFSIZE 4096 +struct kerneldumpkey; +struct kerneldumpbuffer; struct dumperinfo { dumper_t *dumper; /* Dumping function. */ @@ -332,14 +333,8 @@ 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. */ - char *key; /* Key information. */ - char *tweak; /* Tweak. */ - void *tweak_ctx; /* Tweak context. */ - void *data_ctx; /* Data context. */ - uint8_t buf[DUMPER_BUFSIZE]; /* Raw data buffer. */ - u_int buf_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. */ + struct kerneldumpkey *kdk; /* Kernel dump key. */ + struct kerneldumpbuffer *kdb; /* Kernel dump buffer. */ }; 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 Mon Jul 29 18:02:29 2013 (r255308) +++ soc2013/def/crashdump-head/sys/sys/kerneldump.h Mon Jul 29 18:21:26 2013 (r255309) @@ -39,6 +39,7 @@ #define _SYS_KERNELDUMP_H #include +#include #if BYTE_ORDER == LITTLE_ENDIAN #define dtoh32(x) __bswap32(x) @@ -81,15 +82,16 @@ uint64_t dumptime; uint32_t blocksize; char hostname[64]; - char versionstring[168]; - char panicstring[168]; + char versionstring[170]; + char panicstring[170]; int keysize; char key[KERNELDUMP_KEY_SIZE]; - int tweaksize; char tweak[KERNELDUMP_TWEAK_SIZE]; uint32_t parity; }; +static const char kerneldump_magic[] = "PEFSKEY-V1"; + /* * Parity calculation is endian insensitive. */ @@ -110,15 +112,33 @@ /* * Constant key for kernel crash dumps. */ -static const char kerneldumpkey[32] = { +static char kerneldump_key[KERNELDUMP_KEY_SIZE] = { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }; -static char kerneldumptweak[KERNELDUMP_TWEAK_SIZE]; +static char kerneldump_tweak[KERNELDUMP_TWEAK_SIZE]; + +struct kerneldumpkey { + int keysize; + char key[KERNELDUMP_KEY_SIZE]; + char tweak[KERNELDUMP_TWEAK_SIZE]; + struct xts_ctx data_ctx; + struct xts_ctx tweak_ctx; +}; + +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. */ +}; 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); void mkdumpheader(struct kerneldumpheader *kdh, char *magic, uint32_t archver, uint64_t dumplen, uint32_t blksz);