Skip to content

Commit

Permalink
Support for AES-GCM
Browse files Browse the repository at this point in the history
  • Loading branch information
msprotz committed Jun 25, 2024
1 parent 55df49d commit 6e08d6a
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 13 deletions.
29 changes: 25 additions & 4 deletions hacl-star-snapshot/primitives-js/Primitives.ml
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,32 @@ let chacha20_poly1305_decrypt ~key ~iv ~ad ~ct ~tag =
| Some pt -> Some (H.bytes_of_uint8array pt)
| None -> None

external whacl_aes128gcm_encrypt:
js_u8array -> js_u8array -> js_u8array -> js_u8array -> js_u8array Js.js_array Js.t
= "whacl_aes128gcm_encrypt"

let aes128gcm_encrypt ~key ~iv ~ad ~pt =
ignore (key, iv, ad, pt);
failwith "Not implemented in JS: aes128gcm_encrypt"
let key = H.uint8array_of_bytes key in
let iv = H.uint8array_of_bytes iv in
let ad = H.uint8array_of_bytes ad in
let pt = H.uint8array_of_bytes pt in
let ret = whacl_aes128gcm_encrypt key iv ad pt in
let ret = Js.to_array ret in
let ct = H.bytes_of_uint8array ret.(0) in
let tag = H.bytes_of_uint8array ret.(1) in
FStar_Seq_Base.append ct tag

external whacl_aes128gcm_decrypt:
js_u8array -> js_u8array -> js_u8array -> js_u8array -> js_u8array -> js_u8array Js.Opt.t
= "whacl_aes128gcm_decrypt"

let aes128gcm_decrypt ~key ~iv ~ad ~ct ~tag =
ignore (key, iv, ad, ct, tag);
failwith "Not implemented in JS: aes128gcm_decrypt"
let key = H.uint8array_of_bytes key in
let iv = H.uint8array_of_bytes iv in
let ad = H.uint8array_of_bytes ad in
let ct = H.uint8array_of_bytes ct in
let tag = H.uint8array_of_bytes tag in
match Js.Opt.to_option (whacl_aes128gcm_decrypt key iv ad ct tag) with
| Some pt -> Some (H.bytes_of_uint8array pt)
| None -> None

8 changes: 8 additions & 0 deletions hacl-star-snapshot/primitives-js/dummy.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,11 @@ CAMLprim value whacl_chacha20_poly1305_encrypt() {
CAMLprim value whacl_chacha20_poly1305_decrypt() {
caml_failwith(error_msg);
}

CAMLprim value whacl_aes128gcm_encrypt() {
caml_failwith(error_msg);
}

CAMLprim value whacl_aes128gcm_decrypt() {
caml_failwith(error_msg);
}
18 changes: 12 additions & 6 deletions js/MLS_JS.ml
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,18 @@ let _ =

(* Expects a JS string that contains the expected ciphersuite *)
method setCiphersuite (cs: _ Js.t) =
match Js.to_string cs with
| _ ->
(* TODO: actually offer more ciphersuites *)
if !crypto_bytes_ <> None then
print_and_fail "Cannot dynamically change ciphersuites";
crypto_bytes_ := Some MLS_Crypto_Builtins.(mk_concrete_crypto_bytes AC_mls_128_dhkemx25519_chacha20poly1305_sha256_ed25519)
let cs = Js.to_string cs in
if !crypto_bytes_ <> None then
print_and_fail "Cannot dynamically change ciphersuites";
let ac = match cs with
| "MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519" ->
MLS_Crypto_Builtins.AC_mls_128_dhkemx25519_aes128gcm_sha256_ed25519
| "MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519" ->
AC_mls_128_dhkemx25519_chacha20poly1305_sha256_ed25519
| _ ->
print_and_fail ("Unsupported ciphersuite: " ^ cs)
in
crypto_bytes_ := Some MLS_Crypto_Builtins.(mk_concrete_crypto_bytes ac)

(* NEW API: binders for MLS.API.fst (via MLS_API.ml) *)

Expand Down
25 changes: 24 additions & 1 deletion js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,31 @@ function HaclCrypto(Hacl) {
return plain;
else
return null;
},

// AES128-GCM implementation relying on OpenSSL via node-crypto to get the
// benefits of hardware acceleration with AESNI
aes128gcm_encrypt: (key, iv, ad, pt) => {
let cipher = node_crypto.createCipheriv("id-aes128-GCM", key, iv, { authTagLength: 16 });
cipher.setAAD(ad);
let ct = cipher.update(pt);
cipher.final();
return [ new Uint8Array(ct.buffer), new Uint8Array(cipher.getAuthTag().buffer) ];
},

aes128gcm_decrypt: (key, iv, ad, ct, tag) => {
let decipher = node_crypto.createDecipheriv("id-aes128-GCM", key, iv, { authTagLength: 16 });
decipher.setAAD(ad);
let pt = decipher.update(ct);
decipher.setAuthTag(tag);
try {
decipher.final();
return pt;
} catch (e) {
return null;
}
}
};
}
}

if (typeof module !== undefined)
Expand Down
10 changes: 10 additions & 0 deletions js/overrides.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ function whacl_chacha20_poly1305_decrypt(key, iv, ad, ct, tag) {
return joo_global_object.MyCrypto.chacha20_poly1305_decrypt(key, iv, ad, ct, tag);
}

//Provides:whacl_aes128gcm_encrypt
function whacl_aes128gcm_encrypt(key, iv, ad, pt) {
return joo_global_object.MyCrypto.aes128gcm_encrypt(key, iv, ad, pt);
}

//Provides:whacl_aes128gcm_decrypt
function whacl_aes128gcm_decrypt(key, iv, ad, ct, tag) {
return joo_global_object.MyCrypto.aes128gcm_decrypt(key, iv, ad, ct, tag);
}

// OCaml system stuff

//Provides: caml_thread_initialize const
Expand Down
6 changes: 4 additions & 2 deletions js/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,10 @@ var test_main = () => {
var test_new = () => {
// A test for the new, more general API. We start with some warm-up.

// This is the only supported one for now, we plan to expose AES-GCM soo.
MLS.setCiphersuite("mls_128_dhkemx25519_chacha20poly1305_sha256_ed25519");
// Pick either one.
// MLS.setCiphersuite("MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519");
MLS.setCiphersuite("MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519");

// The source of entropy is customizable.
MLS.setEntropy((n) => crypto.getRandomValues(new Uint8Array(n)));

Expand Down

0 comments on commit 6e08d6a

Please sign in to comment.