Skip to content

Encryption: Provide better alternative using libsodium for encryption#8394

Closed
chrisbra wants to merge 1 commit intovim:masterfrom
chrisbra:libsodium_public
Closed

Encryption: Provide better alternative using libsodium for encryption#8394
chrisbra wants to merge 1 commit intovim:masterfrom
chrisbra:libsodium_public

Conversation

@chrisbra
Copy link
Member

@chrisbra chrisbra commented Jun 16, 2021

After the issues #638 and #639 I thought about exploring alternatives to
make the crypt code more modern and robust. So for the last couple of
weeks and spend my spare time exploring things and improving my crypt
skills ;)

One of the mentioned alternatives was
libsodium, which is a
library providing encryption, hashing and other cryptographic features
for end-users. Fortunately it is cross plattform so can be used across a
variety of platforms.

This is currently work in progress, it compiles and seems to work for
me, but is not yet considered stable. Also, I am currently not sure, the
changes to memline/memfile are actually correct. I don't really that
low-level code of the data blocks :/

The reason I am posting it here is, that I'd like to get feedback about
the current scope.

In addition I am not so sure, how to properly hook into encrypting the
blocks for swapfiles and undo-files. For stream-encoding, libsodium
needs to know, when a stream of messages is completed and adds an
additional tag for verification. However given the current design of the
block-writing code, I am not sure how to detect whether the current call
for encrypting will be the last one. So I would like to have some
guidance here.

For now, I have just sprinkled a couple of static TRUE and FALSE for the
swap file encryption and for undo-file encryption I just disabled
complete encryption.

Also the current read-file and write-file end up using different block
sizes, so I made some slight changes to the read-file code, to ensure,
that blocks of 8K will be read to make sure that the crypt layer can read
the same block size when reading as when writing. Not sure if there is a
better way to achieve this.

And of course, I'd like to get some CI builds done :)

I'll have a look at the windows changes, once I get my windows build
system ready. Not sure how much work this requires.

Todo:

  • fix error numbers
  • write tests
  • make changes to the windows build system
  • enable complete undofile encryption (?)

@codecov
Copy link

codecov bot commented Jun 16, 2021

Codecov Report

Merging #8394 (e7fa60a) into master (2fb7495) will decrease coverage by 0.49%.
The diff coverage is 60.11%.

❗ Current head e7fa60a differs from pull request most recent head c9255fd. Consider uploading reports for the commit c9255fd to get more accurate results
Impacted file tree graph

@@            Coverage Diff             @@
##           master    #8394      +/-   ##
==========================================
- Coverage   89.85%   89.35%   -0.50%     
==========================================
  Files         149      145       -4     
  Lines      167551   165750    -1801     
==========================================
- Hits       150548   148113    -2435     
- Misses      17003    17637     +634     
Flag Coverage Δ
huge-clang-none 88.68% <56.77%> (-0.31%) ⬇️
huge-gcc-none 89.26% <58.38%> (-0.05%) ⬇️
huge-gcc-testgui ?
huge-gcc-unittests ?

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
src/blowfish.c 87.60% <ø> (ø)
src/crypt_zip.c 97.05% <ø> (ø)
src/evalfunc.c 95.82% <ø> (-0.50%) ⬇️
src/optionstr.c 94.80% <ø> (-0.25%) ⬇️
src/version.c 92.34% <ø> (ø)
src/crypt.c 70.21% <48.36%> (-22.99%) ⬇️
src/bufwrite.c 84.72% <83.33%> (-0.05%) ⬇️
src/memline.c 88.77% <83.33%> (-0.04%) ⬇️
src/fileio.c 84.74% <85.00%> (-0.25%) ⬇️
src/option.c 93.68% <100.00%> (-0.21%) ⬇️
... and 96 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2fb7495...c9255fd. Read the comment docs.

@chrisbra
Copy link
Member Author

Oh and for development I have used libsodium-dev version 1.0.18, which is from january 2019 and readily available in my ubuntu box.

@brammool
Copy link
Contributor

brammool commented Jun 16, 2021 via email

@atoponce
Copy link

I see the Blowfish -> XChaCha20-Poly1305 change fixing #638, but I don't see a KDF replacement for sha256_key() in blowfish.c fixing #639. You've imported libsodium, so you can take advantage of the crypto_pwhash_* API which uses Argon2id, or crypto_pwhash_scryptsalsa208sha256_* which uses Scrypt.

@chrisbra
Copy link
Member Author

Yes, blowfish is kept separate. But the XChaCha20-Poly1305 uses the crypt_pwhash API and it also uses the randombytes API for the salt and the seed.

I did not want to touch the blowfish code for now, as I don't know, if this is backwards compatible (e.g. if this will can still decrypt existing blowfish encrypted files (swap files, undofile, files))

@chrisbra
Copy link
Member Author

okay, let's disable the swapfile encryption. I also made a couple of other small adjustments (such as proper key derivation). Concrete further suggestions welcome!

@brammool
Copy link
Contributor

brammool commented Jun 17, 2021 via email

xchacha20 XChaCha20 Cipher with Poly1305 Message Authentication
Code. Medium strong till strong encryption.
Encryption is provided by the libsodium library, so it
requires Vim to be build with |+sodium|

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
requires Vim to be build with |+sodium|
requires Vim to be built with |+sodium|

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!

