Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KeyForPassword() broken for multi-byte passwords (UTF-8) #77

Closed
arthurwalasek opened this issue Aug 21, 2013 · 2 comments
Closed

KeyForPassword() broken for multi-byte passwords (UTF-8) #77

arthurwalasek opened this issue Aug 21, 2013 · 2 comments
Labels
Milestone

Comments

@arthurwalasek
Copy link

In the code for keyforpassword() you will find:

int result = CCKeyDerivationPBKDF(keySettings.PBKDFAlgorithm,      // algorithm
                   password.UTF8String, // password
                   password.length, // passwordLength
                   ...

The problem is that password.length is the length of the password BEFORE UTF8 encoding, and you are passing the password as a UTF8String. UTF8 encoding will be longer than the original string if using multi-byte characters (use non-english keyboard or hold down a vowel and pick a different symbol).

the password length should be calculated by something like:
const char *utfpass = password.UTF8String;
size_t utfpasslen = strlen(utfpass);

int result = CCKeyDerivationPBKDF(keySettings.PBKDFAlgorithm,      // algorithm
                   utfpass,                // password
                   utfpasslen,                    // passwordLength
                   ...

Unfortunately, keyforpassword() is used during decrypt as well...

@rnapier
Copy link
Member

rnapier commented Aug 22, 2013

That is a really good catch and a major security issue. The password is being significantly shortened for multibyte passwords.

The fix is very easy:

[password lengthOfBytesUsingEncoding:NSUTF8StringEncoding], // passwordLength

My problem is thinking through how to address it for existing files, since this change would cause files that were encrypted with multibyte characters to no longer decrypt at all.

The obvious answer is to rev the format version so the semantics are clear. I'm just trying to think through if that's the only way to do it correctly.

@arthurwalasek
Copy link
Author

I can send you what I did to fix it - it involves when decrypting - if
decrypting fails, to check the 2 password lengths (1 with UTF8 1 without).
If they differ, then decrypt the old way and re-encrypt the new correct
way. I also had to change RNDecryptor for the common header function to
also do it the old way if I set a flag. Basically I made a new
"badkeyforpassword" function that still did it the old way, and called it
instead of the correct one when this condition occurred and I couldn't
decrypt...

On Wed, Aug 21, 2013 at 7:47 PM, Rob Napier notifications@git.luolix.topwrote:

That is a really good catch and a major security issue. The password is
being significantly shortened.

The fix is very easy:

[password lengthOfBytesUsingEncoding:NSUTF8StringEncoding], // passwordLength

My problem is thinking through how to address it for existing files, since
this change would cause files that were encrypted with multibyte characters
to no longer decrypt at all.


Reply to this email directly or view it on GitHubhttps://github.com//issues/77#issuecomment-23065251
.

rnapier added a commit that referenced this issue Dec 20, 2013
rnapier added a commit that referenced this issue Dec 20, 2013
Kyle-Brown pushed a commit to MacPractice/RNCryptor that referenced this issue Feb 28, 2018
Fixes RNCryptor#64: Crash with non-literal password

Summary:
Fixes RNCryptor#57: Typo in README

Fixes RNCryptor#54: Memory leak in [RNCryptor initWithHandler:]

PHP Implementation: Adding support for RNCryptor file version 1, migrating procedural code to OO, and file structure cleanup

Refactoring for code clarity

Ignoring files that should not be tracked (e.g. Eclipse IDE and MAC OS stuff)

Renaming XCode test directory for PHP impl

Adding PHPUnit test suite for PHP impl

Some instructions for PHP impl test suite

PHP impl code coverage files should not be versioned

Turning on code coverage analysis

Regression fix: Encrypting in v0 and v1 was calculating HMAC incorrectly

Improved handling of invalid schema versions

Splitting RNCryptor.php into separate RNEncryptor.php and RNDecryptor.php files; Moving credits and licensing info for PHP impl out of the classes and into separate files

Making HMAC validate properly for schema 0

Merge pull request RNCryptor#68 from curtisdf/master

A bunch of improvements to the PHP implementation, including OO rebuild and support for file version 1

Bugfix: Decryption should assume PKCS7 padding; Cleanup of padding-related code during encryption

Completed adding support for schema 0; Added more unit tests

More tests; Cleaner versions of AES-CTR crypt routines; Documentation update

Fixes two warnings about missing function header declarations

Fixes missing newline and end warning

Refactoring for clarity and simplicity

Refactoring: Settings consolidation, better readability

Merge pull request RNCryptor#70 from curtisdf/master

PKCS7 padding

Merge pull request RNCryptor#71 from steipete/master

Fixes several warnings

Fixes RNCryptor#72 Base64.h and Base64.m were in each others' files

Add decrypt function

Update Python version of RNCryptor (add decryption, rafactoring).

improved podspec, it should support OSX

Improved Python version of RNCryptor (performance, python3).

Merge pull request RNCryptor#74 from brantyoung/master

Add decrypt function for Python implemention

Update .gitignore

Merge pull request RNCryptor#76 from mneorr/osx

improved podspec, it should support OSX

Update .gitignore

Merge branch 'master' of git://github.com/ykalchevskiy/RNCryptor into ykalchevskiy-master

Merge branch 'ykalchevskiy-master'

Remove unneeded pkcs7 package

Convert to XCTest

Minor test cleanup

Move OpenSSL tests into their own file

Add test case for Issue RNCryptor#77

Missing headers in RNCryptor.framework (OS X target)

Merge pull request RNCryptor#89 from brantyoung/master

Missing headers in RNCryptor.framework (OS X target)

Issue RNCryptor#77: Add test case to make sure we can decrypt our old files.

Fixes RNCryptor#77: KeyForPassword() broken for multi-byte passwords (UTF-8) Bumps version number to 3.

Convert to XCTest

Minor test cleanup

Move OpenSSL tests into their own file

Add test case for Issue RNCryptor#77

Merge branch 'issue77'

Updated Ruby version to support file format version 3

This verison will attempt to decrypt encrypted files that may have been
encrypted with truncated multibyte passwords.

Add test vectors for totally empty

Add version handling

Password vectors

Merge pull request RNCryptor#90 from timestretch/master

Updated Ruby version to support file format version 3

KDF vectors

Refactor vectors to siplify code.

Refactor Verify

Fixes RNCryptor#85: PHP: Very Slow Use urandom (non-blocking) by default. This is the correct setting for the vast majority of users.

Fixes RNCryptor#84: Decrypting large (200 MB) file causes huge memory spike

Fixes RNCryptor#78: Divide by zero found in static analysis

Fixes RNCryptor#91 Use constant time HMAC comparisons to avoid timing attacks

Fix RNCryptor#24 Crash on 0-length input Just add tests. It actually works fine.

Improve README.

Fix RNCryptor#93 Update podspec for v2.2

Rewrap README

Fix spacing in README

Fix naming of executable

Fix vectors to use hex vs string correctly

Merging changes to PHP implementation from the master branch which should have gone into the develop branch in the first place

Merge branch 'develop' of https://github.com/rnapier/RNCryptor into develop

Making remaining Key and Password vector tests pass

Removing the requirement for pre-processing vectors; Making v1 and v2 encryption behave like Obj-C by truncating Multibyte passwords in the same way; Code cleanups since v3 additions; Bumping default schema to v3

Merge pull request RNCryptor#101 from curtisdf/develop

PHP v3 finished

Add ChangeLog. Fix python to output format-3 files.

Merge branch 'release/2.2'

Merge branch 'release/2.2' into develop

Use SecureRandom

Merge pull request RNCryptor#105 from klaaspieter/secure-random

Use SecureRandom

Merge branch 'develop'

Move ruby to ruby_rncryptor repository

Move vectors to RNCryptor-Spec repo

Add Spec gitmodules

Point vectors to new Spec submodule

update to latest Spec directory

Update vector validator to point to correct vectors

Point to new spec

Update Spec to require non-empty passwords

Add short (1000 iteration) password vectors

Add short kdf vectors

Working on GenVectorTests. Parses the vector file

First pass GenVectorTests

Generate KDF tests for Xcode

Testing Travis

Move to https submodule

Remove Spec

Switch to https for Spec

Update Spec

Correct the submodule

Add shareddata

Handled a little older version of Ruby

Add enumerable for older ruby (?)

Fix to ruby 2.0.0

Remove extra language line from travis config

Show env variables for ruby script

Update dot-files

Trying ruby in the xcode script

Try /usr/bin/ruby in xcode

Ask travis what ruby it's running

Remove "chunked" from GenVectorTests

Ask for ruby 2

Add rvm to xcode

Another ruby try

Call rvm inside of xcode

Directly call what I hope is the right ruby

Backport to ruby 1.8.3

Fix hard-coded path in xcodeproj

Build for simulator

Add OS X test

Add OSX scheme

Test the oldest releases we support

Bump back test to SDKs travis supports Refactor vector parsing into shared library

Fix warning on OS X 10.8.

Switch to individual scripts to handle build vs test

Switch to matrix

Remove 5.0 testing (since it's not supported)

Auto-generate kdf_short vector tests

refactor test creation

Port all vector tests

Remove old rncryptorvectors project. Now integrated into unit testing

Move php to RNCryptor-php

Move python implementation to RNCryptor-python

Update README.md

iOS: RNCryptor#109 issue fix

Merge pull request RNCryptor#111 from rock88/master

Fixes RNCryptor#109 Headers marked public

Updated links to other languages' repos

Fix minor typo in README.

Fix duplicate content in README

Merge pull request RNCryptor#114 from gabceb/patch-1

Updates links to other languages' repos on README file

Move RNOpenSSLCryptor into its own directory

Move openssl tests to their own directory

Remove old rncryptorvector target

Update Changelog

Refactor generated tests to support versions

Handle v1 test vectors

Update travis to 6.1.

Fix 64-bit test build failures

Travis really doesn't support the 5.0 simulator. travis-ci/travis-ci#2297

Add brew upgrade to fix out-of-date xctool

Add brew update first for Travis... travis-ci/travis-ci#1825

Merge pull request RNCryptor#122 from Armenm/master

Fix duplicate content in README

Fix minor issue in the rnc_isEqualInConsistentTime: NSData method.  I'm pretty sure it's not a problem for RNCryptor's usage, but in general use it was possible for two NSDatas, where one was a prefix of the other and their lengths differ by...

...exactly 256, to compare as equal when they were not.  I added a unit test to exhibit the problem.

The bug was simply using "-" instead of "!=", but truncating the result into an 8-bit value.  This problem would be flagged if the suspicious implicit conversions warning was turned on, so I added that to the project (and quieted some unit test code which was flagged though that was not a bug).  I found the issue when using the source files in another project which did have that warning turned on.  It's possible some other warnings should be enabled.

Update README.md

Fixed broken link containing a line break.

Merge pull request RNCryptor#126 from carllindberg/FixConsistentTimeCompareBug2

Fix minor issue in the rnc_isEqualInConsistentTime: NSData method.

Merge pull request RNCryptor#128 from testzugang/master

Update README.md

Switch to iOS 7.1 for Travis

Move OpenSSL tests into RNOpenSSLCryptor repo

Fixes RNCryptor#147 RNCryptor Inside a Framework. Copy all the CommonCrypto header information we need into our own header.

Fix travis

Addj\ing iOS Framework

Switching namespace

Adding modulemap

Adding a new module map

Add assertion that key decryption is passed key of expected length.

Fix issues identified by Facebook Infer

Merge pull request RNCryptor#151 from DABSquared/iosFramework

iOS Framework

Merge pull request RNCryptor#152 from madsolar8582/fixups

Fix issues identified by Infer

Update Spec link

Fixes RNCryptor#147 RNCryptor Inside a Framework

Update podspec

Updating Podspec

Merge pull request RNCryptor#160 from bassrock/patch-1

Updating Podspec

v3.0.1 Fix podspec to exclude private headers. Minor cleanup in tests.

Perform final decryption iff HMAC validates successfully

Prevent incorrect assertion when corrupt/random data is interpreted as a preamble

Simplify comment

Fixes for Xcode 8 and iOS 10

Bump podspec version

Update podspec for 3.0.2

Add watchOS and tvOS support.

Remove non-modular header from framework header

Upgrade to build on Xcode 9b1. Fixes RNCryptor#17

Merge pull request RNCryptor#11 from brendonjustin/module

Remove non-modular header from framework header

Merge branch 'additional-platforms' of https://github.com/SlaunchaMan/RNCryptor-objc

Remove RNCryptorEngine.h from new public headers

Merge branch 'master' of github.com:RNCryptor/RNCryptor-objc

Release 3.0.4

Cleanup warnings for Cocoapods

Merge branch 'upstreamMaster'

# Conflicts:
#	RNCryptor.xcodeproj/project.pbxproj
#	RNCryptor/RNCryptor.m
#	RNCryptor/RNOpenSSLCryptor.m

Test Plan: Make sure the parts of MP and iEHR that use RNCryptor work as expected - encrypting backups and storing iEHR state data

Differential Revision: https://dev.macpractice.net/D18690
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants