package jasmin

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file securityAnnotations.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
open Utils
open Prog

(* Abstract syntax for security annotations *)
type simple_level = Public | Secret | Named of Name.t

let named n = Named n

type level = { normal : simple_level; speculative : simple_level }

let diag d = { normal = d; speculative = d }
let public = diag Public
let transient = { normal = Public; speculative = Secret }
let secret = diag Secret

type typ = Msf | Direct of level | Indirect of { ptr : level; value : level }

let direct d = Direct d

type typs = typ list
type signature = { arguments : typs; results : typs }

let get_nth_argument n { arguments; _ } = List.nth_opt arguments n
let get_nth_result n { results; _ } = List.nth_opt results n

(** Pretty-printing *)
module PP = struct
  open Format

  let simple_level fmt = function
    | Public -> fprintf fmt "public"
    | Secret -> fprintf fmt "secret"
    | Named n -> fprintf fmt "%s" n

  let level fmt = function
    | { normal = Public; speculative = Secret } -> fprintf fmt "transient"
    | { normal = n; speculative = s } ->
        if n = s then simple_level fmt n
        else
          fprintf fmt "{ normal: %a, speculative: %a }" simple_level n
            simple_level s

  let typ fmt = function
    | Msf -> fprintf fmt "msf"
    | Direct t -> level fmt t
    | Indirect { ptr; value } ->
        fprintf fmt "{ ptr: %a, val: %a }" level ptr level value

  let typs fmt = function
    | [] -> fprintf fmt "()"
    | ts -> fprintf fmt "@[<h>%a@]" (pp_list "@ ×@ " typ) ts

  let signature fmt { arguments; results } =
    fprintf fmt "%a → %a" typs arguments typs results
end

(** Parsing *)
module Parse = struct
  open Angstrom

  let ws =
    skip_while (function
      | '\x20' | '\x0a' | '\x0d' | '\x09' -> true
      | _ -> false)

  let ident =
    take_while1 (function 'a' .. 'z' | '_' | 'A' .. 'Z' -> true | _ -> false)
    >>= fun hd ->
    take_while (function
      | 'a' .. 'z' | '_' | 'A' .. 'Z' | '0' .. '9' -> true
      | _ -> false)
    >>= fun tl -> return (hd ^ tl)

  let arrow = (string "->" <|> string "→") *> ws
  let times = char '*' *> ws <|> string "×" *> ws

  let simple_level =
    string "public" *> ws *> return Public
    <|> string "secret" *> ws *> return Secret
    <|> lift named (ident <* ws)

  (** Accepts a “key: value” pair where the key can be abbreviated by its first character. *)
  let labelled ~(key : string) value =
    char key.[0]
    *> option "" (string String.(sub key 1 (length key - 1)))
    *> ws *> char ':' *> ws *> value
    <* ws

  let level =
    char '{' *> ws
    *> ( labelled ~key:"normal" simple_level >>= fun normal ->
         char ',' *> ws *> labelled ~key:"speculative" simple_level <* ws
         >>= fun speculative -> return { normal; speculative } )
    <* char '}' <* ws
    <|> string "transient" *> ws *> return transient
    <|> lift diag simple_level

  let typ =
    char '{' *> ws
    *> ( labelled ~key:"ptr" level >>= fun ptr ->
         char ',' *> ws *> labelled ~key:"val" level >>= fun value ->
         return (Indirect { ptr; value }) )
    <* char '}' <* ws
    <|> string "msf" *> ws *> return Msf
    <|> lift direct level

  let typs =
    char '(' *> ws *> sep_by times typ <* char ')' <|> sep_by1 times typ

  let signature =
    ws *> typs >>= fun arguments ->
    ws *> arrow *> typs >>= fun results -> return { arguments; results }

  let string s =
    match parse_string ~consume:All signature s with
    | Ok v -> Some v
    | Error rule ->
        warning Always Location.i_dummy "ill-formed security signature (%s): %s"
          rule s;
        None
end

let get_sct_signature a =
  Option.bind (Annotations.get "sct" a) (function
    | Some { pl_desc = Astring s; _ } -> Parse.string s
    | _ -> None)