From 19a9d93b3763d6837dd994075c2f8b37cd617bfa Mon Sep 17 00:00:00 2001 From: karthikbhargavan Date: Wed, 21 Nov 2018 11:10:16 +0100 Subject: [PATCH 1/3] current --- fizz/CMakeLists.txt | 12 +- fizz/crypto/experimental/hacl/Hacl.cpp | 105 +++ fizz/crypto/experimental/hacl/Hacl.h | 53 ++ .../experimental/hacl/Hacl_AesGCM_NI.cpp | 683 ++++++++++++++++++ .../crypto/experimental/hacl/Hacl_AesGCM_NI.h | 41 ++ fizz/crypto/experimental/hacl/TARGETS | 36 + fizz/crypto/experimental/hacl/endianness.h | 220 ++++++ .../experimental/hacl/test/HaclCipherTest.cpp | 207 ++++++ .../hacl/test/HaclCipherTest.cpp~ | 207 ++++++ fizz/crypto/experimental/hacl/vec128.h | 83 +++ fizz/mac-build.sh | 4 +- 11 files changed, 1648 insertions(+), 3 deletions(-) create mode 100644 fizz/crypto/experimental/hacl/Hacl.cpp create mode 100644 fizz/crypto/experimental/hacl/Hacl.h create mode 100644 fizz/crypto/experimental/hacl/Hacl_AesGCM_NI.cpp create mode 100644 fizz/crypto/experimental/hacl/Hacl_AesGCM_NI.h create mode 100644 fizz/crypto/experimental/hacl/TARGETS create mode 100644 fizz/crypto/experimental/hacl/endianness.h create mode 100644 fizz/crypto/experimental/hacl/test/HaclCipherTest.cpp create mode 100644 fizz/crypto/experimental/hacl/test/HaclCipherTest.cpp~ create mode 100644 fizz/crypto/experimental/hacl/vec128.h diff --git a/fizz/CMakeLists.txt b/fizz/CMakeLists.txt index ab3b48fe679..601686af8b9 100644 --- a/fizz/CMakeLists.txt +++ b/fizz/CMakeLists.txt @@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.1) project("fizz" VERSION 1.0.0 LANGUAGES CXX C) -add_compile_options(-std=c++14) +add_compile_options(-std=c++14 -maes -mpclmul -mavx) set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/) @@ -64,6 +64,9 @@ set(FIZZ_HEADER_DIRS server util tool + + # hacl + crypto/experimental/hacl ) set(FIZZ_TEST_HEADER_DIRS @@ -134,6 +137,10 @@ set(FIZZ_SOURCES client/SynchronizedLruPskCache.cpp client/EarlyDataRejectionPolicy.cpp util/FizzUtil.cpp + + # hacl + crypto/experimental/hacl/Hacl_AesGCM_NI.cpp + crypto/experimental/hacl/Hacl.cpp ) add_library(fizz @@ -344,6 +351,9 @@ if(BUILD_TESTS) add_gtest(util/test/FizzUtilTest.cpp FizzUtilTest) add_gtest(test/AsyncFizzBaseTest.cpp AsyncFizzBaseTest) add_gtest(test/HandshakeTest.cpp HandshakeTest) + + # Hacl + add_gtest(crypto/experimental/hacl/test/HaclCipherTest HaclCipherTest) endif() option(BUILD_EXAMPLES "BUILD_EXAMPLES" ON) diff --git a/fizz/crypto/experimental/hacl/Hacl.cpp b/fizz/crypto/experimental/hacl/Hacl.cpp new file mode 100644 index 00000000000..ae597ffd104 --- /dev/null +++ b/fizz/crypto/experimental/hacl/Hacl.cpp @@ -0,0 +1,105 @@ +#include "Hacl.h" + +#include "Hacl_AesGCM_NI.h" +#include +#include +#include + +namespace fizz { +namespace hacl { + +std::array Hacl::createIV(uint64_t seqNum) const { + std::array iv; + uint64_t bigEndianSeqNum = folly::Endian::big(seqNum); + const size_t prefixLength = 12 - sizeof(uint64_t); + memset(iv.data(), 0, prefixLength); + memcpy(iv.data() + prefixLength, &bigEndianSeqNum, 8); + XOR(key_.iv->coalesce(), folly::range(iv)); + return iv; +} + +void Hacl::setKey(TrafficKey tk) { + tk.key->coalesce(); + tk.iv->coalesce(); + key_ = std::move(tk); +} + +std::unique_ptr Hacl::encrypt( + std::unique_ptr&& plaintext, + const folly::IOBuf* associatedData, + uint64_t seqNum) const { + Lib_Vec128_vec128 ctx[22] = {0}; + // get iv and init hacl + auto iv = createIV(seqNum); + uint8_t* keyData = const_cast(key_.key->data()); + Hacl_AesGCM_NI_aes128_gcm_init(ctx, keyData, iv.data()); + + // plaintext needs to be coalesced + plaintext->coalesce(); + auto inputLen = plaintext->computeChainDataLength(); + // output needs to be one contiguous buffer w/ room for the tag + auto out = folly::IOBuf::create(headroom_ + inputLen + getCipherOverhead()); + out->advance(headroom_); + out->append(inputLen + getCipherOverhead()); + auto inData = const_cast(plaintext->data()); + + // set up aad + uint8_t* aad = nullptr; + size_t aadLen = 0; + if (associatedData) { + auto adbuf = const_cast(associatedData); + adbuf->coalesce(); + aad = const_cast(adbuf->data()); + aadLen = adbuf->computeChainDataLength(); + } + + // hacl encrypt! + Hacl_AesGCM_NI_aes128_gcm_encrypt( + ctx, inputLen, out->writableData(), inData, aadLen, aad); + + // assume it worked? + return out; +} + +folly::Optional> Hacl::tryDecrypt( + std::unique_ptr&& ciphertext, + const folly::IOBuf* associatedData, + uint64_t seqNum) const { + Lib_Vec128_vec128 ctx[22] = {0}; + // set up + // get iv and init hacl + auto iv = createIV(seqNum); + uint8_t* keyData = const_cast(key_.key->data()); + Hacl_AesGCM_NI_aes128_gcm_init(ctx, keyData, iv.data()); + + // set up aad + uint8_t* aad = nullptr; + size_t aadLen = 0; + if (associatedData) { + auto adbuf = const_cast(associatedData); + adbuf->coalesce(); + aad = const_cast(adbuf->data()); + aadLen = adbuf->computeChainDataLength(); + } + + ciphertext->coalesce(); + auto inputLen = ciphertext->computeChainDataLength(); + if (inputLen <= getCipherOverhead()) { + return folly::none; + } + auto out = folly::IOBuf::create(inputLen - getCipherOverhead()); + out->append(inputLen - getCipherOverhead()); + + auto cipherData = const_cast(ciphertext->data()); + + auto res = Hacl_AesGCM_NI_aes128_gcm_decrypt( + ctx, inputLen-16, out->writableData(), cipherData, aadLen, aad); + + if (!res) { + return folly::none; + } + return out; +} + +} // namespace hacl +} // namespace fizz diff --git a/fizz/crypto/experimental/hacl/Hacl.h b/fizz/crypto/experimental/hacl/Hacl.h new file mode 100644 index 00000000000..945caa2b5a4 --- /dev/null +++ b/fizz/crypto/experimental/hacl/Hacl.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ +#pragma once + +#include + +namespace fizz { +namespace hacl { + +class Hacl : public Aead { + public: + size_t keyLength() const override { + return 16; + } + + size_t ivLength() const override { + return 12; + } + + void setEncryptedBufferHeadroom(size_t headroom) override { + headroom_ = headroom; + } + + void setKey(TrafficKey trafficKey) override; + + std::unique_ptr encrypt( + std::unique_ptr&& plaintext, + const folly::IOBuf* associatedData, + uint64_t seqNum) const override; + + folly::Optional> tryDecrypt( + std::unique_ptr&& ciphertext, + const folly::IOBuf* associatedData, + uint64_t seqNum) const override; + + size_t getCipherOverhead() const override { + return 16; + } + + std::array createIV(uint64_t seqNum) const; + + private: + size_t headroom_{5}; + TrafficKey key_; +}; + +} // namespace hacl +} // namespace fizz diff --git a/fizz/crypto/experimental/hacl/Hacl_AesGCM_NI.cpp b/fizz/crypto/experimental/hacl/Hacl_AesGCM_NI.cpp new file mode 100644 index 00000000000..aac0ebcf2ae --- /dev/null +++ b/fizz/crypto/experimental/hacl/Hacl_AesGCM_NI.cpp @@ -0,0 +1,683 @@ +/* This file was generated by KreMLin + * KreMLin invocation: /Users/bhargava/Desktop/repositories/kremlin/krml -funroll-loops 8 -warn-error +9 -I /Users/bhargava/Desktop/repositories/hacl-star//lib/ -I /Users/bhargava/Desktop/repositories/hacl-star//lib/fst -I /Users/bhargava/Desktop/repositories/kremlin/kremlib -I /Users/bhargava/Desktop/repositories/hacl-star//specs -I . -I /Users/bhargava/Desktop/repositories/hacl-star//code/experimental/aes -I /Users/bhargava/Desktop/repositories/hacl-star//code/experimental/gf128 -ccopt -march=native -fbuiltin-uint128 -drop FStar.UInt128 -fnocompound-literals -fparentheses -fcurly-braces -tmpdir aesgcm-ni-c aesgcm-ni-c/out.krml -skip-compilation -minimal -add-include "kremlib.h" -add-include "vec128.h" -drop Lib.Vec128 -bundle Hacl.AesGCM.NI=* + * F* version: 518dde40 + * KreMLin version: d94ac163 + */ + +#include "Hacl_AesGCM_NI.h" + +static void Hacl_Impl_Gf128_FieldNI_fadd(Lib_Vec128_vec128 *x, Lib_Vec128_vec128 *y) +{ + x[0U] = Lib_Vec128_vec128_xor(x[0U], y[0U]); +} + +static void Hacl_Impl_Gf128_FieldNI_fmul(Lib_Vec128_vec128 *x, Lib_Vec128_vec128 *y) +{ + Lib_Vec128_vec128 xe = x[0U]; + Lib_Vec128_vec128 ye = y[0U]; + Lib_Vec128_vec128 lo0 = Lib_Vec128_ni_clmul(xe, ye, (uint8_t)0x00U); + Lib_Vec128_vec128 m1 = Lib_Vec128_ni_clmul(xe, ye, (uint8_t)0x10U); + Lib_Vec128_vec128 m2 = Lib_Vec128_ni_clmul(xe, ye, (uint8_t)0x01U); + Lib_Vec128_vec128 hi = Lib_Vec128_ni_clmul(xe, ye, (uint8_t)0x11U); + Lib_Vec128_vec128 m11 = Lib_Vec128_vec128_xor(m1, m2); + Lib_Vec128_vec128 m21 = Lib_Vec128_vec128_shift_left(m11, (uint32_t)64U); + Lib_Vec128_vec128 m12 = Lib_Vec128_vec128_shift_right(m11, (uint32_t)64U); + Lib_Vec128_vec128 lo10 = Lib_Vec128_vec128_xor(lo0, m21); + Lib_Vec128_vec128 hi10 = Lib_Vec128_vec128_xor(hi, m12); + Lib_Vec128_vec128 hi0 = hi10; + Lib_Vec128_vec128 lo = lo10; + Lib_Vec128_vec128 lo1 = Lib_Vec128_vec128_shift_right64(lo, (uint32_t)63U); + Lib_Vec128_vec128 lo2 = Lib_Vec128_vec128_shift_left(lo1, (uint32_t)64U); + Lib_Vec128_vec128 lo3 = Lib_Vec128_vec128_shift_left64(lo, (uint32_t)1U); + Lib_Vec128_vec128 lo31 = Lib_Vec128_vec128_xor(lo3, lo2); + Lib_Vec128_vec128 hi1 = Lib_Vec128_vec128_shift_right64(hi0, (uint32_t)63U); + Lib_Vec128_vec128 hi11 = Lib_Vec128_vec128_shift_left(hi1, (uint32_t)64U); + Lib_Vec128_vec128 hi2 = Lib_Vec128_vec128_shift_left64(hi0, (uint32_t)1U); + Lib_Vec128_vec128 hi21 = Lib_Vec128_vec128_xor(hi2, hi11); + Lib_Vec128_vec128 lo11 = Lib_Vec128_vec128_shift_right64(lo, (uint32_t)63U); + Lib_Vec128_vec128 lo12 = Lib_Vec128_vec128_shift_right(lo11, (uint32_t)64U); + Lib_Vec128_vec128 hi22 = Lib_Vec128_vec128_xor(hi21, lo12); + Lib_Vec128_vec128 lo4 = lo31; + Lib_Vec128_vec128 hi3 = hi22; + Lib_Vec128_vec128 lo13 = Lib_Vec128_vec128_shift_left64(lo4, (uint32_t)63U); + Lib_Vec128_vec128 lo21 = Lib_Vec128_vec128_shift_left64(lo4, (uint32_t)62U); + Lib_Vec128_vec128 lo32 = Lib_Vec128_vec128_shift_left64(lo4, (uint32_t)57U); + Lib_Vec128_vec128 lo14 = Lib_Vec128_vec128_xor(lo13, lo21); + Lib_Vec128_vec128 lo15 = Lib_Vec128_vec128_xor(lo14, lo32); + Lib_Vec128_vec128 lo22 = Lib_Vec128_vec128_shift_right(lo15, (uint32_t)64U); + Lib_Vec128_vec128 lo33 = Lib_Vec128_vec128_shift_left(lo15, (uint32_t)64U); + Lib_Vec128_vec128 lo5 = Lib_Vec128_vec128_xor(lo4, lo33); + Lib_Vec128_vec128 lo_ = lo22; + Lib_Vec128_vec128 lo16 = Lib_Vec128_vec128_shift_right64(lo5, (uint32_t)1U); + Lib_Vec128_vec128 lo23 = Lib_Vec128_vec128_shift_right64(lo5, (uint32_t)2U); + Lib_Vec128_vec128 lo34 = Lib_Vec128_vec128_shift_right64(lo5, (uint32_t)7U); + Lib_Vec128_vec128 lo17 = Lib_Vec128_vec128_xor(lo16, lo23); + Lib_Vec128_vec128 lo18 = Lib_Vec128_vec128_xor(lo17, lo34); + Lib_Vec128_vec128 lo19 = Lib_Vec128_vec128_xor(lo18, lo_); + Lib_Vec128_vec128 lo6 = Lib_Vec128_vec128_xor(lo5, lo19); + Lib_Vec128_vec128 lo7 = Lib_Vec128_vec128_xor(lo6, hi3); + Lib_Vec128_vec128 lo110 = lo7; + x[0U] = lo110; +} + +static void Hacl_Impl_Gf128_FieldNI_load_precompute_r(Lib_Vec128_vec128 *pre, uint8_t *key) +{ + Lib_Vec128_vec128 *r_4 = pre; + Lib_Vec128_vec128 *r_3 = pre + (uint32_t)1U; + Lib_Vec128_vec128 *r_2 = pre + (uint32_t)2U; + Lib_Vec128_vec128 *r = pre + (uint32_t)3U; + r[0U] = Lib_Vec128_vec128_load_be(key); + pre[0U] = r[0U]; + pre[1U] = r[0U]; + pre[2U] = r[0U]; + Hacl_Impl_Gf128_FieldNI_fmul(r_2, r); + Hacl_Impl_Gf128_FieldNI_fmul(r_3, r_2); + Hacl_Impl_Gf128_FieldNI_fmul(r_4, r_3); +} + +static void +Hacl_Impl_Gf128_FieldNI_fadd_mul4( + Lib_Vec128_vec128 *acc, + Lib_Vec128_vec128 *x, + Lib_Vec128_vec128 *pre +) +{ + Lib_Vec128_vec128 x1 = x[0U]; + Lib_Vec128_vec128 x2 = x[1U]; + Lib_Vec128_vec128 x3 = x[2U]; + Lib_Vec128_vec128 x4 = x[3U]; + Lib_Vec128_vec128 y1 = pre[0U]; + Lib_Vec128_vec128 y2 = pre[1U]; + Lib_Vec128_vec128 y3 = pre[2U]; + Lib_Vec128_vec128 y4 = pre[3U]; + Lib_Vec128_vec128 acc0 = acc[0U]; + Lib_Vec128_vec128 acc01 = Lib_Vec128_vec128_xor(acc0, x1); + Lib_Vec128_vec128 lo10 = Lib_Vec128_ni_clmul(acc01, y1, (uint8_t)0x00U); + Lib_Vec128_vec128 lo2 = Lib_Vec128_ni_clmul(x2, y2, (uint8_t)0x00U); + Lib_Vec128_vec128 lo30 = Lib_Vec128_ni_clmul(x3, y3, (uint8_t)0x00U); + Lib_Vec128_vec128 lo40 = Lib_Vec128_ni_clmul(x4, y4, (uint8_t)0x00U); + Lib_Vec128_vec128 lo0 = Lib_Vec128_vec128_xor(lo10, lo2); + Lib_Vec128_vec128 lo5 = Lib_Vec128_vec128_xor(lo0, lo30); + Lib_Vec128_vec128 lo6 = Lib_Vec128_vec128_xor(lo5, lo40); + Lib_Vec128_vec128 m1 = Lib_Vec128_ni_clmul(acc01, y1, (uint8_t)0x10U); + Lib_Vec128_vec128 m2 = Lib_Vec128_ni_clmul(x2, y2, (uint8_t)0x10U); + Lib_Vec128_vec128 m3 = Lib_Vec128_ni_clmul(x3, y3, (uint8_t)0x10U); + Lib_Vec128_vec128 m4 = Lib_Vec128_ni_clmul(x4, y4, (uint8_t)0x10U); + Lib_Vec128_vec128 m = Lib_Vec128_vec128_xor(m1, m2); + Lib_Vec128_vec128 m5 = Lib_Vec128_vec128_xor(m, m3); + Lib_Vec128_vec128 m6 = Lib_Vec128_vec128_xor(m5, m4); + Lib_Vec128_vec128 m11 = Lib_Vec128_ni_clmul(acc01, y1, (uint8_t)0x01U); + Lib_Vec128_vec128 m21 = Lib_Vec128_ni_clmul(x2, y2, (uint8_t)0x01U); + Lib_Vec128_vec128 m31 = Lib_Vec128_ni_clmul(x3, y3, (uint8_t)0x01U); + Lib_Vec128_vec128 m41 = Lib_Vec128_ni_clmul(x4, y4, (uint8_t)0x01U); + Lib_Vec128_vec128 m7 = Lib_Vec128_vec128_xor(m6, m11); + Lib_Vec128_vec128 m8 = Lib_Vec128_vec128_xor(m7, m21); + Lib_Vec128_vec128 m9 = Lib_Vec128_vec128_xor(m8, m31); + Lib_Vec128_vec128 m10 = Lib_Vec128_vec128_xor(m9, m41); + Lib_Vec128_vec128 hi10 = Lib_Vec128_ni_clmul(acc01, y1, (uint8_t)0x11U); + Lib_Vec128_vec128 hi20 = Lib_Vec128_ni_clmul(x2, y2, (uint8_t)0x11U); + Lib_Vec128_vec128 hi30 = Lib_Vec128_ni_clmul(x3, y3, (uint8_t)0x11U); + Lib_Vec128_vec128 hi4 = Lib_Vec128_ni_clmul(x4, y4, (uint8_t)0x11U); + Lib_Vec128_vec128 hi = Lib_Vec128_vec128_xor(hi10, hi20); + Lib_Vec128_vec128 hi5 = Lib_Vec128_vec128_xor(hi, hi30); + Lib_Vec128_vec128 hi6 = Lib_Vec128_vec128_xor(hi5, hi4); + Lib_Vec128_vec128 m12 = Lib_Vec128_vec128_shift_left(m10, (uint32_t)64U); + Lib_Vec128_vec128 m22 = Lib_Vec128_vec128_shift_right(m10, (uint32_t)64U); + Lib_Vec128_vec128 lo7 = Lib_Vec128_vec128_xor(lo6, m12); + Lib_Vec128_vec128 hi7 = Lib_Vec128_vec128_xor(hi6, m22); + Lib_Vec128_vec128 hi0 = hi7; + Lib_Vec128_vec128 lo = lo7; + Lib_Vec128_vec128 lo1 = Lib_Vec128_vec128_shift_right64(lo, (uint32_t)63U); + Lib_Vec128_vec128 lo20 = Lib_Vec128_vec128_shift_left(lo1, (uint32_t)64U); + Lib_Vec128_vec128 lo3 = Lib_Vec128_vec128_shift_left64(lo, (uint32_t)1U); + Lib_Vec128_vec128 lo31 = Lib_Vec128_vec128_xor(lo3, lo20); + Lib_Vec128_vec128 hi1 = Lib_Vec128_vec128_shift_right64(hi0, (uint32_t)63U); + Lib_Vec128_vec128 hi11 = Lib_Vec128_vec128_shift_left(hi1, (uint32_t)64U); + Lib_Vec128_vec128 hi2 = Lib_Vec128_vec128_shift_left64(hi0, (uint32_t)1U); + Lib_Vec128_vec128 hi21 = Lib_Vec128_vec128_xor(hi2, hi11); + Lib_Vec128_vec128 lo11 = Lib_Vec128_vec128_shift_right64(lo, (uint32_t)63U); + Lib_Vec128_vec128 lo12 = Lib_Vec128_vec128_shift_right(lo11, (uint32_t)64U); + Lib_Vec128_vec128 hi22 = Lib_Vec128_vec128_xor(hi21, lo12); + Lib_Vec128_vec128 lo4 = lo31; + Lib_Vec128_vec128 hi3 = hi22; + Lib_Vec128_vec128 lo13 = Lib_Vec128_vec128_shift_left64(lo4, (uint32_t)63U); + Lib_Vec128_vec128 lo21 = Lib_Vec128_vec128_shift_left64(lo4, (uint32_t)62U); + Lib_Vec128_vec128 lo32 = Lib_Vec128_vec128_shift_left64(lo4, (uint32_t)57U); + Lib_Vec128_vec128 lo14 = Lib_Vec128_vec128_xor(lo13, lo21); + Lib_Vec128_vec128 lo15 = Lib_Vec128_vec128_xor(lo14, lo32); + Lib_Vec128_vec128 lo22 = Lib_Vec128_vec128_shift_right(lo15, (uint32_t)64U); + Lib_Vec128_vec128 lo33 = Lib_Vec128_vec128_shift_left(lo15, (uint32_t)64U); + Lib_Vec128_vec128 lo50 = Lib_Vec128_vec128_xor(lo4, lo33); + Lib_Vec128_vec128 lo_ = lo22; + Lib_Vec128_vec128 lo16 = Lib_Vec128_vec128_shift_right64(lo50, (uint32_t)1U); + Lib_Vec128_vec128 lo23 = Lib_Vec128_vec128_shift_right64(lo50, (uint32_t)2U); + Lib_Vec128_vec128 lo34 = Lib_Vec128_vec128_shift_right64(lo50, (uint32_t)7U); + Lib_Vec128_vec128 lo17 = Lib_Vec128_vec128_xor(lo16, lo23); + Lib_Vec128_vec128 lo18 = Lib_Vec128_vec128_xor(lo17, lo34); + Lib_Vec128_vec128 lo19 = Lib_Vec128_vec128_xor(lo18, lo_); + Lib_Vec128_vec128 lo60 = Lib_Vec128_vec128_xor(lo50, lo19); + Lib_Vec128_vec128 lo70 = Lib_Vec128_vec128_xor(lo60, hi3); + Lib_Vec128_vec128 lo110 = lo70; + acc[0U] = lo110; +} + +static void Hacl_Gf128_NI_gcm_init(Lib_Vec128_vec128 *ctx, uint8_t *key) +{ + Lib_Vec128_vec128 *acc = ctx; + Lib_Vec128_vec128 *pre = ctx + (uint32_t)1U; + acc[0U] = Lib_Vec128_vec128_zero; + Hacl_Impl_Gf128_FieldNI_load_precompute_r(pre, key); +} + +static void +Hacl_Gf128_NI_gcm_update_blocks(Lib_Vec128_vec128 *ctx, uint32_t len, uint8_t *text) +{ + Lib_Vec128_vec128 *acc = ctx; + Lib_Vec128_vec128 *pre = ctx + (uint32_t)1U; + Lib_Vec128_vec128 b4[4U]; + for (uint32_t _i = 0U; _i < (uint32_t)4U; ++_i) + b4[_i] = Lib_Vec128_vec128_zero; + uint32_t blocks = len / (uint32_t)64U; + for (uint32_t i = (uint32_t)0U; i < blocks; i = i + (uint32_t)1U) + { + uint8_t *uu____0 = text + i * (uint32_t)64U; + b4[0U] = Lib_Vec128_vec128_load_be(uu____0); + b4[1U] = Lib_Vec128_vec128_load_be(uu____0 + (uint32_t)16U); + b4[2U] = Lib_Vec128_vec128_load_be(uu____0 + (uint32_t)32U); + b4[3U] = Lib_Vec128_vec128_load_be(uu____0 + (uint32_t)48U); + Hacl_Impl_Gf128_FieldNI_fadd_mul4(acc, b4, pre); + } + uint32_t rem1 = len % (uint32_t)64U; + uint8_t *last1 = text + blocks * (uint32_t)64U; + Lib_Vec128_vec128 *acc1 = ctx; + Lib_Vec128_vec128 *r = ctx + (uint32_t)4U; + uint32_t blocks1 = rem1 / (uint32_t)16U; + for (uint32_t i = (uint32_t)0U; i < blocks1; i = i + (uint32_t)1U) + { + uint8_t *uu____1 = last1 + i * (uint32_t)16U; + Lib_Vec128_vec128 elem = Lib_Vec128_vec128_zero; + elem = Lib_Vec128_vec128_load_be(uu____1); + Hacl_Impl_Gf128_FieldNI_fadd(acc1, &elem); + Hacl_Impl_Gf128_FieldNI_fmul(acc1, r); + } + uint32_t rem2 = rem1 % (uint32_t)16U; + if (rem2 > (uint32_t)0U) + { + uint8_t *last2 = last1 + blocks1 * (uint32_t)16U; + Lib_Vec128_vec128 elem = Lib_Vec128_vec128_zero; + uint8_t b[16U] = { 0U }; + memcpy(b, last2, rem2 * sizeof last2[0U]); + elem = Lib_Vec128_vec128_load_be(b); + Hacl_Impl_Gf128_FieldNI_fadd(acc1, &elem); + Hacl_Impl_Gf128_FieldNI_fmul(acc1, r); + } +} + +static void +Hacl_Gf128_NI_gcm_update_padded(Lib_Vec128_vec128 *ctx, uint32_t len, uint8_t *text) +{ + Lib_Vec128_vec128 *acc = ctx; + Lib_Vec128_vec128 *pre = ctx + (uint32_t)1U; + Lib_Vec128_vec128 b4[4U]; + for (uint32_t _i = 0U; _i < (uint32_t)4U; ++_i) + b4[_i] = Lib_Vec128_vec128_zero; + uint32_t blocks = len / (uint32_t)64U; + for (uint32_t i = (uint32_t)0U; i < blocks; i = i + (uint32_t)1U) + { + uint8_t *uu____0 = text + i * (uint32_t)64U; + b4[0U] = Lib_Vec128_vec128_load_be(uu____0); + b4[1U] = Lib_Vec128_vec128_load_be(uu____0 + (uint32_t)16U); + b4[2U] = Lib_Vec128_vec128_load_be(uu____0 + (uint32_t)32U); + b4[3U] = Lib_Vec128_vec128_load_be(uu____0 + (uint32_t)48U); + Hacl_Impl_Gf128_FieldNI_fadd_mul4(acc, b4, pre); + } + uint32_t rem1 = len % (uint32_t)64U; + uint8_t *last1 = text + blocks * (uint32_t)64U; + Lib_Vec128_vec128 *acc1 = ctx; + Lib_Vec128_vec128 *r = ctx + (uint32_t)4U; + uint32_t blocks1 = rem1 / (uint32_t)16U; + for (uint32_t i = (uint32_t)0U; i < blocks1; i = i + (uint32_t)1U) + { + uint8_t *uu____1 = last1 + i * (uint32_t)16U; + Lib_Vec128_vec128 elem = Lib_Vec128_vec128_zero; + elem = Lib_Vec128_vec128_load_be(uu____1); + Hacl_Impl_Gf128_FieldNI_fadd(acc1, &elem); + Hacl_Impl_Gf128_FieldNI_fmul(acc1, r); + } + uint32_t rem2 = rem1 % (uint32_t)16U; + if (rem2 > (uint32_t)0U) + { + uint8_t *last2 = last1 + blocks1 * (uint32_t)16U; + Lib_Vec128_vec128 elem = Lib_Vec128_vec128_zero; + uint8_t b[16U] = { 0U }; + memcpy(b, last2, rem2 * sizeof last2[0U]); + elem = Lib_Vec128_vec128_load_be(b); + Hacl_Impl_Gf128_FieldNI_fadd(acc1, &elem); + Hacl_Impl_Gf128_FieldNI_fmul(acc1, r); + } +} + +static void Hacl_Gf128_NI_gcm_emit(uint8_t *tag, Lib_Vec128_vec128 *ctx) +{ + Lib_Vec128_vec128 *acc = ctx; + Lib_Vec128_vec128_store_be(tag, acc[0U]); +} + +inline static void +Hacl_Aes_NI_aes128_init(Lib_Vec128_vec128 *ctx, uint8_t *key, uint8_t *nonce) +{ + Lib_Vec128_vec128 *kex = ctx + (uint32_t)1U; + Lib_Vec128_vec128 *n1 = ctx; + uint32_t klen1 = (uint32_t)1U; + Lib_Vec128_vec128 *uu____0 = kex; + uu____0[0U] = Lib_Vec128_vec128_load_le(key); + Lib_Vec128_vec128 *prev = kex; + Lib_Vec128_vec128 *next = kex + klen1; + next[0U] = Lib_Vec128_ni_aes_keygen_assist(prev[0U], (uint8_t)0x01U); + Lib_Vec128_vec128 n00 = next[0U]; + next[0U] = + Lib_Vec128_vec128_shuffle32(n00, + Lib_Vec128_vec128_shuffle32_spec((uint8_t)3U, (uint8_t)3U, (uint8_t)3U, (uint8_t)3U)); + Lib_Vec128_vec128 key1 = prev[0U]; + Lib_Vec128_vec128 + key2 = Lib_Vec128_vec128_xor(key1, Lib_Vec128_vec128_shift_left(key1, (uint32_t)32U)); + Lib_Vec128_vec128 + key3 = Lib_Vec128_vec128_xor(key2, Lib_Vec128_vec128_shift_left(key2, (uint32_t)32U)); + Lib_Vec128_vec128 + key4 = Lib_Vec128_vec128_xor(key3, Lib_Vec128_vec128_shift_left(key3, (uint32_t)32U)); + next[0U] = Lib_Vec128_vec128_xor(next[0U], key4); + Lib_Vec128_vec128 *prev1 = kex + klen1; + Lib_Vec128_vec128 *next1 = kex + (uint32_t)2U * klen1; + next1[0U] = Lib_Vec128_ni_aes_keygen_assist(prev1[0U], (uint8_t)0x02U); + Lib_Vec128_vec128 n01 = next1[0U]; + next1[0U] = + Lib_Vec128_vec128_shuffle32(n01, + Lib_Vec128_vec128_shuffle32_spec((uint8_t)3U, (uint8_t)3U, (uint8_t)3U, (uint8_t)3U)); + Lib_Vec128_vec128 key10 = prev1[0U]; + Lib_Vec128_vec128 + key20 = Lib_Vec128_vec128_xor(key10, Lib_Vec128_vec128_shift_left(key10, (uint32_t)32U)); + Lib_Vec128_vec128 + key30 = Lib_Vec128_vec128_xor(key20, Lib_Vec128_vec128_shift_left(key20, (uint32_t)32U)); + Lib_Vec128_vec128 + key40 = Lib_Vec128_vec128_xor(key30, Lib_Vec128_vec128_shift_left(key30, (uint32_t)32U)); + next1[0U] = Lib_Vec128_vec128_xor(next1[0U], key40); + Lib_Vec128_vec128 *prev2 = kex + klen1 * (uint32_t)2U; + Lib_Vec128_vec128 *next2 = kex + klen1 * (uint32_t)3U; + next2[0U] = Lib_Vec128_ni_aes_keygen_assist(prev2[0U], (uint8_t)0x04U); + Lib_Vec128_vec128 n02 = next2[0U]; + next2[0U] = + Lib_Vec128_vec128_shuffle32(n02, + Lib_Vec128_vec128_shuffle32_spec((uint8_t)3U, (uint8_t)3U, (uint8_t)3U, (uint8_t)3U)); + Lib_Vec128_vec128 key11 = prev2[0U]; + Lib_Vec128_vec128 + key21 = Lib_Vec128_vec128_xor(key11, Lib_Vec128_vec128_shift_left(key11, (uint32_t)32U)); + Lib_Vec128_vec128 + key31 = Lib_Vec128_vec128_xor(key21, Lib_Vec128_vec128_shift_left(key21, (uint32_t)32U)); + Lib_Vec128_vec128 + key41 = Lib_Vec128_vec128_xor(key31, Lib_Vec128_vec128_shift_left(key31, (uint32_t)32U)); + next2[0U] = Lib_Vec128_vec128_xor(next2[0U], key41); + Lib_Vec128_vec128 *prev3 = kex + klen1 * (uint32_t)3U; + Lib_Vec128_vec128 *next3 = kex + klen1 * (uint32_t)4U; + next3[0U] = Lib_Vec128_ni_aes_keygen_assist(prev3[0U], (uint8_t)0x08U); + Lib_Vec128_vec128 n03 = next3[0U]; + next3[0U] = + Lib_Vec128_vec128_shuffle32(n03, + Lib_Vec128_vec128_shuffle32_spec((uint8_t)3U, (uint8_t)3U, (uint8_t)3U, (uint8_t)3U)); + Lib_Vec128_vec128 key12 = prev3[0U]; + Lib_Vec128_vec128 + key22 = Lib_Vec128_vec128_xor(key12, Lib_Vec128_vec128_shift_left(key12, (uint32_t)32U)); + Lib_Vec128_vec128 + key32 = Lib_Vec128_vec128_xor(key22, Lib_Vec128_vec128_shift_left(key22, (uint32_t)32U)); + Lib_Vec128_vec128 + key42 = Lib_Vec128_vec128_xor(key32, Lib_Vec128_vec128_shift_left(key32, (uint32_t)32U)); + next3[0U] = Lib_Vec128_vec128_xor(next3[0U], key42); + Lib_Vec128_vec128 *prev4 = kex + klen1 * (uint32_t)4U; + Lib_Vec128_vec128 *next4 = kex + klen1 * (uint32_t)5U; + next4[0U] = Lib_Vec128_ni_aes_keygen_assist(prev4[0U], (uint8_t)0x10U); + Lib_Vec128_vec128 n04 = next4[0U]; + next4[0U] = + Lib_Vec128_vec128_shuffle32(n04, + Lib_Vec128_vec128_shuffle32_spec((uint8_t)3U, (uint8_t)3U, (uint8_t)3U, (uint8_t)3U)); + Lib_Vec128_vec128 key13 = prev4[0U]; + Lib_Vec128_vec128 + key23 = Lib_Vec128_vec128_xor(key13, Lib_Vec128_vec128_shift_left(key13, (uint32_t)32U)); + Lib_Vec128_vec128 + key33 = Lib_Vec128_vec128_xor(key23, Lib_Vec128_vec128_shift_left(key23, (uint32_t)32U)); + Lib_Vec128_vec128 + key43 = Lib_Vec128_vec128_xor(key33, Lib_Vec128_vec128_shift_left(key33, (uint32_t)32U)); + next4[0U] = Lib_Vec128_vec128_xor(next4[0U], key43); + Lib_Vec128_vec128 *prev5 = kex + klen1 * (uint32_t)5U; + Lib_Vec128_vec128 *next5 = kex + klen1 * (uint32_t)6U; + next5[0U] = Lib_Vec128_ni_aes_keygen_assist(prev5[0U], (uint8_t)0x20U); + Lib_Vec128_vec128 n05 = next5[0U]; + next5[0U] = + Lib_Vec128_vec128_shuffle32(n05, + Lib_Vec128_vec128_shuffle32_spec((uint8_t)3U, (uint8_t)3U, (uint8_t)3U, (uint8_t)3U)); + Lib_Vec128_vec128 key14 = prev5[0U]; + Lib_Vec128_vec128 + key24 = Lib_Vec128_vec128_xor(key14, Lib_Vec128_vec128_shift_left(key14, (uint32_t)32U)); + Lib_Vec128_vec128 + key34 = Lib_Vec128_vec128_xor(key24, Lib_Vec128_vec128_shift_left(key24, (uint32_t)32U)); + Lib_Vec128_vec128 + key44 = Lib_Vec128_vec128_xor(key34, Lib_Vec128_vec128_shift_left(key34, (uint32_t)32U)); + next5[0U] = Lib_Vec128_vec128_xor(next5[0U], key44); + Lib_Vec128_vec128 *prev6 = kex + klen1 * (uint32_t)6U; + Lib_Vec128_vec128 *next6 = kex + klen1 * (uint32_t)7U; + next6[0U] = Lib_Vec128_ni_aes_keygen_assist(prev6[0U], (uint8_t)0x40U); + Lib_Vec128_vec128 n06 = next6[0U]; + next6[0U] = + Lib_Vec128_vec128_shuffle32(n06, + Lib_Vec128_vec128_shuffle32_spec((uint8_t)3U, (uint8_t)3U, (uint8_t)3U, (uint8_t)3U)); + Lib_Vec128_vec128 key15 = prev6[0U]; + Lib_Vec128_vec128 + key25 = Lib_Vec128_vec128_xor(key15, Lib_Vec128_vec128_shift_left(key15, (uint32_t)32U)); + Lib_Vec128_vec128 + key35 = Lib_Vec128_vec128_xor(key25, Lib_Vec128_vec128_shift_left(key25, (uint32_t)32U)); + Lib_Vec128_vec128 + key45 = Lib_Vec128_vec128_xor(key35, Lib_Vec128_vec128_shift_left(key35, (uint32_t)32U)); + next6[0U] = Lib_Vec128_vec128_xor(next6[0U], key45); + Lib_Vec128_vec128 *prev7 = kex + klen1 * (uint32_t)7U; + Lib_Vec128_vec128 *next7 = kex + klen1 * (uint32_t)8U; + next7[0U] = Lib_Vec128_ni_aes_keygen_assist(prev7[0U], (uint8_t)0x80U); + Lib_Vec128_vec128 n07 = next7[0U]; + next7[0U] = + Lib_Vec128_vec128_shuffle32(n07, + Lib_Vec128_vec128_shuffle32_spec((uint8_t)3U, (uint8_t)3U, (uint8_t)3U, (uint8_t)3U)); + Lib_Vec128_vec128 key16 = prev7[0U]; + Lib_Vec128_vec128 + key26 = Lib_Vec128_vec128_xor(key16, Lib_Vec128_vec128_shift_left(key16, (uint32_t)32U)); + Lib_Vec128_vec128 + key36 = Lib_Vec128_vec128_xor(key26, Lib_Vec128_vec128_shift_left(key26, (uint32_t)32U)); + Lib_Vec128_vec128 + key46 = Lib_Vec128_vec128_xor(key36, Lib_Vec128_vec128_shift_left(key36, (uint32_t)32U)); + next7[0U] = Lib_Vec128_vec128_xor(next7[0U], key46); + Lib_Vec128_vec128 *prev8 = kex + klen1 * (uint32_t)8U; + Lib_Vec128_vec128 *next8 = kex + klen1 * (uint32_t)9U; + next8[0U] = Lib_Vec128_ni_aes_keygen_assist(prev8[0U], (uint8_t)0x1bU); + Lib_Vec128_vec128 n08 = next8[0U]; + next8[0U] = + Lib_Vec128_vec128_shuffle32(n08, + Lib_Vec128_vec128_shuffle32_spec((uint8_t)3U, (uint8_t)3U, (uint8_t)3U, (uint8_t)3U)); + Lib_Vec128_vec128 key17 = prev8[0U]; + Lib_Vec128_vec128 + key27 = Lib_Vec128_vec128_xor(key17, Lib_Vec128_vec128_shift_left(key17, (uint32_t)32U)); + Lib_Vec128_vec128 + key37 = Lib_Vec128_vec128_xor(key27, Lib_Vec128_vec128_shift_left(key27, (uint32_t)32U)); + Lib_Vec128_vec128 + key47 = Lib_Vec128_vec128_xor(key37, Lib_Vec128_vec128_shift_left(key37, (uint32_t)32U)); + next8[0U] = Lib_Vec128_vec128_xor(next8[0U], key47); + Lib_Vec128_vec128 *prev9 = kex + klen1 * (uint32_t)9U; + Lib_Vec128_vec128 *next9 = kex + klen1 * (uint32_t)10U; + next9[0U] = Lib_Vec128_ni_aes_keygen_assist(prev9[0U], (uint8_t)0x36U); + Lib_Vec128_vec128 n0 = next9[0U]; + next9[0U] = + Lib_Vec128_vec128_shuffle32(n0, + Lib_Vec128_vec128_shuffle32_spec((uint8_t)3U, (uint8_t)3U, (uint8_t)3U, (uint8_t)3U)); + Lib_Vec128_vec128 key18 = prev9[0U]; + Lib_Vec128_vec128 + key28 = Lib_Vec128_vec128_xor(key18, Lib_Vec128_vec128_shift_left(key18, (uint32_t)32U)); + Lib_Vec128_vec128 + key38 = Lib_Vec128_vec128_xor(key28, Lib_Vec128_vec128_shift_left(key28, (uint32_t)32U)); + Lib_Vec128_vec128 + key48 = Lib_Vec128_vec128_xor(key38, Lib_Vec128_vec128_shift_left(key38, (uint32_t)32U)); + next9[0U] = Lib_Vec128_vec128_xor(next9[0U], key48); + uint8_t nb1[16U] = { 0U }; + memcpy(nb1, nonce, (uint32_t)12U * sizeof nonce[0U]); + n1[0U] = Lib_Vec128_vec128_load_le(nb1); +} + +inline static void Hacl_Aes_NI_aes128_set_nonce(Lib_Vec128_vec128 *ctx, uint8_t *nonce) +{ + Lib_Vec128_vec128 *n1 = ctx; + uint8_t nb1[16U] = { 0U }; + memcpy(nb1, nonce, (uint32_t)12U * sizeof nonce[0U]); + n1[0U] = Lib_Vec128_vec128_load_le(nb1); +} + +inline static void +Hacl_Aes_NI_aes128_key_block(uint8_t *kb, Lib_Vec128_vec128 *ctx, uint32_t counter) +{ + Lib_Vec128_vec128 *kex = ctx + (uint32_t)1U; + Lib_Vec128_vec128 *n1 = ctx; + + Lib_Vec128_vec128 st[4U]; + for (uint32_t _i = 0U; _i < (uint32_t)4U; ++_i) + st[_i] = Lib_Vec128_vec128_zero; + uint32_t counter0 = htobe32(counter); + uint32_t counter1 = htobe32(counter + (uint32_t)1U); + uint32_t counter2 = htobe32(counter + (uint32_t)2U); + uint32_t counter3 = htobe32(counter + (uint32_t)3U); + st[0U] = Lib_Vec128_vec128_insert32(n1[0U], counter0, (uint8_t)3U); + st[1U] = Lib_Vec128_vec128_insert32(n1[0U], counter1, (uint8_t)3U); + st[2U] = Lib_Vec128_vec128_insert32(n1[0U], counter2, (uint8_t)3U); + st[3U] = Lib_Vec128_vec128_insert32(n1[0U], counter3, (uint8_t)3U); + uint32_t klen1 = (uint32_t)1U; + Lib_Vec128_vec128 *k0 = kex; + Lib_Vec128_vec128 *kr = kex + klen1; + Lib_Vec128_vec128 *kn = kex + (uint32_t)10U * klen1; + st[0U] = Lib_Vec128_vec128_xor(st[0U], k0[0U]); + st[1U] = Lib_Vec128_vec128_xor(st[1U], k0[0U]); + st[2U] = Lib_Vec128_vec128_xor(st[2U], k0[0U]); + st[3U] = Lib_Vec128_vec128_xor(st[3U], k0[0U]); + for (uint32_t i = (uint32_t)0U; i < (uint32_t)10U - (uint32_t)1U; i = i + (uint32_t)1U) + { + Lib_Vec128_vec128 *sub_key = kr + i * (uint32_t)1U; + st[0U] = Lib_Vec128_ni_aes_enc(st[0U], sub_key[0U]); + st[1U] = Lib_Vec128_ni_aes_enc(st[1U], sub_key[0U]); + st[2U] = Lib_Vec128_ni_aes_enc(st[2U], sub_key[0U]); + st[3U] = Lib_Vec128_ni_aes_enc(st[3U], sub_key[0U]); + } + st[0U] = Lib_Vec128_ni_aes_enc_last(st[0U], kn[0U]); + st[1U] = Lib_Vec128_ni_aes_enc_last(st[1U], kn[0U]); + st[2U] = Lib_Vec128_ni_aes_enc_last(st[2U], kn[0U]); + st[3U] = Lib_Vec128_ni_aes_enc_last(st[3U], kn[0U]); + Lib_Vec128_vec128_store_le(kb, st[0U]); +} + +inline static void +Hacl_Aes_NI_aes128_ctr( + uint32_t len, + uint8_t *out, + uint8_t *inp, + Lib_Vec128_vec128 *ctx, + uint32_t counter +) +{ + uint32_t blocks64 = len / (uint32_t)64U; + for (uint32_t i = (uint32_t)0U; i < blocks64; i = i + (uint32_t)1U) + { + uint32_t ctr = counter + i * (uint32_t)4U; + uint8_t *ib = inp + i * (uint32_t)64U; + uint8_t *ob = out + i * (uint32_t)64U; + Lib_Vec128_vec128 st[4U]; + for (uint32_t _i = 0U; _i < (uint32_t)4U; ++_i) + st[_i] = Lib_Vec128_vec128_zero; + Lib_Vec128_vec128 *kex = ctx + (uint32_t)1U; + Lib_Vec128_vec128 *n1 = ctx; + uint32_t counter0 = htobe32(ctr); + uint32_t counter1 = htobe32(ctr + (uint32_t)1U); + uint32_t counter2 = htobe32(ctr + (uint32_t)2U); + uint32_t counter3 = htobe32(ctr + (uint32_t)3U); + st[0U] = Lib_Vec128_vec128_insert32(n1[0U], counter0, (uint8_t)3U); + st[1U] = Lib_Vec128_vec128_insert32(n1[0U], counter1, (uint8_t)3U); + st[2U] = Lib_Vec128_vec128_insert32(n1[0U], counter2, (uint8_t)3U); + st[3U] = Lib_Vec128_vec128_insert32(n1[0U], counter3, (uint8_t)3U); + uint32_t klen1 = (uint32_t)1U; + Lib_Vec128_vec128 *k0 = kex; + Lib_Vec128_vec128 *kr = kex + klen1; + Lib_Vec128_vec128 *kn = kex + (uint32_t)10U * klen1; + st[0U] = Lib_Vec128_vec128_xor(st[0U], k0[0U]); + st[1U] = Lib_Vec128_vec128_xor(st[1U], k0[0U]); + st[2U] = Lib_Vec128_vec128_xor(st[2U], k0[0U]); + st[3U] = Lib_Vec128_vec128_xor(st[3U], k0[0U]); + for (uint32_t i = (uint32_t)0U; i < (uint32_t)10U - (uint32_t)1U; i = i + (uint32_t)1U) + { + Lib_Vec128_vec128 *sub_key = kr + i * (uint32_t)1U; + st[0U] = Lib_Vec128_ni_aes_enc(st[0U], sub_key[0U]); + st[1U] = Lib_Vec128_ni_aes_enc(st[1U], sub_key[0U]); + st[2U] = Lib_Vec128_ni_aes_enc(st[2U], sub_key[0U]); + st[3U] = Lib_Vec128_ni_aes_enc(st[3U], sub_key[0U]); + } + st[0U] = Lib_Vec128_ni_aes_enc_last(st[0U], kn[0U]); + st[1U] = Lib_Vec128_ni_aes_enc_last(st[1U], kn[0U]); + st[2U] = Lib_Vec128_ni_aes_enc_last(st[2U], kn[0U]); + st[3U] = Lib_Vec128_ni_aes_enc_last(st[3U], kn[0U]); + Lib_Vec128_vec128 v0 = Lib_Vec128_vec128_load_le(ib); + Lib_Vec128_vec128 v1 = Lib_Vec128_vec128_load_le(ib + (uint32_t)16U); + Lib_Vec128_vec128 v2 = Lib_Vec128_vec128_load_le(ib + (uint32_t)32U); + Lib_Vec128_vec128 v3 = Lib_Vec128_vec128_load_le(ib + (uint32_t)48U); + Lib_Vec128_vec128 v01 = Lib_Vec128_vec128_xor(v0, st[0U]); + Lib_Vec128_vec128 v11 = Lib_Vec128_vec128_xor(v1, st[1U]); + Lib_Vec128_vec128 v21 = Lib_Vec128_vec128_xor(v2, st[2U]); + Lib_Vec128_vec128 v31 = Lib_Vec128_vec128_xor(v3, st[3U]); + Lib_Vec128_vec128_store_le(ob, v01); + Lib_Vec128_vec128_store_le(ob + (uint32_t)16U, v11); + Lib_Vec128_vec128_store_le(ob + (uint32_t)32U, v21); + Lib_Vec128_vec128_store_le(ob + (uint32_t)48U, v31); + } + uint32_t rem1 = len % (uint32_t)64U; + uint8_t last1[64U]; + if (rem1 > (uint32_t)0U) + { + uint32_t ctr = counter + blocks64 * (uint32_t)4U; + uint8_t *ib = inp + blocks64 * (uint32_t)64U; + uint8_t *ob = out + blocks64 * (uint32_t)64U; + uint8_t init = (uint8_t)0U; + for (uint32_t i = (uint32_t)0U; i < (uint32_t)64U; i = i + (uint32_t)1U) + { + last1[i] = init; + } + memcpy(last1, ib, rem1 * sizeof ib[0U]); + Lib_Vec128_vec128 st[4U]; + for (uint32_t _i = 0U; _i < (uint32_t)4U; ++_i) + st[_i] = Lib_Vec128_vec128_zero; + Lib_Vec128_vec128 *kex = ctx + (uint32_t)1U; + Lib_Vec128_vec128 *n1 = ctx; + uint32_t counter0 = htobe32(ctr); + uint32_t counter1 = htobe32(ctr + (uint32_t)1U); + uint32_t counter2 = htobe32(ctr + (uint32_t)2U); + uint32_t counter3 = htobe32(ctr + (uint32_t)3U); + st[0U] = Lib_Vec128_vec128_insert32(n1[0U], counter0, (uint8_t)3U); + st[1U] = Lib_Vec128_vec128_insert32(n1[0U], counter1, (uint8_t)3U); + st[2U] = Lib_Vec128_vec128_insert32(n1[0U], counter2, (uint8_t)3U); + st[3U] = Lib_Vec128_vec128_insert32(n1[0U], counter3, (uint8_t)3U); + uint32_t klen1 = (uint32_t)1U; + Lib_Vec128_vec128 *k0 = kex; + Lib_Vec128_vec128 *kr = kex + klen1; + Lib_Vec128_vec128 *kn = kex + (uint32_t)10U * klen1; + st[0U] = Lib_Vec128_vec128_xor(st[0U], k0[0U]); + st[1U] = Lib_Vec128_vec128_xor(st[1U], k0[0U]); + st[2U] = Lib_Vec128_vec128_xor(st[2U], k0[0U]); + st[3U] = Lib_Vec128_vec128_xor(st[3U], k0[0U]); + for (uint32_t i = (uint32_t)0U; i < (uint32_t)10U - (uint32_t)1U; i = i + (uint32_t)1U) + { + Lib_Vec128_vec128 *sub_key = kr + i * (uint32_t)1U; + st[0U] = Lib_Vec128_ni_aes_enc(st[0U], sub_key[0U]); + st[1U] = Lib_Vec128_ni_aes_enc(st[1U], sub_key[0U]); + st[2U] = Lib_Vec128_ni_aes_enc(st[2U], sub_key[0U]); + st[3U] = Lib_Vec128_ni_aes_enc(st[3U], sub_key[0U]); + } + st[0U] = Lib_Vec128_ni_aes_enc_last(st[0U], kn[0U]); + st[1U] = Lib_Vec128_ni_aes_enc_last(st[1U], kn[0U]); + st[2U] = Lib_Vec128_ni_aes_enc_last(st[2U], kn[0U]); + st[3U] = Lib_Vec128_ni_aes_enc_last(st[3U], kn[0U]); + Lib_Vec128_vec128 v0 = Lib_Vec128_vec128_load_le(last1); + Lib_Vec128_vec128 v1 = Lib_Vec128_vec128_load_le(last1 + (uint32_t)16U); + Lib_Vec128_vec128 v2 = Lib_Vec128_vec128_load_le(last1 + (uint32_t)32U); + Lib_Vec128_vec128 v3 = Lib_Vec128_vec128_load_le(last1 + (uint32_t)48U); + Lib_Vec128_vec128 v01 = Lib_Vec128_vec128_xor(v0, st[0U]); + Lib_Vec128_vec128 v11 = Lib_Vec128_vec128_xor(v1, st[1U]); + Lib_Vec128_vec128 v21 = Lib_Vec128_vec128_xor(v2, st[2U]); + Lib_Vec128_vec128 v31 = Lib_Vec128_vec128_xor(v3, st[3U]); + Lib_Vec128_vec128_store_le(last1, v01); + Lib_Vec128_vec128_store_le(last1 + (uint32_t)16U, v11); + Lib_Vec128_vec128_store_le(last1 + (uint32_t)32U, v21); + Lib_Vec128_vec128_store_le(last1 + (uint32_t)48U, v31); + memcpy(ob, last1, rem1 * sizeof last1[0U]); + } +} + +void Hacl_AesGCM_NI_aes128_gcm_init(Lib_Vec128_vec128 *ctx, uint8_t *key, uint8_t *nonce) +{ + uint8_t gcm_key[16U] = { 0U }; + uint8_t tag_mix[16U] = { 0U }; + uint8_t nonce0[12U] = { 0U }; + Lib_Vec128_vec128 *aes_ctx = ctx; + Lib_Vec128_vec128 *gcm_ctx = ctx + (uint32_t)16U; + Hacl_Aes_NI_aes128_init(aes_ctx, key, nonce0); + Hacl_Aes_NI_aes128_key_block(gcm_key, aes_ctx, (uint32_t)0U); + Hacl_Aes_NI_aes128_set_nonce(aes_ctx, nonce); + Hacl_Aes_NI_aes128_key_block(tag_mix, aes_ctx, (uint32_t)1U); + Hacl_Gf128_NI_gcm_init(gcm_ctx, gcm_key); + ctx[21U] = Lib_Vec128_vec128_load_le(tag_mix); +} + +void +Hacl_AesGCM_NI_aes128_gcm_encrypt( + Lib_Vec128_vec128 *ctx, + uint32_t len, + uint8_t *out, + uint8_t *text, + uint32_t aad_len, + uint8_t *aad +) +{ + uint8_t *cip = out; + Lib_Vec128_vec128 *aes_ctx = ctx; + Hacl_Aes_NI_aes128_ctr(len, cip, text, aes_ctx, (uint32_t)2U); + Lib_Vec128_vec128 *gcm_ctx = ctx + (uint32_t)16U; + Lib_Vec128_vec128 tag_mix = ctx[21U]; + Hacl_Gf128_NI_gcm_update_padded(gcm_ctx, aad_len, aad); + Hacl_Gf128_NI_gcm_update_padded(gcm_ctx, len, cip); + uint8_t tmp[16U] = { 0U }; + store64_be(tmp, (uint64_t)(aad_len * (uint32_t)8U)); + store64_be(tmp + (uint32_t)8U, (uint64_t)(len * (uint32_t)8U)); + Hacl_Gf128_NI_gcm_update_blocks(gcm_ctx, (uint32_t)16U, tmp); + Hacl_Gf128_NI_gcm_emit(tmp, gcm_ctx); + Lib_Vec128_vec128 tmp_vec = Lib_Vec128_vec128_load_le(tmp); + Lib_Vec128_vec128 tmp_vec1 = Lib_Vec128_vec128_xor(tmp_vec, tag_mix); + Lib_Vec128_vec128_store_le(out + len, tmp_vec1); +} + +bool +Hacl_AesGCM_NI_aes128_gcm_decrypt( + Lib_Vec128_vec128 *ctx, + uint32_t len, + uint8_t *out, + uint8_t *cipher, + uint32_t aad_len, + uint8_t *aad +) +{ + Lib_Vec128_vec128 *aes_ctx = ctx; + Lib_Vec128_vec128 *gcm_ctx = ctx + (uint32_t)16U; + Lib_Vec128_vec128 tag_mix = ctx[21U]; + Hacl_Gf128_NI_gcm_update_padded(gcm_ctx, aad_len, aad); + Hacl_Gf128_NI_gcm_update_padded(gcm_ctx, len, cipher); + uint8_t tmp[16U] = { 0U }; + store64_be(tmp, (uint64_t)(aad_len * (uint32_t)8U)); + store64_be(tmp + (uint32_t)8U, (uint64_t)(len * (uint32_t)8U)); + Hacl_Gf128_NI_gcm_update_blocks(gcm_ctx, (uint32_t)16U, tmp); + Hacl_Gf128_NI_gcm_emit(tmp, gcm_ctx); + Lib_Vec128_vec128 tmp_vec = Lib_Vec128_vec128_load_le(tmp); + Lib_Vec128_vec128 tmp_vec1 = Lib_Vec128_vec128_xor(tmp_vec, tag_mix); + Lib_Vec128_vec128_store_le(tmp, tmp_vec1); + uint8_t *tag = cipher + len; + uint8_t res = (uint8_t)0U; + for (uint32_t i = (uint32_t)0U; i < (uint32_t)16U; i = i + (uint32_t)1U) + { + res = res | (tmp[i] ^ tag[i]); + } + uint8_t r = res; + if (r == (uint8_t)0U) + { + uint8_t *cip = cipher; + Hacl_Aes_NI_aes128_ctr(len, out, cip, aes_ctx, (uint32_t)2U); + return true; + } + else + { + return false; + } +} + diff --git a/fizz/crypto/experimental/hacl/Hacl_AesGCM_NI.h b/fizz/crypto/experimental/hacl/Hacl_AesGCM_NI.h new file mode 100644 index 00000000000..42f96ad2aee --- /dev/null +++ b/fizz/crypto/experimental/hacl/Hacl_AesGCM_NI.h @@ -0,0 +1,41 @@ +/* This file was generated by KreMLin + * KreMLin invocation: /Users/bhargava/Desktop/repositories/kremlin/krml -funroll-loops 8 -warn-error +9 -I /Users/bhargava/Desktop/repositories/hacl-star//lib/ -I /Users/bhargava/Desktop/repositories/hacl-star//lib/fst -I /Users/bhargava/Desktop/repositories/kremlin/kremlib -I /Users/bhargava/Desktop/repositories/hacl-star//specs -I . -I /Users/bhargava/Desktop/repositories/hacl-star//code/experimental/aes -I /Users/bhargava/Desktop/repositories/hacl-star//code/experimental/gf128 -ccopt -march=native -fbuiltin-uint128 -drop FStar.UInt128 -fnocompound-literals -fparentheses -fcurly-braces -tmpdir aesgcm-ni-c aesgcm-ni-c/out.krml -skip-compilation -minimal -add-include "kremlib.h" -add-include "vec128.h" -drop Lib.Vec128 -bundle Hacl.AesGCM.NI=* + * F* version: 518dde40 + * KreMLin version: d94ac163 + */ + + +#ifndef __Hacl_AesGCM_NI_H +#define __Hacl_AesGCM_NI_H + +#include +#include +#include "endianness.h" +#include "vec128.h" + +typedef Lib_Vec128_vec128 Hacl_AesGCM_NI_aes_gcm_ctx[22]; + +void Hacl_AesGCM_NI_aes128_gcm_init(Lib_Vec128_vec128 *ctx, uint8_t *key, uint8_t *nonce); + +void +Hacl_AesGCM_NI_aes128_gcm_encrypt( + Lib_Vec128_vec128 *ctx, + uint32_t len, + uint8_t *out, + uint8_t *text, + uint32_t aad_len, + uint8_t *aad +); + +bool +Hacl_AesGCM_NI_aes128_gcm_decrypt( + Lib_Vec128_vec128 *ctx, + uint32_t len, + uint8_t *out, + uint8_t *cipher, + uint32_t aad_len, + uint8_t *aad +); + +#define __Hacl_AesGCM_NI_H_DEFINED +#endif diff --git a/fizz/crypto/experimental/hacl/TARGETS b/fizz/crypto/experimental/hacl/TARGETS new file mode 100644 index 00000000000..8285fed1d60 --- /dev/null +++ b/fizz/crypto/experimental/hacl/TARGETS @@ -0,0 +1,36 @@ +cpp_library( + name = "hacl", + srcs = [ + "Hacl.cpp", + "Hacl_AesGCM_NI.cpp", + ], + headers = [ + "endianness.h", + "vec128.h", + ], + compiler_flags = [ + "-maes -mpclmul -mavx", + ], + deps = [ + "//fizz/crypto/aead:evpcipher", + ], +) + +cpp_unittest( + name = "hacltest", + srcs = [ + "test/HaclCipherTest.cpp", + ], + deps = [ + ":hacl", + "//fizz/crypto/aead:evpcipher", + "//fizz/crypto/aead:iobuf", + "//fizz/crypto/aead/test:test_util", + "//fizz/record:record", + "//folly:exception_wrapper", + "//folly/portability:openssl", + ], + external_deps = [ + "glog", + ], +) diff --git a/fizz/crypto/experimental/hacl/endianness.h b/fizz/crypto/experimental/hacl/endianness.h new file mode 100644 index 00000000000..39e0fe2b90a --- /dev/null +++ b/fizz/crypto/experimental/hacl/endianness.h @@ -0,0 +1,220 @@ +/* MIT License + * + * Copyright (c) 2016-2017 INRIA and Microsoft Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ENDIANNESS_H +#define __ENDIANNESS_H +/******************************************************************************/ +/* Endian-ness macros that can only be implemented in C */ +/******************************************************************************/ + +/* ... for Linux */ +#if defined(__linux__) || defined(__CYGWIN__) +#include +#include + +/* ... for OSX */ +#elif defined(__APPLE__) +#include +#define htole64(x) OSSwapHostToLittleInt64(x) +#define le64toh(x) OSSwapLittleToHostInt64(x) +#define htobe64(x) OSSwapHostToBigInt64(x) +#define be64toh(x) OSSwapBigToHostInt64(x) + +#define htole16(x) OSSwapHostToLittleInt16(x) +#define le16toh(x) OSSwapLittleToHostInt16(x) +#define htobe16(x) OSSwapHostToBigInt16(x) +#define be16toh(x) OSSwapBigToHostInt16(x) + +#define htole32(x) OSSwapHostToLittleInt32(x) +#define le32toh(x) OSSwapLittleToHostInt32(x) +#define htobe32(x) OSSwapHostToBigInt32(x) +#define be32toh(x) OSSwapBigToHostInt32(x) + +/* ... for Solaris */ +#elif defined(__sun__) +#include +#define htole64(x) LE_64(x) +#define le64toh(x) LE_64(x) +#define htobe64(x) BE_64(x) +#define be64toh(x) BE_64(x) + +#define htole16(x) LE_16(x) +#define le16toh(x) LE_16(x) +#define htobe16(x) BE_16(x) +#define be16toh(x) BE_16(x) + +#define htole32(x) LE_32(x) +#define le32toh(x) LE_32(x) +#define htobe32(x) BE_32(x) +#define be32toh(x) BE_32(x) + +/* ... for the BSDs */ +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) +#include +#elif defined(__OpenBSD__) +#include + +/* ... for Windows (MSVC)... not targeting XBOX 360! */ +#elif defined(_MSC_VER) + +#include +#define htobe16(x) _byteswap_ushort(x) +#define htole16(x) (x) +#define be16toh(x) _byteswap_ushort(x) +#define le16toh(x) (x) + +#define htobe32(x) _byteswap_ulong(x) +#define htole32(x) (x) +#define be32toh(x) _byteswap_ulong(x) +#define le32toh(x) (x) + +#define htobe64(x) _byteswap_uint64(x) +#define htole64(x) (x) +#define be64toh(x) _byteswap_uint64(x) +#define le64toh(x) (x) + +/* ... for Windows (GCC-like, e.g. mingw or clang) */ +#elif (defined(_WIN32) || defined(_WIN64)) && \ + (defined(__GNUC__) || defined(__clang__)) + +#define htobe16(x) __builtin_bswap16(x) +#define htole16(x) (x) +#define be16toh(x) __builtin_bswap16(x) +#define le16toh(x) (x) + +#define htobe32(x) __builtin_bswap32(x) +#define htole32(x) (x) +#define be32toh(x) __builtin_bswap32(x) +#define le32toh(x) (x) + +#define htobe64(x) __builtin_bswap64(x) +#define htole64(x) (x) +#define be64toh(x) __builtin_bswap64(x) +#define le64toh(x) (x) + +/* ... generic big-endian fallback code */ +#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + +/* byte swapping code inspired by: + * https://github.com/rweather/arduinolibs/blob/master/libraries/Crypto/utility/EndianUtil.h + * */ + +#define htobe32(x) (x) +#define be32toh(x) (x) +#define htole32(x) \ + (__extension__({ \ + uint32_t _temp = (x); \ + ((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) | \ + ((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \ + })) +#define le32toh(x) (htole32((x))) + +#define htobe64(x) (x) +#define be64toh(x) (x) +#define htole64(x) \ + (__extension__({ \ + uint64_t __temp = (x); \ + uint32_t __low = htobe32((uint32_t)__temp); \ + uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \ + (((uint64_t)__low) << 32) | __high; \ + })) +#define le64toh(x) (htole64((x))) + +/* ... generic little-endian fallback code */ +#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + +#define htole32(x) (x) +#define le32toh(x) (x) +#define htobe32(x) \ + (__extension__({ \ + uint32_t _temp = (x); \ + ((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) | \ + ((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \ + })) +#define be32toh(x) (htobe32((x))) + +#define htole64(x) (x) +#define le64toh(x) (x) +#define htobe64(x) \ + (__extension__({ \ + uint64_t __temp = (x); \ + uint32_t __low = htobe32((uint32_t)__temp); \ + uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \ + (((uint64_t)__low) << 32) | __high; \ + })) +#define be64toh(x) (htobe64((x))) + +/* ... couldn't determine endian-ness of the target platform */ +#else +#error "Please define __BYTE_ORDER__!" + +#endif /* defined(__linux__) || ... */ + +/* Loads and stores. These avoid undefined behavior due to unaligned memory + * accesses, via memcpy. */ + +inline static uint16_t load16(uint8_t* b) { + uint16_t x; + memcpy(&x, b, 2); + return x; +} + +inline static uint32_t load32(uint8_t* b) { + uint32_t x; + memcpy(&x, b, 4); + return x; +} + +inline static uint64_t load64(uint8_t* b) { + uint64_t x; + memcpy(&x, b, 8); + return x; +} + +inline static void store16(uint8_t* b, uint16_t i) { + memcpy(b, &i, 2); +} + +inline static void store32(uint8_t* b, uint32_t i) { + memcpy(b, &i, 4); +} + +inline static void store64(uint8_t* b, uint64_t i) { + memcpy(b, &i, 8); +} + +#define load16_le(b) (le16toh(load16(b))) +#define store16_le(b, i) (store16(b, htole16(i))) +#define load16_be(b) (be16toh(load16(b))) +#define store16_be(b, i) (store16(b, htobe16(i))) + +#define load32_le(b) (le32toh(load32(b))) +#define store32_le(b, i) (store32(b, htole32(i))) +#define load32_be(b) (be32toh(load32(b))) +#define store32_be(b, i) (store32(b, htobe32(i))) + +#define load64_le(b) (le64toh(load64(b))) +#define store64_le(b, i) (store64(b, htole64(i))) +#define load64_be(b) (be64toh(load64(b))) +#define store64_be(b, i) (store64(b, htobe64(i))) + +#endif diff --git a/fizz/crypto/experimental/hacl/test/HaclCipherTest.cpp b/fizz/crypto/experimental/hacl/test/HaclCipherTest.cpp new file mode 100644 index 00000000000..34912080dd1 --- /dev/null +++ b/fizz/crypto/experimental/hacl/test/HaclCipherTest.cpp @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace folly; + +namespace fizz { +namespace test { + +struct CipherParams { + std::string key; + std::string iv; + uint64_t seqNum; + std::string aad; + std::string plaintext; + std::string ciphertext; + bool valid; + CipherSuite cipher; +}; + +constexpr size_t kHeadroom = 10; + +class OpenSSLEVPCipherTest : public ::testing::TestWithParam {}; + +std::unique_ptr getCipher(const CipherParams& params) { + std::unique_ptr cipher; + switch (params.cipher) { + case CipherSuite::TLS_AES_128_GCM_SHA256: + cipher = std::make_unique(); + break; + default: + throw std::runtime_error("Invalid cipher"); + } + + TrafficKey trafficKey; + trafficKey.key = toIOBuf(params.key); + trafficKey.iv = toIOBuf(params.iv); + cipher->setKey(std::move(trafficKey)); + cipher->setEncryptedBufferHeadroom(kHeadroom); + return cipher; +} + +std::unique_ptr copyBuffer(const folly::IOBuf& buf) { + std::unique_ptr out; + for (auto r : buf) { + if (out) { + out->prependChain(IOBuf::copyBuffer(r)); + } else { + out = IOBuf::copyBuffer(r); + } + } + return out; +} + +std::unique_ptr callEncrypt( + std::unique_ptr& cipher, + const CipherParams& params, + std::unique_ptr plaintext = nullptr, + std::unique_ptr aad = nullptr) { + if (!plaintext) { + plaintext = toIOBuf(params.plaintext); + } + + if (!aad && !params.aad.empty()) { + aad = toIOBuf(params.aad); + } + auto ptCopy = copyBuffer(*plaintext); + auto out = cipher->encrypt(std::move(plaintext), aad.get(), params.seqNum); + bool valid = IOBufEqualTo()(toIOBuf(params.ciphertext), out); + + EXPECT_EQ(valid, params.valid); + EXPECT_EQ( + out->computeChainDataLength(), + ptCopy->computeChainDataLength() + cipher->getCipherOverhead()); + return out; +} + +void callDecrypt( + std::unique_ptr& cipher, + const CipherParams& params, + std::unique_ptr ciphertext = nullptr, + std::unique_ptr aad = nullptr) { + if (!ciphertext) { + ciphertext = toIOBuf(params.ciphertext); + } + if (!aad && !params.aad.empty()) { + aad = toIOBuf(params.aad); + } + auto ctCopy = copyBuffer(*ciphertext); + try { + auto out = cipher->decrypt(std::move(ciphertext), aad.get(), params.seqNum); + EXPECT_TRUE(params.valid); + EXPECT_TRUE(IOBufEqualTo()(toIOBuf(params.plaintext), out)); + + EXPECT_EQ( + out->computeChainDataLength(), + ctCopy->computeChainDataLength() - cipher->getCipherOverhead()); + } catch (const std::runtime_error& e) { + EXPECT_FALSE(params.valid) << e.what(); + } +} + +TEST_P(OpenSSLEVPCipherTest, TestEncrypt) { + auto cipher = getCipher(GetParam()); + auto out = callEncrypt(cipher, GetParam()); +} + +TEST_P(OpenSSLEVPCipherTest, TestEncryptReusedCipher) { + auto cipher = getCipher(GetParam()); + auto params = GetParam(); + callEncrypt(cipher, params); + callEncrypt(cipher, GetParam()); +} + +TEST_P(OpenSSLEVPCipherTest, TestDecrypt) { + auto cipher = getCipher(GetParam()); + callDecrypt(cipher, GetParam()); +} + +TEST_P(OpenSSLEVPCipherTest, TestDecryptReusedCipher) { + auto cipher = getCipher(GetParam()); + auto params = GetParam(); + callDecrypt(cipher, params); + callDecrypt(cipher, GetParam()); +} + +// Adapted from draft-thomson-tls-tls13-vectors +INSTANTIATE_TEST_CASE_P( + AESGCM128TestVectors, + OpenSSLEVPCipherTest, + ::testing::Values( + CipherParams{"87f6c12b1ae8a9b7efafc65af0f5c994", + "479e25839c19e0476f95a6f5", + 1, + "", + "010015", + "9d4db5ecd768198892531eebac72cf1d477dd0", + true, + CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{ + "911dc107aa6eccb6706bdcc37e76a07a", + "11c7fa13e9499ed042b09e57", + 0, + "", + "14000020de15cbc8c62d0e6fef73a6d4e70e5c372c2b94fe08ea40d11166a7e6c967ba9c16", + "56a21739148c898fe807026a179d59202647a3b1e01267a3883cf5f69fd233f63ff12c1c71b4c8f3d6086affb49621f96b842e1d35", + true, + CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{"a0f49e7076cae6eb25ca23a2da0eaf12", + "3485d33f22128dff91e47062", + 0, + "", + "41424344454617", + "92fdec5c241e994fb7d889e1b61d1db2b9be6777f5a393", + true, + CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{"fda2a4404670808f4937478b8b6e3fe1", "b5f3a3fae1cb25c9dcd73993", 0, "", "0800001e001c000a00140012001d00170018001901000101010201030104000000000b0001b9000001b50001b0308201ac30820115a003020102020102300d06092a864886f70d01010b0500300e310c300a06035504031303727361301e170d3136303733303031323335395a170d3236303733303031323335395a300e310c300a0603550403130372736130819f300d06092a864886f70d010101050003818d0030818902818100b4bb498f8279303d980836399b36c6988c0c68de55e1bdb826d3901a2461eafd2de49a91d015abbc9a95137ace6c1af19eaa6af98c7ced43120998e187a80ee0ccb0524b1b018c3e0b63264d449a6d38e22a5fda430846748030530ef0461c8ca9d9efbfae8ea6d1d03e2bd193eff0ab9a8002c47428a6d35a8d88d79f7f1e3f0203010001a31a301830090603551d1304023000300b0603551d0f0404030205a0300d06092a864886f70d01010b05000381810085aad2a0e5b9276b908c65f73a7267170618a54c5f8a7b337d2df7a594365417f2eae8f8a58c8f8172f9319cf36b7fd6c55b80f21a03015156726096fd335e5e67f2dbf102702e608ccae6bec1fc63a42a99be5c3eb7107c3c54e9b9eb2bd5203b1c3b84e0a8b2f759409ba3eac9d91d402dcc0cc8f8961229ac9187b42b4de100000f000084080400804547d6168f2510c550bd949cd2bc631ff134fa10a827ff69b166a6bd95e249ed0daf571592ebbe9ff13de6b03acc218146781f693b5a692b7319d74fd2e53b6a2df0f6785d624f024a44030ca00b869ae81a532b19e47e525ff4a62c51a5889eb565fee268590d8a3ca3c1bc3bd5404e39720ca2eaee308f4e0700761e986389140000209efee03ebffbc0dc23d26d958744c09e3000477eff7ae3148a50e5670013aaaa16", "c1e631f81d2af221ebb6a957f58f3ee266272635e67f99a752f0df08adeb33bab8611e55f33d72cf84382461a8bfe0a659ba2dd1873f6fcc707a9841cefc1fb03526b9ca4fe343e5805e95a5c01e56570638a76a4bc8feb07be879f90568617d905fecd5b1619fb8ec4a6628d1bb2bb224c490ff97a6c0e9acd03604bc3a59d86bdab4e084c1c1450f9c9d2afeb172c07234d739868ebd62de2060a8de989414a82920dacd1cac0c6e72ecd7f4018574ceaca6d29f361bc37ee2888b8e302ca9561a9de9163edfa66badd4894884c7b359bcacae5908051b37952e10a45fe73fda126ebd67575f1bed8a992a89474d7dec1eed327824123a414adb66d5ef7d0836ff98c2cdd7fb0781e192bf0c7568bf7d890a51c332879b5037b212d622412ca48e8323817bd6d746eef683845cec4e3ef64b3a18fcce513ea951f3366693a7ff490d09d08ab1f63e13625a545961599c0d9c7a099d1163cad1b9bcf8e917d766b98853ef6877834f891df16be1fcc9c18ea1882ea3f1f4b64358e1b146cebfb3e02e153fdb73af2693f22c6f593fa475380ba6611740ad20e319a654ac5684775236162e8447ed808861bfbda6e18ec97ae090bf703475cfb90fe20a3c55bef6f5eba6e6a1da6a1996b8bde42180608ca2279def8e8153895cc850db6420561c04b5729cc6883436ea02ee07eb9baee2fb3a9e1bbda8730d6b220576e24df70af6928eb865fee8a1d1c0f1818aca68d5002ae4c65b2f49c9e6e21dcf76784adbd0e887a36832ef85beb10587f16c6ffe60d7451059ec7f1014c3efe19e56aedb5ad31a9f29dc4458cfbf0c7070c175dcad46e1675226b47c071aad3172ebd33e45d741cb91253a01a69ae3cc292bce9c03246ac951e45e97ebf04a9d51fab5cf06d9485cce746b1c077be69ad153f1656ef89fc7d1ed8c3e2da7a2", true, CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{"a0f49e7076cbe6eb25ca23a2da0eaf12", + "3485d33f22128dff91e47062", + 0, + "", + "41424344454617", + "92fdec5c241e994fb7d889e1b61d1db2b9be6777f5a393", + false, + CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{"a0f49e7076cae6eb25ca23a2da0eaf12", + "3485d33f22128dff91e47062", + 0, + "", + "41424344454617", + "92fdec", + false, + CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{ + "AD7A2BD03EAC835A6F620FDCB506B345", + "12153524C0895E81B2C28465", + 0, + "D609B1F056637A0D46DF998D88E52E00B2C2846512153524C0895E81", + "08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A0002", + "701AFA1CC039C0D765128A665DAB69243899BF7318CCDC81C9931DA17FBE8EDD7D17CB8B4C26FC81E3284F2B7FBA713D4F8D55E7D3F06FD5A13C0C29B9D5B880", + true, + CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{ + "AD7A2BD03EAC835A6F620FDCB506B345", + "12153524C0895E81B2C28465", + 0, + "D609B1F056637A1D46DF998D88E52E00B2C2846512153524C0895E81", + "08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A0002", + "701AFA1CC039C0D765128A665DAB69243899BF7318CCDC81C9931DA17FBE8EDD7D17CB8B4C26FC81E3284F2B7FBA713D4F8D55E7D3F06FD5A13C0C29B9D5B880", + false, + CipherSuite::TLS_AES_128_GCM_SHA256})); +} // namespace test +} // namespace fizz diff --git a/fizz/crypto/experimental/hacl/test/HaclCipherTest.cpp~ b/fizz/crypto/experimental/hacl/test/HaclCipherTest.cpp~ new file mode 100644 index 00000000000..d87f772087a --- /dev/null +++ b/fizz/crypto/experimental/hacl/test/HaclCipherTest.cpp~ @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace folly; + +namespace fizz { +namespace test { + +struct CipherParams { + std::string key; + std::string iv; + uint64_t seqNum; + std::string aad; + std::string plaintext; + std::string ciphertext; + bool valid; + CipherSuite cipher; +}; + +constexpr size_t kHeadroom = 10; + +class OpenSSLEVPCipherTest : public ::testing::TestWithParam {}; + +std::unique_ptr getCipher(const CipherParams& params) { + std::unique_ptr cipher; + switch (params.cipher) { + case CipherSuite::TLS_AES_128_GCM_SHA256: + cipher = std::make_unique(); + break; + default: + throw std::runtime_error("Invalid cipher"); + } + + TrafficKey trafficKey; + trafficKey.key = toIOBuf(params.key); + trafficKey.iv = toIOBuf(params.iv); + cipher->setKey(std::move(trafficKey)); + cipher->setEncryptedBufferHeadroom(kHeadroom); + return cipher; +} + +std::unique_ptr copyBuffer(const folly::IOBuf& buf) { + std::unique_ptr out; + for (auto r : buf) { + if (out) { + out->prependChain(IOBuf::copyBuffer(r)); + } else { + out = IOBuf::copyBuffer(r); + } + } + return out; +} + +std::unique_ptr callEncrypt( + std::unique_ptr& cipher, + const CipherParams& params, + std::unique_ptr plaintext = nullptr, + std::unique_ptr aad = nullptr) { + if (!plaintext) { + plaintext = toIOBuf(params.plaintext); + } + + if (!aad && !params.aad.empty()) { + aad = toIOBuf(params.aad); + } + auto ptCopy = copyBuffer(*plaintext); + auto out = cipher->encrypt(std::move(plaintext), aad.get(), params.seqNum); + bool valid = IOBufEqualTo()(toIOBuf(params.ciphertext), out); + + EXPECT_EQ(valid, params.valid); + EXPECT_EQ( + out->computeChainDataLength(), + ptCopy->computeChainDataLength() + cipher->getCipherOverhead()); + return out; +} + +void callDecrypt( + std::unique_ptr& cipher, + const CipherParams& params, + std::unique_ptr ciphertext = nullptr, + std::unique_ptr aad = nullptr) { + if (!ciphertext) { + ciphertext = toIOBuf(params.ciphertext); + } + if (!aad && !params.aad.empty()) { + aad = toIOBuf(params.aad); + } + auto ctCopy = copyBuffer(*ciphertext); + try { + auto out = cipher->decrypt(std::move(ciphertext), aad.get(), params.seqNum); + EXPECT_TRUE(params.valid); + EXPECT_TRUE(IOBufEqualTo()(toIOBuf(params.plaintext), out)); + + EXPECT_EQ( + out->computeChainDataLength(), + ctCopy->computeChainDataLength() - cipher->getCipherOverhead()); + } catch (const std::runtime_error& e) { + EXPECT_FALSE(params.valid) << e.what(); + } +} + +TEST_P(OpenSSLEVPCipherTest, TestEncrypt) { + auto cipher = getCipher(GetParam()); + auto out = callEncrypt(cipher, GetParam()); +} + +TEST_P(OpenSSLEVPCipherTest, TestEncryptReusedCipher) { + auto cipher = getCipher(GetParam()); + auto params = GetParam(); + callEncrypt(cipher, params); + callEncrypt(cipher, GetParam()); +} + +TEST_P(OpenSSLEVPCipherTest, TestDecrypt) { + auto cipher = getCipher(GetParam()); + callDecrypt(cipher, GetParam()); +} + +TEST_P(OpenSSLEVPCipherTest, TestDecryptReusedCipher) { + auto cipher = getCipher(GetParam()); + auto params = GetParam(); + callDecrypt(cipher, params); + callDecrypt(cipher, GetParam()); +} + +// Adapted from draft-thomson-tls-tls13-vectors +INSTANTIATE_TEST_CASE_P( + AESGCM128TestVectors, + OpenSSLEVPCipherTest, + ::testing::Values( + CipherParams{"87f6c12b1ae8a9b7efafc65af0f5c994", + "479e25839c19e0476f95a6f5", + 1, + "", + "010015", + "9d4db5ecd768198892531eebac72cf1d477dd0", + true, + CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{ + "911dc107aa6eccb6706bdcc37e76a07a", + "11c7fa13e9499ed042b09e57", + 0, + "", + "14000020de15cbc8c62d0e6fef73a6d4e70e5c372c2b94fe08ea40d11166a7e6c967ba9c16", + "56a21739148c898fe807026a179d59202647a3b1e01267a3883cf5f69fd233f63ff12c1c71b4c8f3d6086affb49621f96b842e1d35", + true, + CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{"a0f49e7076cae6eb25ca23a2da0eaf12", + "3485d33f22128dff91e47062", + 0, + "", + "41424344454617", + "92fdec5c241e994fb7d889e1b61d1db2b9be6777f5a393", + true, + CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{"fda2a4404670808f4937478b8b6e3fe1", "b5f3a3fae1cb25c9dcd73993", 0, "", "0800001e001c000a00140012001d00170018001901000101010201030104000000000b0001b9000001b50001b0308201ac30820115a003020102020102300d06092a864886f70d01010b0500300e310c300a06035504031303727361301e170d3136303733303031323335395a170d3236303733303031323335395a300e310c300a0603550403130372736130819f300d06092a864886f70d010101050003818d0030818902818100b4bb498f8279303d980836399b36c6988c0c68de55e1bdb826d3901a2461eafd2de49a91d015abbc9a95137ace6c1af19eaa6af98c7ced43120998e187a80ee0ccb0524b1b018c3e0b63264d449a6d38e22a5fda430846748030530ef0461c8ca9d9efbfae8ea6d1d03e2bd193eff0ab9a8002c47428a6d35a8d88d79f7f1e3f0203010001a31a301830090603551d1304023000300b0603551d0f0404030205a0300d06092a864886f70d01010b05000381810085aad2a0e5b9276b908c65f73a7267170618a54c5f8a7b337d2df7a594365417f2eae8f8a58c8f8172f9319cf36b7fd6c55b80f21a03015156726096fd335e5e67f2dbf102702e608ccae6bec1fc63a42a99be5c3eb7107c3c54e9b9eb2bd5203b1c3b84e0a8b2f759409ba3eac9d91d402dcc0cc8f8961229ac9187b42b4de100000f000084080400804547d6168f2510c550bd949cd2bc631ff134fa10a827ff69b166a6bd95e249ed0daf571592ebbe9ff13de6b03acc218146781f693b5a692b7319d74fd2e53b6a2df0f6785d624f024a44030ca00b869ae81a532b19e47e525ff4a62c51a5889eb565fee268590d8a3ca3c1bc3bd5404e39720ca2eaee308f4e0700761e986389140000209efee03ebffbc0dc23d26d958744c09e3000477eff7ae3148a50e5670013aaaa16", "c1e631f81d2af221ebb6a957f58f3ee266272635e67f99a752f0df08adeb33bab8611e55f33d72cf84382461a8bfe0a659ba2dd1873f6fcc707a9841cefc1fb03526b9ca4fe343e5805e95a5c01e56570638a76a4bc8feb07be879f90568617d905fecd5b1619fb8ec4a6628d1bb2bb224c490ff97a6c0e9acd03604bc3a59d86bdab4e084c1c1450f9c9d2afeb172c07234d739868ebd62de2060a8de989414a82920dacd1cac0c6e72ecd7f4018574ceaca6d29f361bc37ee2888b8e302ca9561a9de9163edfa66badd4894884c7b359bcacae5908051b37952e10a45fe73fda126ebd67575f1bed8a992a89474d7dec1eed327824123a414adb66d5ef7d0836ff98c2cdd7fb0781e192bf0c7568bf7d890a51c332879b5037b212d622412ca48e8323817bd6d746eef683845cec4e3ef64b3a18fcce513ea951f3366693a7ff490d09d08ab1f63e13625a545961599c0d9c7a099d1163cad1b9bcf8e917d766b98853ef6877834f891df16be1fcc9c18ea1882ea3f1f4b64358e1b146cebfb3e02e153fdb73af2693f22c6f593fa475380ba6611740ad20e319a654ac5684775236162e8447ed808861bfbda6e18ec97ae090bf703475cfb90fe20a3c55bef6f5eba6e6a1da6a1996b8bde42180608ca2279def8e8153895cc850db6420561c04b5729cc6883436ea02ee07eb9baee2fb3a9e1bbda8730d6b220576e24df70af6928eb865fee8a1d1c0f1818aca68d5002ae4c65b2f49c9e6e21dcf76784adbd0e887a36832ef85beb10587f16c6ffe60d7451059ec7f1014c3efe19e56aedb5ad31a9f29dc4458cfbf0c7070c175dcad46e1675226b47c071aad3172ebd33e45d741cb91253a01a69ae3cc292bce9c03246ac951e45e97ebf04a9d51fab5cf06d9485cce746b1c077be69ad153f1656ef89fc7d1ed8c3e2da7a2", true, CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{"a0f49e7076cbe6eb25ca23a2da0eaf12", + "3485d33f22128dff91e47062", + 0, + "", + "41424344454617", + "92fdec5c241e994fb7d889e1b61d1db2b9be6777f5a393", + false, + CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{"a0f49e7076cae6eb25ca23a2da0eaf12", + "3485d33f22128dff91e47062", + 0, + "", + "41424344454617", + "92fdec", + false, + CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{ + "AD7A2BD03EAC835A6F620FDCB506B345", + "12153524C0895E81B2C28465", + 0, + "D609B1F056637A0D46DF998D88E52E00B2C2846512153524C0895E81", + "08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A0002", + "701AFA1CC039C0D765128A665DAB69243899BF7318CCDC81C9931DA17FBE8EDD7D17CB8B4C26FC81E3284F2B7FBA713D4F8D55E7D3F06FD5A13C0C29B9D5B880", + true, + CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{ + "AD7A2BD03EAC835A6F620FDCB506B345", + "12153524C0895E81B2C28465", + 0, + "D609B1F056637A1D46DF998D88E52E00B2C2846512153524C0895E81", + "08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A0002", + "701AFA1CC039C0D765128A665DAB69243899BF7318CCDC81C9931DA17FBE8EDD7D17CB8B4C26FC81E3284F2B7FBA713D4F8D55E7D3F06FD5A13C0C29B9D5B880", + false, + CipherSuite::TLS_AES_128_GCM_SHA256})); +} // namespace test +} // namespace fizz diff --git a/fizz/crypto/experimental/hacl/vec128.h b/fizz/crypto/experimental/hacl/vec128.h new file mode 100644 index 00000000000..36bb975dbab --- /dev/null +++ b/fizz/crypto/experimental/hacl/vec128.h @@ -0,0 +1,83 @@ +#ifndef __Vec_H +#define __Vec_H + +#include +#include +#include + +typedef __m128i Lib_Vec128_vec128; + +#define Lib_Vec128_ni_aes_enc(x0, x1) (_mm_aesenc_si128(x0, x1)) + +#define Lib_Vec128_ni_aes_enc_last(x0, x1) (_mm_aesenclast_si128(x0, x1)) + +#define Lib_Vec128_ni_aes_keygen_assist(x0, x1) \ + (_mm_aeskeygenassist_si128(x0, x1)) + +#define Lib_Vec128_ni_clmul(x0, x1, x2) (_mm_clmulepi64_si128(x0, x1, x2)) + +#define Lib_Vec128_vec128_xor(x0, x1) (_mm_xor_si128(x0, x1)) + +#define Lib_Vec128_vec128_eq64(x0, x1) (_mm_cmpeq_epi64(x0, x1)) + +#define Lib_Vec128_vec128_or(x0, x1) (_mm_or_si128(x0, x1)) + +#define Lib_Vec128_vec128_and(x0, x1) (_mm_and_si128(x0, x1)) + +#define Lib_Vec128_vec128_lognot(x0) (_mm_xor_si128(x0, _mm_set1_epi32(-1))) + +#define Lib_Vec128_vec128_shift_left(x0, x1) (_mm_slli_si128(x0, (x1) / 8)) + +#define Lib_Vec128_vec128_shift_right(x0, x1) (_mm_srli_si128(x0, (x1) / 8)) + +#define Lib_Vec128_vec128_shift_left64(x0, x1) (_mm_slli_epi64(x0, x1)) + +#define Lib_Vec128_vec128_shift_right64(x0, x1) (_mm_srli_epi64(x0, x1)) + +#define Lib_Vec128_vec128_shuffle32(x0, x1) (_mm_shuffle_epi32(x0, x1)) + +#define Lib_Vec128_vec128_shuffle32_spec(x0, x1, x2, x3) \ + (_MM_SHUFFLE(x0, x1, x2, x3)) + +#define Lib_Vec128_vec128_load_le(x0) (_mm_loadu_si128((__m128i*)(x0))) + +#define Lib_Vec128_vec128_store_le(x0, x1) \ + (_mm_storeu_si128((__m128i*)(x0), x1)) + +#define Lib_Vec128_vec128_load_be(x0) \ + (_mm_shuffle_epi8( \ + _mm_loadu_si128((__m128i*)(x0)), \ + _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15))) + +#define Lib_Vec128_vec128_store_be(x0, x1) \ + (_mm_storeu_si128( \ + (__m128i*)(x0), \ + _mm_shuffle_epi8( \ + x1, \ + _mm_set_epi8( \ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)))) + +#define Lib_Vec128_vec128_insert32(x0, x1, x2) (_mm_insert_epi32(x0, x1, x2)) + +#define Lib_Vec128_vec128_zero (_mm_set1_epi16((uint16_t)0)) + +#define Lib_Vec128_bit_mask64(x) -((x)&1) + +#define Lib_Vec128_vec128_add64(x0, x1) (_mm_add_epi64(x0, x1)) + +#define Lib_Vec128_vec128_sub64(x0, x1) (_mm_sub_epi64(x0, x1)) + +#define Lib_Vec128_vec128_mul64(x0, x1) (_mm_mul_epu32(x0, x1)) + +#define Lib_Vec128_vec128_smul64(x0, x1) \ + (_mm_mul_epu32(x0, _mm_set1_epi64x(x1))) + +#define Lib_Vec128_vec128_load64s(x1, x2) (_mm_set_epi64x(x1, x2)) // hi lo + +#define Lib_Vec128_vec128_load64(x) (_mm_set1_epi64x(x)) // hi lo + +#define Lib_Vec128_vec128_interleave_low64(x1, x2) (_mm_unpacklo_epi64(x1, x2)) + +#define Lib_Vec128_vec128_interleave_high64(x1, x2) (_mm_unpackhi_epi64(x1, x2)) + +#endif diff --git a/fizz/mac-build.sh b/fizz/mac-build.sh index 9b455d4cb50..a3336f52ecd 100644 --- a/fizz/mac-build.sh +++ b/fizz/mac-build.sh @@ -25,8 +25,8 @@ mkdir -p "$FIZZ_BUILD_DIR" # OpenSSL dirs. If you have OpenSSL installed somewhere # else, change these dirs -OPENSSL_ROOT_DIR=/usr/local/opt/openssl -OPENSSL_LIB_DIR=/usr/local/opt/openssl/lib/ +OPENSSL_ROOT_DIR=/usr/local/Cellar/openssl@1.1/1.1.1 +OPENSSL_LIB_DIR=/usr/local/Cellar/openssl@1.1/1.1.1/lib/ if [ -z "$INSTALL_PREFIX" ]; then From b6f6b210958fcba6631ad0be61c4c272cb86fa0f Mon Sep 17 00:00:00 2001 From: karthikbhargavan Date: Wed, 21 Nov 2018 11:11:26 +0100 Subject: [PATCH 2/3] remove autosave file --- .../hacl/test/HaclCipherTest.cpp~ | 207 ------------------ 1 file changed, 207 deletions(-) delete mode 100644 fizz/crypto/experimental/hacl/test/HaclCipherTest.cpp~ diff --git a/fizz/crypto/experimental/hacl/test/HaclCipherTest.cpp~ b/fizz/crypto/experimental/hacl/test/HaclCipherTest.cpp~ deleted file mode 100644 index d87f772087a..00000000000 --- a/fizz/crypto/experimental/hacl/test/HaclCipherTest.cpp~ +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2018-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include - -using namespace folly; - -namespace fizz { -namespace test { - -struct CipherParams { - std::string key; - std::string iv; - uint64_t seqNum; - std::string aad; - std::string plaintext; - std::string ciphertext; - bool valid; - CipherSuite cipher; -}; - -constexpr size_t kHeadroom = 10; - -class OpenSSLEVPCipherTest : public ::testing::TestWithParam {}; - -std::unique_ptr getCipher(const CipherParams& params) { - std::unique_ptr cipher; - switch (params.cipher) { - case CipherSuite::TLS_AES_128_GCM_SHA256: - cipher = std::make_unique(); - break; - default: - throw std::runtime_error("Invalid cipher"); - } - - TrafficKey trafficKey; - trafficKey.key = toIOBuf(params.key); - trafficKey.iv = toIOBuf(params.iv); - cipher->setKey(std::move(trafficKey)); - cipher->setEncryptedBufferHeadroom(kHeadroom); - return cipher; -} - -std::unique_ptr copyBuffer(const folly::IOBuf& buf) { - std::unique_ptr out; - for (auto r : buf) { - if (out) { - out->prependChain(IOBuf::copyBuffer(r)); - } else { - out = IOBuf::copyBuffer(r); - } - } - return out; -} - -std::unique_ptr callEncrypt( - std::unique_ptr& cipher, - const CipherParams& params, - std::unique_ptr plaintext = nullptr, - std::unique_ptr aad = nullptr) { - if (!plaintext) { - plaintext = toIOBuf(params.plaintext); - } - - if (!aad && !params.aad.empty()) { - aad = toIOBuf(params.aad); - } - auto ptCopy = copyBuffer(*plaintext); - auto out = cipher->encrypt(std::move(plaintext), aad.get(), params.seqNum); - bool valid = IOBufEqualTo()(toIOBuf(params.ciphertext), out); - - EXPECT_EQ(valid, params.valid); - EXPECT_EQ( - out->computeChainDataLength(), - ptCopy->computeChainDataLength() + cipher->getCipherOverhead()); - return out; -} - -void callDecrypt( - std::unique_ptr& cipher, - const CipherParams& params, - std::unique_ptr ciphertext = nullptr, - std::unique_ptr aad = nullptr) { - if (!ciphertext) { - ciphertext = toIOBuf(params.ciphertext); - } - if (!aad && !params.aad.empty()) { - aad = toIOBuf(params.aad); - } - auto ctCopy = copyBuffer(*ciphertext); - try { - auto out = cipher->decrypt(std::move(ciphertext), aad.get(), params.seqNum); - EXPECT_TRUE(params.valid); - EXPECT_TRUE(IOBufEqualTo()(toIOBuf(params.plaintext), out)); - - EXPECT_EQ( - out->computeChainDataLength(), - ctCopy->computeChainDataLength() - cipher->getCipherOverhead()); - } catch (const std::runtime_error& e) { - EXPECT_FALSE(params.valid) << e.what(); - } -} - -TEST_P(OpenSSLEVPCipherTest, TestEncrypt) { - auto cipher = getCipher(GetParam()); - auto out = callEncrypt(cipher, GetParam()); -} - -TEST_P(OpenSSLEVPCipherTest, TestEncryptReusedCipher) { - auto cipher = getCipher(GetParam()); - auto params = GetParam(); - callEncrypt(cipher, params); - callEncrypt(cipher, GetParam()); -} - -TEST_P(OpenSSLEVPCipherTest, TestDecrypt) { - auto cipher = getCipher(GetParam()); - callDecrypt(cipher, GetParam()); -} - -TEST_P(OpenSSLEVPCipherTest, TestDecryptReusedCipher) { - auto cipher = getCipher(GetParam()); - auto params = GetParam(); - callDecrypt(cipher, params); - callDecrypt(cipher, GetParam()); -} - -// Adapted from draft-thomson-tls-tls13-vectors -INSTANTIATE_TEST_CASE_P( - AESGCM128TestVectors, - OpenSSLEVPCipherTest, - ::testing::Values( - CipherParams{"87f6c12b1ae8a9b7efafc65af0f5c994", - "479e25839c19e0476f95a6f5", - 1, - "", - "010015", - "9d4db5ecd768198892531eebac72cf1d477dd0", - true, - CipherSuite::TLS_AES_128_GCM_SHA256}, - CipherParams{ - "911dc107aa6eccb6706bdcc37e76a07a", - "11c7fa13e9499ed042b09e57", - 0, - "", - "14000020de15cbc8c62d0e6fef73a6d4e70e5c372c2b94fe08ea40d11166a7e6c967ba9c16", - "56a21739148c898fe807026a179d59202647a3b1e01267a3883cf5f69fd233f63ff12c1c71b4c8f3d6086affb49621f96b842e1d35", - true, - CipherSuite::TLS_AES_128_GCM_SHA256}, - CipherParams{"a0f49e7076cae6eb25ca23a2da0eaf12", - "3485d33f22128dff91e47062", - 0, - "", - "41424344454617", - "92fdec5c241e994fb7d889e1b61d1db2b9be6777f5a393", - true, - CipherSuite::TLS_AES_128_GCM_SHA256}, - CipherParams{"fda2a4404670808f4937478b8b6e3fe1", "b5f3a3fae1cb25c9dcd73993", 0, "", "0800001e001c000a00140012001d00170018001901000101010201030104000000000b0001b9000001b50001b0308201ac30820115a003020102020102300d06092a864886f70d01010b0500300e310c300a06035504031303727361301e170d3136303733303031323335395a170d3236303733303031323335395a300e310c300a0603550403130372736130819f300d06092a864886f70d010101050003818d0030818902818100b4bb498f8279303d980836399b36c6988c0c68de55e1bdb826d3901a2461eafd2de49a91d015abbc9a95137ace6c1af19eaa6af98c7ced43120998e187a80ee0ccb0524b1b018c3e0b63264d449a6d38e22a5fda430846748030530ef0461c8ca9d9efbfae8ea6d1d03e2bd193eff0ab9a8002c47428a6d35a8d88d79f7f1e3f0203010001a31a301830090603551d1304023000300b0603551d0f0404030205a0300d06092a864886f70d01010b05000381810085aad2a0e5b9276b908c65f73a7267170618a54c5f8a7b337d2df7a594365417f2eae8f8a58c8f8172f9319cf36b7fd6c55b80f21a03015156726096fd335e5e67f2dbf102702e608ccae6bec1fc63a42a99be5c3eb7107c3c54e9b9eb2bd5203b1c3b84e0a8b2f759409ba3eac9d91d402dcc0cc8f8961229ac9187b42b4de100000f000084080400804547d6168f2510c550bd949cd2bc631ff134fa10a827ff69b166a6bd95e249ed0daf571592ebbe9ff13de6b03acc218146781f693b5a692b7319d74fd2e53b6a2df0f6785d624f024a44030ca00b869ae81a532b19e47e525ff4a62c51a5889eb565fee268590d8a3ca3c1bc3bd5404e39720ca2eaee308f4e0700761e986389140000209efee03ebffbc0dc23d26d958744c09e3000477eff7ae3148a50e5670013aaaa16", "c1e631f81d2af221ebb6a957f58f3ee266272635e67f99a752f0df08adeb33bab8611e55f33d72cf84382461a8bfe0a659ba2dd1873f6fcc707a9841cefc1fb03526b9ca4fe343e5805e95a5c01e56570638a76a4bc8feb07be879f90568617d905fecd5b1619fb8ec4a6628d1bb2bb224c490ff97a6c0e9acd03604bc3a59d86bdab4e084c1c1450f9c9d2afeb172c07234d739868ebd62de2060a8de989414a82920dacd1cac0c6e72ecd7f4018574ceaca6d29f361bc37ee2888b8e302ca9561a9de9163edfa66badd4894884c7b359bcacae5908051b37952e10a45fe73fda126ebd67575f1bed8a992a89474d7dec1eed327824123a414adb66d5ef7d0836ff98c2cdd7fb0781e192bf0c7568bf7d890a51c332879b5037b212d622412ca48e8323817bd6d746eef683845cec4e3ef64b3a18fcce513ea951f3366693a7ff490d09d08ab1f63e13625a545961599c0d9c7a099d1163cad1b9bcf8e917d766b98853ef6877834f891df16be1fcc9c18ea1882ea3f1f4b64358e1b146cebfb3e02e153fdb73af2693f22c6f593fa475380ba6611740ad20e319a654ac5684775236162e8447ed808861bfbda6e18ec97ae090bf703475cfb90fe20a3c55bef6f5eba6e6a1da6a1996b8bde42180608ca2279def8e8153895cc850db6420561c04b5729cc6883436ea02ee07eb9baee2fb3a9e1bbda8730d6b220576e24df70af6928eb865fee8a1d1c0f1818aca68d5002ae4c65b2f49c9e6e21dcf76784adbd0e887a36832ef85beb10587f16c6ffe60d7451059ec7f1014c3efe19e56aedb5ad31a9f29dc4458cfbf0c7070c175dcad46e1675226b47c071aad3172ebd33e45d741cb91253a01a69ae3cc292bce9c03246ac951e45e97ebf04a9d51fab5cf06d9485cce746b1c077be69ad153f1656ef89fc7d1ed8c3e2da7a2", true, CipherSuite::TLS_AES_128_GCM_SHA256}, - CipherParams{"a0f49e7076cbe6eb25ca23a2da0eaf12", - "3485d33f22128dff91e47062", - 0, - "", - "41424344454617", - "92fdec5c241e994fb7d889e1b61d1db2b9be6777f5a393", - false, - CipherSuite::TLS_AES_128_GCM_SHA256}, - CipherParams{"a0f49e7076cae6eb25ca23a2da0eaf12", - "3485d33f22128dff91e47062", - 0, - "", - "41424344454617", - "92fdec", - false, - CipherSuite::TLS_AES_128_GCM_SHA256}, - CipherParams{ - "AD7A2BD03EAC835A6F620FDCB506B345", - "12153524C0895E81B2C28465", - 0, - "D609B1F056637A0D46DF998D88E52E00B2C2846512153524C0895E81", - "08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A0002", - "701AFA1CC039C0D765128A665DAB69243899BF7318CCDC81C9931DA17FBE8EDD7D17CB8B4C26FC81E3284F2B7FBA713D4F8D55E7D3F06FD5A13C0C29B9D5B880", - true, - CipherSuite::TLS_AES_128_GCM_SHA256}, - CipherParams{ - "AD7A2BD03EAC835A6F620FDCB506B345", - "12153524C0895E81B2C28465", - 0, - "D609B1F056637A1D46DF998D88E52E00B2C2846512153524C0895E81", - "08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A0002", - "701AFA1CC039C0D765128A665DAB69243899BF7318CCDC81C9931DA17FBE8EDD7D17CB8B4C26FC81E3284F2B7FBA713D4F8D55E7D3F06FD5A13C0C29B9D5B880", - false, - CipherSuite::TLS_AES_128_GCM_SHA256})); -} // namespace test -} // namespace fizz From 69c9f68178e387888245c2dc9b2cb16ec013538b Mon Sep 17 00:00:00 2001 From: karthikbhargavan Date: Wed, 21 Nov 2018 11:15:18 +0100 Subject: [PATCH 3/3] copyright notice --- .../experimental/hacl/Hacl_AesGCM_NI.cpp | 25 +++++++++++++++--- .../crypto/experimental/hacl/Hacl_AesGCM_NI.h | 26 +++++++++++++++---- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/fizz/crypto/experimental/hacl/Hacl_AesGCM_NI.cpp b/fizz/crypto/experimental/hacl/Hacl_AesGCM_NI.cpp index aac0ebcf2ae..bf0559e44e9 100644 --- a/fizz/crypto/experimental/hacl/Hacl_AesGCM_NI.cpp +++ b/fizz/crypto/experimental/hacl/Hacl_AesGCM_NI.cpp @@ -1,7 +1,24 @@ -/* This file was generated by KreMLin - * KreMLin invocation: /Users/bhargava/Desktop/repositories/kremlin/krml -funroll-loops 8 -warn-error +9 -I /Users/bhargava/Desktop/repositories/hacl-star//lib/ -I /Users/bhargava/Desktop/repositories/hacl-star//lib/fst -I /Users/bhargava/Desktop/repositories/kremlin/kremlib -I /Users/bhargava/Desktop/repositories/hacl-star//specs -I . -I /Users/bhargava/Desktop/repositories/hacl-star//code/experimental/aes -I /Users/bhargava/Desktop/repositories/hacl-star//code/experimental/gf128 -ccopt -march=native -fbuiltin-uint128 -drop FStar.UInt128 -fnocompound-literals -fparentheses -fcurly-braces -tmpdir aesgcm-ni-c aesgcm-ni-c/out.krml -skip-compilation -minimal -add-include "kremlib.h" -add-include "vec128.h" -drop Lib.Vec128 -bundle Hacl.AesGCM.NI=* - * F* version: 518dde40 - * KreMLin version: d94ac163 +/* MIT License + * + * Copyright (c) 2018 INRIA + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include "Hacl_AesGCM_NI.h" diff --git a/fizz/crypto/experimental/hacl/Hacl_AesGCM_NI.h b/fizz/crypto/experimental/hacl/Hacl_AesGCM_NI.h index 42f96ad2aee..db6ad84cf21 100644 --- a/fizz/crypto/experimental/hacl/Hacl_AesGCM_NI.h +++ b/fizz/crypto/experimental/hacl/Hacl_AesGCM_NI.h @@ -1,10 +1,26 @@ -/* This file was generated by KreMLin - * KreMLin invocation: /Users/bhargava/Desktop/repositories/kremlin/krml -funroll-loops 8 -warn-error +9 -I /Users/bhargava/Desktop/repositories/hacl-star//lib/ -I /Users/bhargava/Desktop/repositories/hacl-star//lib/fst -I /Users/bhargava/Desktop/repositories/kremlin/kremlib -I /Users/bhargava/Desktop/repositories/hacl-star//specs -I . -I /Users/bhargava/Desktop/repositories/hacl-star//code/experimental/aes -I /Users/bhargava/Desktop/repositories/hacl-star//code/experimental/gf128 -ccopt -march=native -fbuiltin-uint128 -drop FStar.UInt128 -fnocompound-literals -fparentheses -fcurly-braces -tmpdir aesgcm-ni-c aesgcm-ni-c/out.krml -skip-compilation -minimal -add-include "kremlib.h" -add-include "vec128.h" -drop Lib.Vec128 -bundle Hacl.AesGCM.NI=* - * F* version: 518dde40 - * KreMLin version: d94ac163 +/* MIT License + * + * Copyright (c) 2018 INRIA + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ - #ifndef __Hacl_AesGCM_NI_H #define __Hacl_AesGCM_NI_H