Page MenuHomeFreeBSD

D17322.diff
No OneTemporary

D17322.diff

Index: sbin/decryptcore/decryptcore.c
===================================================================
--- sbin/decryptcore/decryptcore.c
+++ sbin/decryptcore/decryptcore.c
@@ -119,7 +119,8 @@
decrypt(int ofd, const char *privkeyfile, const char *keyfile,
const char *input)
{
- uint8_t buf[KERNELDUMP_BUFFER_SIZE], key[KERNELDUMP_KEY_MAX_SIZE];
+ uint8_t buf[KERNELDUMP_BUFFER_SIZE], key[KERNELDUMP_KEY_MAX_SIZE],
+ chachaiv[4 * 4];
EVP_CIPHER_CTX *ctx;
const EVP_CIPHER *cipher;
FILE *fp;
@@ -207,6 +208,9 @@
case KERNELDUMP_ENC_AES_256_CBC:
cipher = EVP_aes_256_cbc();
break;
+ case KERNELDUMP_ENC_CHACHA20:
+ cipher = EVP_chacha20();
+ break;
default:
pjdlog_error("Invalid encryption algorithm.");
goto failed;
@@ -222,7 +226,23 @@
RSA_free(privkey);
privkey = NULL;
- EVP_DecryptInit_ex(ctx, cipher, NULL, key, kdk->kdk_iv);
+ if (kdk->kdk_encryption == KERNELDUMP_ENC_CHACHA20) {
+ /*
+ * OpenSSL treats the IV as 4 little-endian 32 bit integers.
+ *
+ * The first two represent a 64-bit counter, where the low half
+ * is the first 32-bit word.
+ *
+ * Start at counter block zero...
+ */
+ memset(chachaiv, 0, 4 * 2);
+ /*
+ * And use the IV specified by the dump.
+ */
+ memcpy(&chachaiv[4 * 2], kdk->kdk_iv, 4 * 2);
+ EVP_DecryptInit_ex(ctx, cipher, NULL, key, chachaiv);
+ } else
+ EVP_DecryptInit_ex(ctx, cipher, NULL, key, kdk->kdk_iv);
EVP_CIPHER_CTX_set_padding(ctx, 0);
explicit_bzero(key, sizeof(key));
Index: sbin/dumpon/dumpon.8
===================================================================
--- sbin/dumpon/dumpon.8
+++ sbin/dumpon/dumpon.8
@@ -28,7 +28,7 @@
.\" From: @(#)swapon.8 8.1 (Berkeley) 6/5/93
.\" $FreeBSD$
.\"
-.Dd May 1, 2019
+.Dd May 3, 2019
.Dt DUMPON 8
.Os
.Sh NAME
@@ -39,6 +39,7 @@
.Op Fl i Ar index
.Op Fl r
.Op Fl v
+.Op Fl C Ar cipher
.Op Fl k Ar pubkey
.Op Fl Z
.Op Fl z
@@ -47,6 +48,7 @@
.Op Fl i Ar index
.Op Fl r
.Op Fl v
+.Op Fl C Ar cipher
.Op Fl k Ar pubkey
.Op Fl Z
.Op Fl z
@@ -129,6 +131,14 @@
The
.Va pubkey
file should be a PEM-formatted RSA key of at least 1024 bits.
+.It Fl C Ar cipher
+Select the symmetric algorithm used for encrypted kernel crash dump.
+The default is
+.Dq chacha20
+but
+.Dq aes256-cbc
+is also available.
+(AES256-CBC mode does not work in conjunction with compression.)
.It Fl l
List the currently configured dump device(s), or /dev/null if no devices are
configured.
@@ -381,10 +391,6 @@
.Dv GZIO
option.
.Sh BUGS
-It is currently not possible to configure both compression and encryption.
-The encrypted dump format assumes that the kernel dump size is a multiple
-of the cipher block size, which may not be true when the dump is compressed.
-.Pp
Netdump only supports IPv4 at this time.
.Sh SECURITY CONSIDERATIONS
The current encrypted kernel core dump scheme does not provide integrity nor
Index: sbin/dumpon/dumpon.c
===================================================================
--- sbin/dumpon/dumpon.c
+++ sbin/dumpon/dumpon.c
@@ -276,7 +276,16 @@
if (kdap->kda_encryptedkey == NULL)
err(1, "Unable to allocate encrypted key");
- kdap->kda_encryption = KERNELDUMP_ENC_AES_256_CBC;
+ /*
+ * If no cipher was specified, choose a reasonable default.
+ */
+ if (kdap->kda_encryption == KERNELDUMP_ENC_NONE)
+ kdap->kda_encryption = KERNELDUMP_ENC_CHACHA20;
+ else if (kdap->kda_encryption == KERNELDUMP_ENC_AES_256_CBC &&
+ kdap->kda_compression != KERNELDUMP_COMP_NONE)
+ errx(EX_USAGE, "Unpadded AES256-CBC mode cannot be used "
+ "with compression.");
+
arc4random_buf(kdap->kda_key, sizeof(kdap->kda_key));
if (RSA_public_encrypt(sizeof(kdap->kda_key), kdap->kda_key,
kdap->kda_encryptedkey, pubkey,
@@ -378,7 +387,7 @@
struct diocskerneldump_arg ndconf, *kdap;
struct addrinfo hints, *res;
const char *dev, *pubkeyfile, *server, *client, *gateway;
- int ch, error, fd;
+ int ch, error, fd, cipher;
bool gzip, list, netdump, zstd, insert, remove;
uint8_t ins_idx;
@@ -387,9 +396,21 @@
pubkeyfile = NULL;
server = client = gateway = NULL;
ins_idx = KDA_APPEND;
+ cipher = KERNELDUMP_ENC_NONE;
- while ((ch = getopt(argc, argv, "c:g:i:k:lrs:vZz")) != -1)
+ while ((ch = getopt(argc, argv, "C:c:g:i:k:lrs:vZz")) != -1)
switch ((char)ch) {
+ case 'C':
+ if (strcasecmp(optarg, "chacha") == 0 ||
+ strcasecmp(optarg, "chacha20") == 0)
+ cipher = KERNELDUMP_ENC_CHACHA20;
+ else if (strcasecmp(optarg, "aes-cbc") == 0 ||
+ strcasecmp(optarg, "aes256-cbc") == 0)
+ cipher = KERNELDUMP_ENC_AES_256_CBC;
+ else
+ errx(EX_USAGE, "Unrecognized cipher algorithm "
+ "'%s'", optarg);
+ break;
case 'c':
client = optarg;
break;
@@ -451,7 +472,10 @@
if (argc != 1)
usage();
-#ifndef HAVE_CRYPTO
+#ifdef HAVE_CRYPTO
+ if (cipher != KERNELDUMP_ENC_NONE && pubkeyfile == NULL)
+ errx(EX_USAGE, "-C option requires a public key file.");
+#else
if (pubkeyfile != NULL)
errx(EX_UNAVAILABLE,"Unable to use the public key."
" Recompile dumpon with OpenSSL support.");
@@ -526,8 +550,10 @@
}
#ifdef HAVE_CRYPTO
- if (pubkeyfile != NULL)
+ if (pubkeyfile != NULL) {
+ kdap->kda_encryption = cipher;
genkey(pubkeyfile, kdap);
+ }
#endif
error = ioctl(fd, DIOCSKERNELDUMP, kdap);
if (error != 0)
Index: sys/kern/kern_shutdown.c
===================================================================
--- sys/kern/kern_shutdown.c
+++ sys/kern/kern_shutdown.c
@@ -80,6 +80,7 @@
#include <sys/vnode.h>
#include <sys/watchdog.h>
+#include <crypto/chacha20/chacha.h>
#include <crypto/rijndael/rijndael-api-fst.h>
#include <crypto/sha2/sha256.h>
@@ -180,8 +181,16 @@
struct kerneldumpcrypto {
uint8_t kdc_encryption;
uint8_t kdc_iv[KERNELDUMP_IV_MAX_SIZE];
- keyInstance kdc_ki;
- cipherInstance kdc_ci;
+ union {
+ struct {
+ keyInstance aes_ki;
+ cipherInstance aes_ci;
+ } u_aes;
+ struct chacha_ctx u_chacha;
+ } u;
+#define kdc_ki u.u_aes.aes_ki
+#define kdc_ci u.u_aes.aes_ci
+#define kdc_chacha u.u_chacha
uint32_t kdc_dumpkeysize;
struct kerneldumpkey kdc_dumpkey[];
};
@@ -1024,6 +1033,9 @@
if (rijndael_makeKey(&kdc->kdc_ki, DIR_ENCRYPT, 256, key) <= 0)
goto failed;
break;
+ case KERNELDUMP_ENC_CHACHA20:
+ chacha_keysetup(&kdc->kdc_chacha, key, 256);
+ break;
default:
goto failed;
}
@@ -1072,6 +1084,9 @@
goto out;
}
break;
+ case KERNELDUMP_ENC_CHACHA20:
+ chacha_ivsetup(&kdc->kdc_chacha, kdc->kdc_iv, NULL);
+ break;
default:
error = EINVAL;
goto out;
@@ -1208,11 +1223,12 @@
}
if (kda->kda_compression != KERNELDUMP_COMP_NONE) {
/*
- * We currently can't support simultaneous encryption and
- * compression because our only encryption mode is an unpadded
- * block cipher, go figure. This is low hanging fruit to fix.
+ * We can't support simultaneous unpadded block cipher
+ * encryption and compression because there is no guarantee the
+ * length of the compressed result is exactly a multiple of the
+ * cipher block size.
*/
- if (kda->kda_encryption != KERNELDUMP_ENC_NONE) {
+ if (kda->kda_encryption == KERNELDUMP_ENC_AES_256_CBC) {
error = EOPNOTSUPP;
goto cleanup;
}
@@ -1368,6 +1384,9 @@
return (EIO);
}
break;
+ case KERNELDUMP_ENC_CHACHA20:
+ chacha_encrypt_bytes(&kdc->kdc_chacha, buf, buf, size);
+ break;
default:
return (EINVAL);
}
Index: sys/sys/kerneldump.h
===================================================================
--- sys/sys/kerneldump.h
+++ sys/sys/kerneldump.h
@@ -63,6 +63,7 @@
#define KERNELDUMP_ENC_NONE 0
#define KERNELDUMP_ENC_AES_256_CBC 1
+#define KERNELDUMP_ENC_CHACHA20 2
#define KERNELDUMP_BUFFER_SIZE 4096
#define KERNELDUMP_IV_MAX_SIZE 32

File Metadata

Mime Type
text/plain
Expires
Mon, Jan 19, 6:55 AM (4 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27734985
Default Alt Text
D17322.diff (7 KB)

Event Timeline