Verified Secure ZeroCopy Parsers for Authenticated Message Formats

  • Slides: 31
Download presentation
Verified Secure Zero-Copy Parsers for Authenticated Message Formats

Verified Secure Zero-Copy Parsers for Authenticated Message Formats

Verified Secure Zero-Copy Parsers for Authenticated Message Formats ⊥ {0, 255}* V p⁻¹(V) p·p⁻¹(V)

Verified Secure Zero-Copy Parsers for Authenticated Message Formats ⊥ {0, 255}* V p⁻¹(V) p·p⁻¹(V) p s ⊥ s(V) ∀ ∈

Verified Secure Zero-Copy Parsers for Authenticated Message Formats ⊥ {0, 255}* V p⁻¹(V) p·p⁻¹(V)

Verified Secure Zero-Copy Parsers for Authenticated Message Formats ⊥ {0, 255}* V p⁻¹(V) p·p⁻¹(V) p s s(V) If s(x) = s(y), then p(s(x)) =

Verified Secure Zero-Copy Parsers for Authenticated Message Formats ⊥ {0, 255}* V p⁻¹(V) p·p⁻¹(V)

Verified Secure Zero-Copy Parsers for Authenticated Message Formats ⊥ {0, 255}* V p⁻¹(V) p·p⁻¹(V) p s s(V) ⊥ for some x ∉ s(V),

6 f 9 f 544 f 3545 f 84977549 d 01 efcf 664 cc

6 f 9 f 544 f 3545 f 84977549 d 01 efcf 664 cc 4 c 1 b 603 3021300906052 b 0 e 03021 a 050004146 f 9 f 544 f 3545 f 84977549 d 01 efcf 664 cc 4 c 1 b 603 0001 ffffffffffffffffffffffffffffffffffffffffffffff 003021300906052 b 0 e 03021 a 050004146 f 9 f 544 f 3545 f 84977549 d 01 efcf 664 cc 4 c 1 b 603 Digest. Info : : = SEQUENCE { hash_alg OID; parameters NULL; } digest OCTET STRING }

0001 ff 003021300906052 b 0 e 03021 a 050004146 f 9 f 544 f

0001 ff 003021300906052 b 0 e 03021 a 050004146 f 9 f 544 f 3545 f 84977549 d 01 efcf 664 cc 4 c 1 b 6037 b 031 fced 013437521 bf 3 f 36 c 44 e 0 d 410 c 750 da 3 cc 510 abd 12 ca 5 cc 0 fceebb 75912 fc 2 e 38 e 953 cea 30432 e 7521 bf 3 f 36 c 44 e 0 d 410 c 750 da 3 cc 510 abd 12 ca 5 cc 0 fceebb 75912 fc 2 e 0001 ff 003021300906052 b 0 e 03021 a 050004 dc 7 b 031 fce d 013437521 bf 3 f 36 c 44 e 0 d 410 c 750 da 3 cc 510 abd 12 ca 5 c c 0 fceebb 75912 fc 2 e 38 e 953 cea 30432 e 7521 bf 3 f 36 c 44 e 0 d 410 c 750 da 3 cc 510 abd 12 ca 5 cc 0 fceebb 75912 fc 2 e 0000 00146 f 9 f 544 f 3545 f 84977549 d 01 efcf 664 cc 4 c 1 b 603 unsigned length = 0; for (i = 0; i < length_of_length; i++) { length <<= 8; length |= length[i]; } Hash_alg = 2 b 0 e 03021 a Digest = 6 f 9 f 544 f 3545 f 84977549 d 0 1 efcf 664 cc 4 c 1 b 603 0001 ff 003021300906052 b 0 e 03021 a 05 dc 7 b 031 fced 01 3437521 bf 3 f 36 c 44 e 0 d 410 c 750 da 3 cc 510 abd 12 ca 5 cc 0 f ceebb 75912 fc 2 e 38 e 953 cea 30432 e 7521 bf 3 f 36 c 44 e 0 d 4 10 c 750 da 3 cc 510 abd 12 ca 5 cc 0 fceebb 75912 fc 23 cde 143 04146 f 9 f 544 f 3545 f 84977549 d 01 efcf 664 cc 4 c 1 b 603

Verified Secure Zero-Copy Parsers for Authenticated Message Formats {0, 255}* ⊥ V p·p⁻¹(V) p

Verified Secure Zero-Copy Parsers for Authenticated Message Formats {0, 255}* ⊥ V p·p⁻¹(V) p s p⁻¹(V) = s(V) secure p⁻¹(V) = s(V) ⊥

Verified Secure Zero-Copy Parsers for Authenticated Message Formats {0, 255}* ⊥ V = p·p⁻¹(V)

Verified Secure Zero-Copy Parsers for Authenticated Message Formats {0, 255}* ⊥ V = p·p⁻¹(V) p s p⁻¹(V) = s(V) secure

Verified Secure Zero-Copy Parsers for Authenticated Message Formats memory safety risks correct, secure and

Verified Secure Zero-Copy Parsers for Authenticated Message Formats memory safety risks correct, secure and safe

