ext/polarssl/cipher.c in polarssl-0.0.7 vs ext/polarssl/cipher.c in polarssl-1.0.0

- old
+ new

@@ -28,10 +28,11 @@ VALUE rb_cipher_allocate(); VALUE rb_cipher_initialize(); VALUE rb_cipher_setkey(); VALUE rb_cipher_update(); VALUE rb_cipher_finish(); +VALUE rb_cipher_set_iv(); VALUE rb_cipher_reset(); void rb_cipher_free(); VALUE e_UnsupportedCipher; VALUE e_BadInputData; @@ -57,11 +58,11 @@ * require 'base64' * * my_iv = SecureRandom.random_bytes(16) * * cipher = PolarSSL::Cipher.new("AES-128-CTR") - * cipher.reset(my_iv) + * cipher.set_iv(my_iv, 16) * cipher.setkey("mykey", 128, PolarSSL::Cipher::OPERATION_ENCRYPT) * cipher.update("secret stuff I want encrypted") * encrypted_data = cipher.finish() * * encoded_encrypted_data = Base64.encode64(encrypted_data) @@ -146,11 +147,12 @@ rb_define_alloc_func( cCipher, rb_cipher_allocate ); rb_define_method( cCipher, "initialize", rb_cipher_initialize, 1 ); rb_define_method( cCipher, "setkey", rb_cipher_setkey, 3 ); rb_define_method( cCipher, "update", rb_cipher_update, 1 ); rb_define_method( cCipher, "finish", rb_cipher_finish, 0 ); - rb_define_method( cCipher, "reset", rb_cipher_reset, 1 ); + rb_define_method( cCipher, "set_iv", rb_cipher_set_iv, 2 ); + rb_define_method( cCipher, "reset", rb_cipher_reset, 0 ); } VALUE rb_cipher_allocate( VALUE klass ) { rb_cipher_t *rb_cipher; @@ -168,11 +170,15 @@ } /* * call-seq: new(cipher_type) * - * Initializes a new Cipher object to encrypt data with. For supported cipher types, + * Initializes a new Cipher object to encrypt data with. + * + * cipher = PolarSSL::Cipher.new('AES-128-CTR') + * + * For supported cipher types, * see: https://github.com/michiels/polarssl-ruby/wiki/Using-PolarSSL::Cipher * */ VALUE rb_cipher_initialize( VALUE self, VALUE cipher_type ) { @@ -202,51 +208,70 @@ return self; } /* - * call-seq: reset(initialization_vector) + * call-seq: set_iv(iv_val, iv_len_val) * - * Sets or resets the initialization vector for the cipher. An initialization + * Sets the initialization vector for the cipher. An initialization * vector is used to "randomize" the output ciphertext so attackers cannot * guess your data based on a partially decrypted data. * - * This method needs to be called before you run the first #update. + * cipher.set_iv("16byteiv12345678", 16) * * One option to generate a random initialization vector is by using * SecureRandom.random_bytes. Store this initialization vector with the * ciphertext and you'll easily able to decrypt the ciphertext. * */ -VALUE rb_cipher_reset( VALUE self, VALUE initialization_vector ) +VALUE rb_cipher_set_iv( VALUE self, VALUE iv_val, VALUE iv_len_val ) { + int ret = 0; rb_cipher_t *rb_cipher; unsigned char *iv; - int ret; + size_t iv_len; - Check_Type( initialization_vector, T_STRING ); + Data_Get_Struct( self, rb_cipher_t, rb_cipher ); + Check_Type( iv_val, T_STRING ); + iv = (unsigned char *) StringValuePtr( iv_val ); + Check_Type( iv_len_val, T_FIXNUM ); + iv_len = FIX2INT( iv_len_val ); - iv = (unsigned char *) StringValuePtr( initialization_vector ); + if ( ( ret = cipher_set_iv( rb_cipher->ctx, iv, iv_len ) ) != 0 ) + rb_raise( e_CipherError, "Failed to set IV. PolarSSL error: -0x%x", -ret ); - Data_Get_Struct( self, rb_cipher_t, rb_cipher ); + return Qtrue; +} - ret = cipher_reset( rb_cipher->ctx, iv ); +/* + * call-seq: reset + * + * Reset the cipher context and buffers. + * + * cipher.reset() + * + */ +VALUE rb_cipher_reset( VALUE self ) +{ + int ret; + rb_cipher_t *rb_cipher; - if ( ret < 0 ) - rb_raise( e_BadInputData, "Either the cipher type, key or initialization vector was not set." ); + Data_Get_Struct( self, rb_cipher_t, rb_cipher ); + if ( ( ret = cipher_reset( rb_cipher->ctx ) ) != 0 ) + rb_raise( e_CipherError, "Failed to reset cipher. PolarSSL error: -0x%x", -ret ); + return Qtrue; } /* * call-seq: setkey(key, key_length, operation) * * Sets the key to be used for encrypting/decrypting this cipher. The key, key_length and operation * depend on which cipher you are using. For example, when using AES-128-CTR you would use something like: * - * cipher = PolarSSL::Cipher.new('AES-128-CTR') - * cipher.setkey('mykey', 128, PolarSSL::Cipher::OPERATION_ENCRYPT) + * cipher.setkey('my16bytekey12345', 128, PolarSSL::Cipher::OPERATION_ENCRYPT) * * for both encryping and decrypting your cipher. * */ VALUE rb_cipher_setkey( VALUE self, VALUE key, VALUE key_length, VALUE operation ) @@ -271,10 +296,12 @@ /* * call-seq: update(input) * * Adds input to your cipher. * + * cipher.update("Some message I want to encrypt") + * */ VALUE rb_cipher_update( VALUE self, VALUE rb_input ) { rb_cipher_t *rb_cipher; char *input; @@ -303,10 +330,12 @@ /* * call-seq: finish() * * Finishes encrypting the data added by one or multiple update() calls and returns the encrypted data. * + * encrypted_ciphertext = cipher.finish() + * */ VALUE rb_cipher_finish( VALUE self ) { rb_cipher_t *rb_cipher; int ret; @@ -326,6 +355,6 @@ if ( rb_cipher->ctx ) cipher_free_ctx(rb_cipher->ctx ); xfree( rb_cipher ); -} \ No newline at end of file +}