Bug 234028 - Openssl cannot decrypt properly
Summary: Openssl cannot decrypt properly
Status: Closed Not A Bug
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: 12.0-RELEASE
Hardware: Any Any
: --- Affects Many People
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-12-15 00:15 UTC by bc979
Modified: 2018-12-15 05:27 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description bc979 2018-12-15 00:15:25 UTC
If I encrypt a file on 11.1 using aes256:

master# openssl enc -aes256 -in xxx.c -out xxx.enc

Then transfer xxx.enc to 12.0 and try to decrypt it, I get garbage with a couple of what appear to be warnings:

test# openssl enc -d -aes256 -in xxx.enc
enter aes-256-cbc decryption password:
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
s??6@TU?lPD?]+?'RPB????^?"?wHC?^q۸??p5YkZ?t?????/?i????B????#?%?8'??!NAZ`!?m??K^
Comment 1 Conrad Meyer freebsd_committer freebsd_triage 2018-12-15 02:32:15 UTC
When I do the same thing on 11.2ish with a 16-byte plaintext file, it uses aes-256-cbc and produces a 48 byte output.

I am able to reproduce, sort of — I don't get bogus output, but a decryption error instead.  Because it may be useful, here is the output with '-v -v -v -debug' too:

ENCRYPT, 11.x:
==============
BIO[0x801816070]: ctrl(108) - FILE pointer
BIO[0x801816070]: ctrl return 1
enter aes-256-cbc encryption password:
Verifying - enter aes-256-cbc encryption password:
BIO[0x8018160e0]: ctrl(108) - FILE pointer
BIO[0x8018160e0]: ctrl return 1
BIO[0x8018160e0]: write(0,8) - FILE pointer
BIO[0x8018160e0]: write return 8
BIO[0x8018160e0]: write(0,8) - FILE pointer
BIO[0x8018160e0]: write return 8
BIO[0x801816150]: ctrl(6) - cipher
BIO[0x8018160e0]: ctrl(6) - FILE pointer
BIO[0x8018160e0]: ctrl return 0
BIO[0x801816150]: ctrl return 0
BIO[0x801816070]: read(0,8192) - FILE pointer
BIO[0x801816070]: read return 16
BIO[0x801816150]: write(0,16) - cipher
BIO[0x8018160e0]: write(0,16) - FILE pointer
BIO[0x8018160e0]: write return 16
BIO[0x801816150]: write return 16
BIO[0x801816070]: read(0,8192) - FILE pointer
BIO[0x801816070]: read return 0
BIO[0x801816150]: ctrl(11) - cipher
BIO[0x8018160e0]: write(0,16) - FILE pointer
BIO[0x8018160e0]: write return 16
BIO[0x8018160e0]: ctrl(11) - FILE pointer
BIO[0x8018160e0]: ctrl return 1
BIO[0x801816150]: ctrl return 1
bytes read   :      16
bytes written:      48
BIO[0x801816070]: Free - FILE pointer
BIO[0x8018160e0]: Free - FILE pointer
BIO[0x801816150]: Free - cipher

DECRYPT, CURRENT:
=================
bufsize=8192
enter aes-256-cbc decryption password:
BIO[0x800aea180]: read(0,8) - FILE pointer
BIO[0x800aea180]: read return 8
BIO[0x800aea180]: read(0,8) - FILE pointer
BIO[0x800aea180]: read return 8
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
BIO[0x800aea280]: ctrl(6) - cipher
BIO[0x800aea200]: ctrl(6) - FILE pointer
BIO[0x800aea200]: ctrl return 0
BIO[0x800aea280]: ctrl return 0
BIO[0x800aea180]: read(0,8192) - FILE pointer
BIO[0x800aea180]: read return 32
BIO[0x800aea280]: write(0,32) - cipher
BIO[0x800aea200]: write(0,16) - FILE pointer
BIO[0x800aea200]: write return 16
BIO[0x800aea280]: write return 32
BIO[0x800aea180]: read(0,8192) - FILE pointer
BIO[0x800aea180]: read return 0
BIO[0x800aea280]: ctrl(11) - cipher
BIO[0x800aea280]: ctrl return 0
bad decrypt
34371153920:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:/usr/home/conrad/src/freebsd/crypto/openssl/crypto/evp/evp_enc.c:537:
BIO[0x800aea180]: Free - FILE pointer
BIO[0x800aea200]: Free - FILE pointer
BIO[0x800aea280]: Free - cipher


Additionally, running the same encryption command on CURRENT with the same plaintext produces a different ciphertext.  But result is salted, so that isn't very surprising.  CURRENT openssl is able to decrypt the output from the enc command on CURRENT.

The debug output is identical, up to this point:

BIO[0x800aea280]: write return 32
BIO[0x800aea180]: read(0,8192) - FILE pointer
BIO[0x800aea180]: read return 0
BIO[0x800aea280]: ctrl(11) - cipher
-------------------------------------- diverges
BIO[0x800aea200]: ctrl(11) - FILE pointer
BIO[0x800aea200]: ctrl return 1
BIO[0x800aea280]: ctrl return 1
bytes read   :       48
bytes written:       16
Comment 2 Conrad Meyer freebsd_committer freebsd_triage 2018-12-15 02:43:47 UTC
When I pass '-md md5', CURRENT is able to decrypt the encrypted file from 11.x just fine.
Comment 3 Conrad Meyer freebsd_committer freebsd_triage 2018-12-15 02:46:22 UTC
This is sort of documented in the HISTORY section of openssl-enc(1):

HISTORY
       The default digest was changed from MD5 to SHA256 in Openssl 1.1.0.

I guess it'd be nice if they had revved the format so new openssl could tell if the file had been produced by OpenSSL <1.1.0, but I guess they chose not to.

This is an upstream OpenSSL behavior so I don't think we're going to change it.
Comment 4 Conrad Meyer freebsd_committer freebsd_triage 2018-12-15 02:53:22 UTC
Not a bug.  Pass an explicit key derivation method for encrypt and the same same method for decrypt to get consistent results as defaults change.
Comment 5 bc979 2018-12-15 04:20:43 UTC
It does seem to work when -md md5 is used.  However, I point out that the -md parameter is not documented in the man page for enc on 11.1 or earlier.  It does appear in 12.0.  But it only lists the default for 12.0.  Even if I knew about that parameter, I would have no idea what the default value would have been.  

The decryption with the wrong md does generate output, but it is not correct.  enc even notifies you of this with the message "bad decrypt" which is in your output.  Why it bothers to generate garbage output when it knows the decrypt failed is interesting.
Comment 6 Conrad Meyer freebsd_committer freebsd_triage 2018-12-15 05:27:08 UTC
(In reply to bc979 from comment #5)
> However, I point out that the -md parameter is not documented in the man page for enc on 11.1 or earlier.

Yep.  It's mentioned, but usage and default are totally undocumented (and on 11.2 as well).

$ openssl enc -h
unknown option '-h'
...
-md            the next argument is the md to use to create a key
                 from a passphrase.  One of md2, md5, sha or sha1

Helpfully, none of the *listed* options in 1.0.2o enc are the 1.1.0 default (sha256). /s  However, '-md sha256' can be provided manually and seems to decode correctly on 12.

NAME
       openssl-enc, enc - symmetric cipher routines

SYNOPSIS
       openssl enc -ciphername [-in filename] [-out filename] [-pass arg] [-e]
       [-d] [-a/-base64] [-A] [-k password] [-kfile filename] [-K key] [-iv
       IV] [-S salt] [-salt] [-nosalt] [-z] [-md] [-p] [-P] [-bufsize number]
                                             ^^^
(-md not documented anywhere else in the page)

Generating gibberish makes sense, unfortunately — enc has no way of knowing that the wrong KDF function was used to turn password into key, and AES-256-CBC does not have any sort of integrity MAC to verify the correct key was used.  So you get gibberish.  I suspect the only reason a bad decrypt was noticed in my (short) input was that the final padding byte(s) didn't match up with PKCS expectations.  You might see the same message (but only at the very end of the "decrypted" contents).