Skip to content

Commit

Permalink
memcmp() typically does not execute in constant time. Hence timing at…
Browse files Browse the repository at this point in the history
…tack

can be performed while comparing hmacs. Thanks to Scott Arciszewski for
pointing it out. Fixes issue #1
  • Loading branch information
muquit committed Jan 25, 2016
1 parent ca238ab commit e5431fe
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 3 deletions.
31 changes: 30 additions & 1 deletion README.asc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
:toc:
:toc-placement: preamble

A C implementation of Rob Napier's *Objective-C* library https://github.com/RNCryptor/RNCryptor[RNCryptor]'s data format specification. This implementation supports https://github.com/RNCryptor/RNCryptor-Spec/blob/master/RNCryptor-Spec-v3.md[Data Format Specification v3]. Please note, this is not a port of RNCryptor, rather an implementation of the RNCryptor's https://github.com/RNCryptor/RNCryptor-Spec/blob/master/RNCryptor-Spec-v3.md[Data Format Specification v3] in C. Suggestions, bug reports are always welcome. If you have any question, request or suggestion, please enter it in the https://github.com/RNCryptor/RNCryptor-C/issues/[Issues] with appropriate label.
A C implementation of Rob Napier's Objective-C library https://github.com/RNCryptor/RNCryptor[RNCryptor]'s data format specification. This implementation supports https://github.com/RNCryptor/RNCryptor-Spec/blob/master/RNCryptor-Spec-v3.md[Data Format Specification v3]. Please note, this is not a port of RNCryptor, rather an implementation of the RNCryptor's https://github.com/RNCryptor/RNCryptor-Spec/blob/master/RNCryptor-Spec-v3.md[Data Format Specification v3] in C. I wrote this because I like RNCryptor and I use it in iOS. I wanted to decrypt RNCryptor's encrypted files to other platforms but I found the most implementations of RNCryptor's specification are incomplete, buggy and shear lack of documentation. I'm releasing it with the hope that you'll find it useful. Suggestions, bug reports are always welcome. If you have any question, request or suggestion, please enter it in the https://github.com/RNCryptor/RNCryptor-C/issues/[Issues] with appropriate label.
== Requirements
* http://openssl.org[OpenSSL] header files and libraries
Expand Down Expand Up @@ -862,6 +862,35 @@ The encryption and hmac keys are generated with openssl:
$ openssl rand 32 -out tests/encrkeyfile.bin
$ openssl rand 32 -out tests/hmackey.bin
----

== FAQ
1. *How big are the encrypted output size than the plain text?*

RNCryptor's data format v3 uses cipher type AES-256-CBC (AES encryption with 256 bytes long key in CBC mode). In CBC mode, input must have a lenght multiple of block size, therefore input will be padded if necessary.

The encrypted output length can be determined by the following formula:

* For password based encryption
----
output_size = header_size + ciphertext_size + hamc_size
header_size = 34
block_size = 16
ciphertext_size = plaintext_size + block_size - (plaintext_size % block_size)
----
If a plaintext size is say 12 bytes:
----
ciphertext_size = 12 + 16 - (12 % 16)
= 12 + 16 - 12
= 16
----
Note the padding of 4 bytes
----
output_size = 34 + 16 + 32
= 82 bytes
----


== License

The MIT License (MIT)
Expand Down
21 changes: 20 additions & 1 deletion rncryptor_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,24 @@ do \
goto ExitProcessing; \
}\
}while(0)
/*
** from: https://cryptocoding.net/index.php/Coding_rules#Compare_secret_strings_in_constant_time
** compare in constant time
** Issue# 1
*/
int util_cmp_const(const void * a, const void *b, const size_t size)
{
const unsigned char *_a = (const unsigned char *) a;
const unsigned char *_b = (const unsigned char *) b;
unsigned char result = 0;
size_t i;

for (i = 0; i < size; i++) {
result |= _a[i] ^ _b[i];
}

return result; /* returns 0 if equal, nonzero otherwise */
}

/* id is 0 or 1 */
void rncryptorc_set_debug(int d)
Expand Down Expand Up @@ -426,7 +444,8 @@ static int verify_hmac(RNCryptorInfo *ci,const char *password, int password_len)
HMAC_Update(&hmac_ctx,ci->blob->data,ci->blob->length - 32);
HMAC_Final(&hmac_ctx,hmac_sha256,&hmac_len);
HMAC_CTX_cleanup(&hmac_ctx);
rc = memcmp(ci->hmac,hmac_sha256,32);
/* rc = memcmp(ci->hmac,hmac_sha256,32); */
rc = util_cmp_const(ci->hmac,hmac_sha256,32);
if (rc != 0)
{
log_err("ERROR: Could not verify HMAC");
Expand Down
2 changes: 1 addition & 1 deletion tests/test_with_test_vectors.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
** WARNING: This file is auto generated. DO NOT MODIFY
** 2015-06-01 19:54:34 -0400 by GenVectorTests-C.rb
** 2016-01-25 11:00:55 -0500 by GenVectorTests-C.rb
*/
#include "rncryptor_c.h"
#include "mutils.h"
Expand Down

0 comments on commit e5431fe

Please sign in to comment.