aead 1.8.0 → 1.8.1

Sign up to get free protection for your applications and to get access to all the features.
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: