Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion fuzz/fuzz_unprotect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
}

// Use the first byte to select a cipher suite, remaining bytes as ciphertext.
auto suite = static_cast<CipherSuite>((data[0] % 5) + 1);
auto suite = static_cast<CipherSuite>((data[0] % 8) + 1);
auto ciphertext = input_bytes(data + 1, size - 1);

auto ctx = Context(suite);
Expand Down
6 changes: 5 additions & 1 deletion include/sframe/sframe.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ enum class CipherSuite : uint16_t
AES_128_CTR_HMAC_SHA256_32 = 3,
AES_GCM_128_SHA256 = 4,
AES_GCM_256_SHA512 = 5,
AES_256_CTR_HMAC_SHA512_80 = 6,
AES_256_CTR_HMAC_SHA512_64 = 7,
AES_256_CTR_HMAC_SHA512_32 = 8,
};

using input_bytes = span<const uint8_t>;
Expand All @@ -106,7 +109,8 @@ struct KeyRecord
KeyUsage usage,
input_bytes base_key);

static constexpr size_t max_key_size = 48;
// 32-byte AES-256 key + 64-byte HMAC-SHA512 key
static constexpr size_t max_key_size = 96;
static constexpr size_t max_salt_size = 12;

owned_bytes<max_key_size> key;
Expand Down
20 changes: 20 additions & 0 deletions src/crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ cipher_digest_size(CipherSuite suite)
return 32;

case CipherSuite::AES_GCM_256_SHA512:
case CipherSuite::AES_256_CTR_HMAC_SHA512_80:
case CipherSuite::AES_256_CTR_HMAC_SHA512_64:
case CipherSuite::AES_256_CTR_HMAC_SHA512_32:
return 64;

default:
Expand All @@ -35,6 +38,12 @@ cipher_key_size(CipherSuite suite)
// 16-byte AES key + 32-byte HMAC key
return 48;

case CipherSuite::AES_256_CTR_HMAC_SHA512_80:
case CipherSuite::AES_256_CTR_HMAC_SHA512_64:
case CipherSuite::AES_256_CTR_HMAC_SHA512_32:
// 32-byte AES key + 64-byte HMAC key
return 96;

case CipherSuite::AES_GCM_128_SHA256:
return 16;

Expand All @@ -55,6 +64,11 @@ cipher_enc_key_size(CipherSuite suite)
case CipherSuite::AES_128_CTR_HMAC_SHA256_32:
return 16;

case CipherSuite::AES_256_CTR_HMAC_SHA512_80:
case CipherSuite::AES_256_CTR_HMAC_SHA512_64:
case CipherSuite::AES_256_CTR_HMAC_SHA512_32:
return 32;

default:
return SFrameErrorType::unsupported_ciphersuite_error;
}
Expand All @@ -69,6 +83,9 @@ cipher_nonce_size(CipherSuite suite)
case CipherSuite::AES_128_CTR_HMAC_SHA256_32:
case CipherSuite::AES_GCM_128_SHA256:
case CipherSuite::AES_GCM_256_SHA512:
case CipherSuite::AES_256_CTR_HMAC_SHA512_80:
case CipherSuite::AES_256_CTR_HMAC_SHA512_64:
case CipherSuite::AES_256_CTR_HMAC_SHA512_32:
return 12;

