From bb4b74d2f8dee80160f023c9a9dd1a02dd441992 Mon Sep 17 00:00:00 2001 From: Lars Schmertmann Date: Tue, 1 Apr 2014 22:54:48 +0200 Subject: [PATCH] Documentation update. --- README.md | 33 +++++++++++++++++++++++++++++++-- lib/openssl/ccm.rb | 4 ++-- lib/openssl/ccm/version.rb | 3 +-- pkg/openssl-ccm-1.1.0.gem | Bin 0 -> 24064 bytes 4 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 pkg/openssl-ccm-1.1.0.gem diff --git a/README.md b/README.md index 5f33bf6..f56cc49 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,33 @@ -openssl-ccm -=========== +# openssl-ccm Ruby Gem for RFC 3610 - Counter with CBC-MAC (CCM) + +Abstract from tools.ietf.org/html/rfc3610: Counter with CBC-MAC (CCM) is a generic authenticated encryption block cipher mode. CCM is defined for use with 128-bit block ciphers, such as the Advanced Encryption Standard (AES). + +## Installation + +Add this line to your application's Gemfile: + + gem 'openssl-ccm' + +And then execute: + + $ bundle + +Or install it yourself as: + + $ gem install openssl-ccm + +## Usage + +Example: + + require 'openssl/ccm' + + ccm = OpenSSL::CCM.new('AES', 'My16Byte LongKey', 8) + + ciphertext = ccm.encrypt('The message to encrypt', 'The nonce') + + plaintext = ccm.decrypt(ciphertext, 'The nonce') + +After initialisation, you can use the object as often you need. diff --git a/lib/openssl/ccm.rb b/lib/openssl/ccm.rb index a8ca5d2..958670a 100644 --- a/lib/openssl/ccm.rb +++ b/lib/openssl/ccm.rb @@ -12,14 +12,14 @@ class CCMError < StandardError # ciphers, such as the Advanced Encryption Standard (AES). # # At the moment there is no update function, because length of - # data and additional_data are needed to start of cipher process. + # data and additional_data are needed at the begin of cipher process. # In future init(nonce, data_len, additional_data_len) could # be a solution, to solve this problem. After init, update(data) # could be used to set additional_data first followed by data. class CCM # Searches for supported algorithms within OpenSSL # - # @return [Stringlist] of supported algorithms + # @return [[String]] supported algorithms def self.ciphers l = OpenSSL::Cipher.ciphers.keep_if { |c| c.end_with?('-128-CBC') } l.length.times { |i| l[i] = l[i][0..-9] } diff --git a/lib/openssl/ccm/version.rb b/lib/openssl/ccm/version.rb index 3b8bed7..30b3098 100644 --- a/lib/openssl/ccm/version.rb +++ b/lib/openssl/ccm/version.rb @@ -1,6 +1,5 @@ module OpenSSL - # CCM Version class CCM - VERSION = '1.0.0' + VERSION = '1.1.0' end end diff --git a/pkg/openssl-ccm-1.1.0.gem b/pkg/openssl-ccm-1.1.0.gem new file mode 100644 index 0000000000000000000000000000000000000000..a2027149af8c044de27f4d9520d19ca636104874 GIT binary patch literal 24064 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 a{fS;}S`*}-2>yM>_X6Jwd@t}HQsCd4Zq^L| literal 0 HcmV?d00001