Module: AESKeyWrap
- Defined in:
- lib/aes_key_wrap.rb,
lib/aes_key_wrap/version.rb
Overview
A Ruby implementation of AES Key Wrap, a.k.a RFC 3394, a.k.a NIST Key Wrapping
Constant Summary collapse
- DEFAULT_IV =
0xA6A6A6A6A6A6A6A6
- IV_SIZE =
bytes
8
- UnwrapFailedError =
Class.new(StandardError)
- VERSION =
'1.1.0'
Class Method Summary collapse
-
.unwrap(wrapped_key, kek, expected_iv = DEFAULT_IV) ⇒ String
Unwraps an encrypted key using a key-encrypting key (KEK).
-
.unwrap!(*args) ⇒ Object
Exception-throwing version of #unwrap.
-
.wrap(unwrapped_key, kek, iv = DEFAULT_IV) ⇒ String
Wraps a key using a key-encrypting key (KEK).
Class Method Details
.unwrap(wrapped_key, kek, expected_iv = DEFAULT_IV) ⇒ String
Unwraps an encrypted key using a key-encrypting key (KEK)
This is an implementation of the “index based” algorithm specified in section 2.2.2 of RFC 3394: www.ietf.org/rfc/rfc3394.txt
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/aes_key_wrap.rb', line 77 def unwrap(wrapped_key, kek, expected_iv=DEFAULT_IV) # 1) Initialize variables. # # C: buffer (from wrapped_key) # A: buffer[0] # R: buffer # n: block_count # K: kek # AES-1: aes(:decrypt, _, _) buffer = wrapped_key.unpack('Q>*') block_count = buffer.size - 1 # 2) Calculate intermediate values. # t: round 5.downto(0) do |j| block_count.downto(1) do |i| round = block_count*j + i # In buffer[0] = buffer[0] ^ round # XorT data = [buffer[0], buffer[i]].pack('Q>2') buffer[0], buffer[i] = aes(:decrypt, kek, data).unpack('Q>2') # Dec end end # 3) Output the results. if buffer[0] == coerce_uint64(expected_iv) buffer.drop(1).pack('Q>*') else nil end end |
.unwrap!(*args) ⇒ Object
Exception-throwing version of #unwrap
116 117 118 |
# File 'lib/aes_key_wrap.rb', line 116 def unwrap!(*args) unwrap(*args) || raise(UnwrapFailedError, 'Unwrapped IV does not match') end |
.wrap(unwrapped_key, kek, iv = DEFAULT_IV) ⇒ String
Wraps a key using a key-encrypting key (KEK)
This is an implementation of the “index based” algorithm specified in section 2.2.1 of RFC 3394: www.ietf.org/rfc/rfc3394.txt
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/aes_key_wrap.rb', line 28 def wrap(unwrapped_key, kek, iv=DEFAULT_IV) # 1) Initialize variables. # # P: buffer (from unwrapped_key) # A: buffer[0] # R: buffer # K: kek # n: block_count # AES: aes(:encrypt, _, _) # IV: iv buffer = [coerce_uint64(iv)] + unwrapped_key.unpack('Q>*') block_count = buffer.size - 1 # 2) Calculate intermediate values. # t: round 0.upto(5) do |j| 1.upto(block_count) do |i| round = block_count*j + i # In data = [buffer[0], buffer[i]].pack('Q>2') buffer[0], buffer[i] = aes(:encrypt, kek, data).unpack('Q>2') # Enc buffer[0] = buffer[0] ^ round # XorT end end # 3) Output the results. buffer.pack('Q>*') end |