Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

passes all specs, readme, \x00 stripping fixed

  • Loading branch information...
commit 41705b2b00630b06b3160f05e0742e8ef55b995f 1 parent 9b1dda1
Nate Wiger authored
View
39 README.rdoc
@@ -18,7 +18,8 @@ Since this library wraps the Christophe's implementation, it supports a subset o
* Cipher Block Chaining (CBC) mode only
* Data is auto-padded at 16-bit boundaries
-You can read specifics about AES-CBC in the IPSec-related {RFC 3602}[http://www.rfc-archive.org/getrfc.php?rfc=3602]
+You can read specifics about AES-CBC in the IPSec-related {RFC 3602}[http://www.rfc-archive.org/getrfc.php?rfc=3602].
+CBC is a well-tested cipher mode, recommended for {many tasks}[http://www.di-mgt.com.au/cryptopad.html].
=== Other Ruby AES gems
@@ -42,32 +43,44 @@ Simple encryption/decryption:
require 'fast-aes'
- aes = FastAES.new(key) # can be 128, 192, or 256 bits
+ key = '424b3b5c4d454c7a51376748255d7b7156585f543f776243227352746f'
- text = "Hey there"
+ aes = FastAES.new(key) # key can be 128, 192, or 256 bits
+
+ text = "Hey there, how are you?"
data = aes.encrypt(text)
- puts aes.decrypt(data) # "Hey there"
-== Why FastAES
+ puts aes.decrypt(data) # "Hey there, how are you?"
+
+== Why AES?
=== SSL vs AES
I'm going to guess you're using Ruby with Rails, which means you're doing 90+% web development.
-If you need security, SSL is the obvious choice.
+In that case, if you need security, SSL is the obvious choice (and the right one).
-There will probably come a time, however, when you need a couple backend servers to talk, maybe
-job servers, or an admin interface, or whatever. Maybe even a simple chat server.
+But there will probably come a time, padawan, when you need a couple backend servers to talk -
+maybe job servers, or an admin port, or whatever. Maybe even a simple chat server.
You can use SSL for this if you want it to be time-consuming to setup, painful to maintain, and
-slow. Or you can use an alternative, such as AES. Setting up an SSH tunnel is another good
-alternative.
+slow. Or you can use a different algorithm, such as AES. Setting up an SSH tunnel is another good
+alternative (although AES is faster and setup is slightly easier).
+
+=== AES vs Other Encryption Standards
+
+There are a bizillion (really - literally) different encryption standards out there. If you have
+a PhD, and can't find a job, writing an encryption algorithm is a good thing to put on your resume,
+in the desperate hopes that someone will hire you and use it. If you don't possess the talent to
+write an encryption standard, you can spend hours trying to crack one - for similar reasons. As a
+result, of these other encryption alternatives, most are either (a) cracked or (b) covered by patents.
-There are other alternatives, but many of these are either (a) cracked or (b) covered by patents.
+Personally, when it comes to encryption, I think choosing what the US government chooses is a decent
+choice.
-== Special Note
+=== Special Note
-As this software deals with encryption/decryption, please note there is NO WARRANTY, even
+As this software deals with encryption/decryption, please note there is *NO* *WARRANTY*, even
with regards to FITNESS FOR A PARTICULAR PURPOSE. This means if you use this library,
and it turns out there's a flaw in the implementation that results in your data being
hacked, IT'S NOT MY FAULT. It's YOUR responsibility to check the implementation of this
View
2  ext/extconf.rb
@@ -2,7 +2,7 @@
require 'mkmf'
# Give it a name
-extension_name = 'fast-aes'
+extension_name = 'fast_aes'
# The destination
dir_config(extension_name)
View
63 ext/fast_aes.c
@@ -1,9 +1,8 @@
/*//////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
-// Since the AES block cipher (block as in, "Fixed-length blocks") needs 16
-// bytes per cycle, the policy will be to pad input in the encrypt() with zeros
-// to form 16-byte boundaries and encode.
+// Part of the FastAES Ruby/C library implementation.
+// Implementation in C originally by Christophe Devine.
//
////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////*/
@@ -112,10 +111,11 @@ void fast_aes_module_shutdown( fast_aes_t* fast_aes )
{
}
+/* This method **MUST** be present even if it does nothing */
void fast_aes_mark( fast_aes_t* fast_aes )
{
- //rb_gc_mark(??);
- //should we mark each member here?
+ /*rb_gc_mark(??);
+ //should we mark each member here? */
}
void fast_aes_free( fast_aes_t* fast_aes )
@@ -136,17 +136,15 @@ VALUE fast_aes_encrypt(
char* pDataIn = StringValuePtr(buffer);
int uiNumBytesIn = RSTRING_LEN(buffer);
char* pDataOut = malloc((uiNumBytesIn + 15) & -16); /* auto-malloc min size in 16-byte increments */
- // printf("input='%s' (length=%d)\n", pDataIn, uiNumBytesIn);
- /*size_t* puiNumBytesOut*/
unsigned char *pRead, *pWrite;
pRead = (unsigned char*)pDataIn;
pWrite = (unsigned char*)pDataOut;
/*//////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
- // AES does not fail, and this routine will encode all input bytes
- // entirely. */
+ // This routine will encode all input bytes in entirety (AES always "succeeds")
+ */
int puiNumBytesOut = 0;
/* set the state back to the start to allow for correct encryption
@@ -157,12 +155,11 @@ VALUE fast_aes_encrypt(
return Qnil;
}
- //printf( "using key %s to AES %d bits\n", (char*)m_key, strlen((char*)m_key)*8 );
-
/*//////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Perform block encodes 16 bytes at a time while we still have at least
- // 16 bytes of input remaining. */
+ // 16 bytes of input remaining.
+ */
while( uiNumBytesIn >= 16 )
{
fast_aes_encrypt_block(fast_aes, pRead, pWrite);
@@ -174,19 +171,17 @@ VALUE fast_aes_encrypt(
/*//////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Have to catch any straggling bytes that are left after encoding the
- // 16-byte blocks. The policy here will be to pad the input with zeros. */
+ // 16-byte blocks. The policy here will be to pad the input with zeros.
+ */
if( uiNumBytesIn > 0 )
{
unsigned char temp[16];
memset(temp, 0, sizeof(temp)); /* pad with 0's */
- // printf("temp='%s'; pWrite='%s'\n", temp, pWrite);
memcpy(temp, pRead, uiNumBytesIn);
- // printf("temp='%s'; pWrite='%s'\n", temp, pWrite);
fast_aes_encrypt_block(fast_aes, temp, pWrite);
- // printf("temp='%s'; pWrite='%s'\n", temp, pWrite);
puiNumBytesOut += 16;
}
-
+
/* return the encrypted string */
VALUE new_str = rb_str_new(pDataOut, puiNumBytesOut);
free(pDataOut);
@@ -214,21 +209,23 @@ VALUE fast_aes_decrypt(
/*//////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// AES does not fail, and this routine will encode all input bytes
- // entirely. */
+ // entirely.
+ */
int puiNumBytesOut = 0;
- // set the state back to the start to allow for correct decryption
+ /* set the state back to the start to allow for correct decryption
// everytime we are passed data to decrypt
+ */
if (fast_aes_reinitialize_state(fast_aes)) {
rb_raise(rb_eRuntimeError, "Failed to reinitialize AES internal state");
return Qnil;
}
- //printf( "using key %s to AES %d bits\n", (char*)m_key, strlen((char*)m_key)*8 );
- ////////////////////////////////////////////////////////////////////////////
+ /*//////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Perform block decodes 16 bytes at a time while we still have at least
// 16 bytes of input remaining.
+ */
while( uiNumBytesIn >= 16 )
{
fast_aes_decrypt_block(fast_aes, pRead, pWrite);
@@ -237,10 +234,13 @@ VALUE fast_aes_decrypt(
puiNumBytesOut += 16;
}
- ////////////////////////////////////////////////////////////////////////////
+ /*//////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Have to catch any straggling bytes that are left after decoding the
- // 16-byte blocks. The policy here will be to pad the input with zeros.
+ // 16-byte blocks. Strip trailing zeros, which is something fucking
+ // loose-cannon rjc couldn't figure out despite being a "genius". He needs
+ // a punch in the junk, I swear to god.
+ */
if( uiNumBytesIn > 0 )
{
unsigned char temp[16];
@@ -249,15 +249,23 @@ VALUE fast_aes_decrypt(
fast_aes_decrypt_block(fast_aes, temp, pWrite);
puiNumBytesOut += 16;
}
-
+
+ /* Strip zeros, simple but effective. RJC can suck my kawck.
+ * "Senior." LOL. You're fired.
+ */
+ while (puiNumBytesOut > 0) {
+ if (pDataOut[puiNumBytesOut - 1] != 0) break;
+ puiNumBytesOut -= 1;
+ }
+
/* return the decrypted string */
VALUE new_str = rb_str_new(pDataOut, puiNumBytesOut);
free(pDataOut);
return new_str;
}
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
+/*//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////*/
/* uncomment the following line to use pre-computed tables */
/* otherwise the tables will be generated at the first run */
@@ -822,8 +830,9 @@ fast_aes_initialize_state(fast_aes_t* fast_aes)
int
fast_aes_reinitialize_state(fast_aes_t* fast_aes)
{
- // put round keys for encryption and decryption back to their initial
+ /* put round keys for encryption and decryption back to their initial
// states so we can encrypt and decrypt new items properly
+ */
memcpy(fast_aes->erk, fast_aes->initial_erk, sizeof(fast_aes->initial_erk));
memcpy(fast_aes->drk, fast_aes->initial_drk, sizeof(fast_aes->initial_drk));
View
2  fast-aes.gemspec
@@ -3,7 +3,7 @@ spec = Gem::Specification.new do |s|
s.version = '0.1.0'
s.summary = "Fast AES implementation in C. Works with Ruby 1.8 and 1.9"
s.description = s.summary
- s.files = Dir['ext/**/*.{rb,c,h}'] + Dir['spec/**/*.rb'] + Dir['test/**/*.rb']
+ s.files = Dir['ext/**/*.{rb,c,h}'] + Dir['lib/**/*.rb'] + Dir['spec/**/*.rb'] + Dir['test/**/*.rb']
s.require_path = 'lib'
s.has_rdoc = true
s.rubyforge_project = 'fast-aes'
View
28 spec/fast_aes_spec.rb
@@ -8,11 +8,10 @@
Dir.chdir("#{File.dirname(__FILE__)}/../ext") do
system "ruby extconf.rb"
system "make clean"
- system "make"
- system "make install RUBYARCHDIR=#{RUBY_PLATFORM}"
+ system "make && make install RUBYARCHDIR=#{RUBY_PLATFORM}"
end
- require 'fast_aes'
+ require 'fast-aes'
end
it "should accept 128, 192, and 256-bit keys" do
@@ -22,5 +21,28 @@
aes.key.should == key
end
end
+
+ it "should encrypt and decrypt messages (what a concept)" do
+ phrases = [
+ 'Hey there, how are you?',
+ 'You know, encryption is just so gosh-darned cool I wish I had a girlfriend to tell about it!!',
+ 'A subject for a great poet would be God\'s boredom after the seventh day of creation.',
+ 'The individual has always had to struggle to keep from being overwhelmed by the tribe. If you try it, '+
+ 'you will be lonely often, and sometimes frightened. But no price is too high to pay for the privilege of owning yourself.',
+ 'But although all our knowledge begins with experience, it does not follow that it arises from experience.',
+ 'Some with nulls\x00in-between\x00\x00 you know'
+ ]
+
+ phrases.each do |text|
+ [128, 192, 256].each do |bits|
+ key = 'a' * (bits/8)
+ aes = FastAES.new(key)
+ aes.key.should == key
+ data = aes.encrypt(text)
+ aes.decrypt(data).should == text
+ end
+ end
+ end
+
end
Please sign in to comment.
Something went wrong with that request. Please try again.