type parser t = b: bytes -> option (t * n: nat{n <= length

type parser t = b: bytes -> option (t * n: nat{n <= length b}) type serializer (p: parser t) = f: (t -> bytes) { forall x. p (f x) == Some (x, length (f x)) } val val return: parser unit bind: parser t -> (t -> parser t’) -> parser t’ seq: parser t -> parser t’ -> parser (t * t’) map: f: (t -> t’) -> parser t’

Low. Parse DSL Spec (TLS, ASN. 1) F* Spec Quacky. Ducky F* Impl F*

Low. Parse DSL Spec (TLS, ASN. 1) F* Spec Quacky. Ducky F* Impl F* App Low* Impl Memory-safe, zero-copy C code C App

let validator (p: parser t) = bs: array uint 8 -> pos: u 32

let validator (p: parser t) = bs: array uint 8 -> pos: u 32 { pos <= length bs } -> ST u 32 (requires fun h 0 -> h 0 `contains` bs) (ensures fun h 0 res h 1 -> h 0 == h 1 / (if res < ERROR_CODE then exists v. p (as_bytes bs h 0 pos) = Some (v, res) (* parsing succeeds *) else p (as_bytes bs h 0 pos) = None (* parsing fails *)))

uint 32_t Txin_txin_validator(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Txin_txin_jumper(Low. Parse_Low_Base_slice input, uint

uint 32_t Txin_txin_validator(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Txin_txin_jumper(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Txin_accessor_txin_prev_hash(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Txin_accessor_txin_prev_idx(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Txin_accessor_txin_script. Sig(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Txin_accessor_txin_seq_no(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Txout_txout_validator(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Txout_txout_jumper(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Txout_accessor_txout_value(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Txout_accessor_txout_script. Pub. Key(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Transaction_transaction_validator(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Transaction_transaction_jumper(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Transaction_accessor_transaction_version(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Transaction_accessor_transaction_inputs(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Transaction_accessor_transaction_outputs(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Transaction_accessor_transaction_lock_time(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Block_block_validator(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Block_block_jumper(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Block_accessor_block_version(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Block_accessor_block_prev_block(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Block_accessor_block_merkle_root(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Block_accessor_block_timestamp(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Block_accessor_block_bits(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Block_accessor_block_nonce(Low. Parse_Low_Base_slice input, uint 32_t pos); uint 32_t Block_accessor_block_tx(Low. Parse_Low_Base_slice input, uint 32_t pos);

TLS Transport QUIC Transport mi. TLS Record mi. TLS Handshake Ever. Crypt HACL* (Poly

TLS Transport QUIC Transport mi. TLS Record mi. TLS Handshake Ever. Crypt HACL* (Poly 1305, Curve 25519, Chacha 20, SHA, etc. ) Ever. Parse Vale (Poly 1305, Curve 25519, AESGCM, SHA 2, etc. ) Crypto specs / Hacspec

F* lines of code (TLS) TLS 6 k 21% Handshake 6 k 22% Key

F* lines of code (TLS) TLS 6 k 21% Handshake 6 k 22% Key Schedule 3 k 9% Formatting 7 k 28% Crypto (real) 4% Crypto (ideal) 15%

/*@implicit*/

/*@implicit*/

struct { Heartbeat. Message. Type type; uint 16 payload_length; opaque payload[payload_length]; opaque padding[padding_length]; }

struct { Heartbeat. Message. Type type; uint 16 payload_length; opaque payload[payload_length]; opaque padding[padding_length]; } Heartbeat. Message; padding_length MUST be at least 16, and equal to TLSPlaintext. length-payload_length-3

struct { Heartbeat. Message. Type type; opaque payload<0. . 2^14 -21>; opaque padding<16. .

struct { Heartbeat. Message. Type type; opaque payload<0. . 2^14 -21>; opaque padding<16. . 2^14 -3>; } Heartbeat. Message;

struct { select (Handshake. msg_type) { case client_hello: Protocol. Version versions<2. . 254>; case

struct { select (Handshake. msg_type) { case client_hello: Protocol. Version versions<2. . 254>; case server_hello: /* and Hello. Retry. Request */ Protocol. Version selected_version; }; } Supported. Versions;

struct { Extension. Type type; uint 16 len; select(type) { case server_name: Server. Name.

struct { Extension. Type type; uint 16 len; select(type) { case server_name: Server. Name. List; //. . . case supported_versions: Supported. Versions; //. . . default: opaque; } CHE[len]; /*extension_data*/ } Client. Hello. Extension; struct { Extension. Type type; uint 16 len; select(type) { case server_name: Empty; //. . . case supported_versions: Protocol. Version; //. . . default: opaque; } SHE[len]; /*extension_data*/ } Server. Hello. Extension;

https: //github. com/project-everest/everparse https: //github. com/project-everest/mitls-fstar https: //fstar-lang. org https: //hub. docker. com/r/projecteverest/quackyducky-linux

https: //github. com/project-everest/everparse https: //github. com/project-everest/mitls-fstar https: //fstar-lang. org https: //hub. docker. com/r/projecteverest/quackyducky-linux