default:
Expand All @@ -81,12 +98,15 @@ cipher_overhead(CipherSuite suite)
{
switch (suite) {
case CipherSuite::AES_128_CTR_HMAC_SHA256_80:
case CipherSuite::AES_256_CTR_HMAC_SHA512_80:
return 10; // 80-bit tag

case CipherSuite::AES_128_CTR_HMAC_SHA256_64:
case CipherSuite::AES_256_CTR_HMAC_SHA512_64:
return 8; // 64-bit tag

case CipherSuite::AES_128_CTR_HMAC_SHA256_32:
case CipherSuite::AES_256_CTR_HMAC_SHA512_32:
return 4; // 32-bit tag

case CipherSuite::AES_GCM_128_SHA256:
Expand Down
2 changes: 1 addition & 1 deletion src/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ clear_openssl_errors();
///

static constexpr size_t max_hkdf_extract_size = 64;
static constexpr size_t max_hkdf_expand_size = 64;
static constexpr size_t max_hkdf_expand_size = 96;

Result<owned_bytes<max_hkdf_extract_size>>
hkdf_extract(CipherSuite suite, input_bytes salt, input_bytes ikm);
Expand Down
24 changes: 19 additions & 5 deletions src/crypto_boringssl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ openssl_digest_type(CipherSuite suite)
return EVP_sha256();

case CipherSuite::AES_GCM_256_SHA512:
case CipherSuite::AES_256_CTR_HMAC_SHA512_80:
case CipherSuite::AES_256_CTR_HMAC_SHA512_64:
case CipherSuite::AES_256_CTR_HMAC_SHA512_32:
return EVP_sha512();

default:
Expand All @@ -55,6 +58,11 @@ openssl_cipher(CipherSuite suite)
case CipherSuite::AES_128_CTR_HMAC_SHA256_32:
return EVP_aes_128_ctr();

case CipherSuite::AES_256_CTR_HMAC_SHA512_80:
case CipherSuite::AES_256_CTR_HMAC_SHA512_64:
case CipherSuite::AES_256_CTR_HMAC_SHA512_32:
return EVP_aes_256_ctr();

case CipherSuite::AES_GCM_128_SHA256:
return EVP_aes_128_gcm();

Expand All @@ -70,12 +78,12 @@ openssl_cipher(CipherSuite suite)
/// HKDF
///

Result<owned_bytes<max_hkdf_expand_size>>
Result<owned_bytes<max_hkdf_extract_size>>
hkdf_extract(CipherSuite suite, input_bytes salt, input_bytes ikm)
{
clear_openssl_errors();
SFRAME_VALUE_OR_RETURN(md, openssl_digest_type(suite));
auto out = owned_bytes<max_hkdf_expand_size>(EVP_MD_size(md));
auto out = owned_bytes<max_hkdf_extract_size>(EVP_MD_size(md));
auto out_len = size_t(out.size());
if (1 != HKDF_extract(out.data(),
&out_len,
Expand All @@ -90,7 +98,7 @@ hkdf_extract(CipherSuite suite, input_bytes salt, input_bytes ikm)
return out;
}

Result<owned_bytes<max_hkdf_extract_size>>
Result<owned_bytes<max_hkdf_expand_size>>
hkdf_expand(CipherSuite suite, input_bytes prk, input_bytes info, size_t size)
{
clear_openssl_errors();
Expand Down Expand Up @@ -318,7 +326,10 @@ seal(CipherSuite suite,
switch (suite) {
case CipherSuite::AES_128_CTR_HMAC_SHA256_80:
case CipherSuite::AES_128_CTR_HMAC_SHA256_64:
case CipherSuite::AES_128_CTR_HMAC_SHA256_32: {
case CipherSuite::AES_128_CTR_HMAC_SHA256_32:
case CipherSuite::AES_256_CTR_HMAC_SHA512_80:
case CipherSuite::AES_256_CTR_HMAC_SHA512_64:
case CipherSuite::AES_256_CTR_HMAC_SHA512_32: {
return seal_ctr(suite, key, nonce, ct, aad, pt);
}

Expand Down Expand Up @@ -444,7 +455,10 @@ open(CipherSuite suite,
switch (suite) {
case CipherSuite::AES_128_CTR_HMAC_SHA256_80:
case CipherSuite::AES_128_CTR_HMAC_SHA256_64:
case CipherSuite::AES_128_CTR_HMAC_SHA256_32: {
case CipherSuite::AES_128_CTR_HMAC_SHA256_32:
case CipherSuite::AES_256_CTR_HMAC_SHA512_80:
case CipherSuite::AES_256_CTR_HMAC_SHA512_64:
case CipherSuite::AES_256_CTR_HMAC_SHA512_32: {
return open_ctr(suite, key, nonce, pt, aad, ct);
}

Expand Down
29 changes: 21 additions & 8 deletions src/crypto_openssl11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ openssl_digest_type(CipherSuite suite)
return EVP_sha256();

case CipherSuite::AES_GCM_256_SHA512:
case CipherSuite::AES_256_CTR_HMAC_SHA512_80:
case CipherSuite::AES_256_CTR_HMAC_SHA512_64:
case CipherSuite::AES_256_CTR_HMAC_SHA512_32:
return EVP_sha512();

default:
Expand All @@ -61,6 +64,11 @@ openssl_cipher(CipherSuite suite)
case CipherSuite::AES_128_CTR_HMAC_SHA256_32:
return EVP_aes_128_ctr();

case CipherSuite::AES_256_CTR_HMAC_SHA512_80:
case CipherSuite::AES_256_CTR_HMAC_SHA512_64:
case CipherSuite::AES_256_CTR_HMAC_SHA512_32:
return EVP_aes_256_ctr();

case CipherSuite::AES_GCM_128_SHA256:
return EVP_aes_128_gcm();

Expand Down Expand Up @@ -146,30 +154,29 @@ struct HMAC
/// HKDF
///

Result<owned_bytes<max_hkdf_expand_size>>
Result<owned_bytes<max_hkdf_extract_size>>
hkdf_extract(CipherSuite suite, input_bytes salt, input_bytes ikm)
{
clear_openssl_errors();
SFRAME_VALUE_OR_RETURN(h, HMAC::create(suite, salt));
SFRAME_VOID_OR_RETURN(h.write(ikm));

auto out = owned_bytes<max_hkdf_expand_size>();
auto out = owned_bytes<max_hkdf_extract_size>();
SFRAME_VALUE_OR_RETURN(md, h.digest(out));
out.resize(md.size());
return out;
}

Result<owned_bytes<max_hkdf_extract_size>>
Result<owned_bytes<max_hkdf_expand_size>>
hkdf_expand(CipherSuite suite, input_bytes prk, input_bytes info, size_t size)
{
clear_openssl_errors();
// Ensure that we need only one hash invocation
if (size > max_hkdf_extract_size) {
if (size > max_hkdf_expand_size) {
return SFrameError(SFrameErrorType::invalid_parameter_error,
"Size too big for hkdf_expand");
}

auto out = owned_bytes<max_hkdf_extract_size>(0);
auto out = owned_bytes<max_hkdf_expand_size>(0);

auto block = owned_bytes<max_hkdf_extract_size>(0);
SFRAME_VALUE_OR_RETURN(block_size, cipher_digest_size(suite));
Expand Down Expand Up @@ -370,7 +377,10 @@ seal(CipherSuite suite,
switch (suite) {
case CipherSuite::AES_128_CTR_HMAC_SHA256_80:
case CipherSuite::AES_128_CTR_HMAC_SHA256_64:
case CipherSuite::AES_128_CTR_HMAC_SHA256_32: {
case CipherSuite::AES_128_CTR_HMAC_SHA256_32:
case CipherSuite::AES_256_CTR_HMAC_SHA512_80:
case CipherSuite::AES_256_CTR_HMAC_SHA512_64:
case CipherSuite::AES_256_CTR_HMAC_SHA512_32: {
return seal_ctr(suite, key, nonce, ct, aad, pt);
}

Expand Down Expand Up @@ -496,7 +506,10 @@ open(CipherSuite suite,
switch (suite) {
case CipherSuite::AES_128_CTR_HMAC_SHA256_80:
case CipherSuite::AES_128_CTR_HMAC_SHA256_64:
case CipherSuite::AES_128_CTR_HMAC_SHA256_32: {
case CipherSuite::AES_128_CTR_HMAC_SHA256_32:
case CipherSuite::AES_256_CTR_HMAC_SHA512_80:
case CipherSuite::AES_256_CTR_HMAC_SHA512_64:
case CipherSuite::AES_256_CTR_HMAC_SHA512_32: {
return open_ctr(suite, key, nonce, pt, aad, ct);
}

Expand Down
24 changes: 19 additions & 5 deletions src/crypto_openssl3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ openssl_cipher(CipherSuite suite)
case CipherSuite::AES_128_CTR_HMAC_SHA256_32:
return EVP_aes_128_ctr();

case CipherSuite::AES_256_CTR_HMAC_SHA512_80:
case CipherSuite::AES_256_CTR_HMAC_SHA512_64:
case CipherSuite::AES_256_CTR_HMAC_SHA512_32:
return EVP_aes_256_ctr();

case CipherSuite::AES_GCM_128_SHA256:
return EVP_aes_128_gcm();

Expand All @@ -60,6 +65,9 @@ openssl_digest_name(CipherSuite suite)
return std::string(OSSL_DIGEST_NAME_SHA2_256);

case CipherSuite::AES_GCM_256_SHA512:
case CipherSuite::AES_256_CTR_HMAC_SHA512_80:
case CipherSuite::AES_256_CTR_HMAC_SHA512_64:
case CipherSuite::AES_256_CTR_HMAC_SHA512_32:
return std::string(OSSL_DIGEST_NAME_SHA2_512);

default:
Expand All @@ -75,7 +83,7 @@ using scoped_evp_kdf = std::unique_ptr<EVP_KDF, decltype(&EVP_KDF_free)>;
using scoped_evp_kdf_ctx =
std::unique_ptr<EVP_KDF_CTX, decltype(&EVP_KDF_CTX_free)>;

Result<owned_bytes<max_hkdf_expand_size>>
Result<owned_bytes<max_hkdf_extract_size>>
hkdf_extract(CipherSuite suite, input_bytes salt, input_bytes ikm)
{
clear_openssl_errors();
Expand Down Expand Up @@ -104,15 +112,15 @@ hkdf_extract(CipherSuite suite, input_bytes salt, input_bytes ikm)
}

const auto digest_size = EVP_KDF_CTX_get_kdf_size(ctx.get());
auto out = owned_bytes<max_hkdf_expand_size>(digest_size);
auto out = owned_bytes<max_hkdf_extract_size>(digest_size);
if (1 != EVP_KDF_derive(ctx.get(), out.data(), out.size(), nullptr)) {
return SFrameErrorType::crypto_error;
}

return out;
}

Result<owned_bytes<max_hkdf_extract_size>>
Result<owned_bytes<max_hkdf_expand_size>>
hkdf_expand(CipherSuite suite, input_bytes prk, input_bytes info, size_t size)
{
clear_openssl_errors();
Expand Down Expand Up @@ -359,7 +367,10 @@ seal(CipherSuite suite,
switch (suite) {
case CipherSuite::AES_128_CTR_HMAC_SHA256_80:
case CipherSuite::AES_128_CTR_HMAC_SHA256_64:
case CipherSuite::AES_128_CTR_HMAC_SHA256_32: {
case CipherSuite::AES_128_CTR_HMAC_SHA256_32:
case CipherSuite::AES_256_CTR_HMAC_SHA512_80:
case CipherSuite::AES_256_CTR_HMAC_SHA512_64:
case CipherSuite::AES_256_CTR_HMAC_SHA512_32: {
return seal_ctr(suite, key, nonce, ct, aad, pt);
}

Expand Down Expand Up @@ -485,7 +496,10 @@ open(CipherSuite suite,
switch (suite) {
case CipherSuite::AES_128_CTR_HMAC_SHA256_80:
case CipherSuite::AES_128_CTR_HMAC_SHA256_64:
case CipherSuite::AES_128_CTR_HMAC_SHA256_32: {
case CipherSuite::AES_128_CTR_HMAC_SHA256_32:
case CipherSuite::AES_256_CTR_HMAC_SHA512_80:
case CipherSuite::AES_256_CTR_HMAC_SHA512_64:
case CipherSuite::AES_256_CTR_HMAC_SHA512_32: {
return open_ctr(suite, key, nonce, pt, aad, ct);
}

Expand Down
6 changes: 4 additions & 2 deletions src/sframe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,8 +359,10 @@ MLSContext::EpochKeys::base_key(CipherSuite ciphersuite,
auto enc_sender_id = owned_bytes<8>();
encode_uint(sender_id, enc_sender_id);

return hkdf_expand(
ciphersuite, sframe_epoch_secret, enc_sender_id, hash_size);
SFRAME_VALUE_OR_RETURN(
expanded,
hkdf_expand(ciphersuite, sframe_epoch_secret, enc_sender_id, hash_size));
return owned_bytes<max_secret_size>(expanded);
}

void
Expand Down
Loading
Loading