Class: Rex::Proto::Kerberos::Crypto::BlockCipherBase
- Inherits:
-
Object
- Object
- Rex::Proto::Kerberos::Crypto::BlockCipherBase
- Defined in:
- lib/rex/proto/kerberos/crypto/block_cipher_base.rb
Direct Known Subclasses
Instance Method Summary collapse
-
#add_ones_complement(arr1, arr2) ⇒ Object
Add equal-length strings together with end-around carry.
- #calculate_encrypted_length(plaintext_len) ⇒ Object
-
#checksum(key, msg_type, data) ⇒ String
Use this class’s encryption routines to create a checksum of the data based on the key and message type.
-
#decrypt(ciphertext_and_mac, key, msg_type) ⇒ String
(also: #decrypt_asn1)
Decrypts the cipher.
-
#encrypt(plaintext, key, msg_type, confounder: nil) ⇒ String
Encrypts the cipher.
- #gss_unwrap(ciphertext, key, expected_sequence_number, is_initiator, opts = {}) ⇒ Object
- #gss_wrap(plaintext, key, sequence_number, is_initiator, opts = {}) ⇒ Object
-
#rotate_right(ba, nbits) ⇒ Object
Rotate the bytes in ba to the right by nbits bits.
-
#string_to_key(password, salt, params = nil) ⇒ String
Derive an encryption key based on a password and salt for the given cipher type.
Instance Method Details
#add_ones_complement(arr1, arr2) ⇒ Object
Add equal-length strings together with end-around carry.
150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/rex/proto/kerberos/crypto/block_cipher_base.rb', line 150 def add_ones_complement(arr1, arr2) n = arr1.length # Add all pairs of numbers v = arr1.zip(arr2).map { |a,b| a+b} while v.any? { |x| x > 0xff } v = v.length.times.map {|i| (v[i-n+1]>>8) + (v[i]&0xff)} end v end |
#calculate_encrypted_length(plaintext_len) ⇒ Object
101 102 103 |
# File 'lib/rex/proto/kerberos/crypto/block_cipher_base.rb', line 101 def calculate_encrypted_length(plaintext_len) raise NotImplementedError end |
#checksum(key, msg_type, data) ⇒ String
Use this class’s encryption routines to create a checksum of the data based on the key and message type
35 36 37 38 39 40 |
# File 'lib/rex/proto/kerberos/crypto/block_cipher_base.rb', line 35 def checksum(key, msg_type, data) kc = derive(key, [msg_type, 0x99].pack('NC')) hmac = OpenSSL::HMAC.digest(self.class::HASH_FUNCTION, kc, data) hmac[0, self.class::MAC_SIZE] end |
#decrypt(ciphertext_and_mac, key, msg_type) ⇒ String Also known as: decrypt_asn1
Decrypts the cipher
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/rex/proto/kerberos/crypto/block_cipher_base.rb', line 49 def decrypt(ciphertext_and_mac, key, msg_type) ki = derive(key, [msg_type, 0x55].pack('NC')) ke = derive(key, [msg_type, 0xAA].pack('NC')) raise Rex::Proto::Kerberos::Model::Error::KerberosError, 'Ciphertext too short' if ciphertext_and_mac.length < (self.class::BLOCK_SIZE + self.class::MAC_SIZE) ciphertext = ciphertext_and_mac.slice(0..-(self.class::MAC_SIZE+1)) mac = ciphertext_and_mac[-self.class::MAC_SIZE, self.class::MAC_SIZE] plaintext = decrypt_basic(ciphertext, ke) hmac = OpenSSL::HMAC.digest(self.class::HASH_FUNCTION, ki, plaintext) hmac_subset = hmac[0, self.class::MAC_SIZE] if mac != hmac_subset raise Rex::Proto::Kerberos::Model::Error::KerberosError, 'HMAC integrity error' end # Discard the confounder. plaintext[self.class::BLOCK_SIZE, plaintext.length] end |
#encrypt(plaintext, key, msg_type, confounder: nil) ⇒ String
Encrypts the cipher
83 84 85 86 87 88 89 90 91 |
# File 'lib/rex/proto/kerberos/crypto/block_cipher_base.rb', line 83 def encrypt(plaintext, key, msg_type, confounder: nil) ki = derive(key, [msg_type, 0x55].pack('NC')) ke = derive(key, [msg_type, 0xAA].pack('NC')) confounder = Rex::Text::rand_text(self.class::BLOCK_SIZE) if confounder == nil plaintext = confounder + pad_with_zeroes(plaintext, self.class::PADDING_SIZE) hmac = OpenSSL::HMAC.digest(self.class::HASH_FUNCTION, ki, plaintext) encrypt_basic(plaintext, ke) + hmac[0,self.class::MAC_SIZE] end |
#gss_unwrap(ciphertext, key, expected_sequence_number, is_initiator, opts = {}) ⇒ Object
97 98 99 |
# File 'lib/rex/proto/kerberos/crypto/block_cipher_base.rb', line 97 def gss_unwrap(ciphertext, key, expected_sequence_number, is_initiator, opts={}) raise NotImplementedError end |
#gss_wrap(plaintext, key, sequence_number, is_initiator, opts = {}) ⇒ Object
93 94 95 |
# File 'lib/rex/proto/kerberos/crypto/block_cipher_base.rb', line 93 def gss_wrap(plaintext, key, sequence_number, is_initiator, opts={}) raise NotImplementedError end |
#rotate_right(ba, nbits) ⇒ Object
Rotate the bytes in ba to the right by nbits bits.
142 143 144 145 146 147 |
# File 'lib/rex/proto/kerberos/crypto/block_cipher_base.rb', line 142 def rotate_right(ba, nbits) nbytes, remain = (nbits / 8) % ba.length, nbits % 8 ba.length.times.map do |i| (ba[i-nbytes] >> remain) | ((ba[i-nbytes-1] << (8-remain)) & 0xff) end end |
#string_to_key(password, salt, params = nil) ⇒ String
Derive an encryption key based on a password and salt for the given cipher type
25 26 27 |
# File 'lib/rex/proto/kerberos/crypto/block_cipher_base.rb', line 25 def string_to_key(password, salt, params=nil) raise NotImplementedError end |