encrypted. This needs at least a Vim 8.XXXX to read
such a file. Encryption of Swapfiles not supported,
therefore swap files will be disabled.
Currently experiemental.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Currently experiemental.
Currently experimental.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will be fixed on next push

@chrisbra
Copy link
Member Author

I think you mean "disable the swapfile". When using strong encryption

Yes of course.

writing the swapfile (accidentally) leaks the text, thus I think we
should make it impossible to enable the swapfile.

I fixed a couple of more problems to make sure Vim closes the swapfile
and won't try to encrypt it. I also fixed a couple of edge cases that come from
the fact, that since the new crypt code allocates a new buffer, converting
could cause a buffer-overflow. Also properly free the allocated buffer.

The swapfile is temporary, thus some people may think it's OK. But
these days with SSD and other types of disks deleting a file doesn't
mean the text is gone. Even reformatting the disk may not help.

I also disabled the undofile. I thought it worked before, but when writing the tests,
I got a couple of overflows, most likely, because the size was too small.

I added some tests to ensure the buffer size for en/decoding is large enough.

Tests should be there in a minute , once I push. They probably won't yet run,
I need to make changes to the CI, so that vim is build with libsodium.

@brammool
Copy link
Contributor

brammool commented Jun 17, 2021 via email

@chrisbra
Copy link
Member Author

It may require using a different file format for the undo file.

Yes, lets leave that for later. Personally, I think it may make sense to disable undo files for sensitive data.

I have also added some slight changes to the MSVC and MSYS Makefiles. I cannot test the MSVC build however. The MSYS build works however.

@brammool
Copy link
Contributor

The change in eval.txt uses spaces instead of tabs.

Is this now good enough to include? I think we should mark this "experimental", so that users know that the encoding may still change and files might not decrypt with a later version of Vim. This will give users some time to try it out and hopefully some crypt experts can check if we are using the crypt method properly.

After the issues vim#638 and vim#639 I thought about exploring alternatives to
make the crypt code more modern and robust. So for the last couple of
weeks and spend my spare time exploring things and improving my crypt
skills ;)

One of the mentioned alternatives was
[libsodium](https://libsodium.gitbook.io/doc/), which is a
library providing encryption, hashing and other cryptographi features
for end-users. Fortunately it is cross plattform so can be used across a
variety of platforms.

This is currently work in progress, it compiles and seems to work for
me, but is not yet considered stable. Also, I am currently not sure, the
changes to memline/memfile are actually correct. I don't really that
low-level code of the data blocks :/

The reason I am posting it here is, that I'd like to get feedback about
the current scope.

In addition I am not so sure, how to properly hook into encrypting the
blocks for swapfiles and undo-files. For stream-encoding, libsodium
needs to know, when a stream of messages is completed and adds an
additional tag for verification. However given the current design of the
block-writing code, I am not sure how to detect whether the current call
for encrypting will be the last one. So I would like to have some
guidance here.

For now, I have just sprinkled a couple of static TRUE and FALSE for the
swap file encryption and for undo-file encryption I just disabled
complete encryption.

Also the current read-file and write-file end up using different block
sizes, so I made some slight changes to the read-file code, to ensure,
that blocks of 8K will be read to make sure that the crypt layer can read
the same block size when reading as when writing. Not sure if there is a
better way to achieve this.

And of course, I'd like to get some CI builds done :)

I'll have a look at the windows changes, once I get my windows build
system ready. Not sure how much work this requires.

Tests are written and enabled in the CI system.

Also, a couple of minor bugs have been fixed in the reading and writing
of buffers code.

Todo:

- [ ] fix error numbers
- [ ] write tests
- [ ] make changes to the windows build system
- [ ] enable complete undofile encryption (?)
@chrisbra
Copy link
Member Author

The change in eval.txt uses spaces instead of tabs.

Fixed that.

Is this now good enough to include? I think we should mark this "experimental", so that users know that the encoding may still change and files might not decrypt with a later version of Vim. This will give users some time to try it out and hopefully some crypt experts can check if we are using the crypt method properly.

Yes, should be good now. I made a couple of minor adjustments (added proper error numbers) and adjusted the documentation a bit. I think it is good to be tried out now.

@brammool brammool closed this in f573c6e Jun 20, 2021
@brammool
Copy link
Contributor

brammool commented Jun 20, 2021 via email

@chrisbra
Copy link
Member Author

Hi Bram, thanks for merging.

The 'swapfile' option is disabled when 'cryptmethod' is set, but no key
has been entered yet. The swapfile should only be disabled when
encryption is actually setup, thus the 'key' option is not empty.

Are you talking about manually setting the key? E.g. not after :X? It makes sense,
but manually setting the key should not be done.

The "corrupted chunk" note is incorrect. We may not be able to
distinguish between a wrong password

Okay makes sense, will change.

I wonder why the invalid sample text is so long.

I was trying to get a file that is written in 2 chunks, so 16384 K. I made some mistakes, but thought it would be a good test sample nevertheless.

I'll create a follow-up PR implementing those changes.

@vim-ml
Copy link

vim-ml commented Jun 20, 2021 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants