aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Haines <mark.haines@matrix.org>2015-06-21 18:47:06 +0100
committerMark Haines <mark.haines@matrix.org>2015-06-21 18:47:06 +0100
commitfb980849c4ffc99bca7a2dd5a347e9f0b4b99469 (patch)
treed223e53f304a8fa7dca8df7b8f442af7bd6ff67e
parent0ca3797d2d065e63dc5806ba014bcb742b09c5d7 (diff)
Add gdb script and psuedo-call graph generator python script for tracing calls to crypto primitives
-rw-r--r--tracing/README.rst8
-rwxr-xr-xtracing/graph.py100
-rw-r--r--tracing/trace.gdb133
3 files changed, 241 insertions, 0 deletions
diff --git a/tracing/README.rst b/tracing/README.rst
new file mode 100644
index 0000000..d2846ef
--- /dev/null
+++ b/tracing/README.rst
@@ -0,0 +1,8 @@
+Tracing
+=======
+
+To see what crypto functions are being called with what input run
+
+.. code:: bash
+
+ gdb --batch -x tracing/trace.gdb ./build/test_ratchet | grep "^[- ]" | tr "{}" "[]" | tracing/graph.py
diff --git a/tracing/graph.py b/tracing/graph.py
new file mode 100755
index 0000000..ac121aa
--- /dev/null
+++ b/tracing/graph.py
@@ -0,0 +1,100 @@
+#! /usr/bin/python
+
+import sys
+import yaml
+import array
+
+class Call(object):
+ def __init__(self, call):
+ self.func, = call
+ args = dict(call[self.func])
+ self.output = array.array("B", args.pop("output")).tostring()
+ self.inputs = {
+ name: array.array("B", args[name]).tostring()
+ for name in args
+ if not name.endswith("_length")
+ }
+ self.bind = {}
+
+ def expr(self, stream, indent=" ", level=""):
+ stream.write(self.func + "(\n")
+ for name, value in self.inputs.items():
+ stream.write(level + indent + name + "=")
+ self.bind.get(name, Literal(value)).expr(
+ stream, indent, level + indent
+ )
+ stream.write(",\n")
+ stream.write(level + ")")
+
+
+class Literal(str):
+ def expr(self, stream, indent, level):
+ stream.write("\"" + self.encode("hex") + "\"")
+
+
+class Slice(object):
+ def __init__(self, thing, start, end):
+ self.thing = thing
+ self.start = start
+ self.end = end
+
+ def expr(self, stream, indent=" ", level=""):
+ self.thing.expr(stream, indent, level)
+ stream.write("[%d:%d]" % (self.start, self.end))
+
+
+class Concat(list):
+ def expr(self, stream, indent=" ", level=""):
+ stream.write("concat(\n")
+ for thing in self:
+ stream.write(level + indent)
+ thing.expr(stream, indent, level + indent)
+ stream.write(",\n")
+ stream.write(level + ")")
+
+
+calls = [Call(c) for c in yaml.load(sys.stdin)]
+
+outputs = {}
+
+for call in calls:
+ for i in range(8, len(call.output)):
+ outputs.setdefault(call.output[i - 8: i], []).append(call)
+
+for call in calls:
+ for name, value in call.inputs.items():
+ for bind in outputs.get(value[:8], ()):
+ if value == bind.output:
+ call.bind[name] = bind
+ else:
+ for end in range(len(value), len(bind.output) + 1):
+ start = end - len(value)
+ if value == bind.output[start:end]:
+ call.bind[name] = Slice(bind, start, end)
+ if not name in call.bind:
+ i = 0
+ j = 1
+ k = 0
+ concat = Concat()
+ while i < len(value):
+ for bind in outputs.get(value[i:i+8], ()):
+ if value[i:].startswith(bind.output):
+ if k != i:
+ concat.append(Literal(value[k:i]))
+ concat.append(bind)
+ j = len(bind.output)
+ k = i + j
+ break
+ i += j
+ j = 1
+ if concat:
+ if k != i:
+ concat.append(Literal(value[k:i]))
+ call.bind[name] = concat
+
+for call in calls:
+ if call.func.startswith("h"):
+ sys.stdout.write("\"" + call.output.encode("hex") + "\" = ")
+ call.expr(sys.stdout)
+ sys.stdout.write("\n")
+
diff --git a/tracing/trace.gdb b/tracing/trace.gdb
new file mode 100644
index 0000000..bdece2e
--- /dev/null
+++ b/tracing/trace.gdb
@@ -0,0 +1,133 @@
+set print pretty off
+set print repeats unlimited
+set print elements unlimited
+set breakpoint pending on
+
+
+break crypto.cpp:273
+commands
+silent
+printf "- hmac_sha256:\n"
+printf " key_length: %d\n", key_length
+printf " input_length: %d\n", input_length
+if key_length > 0
+ printf " key: "
+ output/x *key@key_length
+ printf "\n"
+else
+ printf " key: {}\n"
+end
+if input_length > 0
+ printf " input: "
+ output/x *input@input_length
+ printf "\n"
+else
+ printf " input: {}\n"
+end
+cont
+end
+
+
+break crypto.cpp:280
+commands
+silent
+printf " output: "
+output/x *output@32
+printf "\n"
+cont
+end
+
+
+break crypto.cpp:307
+commands
+silent
+set $hkdf_output = output
+cont
+end
+
+
+break crypto.cpp:323
+commands
+silent
+printf "- hkdf_sha256:\n"
+printf " input_length: %d\n", input_length
+printf " salt_length: %d\n", salt_length
+printf " info_length: %d\n", info_length
+printf " output_length: %d\n", output_length
+if input_length > 0
+ printf " input: "
+ output/x *input@input_length
+ printf "\n"
+else
+ printf " input: {}\n"
+end
+if salt_length > 0
+ printf " salt: "
+ output/x *salt@salt_length
+ printf "\n"
+else
+ printf " salt: {}\n"
+end
+if info_length > 0
+ printf " info: "
+ output/x *info@info_length
+ printf "\n"
+else
+ printf " info: {}\n"
+end
+printf " output: "
+output/x *$hkdf_output@output_length
+printf "\n"
+cont
+end
+
+
+break crypto.cpp:156
+commands
+silent
+printf "- curve25519:\n"
+printf " public: "
+output/x *their_key.public_key@32
+printf "\n"
+printf " private: "
+output/x *our_key.private_key@32
+printf "\n"
+printf " output: "
+output/x *output@32
+printf "\n"
+cont
+end
+
+break crypto.cpp:156
+commands
+silent
+printf "- curve25519:\n"
+printf " public: "
+output/x *their_key.public_key@32
+printf "\n"
+printf " private: "
+output/x *our_key.private_key@32
+printf "\n"
+printf " output: "
+output/x *output@32
+printf "\n"
+cont
+end
+
+break crypto.cpp:147
+commands
+silent
+printf "- curve25519:\n"
+printf " public: "
+output/x *CURVE25519_BASEPOINT@32
+printf "\n"
+printf " private: "
+output/x *key_pair.private_key@32
+printf "\n"
+printf " output: "
+output/x *key_pair.public_key@32
+printf "\n"
+cont
+end
+
+run