Class: OpenSSL::CMAC
- Inherits:
-
Object
- Object
- OpenSSL::CMAC
- Defined in:
- lib/openssl_cmac.rb
Constant Summary collapse
- CONST_ZERO =
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".force_encoding('ASCII-8BIT')
- CONST_RB =
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x87]
Class Method Summary collapse
Instance Method Summary collapse
- #generate(data) ⇒ Object
-
#initialize(key) ⇒ CMAC
constructor
key - base 128 bit AES key.
- #verify(data, cmac) ⇒ Object
Constructor Details
#initialize(key) ⇒ CMAC
key - base 128 bit AES key
15 16 17 18 |
# File 'lib/openssl_cmac.rb', line 15 def initialize(key) @key = key @k1, @k2 = CMAC.gen_subkeys(@key) end |
Class Method Details
.gen_subkeys(key) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/openssl_cmac.rb', line 46 def self.gen_subkeys(key) cipher = Cipher::AES.new(128, :ECB) cipher.encrypt cipher.key = key k1 = (cipher.update(CONST_ZERO)).unpack('C*') xor_flag = k1[0] >= 0x80 k2 = Array.new(16) k1.each_with_index {|e, i| lsb = i == 15 ? 0 : (k1[i+1] & 0x80) / 0x80 k1[i] = (k1[i] << 1) % 256 | lsb k1[i] ^= CONST_RB[i] if xor_flag lsb = i == 15 ? 0 : (k1[i+1] << 1 & 0x80) / 0x80 k2[i] = (k1[i] << 1) % 256 | lsb k2[i] ^= CONST_RB[i] if k1[0] >= 0x80 } [k1, k2] end |
Instance Method Details
#generate(data) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/openssl_cmac.rb', line 20 def generate(data) data8 = data.dup.force_encoding('ASCII-8BIT') xor_key = @k1 unless data8.size > 0 && 0 == data8.size % 16 xor_key = @k2 padding = "\x80" padding << "\x00" * (15 - data8.size % 16) data8 << padding end data8[-16, 16].unpack('C*').each_with_index do |e, i| data8[data8.size - 16 + i] = (e ^ xor_key[i]).chr end cipher = Cipher::AES.new(128, :CBC) cipher.encrypt cipher.key = @key cipher.update(data8)[-16, 16] end |
#verify(data, cmac) ⇒ Object
42 43 44 |
# File 'lib/openssl_cmac.rb', line 42 def verify(data, cmac) generate(data) == cmac end |