diff --git a/core/crypto/ecdh/ecdh.odin b/core/crypto/ecdh/ecdh.odin index f5106d152..d31a69aa8 100644 --- a/core/crypto/ecdh/ecdh.odin +++ b/core/crypto/ecdh/ecdh.odin @@ -106,6 +106,7 @@ Public_Key :: struct { // private_key_generate uses the system entropy source to generate a new // Private_Key. This will only fail if and only if (⟺) the system entropy source is // missing or broken. +@(require_results) private_key_generate :: proc(priv_key: ^Private_Key, curve: Curve) -> bool { private_key_clear(priv_key) @@ -143,6 +144,7 @@ private_key_generate :: proc(priv_key: ^Private_Key, curve: Curve) -> bool { // private_key_set_bytes decodes a byte-encoded private key, and returns // true if and only if (⟺) the operation was successful. +@(require_results) private_key_set_bytes :: proc(priv_key: ^Private_Key, curve: Curve, b: []byte) -> bool { private_key_clear(priv_key) @@ -281,6 +283,7 @@ private_key_bytes :: proc(priv_key: ^Private_Key, dst: []byte) { // private_key_equal returns true if and only if (⟺) the private keys are equal, // in constant time. +@(require_results) private_key_equal :: proc(p, q: ^Private_Key) -> bool { if p._curve != q._curve { return false @@ -311,6 +314,7 @@ private_key_clear :: proc "contextless" (priv_key: ^Private_Key) { // public_key_set_bytes decodes a byte-encoded public key, and returns // true if and only if (⟺) the operation was successful. +@(require_results) public_key_set_bytes :: proc(pub_key: ^Public_Key, curve: Curve, b: []byte) -> bool { public_key_clear(pub_key) @@ -411,6 +415,7 @@ public_key_bytes :: proc(pub_key: ^Public_Key, dst: []byte) { // public_key_equal returns true if and only if (⟺) the public keys are equal, // in constant time. +@(require_results) public_key_equal :: proc(p, q: ^Public_Key) -> bool { if p._curve != q._curve { return false @@ -479,11 +484,13 @@ ecdh :: proc(priv_key: ^Private_Key, pub_key: ^Public_Key, dst: []byte) -> bool } // curve returns the Curve used by a Private_Key or Public_Key instance. +@(require_results) curve :: proc(k: ^$T) -> Curve where(T == Private_Key || T == Public_Key) { return k._curve } // key_size returns the key size of a Private_Key or Public_Key in bytes. +@(require_results) key_size :: proc(k: ^$T) -> int where(T == Private_Key || T == Public_Key) { when T == Private_Key { return PRIVATE_KEY_SIZES[k._curve] @@ -494,6 +501,7 @@ key_size :: proc(k: ^$T) -> int where(T == Private_Key || T == Public_Key) { // shared_secret_size returns the shared secret size of a key exchange // in bytes. +@(require_results) shared_secret_size :: proc(k: ^$T) -> int where(T == Private_Key || T == Public_Key) { return SHARED_SECRET_SIZES[k._curve] } diff --git a/core/crypto/ecdsa/ecdsa.odin b/core/crypto/ecdsa/ecdsa.odin index 350bab3ec..8bb1748cf 100644 --- a/core/crypto/ecdsa/ecdsa.odin +++ b/core/crypto/ecdsa/ecdsa.odin @@ -81,6 +81,7 @@ Public_Key :: struct { // private_key_generate uses the system entropy source to generate a new // Private_Key. This will only fail if and only if (⟺) the system entropy source is // missing or broken. +@(require_results) private_key_generate :: proc(priv_key: ^Private_Key, curve: Curve) -> bool { private_key_clear(priv_key) @@ -112,6 +113,7 @@ private_key_generate :: proc(priv_key: ^Private_Key, curve: Curve) -> bool { // private_key_set_bytes decodes a byte-encoded private key, and returns // true if and only if (⟺) the operation was successful. +@(require_results) private_key_set_bytes :: proc(priv_key: ^Private_Key, curve: Curve, b: []byte) -> bool { private_key_clear(priv_key) @@ -222,6 +224,7 @@ private_key_set :: proc(priv_key, src: ^Private_Key) { // private_key_equal returns true if and only if (⟺) the private keys are equal, // in constant time. +@(require_results) private_key_equal :: proc(p, q: ^Private_Key) -> bool { if p._curve != q._curve { return false @@ -246,6 +249,7 @@ private_key_clear :: proc "contextless" (priv_key: ^Private_Key) { // public_key_set_bytes decodes a byte-encoded public key, and returns // true if and only if (⟺) the operation was successful. +@(require_results) public_key_set_bytes :: proc(pub_key: ^Public_Key, curve: Curve, b: []byte) -> bool { public_key_clear(pub_key) @@ -334,6 +338,7 @@ public_key_bytes :: proc(pub_key: ^Public_Key, dst: []byte) { // public_key_equal returns true if and only if (⟺) the public keys are equal, // in constant time. +@(require_results) public_key_equal :: proc(p, q: ^Public_Key) -> bool { if p._curve != q._curve { return false diff --git a/core/crypto/noise/protocol.odin b/core/crypto/noise/protocol.odin index 883376a42..29482bd36 100644 --- a/core/crypto/noise/protocol.odin +++ b/core/crypto/noise/protocol.odin @@ -58,7 +58,9 @@ generate_keypair :: proc(protocol: ^Protocol, private_key: ^ecdh.Private_Key) { case: panic("crypto/noise: unsupported DH curve in protocol") } - ecdh.private_key_generate(private_key, protocol.dh) + if !ecdh.private_key_generate(private_key, protocol.dh) { + panic("crypto/noise: entropy source unavailable") + } } // Performs a Diffie-Hellman calculation between the private key in key_pair @@ -837,7 +839,9 @@ handshakestate_read_message :: proc(self: ^Handshake_State, message, dst: []byte panic("crypto/noise: re was not empty when processing token 'e' during ReadMessage") } - ecdh.public_key_set_bytes(&self.re, protocol.dh, re) + if !ecdh.public_key_set_bytes(&self.re, protocol.dh, re) { + return nil, .Invalid_Handshake_Message + } symmetricstate_mix_hash(&self.symmetric_state, re) if self.message_pattern.is_psk { symmetricstate_mix_key(&self.symmetric_state, re) @@ -864,7 +868,10 @@ handshakestate_read_message :: proc(self: ^Handshake_State, message, dst: []byte panic("crypto/noise: rs was not empty when processing token 's' during ReadMessage") } - ecdh.public_key_set_bytes(&self.rs, protocol.dh, rs) + if !ecdh.public_key_set_bytes(&self.rs, protocol.dh, rs) { + self.status = .Handshake_Failed + return nil, .Invalid_Handshake_Message + } msg = msg[rs_len:] case .ee: