@@ -336,7 +336,7 @@ def test_aes_stream_modes_nist_kat
336336 def test_aes_ctr_streaming_arbitrary_chunks
337337 iv = [ 'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff' ] . pack ( 'H*' )
338338 data = ( "Streaming CTR keeps a running counter across updates. " * 5 ) . b # 265 bytes
339- %w[ aes-128-ctr aes-256-ctr ] . each do |algo |
339+ %w[ aes-128-ctr aes-192-ctr aes- 256-ctr] . each do |algo |
340340 key = OpenSSL ::Cipher . new ( algo ) . random_key
341341 one = OpenSSL ::Cipher . new ( algo ) . encrypt ; one . key = key ; one . iv = iv
342342 expected = one . update ( data ) + one . final
@@ -352,6 +352,88 @@ def test_aes_ctr_streaming_arbitrary_chunks
352352 end
353353 end
354354
355+ def test_other_ctr_ciphers_continue_after_final_on_block_boundary
356+ skip_fips_unapproved_ciphers
357+
358+ algos = %w[ camellia-128-ctr camellia-192-ctr camellia-256-ctr ]
359+ algos += %w[ bf-ctr cast5-ctr des-ctr des-ede3-ctr rc2-ctr twofish-ctr ] if defined? JRUBY_VERSION
360+ algos . each do |algo |
361+ base = OpenSSL ::Cipher . new ( algo )
362+ key = "k" * base . key_len
363+ iv = "\0 " . b * base . iv_len
364+ data = ( "0123456789abcdef" * 2 ) . b
365+
366+ whole = OpenSSL ::Cipher . new ( algo ) . encrypt ; whole . key = key ; whole . iv = iv
367+ expected = whole . update ( data ) + whole . final
368+
369+ split = OpenSSL ::Cipher . new ( algo ) . encrypt ; split . key = key ; split . iv = iv
370+ first = split . update ( data . byteslice ( 0 , base . iv_len ) ) + split . final
371+ second = split . update ( data . byteslice ( base . iv_len , data . bytesize - base . iv_len ) ) + split . final
372+ assert_equal expected , first + second , "#{ algo } encrypt after final"
373+ end
374+ end
375+
376+ def test_ofb_ciphers_continue_after_final_on_block_boundary
377+ skip_fips_unapproved_ciphers
378+
379+ algos = %w[ aes-128-ofb aes-192-ofb aes-256-ofb
380+ camellia-128-ofb camellia-192-ofb camellia-256-ofb ]
381+ algos . each do |algo |
382+ base = OpenSSL ::Cipher . new ( algo )
383+ key = "k" * base . key_len
384+ iv = "v" * base . iv_len
385+ data = ( "0123456789abcdef" * 2 ) . b
386+
387+ whole = OpenSSL ::Cipher . new ( algo ) . encrypt ; whole . key = key ; whole . iv = iv
388+ expected = whole . update ( data ) + whole . final
389+
390+ split = OpenSSL ::Cipher . new ( algo ) . encrypt ; split . key = key ; split . iv = iv
391+ first = split . update ( data . byteslice ( 0 , base . iv_len ) ) + split . final
392+ second = split . update ( data . byteslice ( base . iv_len , data . bytesize - base . iv_len ) ) + split . final
393+ assert_equal expected , first + second , "#{ algo } encrypt after final"
394+
395+ dec = OpenSSL ::Cipher . new ( algo ) . decrypt ; dec . key = key ; dec . iv = iv
396+ plain = dec . update ( first ) + dec . final + dec . update ( second ) + dec . final
397+ assert_equal data , plain , "#{ algo } decrypt after final"
398+ end
399+ end
400+
401+ def test_aes_ctr_continues_after_final_on_block_boundary
402+ iv = [ '000102030405060708090a0b0c0dfeff' ] . pack ( 'H*' )
403+ data = ( "0123456789abcdef" * 4 ) . b
404+
405+ %w[ aes-128-ctr aes-192-ctr aes-256-ctr ] . each do |algo |
406+ key = "k" * OpenSSL ::Cipher . new ( algo ) . key_len
407+ whole = OpenSSL ::Cipher . new ( algo ) . encrypt ; whole . key = key ; whole . iv = iv
408+ expected = whole . update ( data ) + whole . final
409+
410+ enc = OpenSSL ::Cipher . new ( algo ) . encrypt ; enc . padding = 0 ; enc . key = key ; enc . iv = iv
411+ encrypted = "" . b ; offset = 0
412+ 4 . times do
413+ chunk = data . byteslice ( offset , 16 )
414+ encrypted << enc . update ( chunk )
415+ assert_equal "" , enc . final , "#{ algo } encrypt final"
416+ assert_equal "" , enc . final , "#{ algo } repeated final"
417+ offset += chunk . bytesize
418+ end
419+ assert_equal expected , encrypted , "#{ algo } encrypt after final"
420+
421+ dec = OpenSSL ::Cipher . new ( algo ) . decrypt ; dec . padding = 0 ; dec . key = key ; dec . iv = iv
422+ plain = "" . b ; offset = 0
423+ 4 . times do
424+ chunk = encrypted . byteslice ( offset , 16 )
425+ plain << dec . update ( chunk )
426+ assert_equal "" , dec . final , "#{ algo } decrypt final"
427+ offset += chunk . bytesize
428+ end
429+ assert_equal data , plain , "#{ algo } decrypt after final"
430+
431+ enc . reset
432+ enc . iv = iv
433+ assert_equal expected , enc . update ( data ) + enc . final , "#{ algo } reset with IV after final"
434+ end
435+ end
436+
355437 # NIST SP 800-38A F.5.5/F.5.6 AES-256-CTR known-answer vector
356438 def test_aes256_ctr_nist_kat
357439 key = [ '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4' ] . pack ( 'H*' )
0 commit comments