Class: Miscreant::AES::CMAC

Inherits:
Object
  • Object
show all
Defined in:
lib/miscreant/aes/cmac.rb

Overview

The AES-CMAC message authentication code

Instance Method Summary collapse

Constructor Details

#initialize(key) ⇒ CMAC

Create a new AES-CMAC instance

Parameters:

  • key (String)

    16-byte or 32-byte Encoding::BINARY cryptographic key



12
13
14
15
16
17
18
19
20
21
# File 'lib/miscreant/aes/cmac.rb', line 12

def initialize(key)
  @cipher = Internals::AES::BlockCipher.new(key)

  @subkey1 = Internals::Block.new
  @subkey1.encrypt(@cipher)
  @subkey1.dbl

  @subkey2 = @subkey1.dup
  @subkey2.dbl
end

Instance Method Details

#digest(message) ⇒ String

Compute the AES-CMAC of the given input message in a single shot, outputting the MAC tag.

Unlike other AES-CMAC implementations, this one does not support incremental processing/IUF operation. (Though that would enable slightly more efficient decryption for AES-SIV)

Parameters:

  • message (String)

    an Encoding::BINARY string to authenticate

Returns:

  • (String)

    CMAC tag



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

def digest(message)
  Internals::Util.validate_bytestring("message", message)

  if message.empty? || message.length % Internals::Block::SIZE != 0
    message = Internals::Util.pad(message, Internals::Block::SIZE)
    subkey = @subkey2
  else
    subkey = @subkey1
  end

  count = message.length / Internals::Block::SIZE
  digest = Internals::Block.new

  count.times do |i|
    digest.xor_in_place(message[Internals::Block::SIZE * i, Internals::Block::SIZE])
    digest.xor_in_place(subkey) if i == count - 1
    digest.encrypt(@cipher)
  end

  digest.data
end

#inspectString

Inspect this AES-CMAC instance

Returns:

  • (String)

    description of this instance



26
27
28
# File 'lib/miscreant/aes/cmac.rb', line 26

def inspect
  to_s
end