aead 1.8.0 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4fa60b57e4bf63e26513af118b1ed12edc3eba1f
4
- data.tar.gz: 567bc3e4243d6ef1f38950bc998af9fcddf28260
3
+ metadata.gz: ec5ecf304323da8bdc09bf7d9e4c7aabff91f9d9
4
+ data.tar.gz: 78b797df1043c60fbd5a63be09a0988f981577c4
5
5
  SHA512:
6
- metadata.gz: 513380c93ec0da891916e9f4788168896c8e8e7fdc01e0c05a23022f7d4d7b3055790f16d6a0dd1f1b4c5c8266dc11b274c41c6c6f2d4dcf6e414de41bfaa04c
7
- data.tar.gz: 7cf3219248dd1f0adae7b1be92e3d1cdab0af560ffd76c0e5398449e03bb24caf54bf78a6db51b808097dc326a0e988c124caf2c16c3af1d999a33fca1d160a1
6
+ metadata.gz: f6c7ca97b9619a9c31b05d8a9ada8388e923822f2735ab68c0d8e590e59a1781e0ca69f3d79a05adcc04527ba5e3e8c71fe08c75c8c21df66c6a7e22dea946b4
7
+ data.tar.gz: fa86c9dd50321c3c0f5f15811636bab1db7976b7bc32bbd900756d3ac477d0f0e0630a2e6bb1c7ee62d4b5040f11a5ab5230e6b9de7e87b8edcb3c2f2dd2203c
@@ -1,3 +1,4 @@
1
1
  rvm:
2
- - 1.9.2
3
2
  - 1.9.3
3
+ - 2.0.0
4
+ - 2.1.2
data/Gemfile CHANGED
@@ -1,7 +1,3 @@
1
1
  source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
-
5
- gem 'terminal-notifier-guard'
6
- gem 'pry'
7
- gem 'pry-doc'
data/README.md CHANGED
@@ -23,8 +23,8 @@ require 'aead'
23
23
 
24
24
  # currently, AES-256-GCM and AES-256-CTR-HMAC-SHA-256 are supported
25
25
  mode = AEAD::Cipher.new('AES-256-GCM')
26
- key = cipher.generate_key
27
- nonce = cipher.generate_nonce
26
+ key = mode.generate_key
27
+ nonce = mode.generate_nonce
28
28
 
29
29
  cipher = mode.new(key)
30
30
  aead = cipher.encrypt(nonce, 'authentication data', 'plaintext')
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.8.0
1
+ 1.8.1
@@ -17,6 +17,8 @@ Gem::Specification.new do |gem|
17
17
  gem.executables = `git ls-files -- script/*`.split("\n").map {|e| e[7..-1] }
18
18
  gem.test_files = `git ls-files -- spec/*` .split("\n")
19
19
 
20
+ gem.licenses = ['MIT']
21
+
20
22
  gem.add_dependency 'macaddr', '~> 1'
21
23
 
22
24
  gem.add_development_dependency 'bundler'
@@ -25,7 +27,7 @@ Gem::Specification.new do |gem|
25
27
  gem.add_development_dependency 'guard-minitest'
26
28
  gem.add_development_dependency 'guard-yard'
27
29
  gem.add_development_dependency 'markdown'
28
- gem.add_development_dependency 'minitest'
30
+ gem.add_development_dependency 'minitest', '~> 4'
29
31
  gem.add_development_dependency 'rake'
30
32
  gem.add_development_dependency 'redcarpet'
31
33
  gem.add_development_dependency 'simplecov'
@@ -126,6 +126,24 @@ ossl_cipher_set_tag(VALUE self, VALUE data)
126
126
  return data;
127
127
  }
128
128
 
129
+ static VALUE
130
+ ossl_cipher_set_iv_length(VALUE self, VALUE iv_length)
131
+ {
132
+ EVP_CIPHER_CTX *ctx;
133
+ int ivlen = NUM2INT(iv_length);
134
+
135
+ GetCipher(self, ctx);
136
+
137
+ #ifndef EVP_CTRL_GCM_SET_IVLEN
138
+ ossl_raise(eCipherError, "your version of OpenSSL doesn't support GCM");
139
+ #else
140
+ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL))
141
+ ossl_raise(eCipherError, NULL);
142
+ #endif
143
+
144
+ return iv_length;
145
+ }
146
+
129
147
  static VALUE
