Sha256: 549e6e31be676050111a294da08dc166c371673434a4caca1586912b16c61207

Contents?: true

Size: 1.78 KB

Versions: 1

Compression:

Stored size: 1.78 KB

Contents

require 'aead/cipher'

#
# Provides the implementation details of AES + HMAC, assuming the
# class including this module has defined proper class methods.
#
module AEAD::Cipher::AES_HMAC
  #
  # Initializes the cipher with a given secret encryption key.
  #
  # @param [String] key a secret encryption key
  #
  def initialize(key, options = {})
    super(self.class.cipher_mode, key)
  end

  protected

  def encryption_key
    self.key[0, self.class.encryption_key_len]
  end

  def signing_key
    self.key[self.class.encryption_key_len, self.class.signing_key_len]
  end

  def _encrypt(nonce, aad, plaintext)
    self.cipher(:encrypt) do |cipher|
      cipher.key = self.encryption_key
      cipher.iv  = nonce

      unless plaintext.nil? || plaintext.empty?
        ciphertext = cipher.update(plaintext)
      end
      ciphertext = (ciphertext || "") + cipher.final
      mac        = hmac_generate(nonce, aad.to_s, ciphertext)

      ciphertext << mac
    end
  end

  def _decrypt(nonce, aad, ciphertext, tag)
    raise ArgumentError, 'ciphertext failed authentication step' unless
      hmac_verify(nonce, aad.to_s, ciphertext, tag)

    self.cipher(:decrypt) do |cipher|
      cipher.key = self.encryption_key
      cipher.iv  = nonce

      cipher.update(ciphertext) << cipher.final
    end
  end

  def hmac_generate(nonce, aad, ciphertext)
    OpenSSL::HMAC.digest self.class.digest_mode, self.signing_key,
      hmac_encode(self.class.cipher_mode) <<
      hmac_encode(ciphertext)             <<
      hmac_encode(nonce)                  <<
      hmac_encode(aad)
  end

  def hmac_verify(nonce, aad, ciphertext, hmac)
    self.class.signature_compare(
      hmac_generate(nonce, aad, ciphertext),
      hmac
    )
  end

  def hmac_encode(string)
    [ string.length ].pack('Q<') << string
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
aead-1.8.1 lib/aead/cipher/aes_hmac.rb