From f6737a766f80399385a6239ca595567452b0a5bd Mon Sep 17 00:00:00 2001 From: Didactic Drunk <1479616+didactic-drunk@users.noreply.github.com> Date: Sun, 13 Jun 2021 12:52:05 -0700 Subject: [PATCH] Crypto::Secret Timing safe == --- spec/not_spec.cr | 12 ++++++++++-- src/crypto-secret/secret.cr | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/spec/not_spec.cr b/spec/not_spec.cr index bc6cc8b..5a9413b 100644 --- a/spec/not_spec.cr +++ b/spec/not_spec.cr @@ -4,7 +4,15 @@ require "../src/crypto-secret/not" describe Crypto::Secret::Not do it "works" do ksize = 32 - secret = Crypto::Secret::Not.new ksize - secret.to_slice.should eq Bytes.new ksize + key = Bytes.new ksize + key[1] = 1_u8 + + secret1 = Crypto::Secret::Not.new key.dup + secret1.to_slice.should eq key + + secret2 = Crypto::Secret::Not.new key.dup + + (secret1 == secret2).should be_true + (secret1 == secret2.to_slice).should be_true end end diff --git a/src/crypto-secret/secret.cr b/src/crypto-secret/secret.cr index b1335f6..217f14f 100644 --- a/src/crypto-secret/secret.cr +++ b/src/crypto-secret/secret.cr @@ -1,3 +1,5 @@ +require "crypto/subtle" + # Interface to hold sensitive information (often cryptographic keys) # # **Only for direct use by cryptographic library authors** @@ -41,4 +43,20 @@ module Crypto::Secret def finalize wipe end + + # Timing safe memory compare + def ==(other : Secret): Bool + readonly do + other.readonly do + Crypto::Subtle.constant_time_compare to_slice, other.to_slice + end + end + end + + # Timing safe memory compare + def ==(other : Bytes) : Bool + readonly do + Crypto::Subtle.constant_time_compare to_slice, other.to_slice + end + end end