mirror of
https://github.com/odin-lang/Odin.git
synced 2026-05-26 13:48:23 +00:00
core/crypto/noise: Add support for deferred patterns
This commit is contained in:
@@ -459,3 +459,129 @@ cipherstates_cs :: proc(self: ^Cipher_States, seal_key: bool) -> ^Cipher_State {
|
||||
}
|
||||
unreachable()
|
||||
}
|
||||
|
||||
// split_protocol_string splits a protocol string into individual components.
|
||||
@(require_results)
|
||||
split_protocol_string :: proc(protocol_name: string) -> (Handshake_Pattern, ecdh.Curve, aead.Algorithm, hash.Algorithm, Status) {
|
||||
str := protocol_name
|
||||
|
||||
if len(str) > 255 {
|
||||
return .Invalid, .Invalid, .Invalid, .Invalid, .Invalid_Protocol_String
|
||||
}
|
||||
|
||||
s, ok := strings.split_by_byte_iterator(&str, '_')
|
||||
if !ok || s != "Noise" {
|
||||
return .Invalid, .Invalid, .Invalid, .Invalid, .Invalid_Protocol_String
|
||||
}
|
||||
|
||||
if s, ok = strings.split_by_byte_iterator(&str, '_'); !ok {
|
||||
return .Invalid, .Invalid, .Invalid, .Invalid, .Invalid_Protocol_String
|
||||
}
|
||||
|
||||
pattern: Handshake_Pattern
|
||||
switch s {
|
||||
case "N" : pattern = .N
|
||||
case "K" : pattern = .K
|
||||
case "X" : pattern = .X
|
||||
case "XX": pattern = .XX
|
||||
case "NK": pattern = .NK
|
||||
case "NN": pattern = .NN
|
||||
case "KN": pattern = .KN
|
||||
case "KK": pattern = .KK
|
||||
case "NX": pattern = .NX
|
||||
case "KX": pattern = .KX
|
||||
case "XN": pattern = .XN
|
||||
case "IN": pattern = .IN
|
||||
case "XK": pattern = .XK
|
||||
case "IK": pattern = .IK
|
||||
case "IX": pattern = .IX
|
||||
case "NK1": pattern = .NK1
|
||||
case "NX1": pattern = .NX1
|
||||
case "X1N": pattern = .X1N
|
||||
case "X1K": pattern = .X1K
|
||||
case "XK1": pattern = .XK1
|
||||
case "X1K1": pattern = .X1K1
|
||||
case "X1X": pattern = .X1X
|
||||
case "XX1": pattern = .XX1
|
||||
case "X1X1": pattern = .X1X1
|
||||
case "K1N": pattern = .K1N
|
||||
case "K1K": pattern = .K1K
|
||||
case "KK1": pattern = .KK1
|
||||
case "K1K1": pattern = .K1K1
|
||||
case "K1X": pattern = .K1X
|
||||
case "KX1": pattern = .KX1
|
||||
case "K1X1": pattern = .K1X1
|
||||
case "I1N": pattern = .I1N
|
||||
case "I1K": pattern = .I1K
|
||||
case "IK1": pattern = .IK1
|
||||
case "I1K1": pattern = .I1K1
|
||||
case "I1X": pattern = .I1X
|
||||
case "IX1": pattern = .IX1
|
||||
case "I1X1": pattern = .I1X1
|
||||
case "Npsk0": pattern = .Npsk0
|
||||
case "Kpsk0": pattern = .Kpsk0
|
||||
case "Xpsk1": pattern = .Xpsk1
|
||||
case "NNpsk0": pattern = .NNpsk0
|
||||
case "NNpsk2": pattern = .NNpsk2
|
||||
case "NKpsk0": pattern = .NKpsk0
|
||||
case "NKpsk2": pattern = .NKpsk2
|
||||
case "NXpsk2": pattern = .NXpsk2
|
||||
case "XNpsk3": pattern = .XNpsk3
|
||||
case "XKpsk3": pattern = .XKpsk3
|
||||
case "XXpsk3": pattern = .XXpsk3
|
||||
case "KNpsk0": pattern = .KNpsk0
|
||||
case "KNpsk2": pattern = .KNpsk2
|
||||
case "KKpsk0": pattern = .KKpsk0
|
||||
case "KKpsk2": pattern = .KKpsk2
|
||||
case "KXpsk2": pattern = .KXpsk2
|
||||
case "INpsk1": pattern = .INpsk1
|
||||
case "INpsk2": pattern = .INpsk2
|
||||
case "IKpsk1": pattern = .IKpsk1
|
||||
case "IKpsk2": pattern = .IKpsk2
|
||||
case "IXpsk2": pattern = .IXpsk2
|
||||
case: pattern = .Invalid
|
||||
}
|
||||
|
||||
if s, ok = strings.split_by_byte_iterator(&str, '_'); !ok {
|
||||
return .Invalid, .Invalid, .Invalid, .Invalid, .Invalid_Protocol_String
|
||||
}
|
||||
dh: ecdh.Curve
|
||||
switch s {
|
||||
case "25519": dh = .X25519
|
||||
case "448": dh = .X448
|
||||
case: dh = .Invalid
|
||||
}
|
||||
|
||||
if s, ok = strings.split_by_byte_iterator(&str, '_'); !ok {
|
||||
return .Invalid, .Invalid, .Invalid, .Invalid, .Invalid_Protocol_String
|
||||
}
|
||||
cipher: aead.Algorithm
|
||||
switch s {
|
||||
case "AESGCM": cipher = .AES_GCM_256
|
||||
case "ChaChaPoly": cipher = .CHACHA20POLY1305
|
||||
case: cipher = .Invalid
|
||||
}
|
||||
|
||||
if s, ok = strings.split_by_byte_iterator(&str, '_'); !ok {
|
||||
return .Invalid, .Invalid, .Invalid, .Invalid, .Invalid_Protocol_String
|
||||
}
|
||||
hash: hash.Algorithm
|
||||
switch s {
|
||||
case "SHA512": hash = .SHA512
|
||||
case "SHA256": hash = .SHA256
|
||||
case "BLAKE2s": hash = .BLAKE2S
|
||||
case "BLAKE2b": hash = .BLAKE2B
|
||||
case: hash = .Invalid
|
||||
}
|
||||
|
||||
status: Status
|
||||
|
||||
if len(str) != 0 {
|
||||
status = .Invalid_Protocol_String
|
||||
}
|
||||
if pattern == .Invalid || dh == .Invalid || cipher == .Invalid || hash == .Invalid {
|
||||
status = .Invalid_Protocol_String
|
||||
}
|
||||
|
||||
return pattern, dh, cipher, hash, status
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
An implementation of the Noise Protocol Framework (Revision 34).
|
||||
|
||||
The `fallback` modifier and deferred/multi-PSK patterns are not supported
|
||||
The `fallback` modifier and multi-PSK patterns are not supported
|
||||
for the sake of simplicity.
|
||||
|
||||
See:
|
||||
|
||||
@@ -51,6 +51,31 @@ Handshake_Pattern :: enum {
|
||||
IK,
|
||||
IX,
|
||||
|
||||
// Deferred patterns
|
||||
NK1,
|
||||
NX1,
|
||||
X1N,
|
||||
X1K,
|
||||
XK1,
|
||||
X1K1,
|
||||
X1X,
|
||||
XX1,
|
||||
X1X1,
|
||||
K1N,
|
||||
K1K,
|
||||
KK1,
|
||||
K1K1,
|
||||
K1X,
|
||||
KX1,
|
||||
K1X1,
|
||||
I1N,
|
||||
I1K,
|
||||
IK1,
|
||||
I1K1,
|
||||
I1X,
|
||||
IX1,
|
||||
I1X1,
|
||||
|
||||
// Recommended PSK patterns
|
||||
Npsk0,
|
||||
Kpsk0,
|
||||
@@ -132,6 +157,7 @@ HANDSHAKE_PATTERNS := [Handshake_Pattern]^Message_Pattern {
|
||||
.N = &PATTERN_N,
|
||||
.K = &PATTERN_K,
|
||||
.X = &PATTERN_X,
|
||||
|
||||
.XX = &PATTERN_XX,
|
||||
.NK = &PATTERN_NK,
|
||||
.NN = &PATTERN_NN,
|
||||
@@ -144,6 +170,31 @@ HANDSHAKE_PATTERNS := [Handshake_Pattern]^Message_Pattern {
|
||||
.XK = &PATTERN_XK,
|
||||
.IK = &PATTERN_IK,
|
||||
.IX = &PATTERN_IX,
|
||||
|
||||
.NK1 = &PATTERN_NK1,
|
||||
.NX1 = &PATTERN_NX1,
|
||||
.X1N = &PATTERN_X1N,
|
||||
.X1K = &PATTERN_X1K,
|
||||
.XK1 = &PATTERN_XK1,
|
||||
.X1K1 = &PATTERN_X1K1,
|
||||
.X1X = &PATTERN_X1X,
|
||||
.XX1 = &PATTERN_XX1,
|
||||
.X1X1 = &PATTERN_X1X1,
|
||||
.K1N = &PATTERN_K1N,
|
||||
.K1K = & PATTERN_K1K,
|
||||
.KK1 = &PATTERN_KK1,
|
||||
.K1K1 = &PATTERN_K1K1,
|
||||
.K1X = &PATTERN_K1X,
|
||||
.KX1 = &PATTERN_KX1,
|
||||
.K1X1 = &PATTERN_K1X1,
|
||||
.I1N = &PATTERN_I1N,
|
||||
.I1K = &PATTERN_I1K,
|
||||
.IK1 = &PATTERN_IK1,
|
||||
.I1K1 = &PATTERN_I1K1,
|
||||
.I1X = &PATTERN_I1X,
|
||||
.IX1 = &PATTERN_IX1,
|
||||
.I1X1 = &PATTERN_I1X1,
|
||||
|
||||
.Npsk0 = &PATTERN_Npsk0,
|
||||
.Kpsk0 = &PATTERN_Kpsk0,
|
||||
.Xpsk1 = &PATTERN_Xpsk1,
|
||||
@@ -378,6 +429,367 @@ PATTERN_IX : Message_Pattern = {
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
// ------------- DEFERRED PATTERNS --------------------------------------------------------
|
||||
|
||||
// NK1:
|
||||
// <- s
|
||||
// ...
|
||||
// -> e
|
||||
// <- e, ee, es
|
||||
@(private,rodata)
|
||||
PATTERN_NK1 : Message_Pattern = {
|
||||
pre_messages = {.res_s},
|
||||
messages = {
|
||||
{.e},
|
||||
{.e, .ee, .es},
|
||||
},
|
||||
}
|
||||
|
||||
// NX1:
|
||||
// -> e
|
||||
// <- e, ee, s
|
||||
// -> es
|
||||
@(private,rodata)
|
||||
PATTERN_NX1 : Message_Pattern = {
|
||||
pre_messages = nil,
|
||||
messages = {
|
||||
{.e},
|
||||
{.e, .ee, .s},
|
||||
{.es},
|
||||
},
|
||||
}
|
||||
|
||||
// X1N:
|
||||
// -> e
|
||||
// <- e, ee
|
||||
// -> s
|
||||
// <- se
|
||||
@(private,rodata)
|
||||
PATTERN_X1N : Message_Pattern = {
|
||||
pre_messages = nil,
|
||||
messages = {
|
||||
{.e},
|
||||
{.e, .ee},
|
||||
{.s},
|
||||
{.se},
|
||||
},
|
||||
}
|
||||
|
||||
// X1K:
|
||||
// <- s
|
||||
// ...
|
||||
// -> e, es
|
||||
// <- e, ee
|
||||
// -> s
|
||||
// <- se
|
||||
@(private,rodata)
|
||||
PATTERN_X1K : Message_Pattern = {
|
||||
pre_messages = {.res_s},
|
||||
messages = {
|
||||
{.e, .es},
|
||||
{.e, .ee},
|
||||
{.s},
|
||||
{.se},
|
||||
},
|
||||
}
|
||||
|
||||
// XK1:
|
||||
// <- s
|
||||
// ...
|
||||
// -> e
|
||||
// <- e, ee, es
|
||||
// -> s, se
|
||||
@(private,rodata)
|
||||
PATTERN_XK1 : Message_Pattern = {
|
||||
pre_messages = {.res_s},
|
||||
messages = {
|
||||
{.e},
|
||||
{.e, .ee, .es},
|
||||
{.s, .se},
|
||||
},
|
||||
}
|
||||
|
||||
// X1K1:
|
||||
// <- s
|
||||
// ...
|
||||
// -> e
|
||||
// <- e, ee, es
|
||||
// -> s
|
||||
// <- se
|
||||
@(private,rodata)
|
||||
PATTERN_X1K1 : Message_Pattern = {
|
||||
pre_messages = {.res_s},
|
||||
messages = {
|
||||
{.e},
|
||||
{.e, .ee, .es},
|
||||
{.s},
|
||||
{.se},
|
||||
},
|
||||
}
|
||||
|
||||
// X1X:
|
||||
// -> e
|
||||
// <- e, ee, s, es
|
||||
// -> s
|
||||
// <- se
|
||||
@(private,rodata)
|
||||
PATTERN_X1X : Message_Pattern = {
|
||||
pre_messages = nil,
|
||||
messages = {
|
||||
{.e},
|
||||
{.e, .ee, .s, .es},
|
||||
{.s},
|
||||
{.se},
|
||||
},
|
||||
}
|
||||
|
||||
// XX1:
|
||||
// -> e
|
||||
// <- e, ee, s
|
||||
// -> es, s, se
|
||||
@(private,rodata)
|
||||
PATTERN_XX1 : Message_Pattern = {
|
||||
pre_messages = nil,
|
||||
messages = {
|
||||
{.e},
|
||||
{.e, .ee, .s},
|
||||
{.es, .s, .se},
|
||||
},
|
||||
}
|
||||
|
||||
// X1X1:
|
||||
// -> e
|
||||
// <- e, ee, s
|
||||
// -> es, s
|
||||
// <- se
|
||||
@(private,rodata)
|
||||
PATTERN_X1X1 : Message_Pattern = {
|
||||
pre_messages = nil,
|
||||
messages = {
|
||||
{.e},
|
||||
{.e, .ee, .s},
|
||||
{.es, .s},
|
||||
{.se},
|
||||
},
|
||||
}
|
||||
|
||||
// K1N:
|
||||
// -> s
|
||||
// ...
|
||||
// -> e
|
||||
// <- e, ee
|
||||
// -> se
|
||||
@(private,rodata)
|
||||
PATTERN_K1N : Message_Pattern = {
|
||||
pre_messages = {.ini_s},
|
||||
messages = {
|
||||
{.e,},
|
||||
{.e, .ee},
|
||||
{.se},
|
||||
},
|
||||
}
|
||||
|
||||
// K1K:
|
||||
// -> s
|
||||
// <- s
|
||||
// ...
|
||||
// -> e, es
|
||||
// <- e, ee
|
||||
// -> se
|
||||
@(private,rodata)
|
||||
PATTERN_K1K : Message_Pattern = {
|
||||
pre_messages = {.ini_s, .res_s},
|
||||
messages = {
|
||||
{.e, .es},
|
||||
{.e, .ee},
|
||||
{.se},
|
||||
},
|
||||
}
|
||||
|
||||
// KK1:
|
||||
// -> s
|
||||
// <- s
|
||||
// ...
|
||||
// -> e
|
||||
// <- e, ee, se, es
|
||||
@(private,rodata)
|
||||
PATTERN_KK1 : Message_Pattern = {
|
||||
pre_messages = {.ini_s, .res_s},
|
||||
messages = {
|
||||
{.e},
|
||||
{.e, .ee, .se, .es},
|
||||
},
|
||||
}
|
||||
|
||||
// K1K1:
|
||||
// -> s
|
||||
// <- s
|
||||
// ...
|
||||
// -> e
|
||||
// <- e, ee, es
|
||||
// -> se
|
||||
@(private,rodata)
|
||||
PATTERN_K1K1 : Message_Pattern = {
|
||||
pre_messages = {.ini_s, .res_s},
|
||||
messages = {
|
||||
{.e},
|
||||
{.e, .ee, .es},
|
||||
{.se},
|
||||
},
|
||||
}
|
||||
|
||||
// K1X:
|
||||
// -> s
|
||||
// ...
|
||||
// -> e
|
||||
// <- e, ee, s, es
|
||||
// -> se
|
||||
@(private,rodata)
|
||||
PATTERN_K1X : Message_Pattern = {
|
||||
pre_messages = {.ini_s},
|
||||
messages = {
|
||||
{.e},
|
||||
{.e, .ee, .s, .es},
|
||||
{.se},
|
||||
},
|
||||
}
|
||||
|
||||
// KX1:
|
||||
// -> s
|
||||
// ...
|
||||
// -> e
|
||||
// <- e, ee, se, s
|
||||
// -> es
|
||||
@(private,rodata)
|
||||
PATTERN_KX1 : Message_Pattern = {
|
||||
pre_messages = {.ini_s},
|
||||
messages = {
|
||||
{.e},
|
||||
{.e, .ee, .se, .s},
|
||||
{.es},
|
||||
},
|
||||
}
|
||||
|
||||
// K1X1:
|
||||
// -> s
|
||||
// ...
|
||||
// -> e
|
||||
// <- e, ee, s
|
||||
// -> se, es
|
||||
@(private,rodata)
|
||||
PATTERN_K1X1 : Message_Pattern = {
|
||||
pre_messages = {.ini_s},
|
||||
messages = {
|
||||
{.e},
|
||||
{.e, .ee, .s},
|
||||
{.se, .es},
|
||||
},
|
||||
}
|
||||
|
||||
// I1N:
|
||||
// -> e, s
|
||||
// <- e, ee
|
||||
// -> se
|
||||
@(private,rodata)
|
||||
PATTERN_I1N : Message_Pattern = {
|
||||
pre_messages = nil,
|
||||
messages = {
|
||||
{.e, .s},
|
||||
{.e, .ee},
|
||||
{.se},
|
||||
},
|
||||
}
|
||||
|
||||
// I1K:
|
||||
// <- s
|
||||
// ...
|
||||
// -> e, es, s
|
||||
// <- e, ee
|
||||
// -> se
|
||||
@(private,rodata)
|
||||
PATTERN_I1K : Message_Pattern = {
|
||||
pre_messages = {.res_s},
|
||||
messages = {
|
||||
{.e, .es, .s},
|
||||
{.e, .ee},
|
||||
{.se},
|
||||
},
|
||||
}
|
||||
|
||||
// IK1:
|
||||
// <- s
|
||||
// ...
|
||||
// -> e, s
|
||||
// <- e, ee, se, es
|
||||
@(private,rodata)
|
||||
PATTERN_IK1 : Message_Pattern = {
|
||||
pre_messages = {.res_s},
|
||||
messages = {
|
||||
{.e, .s},
|
||||
{.e, .ee, .se, .es},
|
||||
},
|
||||
}
|
||||
|
||||
// I1K1:
|
||||
// <- s
|
||||
// ...
|
||||
// -> e, s
|
||||
// <- e, ee, es
|
||||
// -> se
|
||||
@(private,rodata)
|
||||
PATTERN_I1K1 : Message_Pattern = {
|
||||
pre_messages = {.res_s},
|
||||
messages = {
|
||||
{.e, .s},
|
||||
{.e, .ee, .es},
|
||||
{.se},
|
||||
},
|
||||
}
|
||||
|
||||
// I1X:
|
||||
// -> e, s
|
||||
// <- e, ee, s, es
|
||||
// -> se
|
||||
@(private,rodata)
|
||||
PATTERN_I1X : Message_Pattern = {
|
||||
pre_messages = nil,
|
||||
messages = {
|
||||
{.e, .s},
|
||||
{.e, .ee, .s, .es},
|
||||
{.se},
|
||||
},
|
||||
}
|
||||
|
||||
// IX1:
|
||||
// -> e, s
|
||||
// <- e, ee, se, s
|
||||
// -> es
|
||||
@(private,rodata)
|
||||
PATTERN_IX1 : Message_Pattern = {
|
||||
pre_messages = nil,
|
||||
messages = {
|
||||
{.e, .s},
|
||||
{.e, .ee, .se, .s},
|
||||
{.es},
|
||||
},
|
||||
}
|
||||
|
||||
// I1X1:
|
||||
// -> e, s
|
||||
// <- e, ee, s
|
||||
// -> se, es
|
||||
@(private,rodata)
|
||||
PATTERN_I1X1 : Message_Pattern = {
|
||||
pre_messages = nil,
|
||||
messages = {
|
||||
{.e, .s},
|
||||
{.e, .ee, .s},
|
||||
{.se, .es},
|
||||
},
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
// ------------- PSK PATTERNS -------------------------------------------------------------
|
||||
|
||||
// Npsk0:
|
||||
|
||||
@@ -817,10 +817,6 @@ handshakestate_write_message :: proc(self: ^Handshake_State, payload, dst: []byt
|
||||
handshakestate_read_message :: proc(self: ^Handshake_State, message, dst: []byte, allocator := context.allocator) -> ([]byte, Status) {
|
||||
ensure(self.status == .Handshake_Pending, "crypto/noise: invalid state for ReadMessage")
|
||||
|
||||
if len(message) < MIN_DH_SIZE {
|
||||
return nil, .Invalid_Handshake_Message
|
||||
}
|
||||
|
||||
protocol := &self.symmetric_state.protocol
|
||||
d_len := dh_len(&self.symmetric_state.protocol)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user