Refactor HPKE API to include explicit length parameters.
Bug: 275 Change-Id: I724e9315b860e230e8fed92de34d89a875ef043c Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/46184 Reviewed-by: David Benjamin <davidben@google.com> Commit-Queue: David Benjamin <davidben@google.com>
This commit is contained in:
parent
c9d3265a92
commit
d9ee55a89f
@ -9,6 +9,7 @@ EVP,106,EXPECTING_AN_EC_KEY_KEY
|
||||
EVP,107,EXPECTING_AN_RSA_KEY
|
||||
EVP,108,EXPECTING_A_DSA_KEY
|
||||
EVP,109,ILLEGAL_OR_UNSUPPORTED_PADDING_MODE
|
||||
EVP,137,INVALID_BUFFER_SIZE
|
||||
EVP,110,INVALID_DIGEST_LENGTH
|
||||
EVP,111,INVALID_DIGEST_TYPE
|
||||
EVP,112,INVALID_KEYBITS
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include <openssl/aead.h>
|
||||
#include <openssl/bytestring.h>
|
||||
#include <openssl/curve25519.h>
|
||||
#include <openssl/digest.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp_errors.h>
|
||||
@ -316,27 +317,44 @@ void EVP_HPKE_CTX_cleanup(EVP_HPKE_CTX *ctx) {
|
||||
EVP_AEAD_CTX_cleanup(&ctx->aead_ctx);
|
||||
}
|
||||
|
||||
int EVP_HPKE_CTX_setup_base_s_x25519(
|
||||
EVP_HPKE_CTX *hpke, uint8_t out_enc[X25519_PUBLIC_VALUE_LEN],
|
||||
uint16_t kdf_id, uint16_t aead_id,
|
||||
const uint8_t peer_public_value[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t *info, size_t info_len) {
|
||||
int EVP_HPKE_CTX_setup_base_s_x25519(EVP_HPKE_CTX *hpke, uint8_t *out_enc,
|
||||
size_t out_enc_len, uint16_t kdf_id,
|
||||
uint16_t aead_id,
|
||||
const uint8_t *peer_public_value,
|
||||
size_t peer_public_value_len,
|
||||
const uint8_t *info, size_t info_len) {
|
||||
if (out_enc_len != X25519_PUBLIC_VALUE_LEN) {
|
||||
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_BUFFER_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The GenerateKeyPair() step technically belongs in the KEM's Encap()
|
||||
// function, but we've moved it up a layer to make it easier for tests to
|
||||
// inject an ephemeral keypair.
|
||||
uint8_t ephemeral_private[X25519_PRIVATE_KEY_LEN];
|
||||
X25519_keypair(out_enc, ephemeral_private);
|
||||
return EVP_HPKE_CTX_setup_base_s_x25519_for_test(
|
||||
hpke, kdf_id, aead_id, peer_public_value, info, info_len,
|
||||
ephemeral_private, out_enc);
|
||||
hpke, kdf_id, aead_id, peer_public_value, peer_public_value_len, info,
|
||||
info_len, ephemeral_private, sizeof(ephemeral_private), out_enc,
|
||||
out_enc_len);
|
||||
}
|
||||
|
||||
int EVP_HPKE_CTX_setup_base_s_x25519_for_test(
|
||||
EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id,
|
||||
const uint8_t peer_public_value[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t *info, size_t info_len,
|
||||
const uint8_t ephemeral_private[X25519_PRIVATE_KEY_LEN],
|
||||
const uint8_t ephemeral_public[X25519_PUBLIC_VALUE_LEN]) {
|
||||
const uint8_t *peer_public_value, size_t peer_public_value_len,
|
||||
const uint8_t *info, size_t info_len, const uint8_t *ephemeral_private,
|
||||
size_t ephemeral_private_len, const uint8_t *ephemeral_public,
|
||||
size_t ephemeral_public_len) {
|
||||
if (peer_public_value_len != X25519_PUBLIC_VALUE_LEN) {
|
||||
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
|
||||
return 0;
|
||||
}
|
||||
if (ephemeral_private_len != X25519_PRIVATE_KEY_LEN ||
|
||||
ephemeral_public_len != X25519_PUBLIC_VALUE_LEN) {
|
||||
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
hpke->is_sender = 1;
|
||||
hpke->kdf_id = kdf_id;
|
||||
hpke->aead_id = aead_id;
|
||||
@ -355,12 +373,23 @@ int EVP_HPKE_CTX_setup_base_s_x25519_for_test(
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_HPKE_CTX_setup_base_r_x25519(
|
||||
EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id,
|
||||
const uint8_t enc[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t public_key[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t private_key[X25519_PRIVATE_KEY_LEN], const uint8_t *info,
|
||||
size_t info_len) {
|
||||
int EVP_HPKE_CTX_setup_base_r_x25519(EVP_HPKE_CTX *hpke, uint16_t kdf_id,
|
||||
uint16_t aead_id, const uint8_t *enc,
|
||||
size_t enc_len, const uint8_t *public_key,
|
||||
size_t public_key_len,
|
||||
const uint8_t *private_key,
|
||||
size_t private_key_len,
|
||||
const uint8_t *info, size_t info_len) {
|
||||
if (enc_len != X25519_PUBLIC_VALUE_LEN) {
|
||||
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
|
||||
return 0;
|
||||
}
|
||||
if (public_key_len != X25519_PUBLIC_VALUE_LEN ||
|
||||
private_key_len != X25519_PRIVATE_KEY_LEN) {
|
||||
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
hpke->is_sender = 0;
|
||||
hpke->kdf_id = kdf_id;
|
||||
hpke->aead_id = aead_id;
|
||||
@ -378,29 +407,47 @@ int EVP_HPKE_CTX_setup_base_r_x25519(
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_HPKE_CTX_setup_psk_s_x25519(
|
||||
EVP_HPKE_CTX *hpke, uint8_t out_enc[X25519_PUBLIC_VALUE_LEN],
|
||||
uint16_t kdf_id, uint16_t aead_id,
|
||||
const uint8_t peer_public_value[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t *info, size_t info_len, const uint8_t *psk, size_t psk_len,
|
||||
const uint8_t *psk_id, size_t psk_id_len) {
|
||||
int EVP_HPKE_CTX_setup_psk_s_x25519(EVP_HPKE_CTX *hpke, uint8_t *out_enc,
|
||||
size_t out_enc_len, uint16_t kdf_id,
|
||||
uint16_t aead_id,
|
||||
const uint8_t *peer_public_value,
|
||||
size_t peer_public_value_len,
|
||||
const uint8_t *info, size_t info_len,
|
||||
const uint8_t *psk, size_t psk_len,
|
||||
const uint8_t *psk_id, size_t psk_id_len) {
|
||||
if (out_enc_len != X25519_PUBLIC_VALUE_LEN) {
|
||||
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_BUFFER_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The GenerateKeyPair() step technically belongs in the KEM's Encap()
|
||||
// function, but we've moved it up a layer to make it easier for tests to
|
||||
// inject an ephemeral keypair.
|
||||
uint8_t ephemeral_private[X25519_PRIVATE_KEY_LEN];
|
||||
X25519_keypair(out_enc, ephemeral_private);
|
||||
return EVP_HPKE_CTX_setup_psk_s_x25519_for_test(
|
||||
hpke, kdf_id, aead_id, peer_public_value, info, info_len, psk, psk_len,
|
||||
psk_id, psk_id_len, ephemeral_private, out_enc);
|
||||
hpke, kdf_id, aead_id, peer_public_value, peer_public_value_len, info,
|
||||
info_len, psk, psk_len, psk_id, psk_id_len, ephemeral_private,
|
||||
sizeof(ephemeral_private), out_enc, out_enc_len);
|
||||
}
|
||||
|
||||
int EVP_HPKE_CTX_setup_psk_s_x25519_for_test(
|
||||
EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id,
|
||||
const uint8_t peer_public_value[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t *peer_public_value, size_t peer_public_value_len,
|
||||
const uint8_t *info, size_t info_len, const uint8_t *psk, size_t psk_len,
|
||||
const uint8_t *psk_id, size_t psk_id_len,
|
||||
const uint8_t ephemeral_private[X25519_PRIVATE_KEY_LEN],
|
||||
const uint8_t ephemeral_public[X25519_PUBLIC_VALUE_LEN]) {
|
||||
const uint8_t *psk_id, size_t psk_id_len, const uint8_t *ephemeral_private,
|
||||
size_t ephemeral_private_len, const uint8_t *ephemeral_public,
|
||||
size_t ephemeral_public_len) {
|
||||
if (peer_public_value_len != X25519_PUBLIC_VALUE_LEN) {
|
||||
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
|
||||
return 0;
|
||||
}
|
||||
if (ephemeral_private_len != X25519_PRIVATE_KEY_LEN ||
|
||||
ephemeral_public_len != X25519_PUBLIC_VALUE_LEN) {
|
||||
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
hpke->is_sender = 1;
|
||||
hpke->kdf_id = kdf_id;
|
||||
hpke->aead_id = aead_id;
|
||||
@ -420,12 +467,21 @@ int EVP_HPKE_CTX_setup_psk_s_x25519_for_test(
|
||||
}
|
||||
|
||||
int EVP_HPKE_CTX_setup_psk_r_x25519(
|
||||
EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id,
|
||||
const uint8_t enc[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t public_key[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t private_key[X25519_PRIVATE_KEY_LEN], const uint8_t *info,
|
||||
EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id, const uint8_t *enc,
|
||||
size_t enc_len, const uint8_t *public_key, size_t public_key_len,
|
||||
const uint8_t *private_key, size_t private_key_len, const uint8_t *info,
|
||||
size_t info_len, const uint8_t *psk, size_t psk_len, const uint8_t *psk_id,
|
||||
size_t psk_id_len) {
|
||||
if (enc_len != X25519_PUBLIC_VALUE_LEN) {
|
||||
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
|
||||
return 0;
|
||||
}
|
||||
if (public_key_len != X25519_PUBLIC_VALUE_LEN ||
|
||||
private_key_len != X25519_PRIVATE_KEY_LEN) {
|
||||
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
hpke->is_sender = 0;
|
||||
hpke->kdf_id = kdf_id;
|
||||
hpke->aead_id = aead_id;
|
||||
|
@ -62,13 +62,15 @@ class HPKETestVector {
|
||||
// Set up the sender.
|
||||
ASSERT_TRUE(EVP_HPKE_CTX_setup_base_s_x25519_for_test(
|
||||
sender_ctx.get(), kdf_id_, aead_id_, public_key_r_.data(),
|
||||
info_.data(), info_.size(), secret_key_e_.data(),
|
||||
public_key_e_.data()));
|
||||
public_key_r_.size(), info_.data(), info_.size(),
|
||||
secret_key_e_.data(), secret_key_e_.size(), public_key_e_.data(),
|
||||
public_key_e_.size()));
|
||||
|
||||
// Set up the receiver.
|
||||
ASSERT_TRUE(EVP_HPKE_CTX_setup_base_r_x25519(
|
||||
receiver_ctx.get(), kdf_id_, aead_id_, public_key_e_.data(),
|
||||
public_key_r_.data(), secret_key_r_.data(), info_.data(),
|
||||
public_key_e_.size(), public_key_r_.data(), public_key_r_.size(),
|
||||
secret_key_r_.data(), secret_key_r_.size(), info_.data(),
|
||||
info_.size()));
|
||||
break;
|
||||
|
||||
@ -80,14 +82,15 @@ class HPKETestVector {
|
||||
// Set up the sender.
|
||||
ASSERT_TRUE(EVP_HPKE_CTX_setup_psk_s_x25519_for_test(
|
||||
sender_ctx.get(), kdf_id_, aead_id_, public_key_r_.data(),
|
||||
info_.data(), info_.size(), psk_.data(), psk_.size(),
|
||||
psk_id_.data(), psk_id_.size(), secret_key_e_.data(),
|
||||
public_key_e_.data()));
|
||||
public_key_r_.size(), info_.data(), info_.size(), psk_.data(),
|
||||
psk_.size(), psk_id_.data(), psk_id_.size(), secret_key_e_.data(),
|
||||
secret_key_e_.size(), public_key_e_.data(), public_key_e_.size()));
|
||||
|
||||
// Set up the receiver.
|
||||
ASSERT_TRUE(EVP_HPKE_CTX_setup_psk_r_x25519(
|
||||
receiver_ctx.get(), kdf_id_, aead_id_, public_key_e_.data(),
|
||||
public_key_r_.data(), secret_key_r_.data(), info_.data(),
|
||||
public_key_e_.size(), public_key_r_.data(), public_key_r_.size(),
|
||||
secret_key_r_.data(), secret_key_r_.size(), info_.data(),
|
||||
info_.size(), psk_.data(), psk_.size(), psk_id_.data(),
|
||||
psk_id_.size()));
|
||||
break;
|
||||
@ -282,14 +285,15 @@ TEST(HPKETest, RoundTrip) {
|
||||
ScopedEVP_HPKE_CTX sender_ctx;
|
||||
uint8_t enc[X25519_PUBLIC_VALUE_LEN];
|
||||
ASSERT_TRUE(EVP_HPKE_CTX_setup_base_s_x25519(
|
||||
sender_ctx.get(), enc, kdf_id, aead_id, public_key_r, info.data(),
|
||||
info.size()));
|
||||
sender_ctx.get(), enc, sizeof(enc), kdf_id, aead_id, public_key_r,
|
||||
sizeof(public_key_r), info.data(), info.size()));
|
||||
|
||||
// Set up the receiver.
|
||||
ScopedEVP_HPKE_CTX receiver_ctx;
|
||||
ASSERT_TRUE(EVP_HPKE_CTX_setup_base_r_x25519(
|
||||
receiver_ctx.get(), kdf_id, aead_id, enc, public_key_r,
|
||||
secret_key_r, info.data(), info.size()));
|
||||
receiver_ctx.get(), kdf_id, aead_id, enc, sizeof(enc),
|
||||
public_key_r, sizeof(public_key_r), secret_key_r,
|
||||
sizeof(secret_key_r), info.data(), info.size()));
|
||||
|
||||
const char kCleartextPayload[] = "foobar";
|
||||
|
||||
@ -347,14 +351,15 @@ TEST(HPKETest, X25519EncapSmallOrderPoint) {
|
||||
ScopedEVP_HPKE_CTX sender_ctx;
|
||||
uint8_t enc[X25519_PUBLIC_VALUE_LEN];
|
||||
ASSERT_FALSE(EVP_HPKE_CTX_setup_base_s_x25519(
|
||||
sender_ctx.get(), enc, kdf_id, aead_id, kSmallOrderPoint, nullptr,
|
||||
0));
|
||||
sender_ctx.get(), enc, sizeof(enc), kdf_id, aead_id, kSmallOrderPoint,
|
||||
sizeof(kSmallOrderPoint), nullptr, 0));
|
||||
|
||||
// Set up the receiver, passing in kSmallOrderPoint as |enc|.
|
||||
ScopedEVP_HPKE_CTX receiver_ctx;
|
||||
ASSERT_FALSE(EVP_HPKE_CTX_setup_base_r_x25519(
|
||||
receiver_ctx.get(), kdf_id, aead_id, kSmallOrderPoint, public_key_r,
|
||||
secret_key_r, nullptr, 0));
|
||||
receiver_ctx.get(), kdf_id, aead_id, kSmallOrderPoint,
|
||||
sizeof(kSmallOrderPoint), public_key_r, sizeof(public_key_r),
|
||||
secret_key_r, sizeof(secret_key_r), nullptr, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -373,7 +378,8 @@ TEST(HPKETest, ReceiverInvalidSeal) {
|
||||
ScopedEVP_HPKE_CTX receiver_ctx;
|
||||
ASSERT_TRUE(EVP_HPKE_CTX_setup_base_r_x25519(
|
||||
receiver_ctx.get(), EVP_HPKE_HKDF_SHA256, EVP_HPKE_AEAD_AES_GCM_128,
|
||||
kMockEnc, public_key_r, secret_key_r, nullptr, 0));
|
||||
kMockEnc, sizeof(kMockEnc), public_key_r, sizeof(public_key_r),
|
||||
secret_key_r, sizeof(secret_key_r), nullptr, 0));
|
||||
|
||||
// Call Seal() on the receiver.
|
||||
size_t ciphertext_len;
|
||||
@ -398,8 +404,9 @@ TEST(HPKETest, SenderInvalidOpen) {
|
||||
ScopedEVP_HPKE_CTX sender_ctx;
|
||||
uint8_t enc[X25519_PUBLIC_VALUE_LEN];
|
||||
ASSERT_TRUE(EVP_HPKE_CTX_setup_base_s_x25519(
|
||||
sender_ctx.get(), enc, EVP_HPKE_HKDF_SHA256, EVP_HPKE_AEAD_AES_GCM_128,
|
||||
public_key_r, nullptr, 0));
|
||||
sender_ctx.get(), enc, sizeof(enc), EVP_HPKE_HKDF_SHA256,
|
||||
EVP_HPKE_AEAD_AES_GCM_128, public_key_r, sizeof(public_key_r), nullptr,
|
||||
0));
|
||||
|
||||
// Call Open() on the sender.
|
||||
uint8_t cleartext[128];
|
||||
@ -432,24 +439,10 @@ TEST(HPKETest, EmptyPSK) {
|
||||
|
||||
ScopedEVP_HPKE_CTX sender_ctx;
|
||||
uint8_t enc[X25519_PUBLIC_VALUE_LEN];
|
||||
ASSERT_EQ(EVP_HPKE_CTX_setup_psk_s_x25519(
|
||||
sender_ctx.get(), enc, EVP_HPKE_HKDF_SHA256,
|
||||
EVP_HPKE_AEAD_AES_GCM_128, public_key_r, nullptr, 0,
|
||||
psk.data(), psk.size(), psk_id.data(), psk_id.size()),
|
||||
kExpectSuccess);
|
||||
|
||||
if (!kExpectSuccess) {
|
||||
uint32_t err = ERR_get_error();
|
||||
EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
|
||||
EXPECT_EQ(EVP_R_EMPTY_PSK, ERR_GET_REASON(err));
|
||||
}
|
||||
ERR_clear_error();
|
||||
|
||||
ScopedEVP_HPKE_CTX receiver_ctx;
|
||||
ASSERT_EQ(
|
||||
EVP_HPKE_CTX_setup_psk_r_x25519(
|
||||
receiver_ctx.get(), EVP_HPKE_HKDF_SHA256,
|
||||
EVP_HPKE_AEAD_AES_GCM_128, kMockEnc, public_key_r, secret_key_r,
|
||||
EVP_HPKE_CTX_setup_psk_s_x25519(
|
||||
sender_ctx.get(), enc, sizeof(enc), EVP_HPKE_HKDF_SHA256,
|
||||
EVP_HPKE_AEAD_AES_GCM_128, public_key_r, sizeof(public_key_r),
|
||||
nullptr, 0, psk.data(), psk.size(), psk_id.data(), psk_id.size()),
|
||||
kExpectSuccess);
|
||||
|
||||
@ -459,10 +452,185 @@ TEST(HPKETest, EmptyPSK) {
|
||||
EXPECT_EQ(EVP_R_EMPTY_PSK, ERR_GET_REASON(err));
|
||||
}
|
||||
ERR_clear_error();
|
||||
|
||||
ScopedEVP_HPKE_CTX receiver_ctx;
|
||||
ASSERT_EQ(EVP_HPKE_CTX_setup_psk_r_x25519(
|
||||
receiver_ctx.get(), EVP_HPKE_HKDF_SHA256,
|
||||
EVP_HPKE_AEAD_AES_GCM_128, kMockEnc, sizeof(kMockEnc),
|
||||
public_key_r, sizeof(public_key_r), secret_key_r,
|
||||
sizeof(secret_key_r), nullptr, 0, psk.data(), psk.size(),
|
||||
psk_id.data(), psk_id.size()),
|
||||
kExpectSuccess);
|
||||
|
||||
if (!kExpectSuccess) {
|
||||
uint32_t err = ERR_get_error();
|
||||
EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
|
||||
EXPECT_EQ(EVP_R_EMPTY_PSK, ERR_GET_REASON(err));
|
||||
}
|
||||
ERR_clear_error();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(HPKETest, SetupSenderWrongLengthEnc) {
|
||||
uint8_t secret_key_r[X25519_PRIVATE_KEY_LEN];
|
||||
uint8_t public_key_r[X25519_PUBLIC_VALUE_LEN];
|
||||
X25519_keypair(public_key_r, secret_key_r);
|
||||
|
||||
ScopedEVP_HPKE_CTX sender_ctx;
|
||||
uint8_t bogus_enc[X25519_PUBLIC_VALUE_LEN + 5];
|
||||
{
|
||||
ASSERT_FALSE(EVP_HPKE_CTX_setup_base_s_x25519(
|
||||
sender_ctx.get(), bogus_enc, sizeof(bogus_enc), EVP_HPKE_HKDF_SHA256,
|
||||
EVP_HPKE_AEAD_AES_GCM_128, public_key_r, sizeof(public_key_r), nullptr,
|
||||
0));
|
||||
uint32_t err = ERR_get_error();
|
||||
EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
|
||||
EXPECT_EQ(EVP_R_INVALID_BUFFER_SIZE, ERR_GET_REASON(err));
|
||||
ERR_clear_error();
|
||||
}
|
||||
{
|
||||
const uint8_t psk[] = {1, 2, 3, 4};
|
||||
const uint8_t psk_id[] = {1, 2, 3, 4};
|
||||
ASSERT_FALSE(EVP_HPKE_CTX_setup_psk_s_x25519(
|
||||
sender_ctx.get(), bogus_enc, sizeof(bogus_enc), EVP_HPKE_HKDF_SHA256,
|
||||
EVP_HPKE_AEAD_AES_GCM_128, public_key_r, sizeof(public_key_r), nullptr,
|
||||
0, psk, sizeof(psk), psk_id, sizeof(psk_id)));
|
||||
uint32_t err = ERR_get_error();
|
||||
EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
|
||||
EXPECT_EQ(EVP_R_INVALID_BUFFER_SIZE, ERR_GET_REASON(err));
|
||||
ERR_clear_error();
|
||||
}
|
||||
}
|
||||
|
||||
TEST(HPKETest, SetupReceiverWrongLengthEnc) {
|
||||
uint8_t private_key[X25519_PRIVATE_KEY_LEN];
|
||||
uint8_t public_key[X25519_PUBLIC_VALUE_LEN];
|
||||
X25519_keypair(public_key, private_key);
|
||||
|
||||
const uint8_t bogus_enc[X25519_PUBLIC_VALUE_LEN + 5] = {0xff};
|
||||
|
||||
ScopedEVP_HPKE_CTX receiver_ctx;
|
||||
{
|
||||
ASSERT_FALSE(EVP_HPKE_CTX_setup_base_r_x25519(
|
||||
receiver_ctx.get(), EVP_HPKE_HKDF_SHA256, EVP_HPKE_AEAD_AES_GCM_128,
|
||||
bogus_enc, sizeof(bogus_enc), public_key, sizeof(public_key),
|
||||
private_key, sizeof(private_key), nullptr, 0));
|
||||
uint32_t err = ERR_get_error();
|
||||
EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
|
||||
EXPECT_EQ(EVP_R_INVALID_PEER_KEY, ERR_GET_REASON(err));
|
||||
ERR_clear_error();
|
||||
}
|
||||
{
|
||||
const uint8_t psk[] = {1, 2, 3, 4};
|
||||
const uint8_t psk_id[] = {1, 2, 3, 4};
|
||||
ASSERT_FALSE(EVP_HPKE_CTX_setup_psk_r_x25519(
|
||||
receiver_ctx.get(), EVP_HPKE_HKDF_SHA256, EVP_HPKE_AEAD_AES_GCM_128,
|
||||
bogus_enc, sizeof(bogus_enc), public_key, sizeof(public_key),
|
||||
private_key, sizeof(private_key), nullptr, 0, psk, sizeof(psk), psk_id,
|
||||
sizeof(psk_id)));
|
||||
uint32_t err = ERR_get_error();
|
||||
EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
|
||||
EXPECT_EQ(EVP_R_INVALID_PEER_KEY, ERR_GET_REASON(err));
|
||||
ERR_clear_error();
|
||||
}
|
||||
}
|
||||
|
||||
TEST(HPKETest, SetupSenderWrongLengthPeerPublicValue) {
|
||||
const uint8_t bogus_public_key_r[X25519_PRIVATE_KEY_LEN + 5] = {0xff};
|
||||
ScopedEVP_HPKE_CTX sender_ctx;
|
||||
uint8_t enc[X25519_PUBLIC_VALUE_LEN];
|
||||
{
|
||||
ASSERT_FALSE(EVP_HPKE_CTX_setup_base_s_x25519(
|
||||
sender_ctx.get(), enc, sizeof(enc), EVP_HPKE_HKDF_SHA256,
|
||||
EVP_HPKE_AEAD_AES_GCM_128, bogus_public_key_r,
|
||||
sizeof(bogus_public_key_r), nullptr, 0));
|
||||
uint32_t err = ERR_get_error();
|
||||
EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
|
||||
EXPECT_EQ(EVP_R_INVALID_PEER_KEY, ERR_GET_REASON(err));
|
||||
ERR_clear_error();
|
||||
}
|
||||
{
|
||||
const uint8_t psk[] = {1, 2, 3, 4};
|
||||
const uint8_t psk_id[] = {1, 2, 3, 4};
|
||||
|
||||
ASSERT_FALSE(EVP_HPKE_CTX_setup_psk_s_x25519(
|
||||
sender_ctx.get(), enc, sizeof(enc), EVP_HPKE_HKDF_SHA256,
|
||||
EVP_HPKE_AEAD_AES_GCM_128, bogus_public_key_r,
|
||||
sizeof(bogus_public_key_r), nullptr, 0, psk, sizeof(psk), psk_id,
|
||||
sizeof(psk_id)));
|
||||
uint32_t err = ERR_get_error();
|
||||
EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
|
||||
EXPECT_EQ(EVP_R_INVALID_PEER_KEY, ERR_GET_REASON(err));
|
||||
ERR_clear_error();
|
||||
}
|
||||
}
|
||||
|
||||
TEST(HPKETest, SetupReceiverWrongLengthKeys) {
|
||||
uint8_t private_key[X25519_PRIVATE_KEY_LEN];
|
||||
uint8_t public_key[X25519_PUBLIC_VALUE_LEN];
|
||||
X25519_keypair(public_key, private_key);
|
||||
|
||||
uint8_t unused[X25519_PRIVATE_KEY_LEN];
|
||||
uint8_t enc[X25519_PUBLIC_VALUE_LEN];
|
||||
X25519_keypair(enc, unused);
|
||||
|
||||
const uint8_t bogus_public_key[X25519_PUBLIC_VALUE_LEN + 5] = {0xff};
|
||||
const uint8_t bogus_private_key[X25519_PUBLIC_VALUE_LEN + 5] = {0xff};
|
||||
|
||||
ScopedEVP_HPKE_CTX receiver_ctx;
|
||||
{
|
||||
// Test base mode with |bogus_public_key|.
|
||||
ASSERT_FALSE(EVP_HPKE_CTX_setup_base_r_x25519(
|
||||
receiver_ctx.get(), EVP_HPKE_HKDF_SHA256, EVP_HPKE_AEAD_AES_GCM_128,
|
||||
enc, sizeof(enc), bogus_public_key, sizeof(bogus_public_key),
|
||||
private_key, sizeof(private_key), nullptr, 0));
|
||||
uint32_t err = ERR_get_error();
|
||||
EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
|
||||
EXPECT_EQ(EVP_R_DECODE_ERROR, ERR_GET_REASON(err));
|
||||
ERR_clear_error();
|
||||
}
|
||||
{
|
||||
// Test base mode with |bogus_private_key|.
|
||||
ASSERT_FALSE(EVP_HPKE_CTX_setup_base_r_x25519(
|
||||
receiver_ctx.get(), EVP_HPKE_HKDF_SHA256, EVP_HPKE_AEAD_AES_GCM_128,
|
||||
enc, sizeof(enc), public_key, sizeof(public_key), bogus_private_key,
|
||||
sizeof(bogus_private_key), nullptr, 0));
|
||||
uint32_t err = ERR_get_error();
|
||||
EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
|
||||
EXPECT_EQ(EVP_R_DECODE_ERROR, ERR_GET_REASON(err));
|
||||
ERR_clear_error();
|
||||
}
|
||||
{
|
||||
// Test PSK mode with |bogus_public_key|.
|
||||
const uint8_t psk[] = {1, 2, 3, 4};
|
||||
const uint8_t psk_id[] = {1, 2, 3, 4};
|
||||
ASSERT_FALSE(EVP_HPKE_CTX_setup_psk_r_x25519(
|
||||
receiver_ctx.get(), EVP_HPKE_HKDF_SHA256, EVP_HPKE_AEAD_AES_GCM_128,
|
||||
enc, sizeof(enc), bogus_public_key, sizeof(bogus_public_key),
|
||||
private_key, sizeof(private_key), nullptr, 0, psk, sizeof(psk), psk_id,
|
||||
sizeof(psk_id)));
|
||||
uint32_t err = ERR_get_error();
|
||||
EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
|
||||
EXPECT_EQ(EVP_R_DECODE_ERROR, ERR_GET_REASON(err));
|
||||
ERR_clear_error();
|
||||
}
|
||||
{
|
||||
// Test PSK mode with |bogus_private_key|.
|
||||
const uint8_t psk[] = {1, 2, 3, 4};
|
||||
const uint8_t psk_id[] = {1, 2, 3, 4};
|
||||
ASSERT_FALSE(EVP_HPKE_CTX_setup_psk_r_x25519(
|
||||
receiver_ctx.get(), EVP_HPKE_HKDF_SHA256, EVP_HPKE_AEAD_AES_GCM_128,
|
||||
enc, sizeof(enc), public_key, sizeof(public_key), bogus_private_key,
|
||||
sizeof(bogus_private_key), nullptr, 0, psk, sizeof(psk), psk_id,
|
||||
sizeof(psk_id)));
|
||||
uint32_t err = ERR_get_error();
|
||||
EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
|
||||
EXPECT_EQ(EVP_R_DECODE_ERROR, ERR_GET_REASON(err));
|
||||
ERR_clear_error();
|
||||
}
|
||||
}
|
||||
|
||||
TEST(HPKETest, InternalParseIntSafe) {
|
||||
uint8_t u8 = 0xff;
|
||||
ASSERT_FALSE(ParseIntSafe(&u8, "-1"));
|
||||
|
@ -86,32 +86,35 @@ OPENSSL_EXPORT void EVP_HPKE_CTX_cleanup(EVP_HPKE_CTX *ctx);
|
||||
// recipient's public key). It returns one on success, and zero otherwise. Note
|
||||
// that this function will fail if |peer_public_value| is invalid.
|
||||
//
|
||||
// This function writes the encapsulated shared secret to |out_enc|.
|
||||
// This function writes the encapsulated shared secret, a Diffie-Hellman public
|
||||
// key, to |out_enc|. It will fail if the buffer's size in |out_enc_len| is not
|
||||
// exactly |X25519_PUBLIC_VALUE_LEN|.
|
||||
OPENSSL_EXPORT int EVP_HPKE_CTX_setup_base_s_x25519(
|
||||
EVP_HPKE_CTX *hpke, uint8_t out_enc[X25519_PUBLIC_VALUE_LEN],
|
||||
uint16_t kdf_id, uint16_t aead_id,
|
||||
const uint8_t peer_public_value[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t *info, size_t info_len);
|
||||
EVP_HPKE_CTX *hpke, uint8_t *out_enc, size_t out_enc_len, uint16_t kdf_id,
|
||||
uint16_t aead_id, const uint8_t *peer_public_value,
|
||||
size_t peer_public_value_len, const uint8_t *info, size_t info_len);
|
||||
|
||||
// EVP_HPKE_CTX_setup_base_s_x25519_for_test behaves like
|
||||
// |EVP_HPKE_CTX_setup_base_s_x25519|, but takes a pre-generated ephemeral
|
||||
// sender key.
|
||||
// sender key. The caller ensures that |ephemeral_public| and
|
||||
// |ephemeral_private| are a valid keypair.
|
||||
OPENSSL_EXPORT int EVP_HPKE_CTX_setup_base_s_x25519_for_test(
|
||||
EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id,
|
||||
const uint8_t peer_public_value[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t *info, size_t info_len,
|
||||
const uint8_t ephemeral_private[X25519_PRIVATE_KEY_LEN],
|
||||
const uint8_t ephemeral_public[X25519_PUBLIC_VALUE_LEN]);
|
||||
const uint8_t *peer_public_value, size_t peer_public_value_len,
|
||||
const uint8_t *info, size_t info_len, const uint8_t *ephemeral_private,
|
||||
size_t ephemeral_private_len, const uint8_t *ephemeral_public,
|
||||
size_t ephemeral_public_len);
|
||||
|
||||
// EVP_HPKE_CTX_setup_base_r_x25519 sets up |hpke| as a recipient context that
|
||||
// can decrypt messages. |private_key| is the recipient's private key, and |enc|
|
||||
// is the encapsulated shared secret from the sender. Note that this function
|
||||
// will fail if |enc| is invalid.
|
||||
// can decrypt messages. It returns one on success, and zero otherwise.
|
||||
//
|
||||
// The recipient's keypair is composed of |public_key| and |private_key|, and
|
||||
// |enc| is the encapsulated shared secret from the sender. If |enc| is invalid,
|
||||
// this function will fail.
|
||||
OPENSSL_EXPORT int EVP_HPKE_CTX_setup_base_r_x25519(
|
||||
EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id,
|
||||
const uint8_t enc[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t public_key[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t private_key[X25519_PRIVATE_KEY_LEN], const uint8_t *info,
|
||||
EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id, const uint8_t *enc,
|
||||
size_t enc_len, const uint8_t *public_key, size_t public_key_len,
|
||||
const uint8_t *private_key, size_t private_key_len, const uint8_t *info,
|
||||
size_t info_len);
|
||||
|
||||
// EVP_HPKE_CTX_setup_psk_s_x25519 sets up |hpke| as a sender context that can
|
||||
@ -124,39 +127,44 @@ OPENSSL_EXPORT int EVP_HPKE_CTX_setup_base_r_x25519(
|
||||
// must be nonempty (|psk_len| and |psk_id_len| must be non-zero), or this
|
||||
// function will fail.
|
||||
//
|
||||
// This function writes the encapsulated shared secret to |out_enc|.
|
||||
// This function writes the encapsulated shared secret, a Diffie-Hellman public
|
||||
// key, to |out_enc|. It will fail if the buffer's size in |out_enc_len| is not
|
||||
// exactly |X25519_PUBLIC_VALUE_LEN|.
|
||||
OPENSSL_EXPORT int EVP_HPKE_CTX_setup_psk_s_x25519(
|
||||
EVP_HPKE_CTX *hpke, uint8_t out_enc[X25519_PUBLIC_VALUE_LEN],
|
||||
uint16_t kdf_id, uint16_t aead_id,
|
||||
const uint8_t peer_public_value[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t *info, size_t info_len, const uint8_t *psk, size_t psk_len,
|
||||
const uint8_t *psk_id, size_t psk_id_len);
|
||||
EVP_HPKE_CTX *hpke, uint8_t *out_enc, size_t out_enc_len, uint16_t kdf_id,
|
||||
uint16_t aead_id, const uint8_t *peer_public_value,
|
||||
size_t peer_public_value_len, const uint8_t *info, size_t info_len,
|
||||
const uint8_t *psk, size_t psk_len, const uint8_t *psk_id,
|
||||
size_t psk_id_len);
|
||||
|
||||
// EVP_HPKE_CTX_setup_psk_s_x25519_for_test behaves like
|
||||
// |EVP_HPKE_CTX_setup_psk_s_x25519|, but takes a pre-generated ephemeral sender
|
||||
// key.
|
||||
// key. The caller ensures that |ephemeral_public| and |ephemeral_private| are a
|
||||
// valid keypair.
|
||||
OPENSSL_EXPORT int EVP_HPKE_CTX_setup_psk_s_x25519_for_test(
|
||||
EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id,
|
||||
const uint8_t peer_public_value[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t *peer_public_value, size_t peer_public_value_len,
|
||||
const uint8_t *info, size_t info_len, const uint8_t *psk, size_t psk_len,
|
||||
const uint8_t *psk_id, size_t psk_id_len,
|
||||
const uint8_t ephemeral_private[X25519_PRIVATE_KEY_LEN],
|
||||
const uint8_t ephemeral_public[X25519_PUBLIC_VALUE_LEN]);
|
||||
const uint8_t *psk_id, size_t psk_id_len, const uint8_t *ephemeral_private,
|
||||
size_t ephemeral_private_len, const uint8_t *ephemeral_public,
|
||||
size_t ephemeral_public_len);
|
||||
|
||||
// EVP_HPKE_CTX_setup_psk_r_x25519 sets up |hpke| as a recipient context that
|
||||
// can decrypt messages. Future open (decrypt) operations will fail if the
|
||||
// sender does not possess the PSK indicated by |psk| and |psk_id|.
|
||||
// |private_key| is the recipient's private key, and |enc| is the encapsulated
|
||||
// shared secret from the sender. If |enc| is invalid, this function will fail.
|
||||
// sender does not possess the PSK indicated by |psk| and |psk_id|. It returns
|
||||
// one on success, and zero otherwise.
|
||||
//
|
||||
// The recipient's keypair is composed of |public_key| and |private_key|, and
|
||||
// |enc| is the encapsulated shared secret from the sender. If |enc| is invalid,
|
||||
// this function will fail.
|
||||
//
|
||||
// The PSK and its ID must be provided in |psk| and |psk_id|, respectively. Both
|
||||
// must be nonempty (|psk_len| and |psk_id_len| must be non-zero), or this
|
||||
// function will fail.
|
||||
OPENSSL_EXPORT int EVP_HPKE_CTX_setup_psk_r_x25519(
|
||||
EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id,
|
||||
const uint8_t enc[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t public_key[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t private_key[X25519_PRIVATE_KEY_LEN], const uint8_t *info,
|
||||
EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id, const uint8_t *enc,
|
||||
size_t enc_len, const uint8_t *public_key, size_t public_key_len,
|
||||
const uint8_t *private_key, size_t private_key_len, const uint8_t *info,
|
||||
size_t info_len, const uint8_t *psk, size_t psk_len, const uint8_t *psk_id,
|
||||
size_t psk_id_len);
|
||||
|
||||
|
@ -94,5 +94,6 @@
|
||||
#define EVP_R_INVALID_PEER_KEY 134
|
||||
#define EVP_R_NOT_XOF_OR_INVALID_LENGTH 135
|
||||
#define EVP_R_EMPTY_PSK 136
|
||||
#define EVP_R_INVALID_BUFFER_SIZE 137
|
||||
|
||||
#endif // OPENSSL_HEADER_EVP_ERRORS_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user