Project

krypt-cmac

0.0
The project is in a healthy, maintained state
An implementation of AES-CMAC for 128, 192, and 256 bit keys as specified in NIST SP 800-38B and RFC 4493, capable of streaming processing. Also included is an implementation of AES-CMAC-PRF-128 as specified in RFC 4615 and of CMAC-96 as specified in RFC 4494.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies
 Project Readme

Krypt::Cmac

Gem Version

First off, don't use CMAC unless you really need to. HMAC is usually faster, more robust, and easier to use. Only go for CMAC if it's already been decided and you need to work with it.

Krypt::Cmac provides implementations for all versions of the AES-CMAC algorithm as specified in:

It supports 128, 192, and 256-bit keys, variable length keys, and can handle streaming processing. Only AES is supported as the underlying block cipher algorithm. The implementations offer the same public API as OpenSSL::HMAC except for the reset method.

Installation

Add this line to your application's Gemfile:

gem 'krypt-cmac'

And then execute:

bundle install

If you aren't using bundler for managing dependencies, you may install the gem directly by executing:

gem install krypt-cmac

Usage

AES-CMAC with 128, 192 or 256 bits (NIST SP 800-38B, RFC 4493)

When using the default implementation, the size of the key determines the version of AES being used. This implies that keys must be either 128, 192 or 256 bits long, resulting in AES-128-CMAC, AES-192-CMAC or AES-256-CMAC tags. See below for variable key lengths.

require 'krypt/cmac'

key = ["2b7e151628aed2a6abf7158809cf4f3c"].pack("H*")
message = ["6bc1bee22e409f96e93d7e117393172a"].pack("H*")

# One-shot computation
cmac = Krypt::Cmac.new(key)
tag = cmac.digest(message)

# Streaming computation
cmac = Krypt::Cmac.new(key)
cmac.update(message)
tag = cmac.digest

AES-CMAC-96 (RFC 4494)

To generate CMAC tags that are 96 bits long instead of the default 128 bits, use Krypt::Cmac::Cmac96. Note that CMAC-96 tags are simply regular tags truncated to 96 bits. If you need any other tag size below 128 bits, you can truncate the regular tag manually.

require 'krypt/cmac'

key = ["2b7e151628aed2a6abf7158809cf4f3c"].pack("H*")
message = ["6bc1bee22e409f96e93d7e117393172a"].pack("H*")

# AES-CMAC-96 one-shot computation
cmac = Krypt::Cmac::Cmac96.new(key)
tag = cmac.digest(message)

# AES-CMAC-96 streaming computation
cmac = Krypt::Cmac::Cmac96.new(key)
cmac.update(message)
tag = cmac.digest

AES-CMAC-PRF-128 (RFC 4615)

If you need to generate CMAC tags from keys of varying lengths and not the usual 128, 192, or 256 bit range, use AES-CMAC-PRF-128 as provided by Krypt::Cmac::CmacPrf128. It computes a regular AES-CMAC on the key first and uses the 128 bit result as the actual key for CMAC computation. You might also use it if you need an AES-128-CMAC tag for keys that are 192 or 256 bits long. Using regular AES-CMAC with such keys would compute AES-192-CMAC and AES-256-CMAC tags respectively.

require 'krypt/cmac'

key = ["2b7e151628aed2a6abf7158809cf4f3c"].pack("H*")
message = ["6bc1bee22e409f96e93d7e117393172a"].pack("H*")

# AES-CMAC-PRF-128 one-shot computation
cmac = Krypt::Cmac::CmacPrf128.new(key)
tag = cmac.digest(message)

# AES-CMAC-PRF-128 streaming computation
cmac = Krypt::Cmac::CmacPrf128.new(key)
cmac.update(message)
tag = cmac.digest

Tag verification

Verifying a given tag means recomputing it and then comparing the two. However, it is crucial for security reasons to avoid comparing them with == or similar comparisons subject to short-circuiting. To securely verify a tag, use:

require 'krypt/cmac'

key = ["2b7e151628aed2a6abf7158809cf4f3c"].pack("H*")
message = ["6bc1bee22e409f96e93d7e117393172a"].pack("H*")
tag = ["070a16b46b4d4144f79bdd9dd04a287c"].pack("H*")

# Verifying a tag with data supplied to the method
cmac = Krypt::Cmac.new(key)
valid = cmac.verify(tag, message)

# Verifying a tag without data supplied to the method
cmac = Krypt::Cmac.new(key)
cmac.update(message)
begin
  valid = cmac.verify(tag)
  puts "Tag successfully verified"
rescue Krypt::Cmac::TagMismatchError => e
  # tag invalid
end

Even though the verify method returns true on successful verification, it still raises a Krypt::Cmac::TagMismatchError on invalid tags. This ensures that invalid tags cannot go undetected if the verifying code forgets to check for true explicitly.

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in lib/krypt/cmac/version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/krypt/krypt-cmac.

License

The gem is available as open source under the terms of the MIT License.