Module Smartcard::Gp::Des
In: lib/smartcard/gp/des.rb

DES and 3DES encryption and MAC logic for GlobalPlatform secure channels.

Methods

Public Class methods

Perform DES or 3DES encryption.

Args:

  key:: the encryption key to be used (8-byte or 16-byte)
  data:: the data to be encrypted or decrypted
  iv:: initialization vector
  decrypt:: if +false+ performs encryption, otherwise performs decryption

Returns the encrypted / decrypted data.

[Source]

    # File lib/smartcard/gp/des.rb, line 34
34:   def self.crypt(key, data, iv = nil, decrypt = false)
35:     cipher_name = key.length == 8 ? 'DES-CBC' : 'DES-EDE-CBC'
36:     cipher = OpenSSL::Cipher::Cipher.new cipher_name
37:     decrypt ? cipher.decrypt : cipher.encrypt
38:     cipher.key = key
39:     cipher.iv = iv || ("\x00" * 8)
40:     cipher.padding = 0
41:     crypted = cipher.update data
42:     crypted += cipher.final
43:     crypted
44:   end

[Source]

    # File lib/smartcard/gp/des.rb, line 58
58:   def self.mac_3des(key, data)
59:     # Output transformation: add 80, then 00 until it's block-sized.
60:     data = data + "\x80"
61:     data += "\x00" * (8 - data.length % 8) unless data.length % 8 == 0
62:     
63:     # The MAC is the last block from 3DES-encrypting the data.
64:     crypt(key, data)[-8, 8]
65:   end

Computes a MAC using DES mixed with 3DES.

[Source]

    # File lib/smartcard/gp/des.rb, line 47
47:   def self.mac_retail(key, data, iv = nil)
48:     # Output transformation: add 80, then 00 until it's block-sized.
49:     data = data + "\x80"
50:     data += "\x00" * (8 - data.length % 8) unless data.length % 8 == 0
51: 
52:     # DES-encrypt everything except for the last block.
53:     iv = crypt(key[0, 8], data[0, data.length - 8], iv)[-8, 8]
54:     # Take the chained block and supply it to a 3DES-encryption. 
55:     crypt(key, data[-8, 8], iv)
56:   end

Generates random bytes for session nonces.

Args:

  bytes:: how many bytes are desired

Returns a string of random bytes.

[Source]

    # File lib/smartcard/gp/des.rb, line 21
21:   def self.random_bytes(bytes)
22:     OpenSSL::Random.random_bytes bytes
23:   end

[Validate]