summaryrefslogtreecommitdiff
path: root/src/crypto/evp/evp_extra_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/evp/evp_extra_test.cc')
-rw-r--r--src/crypto/evp/evp_extra_test.cc107
1 files changed, 97 insertions, 10 deletions
diff --git a/src/crypto/evp/evp_extra_test.cc b/src/crypto/evp/evp_extra_test.cc
index 1f6a61d3..f5205988 100644
--- a/src/crypto/evp/evp_extra_test.cc
+++ b/src/crypto/evp/evp_extra_test.cc
@@ -555,13 +555,10 @@ TEST(EVPExtraTest, Ed25519) {
0xa6, 0x23, 0x25, 0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a,
};
- static const uint8_t kPrivateKey[64] = {
+ static const uint8_t kPrivateKeySeed[32] = {
0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60, 0xba, 0x84, 0x4a,
0xf4, 0x92, 0xec, 0x2c, 0xc4, 0x44, 0x49, 0xc5, 0x69, 0x7b, 0x32,
- 0x69, 0x19, 0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae, 0x7f, 0x60, 0xd7,
- 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7, 0xd5, 0x4b, 0xfe, 0xd3,
- 0xc9, 0x64, 0x07, 0x3a, 0x0e, 0xe1, 0x72, 0xf3, 0xda, 0xa6, 0x23,
- 0x25, 0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a,
+ 0x69, 0x19, 0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae, 0x7f, 0x60,
};
static const uint8_t kPrivateKeyPKCS8[] = {
@@ -572,10 +569,38 @@ TEST(EVPExtraTest, Ed25519) {
};
// Create a public key.
- bssl::UniquePtr<EVP_PKEY> pubkey(EVP_PKEY_new_ed25519_public(kPublicKey));
+ bssl::UniquePtr<EVP_PKEY> pubkey(EVP_PKEY_new_raw_public_key(
+ EVP_PKEY_ED25519, nullptr, kPublicKey, sizeof(kPublicKey)));
ASSERT_TRUE(pubkey);
EXPECT_EQ(EVP_PKEY_ED25519, EVP_PKEY_id(pubkey.get()));
+ // The public key must be extractable.
+ uint8_t buf[32];
+ size_t len;
+ ASSERT_TRUE(EVP_PKEY_get_raw_public_key(pubkey.get(), nullptr, &len));
+ EXPECT_EQ(len, 32u);
+ ASSERT_TRUE(EVP_PKEY_get_raw_public_key(pubkey.get(), buf, &len));
+ EXPECT_EQ(Bytes(buf, len), Bytes(kPublicKey));
+ // Passing too large of a buffer is okay. The function will still only read
+ // 32 bytes.
+ len = 64;
+ ASSERT_TRUE(EVP_PKEY_get_raw_public_key(pubkey.get(), buf, &len));
+ EXPECT_EQ(Bytes(buf, len), Bytes(kPublicKey));
+ // Passing too small of a buffer is noticed.
+ len = 31;
+ EXPECT_FALSE(EVP_PKEY_get_raw_public_key(pubkey.get(), buf, &len));
+ uint32_t err = ERR_get_error();
+ EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
+ EXPECT_EQ(EVP_R_BUFFER_TOO_SMALL, ERR_GET_REASON(err));
+ ERR_clear_error();
+
+ // There is no private key.
+ EXPECT_FALSE(EVP_PKEY_get_raw_private_key(pubkey.get(), nullptr, &len));
+ err = ERR_get_error();
+ EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
+ EXPECT_EQ(EVP_R_NOT_A_PRIVATE_KEY, ERR_GET_REASON(err));
+ ERR_clear_error();
+
// The public key must encode properly.
bssl::ScopedCBB cbb;
uint8_t *der;
@@ -589,16 +614,40 @@ TEST(EVPExtraTest, Ed25519) {
// The public key must gracefully fail to encode as a private key.
ASSERT_TRUE(CBB_init(cbb.get(), 0));
EXPECT_FALSE(EVP_marshal_private_key(cbb.get(), pubkey.get()));
- uint32_t err = ERR_get_error();
+ err = ERR_get_error();
EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
EXPECT_EQ(EVP_R_NOT_A_PRIVATE_KEY, ERR_GET_REASON(err));
+ ERR_clear_error();
cbb.Reset();
// Create a private key.
- bssl::UniquePtr<EVP_PKEY> privkey(EVP_PKEY_new_ed25519_private(kPrivateKey));
+ bssl::UniquePtr<EVP_PKEY> privkey(EVP_PKEY_new_raw_private_key(
+ EVP_PKEY_ED25519, NULL, kPrivateKeySeed, sizeof(kPrivateKeySeed)));
ASSERT_TRUE(privkey);
EXPECT_EQ(EVP_PKEY_ED25519, EVP_PKEY_id(privkey.get()));
+ // The private key must be extractable.
+ ASSERT_TRUE(EVP_PKEY_get_raw_private_key(privkey.get(), nullptr, &len));
+ EXPECT_EQ(len, 32u);
+ ASSERT_TRUE(EVP_PKEY_get_raw_private_key(privkey.get(), buf, &len));
+ EXPECT_EQ(Bytes(buf, len), Bytes(kPrivateKeySeed));
+ // Passing too large of a buffer is okay. The function will still only read
+ // 32 bytes.
+ len = 64;
+ ASSERT_TRUE(EVP_PKEY_get_raw_private_key(privkey.get(), buf, &len));
+ EXPECT_EQ(Bytes(buf, len), Bytes(kPrivateKeySeed));
+ // Passing too small of a buffer is noticed.
+ len = 31;
+ EXPECT_FALSE(EVP_PKEY_get_raw_private_key(privkey.get(), buf, &len));
+ err = ERR_get_error();
+ EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
+ EXPECT_EQ(EVP_R_BUFFER_TOO_SMALL, ERR_GET_REASON(err));
+ ERR_clear_error();
+ // The public key must be extractable.
+ len = 32;
+ ASSERT_TRUE(EVP_PKEY_get_raw_public_key(privkey.get(), buf, &len));
+ EXPECT_EQ(Bytes(buf, len), Bytes(kPublicKey));
+
// The public key must encode from the private key.
ASSERT_TRUE(CBB_init(cbb.get(), 0));
ASSERT_TRUE(EVP_marshal_public_key(cbb.get(), privkey.get()));
@@ -617,7 +666,8 @@ TEST(EVPExtraTest, Ed25519) {
EXPECT_EQ(1, EVP_PKEY_cmp(pubkey.get(), privkey.get()));
static const uint8_t kZeros[32] = {0};
- bssl::UniquePtr<EVP_PKEY> pubkey2(EVP_PKEY_new_ed25519_public(kZeros));
+ bssl::UniquePtr<EVP_PKEY> pubkey2(EVP_PKEY_new_raw_public_key(
+ EVP_PKEY_ED25519, nullptr, kZeros, sizeof(kZeros)));
ASSERT_TRUE(pubkey2);
EXPECT_EQ(0, EVP_PKEY_cmp(pubkey.get(), pubkey2.get()));
EXPECT_EQ(0, EVP_PKEY_cmp(privkey.get(), pubkey2.get()));
@@ -627,7 +677,6 @@ TEST(EVPExtraTest, Ed25519) {
ASSERT_TRUE(
EVP_DigestSignInit(ctx.get(), nullptr, nullptr, nullptr, privkey.get()));
EXPECT_FALSE(EVP_DigestSignUpdate(ctx.get(), nullptr, 0));
- size_t len;
EXPECT_FALSE(EVP_DigestSignFinal(ctx.get(), nullptr, &len));
ERR_clear_error();
@@ -637,6 +686,18 @@ TEST(EVPExtraTest, Ed25519) {
EXPECT_FALSE(EVP_DigestVerifyUpdate(ctx.get(), nullptr, 0));
EXPECT_FALSE(EVP_DigestVerifyFinal(ctx.get(), nullptr, 0));
ERR_clear_error();
+
+ // The buffer length to |EVP_DigestSign| is an input/output parameter and
+ // should be checked before signing.
+ ctx.Reset();
+ ASSERT_TRUE(
+ EVP_DigestSignInit(ctx.get(), nullptr, nullptr, nullptr, privkey.get()));
+ len = 31;
+ EXPECT_FALSE(EVP_DigestSign(ctx.get(), buf, &len, nullptr /* msg */, 0));
+ err = ERR_get_error();
+ EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
+ EXPECT_EQ(EVP_R_BUFFER_TOO_SMALL, ERR_GET_REASON(err));
+ ERR_clear_error();
}
static void ExpectECGroupOnly(const EVP_PKEY *pkey, int nid) {
@@ -695,3 +756,29 @@ TEST(EVPExtraTest, ECKeygen) {
raw = nullptr;
ExpectECGroupAndKey(pkey.get(), NID_X9_62_prime256v1);
}
+
+// Test that |EVP_PKEY_keygen| works for Ed25519.
+TEST(EVPExtraTest, Ed25519Keygen) {
+ bssl::UniquePtr<EVP_PKEY_CTX> pctx(
+ EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, nullptr));
+ ASSERT_TRUE(pctx);
+ ASSERT_TRUE(EVP_PKEY_keygen_init(pctx.get()));
+ EVP_PKEY *raw = nullptr;
+ ASSERT_TRUE(EVP_PKEY_keygen(pctx.get(), &raw));
+ bssl::UniquePtr<EVP_PKEY> pkey(raw);
+
+ // Round-trip a signature to sanity-check the key is good.
+ bssl::ScopedEVP_MD_CTX ctx;
+ ASSERT_TRUE(
+ EVP_DigestSignInit(ctx.get(), nullptr, nullptr, nullptr, pkey.get()));
+ uint8_t sig[64];
+ size_t len = sizeof(sig);
+ ASSERT_TRUE(EVP_DigestSign(ctx.get(), sig, &len,
+ reinterpret_cast<const uint8_t *>("hello"), 5));
+
+ ctx.Reset();
+ ASSERT_TRUE(
+ EVP_DigestVerifyInit(ctx.get(), nullptr, nullptr, nullptr, pkey.get()));
+ ASSERT_TRUE(EVP_DigestVerify(ctx.get(), sig, len,
+ reinterpret_cast<const uint8_t *>("hello"), 5));
+}