130
148
  ossl_cipher_verify(VALUE self)
131
149
  {
@@ -149,8 +167,9 @@ Init_aead(void)
149
167
 
150
168
  eCipherError = rb_define_class_under(mOSSLCipher, "CipherError", eOSSLError);
151
169
 
152
- rb_define_method(mOSSLCipher, "aad=", ossl_cipher_set_aad, 1);
153
- rb_define_method(mOSSLCipher, "gcm_tag", ossl_cipher_get_tag, 0);
154
- rb_define_method(mOSSLCipher, "gcm_tag=", ossl_cipher_set_tag, 1);
155
- rb_define_method(mOSSLCipher, "verify", ossl_cipher_verify, 0);
170
+ rb_define_method(mOSSLCipher, "aad=", ossl_cipher_set_aad, 1);
171
+ rb_define_method(mOSSLCipher, "gcm_tag", ossl_cipher_get_tag, 0);
172
+ rb_define_method(mOSSLCipher, "gcm_tag=", ossl_cipher_set_tag, 1);
173
+ rb_define_method(mOSSLCipher, "gcm_iv_len=", ossl_cipher_set_iv_length, 1);
174
+ rb_define_method(mOSSLCipher, "verify", ossl_cipher_verify, 0);
156
175
  }
@@ -8,6 +8,7 @@ require 'securerandom'
8
8
  # Wraps AEAD ciphers in a simplified interface.
9
9
  #
10
10
  class AEAD::Cipher
11
+ autoload :AES_128_GCM, 'aead/cipher/aes_128_gcm'
11
12
  autoload :AES_256_GCM, 'aead/cipher/aes_256_gcm'
12
13
  autoload :AES_256_CBC_HMAC_SHA_256, 'aead/cipher/aes_256_cbc_hmac_sha_256'
13
14
  autoload :AES_256_CTR_HMAC_SHA_256, 'aead/cipher/aes_256_ctr_hmac_sha_256'
@@ -18,7 +19,7 @@ class AEAD::Cipher
18
19
  # @param [String] algorithm the AEAD implementation to use
19
20
  # @return [Class] the cipher implementation
20
21
  #
21
- def self.new(algorithm)
22
+ def self.new(algorithm, options = {})
22
23
  # run normal Class#new if we're being called from a subclass
23
24
  return super unless self == AEAD::Cipher
24
25
 
@@ -110,7 +111,6 @@ class AEAD::Cipher
110
111
  #
111
112
  def encrypt(nonce, aad, plaintext)
112
113
  _verify_nonce_bytesize(nonce, self.nonce_len)
113
- _verify_plaintext_presence(plaintext)
114
114
 
