socsvn commit: r255309 - in soc2013/def/crashdump-head: sbin/savecore sys/conf sys/crypto sys/crypto/hmac sys/kern sys/sys
def at FreeBSD.org
def at FreeBSD.org
Mon Jul 29 18:21:27 UTC 2013
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 <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <opencrypto/cryptodev.h>
+#include <crypto/hmac/hmac.h>
#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 <pjd at FreeBSD.org>
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#ifdef _KERNEL
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#include <opencrypto/cryptodev.h>
+
+#include <crypto/hmac/hmac.h>
+
+#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 <pjd at FreeBSD.org>
+ * 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 <crypto/sha2/sha2.h>
+
+#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 <crypto/camellia/camellia.h>
#include <crypto/rijndael/rijndael.h>
+#include <crypto/hmac/hmac.h>
#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 <sys/signalvar.h>
-#include <crypto/xts.h>
+#include <opencrypto/cryptodev.h>
#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 <machine/endian.h>
+#include <crypto/xts.h>
#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);
More information about the svn-soc-all
mailing list