I'm working on implementing a protocol and per the specification I need to encrypt / decrypt data using AES-128-CCM and AES-128-GCM. My question is: how do you use CCM mode while specifying the Cipher#auth_data? All the examples I find online are using GCM mode which seems to be working, while CCM does not. The exception I encounter is a very generic OpenSSL::Cipher::CipherError
with no additional details.
The example code I have below works when algo
is either option (AES-128-CCM or AES-128-GCM), and no auth_data is nil
, or when algo is AES-128-GCM and the auth_data is non-nil
.
I'm using Ruby v2.5.5 and OpenSSL v2.1.2.
algo = 'AES-128-CCM' # AES-128-GCM works
auth_data = OpenSSL::Random.random_bytes(32) # nil works
cipher = OpenSSL::Cipher.new(algo).encrypt
if algo == 'AES-128-CCM'
cipher.auth_tag_len = 16
cipher.iv_len = 11
elsif algo == 'AES-128-GCM'
cipher.iv_len = 12
end
key = cipher.random_key
iv = cipher.random_iv
# has to be done in this order for unknown reasons
if algo == 'AES-128-CCM'
encrypted = cipher.update('Hello World') + cipher.final
cipher.auth_data = auth_data unless auth_data.nil?
elsif algo == 'AES-128-GCM'
cipher.auth_data = auth_data unless auth_data.nil?
encrypted = cipher.update('Hello World') + cipher.final
end
auth_tag = cipher.auth_tag
cipher = OpenSSL::Cipher.new(algo).decrypt
if algo == 'AES-128-CCM'
cipher.auth_tag_len = 16
cipher.iv_len = 11
elsif algo == 'AES-128-GCM'
cipher.iv_len = 12
end
cipher.key = key
cipher.iv = iv
cipher.auth_tag = auth_tag
cipher.update(encrypted) # crashes when auth_data != nil and algo == AES-128-CCM