Date: Sat, 21 Sep 2013 20:45:53 GMT From: def@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r257574 - soc2013/def/crashdump-head/sbin/dumpkey Message-ID: <201309212045.r8LKjrKN080274@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: def Date: Sat Sep 21 20:45:53 2013 New Revision: 257574 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=257574 Log: dumpkey program which generates an AES key, encrypts it with RSA and transfers it to kernel via sysctl. Added: soc2013/def/crashdump-head/sbin/dumpkey/ soc2013/def/crashdump-head/sbin/dumpkey/Makefile soc2013/def/crashdump-head/sbin/dumpkey/dumpkey.c Added: soc2013/def/crashdump-head/sbin/dumpkey/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2013/def/crashdump-head/sbin/dumpkey/Makefile Sat Sep 21 20:45:53 2013 (r257574) @@ -0,0 +1,15 @@ +SYS= ${.CURDIR}/../../sys +.PATH: ${SYS}/crypto ${SYS}/crypto/rijndael +.PATH: ${SYS}/crypto/hmac ${SYS}/crypto/sha2 + +PROG= dumpkey +SRCS= ${PROG}.c +SRCS+= rijndael-api.c rijndael-api-fst.c rijndael-alg-fst.c +SRCS+= hmac.c xts.c sha2.c +CFLAGS+=-I${SYS} +DPADD+= ${LIBCRYPTO} +LDADD+= -lcrypto +WARNS?= 2 +NO_MAN= + +.include <bsd.prog.mk> Added: soc2013/def/crashdump-head/sbin/dumpkey/dumpkey.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2013/def/crashdump-head/sbin/dumpkey/dumpkey.c Sat Sep 21 20:45:53 2013 (r257574) @@ -0,0 +1,227 @@ +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <sys/sysctl.h> +#include <sys/kerneldump.h> +#include <crypto/xts.h> +#include <opencrypto/cryptodev.h> + +#define OPENSSL_NO_SHA +#include <openssl/conf.h> +#include <openssl/err.h> +#include <openssl/rsa.h> +#include <openssl/pem.h> + +#define PATH_DEVRANDOM "/dev/random" + +static 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); +} + +static void +usage(void) +{ + printf("usage: dumpkey -p public_key\n"); +} + +static int +read_data(char *buf, size_t size, const char *file) +{ + FILE *fp; + + fp = fopen(file, "r"); + + if (fp == NULL) + return (-1); + + if (fread(buf, size, 1, fp) != 1) { + fclose(fp); + + return (-1); + } + + fclose(fp); + + return (0); +} + +static int +random_data(char *buf, size_t size) +{ + if(read_data(buf, size, PATH_DEVRANDOM)) + return (-1); + + return (0); +} + +static int +encrypt_key(char *key, size_t keysize, char *encrypted_key, RSA *public_key, char *public_key_file) +{ + FILE *fp; + + fp = fopen(public_key_file, "r"); + + if (fp == NULL) + return (-1); + + public_key = PEM_read_RSA_PUBKEY(fp, &public_key, NULL, NULL); + fclose(fp); + + if (public_key == NULL) + return (-1); + + if (RSA_public_encrypt(keysize, key, encrypted_key, public_key, RSA_PKCS1_PADDING) == -1) + return (-1); + + return (0); +} + +static int +expand_key(char *key, size_t keysize, char *data_key, char *tweak_key) +{ + struct xts_ctx ctx; + + bzero(&ctx, sizeof(ctx)); + bzero(data_key, keysize); + bzero(tweak_key, keysize); + + hkdf_expand(&ctx, key, data_key, 1, kerneldump_magic, sizeof(kerneldump_magic)); + memcpy(tweak_key, data_key, keysize); + hkdf_expand(&ctx, key, tweak_key, 2, kerneldump_magic, sizeof(kerneldump_magic)); + + bzero(&ctx, sizeof(ctx)); + + return (0); +} + +static int +set_data_key(char *key, size_t keysize) +{ + return (sysctlbyname("kern.dump.key.data", NULL, 0, key, keysize)); +} + +static int +set_tweak_key(char *key, size_t keysize) +{ + return (sysctlbyname("kern.dump.key.tweak", NULL, 0, key, keysize)); +} + +static int +set_encrypted_key(char *key, size_t keysize) +{ + return (sysctlbyname("kern.dump.key.encrypted", NULL, 0, key, keysize)); +} + +static int +set_tweak(char *tweak, size_t tweaksize) +{ + return (sysctlbyname("kern.dump.tweak", NULL, 0, tweak, tweaksize)); +} + +int +main(int argc, char **argv) +{ + char *public_key_file; + char key[KERNELDUMP_KEY_SIZE], encrypted_key[KERNELDUMP_ENCRYPTED_KEY_SIZE]; + char data_key[KERNELDUMP_KEY_SIZE], tweak_key[KERNELDUMP_KEY_SIZE]; + char tweak[KERNELDUMP_TWEAK_SIZE]; + int ch, error; + RSA *public_key; + + ERR_load_crypto_strings(); + OpenSSL_add_all_algorithms(); + OPENSSL_config(NULL); + + error = 0; + public_key_file = NULL; + public_key = RSA_new(); + + while ((ch = getopt(argc, argv, "p:")) != -1) + switch (ch) { + case 'p': + public_key_file = optarg; + break; + default: + usage(); + error = 1; + goto out; + } + + if (public_key_file == NULL) { + usage(); + error = 1; + goto out; + } + + if (random_data(key, KERNELDUMP_KEY_SIZE)) { + printf("Error: cannot generate a symmetric key.\n"); + error = 1; + goto out; + } + + if (encrypt_key(key, KERNELDUMP_KEY_SIZE, encrypted_key, public_key, public_key_file)) { + printf("Error: cannot encrypt a symmetric key.\n"); + error = 1; + goto out; + } + + if (set_encrypted_key(encrypted_key, KERNELDUMP_ENCRYPTED_KEY_SIZE)) { + printf("Error: cannot set an encrypted symmetric key.\n"); + error = 1; + goto out; + } + + if (expand_key(key, KERNELDUMP_KEY_SIZE, data_key, tweak_key)) { + printf("Error: cannot expand a symmetric key."); + error = 1; + goto out; + } + + if (set_data_key(data_key, KERNELDUMP_KEY_SIZE)) { + printf("Error: cannot set a symmetric data key.\n"); + error = 1; + goto out; + } + + if (set_tweak_key(tweak_key, KERNELDUMP_KEY_SIZE)) { + printf("Error: cannot set a symmetric tweak key."); + error = 1; + goto out; + } + + if (random_data(tweak, KERNELDUMP_TWEAK_SIZE)) { + printf("Error: cannot generate a tweak.\n"); + error = 1; + goto out; + } + + if (set_tweak(tweak, KERNELDUMP_TWEAK_SIZE)) { + printf("Error: cannot set a tweak.\n"); + error = 1; + goto out; + } + +out: + bzero(key, KERNELDUMP_KEY_SIZE); + bzero(encrypted_key, KERNELDUMP_ENCRYPTED_KEY_SIZE); + bzero(data_key, KERNELDUMP_KEY_SIZE); + bzero(tweak_key, KERNELDUMP_KEY_SIZE); + bzero(tweak, KERNELDUMP_TWEAK_SIZE); + RSA_free(public_key); + + ERR_free_strings(); + EVP_cleanup(); + + return (0); +} +
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201309212045.r8LKjrKN080274>