115
115
  self._encrypt(
116
116
  _pad_nonce(nonce),
@@ -147,6 +147,8 @@ class AEAD::Cipher
147
147
  # The secret key provided by the user.
148
148
  attr_accessor :key
149
149
 
150
+ attr_writer :iv_len
151
+
150
152
  #
151
153
  # Initializes the cipher.
152
154
  #
@@ -155,12 +157,14 @@ class AEAD::Cipher
155
157
  # @param [String] key the encryption key supplied by the user
156
158
  # @return [Cipher] the initialized Cipher
157
159
  #
158
- def initialize(algorithm, key)
160
+ def initialize(algorithm, key, options = {})
159
161
  _verify_key_bytesize(key, self.key_len)
160
162
 
161
163
  self.algorithm = algorithm.dup.freeze
162
164
  self.key = key.dup.freeze
163
165
 
166
+ self.iv_len = options[:iv_len]
167
+
164
168
  self.freeze
165
169
  end
166
170
 
@@ -178,7 +182,7 @@ class AEAD::Cipher
178
182
  # @return [Integer] the length of initialization vectors in bytes
179
183
  #
180
184
  def iv_len
181
- self.class.iv_len
185
+ @iv_len || self.class.iv_len
182
186
  end
183
187
 
184
188
  #
@@ -201,15 +205,10 @@ class AEAD::Cipher
201
205
  end
202
206
 
203
207
  def _verify_nonce_bytesize(nonce, nonce_len)
204
- raise ArgumentError, "nonce must be at least #{nonce_len} bytes" unless
208
+ raise ArgumentError, "nonce must be #{nonce_len} bytes" unless
205
209
  nonce.bytesize == nonce_len
206
210
  end
207
211
 
208
- def _verify_plaintext_presence(plaintext)
209
- raise ArgumentError, 'plaintext must not be empty' unless
210
- not plaintext.nil? and not plaintext.empty?
211
- end
212
-
213
212
  def _pad_nonce(nonce)
214
213
  nonce.rjust(self.iv_len, "\0")
215
214
  end
@@ -0,0 +1,17 @@
1
+ require 'aead/cipher'
2
+ require 'aead/cipher/aes_gcm'
3
+
4
+ #
5
+ # Encrypt plaintext using the Galois Counter Mode of AES.
6
+ #
7
+ class AEAD::Cipher::AES_128_GCM < AEAD::Cipher
8
+ include AEAD::Cipher::AES_GCM
9
+
10
+ def self.cipher_mode; 'aes-128-gcm'; end
11
+
12
+ def self.key_len; 16; end
13
+ def self.iv_len; 12; end
14
+ #def self.nonce_len; 12; end
15
+ def self.tag_len; 16; end
16
+
17
+ end
@@ -1,45 +1,17 @@
1
1
  require 'aead/cipher'
2
+ require 'aead/cipher/aes_gcm'
2
3
 
3
4
  #
4
5
  # Encrypt plaintext using the Galois Counter Mode of AES.
5
6
  #
6
7
  class AEAD::Cipher::AES_256_GCM < AEAD::Cipher
8
+ include AEAD::Cipher::AES_GCM
9
+
10
+ def self.cipher_mode; 'aes-256-gcm'; end
11
+
7
12
  def self.key_len; 32; end
8
13
  def self.iv_len; 12; end
9
14
  def self.nonce_len; 12; end
10
15
  def self.tag_len; 16; end
11
16
 
12
- #
13
- # Instantiates the cipher with a secret key.
14
- #
15
- # @param [String] key a secret encryption key
16
- #
17
- def initialize(key)
18
- super('aes-256-gcm', key)
19
- end
20
-
21
- protected
22
-
23
- def _encrypt(nonce, aad, plaintext)
24
- self.cipher(:encrypt) do |cipher|
25
- cipher.key = self.key
26
- cipher.iv = nonce
27
- cipher.aad = aad.to_s if aad
28
-
29
- cipher.update(plaintext) + cipher.final + cipher.gcm_tag
30
- end
31
- end
32
-
33
- def _decrypt(nonce, aad, ciphertext, tag)
34
- self.cipher(:decrypt) do |cipher|
35
- cipher.key = self.key
36
- cipher.iv = nonce
37
- cipher.gcm_tag = tag
38
- cipher.aad = aad.to_s if aad
39
-
40
- cipher.update(ciphertext).tap { cipher.verify }
41
- end
42
- rescue OpenSSL::Cipher::CipherError
43
- raise ArgumentError, 'ciphertext failed authentication step'
44
- end
45
17
  end
@@ -0,0 +1,51 @@
1
+ require 'aead/cipher'
2
+
3
+ #
4
+ # Provides the implementation details of AES + GCM, assuming the
5
+ # class including this module has defined proper class methods.
6
+ #
7
+ module AEAD::Cipher::AES_GCM
8
+
9
+ #
10
+ # Instantiates the cipher with a secret key.
11
+ #
12
+ # @param [String] key a secret encryption key
13
+ #
14
+ def initialize(key, options = {})
15
+ super(self.class.cipher_mode, key, options)
16
+ end
17
+
18
+ def nonce_len
19
+ iv_len
20
+ end
21
+
22
+ protected
23
+
24
+ def _encrypt(nonce, aad, plaintext)
25
+ self.cipher(:encrypt) do |cipher|
26
+ cipher.gcm_iv_len = self.iv_len
27
+ cipher.key = self.key
28
+ cipher.iv = nonce
29
+ cipher.aad = aad.to_s if aad
30
+
31
+ unless plaintext.nil? || plaintext.empty?
32
+ ciphertext = cipher.update(plaintext)
33
+ end
34
+ ciphertext = (ciphertext || "") + cipher.final + cipher.gcm_tag
35
+ end
36
+ end
37
+
38
+ def _decrypt(nonce, aad, ciphertext, tag)
39
+ self.cipher(:decrypt) do |cipher|
40
+ cipher.gcm_iv_len = self.iv_len
41
+ cipher.key = self.key
42
+ cipher.iv = nonce
43
+ cipher.gcm_tag = tag
44
+ cipher.aad = aad.to_s if aad
45
+
46
+ cipher.update(ciphertext).tap { cipher.verify }
47
+ end
48
+ rescue OpenSSL::Cipher::CipherError
49
+ raise ArgumentError, 'ciphertext failed authentication step'
50
+ end
51
+ end
@@ -10,7 +10,7 @@ module AEAD::Cipher::AES_HMAC
10
10
  #
11
11
  # @param [String] key a secret encryption key
12
12
  #
13
- def initialize(key)
13
+ def initialize(key, options = {})
14
14
  super(self.class.cipher_mode, key)
15
15
  end
16
16
 
@@ -29,7 +29,10 @@ module AEAD::Cipher::AES_HMAC
29
29
  cipher.key = self.encryption_key
30
30
  cipher.iv = nonce
31
31
 
32
- ciphertext = cipher.update(plaintext) + cipher.final
32
+ unless plaintext.nil? || plaintext.empty?
33
+ ciphertext = cipher.update(plaintext)
34
+ end
35
+ ciphertext = (ciphertext || "") + cipher.final
33
36
  mac = hmac_generate(nonce, aad.to_s, ciphertext)
34
37
 
35
38
  ciphertext << mac
@@ -0,0 +1,149 @@
1
+ require 'spec_helper'
2
+ require 'aead/cipher/aes_128_gcm'
3
+
4
+ describe AEAD::Cipher::AES_128_GCM do
5
+ subject { self.cipher.new(self.key) }
6
+
7
+ let(:algo) { 'aes-128-gcm' }
8
+ let(:cipher) { AEAD::Cipher.new(algo) }
9
+ let(:key) { self.cipher.generate_key }
10
+ let(:nonce) { self.cipher.generate_nonce }
11
+ let(:aad) { SecureRandom.random_bytes }
12
+ let(:plaintext) { SecureRandom.random_bytes }
13
+
14
+ it 'must decrypt its own ciphertexts' do
15
+ ciphertext = subject.encrypt(self.nonce, self.aad, self.plaintext)
16
+ plaintext = subject.decrypt(self.nonce, self.aad, ciphertext)
17
+
18
+ plaintext.must_equal self.plaintext
19
+ end
20
+
21
+ it 'must require a 128-bit or larger key' do
22
+ bad_keys = [ 0, 1, 15 ].map {|size| SecureRandom.random_bytes(size) }
23
+ good_keys = [ 16, 17, 256 ].map {|size| SecureRandom.random_bytes(size) }
24
+
25
+ bad_keys.each do |key|
26
+ lambda { self.cipher.new(key) }.must_raise ArgumentError
27
+ end
28
+
29
+ good_keys.each do |key|
30
+ self.cipher.new(key).must_be_kind_of AEAD::Cipher
31
+ end
32
+ end
33
+
34
+ it 'must require a 12-byte nonce by default' do
35
+ bad_nonces = [0, 1, 11, 13 ].map {|size| SecureRandom.random_bytes(size) }
36
+ good_nonces = [ 12 ] .map {|size| SecureRandom.random_bytes(size) }
37
+
38
+ bad_nonces.each do |nonce|
39
+ lambda { self.subject.encrypt(nonce, self.plaintext, self.aad) }.
40
+ must_raise ArgumentError
41
+ end
42
+
43
+ good_nonces.each do |nonce|
44
+ self.subject.encrypt(nonce, self.plaintext, self.aad).
45
+ must_be_kind_of String
46
+ end
47
+ end
48
+
49
+ it 'must require a correct length nonce' do
50
+ cipher = self.cipher.new(self.key, :iv_len => 16)
51
+ bad_nonces = [0, 1, 15, 17 ].map {|size| SecureRandom.random_bytes(size) }
52
+ good_nonces = [ 16 ] .map {|size| SecureRandom.random_bytes(size) }
53
+
54
+ bad_nonces.each do |nonce|
55
+ lambda { cipher.encrypt(nonce, self.plaintext, self.aad) }.
56
+ must_raise ArgumentError
57
+ end
58
+
59
+ good_nonces.each do |nonce|
60
+ cipher.encrypt(nonce, self.plaintext, self.aad).
61
+ must_be_kind_of String
62
+ end
63
+ end
64
+
65
+ it 'must accept empty plaintext' do
66
+ self.subject.encrypt(nonce, self.aad, nil).must_be_kind_of String
67
+ self.subject.encrypt(nonce, self.aad, '').must_be_kind_of String
68
+ end
69
+
70
+ it 'must encrypt plaintexts correctly' do
71
+ subject.encrypt(self.nonce, self.aad, self.plaintext).
72
+ must_equal openssl_encrypt(self.key, self.nonce, self.aad, self.plaintext)
73
+ end
74
+
75
+ it 'must decrypt ciphertexts correctly' do
76
+ ciphertext = openssl_encrypt(self.key, self.nonce, self.aad, self.plaintext)
77
+
78
+ subject.decrypt(self.nonce, self.aad, ciphertext).
79
+ must_equal openssl_decrypt(self.key, self.nonce, self.aad, ciphertext)
80
+ end
81
+
82
+ it 'must resist manipulation of the key' do
83
+ ciphertext = subject.encrypt(self.nonce, self.aad, self.plaintext)
84
+ cipher = self.cipher.new twiddle(key)
85
+
86
+ lambda { cipher.decrypt(self.nonce, self.aad, ciphertext) }.
87
+ must_raise ArgumentError
88
+ end
89
+
90
+ it 'must resist manipulation of the nonce' do
91
+ ciphertext = subject.encrypt(self.nonce, self.aad, self.plaintext)
92
+ nonce = twiddle(self.nonce)
93
+
94
+ lambda { self.subject.decrypt(nonce, self.aad, ciphertext) }.
95
+ must_raise ArgumentError
96
+ end
97
+
98
+ it 'must resist manipulation of the ciphertext' do
99
+ ciphertext = subject.encrypt(self.nonce, self.aad, self.plaintext)
100
+ ciphertext = twiddle(ciphertext)
101
+
102
+ lambda { self.subject.decrypt(self.nonce, self.aad, ciphertext) }.
103
+ must_raise ArgumentError
104
+ end
105
+
106
+ it 'must resist manipulation of the aad' do
107
+ ciphertext = subject.encrypt(self.nonce, self.aad, self.plaintext)
108
+ aad = twiddle(self.aad)
109
+
110
+ lambda { self.subject.decrypt(self.nonce, aad, ciphertext) }.
111
+ must_raise ArgumentError
112
+ end
113
+
114
+ def twiddle(bytes)
115
+ # pick a random byte to change
116
+ index = SecureRandom.random_number(bytes.bytesize)
117
+
118
+ # change it by a random offset that won't loop back around to its
119
+ # original value
120
+ offset = SecureRandom.random_number(254) + 1
121
+ ord = bytes[index].ord
122
+ byte = (ord + offset).modulo(256).chr
123
+
124
+ # reconstruct the bytes with the twiddled bit inserted in place
125
+ bytes[0, index] << byte << bytes[index.succ..-1]
126
+ end
127
+
128
+ def openssl_encrypt(key, nonce, aad, plaintext)
129
+ cipher = OpenSSL::Cipher.new(self.algo).encrypt
130
+ cipher.key = key
131
+ cipher.iv = nonce
132
+ cipher.aad = aad if aad
133
+
134
+ cipher.update(plaintext) + cipher.final + cipher.gcm_tag
135
+ end
136
+
137
+ def openssl_decrypt(key, nonce, aad, ciphertext)
138
+ tag = ciphertext[ -16 .. -1 ]
139
+ ciphertext = ciphertext[ 0 .. -17 ]
140
+
141
+ cipher = OpenSSL::Cipher.new(self.algo).decrypt
142
+ cipher.key = key
143
+ cipher.iv = nonce
144
+ cipher.gcm_tag = tag
145
+ cipher.aad = aad if aad
146
+
147
+ cipher.update(ciphertext).tap { cipher.verify }
148
+ end
149
+ end if OpenSSL::Cipher.ciphers.include?('aes-128-gcm')
@@ -32,8 +32,10 @@ describe AEAD::Cipher::AES_256_CBC_HMAC_SHA_256 do
32
32
  end
33
33
 
34
34
  it 'must require a 16-byte nonce' do
35
- bad_nonces = [ 0, 1, 15, 17 ].map {|size| SecureRandom.random_bytes(size) }
36
- good_nonces = [ 16 ] .map {|size| SecureRandom.random_bytes(size) }
35
+ bad_nonces = [ 0, 1, 15, 17 ]
36
+ .map { |size| SecureRandom.random_bytes(size) }
37
+ good_nonces = [ 16 ]
38
+ .map { |size| SecureRandom.random_bytes(size) }
37
39
 
38
40
  bad_nonces.each do |nonce|
39
41
  lambda { self.subject.encrypt(nonce, self.plaintext, self.aad) }.
@@ -46,9 +48,9 @@ describe AEAD::Cipher::AES_256_CBC_HMAC_SHA_256 do
46
48
  end
47
49
  end
48
50
 
49
- it 'must require a non-empty plaintext' do
50
- lambda { self.subject.encrypt(nonce, self.aad, nil) }.must_raise ArgumentError
51
- lambda { self.subject.encrypt(nonce, self.aad, '') }.must_raise ArgumentError
51
+ it 'must accept empty plaintext' do
52
+ self.subject.encrypt(nonce, self.aad, nil).must_be_kind_of String
53
+ self.subject.encrypt(nonce, self.aad, '').must_be_kind_of String
52
54
  end
53
55
 
54
56
  it 'must encrypt plaintexts correctly' do
@@ -46,9 +46,9 @@ describe AEAD::Cipher::AES_256_CTR_HMAC_SHA_256 do
46
46
  end
47
47
  end
48
48
 
49
- it 'must require a non-empty plaintext' do
50
- lambda { self.subject.encrypt(nonce, self.aad, nil) }.must_raise ArgumentError
51
- lambda { self.subject.encrypt(nonce, self.aad, '') }.must_raise ArgumentError
49
+ it 'must accept empty plaintext' do
50
+ self.subject.encrypt(nonce, self.aad, nil).must_be_kind_of String
51
+ self.subject.encrypt(nonce, self.aad, '').must_be_kind_of String
52
52
  end
53
53
 
54
54
  it 'must encrypt plaintexts correctly' do
@@ -31,7 +31,7 @@ describe AEAD::Cipher::AES_256_GCM do
31
31
  end
32
32
  end
33
33
 
34
- it 'must require a 12-byte nonce' do
34
+ it 'must require a 12-byte nonce by default' do
35
35
  bad_nonces = [0, 1, 11, 13 ].map {|size| SecureRandom.random_bytes(size) }
36
36
  good_nonces = [ 12 ] .map {|size| SecureRandom.random_bytes(size) }
37
37
 
@@ -46,9 +46,25 @@ describe AEAD::Cipher::AES_256_GCM do
46
46
  end
47
47
  end
48
48
 
49
- it 'must require a non-empty plaintext' do
50
- lambda { self.subject.encrypt(nonce, self.aad, nil) }.must_raise ArgumentError
51
- lambda { self.subject.encrypt(nonce, self.aad, '') }.must_raise ArgumentError
49
+ it 'must require a correct length nonce' do
50
+ cipher = self.cipher.new(self.key, :iv_len => 16)
51
+ bad_nonces = [0, 1, 15, 17 ].map {|size| SecureRandom.random_bytes(size) }
52
+ good_nonces = [ 16 ] .map {|size| SecureRandom.random_bytes(size) }
53
+
54
+ bad_nonces.each do |nonce|
55
+ lambda { cipher.encrypt(nonce, self.plaintext, self.aad) }.
56
+ must_raise ArgumentError
57
+ end
58
+
59
+ good_nonces.each do |nonce|
60
+ cipher.encrypt(nonce, self.plaintext, self.aad).
61
+ must_be_kind_of String
62
+ end
63
+ end
64
+
65
+ it 'must accept empty plaintext' do
66
+ self.subject.encrypt(nonce, self.aad, nil).must_be_kind_of String
67
+ self.subject.encrypt(nonce, self.aad, '').must_be_kind_of String
52
68
  end
53
69
 
54
70
  it 'must encrypt plaintexts correctly' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aead
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.0
4
+ version: 1.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Touset
8
8
  autorequire:
9
9
  bindir: script
10
10
  cert_chain: []
11
- date: 2013-10-30 00:00:00.000000000 Z
11
+ date: 2014-12-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: macaddr
@@ -112,16 +112,16 @@ dependencies:
112
112
  name: minitest
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - ">="
115
+ - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '0'
117
+ version: '4'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - ">="
122
+ - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '0'
124
+ version: '4'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: rake
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -214,12 +214,15 @@ files:
214
214
  - ext/openssl/cipher/aead/extconf.rb
215
215
  - lib/aead.rb
216
216
  - lib/aead/cipher.rb
217
+ - lib/aead/cipher/aes_128_gcm.rb
217
218
  - lib/aead/cipher/aes_256_cbc_hmac_sha_256.rb
218
219
  - lib/aead/cipher/aes_256_ctr_hmac_sha_256.rb
219
220
  - lib/aead/cipher/aes_256_gcm.rb
221
+ - lib/aead/cipher/aes_gcm.rb
220
222
  - lib/aead/cipher/aes_hmac.rb
221
223
  - lib/aead/nonce.rb
222
224
  - lib/openssl/cipher/.gitignore
225
+ - spec/aead/cipher/aes_128_gcm_spec.rb
223
226
  - spec/aead/cipher/aes_256_cbc_hmac_sha_256_spec.rb
224
227
  - spec/aead/cipher/aes_256_ctr_hmac_sha_256_spec.rb
225
228
  - spec/aead/cipher/aes_256_gcm_spec.rb
@@ -227,7 +230,8 @@ files:
227
230
  - spec/aead/nonce_spec.rb
228
231
  - spec/spec_helper.rb
229
232
  homepage: https://github.com/onelogin/aead
230
- licenses: []
233
+ licenses:
234
+ - MIT
231
235
  metadata: {}
232
236
  post_install_message:
233
237
  rdoc_options: []
@@ -245,14 +249,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
245
249
  version: '0'
246
250
  requirements: []
247
251
  rubyforge_project:
248
- rubygems_version: 2.2.0.preview.1
252
+ rubygems_version: 2.2.2
249
253
  signing_key:
250
254
  specification_version: 4
251
255
  summary: Ruby library to generate AEADs
252
256
  test_files:
257
+ - spec/aead/cipher/aes_128_gcm_spec.rb
253
258
  - spec/aead/cipher/aes_256_cbc_hmac_sha_256_spec.rb
254
259
  - spec/aead/cipher/aes_256_ctr_hmac_sha_256_spec.rb
255
260
  - spec/aead/cipher/aes_256_gcm_spec.rb
256
261
  - spec/aead/cipher_spec.rb
257
262
  - spec/aead/nonce_spec.rb
258
263
  - spec/spec_helper.rb
264
+ has_rdoc: