class Analyzers::CbcMac::VariableLength::Analyzer
Public Class Methods
This class implements an attack on CBC-MAC with variable length. This issue is known for a long time and thus should be avoided by any implementation. However this code shows how to forge a tag in this mode and can be seen das a PoC.
Thanks to Matthew Green for this great article about the potential implementation problems of CBC-MAC: blog.cryptographyengineering.com/2013/02/why-i-hate-cbc-mac.html
This class has the VL (variable length) suffix it its name to make100% clear that this attack works only on this condition
# File lib/crypto-toolbox/analyzers/cbc_mac/variable_length/analyzer.rb, line 18 def initialize(oracle_class = ::Analyzers::CbcMac::VariableLength::Oracles::Tcp,block_length=32) @oracle = oracle_class.new end
Public Instance Methods
NOTE: handle too short messages properly
# File lib/crypto-toolbox/analyzers/cbc_mac/variable_length/analyzer.rb, line 23 def analyze(target_message) @oracle.connect # split the target message into chunks of size N (e.g. 32) target_bufs = CryptBuffer(target_message).chunks_of(32) # receive the valid mac for the first chunk of the target message tag1 = CryptBuffer(@oracle.mac(target_bufs[0])) attack_message = assemble_malicious_message(target_bufs,tag1) forged_tag = @oracle.mac(attack_message) ret = @oracle.verify(target_message, forged_tag) report_result(ret,forged_tag) @oracle.disconnect end
Private Instance Methods
Create a message that consists of 1) the first n byte of the second message xored with tag t from the first message 2) the remaining blocks of the second message short: t'' = (m'_0 xor t ) ||m'_1 ||…||m'_n]
# File lib/crypto-toolbox/analyzers/cbc_mac/variable_length/analyzer.rb, line 47 def assemble_malicious_message(target_bufs,tag1) # split the second chunk into blocks of the size of the tag m2_blocks = target_bufs[1].chunks_of(tag1.length) CryptBuffer((m2_blocks[0].xor(tag1)).bytes + m2_blocks[1].bytes) end
# File lib/crypto-toolbox/analyzers/cbc_mac/variable_length/analyzer.rb, line 63 def forge_successfull?(retval) retval == 1 end
# File lib/crypto-toolbox/analyzers/cbc_mac/variable_length/analyzer.rb, line 55 def report_result(ret,tag) if forge_successfull?(ret) puts "[Success] Resulting tag is: #{CryptBuffer(tag).pretty_hexstring}" else puts "[Failure] Message verification failed." end end