lib/lockbox.rb in lockbox-0.2.0 vs lib/lockbox.rb in lockbox-0.2.1

- old
+ new

@@ -20,10 +20,11 @@ end class Lockbox class Error < StandardError; end class DecryptionError < Error; end + class PaddingError < Error; end class << self attr_accessor :default_options attr_writer :master_key end @@ -135,9 +136,58 @@ key end def self.to_hex(str) str.unpack("H*").first + end + + PAD_FIRST_BYTE = "\x80".b + PAD_ZERO_BYTE = "\x00".b + + # ISO/IEC 7816-4 + # same as Libsodium + # https://libsodium.gitbook.io/doc/padding + # apply prior to encryption + # note: current implementation does not + # try to minimize side channels + def self.pad(str, size: 16) + raise ArgumentError, "Invalid size" if size < 1 + + str = str.dup.force_encoding(Encoding::BINARY) + + pad_length = size - 1 + pad_length -= str.bytesize % size + + str << PAD_FIRST_BYTE + pad_length.times do + str << PAD_ZERO_BYTE + end + + str + end + + # note: current implementation does not + # try to minimize side channels + def self.unpad(str, size: 16) + raise ArgumentError, "Invalid size" if size < 1 + + if str.encoding != Encoding::BINARY + str = str.dup.force_encoding(Encoding::BINARY) + end + + i = 1 + while i <= size + case str[-i] + when PAD_ZERO_BYTE + i += 1 + when PAD_FIRST_BYTE + return str[0..-(i + 1)] + else + break + end + end + + raise Lockbox::PaddingError, "Invalid padding" end private def check_string(str, name)