module Net::SSH::Transport::CTR
def self.extended(orig)
def self.extended(orig) orig.instance_eval { @remaining = "" @counter = nil @counter_len = orig.block_size orig.encrypt orig.padding = 0 } class <<orig alias :_update :update private :_update undef :update def iv @counter end def iv_len block_size end def iv=(iv_s) @counter = iv_s if @counter.nil? end def encrypt # DO NOTHING (always set to "encrypt") end def decrypt # DO NOTHING (always set to "encrypt") end def padding=(pad) # DO NOTHING (always 0) end def reset @remaining = "" end def update(data) @remaining += data encrypted = "" while @remaining.bytesize >= block_size encrypted += xor!(@remaining.slice!(0, block_size), _update(@counter)) increment_counter! end encrypted end def final unless @remaining.empty? s = xor!(@remaining, _update(@counter)) else s = "" end @remaining = "" s end private def xor!(s1, s2) s = [] s1.unpack('Q*').zip(s2.unpack('Q*')) {|a,b| s.push(a^b) } s.pack('Q*') end def increment_counter! c = @counter_len while ((c -= 1) > 0) if @counter.setbyte(c, (@counter.getbyte(c) + 1) & 0xff) != 0 break end end end end end
def decrypt
def decrypt # DO NOTHING (always set to "encrypt") end
def encrypt
def encrypt # DO NOTHING (always set to "encrypt") end
def final
def final unless @remaining.empty? s = xor!(@remaining, _update(@counter)) else s = "" end @remaining = "" s end
def increment_counter!
def increment_counter! c = @counter_len while ((c -= 1) > 0) if @counter.setbyte(c, (@counter.getbyte(c) + 1) & 0xff) != 0 break end end end
def iv
def iv @counter end
def iv=(iv_s)
def iv=(iv_s) @counter = iv_s if @counter.nil? end
def iv_len
def iv_len block_size end
def padding=(pad)
def padding=(pad) # DO NOTHING (always 0) end
def reset
def reset @remaining = "" end
def update(data)
def update(data) @remaining += data encrypted = "" while @remaining.bytesize >= block_size encrypted += xor!(@remaining.slice!(0, block_size), _update(@counter)) increment_counter! end encrypted end
def xor!(s1, s2)
def xor!(s1, s2) s = [] s1.unpack('Q*').zip(s2.unpack('Q*')) {|a,b| s.push(a^b) } s.pack('Q*') end