Class: OpenSSL::CCM

Inherits:
Object
  • Object
show all
Defined in:
lib/openssl/ccm.rb,
lib/openssl/ccm/version.rb

Overview

Abstract from tools.ietf.org/html/rfc3610:

Counter with CBC-MAC (CCM) is a generic authenticated encryption block cipher mode. CCM is defined for use with 128-bit block ciphers, such as the Advanced Encryption Standard (AES).

At the moment there is no update function, because length of data and additional_data are needed at the begin of cipher process. In future init(nonce, data_len, additional_data_len) could be a solution, to solve this problem. After init, update(data) could be used to set additional_data first followed by data.

Constant Summary collapse

VERSION =
'1.2.1'

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cipher, key, mac_len) ⇒ Object

Creates a new CCM object.

Parameters:

  • cipher (String)

    one of the supported algorithms like ‘AES’

  • key (String)

    the key used for encryption and decryption

  • mac_len (Number)

    the length of the mac. needs to be in 4, 6, 8, 10, 12, 14, 16



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/openssl/ccm.rb', line 40

def initialize(cipher, key, mac_len)
  unless CCM.ciphers.include?(cipher)
    fail CCMError, "unsupported cipher algorithm (#{cipher})"
  end
  fail CCMError, 'invalid key length' unless key.b.length >= 16
  unless (4..16).step(2).include?(mac_len)
    fail CCMError, 'invalid mac length'
  end

  if key.length < 24
    cipher_key_size = "128"
  elsif key.length < 32
    cipher_key_size = "192"
  else
    cipher_key_size = "256"
  end

  @cipher = OpenSSL::Cipher.new("#{cipher}-" + cipher_key_size  + "-CBC")
  @key = key
  @mac_len = mac_len
end

Class Method Details

.ciphers[String]

Searches for supported algorithms within OpenSSL

Returns:

  • ([String])

    supported algorithms



23
24
25
26
27
28
# File 'lib/openssl/ccm.rb', line 23

def self.ciphers
  l = OpenSSL::Cipher.ciphers.keep_if { |c| c.end_with?('-128-CBC') or
    c.end_with?('-192-CBC') or c.end_with?('-256-CBC') }
  l.length.times { |i| l[i] = l[i][0..-9] }
  l
end

Instance Method Details

#decrypt(data, nonce, additional_data = '') ⇒ String

Decrypts the input data and checks the appended mac. If additional data was used for encryption, its needed for decryption, to check the authentication (mac).

Parameters:

  • data (String)

    the data to decrypt

  • nonce (String)

    the nonce used for decryption

  • additional_data (String) (defaults to: '')

    additional data to check authentication (not part of the output)

Returns:

  • (String)

    the decrypted data without mac



87
88
89
90
91
92
93
94
# File 'lib/openssl/ccm.rb', line 87

def decrypt(data, nonce, additional_data = '')
  valid?(data, nonce, additional_data)

  new_data = crypt(data.b[0...-@mac_len], nonce)
  new_mac = mac(new_data, nonce, additional_data)
  return new_data if new_mac == data.b[-@mac_len..-1]
  ''
end

#encrypt(data, nonce, additional_data = '') ⇒ String

Encrypts the input data and appends mac for authentication. If there is additional data, its included into mac calculation.

Parameters:

  • data (String)

    the data to encrypt

  • nonce (String)

    the nonce used for encryption

  • additional_data (String) (defaults to: '')

    additional data to authenticate with mac (not part of the output)

Returns:

  • (String)

    the encrypted data with appended mac



71
72
73
74
75
# File 'lib/openssl/ccm.rb', line 71

def encrypt(data, nonce, additional_data = '')
  valid?(data, nonce, additional_data)

  crypt(data, nonce) + mac(data, nonce, additional_data)
end