@@ -174,6 +174,48 @@ def test_authenticated
174174 assert_not_predicate ( cipher , :authenticated? )
175175 end
176176
177+ def test_aes_ccm
178+ # RFC 3610 Section 8, Test Case 1
179+ key = [ "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" ] . pack ( "H*" )
180+ iv = [ "00000003020100a0a1a2a3a4a5" ] . pack ( "H*" )
181+ aad = [ "0001020304050607" ] . pack ( "H*" )
182+ pt = [ "08090a0b0c0d0e0f101112131415161718191a1b1c1d1e" ] . pack ( "H*" )
183+ ct = [ "588c979a61c663d2f066d0c2c0f989806d5f6b61dac384" ] . pack ( "H*" )
184+ tag = [ "17e8d12cfdf926e0" ] . pack ( "H*" )
185+
186+ kwargs = { auth_tag_len : 8 , iv_len : 13 , key : key , iv : iv }
187+ cipher = new_encryptor ( "aes-128-ccm" , **kwargs , ccm_data_len : pt . length , auth_data : aad )
188+ assert_equal ct , cipher . update ( pt ) << cipher . final
189+ assert_equal tag , cipher . auth_tag
190+ cipher = new_decryptor ( "aes-128-ccm" , **kwargs , ccm_data_len : ct . length , auth_tag : tag , auth_data : aad )
191+ assert_equal pt , cipher . update ( ct ) << cipher . final
192+
193+ # truncated tag is accepted
194+ cipher = new_encryptor ( "aes-128-ccm" , **kwargs , ccm_data_len : pt . length , auth_data : aad )
195+ assert_equal ct , cipher . update ( pt ) << cipher . final
196+ assert_equal tag [ 0 , 8 ] , cipher . auth_tag ( 8 )
197+ cipher = new_decryptor ( "aes-128-ccm" , **kwargs , ccm_data_len : ct . length , auth_tag : tag [ 0 , 8 ] , auth_data : aad )
198+ assert_equal pt , cipher . update ( ct ) << cipher . final
199+
200+ # wrong tag is rejected
201+ tag2 = tag . dup
202+ tag2 . setbyte ( -1 , ( tag2 . getbyte ( -1 ) + 1 ) & 0xff )
203+ cipher = new_decryptor ( "aes-128-ccm" , **kwargs , ccm_data_len : ct . length , auth_tag : tag2 , auth_data : aad )
204+ assert_raise ( OpenSSL ::Cipher ::CipherError ) { cipher . update ( ct ) }
205+
206+ # wrong aad is rejected
207+ aad2 = aad [ 0 ..-2 ] << aad [ -1 ] . succ
208+ cipher = new_decryptor ( "aes-128-ccm" , **kwargs , ccm_data_len : ct . length , auth_tag : tag , auth_data : aad2 )
209+ assert_raise ( OpenSSL ::Cipher ::CipherError ) { cipher . update ( ct ) }
210+
211+ # wrong ciphertext is rejected
212+ ct2 = ct [ 0 ..-2 ] << ct [ -1 ] . succ
213+ cipher = new_decryptor ( "aes-128-ccm" , **kwargs , ccm_data_len : ct2 . length , auth_tag : tag , auth_data : aad )
214+ assert_raise ( OpenSSL ::Cipher ::CipherError ) { cipher . update ( ct2 ) }
215+ end if has_cipher? ( "aes-128-ccm" ) &&
216+ OpenSSL ::Cipher . new ( "aes-128-ccm" ) . authenticated? &&
217+ OpenSSL ::OPENSSL_VERSION_NUMBER >= 0x10101000 # version >= v1.1.1
218+
177219 def test_aes_gcm
178220 # GCM spec Appendix B Test Case 4
179221 key = [ "feffe9928665731c6d6a8f9467308308" ] . pack ( "H*" )
0 commit comments