diff mbox series

[v3] Remove the superfluous salt parameter

Message ID 20190621132528.4616-1-laszlo@ashin.hu
State Accepted
Headers show
Series [v3] Remove the superfluous salt parameter | expand

Commit Message

'Darko Komljenovic' via swupdate June 21, 2019, 1:25 p.m. UTC
As it turned out salt is not needed for decryption of encrypted files or
images. Using salt is still recommended for generating keys and IVs from
passwords but was always unneeded for doing actual encryption and
decryption.

Best is to not start with a password at the first place, just random
generate the key and IV like this:

```
key=$(dd if=/dev/random bs=32 count=1 | xxd -ps -cols 64)
iv=$(dd if=/dev/random bs=16 count=1 | xxd -ps -cols 32)
```

Refer to the following discussion for more info:

https://groups.google.com/forum/#!topic/swupdate/JBopZ5LNZis

Signed-off-by: Laszlo Ashin <laszlo@ashin.hu>
---
 core/cpio_utils.c               |  4 +---
 core/util.c                     | 23 ++++-------------------
 corelib/swupdate_decrypt.c      | 16 +---------------
 corelib/test/test_crypt.c       | 19 ++++++-------------
 doc/source/encrypted_images.rst | 17 +++++++----------
 include/sslapi.h                |  4 ++--
 include/util.h                  |  1 -
 7 files changed, 21 insertions(+), 63 deletions(-)
diff mbox series

Patch

diff --git a/core/cpio_utils.c b/core/cpio_utils.c
index a464108..182ff1a 100644
--- a/core/cpio_utils.c
+++ b/core/cpio_utils.c
@@ -299,7 +299,6 @@  int copyfile(int fdin, void *out, unsigned int nbytes, unsigned long *offs, unsi
 	unsigned int md_len = 0;
 	unsigned char *aes_key = NULL;
 	unsigned char *ivt = NULL;
-	unsigned char *salt;
 
 	struct InputState input_state = {
 		.fdin = fdin,
@@ -348,8 +347,7 @@  int copyfile(int fdin, void *out, unsigned int nbytes, unsigned long *offs, unsi
 	if (encrypted) {
 		aes_key = get_aes_key();
 		ivt = get_aes_ivt();
-		salt = get_aes_salt();
-		decrypt_state.dcrypt = swupdate_DECRYPT_init(aes_key, ivt, salt);
+		decrypt_state.dcrypt = swupdate_DECRYPT_init(aes_key, ivt);
 		if (!decrypt_state.dcrypt) {
 			ERROR("decrypt initialization failure, aborting");
 			ret = -EFAULT;
diff --git a/core/util.c b/core/util.c
index ea4ad8a..3a72b29 100644
--- a/core/util.c
+++ b/core/util.c
@@ -30,12 +30,10 @@ 
 /*
  * key  is 256 bit for aes_256
  * ivt  is 128 bit
- * salt is  64 bit
  */
 struct decryption_key {
 	unsigned char key[32];
 	unsigned char ivt[16];
-	unsigned char salt[8];
 };
 
 static struct decryption_key *aes_key = NULL;
@@ -416,26 +414,22 @@  int count_elem_list(struct imglist *list)
 int load_decryption_key(char *fname)
 {
 	FILE *fp;
-	char *b1 = NULL, *b2 = NULL, *b3 = NULL;
+	char *b1 = NULL, *b2 = NULL;
 	int ret;
 
 	fp = fopen(fname, "r");
 	if (!fp)
 		return -EBADF;
 
-	ret = fscanf(fp, "%ms %ms %ms", &b1, &b2, &b3);
+	ret = fscanf(fp, "%ms %ms", &b1, &b2);
 	switch (ret) {
 		case 2:
-			b3 = NULL;
 			DEBUG("Read decryption key and initialization vector from file %s.", fname);
 			break;
-		case 3:
-			DEBUG("Read decryption key, initialization vector, and salt from file %s.", fname);
-			break;
 		default:
 			if (b1 != NULL)
 				free(b1);
-			fprintf(stderr, "File with decryption key is not in the format <key> <ivt> nor <key> <ivt> <salt>\n");
+			fprintf(stderr, "File with decryption key is not in the format <key> <ivt>\n");
 			fclose(fp);
 			return -EINVAL;
 	}
@@ -449,15 +443,12 @@  int load_decryption_key(char *fname)
 		return -ENOMEM;
 
 	ret = ascii_to_bin(aes_key->key,  b1, sizeof(aes_key->key)  * 2) |
-	      ascii_to_bin(aes_key->ivt,  b2, sizeof(aes_key->ivt)  * 2) |
-	      ascii_to_bin(aes_key->salt, b3, sizeof(aes_key->salt) * 2);
+	      ascii_to_bin(aes_key->ivt,  b2, sizeof(aes_key->ivt)  * 2);
 
 	if (b1 != NULL)
 		free(b1);
 	if (b2 != NULL)
 		free(b2);
-	if (b3 != NULL)
-		free(b3);
 
 	if (ret) {
 		fprintf(stderr, "Keys are invalid\n");
@@ -479,12 +470,6 @@  unsigned char *get_aes_ivt(void) {
 	return aes_key->ivt;
 }
 
-unsigned char *get_aes_salt(void) {
-	if (!aes_key)
-		return NULL;
-	return aes_key->salt;
-}
-
 char** string_split(const char* in, const char d)
 {
 	char** result    = 0;
diff --git a/corelib/swupdate_decrypt.c b/corelib/swupdate_decrypt.c
index 273196e..e1043d8 100644
--- a/corelib/swupdate_decrypt.c
+++ b/corelib/swupdate_decrypt.c
@@ -17,7 +17,7 @@ 
 #include "sslapi.h"
 #include "util.h"
 
-struct swupdate_digest *swupdate_DECRYPT_init(unsigned char *key, unsigned char *iv, unsigned char *salt)
+struct swupdate_digest *swupdate_DECRYPT_init(unsigned char *key, unsigned char *iv)
 {
 	struct swupdate_digest *dgst;
 	int ret;
@@ -34,20 +34,6 @@  struct swupdate_digest *swupdate_DECRYPT_init(unsigned char *key, unsigned char
 		return NULL;
 	}
 
-	if (salt != NULL) {
-		unsigned char dummy_key[EVP_MAX_KEY_LENGTH];
-		unsigned char dummy_iv[EVP_MAX_IV_LENGTH];
-		unsigned char dummy_pwd[5] = "DUMMY";
-		if (!EVP_BytesToKey(cipher, EVP_sha1(), salt,
-							dummy_pwd, sizeof(dummy_pwd),
-							1,
-							(unsigned char *)&dummy_key, (unsigned char *)&dummy_iv)) {
-			ERROR("Cannot set salt.");
-			free(dgst);
-			return NULL;
-		}
-	}
-
 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
 	EVP_CIPHER_CTX_init(&dgst->ctxdec);
 #else
diff --git a/corelib/test/test_crypt.c b/corelib/test/test_crypt.c
index 84ac6ed..f3b39c6 100644
--- a/corelib/test/test_crypt.c
+++ b/corelib/test/test_crypt.c
@@ -28,7 +28,6 @@ 
 struct cryptdata {
 	unsigned char *key;
 	unsigned char *iv;
-	unsigned char *salt;
 	unsigned char *crypttext;
 };
 
@@ -44,7 +43,7 @@  static void hex2bin(unsigned char *dest, const unsigned char *source)
 static void do_crypt(struct cryptdata *crypt, unsigned char *CRYPTTEXT, unsigned char *PLAINTEXT)
 {
 	int len;
-	void *dcrypt = swupdate_DECRYPT_init(crypt->key, crypt->iv, crypt->salt);
+	void *dcrypt = swupdate_DECRYPT_init(crypt->key, crypt->iv);
 	assert_non_null(dcrypt);
 
 	unsigned char *buffer = calloc(1, strlen((const char *)CRYPTTEXT) + EVP_MAX_BLOCK_LENGTH);
@@ -59,7 +58,7 @@  static void do_crypt(struct cryptdata *crypt, unsigned char *CRYPTTEXT, unsigned
 	free(buffer);
 }
 
-static void test_crypt_nosalt(void **state)
+static void test_crypt_1(void **state)
 {
 	(void)state;
 
@@ -71,7 +70,6 @@  static void test_crypt_nosalt(void **state)
 	struct cryptdata crypt;
 	hex2bin((crypt.key = calloc(1, strlen((const char *)KEY))), KEY);
 	hex2bin((crypt.iv = calloc(1, strlen((const char *)IV))), IV);
-	crypt.salt = NULL;
 	hex2bin((crypt.crypttext = calloc(1, strlen((const char *)CRYPTTEXT))), CRYPTTEXT);
 
 	do_crypt(&crypt, &CRYPTTEXT[0], &PLAINTEXT[0]);
@@ -81,27 +79,24 @@  static void test_crypt_nosalt(void **state)
 	free(crypt.crypttext);
 }
 
-static void test_crypt_salt(void **state)
+static void test_crypt_2(void **state)
 {
 	(void)state;
 
 	unsigned char KEY[] = "69D54287F856D30B51B812FDF714556778CF31E1B104D9C68BD90C669C37D1AB";
 	unsigned char IV[] = "E7039ABFCA63EB8EB1D320F7918275B2";
-	unsigned char SALT[] = "F75A9C11F7F63C08";
 	unsigned char CRYPTTEXT[] = "A17EBBB1A28459352FE3A994404E35AA";
 	unsigned char PLAINTEXT[] = "CRYPTTEST";
 
 	struct cryptdata crypt;
 	hex2bin((crypt.key = calloc(1, strlen((const char *)KEY))), KEY);
 	hex2bin((crypt.iv = calloc(1, strlen((const char *)IV))), IV);
-	hex2bin((crypt.salt = calloc(1, strlen((const char *)SALT))), SALT);
 	hex2bin((crypt.crypttext = calloc(1, strlen((const char *)CRYPTTEXT))), CRYPTTEXT);
 
 	do_crypt(&crypt, &CRYPTTEXT[0], &PLAINTEXT[0]);
 
 	free(crypt.key);
 	free(crypt.iv);
-	free(crypt.salt);
 	free(crypt.crypttext);
 }
 
@@ -116,11 +111,10 @@  static void test_crypt_failure(void **state)
 	struct cryptdata crypt;
 	hex2bin((crypt.key = calloc(1, strlen((const char *)KEY))), KEY);
 	hex2bin((crypt.iv = calloc(1, strlen((const char *)IV))), IV);
-	crypt.salt = NULL;
 	hex2bin((crypt.crypttext = calloc(1, strlen((const char *)CRYPTTEXT))), CRYPTTEXT);
 
 	int len;
-	void *dcrypt = swupdate_DECRYPT_init(crypt.key, crypt.iv, crypt.salt);
+	void *dcrypt = swupdate_DECRYPT_init(crypt.key, crypt.iv);
 	assert_non_null(dcrypt);
 
 	unsigned char *buffer = calloc(1, strlen((const char *)CRYPTTEXT) + EVP_MAX_BLOCK_LENGTH);
@@ -131,7 +125,6 @@  static void test_crypt_failure(void **state)
 
 	free(crypt.key);
 	free(crypt.iv);
-	free(crypt.salt);
 	free(crypt.crypttext);
 }
 
@@ -139,9 +132,9 @@  int main(void)
 {
 	int error_count = 0;
 	const struct CMUnitTest crypt_tests[] = {
-		cmocka_unit_test(test_crypt_nosalt),
+		cmocka_unit_test(test_crypt_1),
 		cmocka_unit_test(test_crypt_failure),
-		cmocka_unit_test(test_crypt_salt)
+		cmocka_unit_test(test_crypt_2)
 	};
 	error_count += cmocka_run_group_tests_name("crypt", crypt_tests, NULL, NULL);
 	return error_count;
diff --git a/doc/source/encrypted_images.rst b/doc/source/encrypted_images.rst
index 113fdd3..781f484 100644
--- a/doc/source/encrypted_images.rst
+++ b/doc/source/encrypted_images.rst
@@ -29,28 +29,25 @@  Then, encrypt an image using this information via
 
 ::
 
-        openssl enc -aes-256-cbc -in <INFILE> -out <OUTFILE> -K <KEY> -iv <IV> -S <SALT>
+        openssl enc -aes-256-cbc -in <INFILE> -out <OUTFILE> -K <KEY> -iv <IV>
 
 where ``<INFILE>`` is the unencrypted source image file and ``<OUTFILE>`` is the
 encrypted output image file to be referenced in ``sw-description``.
 ``<KEY>`` is the hex value part of the 2nd line of output from the key generation
-command above, ``<IV>`` is the hex value part of the 3rd line, and ``<SALT>`` is
-the hex value part of the 1st line.
+command above and ``<IV>`` is the hex value part of the 3rd line.
 
 Then, create a key file to be supplied to SWUpdate via the `-K` switch by 
-putting the key, initialization vector, and salt hex values on one line
+putting the key and initialization vector hex values on one line
 separated by whitespace, e.g., for above example values
 
 ::
 
-        B78CC67DD3DC13042A1B575184D4E16D6A09412C242CE253ACEE0F06B5AD68FC 65D793B87B6724BB27954C7664F15FF3 CE7B0488EFBF0D1B
+        B78CC67DD3DC13042A1B575184D4E16D6A09412C242CE253ACEE0F06B5AD68FC 65D793B87B6724BB27954C7664F15FF3
 
 
-Note that, while not recommended and for backwards compatibility, OpenSSL may be
-used without salt. For disabling salt, add the ``-nosalt`` parameter to the key
-generation command above. Accordingly, drop the ``-S <SALT>`` parameter in the
-encryption command and omit the 3rd field of the key file to be supplied to
-SWUpdate being the salt.
+For earlier versions of SWUpdate it was falsely noted that passing the SALT as a
+3rd parameter would increase security. Key and IV are enough for maximum security,
+salt doesn't add any value.
 
 Encryption of UBI volumes
 -------------------------
diff --git a/include/sslapi.h b/include/sslapi.h
index 6f03ece..c66e005 100644
--- a/include/sslapi.h
+++ b/include/sslapi.h
@@ -124,7 +124,7 @@  int swupdate_HASH_compare(unsigned char *hash1, unsigned char *hash2);
 #endif
 
 #ifdef CONFIG_ENCRYPTED_IMAGES
-struct swupdate_digest *swupdate_DECRYPT_init(unsigned char *key, unsigned char *iv, unsigned char *salt);
+struct swupdate_digest *swupdate_DECRYPT_init(unsigned char *key, unsigned char *iv);
 int swupdate_DECRYPT_update(struct swupdate_digest *dgst, unsigned char *buf, 
 				int *outlen, unsigned char *cryptbuf, int inlen);
 int swupdate_DECRYPT_final(struct swupdate_digest *dgst, unsigned char *buf,
@@ -135,7 +135,7 @@  void swupdate_DECRYPT_cleanup(struct swupdate_digest *dgst);
  * Note: macro for swupdate_DECRYPT_init is
  * just to avoid compiler warnings
  */
-#define swupdate_DECRYPT_init(key, iv, salt) (((key != NULL) | (ivt != NULL) | (salt != NULL)) ? NULL : NULL)
+#define swupdate_DECRYPT_init(key, iv) (((key != NULL) | (ivt != NULL)) ? NULL : NULL)
 #define swupdate_DECRYPT_update(p, buf, len, cbuf, inlen) (-1)
 #define swupdate_DECRYPT_final(p, buf, len) (-1)
 #define swupdate_DECRYPT_cleanup(p)
diff --git a/include/util.h b/include/util.h
index 445e9f2..31c97b6 100644
--- a/include/util.h
+++ b/include/util.h
@@ -194,7 +194,6 @@  void free_string_array(char **nodes);
 int load_decryption_key(char *fname);
 unsigned char *get_aes_key(void);
 unsigned char *get_aes_ivt(void);
-unsigned char *get_aes_salt(void);
 
 /* Getting global information */
 int get_install_info(sourcetype *source, char *buf, size_t len);