[vim] Vim cryptmethod uses SHA-256 for password-based key derivation (#639)

280 views
Skip to first unread message

Aaron Toponce

unread,
Feb 16, 2016, 8:07:52 AM2/16/16
to vim/vim

On L421-L423 of src/blowfish.c, a sha256_key() function is created for password-based key derivation with a salt for blowfish. Unfortunately, even with 1,000 rounds, SHA-256 is designed to be fast, and can be parallelized with GPUs when brute forcing a file. Instead, the Blowfish key should be derived using bcrypt or scrypt. Both defeat parallelization on GPUs, and scrypt further defeats FPGAs.


Reply to this email directly or view it on GitHub.

Bram Moolenaar

unread,
Feb 16, 2016, 11:23:20 AM2/16/16
to vim/vim

Aaron Toponce wrote:

> On
> [L421-L423](https://github.com/vim/vim/blob/master/src/blowfish.c#L421-L423)

> of src/blowfish.c, a `sha256_key()` function is created for
> password-based key derivation with a salt for blowfish. Unfortunately,
> even with 1,000 rounds, SHA-256 is designed to be fast, and can be
> parallelized with GPUs when brute forcing a file. Instead, the
> Blowfish key should be derived using
> [bcrypt](https://en.wikipedia.org/wiki/Bcrypt) or
> [scrypt](https://en.wikipedia.org/wiki/scrypt). Both defeat

> parallelization on GPUs, and scrypt further defeats FPGAs.

There have been ideas for a new crypt mechanism that is much stronger
than Blowfish. Unfortunately nobody has implemented it yet. Note that
this requires experience and/or knowledge about encryption, it's easy to
make mistakes that weaken the encryption significantly.

--
Microsoft: "Windows NT 4.0 now has the same user-interface as Windows 95"
Windows 95: "Press CTRL-ALT-DEL to reboot"
Windows NT 4.0: "Press CTRL-ALT-DEL to login"

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Tony Arcieri

unread,
Feb 16, 2016, 12:13:53 PM2/16/16
to vim/vim

Note that unlike scrypt (or PBKDF2, or Argon2), bcrypt is not designed to be a KDF.

Aaron Toponce

unread,
Feb 16, 2016, 12:26:53 PM2/16/16
to vim/vim

Note that unlike scrypt (or PBKDF2, or Argon2), bcrypt is not designed to be a KDF.

Indeed. Bad recommendation on my part, although I wouldn't recommend Argon2 quite yet either. Scrypt seems to be the most fitting here.

Demetri Obenour

unread,
Mar 19, 2016, 2:43:30 PM3/19/16
to vim/vim

Argon2 is implemented in libsodium and is the winner of the Password Hashing Competition. It is designed as a KDF.

However, note that the rest of Vim's cryptmethod is also poorly implemented. My suggestion is to use Argon2 as a KDF and either XSalsa20-Poly1305 or XChaCha20-Poly1305 (with a strong, random nonce) for authenticated encryption.

libsodium provides high-level APIs for password hashing and authenticated encryption and is my strong suggestion.


You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub

Bram Moolenaar

unread,
Mar 19, 2016, 3:26:03 PM3/19/16
to vim/vim

Demetri Obenour wrote:

> Argon2 is implemented in [libsodium][1] and is the winner of the
> [Password Hashing Competition][2]. It is designed as a KDF.

>
> However, note that the rest of Vim's cryptmethod is also poorly
> implemented. My suggestion is to use Argon2 as a KDF and either
> XSalsa20-Poly1305 or XChaCha20-Poly1305 (with a strong, random nonce)
> for authenticated encryption.
>
> [libsodium][1] provides high-level APIs for password hashing and

> authenticated encryption and is my strong suggestion.
>
> [1]: https://github.com/jedisct1/libsodium/
> [2]: https://password-hashing.net/

Libsodium looks interesting. The License is very liberal, it would
allow us to include the parts that we need in Vim. Although it appears
some individual files have a more restrictive license, need to check
each one.

This is C code, thus it should not be too difficult to add as a new
crypt algorithm in Vim.

--
From "know your smileys":
!-| I-am-a-Cylon-Centurian-with-one-red-eye-bouncing-back-and-forth


/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///


You are receiving this because you are subscribed to this thread.

Reply to this email directly or view it on GitHub

Tony Arcieri

unread,
Mar 19, 2016, 3:32:38 PM3/19/16
to vim/vim

There's also TweetNaCl if you want something smaller to vendor, although you'd have to vendor Argon2 separately:

https://tweetnacl.cr.yp.to/software.html


You are receiving this because you are subscribed to this thread.

Reply to this email directly or view it on GitHub

Ben Fritz

unread,
Mar 21, 2016, 12:00:31 PM3/21/16
to vim_dev, v...@noreply.github.com, reply+00b1d198af3005e6598aa12d8e450a2c177a173...@reply.github.com, vim-dev...@256bit.org
On Saturday, March 19, 2016 at 1:43:30 PM UTC-5, Demetri Obenour wrote:
> Argon2 is implemented in libsodium and is the winner of the Password Hashing Competition. It is designed as a KDF.
>
>
> However, note that the rest of Vim's cryptmethod is also poorly implemented. My suggestion is to use Argon2 as a KDF and either XSalsa20-Poly1305 or XChaCha20-Poly1305 (with a strong, random nonce) for authenticated encryption.
>
>
> libsodium provides high-level APIs for password hashing and authenticated encryption and is my strong suggestion.
>
>

My thoughts on this are:

It's best to use a library. With a library we're going to get any security updates from people who presumably know what they're doing and spend time learning about exploits so they can address them in their code. Also researchers are actually likely to test an external library, but not Vim's internal code.

However it's useful to have *something* available on every system Vim supports, so I think something should be baked in, still. Also Vim needs to be able to read old files.

I think adding a 'cryptkdf' option would be a decent idea. Include something built-in; either copied from a library with a license that allows it (probably best), or something simple like PDKDF2 (we already have a SHA256 we could use a a building block). But also include an option for a library implementation of a few algorithms. Argon2 is a good idea but it's still pretty new so if a flaw is found another method would probably be nice to have already available, so maybe the choices could be something like 'pdkdf2', 'lib-scrypt', and 'lib-argon2' for starters.

The number of iterations is key for the security of these algorithms. I'm vaguely aware that scrypt and argon2 are also configurable in memory use, but I know a lot less about that. But regardless we'll want to allow configuring the KDF to scale with hardware without recompiling Vim. So a 'cryptkdfcount' or similar option should also be provided. I think a good way to do this would be to allow both numeric values, but also time values. For example, the user could do ":set cryptkdfcount=1s" and Vim would estimate how many iterations would take a full second on the current hardware and use that. 1-3 seconds is probably a reasonable default value as well.

Speaking of defaults: I think Vim should default to the strongest method available. I additionally think Vim should warn on saving with a known broken format such as the original blowfish implementation, or the zip algorithm, or even blowfish2 without a decent KDF. Maybe even compile without the broken algorithms altogether unless the user specifically passes --include-bad-crypto to the configure script or something.

As for blowfish: I'm not very concerned about the weaknesses in the algorithm *for the specific uses Vim is likely to use it for*, however having a better encryption algorithm available is much nicer. Nevertheless, I *am* a little concerned whether we know the algorithm is implemented properly. I'd like to see output from Vim's implementation matched up against output from a well-known library implementation. In theory with the same salt, same IV, and same key, I think they should be compatible.

I should note here that I'm also a little uneasy with the current salt/IV generation. Basically it's just one system time (in microseconds) and a hash (I doubt the rand() adds anything useful). That could be a lot better, using /dev/urandom for example where supported, or the equivalent. Or maybe hash system time (still in microseconds) with a previous hash periodically, say while waiting for user input or something; I'm not familiar with best practices when a good system-provided random source is missing. I say I'm "uneasy" because I doubt there's any good exploit for this in Vim's use scenarios, but it's documented widely that a good unpredictable IV is required for CBC mode encryption, so I don't get any warm fuzzies from the "random" code here.

Bram, are you already working on any of this? I have been thinking about starting an implementation of some of the above but that's a lot of work I don't want going to waste if you have other ideas. Maybe hashing out a top-level interface and goals, then making a fork for more distributed development, would be a decent idea? I don't think any halfway implementations will be useful, especially since we'll probably need to grow a blowfish3 or other cryptmethod to use the new KDF (preferably in a forwards-compatible way to handle other new KDFs that may come along in the future).

Scott

unread,
Mar 21, 2016, 12:04:15 PM3/21/16
to vim/vim, vim-dev ML

(Slight nit: it's PBKDF2. The acronym stands for "Password-Based Key Derivation Function #2".)


You are receiving this because you commented.
Reply to this email directly or view it on GitHub

Ben Fritz

unread,
Mar 21, 2016, 12:04:35 PM3/21/16
to vim_dev, v...@noreply.github.com, reply+00b1d198af3005e6598aa12d8e450a2c177a173...@reply.github.com, vim-dev...@256bit.org
On Monday, March 21, 2016 at 11:00:31 AM UTC-5, Ben Fritz wrote:
> On Saturday, March 19, 2016 at 1:43:30 PM UTC-5, Demetri Obenour wrote:
> > Argon2 is implemented in libsodium and is the winner of the Password Hashing Competition. It is designed as a KDF.
> >
> >
> > However, note that the rest of Vim's cryptmethod is also poorly implemented. My suggestion is to use Argon2 as a KDF and either XSalsa20-Poly1305 or XChaCha20-Poly1305 (with a strong, random nonce) for authenticated encryption.
> >
> >
> > libsodium provides high-level APIs for password hashing and authenticated encryption and is my strong suggestion.
> >
> >
>
> My thoughts on this are:
>

Oh, and I forgot one more:

While there *may* not be any exploitable weakness related to non-authenticated encryption *in Vim's case*, we can't prove it. And, if such an attack exists, Vim *will* be vulnerable. If we're already modifying the crypto code (and we should, because the KDF is way too weak) then we may as well throw in a MAC to prevent the *possibility* of a chosen-ciphertext attack. It shouldn't harm anything and it could potentially help a lot. I say we re-open the issue that got created for non-authenticated encryption.

Ben Fritz

unread,
Mar 21, 2016, 12:11:27 PM3/21/16
to vim_dev, v...@noreply.github.com, vim-dev...@256bit.org, reply+00b1d1986f86f0093d8cbf877fa84cd3d26d7ab...@reply.github.com
On Monday, March 21, 2016 at 11:04:15 AM UTC-5, Scott wrote:
> (Slight nit: it's PBKDF2. The acronym stands for "Password-Based Key Derivation Function #2".)
>
>

Thanks, I knew that, I just was typing faster than I was thinking apparently. That's one of those acronyms I really need to expand out in my head before typing correctly. I do the same thing with IMDB which occasionally lands me on some interesting cyber-squatter pages. :-(

Bram Moolenaar

unread,
Mar 23, 2016, 5:58:10 PM3/23/16
to Ben Fritz, vim_dev, v...@noreply.github.com, reply+00b1d198af3005e6598aa12d8e450a2c177a173...@reply.github.com, vim-dev...@256bit.org

Ben Fritz wrote:

> On Saturday, March 19, 2016 at 1:43:30 PM UTC-5, Demetri Obenour wrote:
> > Argon2 is implemented in libsodium and is the winner of the Password Hashing Competition. It is designed as a KDF.
> >
> >
> > However, note that the rest of Vim's cryptmethod is also poorly implemented. My suggestion is to use Argon2 as a KDF and either XSalsa20-Poly1305 or XChaCha20-Poly1305 (with a strong, random nonce) for authenticated encryption.
> >
> >
> > libsodium provides high-level APIs for password hashing and authenticated encryption and is my strong suggestion.
> >
> >
>
> My thoughts on this are:
>
> It's best to use a library. With a library we're going to get any
> security updates from people who presumably know what they're doing
> and spend time learning about exploits so they can address them in
> their code. Also researchers are actually likely to test an external
> library, but not Vim's internal code.

libsodium is currently at version 1.0.8. The version included with
Ubuntu is 1.0.3 ...

> However it's useful to have *something* available on every system Vim
> supports, so I think something should be baked in, still. Also Vim
> needs to be able to read old files.

We could use configure to find a library and when it's not available or
older fall back to the built-in code.

> Speaking of defaults: I think Vim should default to the strongest
> method available. I additionally think Vim should warn on saving with
> a known broken format such as the original blowfish implementation, or
> the zip algorithm, or even blowfish2 without a decent KDF. Maybe even
> compile without the broken algorithms altogether unless the user
> specifically passes --include-bad-crypto to the configure script or
> something.

This has the danger of writing a file on one system, go on holiday and
find out you can't open it on your laptop (that actually happened to me).

I think there should be some number of months between making a new
method available and making it the default.

The original blowfish encryption is not broken, it's just weaker than it
should be. It's still a lot stronger than zip.

> Bram, are you already working on any of this? I have been thinking
> about starting an implementation of some of the above but that's a lot
> of work I don't want going to waste if you have other ideas. Maybe
> hashing out a top-level interface and goals, then making a fork for
> more distributed development, would be a decent idea? I don't think
> any halfway implementations will be useful, especially since we'll
> probably need to grow a blowfish3 or other cryptmethod to use the new
> KDF (preferably in a forwards-compatible way to handle other new KDFs
> that may come along in the future).

No, several people have given their opinion but nobody has done actual
work...

--
Laughing helps. It's like jogging on the inside.

Benjamin Fritz

unread,
Mar 23, 2016, 6:51:59 PM3/23/16
to Bram Moolenaar, vim_dev, vim/vim, reply+00b1d198af3005e6598aa12d8e450a2c177a173...@reply.github.com, vim-dev...@256bit.org

On Wed, Mar 23, 2016 at 4:58 PM, Bram Moolenaar <Br...@moolenaar.net> wrote:
>
> > Speaking of defaults: I think Vim should default to the strongest
> > method available. I additionally think Vim should warn on saving with
> > a known broken format such as the original blowfish implementation, or
> > the zip algorithm, or even blowfish2 without a decent KDF. Maybe even
> > compile without the broken algorithms altogether unless the user
> > specifically passes --include-bad-crypto to the configure script or
> > something.
>
> This has the danger of writing a file on one system, go on holiday and
> find out you can't open it on your laptop (that actually happened to me).
>

That makes some sense, however it only applies to people who edit the same file on multiple systems, AND they don't have the same version of Vim on each of those systems.

If you don't need that capability, having the old broken systems still in the code makes it too easy to make a mistake that could compromise your security.

DROWN recently showed some of the problems with keeping older known-broken crypto code enabled by default. I think it makes sense to keep the code there for people who deliberately choose to use it. But getting rid of it by default can potentially remove an attack vector.

At the very least, we should warn when saving in an insecure format.

> I think there should be some number of months between making a new
> method available and making it the default.
>

OK, that's fair.


> The original blowfish encryption is not broken, it's just weaker than it
> should be.  It's still a lot stronger than zip.

Is it? This page makes it sound like "blowfish" was pretty much completely broken if you knew any of the plaintext: https://dgl.cx/2014/10/vim-blowfish

For example, if you had plugin that always writes a predictable header text to an encrypted file before the actual sensitive data, the attacker would know some plaintext. I'm certainly not comfortable using "blowfish", knowing it had exploitable flaws fixed in blowfish2. I thought "blowfish" was just around to let people read their old data (and hopefully convert to blowfish2).

And while I can probably *personally* use a strong-enough passphrase to let the current too-fast KDF for blowfish2 suffice, I wouldn't recommend it to anyone else, since I know most people choose passwords that can fall way too fast with modern tools and techniques. I'd consider "blowfish2" to be broken for *general use* as well since you need a REALLY good password for it to provide any long-term security guarantees. Once we increase the KDF iterations sufficiently I would warn when saving in blowfish2 as well, in favor of the new method(s) using a better KDF.

Benjamin Fritz

unread,
Mar 23, 2016, 6:52:58 PM3/23/16
to Bram Moolenaar, vim_dev, vim/vim, reply+00b1d198af3005e6598aa12d8e450a2c177a173...@reply.github.com, vim-dev...@256bit.org

On Wed, Mar 23, 2016 at 5:51 PM, Benjamin Fritz <fritzo...@gmail.com> wrote:
>
> I thought "blowfish" was just around to let people read their old data (and hopefully convert to blowfish2).

That reminds me of something else. Why isn't 'modified' set when you change cryptmethod or the encryption password?

Manuel Ortega

unread,
Mar 23, 2016, 7:21:21 PM3/23/16
to vim...@googlegroups.com
That reminds me of something else. Why isn't 'modified' set when you change cryptmethod or the encryption password?

Isn't it because the *buffer* hasn't changed?  IIUC, in the latter case the *file* changes, not the buffer.  In the former case neither has changed, so for sure 'modified' should not be set.

-Manny

Ben Fritz

unread,
Mar 23, 2016, 10:28:33 PM3/23/16
to vim_dev
On Wednesday, March 23, 2016 at 6:21:21 PM UTC-5, Manuel Ortega wrote:
> > That reminds me of something else. Why isn't 'modified' set when you change cryptmethod or the encryption password?
>
>
>
>
>
> Isn't it because the *buffer* hasn't changed?  IIUC, in the latter case the *file* changes, not the buffer.  In the former case neither has changed, so for sure 'modified' should not be set.
>
>

If you change any of 'fileformat', 'fileencoding', 'bomb', or 'nofixeol' then the buffer doesn't change either, only the file. 'cryptmethod' is the oddball here.

I view the 'modified' flag as saying "if you save this buffer then the file will change".

I got caught once while I was testing something where I had the wrong password because I had quit Vim after changing the password, but I hadn't saved yet. Vim let me do that without any complaint, because the buffer wasn't modified.

This might be a decent use for an OptionSet autocmd event, but that seems like a hack.

Manuel Ortega

unread,
Mar 23, 2016, 10:55:53 PM3/23/16
to vim...@googlegroups.com
On Wed, Mar 23, 2016 at 10:28 PM, Ben Fritz <fritzo...@gmail.com> wrote:
On Wednesday, March 23, 2016 at 6:21:21 PM UTC-5, Manuel Ortega wrote:
> > That reminds me of something else. Why isn't 'modified' set when you change cryptmethod or the encryption password?
>
>
> Isn't it because the *buffer* hasn't changed?  IIUC, in the latter case the *file* changes, not the buffer.  In the former case neither has changed, so for sure 'modified' should not be set.
>
>

If you change any of 'fileformat', 'fileencoding', 'bomb', or 'nofixeol' then the buffer doesn't change either, only the file. 'cryptmethod' is the oddball here.

I knew about the first two, but the last two are *really* surprising.  They aren't mentioned at ":help 'mod'", nor are they mentioned at their own respective ":help"s.  (Bram, if this is the intended behavior, it should probably be documented at least at :h 'mod', and probably :h 'bomb' and :h 'fixeol'.)
 
I view the 'modified' flag as saying "if you save this buffer then the file will change".

If that's what it means, the docs need to be fixed.
 
I got caught once while I was testing something where I had the wrong password because I had quit Vim after changing the password, but I hadn't saved yet. Vim let me do that without any complaint, because the buffer wasn't modified.

Changing 'cryptmethod' should ONLY result in a setting of &mod if &key is set to something.  If I haven't turned encryption on, so to speak, then setting &cm to "blowfish2" shouldn't set the modified flag.  (For under this circumstance, the file will not change even if the buffer is saved).

-Manny

Bram Moolenaar

unread,
Mar 24, 2016, 7:09:01 AM3/24/16
to Benjamin Fritz, vim_dev, vim/vim, reply+00b1d198af3005e6598aa12d8e450a2c177a173...@reply.github.com, vim-dev...@256bit.org
Your definition of broken is wrong. Broken means it doesn't work at
all. e.g., Vim crashes when using it, or when decrypting you can't get
back the original text. When do you call a car broken? When you can't
drive. Not when you can't open the window.

> For example, if you had plugin that always writes a predictable header text
> to an encrypted file before the actual sensitive data, the attacker would
> know some plaintext. I'm certainly not comfortable using "blowfish",
> knowing it had exploitable flaws fixed in blowfish2. I thought "blowfish"
> was just around to let people read their old data (and hopefully convert to
> blowfish2).
>
> And while I can probably *personally* use a strong-enough passphrase to let
> the current too-fast KDF for blowfish2 suffice, I wouldn't recommend it to
> anyone else, since I know most people choose passwords that can fall way
> too fast with modern tools and techniques. I'd consider "blowfish2" to be
> broken for *general use* as well since you need a REALLY good password for
> it to provide any long-term security guarantees. Once we increase the KDF
> iterations sufficiently I would warn when saving in blowfish2 as well, in
> favor of the new method(s) using a better KDF.

My favorite example is when I have some text that I don't want my
neighbor to read. Any encryption that Vim provides works for that.

Also keep in mind that, no matter how strong your encryption is, there
is always a weak point. Rembember key loggers? There never ever is
100% reliable encryption.

So please don't overreact.

--
hundred-and-one symptoms of being an internet addict:
107. When using your phone you forget that you don't have to use your
keyboard.

Scott

unread,
Mar 24, 2016, 9:46:16 AM3/24/16
to vim/vim, vim-dev ML

Your definition of broken is wrong. Broken means it doesn't work at all.

Not quite. Think "broken" in the sense of "code-breaker". Is it easy for a skilled analyst to subvert? What about a large team of skilled analysts and mathematicians with billions of dollars of specialized computer hardware?


You are receiving this because you commented.

Reply to this email directly or view it on GitHub

Benjamin Fritz

unread,
Mar 24, 2016, 10:55:14 AM3/24/16
to Bram Moolenaar, vim_dev, vim/vim, reply+00b1d198af3005e6598aa12d8e450a2c177a173...@reply.github.com, vim-dev...@256bit.org


On Thu, Mar 24, 2016 at 6:08 AM, Bram Moolenaar <Br...@moolenaar.net> wrote:
>
>
> Ben Fritz wrote:
>
> > On Wed, Mar 23, 2016 at 4:58 PM, Bram Moolenaar <Br...@moolenaar.net> wrote:
> > > The original blowfish encryption is not broken, it's just weaker than it
> > > should be.  It's still a lot stronger than zip.
> >
> > Is it? This page makes it sound like "blowfish" was pretty much completely
> > broken if you knew any of the plaintext: https://dgl.cx/2014/10/vim-blowfish
>
> Your definition of broken is wrong.  Broken means it doesn't work at
> all.  e.g., Vim crashes when using it, or when decrypting you can't get
> back the original text.  When do you call a car broken?  When you can't
> drive.  Not when you can't open the window.
>

I call something "broken" when it cannot serve its intended purpose. Cryptography's purpose is to keep data secret. If that article is correct, then with "blowfish" (not "blowfish2") there is a trivial attack that can expose *at least* 64 characters of text in a file without ever knowing the password. I'm not clear on the details (the article hand-waves a bit) but potentially the rest of the file may also be recoverable.

If the encrypted file is the basis of a [password manager](http://www.vim.org/scripts/script.php?script_id=5340) for example, then this is quite bad. At least the first password is probably compromised if an attacker gains access to the file.

If anything, this makes "blowfish" *worse* than zip in many scenarios. At least with zip the attacker needs to work for it.

> > For example, if you had plugin that always writes a predictable header text
> > to an encrypted file before the actual sensitive data, the attacker would
> > know some plaintext. I'm certainly not comfortable using "blowfish",
> > knowing it had exploitable flaws fixed in blowfish2. I thought "blowfish"
> > was just around to let people read their old data (and hopefully convert to
> > blowfish2).
> >
> > And while I can probably *personally* use a strong-enough passphrase to let
> > the current too-fast KDF for blowfish2 suffice, I wouldn't recommend it to
> > anyone else, since I know most people choose passwords that can fall way
> > too fast with modern tools and techniques. I'd consider "blowfish2" to be
> > broken for *general use* as well since you need a REALLY good password for
> > it to provide any long-term security guarantees. Once we increase the KDF
> > iterations sufficiently I would warn when saving in blowfish2 as well, in
> > favor of the new method(s) using a better KDF.
>
> My favorite example is when I have some text that I don't want my
> neighbor to read.  Any encryption that Vim provides works for that.
>

That's a straw-man argument. You could also do ggg?G to rot13 the buffer which would keep my neighbor or my kids from reading the file. If that's not enough then a simple plugin to do a Caesar cipher as a BufWritePre/BufRead would also do the trick. But nobody would seriously suggest either of those are secure. Encryption must have a higher standard than keeping out your non-hacker friends.

The help entry blowfish and blowfish2 both say "medium strong encryption". An "implementation flaw" is mentioned for blowfish, but IIUC the flaw is severe enough to make it much, much weaker than blowfish2. Why are they both summarized as the same strength?

> Also keep in mind that, no matter how strong your encryption is, there
> is always a weak point.  Rembember key loggers?  There never ever is
> 100% reliable encryption.
>
> So please don't overreact.
>

This is true. Neither Vim nor any other encryption tool will protect from a compromised system. I don't expect Vim to keep me safe from everything. But I do expect, if I encrypt a file with any modern crypto tool, that I don't need to worry if that file is snagged off my cloud storage, or someone steals my USB stick, or something. Representing a crypto implementation as "secure" when it is trivial to recover some number of bytes in a file is going to leak someone's sensitive data because they trusted you. I don't think it's overreacting to say "we shouldn't present weak crypto as strong enough to keep using".

Maybe "broken" is too changed a word, I'll stop using it. I'll put it this way:

zip - insecure, all of your file can be recovered with commonly available tools. Not recommended.
blowfish - insecure, part or all of your file can be recovered with known methods. Not recommended.
blowfish2 - secure for small files if you use a very strong password and nobody else has write access.
proposed new methods - secure if you don't use a very weak password like "123456", "password", or "letmein".

Manuel Ortega

unread,
Mar 24, 2016, 11:47:40 AM3/24/16
to vim...@googlegroups.com
On Thu, Mar 24, 2016 at 10:54 AM, Benjamin Fritz <fritzo...@gmail.com> wrote:


On Thu, Mar 24, 2016 at 6:08 AM, Bram Moolenaar <Br...@moolenaar.net> wrote:
>
>
> Ben Fritz wrote:
>
> > On Wed, Mar 23, 2016 at 4:58 PM, Bram Moolenaar <Br...@moolenaar.net> wrote:
> > > The original blowfish encryption is not broken, it's just weaker than it
> > > should be.  It's still a lot stronger than zip.
> >
> > Is it? This page makes it sound like "blowfish" was pretty much completely
> > broken if you knew any of the plaintext: https://dgl.cx/2014/10/vim-blowfish
>
> Your definition of broken is wrong.  Broken means it doesn't work at
> all.  e.g., Vim crashes when using it, or when decrypting you can't get
> back the original text.  When do you call a car broken?  When you can't
> drive.  Not when you can't open the window.
>

I call something "broken" when it cannot serve its intended purpose. Cryptography's purpose is to keep data secret.

The purpose of *Vim*'s cryptography, as Bram is trying to stress and nobody seems to ever internalize, is to keep data secret from neighbors and family members, i.e., people not sophisticated enough or motivated enough to e.g., realize that it's VimCrypt, find that webpage, know what a perl script is, know how to apply it, etc.  It is pretty clearly implied in ":h encrypt" that the purpose of Vim's encryption is not to keep data secret from people who even partly know what they're doing.

For this purpose, it works.

But really: it shouldn't be Vim's job to encrypt files on disk anymore than it's Vim's job to do compression and decompression.  There are plugins to use GPG transparently like there are for compressing and decompressing transparently.

-Manny

Benjamin Fritz

unread,
Mar 24, 2016, 12:03:59 PM3/24/16
to vim_dev


On Thu, Mar 24, 2016 at 10:47 AM, Manuel Ortega <manny...@gmail.com> wrote:
>
> The purpose of *Vim*'s cryptography, as Bram is trying to stress and nobody seems to ever internalize, is to keep data secret from neighbors and family members, i.e., people not sophisticated enough or motivated enough to e.g., realize that it's VimCrypt, find that webpage, know what a perl script is, know how to apply it, etc.

I disagree. If that's the case, then why did Vim ever get a new cryptmethod at all? zip is just fine for those purposes.


>  It is pretty clearly implied in ":h encrypt" that the purpose of Vim's encryption is not to keep data secret from people who even partly know what they're doing.
>

I disagree here too. In :help encryption I see "The encrypted text cannot be read without the right key" and "You could do this to edit very secret text." In :help 'cryptmethod' I see blowfish and blowfish2 described as "medium strong encryption." Nowhere do I get the impression Vim's cryptography is not secure enough to keep data secret from people who know what you're doing. In fact I get the opposite impression, that Vim's cryptography is probably strong enough for most purposes if you use "blowfish2".

> For this purpose, it works.
>
> But really: it shouldn't be Vim's job to encrypt files on disk anymore than it's Vim's job to do compression and decompression.  There are plugins to use GPG transparently like there are for compressing and decompressing transparently.
>

And I disagree yet again here. If encryption is not built into the editor, then you cannot use features like swap files or undo files or you risk exposing decrypted text in those files. I think it's a great feature to support encryption in the editor itself to avoid exposing data like that. Additionally the editor could lock the memory to prevent unencrypted data in a buffer from getting saved off to swap space. I don't know whether Vim does that (it probably should), but there's no way you could do that outside of Vim. So either you need some sort of editor built into your encryption program with fewer features than Vim, or you need to do the encryption within Vim, or Vim needs to provide better hooks for external tools to encrypt in multiple places.

Benjamin Fritz

unread,
Mar 24, 2016, 12:05:53 PM3/24/16
to Bram Moolenaar, vim_dev, vim/vim, reply+00b1d198af3005e6598aa12d8e450a2c177a173...@reply.github.com, vim-dev...@256bit.org


On Thu, Mar 24, 2016 at 9:54 AM, Benjamin Fritz <fritzo...@gmail.com> wrote:
>
> The help entry blowfish and blowfish2 both say "medium strong encryption". An "implementation flaw" is mentioned for blowfish, but IIUC the flaw is severe enough to make it much, much weaker than blowfish2. Why are they both summarized as the same strength?
>

Ah, I see some stronger warnings in :help encrypt. I think those should be emphasized more and maybe cross-referenced in the help for 'cryptmethod'.

Bram Moolenaar

unread,
Mar 24, 2016, 3:09:14 PM3/24/16
to Manuel Ortega, vim...@googlegroups.com

Manuel Ortega wrote:

> On Wed, Mar 23, 2016 at 10:28 PM, Ben Fritz <fritzo...@gmail.com> wrote:
>
> > On Wednesday, March 23, 2016 at 6:21:21 PM UTC-5, Manuel Ortega wrote:
> > > > That reminds me of something else. Why isn't 'modified' set when you
> > change cryptmethod or the encryption password?
> > >
> > >
> > > Isn't it because the *buffer* hasn't changed? IIUC, in the latter case
> > the *file* changes, not the buffer. In the former case neither has
> > changed, so for sure 'modified' should not be set.
> >
> > If you change any of 'fileformat', 'fileencoding', 'bomb', or 'nofixeol'
> > then the buffer doesn't change either, only the file. 'cryptmethod' is the
> > oddball here.
> >
>
> I knew about the first two, but the last two are *really* surprising. They
> aren't mentioned at ":help 'mod'", nor are they mentioned at their own
> respective ":help"s. (Bram, if this is the intended behavior, it should
> probably be documented at least at :h 'mod', and probably :h 'bomb' and :h
> 'fixeol'.)

I'll add a remark.

> > I view the 'modified' flag as saying "if you save this buffer then the
> > file will change".
>
> If that's what it means, the docs need to be fixed.

No, that's not really what it means.


> > I got caught once while I was testing something where I had the wrong
> > password because I had quit Vim after changing the password, but I hadn't
> > saved yet. Vim let me do that without any complaint, because the buffer
> > wasn't modified.
>
> Changing 'cryptmethod' should ONLY result in a setting of &mod if &key is
> set to something. If I haven't turned encryption on, so to speak, then
> setting &cm to "blowfish2" shouldn't set the modified flag. (For under
> this circumstance, the file will not change even if the buffer is saved).

Although there is something to say for it, changing this behavior
probably causes more confusion than it solves. Especially if someone
changes the key then then does "ZZ", expecting the file NOT to be
written.

--
hundred-and-one symptoms of being an internet addict:
113. You are asked about a bus schedule, you wonder if it is 16 or 32 bits.

Bram Moolenaar

unread,
Mar 24, 2016, 3:09:44 PM3/24/16
to vim/vim, vim-dev ML

Scott wrote:

> > Your definition of broken is wrong. Broken means it doesn't work at all.
>
> Not quite. Think "broken" in the sense of "code-breaker". Is it easy
> for a skilled analyst to subvert? What about a large team of skilled
> analysts and mathematicians with billions of dollars of specialized
> computer hardware?

It's more like breaking in. Or breakable. That skilled person doesn't
break the encryption, it finds the password. For the next password you
have to start over. English can be quite confusing.


--
hundred-and-one symptoms of being an internet addict:
114. You are counting items, you go "0,1,2,3,4,5,6,7,8,9,A,B,C,D...".


/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///


You are receiving this because you commented.

Reply to this email directly or view it on GitHub

Scott

unread,
Mar 24, 2016, 3:29:27 PM3/24/16
to vim/vim, vim-dev ML

@brammool

It's more like breaking in. Or breakable. That skilled person doesn't
break the encryption, it finds the password. For the next password you
have to start over. English can be quite confusing.

Let's also consider the case of, say, the recent compression oracle against iMessage attachments. You don't "figure out the password", you grab an encrypted message, alter it, send it, and look for errors in the response. Keep doing this (the paper estimated 2^18 messages) until you have the original plaintext message.

In a similar vein, Vaudenay's CBC mode padding oracle.

The consequence of these attacks? Cryptographers say "unauthenticated encryption is broken". Someone else responds: "No it's not; look, it still works".


You are receiving this because you commented.

Reply to this email directly or view it on GitHub

Tom Ristenpart

unread,
Jun 8, 2016, 7:20:58 PM6/8/16
to vim/vim, vim-dev ML, Comment

Few thoughts from a cryptographer (https://rist.tech.cornell.edu). I use vim as my primary editor for everything (thanks for all the great work on it!). I wanted to know if there was built in password-based encryption for exactly the Dropbox use case mentioned on the thread and lead me eventually to this here.

1) Modern authenticated encryption is now universally thought by cryptographers to be necessary for secure encryption. Encrypt-then-MAC (e.g., CTR mode followed by HMAC) is a good way to go, or an all-in-one scheme like GCM or OCB. Using an authenticated encryption scheme provides resistance against any active attacks that manipulate ciphertexts. This is in my opinion clearly in the threat model for untrusted remote storage (such as Dropbox) --- I for one would not want a malicious insider at Dropbox to be able to undetectably modify at will what my encrypted text document contains.

2) Reiterating something from earlier: Looking at the existing code, the randomness used to generate salts and seeds (usually called IVs by cryptographers) does indeed look very weak. Really this should be replaced as indicated above by a call to a system RNG. If no good system RNG is available, probably safest to just disallow use of encryption (decryption would still be ok). It is a pain to integrate portable RNG code, as Windows, BSD, and Linux all do different things and direct reads from devices like /dev/urandom can introduce race conditions, but it is possible to do well and several other libraries out there have done it. This should be a relatively modest change to sha2_seed() given the RNG logic. By the way, the sha2_seed() function has a latent bug unless I am misunderstanding something, as it repeats random data when 32 < salt_len or 32 < header_len. One shouldn't be repeating random data if it is to be used with crypto algorithms. Doesn't appear to curren tly be a n issue since largest salt_len and header_len is 8 bytes, but an 8 byte salt is too small for security these days even if one has a good RNG --- I'd increase it to 16 or 32.

3) I started playing with the code to understand how hard it would be to build in a good authenticated encryption scheme. Right now I have an Encrypt-then-MAC module built that supports authenticated encryption using AES CTR mode and HMAC-SHA256. But this doesn't seem to work for anything but the main file encryption, as there are several places where encryption is assumed to be length-preserving. (Note that authenticated encryption always means that ciphertexts are longer than decryption, by a fixed number of bytes dependent on mode. For my example it is 32 bytes extra.) These calls are (at least) in undo.c and memline.c, and would need to be modified to support authenticated encryption of (I believe) the undo and swap data. I don't understand the implementation of these modules so not sure how invasive a change this will be. Right now I have my toy implementation default to just using CTR mode for these calls and things seem to work though obviously with weaker guarante es for t hose files. (I haven't done extensive testing.)

4) Side point: the messages one gets when recovering from an encrypted swap file is really confusing. I think I may understand the issue, but this would actually be dealt with in a seemingly more user friendly way if one used authenticated encryption since entering the wrong password would be detectable.

5) The issue of validating crypto implementations is an important one, but this should be easy to do with standard test vectors for low-level primitives like AES and SHA-256 (NIST gives out some, for example). The whole encryption format would do well to be documented as well, though, so one could, e.g., implement a separate utility that just decrypts vim encrypted files.

Happy to help someone with developing a good solution. I think having a built in strong password-based encryption would be a very nice feature for vim, and one that I would use.


You are receiving this because you commented.

Reply to this email directly, view it on GitHub, or mute the thread.

Demetri Obenour

unread,
Jun 9, 2016, 3:27:57 PM6/9/16
to vim/vim, vim-dev ML, Comment

Some more thoughts:

  • My personal preference is to use a Git submodule to bundle libsodium as a dependency and statically link to it. This avoids all issues relating to libsodium not being present on the user's system. Distributions that provide a recent enough libsodium can substitute system libsodium with a configure switch. Substituting a too-old version will result in a compile-time error.
  • libsodium provides high-level APIs, so this should be easy. My preference (assuming that we only need to worry about symmetric-key encryption) is the ChaCha20-Poly1305 AEAD, with Argon2 for password-based key derivation. libsodium also provides a portable CSPRNG that gets entropy from the operating system; this solves the portability problems. It even works around bugs such as Linux /dev/urandom not blocking when not seeded.
  • Argon2 requires (by design) a large amount of RAM. This is a security feature, because high-speed ASIC password crackers are often limited by available on-chip high-speed storage. libsodium offers no way to interrupt Argon2 asynchronously. Therefore, it is best to run Argon2 in a subprocess that is given the password, salt, and other parameters over stdin (in binary form) and returns the hash on stdout (again in binary form). The subprocess can be killed with a SIGKILL on Unix or TerminateProcess on Windows in the event of a timeout, with no risk of leaking resources (since it owns none other than memory).
  • As I understand it, the salt doesn't need to be separately authenticated, in that using a different salt will produce a wrong key (and thus authentication failure) with overwhelming probability. But it is best if it is authenticated, for conservatism – hence the use of the ChaCha20-Poly1305 AEAD.
  • Each time a file is encrypted, a fresh salt must be generated uniformly at random. Therefor, the ChaCha20-Poly1305 nonce can safely be hardcoded to 0. But it would be better if it is generated as part of the key.
  • Do not compress the file. This leaks information if part of the file is attacker-controlled.
  • The Poly1305 MAC is a polynomial authenticator, and its strength is inversely proportional to message length – but I don't think this is an issue (for 1TB files, the forgery probability is 2^-66)

Charles E Campbell

unread,
Jun 9, 2016, 3:56:56 PM6/9/16
to vim...@googlegroups.com
Benjamin Fritz wrote:
>
> On Wed, Mar 23, 2016 at 4:58 PM, Bram Moolenaar <Br...@moolenaar.net
> <mailto:Br...@moolenaar.net>> wrote:
> >
> > > Speaking of defaults: I think Vim should default to the strongest
> > > method available. I additionally think Vim should warn on saving with
> > > a known broken format such as the original blowfish implementation, or
> > > the zip algorithm, or even blowfish2 without a decent KDF. Maybe even
> > > compile without the broken algorithms altogether unless the user
> > > specifically passes --include-bad-crypto to the configure script or
> > > something.
> >
> > This has the danger of writing a file on one system, go on holiday and
> > find out you can't open it on your laptop (that actually happened to
> me).
> >
>
> That makes some sense, however it only applies to people who edit the
> same file on multiple systems, AND they don't have the same version of
> Vim on each of those systems.
And, if libraries are used, the system may update the library (while one
is on holiday), potentially rendering encrypted text unreadable. I know
that these things should be done in a backwards compatible fashion, but
Murphy's Law plus having many users guarantees trouble will happen.

I agree that libraries will get better testing, though.

Chip Campbell

Charles Campbell

unread,
Jun 9, 2016, 4:03:57 PM6/9/16
to vim...@googlegroups.com
Bram Moolenaar wrote:
> My favorite example is when I have some text that I don't want my
> neighbor to read. Any encryption that Vim provides works for that.
> Also keep in mind that, no matter how strong your encryption is, there
> is always a weak point. Rembember key loggers? There never ever is
> 100% reliable encryption. So please don't overreact.
We need quantum cryptography! :)

Once quantum computers become available, all encryption will be for
nought. (quantum cryptography, as I understand it, really only tells
you if someone is snooping on a communication intended to be secure; not
really useful for encrypting a file).

Chip Campbell

Benjamin Fritz

unread,
Jun 9, 2016, 7:05:58 PM6/9/16
to vim_dev


On Thu, Jun 9, 2016 at 2:56 PM, Charles E Campbell <drc...@campbellfamily.biz> wrote:
>  if libraries are used, the system may update the library (while one
> is on holiday), potentially rendering encrypted text unreadable.  I know
> that these things should be done in a backwards compatible fashion, but
> Murphy's Law plus having many users guarantees trouble will happen.
>
> I agree that libraries will get better testing, though.
>

Good point. So we should be sure to link statically to the library.

Of course if the system updates to a new Vim we could still have the problem.

It sounds like once the encryption is finished we should add a reference version encrypted file to the tests, and test that vim can decrypt it. Then the test will fail if a library update breaks the decryption.

cryptoz

unread,
Jun 10, 2016, 1:37:55 AM6/10/16
to vim_dev
I have read many good points here and would like to share some of my thoughts.

The focus of Vim should be still on editor. It does not need to repeat all the hard work that has been done in other projects (e.g., gpg, openssl).

The built-in encryption function can be just a few (or just one) good schemes using symmetric-key algorithms. People have different opinion/preferences on ciphers. My opinion is to take a well studied (and maybe popular) method. For example, AES CCMP (or maybe the 256-bit version).

Another effort is to provide really good support to use 3rd party software so people can use whatever software (e.g., gpg, openssl, 7zip, etc.) they like.

Thanks.

Christian Brabandt

unread,
Aug 14, 2023, 6:05:58 AM8/14/23
to vim/vim, vim-dev ML, Manual

I think this can be closed now, that we are (optionally) using libsodium.


Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/639/1677043408@github.com>

Christian Brabandt

unread,
Aug 14, 2023, 6:05:59 AM8/14/23
to vim/vim, vim-dev ML, Manual

Closed #639 as completed.


Reply to this email directly, view it on GitHub.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issue/639/issue_event/10084729105@github.com>

Reply all
Reply to author
Forward
0 new messages