From 4be74741d5b130014dcb6d6387ce91e685637122 Mon Sep 17 00:00:00 2001 From: Didactic Drunk <1479616+didactic-drunk@users.noreply.github.com> Date: Mon, 5 Aug 2019 18:49:17 -0700 Subject: [PATCH] Use timing safe compare in Sodium::SecureBuffer. --- src/sodium/error.cr | 3 +++ src/sodium/lib_sodium.cr | 23 +++++++++++++++++++++++ src/sodium/secure_buffer.cr | 4 ++-- src/sodium/wipe.cr | 6 ------ 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/sodium/error.cr b/src/sodium/error.cr index 68c5cff..9cc7aff 100644 --- a/src/sodium/error.cr +++ b/src/sodium/error.cr @@ -7,5 +7,8 @@ module Sodium class DecryptionFailed < Error end + + class MemcmpFailed < Error + end end end diff --git a/src/sodium/lib_sodium.cr b/src/sodium/lib_sodium.cr index 23cb917..daf6a80 100644 --- a/src/sodium/lib_sodium.cr +++ b/src/sodium/lib_sodium.cr @@ -45,6 +45,7 @@ module Sodium fun crypto_generichash_blake2b_saltbytes : LibC::SizeT fun crypto_generichash_blake2b_personalbytes : LibC::SizeT + fun sodium_memcmp(Pointer(LibC::UChar), Pointer(LibC::UChar), LibC::SizeT) : LibC::Int fun sodium_memzero(Pointer(LibC::UChar), LibC::SizeT) : Nil fun sodium_malloc(LibC::SizeT) : Pointer(LibC::UChar) @@ -280,3 +281,25 @@ module Sodium raise "Assumptions in this library regarding nonce sizes may not be valid" end end + +module Sodium + def self.memcmp(a : Bytes, b : Bytes) : Bool + if a.bytesize != b.bytesize + false + elsif LibSodium.sodium_memcmp(a, b, a.bytesize) == 0 + true + else + false + end + end + + # Raises unless comparison succeeds. + def self.memcmp!(a, b) + raise Error::MemcmpFailed.new unless memcmp(a, b) + true + end + + def self.memzero(bytes : Bytes) + LibSodium.sodium_memzero bytes, bytes.bytesize + end +end diff --git a/src/sodium/secure_buffer.cr b/src/sodium/secure_buffer.cr index dbc1fa4..657fc49 100644 --- a/src/sodium/secure_buffer.cr +++ b/src/sodium/secure_buffer.cr @@ -82,11 +82,11 @@ module Sodium end def ==(other : self) - self.to_slice == other.to_slice + Sodium.memcmp self.to_slice, other.to_slice end def ==(other : Bytes) - self.to_slice == other + Sodium.memcmp self.to_slice, other end end end diff --git a/src/sodium/wipe.cr b/src/sodium/wipe.cr index 2985cc0..798a90b 100644 --- a/src/sodium/wipe.cr +++ b/src/sodium/wipe.cr @@ -1,9 +1,3 @@ -module Sodium - def self.memzero(bytes : Bytes) - LibSodium.sodium_memzero bytes, bytes.bytesize - end -end - module Sodium::Wipe annotation Var end