Class: Mifare::Key
- Inherits:
-
Object
- Object
- Mifare::Key
- Defined in:
- lib/mifare/key.rb
Instance Attribute Summary collapse
-
#cipher_suite ⇒ Object
readonly
Returns the value of attribute cipher_suite.
-
#key_size ⇒ Object
readonly
Returns the value of attribute key_size.
-
#type ⇒ Object
readonly
Returns the value of attribute type.
-
#version ⇒ Object
readonly
Returns the value of attribute version.
Instance Method Summary collapse
- #calculate_cmac(data) ⇒ Object
- #clear_iv ⇒ Object
- #decrypt(data, cbc_mode = :receive) ⇒ Object
- #encrypt(data, cbc_mode = :send) ⇒ Object
- #generate_cmac_subkeys ⇒ Object
-
#initialize(type, key, version = 0x00) ⇒ Key
constructor
A new instance of Key.
- #key ⇒ Object
Constructor Details
#initialize(type, key, version = 0x00) ⇒ Key
Returns a new instance of Key.
8 9 10 11 12 13 |
# File 'lib/mifare/key.rb', line 8 def initialize(type, key, version = 0x00) @type = type set_key_data(type, key, version) clear_iv init_cipher end |
Instance Attribute Details
#cipher_suite ⇒ Object (readonly)
Returns the value of attribute cipher_suite.
4 5 6 |
# File 'lib/mifare/key.rb', line 4 def cipher_suite @cipher_suite end |
#key_size ⇒ Object (readonly)
Returns the value of attribute key_size.
5 6 7 |
# File 'lib/mifare/key.rb', line 5 def key_size @key_size end |
#type ⇒ Object (readonly)
Returns the value of attribute type.
3 4 5 |
# File 'lib/mifare/key.rb', line 3 def type @type end |
#version ⇒ Object (readonly)
Returns the value of attribute version.
6 7 8 |
# File 'lib/mifare/key.rb', line 6 def version @version end |
Instance Method Details
#calculate_cmac(data) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/mifare/key.rb', line 54 def calculate_cmac(data) if @cmac_subkey1.nil? || @cmac_subkey2.nil? raise 'Generate subkeys before calculating CMAC' end # Separate from input object data = data.dup if data.size == 0 || data.size % @block_size != 0 # padding with byte: 0x80, 0x00, 0x00..... data << 0x80 until data.size % @block_size == 0 data << 0x00 end key = @cmac_subkey2 else key = @cmac_subkey1 end # XOR last data block with selected CMAC subkey data = data[0...-@block_size] + data[-@block_size..-1].zip(key).map{|x, y| x ^ y } encrypt(data) @cipher_iv.bytes end |
#clear_iv ⇒ Object
36 37 38 |
# File 'lib/mifare/key.rb', line 36 def clear_iv @cipher_iv = "\x00" * @block_size end |
#decrypt(data, cbc_mode = :receive) ⇒ Object
30 31 32 33 34 |
# File 'lib/mifare/key.rb', line 30 def decrypt(data, cbc_mode = :receive) @cipher.decrypt cbc_crypt(data, cbc_mode) end |
#encrypt(data, cbc_mode = :send) ⇒ Object
19 20 21 22 23 24 25 26 27 28 |
# File 'lib/mifare/key.rb', line 19 def encrypt(data, cbc_mode = :send) @cipher.encrypt # Add padding if not a complete block until data.size % @block_size == 0 data << 0x00 end cbc_crypt(data, cbc_mode) end |
#generate_cmac_subkeys ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/mifare/key.rb', line 40 def generate_cmac_subkeys r = (@block_size == 8) ? 0x1B : 0x87 data = Array.new(@block_size, 0) clear_iv data = encrypt(data, :receive) @cmac_subkey1 = bit_shift_left(data) @cmac_subkey1[-1] ^= r if data[0] & 0x80 != 0 @cmac_subkey2 = bit_shift_left(@cmac_subkey1) @cmac_subkey2[-1] ^= r if @cmac_subkey1[0] & 0x80 != 0 end |
#key ⇒ Object
15 16 17 |
# File 'lib/mifare/key.rb', line 15 def key @key.bytes end |