svn commit: r360226 - in head/sbin: decryptcore dumpon

Conrad Meyer cem at FreeBSD.org
Thu Apr 23 17:56:49 UTC 2020


Author: cem
Date: Thu Apr 23 17:56:48 2020
New Revision: 360226
URL: https://svnweb.freebsd.org/changeset/base/360226

Log:
  EKCD: Preload error strings, PRNG seed; use OAEP padding
  
  Preload OpenSSL ERR string data so that the formatted error messages are
  vaguely meaningful. Add OpenSSL error information to the RSA_public_encrypt()
  operation failure case in one-time key generation.
  
  For obsolescent OpenSSL versions (*cough* FIPS *cough*), pre-seed the PRNG
  before entering Cap mode, as old versions of OpenSSL are unaware of kernel
  RNG interfaces aside from /dev/random (such as the long-supported kern.arnd, or
  the slightly more recent getentropy(3) or getrandom(2)). (RSA_public_encrypt()
  wants a seeded PRNG to randomize the "PS" portion of PKCS 1.5 padding or the
  "MGF" pseudo-random function in OAEP padding.)
  
  Switch dumpon to encrypt the one-time key with OAEP padding (recommended since
  1998; RFC2437) rather than the obsolescent PKCS 1.5 padding (1993; RFC2313).
  
  Switch decryptcore to attempt OAEP decryption first, and try PKCS 1.5
  decryption on failure. This is intended only for transition convenience, and
  we should obsolete support for non-OAEP padding in a release or two.
  
  Reviewed by:	markj
  MFC After:	2 weeks
  Sponsored by:	Dell EMC Isilon
  Differential Revision:	https://reviews.freebsd.org/D24534

Modified:
  head/sbin/decryptcore/decryptcore.c
  head/sbin/dumpon/dumpon.c

Modified: head/sbin/decryptcore/decryptcore.c
==============================================================================
--- head/sbin/decryptcore/decryptcore.c	Thu Apr 23 17:46:29 2020	(r360225)
+++ head/sbin/decryptcore/decryptcore.c	Thu Apr 23 17:56:48 2020	(r360226)
@@ -219,6 +219,10 @@ decrypt(int ofd, const char *privkeyfile, const char *
 
 	if (RSA_private_decrypt(kdk->kdk_encryptedkeysize,
 	    kdk->kdk_encryptedkey, key, privkey,
+	    RSA_PKCS1_OAEP_PADDING) != sizeof(key) &&
+	    /* Fallback to deprecated, formerly-used PKCS 1.5 padding. */
+	    RSA_private_decrypt(kdk->kdk_encryptedkeysize,
+	    kdk->kdk_encryptedkey, key, privkey,
 	    RSA_PKCS1_PADDING) != sizeof(key)) {
 		pjdlog_error("Unable to decrypt key: %s",
 		    ERR_error_string(ERR_get_error(), NULL));

Modified: head/sbin/dumpon/dumpon.c
==============================================================================
--- head/sbin/dumpon/dumpon.c	Thu Apr 23 17:46:29 2020	(r360225)
+++ head/sbin/dumpon/dumpon.c	Thu Apr 23 17:56:48 2020	(r360226)
@@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$");
 #ifdef HAVE_CRYPTO
 #include <openssl/err.h>
 #include <openssl/pem.h>
+#include <openssl/rand.h>
 #include <openssl/rsa.h>
 #endif
 
@@ -224,6 +225,18 @@ genkey(const char *pubkeyfile, struct diocskerneldump_
 	if (fp == NULL)
 		err(1, "Unable to open %s", pubkeyfile);
 
+	/*
+	 * Obsolescent OpenSSL only knows about /dev/random, and needs to
+	 * pre-seed before entering cap mode.  For whatever reason,
+	 * RSA_pub_encrypt uses the internal PRNG.
+	 */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+	{
+		unsigned char c[1];
+		RAND_bytes(c, 1);
+	}
+#endif
+
 	if (caph_enter() < 0)
 		err(1, "Unable to enter capability mode");
 
@@ -286,8 +299,9 @@ genkey(const char *pubkeyfile, struct diocskerneldump_
 	arc4random_buf(kdap->kda_key, sizeof(kdap->kda_key));
 	if (RSA_public_encrypt(sizeof(kdap->kda_key), kdap->kda_key,
 	    kdap->kda_encryptedkey, pubkey,
-	    RSA_PKCS1_PADDING) != (int)kdap->kda_encryptedkeysize) {
-		errx(1, "Unable to encrypt the one-time key.");
+	    RSA_PKCS1_OAEP_PADDING) != (int)kdap->kda_encryptedkeysize) {
+		errx(1, "Unable to encrypt the one-time key: %s",
+		    ERR_error_string(ERR_get_error(), NULL));
 	}
 	RSA_free(pubkey);
 }
@@ -470,8 +484,11 @@ main(int argc, char *argv[])
 		usage();
 
 #ifdef HAVE_CRYPTO
-	if (cipher != KERNELDUMP_ENC_NONE && pubkeyfile == NULL)
+	if (cipher != KERNELDUMP_ENC_NONE && pubkeyfile == NULL) {
 		errx(EX_USAGE, "-C option requires a public key file.");
+	} else if (pubkeyfile != NULL) {
+		ERR_load_crypto_strings();
+	}
 #else
 	if (pubkeyfile != NULL)
 		errx(EX_UNAVAILABLE,"Unable to use the public key."


More information about the svn-src-all mailing list