From 099d4e4f84eada6bdb6c05dd2ea963e269bc64e2 Mon Sep 17 00:00:00 2001 From: Aaron Kaiser Date: Tue, 27 Aug 2024 14:20:03 +0200 Subject: [PATCH] feat: agent with keygen --- .envrc | 1 + .gitignore | 4 ++ Makefile | 25 ++++++++++++ default.nix | 58 +++++++++++++++++++++++++++ src/agent.jazz | 105 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 193 insertions(+) create mode 100644 .envrc create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 default.nix create mode 100644 src/agent.jazz diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..1d953f4 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use nix diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d19d9ba --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +build +result +*.o +.direnv diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..69cce0b --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ +JC ?= jasminc +CC ?= gcc +MAKE ?= make + +JASMIN_ARGS = -protect-calls -return-address-kind mmx + +.PHONY: clean run + +all: build + @true + +build: build/agent.o + ar -crs build/libagent.a build/agent.o + +build/%.o: build/%.S + $(CC) $< -c -o $@ + +clean: + rm build/* 2> /dev/null || true + $(MAKE) -C syscall clean + +build/%.S: src/%.jazz + $(JC) $(JASMIN_ARGS) $< -o $@ + # remove the remaining ret calls to make sure that we don't execute any return. Those returns should not be called anyways due to the infinit loop + sed -i 's/ret/hlt/g' $@ diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..57df68a --- /dev/null +++ b/default.nix @@ -0,0 +1,58 @@ +{ pkgs ? import { } }: +with pkgs; +let + jasmin-src = fetchFromGitHub { + owner = "jasmin-lang"; + repo = "jasmin"; + rev = "4d42c212b924ad7553c2eab49d337fd128ad629b"; + hash = "sha256-Ve9Eezpvi1wynlqQxO4KDSqw13MDXQmR8NjOS3PHWzg="; + }; + + jasmin-drv = callPackage "${jasmin-src}/default.nix" { inherit pkgs; }; + jasmin = jasmin-drv.overrideAttrs { + name = "jasmin with syscalls"; + buildPhase = '' + make -C compiler/ CIL + make -C compiler/ + ''; + }; + + libjade = stdenvNoCC.mkDerivation rec { + name = "libjade-src"; + version = "2023.05-2"; + + src = fetchzip { + url = "https://github.com/formosa-crypto/libjade/releases/download/release%2F${version}/libjade-dist-src-amd64.tar.gz"; + hash = "sha256-IWLMWExvdZ++V3a9zX0a9xjSDgOA98h3sSmLOj8hKPE="; + }; + + buildPhase = '' + mkdir -p $out + cp -r $src/libjade $out + chmod -R u+w $out + sed -i '/#randombytes/c\' $out/libjade/crypto_kem/kyber_kyber768_avx2/kyber_kyber768_avx2.jazz + sed -i 's/#\[returnaddress="stack"\]/#\[returnaddress="mmx"\]/g' $out/libjade/crypto_kem/kyber_kyber768_avx2/kyber_kyber768_avx2.jazz + ''; + }; +in +stdenv.mkDerivation { + name = "mlkem-agent"; + src = nix-gitignore.gitignoreSource [ ] ./.; + + nativeBuildInputs = [ + gnumake + gcc + jasmin + ]; + + configurePhase = '' + mkdir build + ''; + + installPhase = '' + mkdir -p $out/lib + cp build/libagent.a $out/lib + ''; + + JASMINPATH = "Jade=${libjade}/libjade/"; +} diff --git a/src/agent.jazz b/src/agent.jazz new file mode 100644 index 0000000..15b6b70 --- /dev/null +++ b/src/agent.jazz @@ -0,0 +1,105 @@ +from Jade require "crypto_kem/kyber_kyber768_avx2/kyber_kyber768_avx2.jazz" + +inline fn extract_nth_ptr(reg u64 sync_mem shared_mem, inline int i) -> reg u64 { + reg u64 p; + + p = (u64)[sync_mem + (16 + i * 8)]; + p += shared_mem; + + return p; +} + +inline fn extract_ipc_id(reg u64 sync_mem) -> reg u64 { + reg u64 id; + + id = (u64)[sync_mem + 8]; + + return id; +} + +inline fn generate_keypair(reg u64 shared_mem sync_mem private_mem, stack u64 key_id) -> stack u64 { + inline int i; + stack u8[2*KYBER_SYMBYTES] coins; + reg u64 skptr idptr pkptr flag num_bytes; + + while { + flag = 0; + coins, num_bytes = #randombytes(coins, flag); + } (num_bytes != 2*KYBER_SYMBYTES) + + skptr = key_id * 2400; + skptr += private_mem; + + for i=0 to 8 { + (u64)[skptr + i * 8] = coins[u64 i]; + } + + idptr = extract_nth_ptr(sync_mem, shared_mem, 0); + pkptr = extract_nth_ptr(sync_mem, shared_mem, 1); + + jade_kem_kyber_kyber768_amd64_avx2_keypair_derand(pkptr, skptr, skptr); + + (u64)[idptr] = key_id; + + key_id += 1; + + return key_id; +} + +export fn agent_start(reg u64 shared_mem sync_mem private_mem_fd) { + stack u64 key_id; + reg u64 private_mem; + // Futex varibles + reg u64 futex_op val timeout uaddr2 val3 woken_up; + // Mmap variables + reg u64 addr len prot flag off; + + () = #spill(shared_mem, sync_mem); + + private_mem_fd = private_mem_fd; + addr = 0; + len = 3200; + prot = 3; // PROT_READ | PROT_WRITE + flag = 1; // MAP_SHARED; + off = 0; + private_mem = #mmap(addr, len, prot, flag, private_mem_fd, off); + + () = #spill(private_mem); + + key_id = 0; + + while (true) { + () = #unspill(sync_mem); + + futex_op = 0; + val = 0; + timeout = 0; + uaddr2 = 0; + val3 = 0; + woken_up = #futex(sync_mem, futex_op, val, timeout, uaddr2, val3); + + () = #unspill(shared_mem, sync_mem, private_mem); + + reg u64 id; + id = extract_ipc_id(sync_mem); + + if (id == 0) { + key_id = generate_keypair(shared_mem, sync_mem, private_mem, key_id); + } else { + if (id == 1) { + } else { + if (id == 2) { + } + } + } + + () = #unspill(sync_mem); + + futex_op = 1; + val = 1; + timeout = 0; + uaddr2 = 0; + val3 = 0; + woken_up = #futex(sync_mem, futex_op, val, timeout, uaddr2, val3); + } +}