update main-with-bazel from master branch

This commit is contained in:
BoringSSL Robot
2024-12-17 02:09:19 +00:00
42 changed files with 1005 additions and 578 deletions
+14 -14
View File
@@ -136,7 +136,7 @@ TEST(ASN1Test, UnknownTags) {
static bssl::UniquePtr<BIGNUM> BIGNUMPow2(unsigned bit) {
bssl::UniquePtr<BIGNUM> bn(BN_new());
if (!bn ||
if (!bn || //
!BN_set_bit(bn.get(), bit)) {
return nullptr;
}
@@ -415,8 +415,8 @@ TEST(ASN1Test, Integer) {
SCOPED_TRACE(pair.first);
const ASN1_INTEGER *obj = pair.second.get();
EXPECT_EQ(t.type, ASN1_STRING_type(obj));
EXPECT_EQ(Bytes(t.data), Bytes(ASN1_STRING_get0_data(obj),
ASN1_STRING_length(obj)));
EXPECT_EQ(Bytes(t.data),
Bytes(ASN1_STRING_get0_data(obj), ASN1_STRING_length(obj)));
// The object should encode correctly.
TestSerialize(obj, i2d_ASN1_INTEGER, t.der);
@@ -911,7 +911,8 @@ TEST(ASN1Test, StringToUTF8) {
{{0, 0, 0xfe, 0xff, 0, 0, 0, 88}, V_ASN1_UNIVERSALSTRING, nullptr},
// Otherwise, BOMs should pass through.
{{0, 88, 0xfe, 0xff}, V_ASN1_BMPSTRING, "X\xef\xbb\xbf"},
{{0, 0, 0, 88, 0, 0, 0xfe, 0xff}, V_ASN1_UNIVERSALSTRING,
{{0, 0, 0, 88, 0, 0, 0xfe, 0xff},
V_ASN1_UNIVERSALSTRING,
"X\xef\xbb\xbf"},
// The maximum code-point should pass though.
{{0, 16, 0xff, 0xfd}, V_ASN1_UNIVERSALSTRING, "\xf4\x8f\xbf\xbd"},
@@ -975,7 +976,7 @@ static bool ASN1Time_check_posix(const ASN1_TIME *s, int64_t t) {
!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm)) {
return false;
}
return day == 0 && sec ==0;
return day == 0 && sec == 0;
}
static std::string PrintStringToBIO(const ASN1_STRING *str,
@@ -1697,8 +1698,8 @@ TEST(ASN1Test, MBString) {
ERR_clear_error();
ASN1_STRING *str = nullptr;
EXPECT_EQ(-1, ASN1_mbstring_copy(&str, t.in.data(), t.in.size(),
t.format, t.mask));
EXPECT_EQ(-1, ASN1_mbstring_copy(&str, t.in.data(), t.in.size(), t.format,
t.mask));
ERR_clear_error();
EXPECT_EQ(nullptr, str);
}
@@ -1846,9 +1847,9 @@ TEST(ASN1Test, StringByCustomNID) {
ASN1_STRING_length(str.get())));
// Minimum and maximum lengths are enforced.
str.reset(ASN1_STRING_set_by_NID(
nullptr, reinterpret_cast<const uint8_t *>("1234"), 4, MBSTRING_UTF8,
nid1));
str.reset(ASN1_STRING_set_by_NID(nullptr,
reinterpret_cast<const uint8_t *>("1234"), 4,
MBSTRING_UTF8, nid1));
EXPECT_FALSE(str);
ERR_clear_error();
str.reset(ASN1_STRING_set_by_NID(
@@ -1981,7 +1982,7 @@ TEST(ASN1Test, StringTableSorted) {
size_t table_len;
asn1_get_string_table_for_testing(&table, &table_len);
for (size_t i = 1; i < table_len; i++) {
EXPECT_LT(table[i-1].nid, table[i].nid);
EXPECT_LT(table[i - 1].nid, table[i].nid);
}
}
@@ -2058,8 +2059,7 @@ TEST(ASN1Test, Unpack) {
ASSERT_TRUE(str);
static const uint8_t kValid[] = {0x30, 0x00};
ASSERT_TRUE(
ASN1_STRING_set(str.get(), kValid, sizeof(kValid)));
ASSERT_TRUE(ASN1_STRING_set(str.get(), kValid, sizeof(kValid)));
bssl::UniquePtr<BASIC_CONSTRAINTS> val(static_cast<BASIC_CONSTRAINTS *>(
ASN1_item_unpack(str.get(), ASN1_ITEM_rptr(BASIC_CONSTRAINTS))));
ASSERT_TRUE(val);
@@ -2394,7 +2394,7 @@ TEST(ASN1Test, StringEncoding) {
{d2i_ASN1_T61STRING, {0x14, 0x00}, true},
{d2i_ASN1_T61STRING, {0x14, 0x01, 0x00}, true},
};
for (const auto& t : kTests) {
for (const auto &t : kTests) {
SCOPED_TRACE(Bytes(t.in));
const uint8_t *inp;
+6 -2
View File
@@ -37,14 +37,16 @@
#include <sys/socket.h>
#include <unistd.h>
#else
#include <io.h>
#include <fcntl.h>
#include <io.h>
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <winsock2.h>
#include <ws2tcpip.h>
OPENSSL_MSVC_PRAGMA(warning(pop))
#endif
namespace {
#if !defined(OPENSSL_WINDOWS)
using Socket = int;
#define INVALID_SOCKET (-1)
@@ -611,7 +613,7 @@ TEST(BIOTest, Gets) {
// Empty BIO.
{"", 256, ""},
};
for (const auto& t : kGetsTests) {
for (const auto &t : kGetsTests) {
SCOPED_TRACE(t.bio);
SCOPED_TRACE(t.gets_len);
@@ -886,3 +888,5 @@ TEST_P(BIOPairTest, TestPair) {
}
INSTANTIATE_TEST_SUITE_P(All, BIOPairTest, testing::Values(false, true));
} // namespace
+2
View File
@@ -87,6 +87,7 @@ enum {
BIO_CONN_S_OK,
};
namespace {
typedef struct bio_connect_st {
int state;
@@ -107,6 +108,7 @@ typedef struct bio_connect_st {
// compatibility with the SSL info_callback.
int (*info_callback)(const BIO *bio, int state, int ret);
} BIO_CONNECT;
} // namespace
#if !defined(OPENSSL_WINDOWS)
static int closesocket(int sock) { return close(sock); }
+5 -3
View File
@@ -62,6 +62,7 @@
#include "../internal.h"
namespace {
// hexdump_ctx contains the state of a hexdump.
struct hexdump_ctx {
BIO *bio;
@@ -70,16 +71,17 @@ struct hexdump_ctx {
size_t n; // number of bytes total.
unsigned indent;
};
} // namespace
static void hexbyte(char *out, uint8_t b) {
static const char hextable[] = "0123456789abcdef";
out[0] = hextable[b>>4];
out[1] = hextable[b&0x0f];
out[0] = hextable[b >> 4];
out[1] = hextable[b & 0x0f];
}
static char to_char(uint8_t b) {
if (b < 32 || b > 126) {
return '.';
return '.';
}
return b;
}
+2
View File
@@ -61,6 +61,7 @@
#include "../internal.h"
namespace {
struct bio_bio_st {
BIO *peer; // NULL if buf == NULL.
// If peer != NULL, then peer->ptr is also a bio_bio_st,
@@ -79,6 +80,7 @@ struct bio_bio_st {
// it (unsuccessfully) tried to read,
// never more than buffer space (size-len) warrants.
};
} // namespace
static int bio_new(BIO *bio) {
struct bio_bio_st *b =
+48 -47
View File
@@ -29,6 +29,8 @@
#include "internal.h"
namespace {
TEST(CBSTest, Skip) {
static const uint8_t kData[] = {1, 2, 3};
CBS data;
@@ -491,12 +493,14 @@ TEST(CBBTest, DiscardChild) {
bssl::UniquePtr<uint8_t> scoper(buf);
static const uint8_t kExpected[] = {
0xaa,
0,
1, 0xbb,
0, 2, 0xcc, 0xcc,
0, 0, 3, 0xdd, 0xdd, 0xdd,
1, 0xff,
// clang-format off
0xaa,
0,
1, 0xbb,
0, 2, 0xcc, 0xcc,
0, 0, 3, 0xdd, 0xdd, 0xdd,
1, 0xff,
// clang-format on
};
EXPECT_EQ(Bytes(kExpected), Bytes(buf, buf_len));
}
@@ -520,7 +524,7 @@ TEST(CBBTest, Misuse) {
EXPECT_FALSE(CBB_add_u8_length_prefixed(&child, &contents));
EXPECT_FALSE(CBB_add_u16_length_prefixed(&child, &contents));
EXPECT_FALSE(CBB_add_asn1(&child, &contents, 1));
EXPECT_FALSE(CBB_add_bytes(&child, (const uint8_t*) "a", 1));
EXPECT_FALSE(CBB_add_bytes(&child, (const uint8_t *)"a", 1));
ASSERT_TRUE(CBB_finish(cbb.get(), &buf, &buf_len));
bssl::UniquePtr<uint8_t> scoper(buf);
@@ -530,6 +534,7 @@ TEST(CBBTest, Misuse) {
TEST(CBBTest, ASN1) {
static const uint8_t kExpected[] = {
// clang-format off
// SEQUENCE { 1 2 3 }
0x30, 3, 1, 2, 3,
// [4 CONSTRUCTED] { 4 5 6 }
@@ -540,6 +545,7 @@ TEST(CBBTest, ASN1) {
0x5f, 0x1f, 3, 10, 11, 12,
// [PRIVATE 2^29-1 CONSTRUCTED] { 13 14 15 }
0xff, 0x81, 0xff, 0xff, 0xff, 0x7f, 3, 13, 14, 15,
// clang-format on
};
uint8_t *buf;
size_t buf_len;
@@ -553,13 +559,9 @@ TEST(CBBTest, ASN1) {
CBB_add_asn1(cbb.get(), &contents,
CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 4));
ASSERT_TRUE(CBB_add_bytes(&contents, (const uint8_t *)"\x04\x05\x06", 3));
ASSERT_TRUE(
CBB_add_asn1(cbb.get(), &contents,
CBS_ASN1_APPLICATION | 30));
ASSERT_TRUE(CBB_add_asn1(cbb.get(), &contents, CBS_ASN1_APPLICATION | 30));
ASSERT_TRUE(CBB_add_bytes(&contents, (const uint8_t *)"\x07\x08\x09", 3));
ASSERT_TRUE(
CBB_add_asn1(cbb.get(), &contents,
CBS_ASN1_APPLICATION | 31));
ASSERT_TRUE(CBB_add_asn1(cbb.get(), &contents, CBS_ASN1_APPLICATION | 31));
ASSERT_TRUE(CBB_add_bytes(&contents, (const uint8_t *)"\x0a\x0b\x0c", 3));
ASSERT_TRUE(
CBB_add_asn1(cbb.get(), &contents,
@@ -874,10 +876,10 @@ static const ASN1Uint64Test kASN1Uint64Tests[] = {
{127, "\x02\x01\x7f", 3},
{128, "\x02\x02\x00\x80", 4},
{0xdeadbeef, "\x02\x05\x00\xde\xad\xbe\xef", 7},
{UINT64_C(0x0102030405060708),
"\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10},
{UINT64_C(0x0102030405060708), "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08",
10},
{UINT64_C(0xffffffffffffffff),
"\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11},
"\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11},
};
struct ASN1InvalidUint64Test {
@@ -1140,7 +1142,7 @@ TEST(CBSTest, BitString) {
{0x00, 0xff}, // 8 bits
{0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0}, // 42 bits
};
for (const auto& test : kValidBitStrings) {
for (const auto &test : kValidBitStrings) {
SCOPED_TRACE(Bytes(test.data(), test.size()));
CBS cbs;
CBS_init(&cbs, test.data(), test.size());
@@ -1158,7 +1160,7 @@ TEST(CBSTest, BitString) {
// All unused bits must be cleared.
{0x06, 0xff, 0xc1},
};
for (const auto& test : kInvalidBitStrings) {
for (const auto &test : kInvalidBitStrings) {
SCOPED_TRACE(Bytes(test.data(), test.size()));
CBS cbs;
CBS_init(&cbs, test.data(), test.size());
@@ -1192,7 +1194,7 @@ TEST(CBSTest, BitString) {
{{0x06, 0x0f, 0x40}, 16, false},
{{0x06, 0x0f, 0x40}, 1000, false},
};
for (const auto& test : kBitTests) {
for (const auto &test : kBitTests) {
SCOPED_TRACE(Bytes(test.in.data(), test.in.size()));
SCOPED_TRACE(test.bit);
CBS cbs;
@@ -1311,13 +1313,13 @@ TEST(CBBTest, FlushASN1SetOf) {
const struct {
std::vector<uint8_t> in, out;
} kValidInputs[] = {
// No elements.
{{}, {}},
// One element.
{{0x30, 0x00}, {0x30, 0x00}},
// Two identical elements.
{{0x30, 0x00, 0x30, 0x00}, {0x30, 0x00, 0x30, 0x00}},
// clang-format off
// No elements.
{{}, {}},
// One element.
{{0x30, 0x00}, {0x30, 0x00}},
// Two identical elements.
{{0x30, 0x00, 0x30, 0x00}, {0x30, 0x00, 0x30, 0x00}},
// clang-format off
{{0x30, 0x02, 0x00, 0x00,
0x30, 0x00,
0x01, 0x00,
@@ -1336,7 +1338,7 @@ TEST(CBBTest, FlushASN1SetOf) {
0x30, 0x02, 0x00, 0x00,
0x30, 0x03, 0x00, 0x00, 0x00,
0x30, 0x03, 0x00, 0x00, 0x01}},
// clang-format on
// clang-format on
};
for (const auto &t : kValidInputs) {
@@ -1360,9 +1362,9 @@ TEST(CBBTest, FlushASN1SetOf) {
}
const std::vector<uint8_t> kInvalidInputs[] = {
{0x30},
{0x30, 0x01},
{0x30, 0x00, 0x30, 0x00, 0x30, 0x01},
{0x30},
{0x30, 0x01},
{0x30, 0x00, 0x30, 0x00, 0x30, 0x01},
};
for (const auto &t : kInvalidInputs) {
@@ -1559,17 +1561,17 @@ TEST(CBBTest, Unicode) {
}
static const uint32_t kBadCodePoints[] = {
// Surrogate pairs.
0xd800,
0xdfff,
// Non-characters.
0xfffe,
0xffff,
0xfdd0,
0x1fffe,
0x1ffff,
// Too big.
0x110000,
// Surrogate pairs.
0xd800,
0xdfff,
// Non-characters.
0xfffe,
0xffff,
0xfdd0,
0x1fffe,
0x1ffff,
// Too big.
0x110000,
};
bssl::ScopedCBB cbb;
ASSERT_TRUE(CBB_init(cbb.get(), 0));
@@ -1651,11 +1653,8 @@ TEST(CBSTest, BogusTime) {
static const struct {
const char *timestring;
} kUTCTZTests[] = {
{"480711220333-0700"},
{"140704000000-0700"},
{"480222202332-0500"},
{"480726113216-0000"},
{"480726113216-2359"},
{"480711220333-0700"}, {"140704000000-0700"}, {"480222202332-0500"},
{"480726113216-0000"}, {"480726113216-2359"},
};
for (const auto &t : kUTCTZTests) {
SCOPED_TRACE(t.timestring);
@@ -1733,7 +1732,7 @@ TEST(CBSTest, GetU64Decimal) {
for (const auto &t : kTests) {
SCOPED_TRACE(t.text);
CBS cbs;
CBS_init(&cbs, reinterpret_cast<const uint8_t*>(t.text), strlen(t.text));
CBS_init(&cbs, reinterpret_cast<const uint8_t *>(t.text), strlen(t.text));
uint64_t v;
ASSERT_TRUE(CBS_get_u64_decimal(&cbs, &v));
EXPECT_EQ(v, t.val);
@@ -1768,3 +1767,5 @@ TEST(CBSTest, GetU64Decimal) {
EXPECT_FALSE(CBS_get_u64_decimal(&cbs, &v));
}
}
} // namespace
+52 -52
View File
@@ -25,12 +25,14 @@
#include <openssl/err.h>
#include "../fipsmodule/cipher/internal.h"
#include "internal.h"
#include "../internal.h"
#include "../test/abi_test.h"
#include "../test/file_test.h"
#include "../test/test_util.h"
#include "../test/wycheproof_util.h"
#include "internal.h"
namespace {
// kLimitedImplementation indicates that tests that assume a generic AEAD
// interface should not be performed. For example, the key-wrap AEADs only
@@ -55,9 +57,7 @@ constexpr uint32_t RequiresADLength(size_t length) {
// RequiredADLength returns the AD length requirement encoded in |flags|, or
// zero if there isn't one.
constexpr size_t RequiredADLength(uint32_t flags) {
return (flags >> 3) & 0xf;
}
constexpr size_t RequiredADLength(uint32_t flags) { return (flags >> 3) & 0xf; }
constexpr uint32_t RequiresMinimumTagLength(size_t length) {
assert(length < 16);
@@ -278,8 +278,8 @@ TEST_P(PerAEADTest, TestExtraInput) {
const std::string test_vectors =
"crypto/cipher_extra/test/" + std::string(aead_config.test_vectors);
FileTestGTest(test_vectors.c_str(), [&](FileTest *t) {
if (t->HasAttribute("NO_SEAL") ||
t->HasAttribute("FAILS") ||
if (t->HasAttribute("NO_SEAL") || //
t->HasAttribute("FAILS") || //
(aead_config.flags & kNondeterministic)) {
t->SkipCurrent();
return;
@@ -384,9 +384,9 @@ TEST_P(PerAEADTest, TestVectorScatterGather) {
uint32_t err = ERR_peek_error();
if (ERR_GET_LIB(err) == ERR_LIB_CIPHER &&
ERR_GET_REASON(err) == CIPHER_R_CTRL_NOT_IMPLEMENTED) {
t->SkipCurrent();
return;
}
t->SkipCurrent();
return;
}
}
if (t->HasAttribute("FAILS")) {
@@ -407,7 +407,7 @@ TEST_P(PerAEADTest, TestVectorScatterGather) {
// Garbage at the end isn't ignored.
out_tag.push_back(0);
out2.resize(out.size());
ASSERT_EQ(out2.size(), out.size());
EXPECT_FALSE(EVP_AEAD_CTX_open_gather(
ctx.get(), out2.data(), nonce.data(), nonce.size(), out.data(),
out.size(), out_tag.data(), out_tag.size(), ad.data(), ad.size()))
@@ -423,7 +423,7 @@ TEST_P(PerAEADTest, TestVectorScatterGather) {
// Verify integrity is checked.
out_tag[0] ^= 0x80;
out_tag.resize(out_tag.size() - 1);
out2.resize(out.size());
ASSERT_EQ(out2.size(), out.size());
EXPECT_FALSE(EVP_AEAD_CTX_open_gather(
ctx.get(), out2.data(), nonce.data(), nonce.size(), out.data(),
out.size(), out_tag.data(), out_tag.size(), ad.data(), ad.size()))
@@ -483,8 +483,8 @@ TEST_P(PerAEADTest, TruncatedTags) {
const size_t tag_len = MinimumTagLength(GetParam().flags);
bssl::ScopedEVP_AEAD_CTX ctx;
ASSERT_TRUE(EVP_AEAD_CTX_init(ctx.get(), aead(), key, key_len,
tag_len, NULL /* ENGINE */));
ASSERT_TRUE(EVP_AEAD_CTX_init(ctx.get(), aead(), key, key_len, tag_len,
NULL /* ENGINE */));
const uint8_t plaintext[1] = {'A'};
@@ -966,54 +966,54 @@ static void RunWycheproofTestCase(FileTest *t, const EVP_AEAD *aead) {
TEST(AEADTest, WycheproofAESGCMSIV) {
FileTestGTest("third_party/wycheproof_testvectors/aes_gcm_siv_test.txt",
[](FileTest *t) {
std::string key_size_str;
ASSERT_TRUE(t->GetInstruction(&key_size_str, "keySize"));
const EVP_AEAD *aead;
switch (atoi(key_size_str.c_str())) {
case 128:
aead = EVP_aead_aes_128_gcm_siv();
break;
case 256:
aead = EVP_aead_aes_256_gcm_siv();
break;
default:
FAIL() << "Unknown key size: " << key_size_str;
}
std::string key_size_str;
ASSERT_TRUE(t->GetInstruction(&key_size_str, "keySize"));
const EVP_AEAD *aead;
switch (atoi(key_size_str.c_str())) {
case 128:
aead = EVP_aead_aes_128_gcm_siv();
break;
case 256:
aead = EVP_aead_aes_256_gcm_siv();
break;
default:
FAIL() << "Unknown key size: " << key_size_str;
}
RunWycheproofTestCase(t, aead);
});
RunWycheproofTestCase(t, aead);
});
}
TEST(AEADTest, WycheproofAESGCM) {
FileTestGTest("third_party/wycheproof_testvectors/aes_gcm_test.txt",
[](FileTest *t) {
std::string key_size_str;
ASSERT_TRUE(t->GetInstruction(&key_size_str, "keySize"));
const EVP_AEAD *aead;
switch (atoi(key_size_str.c_str())) {
case 128:
aead = EVP_aead_aes_128_gcm();
break;
case 192:
aead = EVP_aead_aes_192_gcm();
break;
case 256:
aead = EVP_aead_aes_256_gcm();
break;
default:
FAIL() << "Unknown key size: " << key_size_str;
}
std::string key_size_str;
ASSERT_TRUE(t->GetInstruction(&key_size_str, "keySize"));
const EVP_AEAD *aead;
switch (atoi(key_size_str.c_str())) {
case 128:
aead = EVP_aead_aes_128_gcm();
break;
case 192:
aead = EVP_aead_aes_192_gcm();
break;
case 256:
aead = EVP_aead_aes_256_gcm();
break;
default:
FAIL() << "Unknown key size: " << key_size_str;
}
RunWycheproofTestCase(t, aead);
});
RunWycheproofTestCase(t, aead);
});
}
TEST(AEADTest, WycheproofChaCha20Poly1305) {
FileTestGTest("third_party/wycheproof_testvectors/chacha20_poly1305_test.txt",
[](FileTest *t) {
t->IgnoreInstruction("keySize");
RunWycheproofTestCase(t, EVP_aead_chacha20_poly1305());
});
t->IgnoreInstruction("keySize");
RunWycheproofTestCase(t, EVP_aead_chacha20_poly1305());
});
}
TEST(AEADTest, WycheproofXChaCha20Poly1305) {
@@ -1025,6 +1025,6 @@ TEST(AEADTest, WycheproofXChaCha20Poly1305) {
});
}
TEST(AEADTest, FreeNull) {
EVP_AEAD_CTX_free(nullptr);
}
TEST(AEADTest, FreeNull) { EVP_AEAD_CTX_free(nullptr); }
} // namespace
+6
View File
@@ -36,10 +36,12 @@
// Optimised AES-GCM-SIV
namespace {
struct aead_aes_gcm_siv_asm_ctx {
alignas(16) uint8_t key[16 * 15];
int is_128_bit;
};
} // namespace
// The assembly code assumes 8-byte alignment of the EVP_AEAD_CTX's state, and
// aligns to 16 bytes itself.
@@ -533,6 +535,7 @@ static const EVP_AEAD aead_aes_256_gcm_siv_asm = {
#endif // X86_64 && !NO_ASM && !WINDOWS
namespace {
struct aead_aes_gcm_siv_ctx {
union {
double align;
@@ -541,6 +544,7 @@ struct aead_aes_gcm_siv_ctx {
block128_f kgk_block;
unsigned is_256 : 1;
};
} // namespace
static_assert(sizeof(((EVP_AEAD_CTX *)NULL)->state) >=
sizeof(struct aead_aes_gcm_siv_ctx),
@@ -651,6 +655,7 @@ static void gcm_siv_polyval(
out_tag[15] &= 0x7f;
}
namespace {
// gcm_siv_record_keys contains the keys used for a specific GCM-SIV record.
struct gcm_siv_record_keys {
uint8_t auth_key[16];
@@ -660,6 +665,7 @@ struct gcm_siv_record_keys {
} enc_key;
block128_f enc_block;
};
} // namespace
// gcm_siv_keys calculates the keys for a specific GCM-SIV record with the
// given nonce and writes them to |*out_keys|.
+4
View File
@@ -19,6 +19,8 @@
#include <gtest/gtest.h>
namespace {
TEST(ARMLinuxTest, CPUInfo) {
struct CPUInfoTest {
const char *cpuinfo;
@@ -146,3 +148,5 @@ TEST(ARMLinuxTest, CPUInfo) {
EXPECT_EQ(t.hwcap2, crypto_get_arm_hwcap2_from_cpuinfo(&sp));
}
}
} // namespace
+2
View File
@@ -319,9 +319,11 @@ static void left_shift_3(uint8_t n[32]) {
}
}
namespace {
typedef struct {
BN_ULONG words[32 / sizeof(BN_ULONG)];
} scalar;
} // namespace
// kOrder is the order of the prime-order subgroup of curve25519.
static const scalar kOrder = {
+19 -15
View File
@@ -36,9 +36,11 @@
#include "../test/test_util.h"
namespace {
struct MD {
// name is the name of the digest.
const char* name;
const char *name;
// md_func is the digest to test.
const EVP_MD *(*func)(void);
// one_shot_func is the convenience one-shot version of the
@@ -46,16 +48,16 @@ struct MD {
uint8_t *(*one_shot_func)(const uint8_t *, size_t, uint8_t *);
};
static const MD md4 = { "MD4", &EVP_md4, nullptr };
static const MD md5 = { "MD5", &EVP_md5, &MD5 };
static const MD sha1 = { "SHA1", &EVP_sha1, &SHA1 };
static const MD sha224 = { "SHA224", &EVP_sha224, &SHA224 };
static const MD sha256 = { "SHA256", &EVP_sha256, &SHA256 };
static const MD sha384 = { "SHA384", &EVP_sha384, &SHA384 };
static const MD sha512 = { "SHA512", &EVP_sha512, &SHA512 };
static const MD sha512_256 = { "SHA512-256", &EVP_sha512_256, &SHA512_256 };
static const MD md5_sha1 = { "MD5-SHA1", &EVP_md5_sha1, nullptr };
static const MD blake2b256 = { "BLAKE2b-256", &EVP_blake2b256, nullptr };
static const MD md4 = {"MD4", &EVP_md4, nullptr};
static const MD md5 = {"MD5", &EVP_md5, &MD5};
static const MD sha1 = {"SHA1", &EVP_sha1, &SHA1};
static const MD sha224 = {"SHA224", &EVP_sha224, &SHA224};
static const MD sha256 = {"SHA256", &EVP_sha256, &SHA256};
static const MD sha384 = {"SHA384", &EVP_sha384, &SHA384};
static const MD sha512 = {"SHA512", &EVP_sha512, &SHA512};
static const MD sha512_256 = {"SHA512-256", &EVP_sha512_256, &SHA512_256};
static const MD md5_sha1 = {"MD5-SHA1", &EVP_md5_sha1, nullptr};
static const MD blake2b256 = {"BLAKE2b-256", &EVP_blake2b256, nullptr};
struct DigestTestVector {
// md is the digest to test.
@@ -145,15 +147,15 @@ static const DigestTestVector kTestVectors[] = {
// MD5-SHA1 tests.
{md5_sha1, "abc", 1,
"900150983cd24fb0d6963f7d28e17f72a9993e364706816aba3e25717850c26c9cd0d89d"},
"900150983cd24fb0d6963f7d28e17f72a9993e364706816aba3e25717850c26c9cd0d89"
"d"},
// BLAKE2b-256 tests.
{blake2b256, "abc", 1,
"bddd813c634239723171ef3fee98579b94964e3bb1cb3e427262c8c068d52319"},
};
static void CompareDigest(const DigestTestVector *test,
const uint8_t *digest,
static void CompareDigest(const DigestTestVector *test, const uint8_t *digest,
size_t digest_len) {
EXPECT_EQ(test->expected_hex,
EncodeHex(bssl::MakeConstSpan(digest, digest_len)));
@@ -320,7 +322,7 @@ TEST(DigestTest, ASN1) {
TEST(DigestTest, TransformBlocks) {
uint8_t blocks[SHA256_CBLOCK * 10];
for (size_t i = 0; i < sizeof(blocks); i++) {
blocks[i] = i*3;
blocks[i] = i * 3;
}
SHA256_CTX ctx1;
@@ -333,3 +335,5 @@ TEST(DigestTest, TransformBlocks) {
EXPECT_TRUE(0 == OPENSSL_memcmp(ctx1.h, ctx2.h, sizeof(ctx1.h)));
}
} // namespace
+12 -10
View File
@@ -7,7 +7,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
@@ -56,14 +56,14 @@
#include <limits.h>
#include <string.h>
#include <openssl/bytestring.h>
#include <openssl/bn.h>
#include <openssl/bytestring.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/nid.h>
#include "../fipsmodule/ec/internal.h"
#include "../bytestring/internal.h"
#include "../fipsmodule/ec/internal.h"
#include "../internal.h"
@@ -86,7 +86,7 @@ EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) {
CBS ec_private_key, private_key;
uint64_t version;
if (!CBS_get_asn1(cbs, &ec_private_key, CBS_ASN1_SEQUENCE) ||
!CBS_get_asn1_uint64(&ec_private_key, &version) ||
!CBS_get_asn1_uint64(&ec_private_key, &version) || //
version != 1 ||
!CBS_get_asn1(&ec_private_key, &private_key, CBS_ASN1_OCTETSTRING)) {
OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
@@ -150,7 +150,7 @@ EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) {
!CBS_get_asn1(&child, &public_key, CBS_ASN1_BITSTRING) ||
// As in a SubjectPublicKeyInfo, the byte-encoded public key is then
// encoded as a BIT STRING with bits ordered as in the DER encoding.
!CBS_get_u8(&public_key, &padding) ||
!CBS_get_u8(&public_key, &padding) || //
padding != 0 ||
// Explicitly check |public_key| is non-empty to save the conversion
// form later.
@@ -251,9 +251,11 @@ int EC_KEY_marshal_private_key(CBB *cbb, const EC_KEY *key,
// kPrimeFieldOID is the encoding of 1.2.840.10045.1.1.
static const uint8_t kPrimeField[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01};
namespace {
struct explicit_prime_curve {
CBS prime, a, b, base_x, base_y, order;
};
} // namespace
static int parse_explicit_prime_curve(CBS *in,
struct explicit_prime_curve *out) {
@@ -263,15 +265,15 @@ static int parse_explicit_prime_curve(CBS *in,
int has_cofactor;
uint64_t version;
if (!CBS_get_asn1(in, &params, CBS_ASN1_SEQUENCE) ||
!CBS_get_asn1_uint64(&params, &version) ||
version != 1 ||
!CBS_get_asn1_uint64(&params, &version) || //
version != 1 || //
!CBS_get_asn1(&params, &field_id, CBS_ASN1_SEQUENCE) ||
!CBS_get_asn1(&field_id, &field_type, CBS_ASN1_OBJECT) ||
CBS_len(&field_type) != sizeof(kPrimeField) ||
OPENSSL_memcmp(CBS_data(&field_type), kPrimeField, sizeof(kPrimeField)) !=
0 ||
!CBS_get_asn1(&field_id, &out->prime, CBS_ASN1_INTEGER) ||
!CBS_is_unsigned_asn1_integer(&out->prime) ||
!CBS_is_unsigned_asn1_integer(&out->prime) || //
CBS_len(&field_id) != 0 ||
!CBS_get_asn1(&params, &curve, CBS_ASN1_SEQUENCE) ||
!CBS_get_asn1(&curve, &out->a, CBS_ASN1_OCTETSTRING) ||
@@ -291,7 +293,7 @@ static int parse_explicit_prime_curve(CBS *in,
if (has_cofactor) {
// We only support prime-order curves so the cofactor must be one.
if (CBS_len(&cofactor) != 1 ||
if (CBS_len(&cofactor) != 1 || //
CBS_data(&cofactor)[0] != 1) {
OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
return 0;
@@ -546,7 +548,7 @@ int i2d_ECParameters(const EC_KEY *key, uint8_t **outp) {
}
CBB cbb;
if (!CBB_init(&cbb, 0) ||
if (!CBB_init(&cbb, 0) || //
!EC_KEY_marshal_curve_name(&cbb, key->group)) {
CBB_cleanup(&cbb);
return -1;
+4
View File
@@ -130,6 +130,7 @@ OPENSSL_MSVC_PRAGMA(warning(pop))
#include "./internal.h"
namespace {
struct err_error_st {
// file contains the filename where the error occurred.
const char *file;
@@ -159,6 +160,7 @@ typedef struct err_state_st {
// previously a |data| pointer of one of the elements of |errors|.
void *to_free;
} ERR_STATE;
} // namespace
extern const uint32_t kOpenSSLReasonValues[];
extern const size_t kOpenSSLReasonValuesLen;
@@ -431,11 +433,13 @@ static const char *err_string_lookup(uint32_t lib, uint32_t key,
return &string_data[(*result) & 0x7fff];
}
namespace {
typedef struct library_name_st {
const char *str;
const char *symbol;
const char *reason_symbol;
} LIBRARY_NAME;
} // namespace
static const LIBRARY_NAME kLibraryNames[ERR_NUM_LIBS] = {
{"invalid library (0)", NULL, NULL},
+2
View File
@@ -18,9 +18,11 @@
#include "internal.h"
namespace {
typedef struct dh_pkey_ctx_st {
int pad;
} DH_PKEY_CTX;
} // namespace
static int pkey_dh_init(EVP_PKEY_CTX *ctx) {
DH_PKEY_CTX *dctx =
+10
View File
@@ -521,6 +521,11 @@ OPENSSL_EXPORT bcm_status BCM_mlkem768_marshal_public_key(
OPENSSL_EXPORT bcm_status BCM_mlkem768_parse_public_key(
struct BCM_mlkem768_public_key *out_public_key, CBS *in);
// BCM_mlkem768_parse_private_key parses a private key, in NIST's format for
// private keys, from |in| and writes the result to |out_private_key|. It
// returns one on success or zero on parse error or if there are trailing bytes
// in |in|. This format is verbose and should be avoided. Private keys should be
// stored as seeds and parsed using |BCM_mlkem768_private_key_from_seed|.
OPENSSL_EXPORT bcm_status BCM_mlkem768_parse_private_key(
struct BCM_mlkem768_private_key *out_private_key, CBS *in);
@@ -595,6 +600,11 @@ OPENSSL_EXPORT bcm_status BCM_mlkem1024_marshal_public_key(
OPENSSL_EXPORT bcm_status BCM_mlkem1024_parse_public_key(
struct BCM_mlkem1024_public_key *out_public_key, CBS *in);
// BCM_mlkem1024_parse_private_key parses a private key, in NIST's format for
// private keys, from |in| and writes the result to |out_private_key|. It
// returns one on success or zero on parse error or if there are trailing bytes
// in |in|. This format is verbose and should be avoided. Private keys should be
// stored as seeds and parsed using |BCM_mlkem1024_private_key_from_seed|.
OPENSSL_EXPORT bcm_status BCM_mlkem1024_parse_private_key(
struct BCM_mlkem1024_private_key *out_private_key, CBS *in);
+35 -34
View File
@@ -87,15 +87,17 @@
#include <openssl/mem.h>
#include <openssl/rand.h>
#include "./internal.h"
#include "./rsaz_exp.h"
#include "../../internal.h"
#include "../../test/abi_test.h"
#include "../../test/file_test.h"
#include "../../test/test_util.h"
#include "../../test/wycheproof_util.h"
#include "./internal.h"
#include "./rsaz_exp.h"
namespace {
static int HexToBIGNUM(bssl::UniquePtr<BIGNUM> *out, const char *in) {
BIGNUM *raw = NULL;
int ret = BN_hex2bn(&raw, in);
@@ -160,10 +162,12 @@ class BIGNUMFileTest {
unsigned num_bignums_;
};
static testing::AssertionResult AssertBIGNUMSEqual(
const char *operation_expr, const char *expected_expr,
const char *actual_expr, const char *operation, const BIGNUM *expected,
const BIGNUM *actual) {
static testing::AssertionResult AssertBIGNUMSEqual(const char *operation_expr,
const char *expected_expr,
const char *actual_expr,
const char *operation,
const BIGNUM *expected,
const BIGNUM *actual) {
if (BN_cmp(expected, actual) == 0) {
return testing::AssertionSuccess();
}
@@ -650,8 +654,7 @@ static void TestModMul(BIGNUMFileTest *t, BN_CTX *ctx) {
ASSERT_TRUE(mont);
// Sanity-check that the constant-time version computes the same n0 and RR.
bssl::UniquePtr<BN_MONT_CTX> mont2(
BN_MONT_CTX_new_consttime(m.get(), ctx));
bssl::UniquePtr<BN_MONT_CTX> mont2(BN_MONT_CTX_new_consttime(m.get(), ctx));
ASSERT_TRUE(mont2);
EXPECT_BIGNUMS_EQUAL("RR (mod M) (constant-time)", &mont->RR, &mont2->RR);
EXPECT_EQ(mont->n0[0], mont2->n0[0]);
@@ -701,8 +704,8 @@ static void TestModMul(BIGNUMFileTest *t, BN_CTX *ctx) {
bn_from_montgomery_small(r_words.get(), m_width, r_words.get(), m_width,
mont.get());
ASSERT_TRUE(bn_set_words(ret.get(), r_words.get(), m_width));
EXPECT_BIGNUMS_EQUAL("A * B (mod M) (Montgomery, words)",
mod_mul.get(), ret.get());
EXPECT_BIGNUMS_EQUAL("A * B (mod M) (Montgomery, words)", mod_mul.get(),
ret.get());
}
#endif
}
@@ -1009,7 +1012,7 @@ static void RunBNFileTest(FileTest *t, BN_CTX *ctx) {
{"ModInv", TestModInv},
{"GCD", TestGCD},
};
void (*func)(BIGNUMFileTest * t, BN_CTX * ctx) = nullptr;
void (*func)(BIGNUMFileTest *t, BN_CTX *ctx) = nullptr;
for (const auto &test : kTests) {
if (t->GetType() == test.name) {
func = test.func;
@@ -1305,12 +1308,12 @@ struct MPITest {
};
static const MPITest kMPITests[] = {
{ "0", "\x00\x00\x00\x00", 4 },
{ "1", "\x00\x00\x00\x01\x01", 5 },
{ "-1", "\x00\x00\x00\x01\x81", 5 },
{ "128", "\x00\x00\x00\x02\x00\x80", 6 },
{ "256", "\x00\x00\x00\x02\x01\x00", 6 },
{ "-256", "\x00\x00\x00\x02\x81\x00", 6 },
{"0", "\x00\x00\x00\x00", 4},
{"1", "\x00\x00\x00\x01\x01", 5},
{"-1", "\x00\x00\x00\x01\x81", 5},
{"128", "\x00\x00\x00\x02\x00\x80", 6},
{"256", "\x00\x00\x00\x02\x01\x00", 6},
{"-256", "\x00\x00\x00\x02\x81\x00", 6},
};
TEST_F(BNTest, MPI) {
@@ -1417,8 +1420,8 @@ TEST_F(BNTest, RandRange) {
ASSERT_TRUE(BN_rand_range_ex(bn.get(), 1, six.get()));
BN_ULONG word = BN_get_word(bn.get());
if (BN_is_negative(bn.get()) ||
word < 1 ||
if (BN_is_negative(bn.get()) || //
word < 1 || //
word >= 6) {
FAIL() << "BN_rand_range_ex generated invalid value: " << word;
}
@@ -1448,10 +1451,8 @@ static const ASN1Test kASN1Tests[] = {
{"127", "\x02\x01\x7f", 3},
{"128", "\x02\x02\x00\x80", 4},
{"0xdeadbeef", "\x02\x05\x00\xde\xad\xbe\xef", 7},
{"0x0102030405060708",
"\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10},
{"0xffffffffffffffff",
"\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11},
{"0x0102030405060708", "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10},
{"0xffffffffffffffff", "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11},
};
struct ASN1InvalidTest {
@@ -1481,7 +1482,7 @@ TEST_F(BNTest, ASN1) {
bssl::UniquePtr<BIGNUM> bn2(BN_new());
ASSERT_TRUE(bn2);
CBS cbs;
CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
CBS_init(&cbs, reinterpret_cast<const uint8_t *>(test.der), test.der_len);
ASSERT_TRUE(BN_parse_asn1_unsigned(&cbs, bn2.get()));
EXPECT_EQ(0u, CBS_len(&cbs));
EXPECT_BIGNUMS_EQUAL("decode ASN.1", bn.get(), bn2.get());
@@ -1498,7 +1499,7 @@ TEST_F(BNTest, ASN1) {
}
for (const ASN1InvalidTest &test : kASN1InvalidTests) {
SCOPED_TRACE(Bytes(test.der, test.der_len));;
SCOPED_TRACE(Bytes(test.der, test.der_len));
bssl::UniquePtr<BIGNUM> bn(BN_new());
ASSERT_TRUE(bn);
CBS cbs;
@@ -1688,7 +1689,7 @@ TEST_F(BNTest, SmallPrime) {
bssl::UniquePtr<BIGNUM> r(BN_new());
ASSERT_TRUE(r);
ASSERT_TRUE(BN_generate_prime_ex(r.get(), static_cast<int>(kBits), 0, NULL,
NULL, NULL));
NULL, NULL));
EXPECT_EQ(kBits, BN_num_bits(r.get()));
}
@@ -1771,7 +1772,7 @@ TEST_F(BNTest, SetGetU64) {
{"ffffffffffffffff", UINT64_C(0xffffffffffffffff)},
};
for (const auto& test : kU64Tests) {
for (const auto &test : kU64Tests) {
SCOPED_TRACE(test.hex);
bssl::UniquePtr<BIGNUM> bn(BN_new()), expected;
ASSERT_TRUE(bn);
@@ -2068,7 +2069,7 @@ TEST_F(BNTest, PrimeChecking) {
int is_probably_prime_1 = 0, is_probably_prime_2 = 0;
enum bn_primality_result_t result_3;
const int max_prime = kPrimes[OPENSSL_ARRAY_SIZE(kPrimes)-1];
const int max_prime = kPrimes[OPENSSL_ARRAY_SIZE(kPrimes) - 1];
size_t next_prime_index = 0;
for (int i = 0; i <= max_prime; i++) {
@@ -2680,16 +2681,14 @@ TEST_F(BNTest, NonMinimal) {
bssl::UniquePtr<BN_MONT_CTX> mont(
BN_MONT_CTX_new_for_modulus(p.get(), ctx()));
ASSERT_TRUE(mont);
bssl::UniquePtr<BN_MONT_CTX> mont2(
BN_MONT_CTX_new_consttime(p.get(), ctx()));
bssl::UniquePtr<BN_MONT_CTX> mont2(BN_MONT_CTX_new_consttime(p.get(), ctx()));
ASSERT_TRUE(mont2);
ASSERT_TRUE(bn_resize_words(p.get(), 32));
bssl::UniquePtr<BN_MONT_CTX> mont3(
BN_MONT_CTX_new_for_modulus(p.get(), ctx()));
ASSERT_TRUE(mont3);
bssl::UniquePtr<BN_MONT_CTX> mont4(
BN_MONT_CTX_new_consttime(p.get(), ctx()));
bssl::UniquePtr<BN_MONT_CTX> mont4(BN_MONT_CTX_new_consttime(p.get(), ctx()));
ASSERT_TRUE(mont4);
EXPECT_EQ(mont->N.width, mont2->N.width);
@@ -2919,7 +2918,7 @@ TEST_F(BNTest, BNMulMontABI) {
#endif
}
}
#endif // OPENSSL_BN_ASM_MONT && SUPPORTS_ABI_TEST
#endif // OPENSSL_BN_ASM_MONT && SUPPORTS_ABI_TEST
#if defined(OPENSSL_BN_ASM_MONT5) && defined(SUPPORTS_ABI_TEST)
TEST_F(BNTest, BNMulMont5ABI) {
@@ -3009,4 +3008,6 @@ TEST_F(BNTest, RSAZABI) {
CHECK_ABI(rsaz_1024_gather5_avx2, rsaz1, table, 7);
CHECK_ABI(rsaz_1024_red2norm_avx2, norm, rsaz1);
}
#endif // RSAZ_ENABLED && SUPPORTS_ABI_TEST
#endif // RSAZ_ENABLED && SUPPORTS_ABI_TEST
} // namespace
@@ -216,6 +216,7 @@ err:
return ret;
}
namespace {
typedef struct bn_recp_ctx_st {
BIGNUM N; // the divisor
BIGNUM Nr; // the reciprocal
@@ -223,6 +224,7 @@ typedef struct bn_recp_ctx_st {
int shift;
int flags;
} BN_RECP_CTX;
} // namespace
static void BN_RECP_CTX_init(BN_RECP_CTX *recp) {
BN_init(&recp->N);
+10 -4
View File
@@ -243,7 +243,7 @@ static int aes_ofb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
const uint8_t *iv, int enc) {
EVP_AES_GCM_CTX *gctx = reinterpret_cast<EVP_AES_GCM_CTX*>(ctx->cipher_data);
EVP_AES_GCM_CTX *gctx = reinterpret_cast<EVP_AES_GCM_CTX *>(ctx->cipher_data);
if (!iv && !key) {
return 1;
}
@@ -276,7 +276,7 @@ static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
}
static void aes_gcm_cleanup(EVP_CIPHER_CTX *c) {
EVP_AES_GCM_CTX *gctx = reinterpret_cast<EVP_AES_GCM_CTX*>(c->cipher_data);
EVP_AES_GCM_CTX *gctx = reinterpret_cast<EVP_AES_GCM_CTX *>(c->cipher_data);
OPENSSL_cleanse(&gctx->key, sizeof(gctx->key));
OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm));
if (gctx->iv != c->iv) {
@@ -285,7 +285,7 @@ static void aes_gcm_cleanup(EVP_CIPHER_CTX *c) {
}
static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
EVP_AES_GCM_CTX *gctx = reinterpret_cast<EVP_AES_GCM_CTX*>(c->cipher_data);
EVP_AES_GCM_CTX *gctx = reinterpret_cast<EVP_AES_GCM_CTX *>(c->cipher_data);
switch (type) {
case EVP_CTRL_INIT:
gctx->key_set = 0;
@@ -406,7 +406,7 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
size_t len) {
EVP_AES_GCM_CTX *gctx = reinterpret_cast<EVP_AES_GCM_CTX*>(ctx->cipher_data);
EVP_AES_GCM_CTX *gctx = reinterpret_cast<EVP_AES_GCM_CTX *>(ctx->cipher_data);
// If not set up, return error
if (!gctx->key_set) {
@@ -737,9 +737,11 @@ EVP_ECB_CIPHER_FUNCTION(256)
#define EVP_AEAD_AES_GCM_TAG_LEN 16
namespace {
struct aead_aes_gcm_ctx {
GCM128_KEY key;
};
} // namespace
static int aead_aes_gcm_init_impl(struct aead_aes_gcm_ctx *gcm_ctx,
size_t *out_tag_len, const uint8_t *key,
@@ -1060,10 +1062,12 @@ DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_256_gcm_randnonce) {
out->open_gather = aead_aes_gcm_open_gather_randnonce;
}
namespace {
struct aead_aes_gcm_tls12_ctx {
struct aead_aes_gcm_ctx gcm_ctx;
uint64_t min_next_nonce;
};
} // namespace
static_assert(sizeof(((EVP_AEAD_CTX *)NULL)->state) >=
sizeof(struct aead_aes_gcm_tls12_ctx),
@@ -1152,12 +1156,14 @@ DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_256_gcm_tls12) {
out->open_gather = aead_aes_gcm_open_gather;
}
namespace {
struct aead_aes_gcm_tls13_ctx {
struct aead_aes_gcm_ctx gcm_ctx;
uint64_t min_next_nonce;
uint64_t mask;
uint8_t first;
};
} // namespace
static_assert(sizeof(((EVP_AEAD_CTX *)NULL)->state) >=
sizeof(struct aead_aes_gcm_tls13_ctx),
+6 -4
View File
@@ -54,8 +54,8 @@
#include <openssl/err.h>
#include <openssl/mem.h>
#include "../delocate.h"
#include "../aes/internal.h"
#include "../delocate.h"
#include "../modes/internal.h"
#include "../service_indicator/internal.h"
#include "internal.h"
@@ -100,8 +100,8 @@ static int ccm128_init_state(const struct ccm128_context *ctx,
const unsigned L = ctx->L;
// |L| determines the expected |nonce_len| and the limit for |plaintext_len|.
if (plaintext_len > CRYPTO_ccm128_max_input(ctx) ||
nonce_len != 15 - L) {
if (plaintext_len > CRYPTO_ccm128_max_input(ctx) //
|| nonce_len != 15 - L) {
return 0;
}
@@ -167,7 +167,7 @@ static int ccm128_init_state(const struct ccm128_context *ctx,
size_t remaining_blocks = 2 * ((plaintext_len + 15) / 16) + 1;
if (plaintext_len + 15 < plaintext_len ||
remaining_blocks + blocks < blocks ||
(uint64_t) remaining_blocks + blocks > UINT64_C(1) << 61) {
(uint64_t)remaining_blocks + blocks > UINT64_C(1) << 61) {
return 0;
}
@@ -257,6 +257,7 @@ static int CRYPTO_ccm128_decrypt(const struct ccm128_context *ctx,
#define EVP_AEAD_AES_CCM_MAX_TAG_LEN 16
namespace {
struct aead_aes_ccm_ctx {
union {
double align;
@@ -264,6 +265,7 @@ struct aead_aes_ccm_ctx {
} ks;
struct ccm128_context ccm;
};
} // namespace
static_assert(sizeof(((EVP_AEAD_CTX *)NULL)->state) >=
sizeof(struct aead_aes_ccm_ctx),
+116 -107
View File
@@ -37,13 +37,16 @@
#include "internal.h"
namespace {
// kECKeyWithoutPublic is an ECPrivateKey with the optional publicKey field
// omitted.
static const uint8_t kECKeyWithoutPublic[] = {
0x30, 0x31, 0x02, 0x01, 0x01, 0x04, 0x20, 0xc6, 0xc1, 0xaa, 0xda, 0x15, 0xb0,
0x76, 0x61, 0xf8, 0x14, 0x2c, 0x6c, 0xaf, 0x0f, 0xdb, 0x24, 0x1a, 0xff, 0x2e,
0xfe, 0x46, 0xc0, 0x93, 0x8b, 0x74, 0xf2, 0xbc, 0xc5, 0x30, 0x52, 0xb0, 0x77,
0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07,
0x30, 0x31, 0x02, 0x01, 0x01, 0x04, 0x20, 0xc6, 0xc1, 0xaa, 0xda,
0x15, 0xb0, 0x76, 0x61, 0xf8, 0x14, 0x2c, 0x6c, 0xaf, 0x0f, 0xdb,
0x24, 0x1a, 0xff, 0x2e, 0xfe, 0x46, 0xc0, 0x93, 0x8b, 0x74, 0xf2,
0xbc, 0xc5, 0x30, 0x52, 0xb0, 0x77, 0xa0, 0x0a, 0x06, 0x08, 0x2a,
0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07,
};
// kECKeySpecifiedCurve is the above key with P-256's parameters explicitly
@@ -80,29 +83,31 @@ static const uint8_t kECKeySpecifiedCurve[] = {
// the private key is one. The private key is incorrectly encoded without zero
// padding.
static const uint8_t kECKeyMissingZeros[] = {
0x30, 0x58, 0x02, 0x01, 0x01, 0x04, 0x01, 0x01, 0xa0, 0x0a, 0x06, 0x08, 0x2a,
0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04,
0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5, 0x63,
0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0, 0xf4, 0xa1,
0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f,
0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57,
0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
0x30, 0x58, 0x02, 0x01, 0x01, 0x04, 0x01, 0x01, 0xa0, 0x0a, 0x06, 0x08,
0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42,
0x00, 0x04, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc,
0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb,
0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3,
0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f,
0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6,
0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
};
// kECKeyMissingZeros is an ECPrivateKey containing a degenerate P-256 key where
// the private key is one. The private key is encoded with the required zero
// padding.
static const uint8_t kECKeyWithZeros[] = {
0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0xa1,
0x44, 0x03, 0x42, 0x00, 0x04, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47,
0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d,
0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3,
0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e,
0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68,
0x37, 0xbf, 0x51, 0xf5,
0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xa0, 0x0a, 0x06, 0x08, 0x2a,
0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42,
0x00, 0x04, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8,
0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81,
0x2d, 0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2,
0x96, 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7,
0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b,
0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
};
static const uint8_t kECKeyWithZerosPublic[] = {
@@ -976,7 +981,7 @@ static std::vector<int> AllCurves() {
std::vector<EC_builtin_curve> curves(num_curves);
EC_get_builtin_curves(curves.data(), num_curves);
std::vector<int> nids;
for (const auto& curve : curves) {
for (const auto &curve : curves) {
nids.push_back(curve.nid);
}
return nids;
@@ -1026,44 +1031,45 @@ TEST(ECTest, ScalarBaseMultVectors) {
bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
ASSERT_TRUE(ctx);
FileTestGTest("crypto/fipsmodule/ec/ec_scalar_base_mult_tests.txt",
[&](FileTest *t) {
const EC_GROUP *group = GetCurve(t, "Curve");
ASSERT_TRUE(group);
bssl::UniquePtr<BIGNUM> n = GetBIGNUM(t, "N");
ASSERT_TRUE(n);
bssl::UniquePtr<BIGNUM> x = GetBIGNUM(t, "X");
ASSERT_TRUE(x);
bssl::UniquePtr<BIGNUM> y = GetBIGNUM(t, "Y");
ASSERT_TRUE(y);
bool is_infinity = BN_is_zero(x.get()) && BN_is_zero(y.get());
FileTestGTest(
"crypto/fipsmodule/ec/ec_scalar_base_mult_tests.txt", [&](FileTest *t) {
const EC_GROUP *group = GetCurve(t, "Curve");
ASSERT_TRUE(group);
bssl::UniquePtr<BIGNUM> n = GetBIGNUM(t, "N");
ASSERT_TRUE(n);
bssl::UniquePtr<BIGNUM> x = GetBIGNUM(t, "X");
ASSERT_TRUE(x);
bssl::UniquePtr<BIGNUM> y = GetBIGNUM(t, "Y");
ASSERT_TRUE(y);
bool is_infinity = BN_is_zero(x.get()) && BN_is_zero(y.get());
bssl::UniquePtr<BIGNUM> px(BN_new());
ASSERT_TRUE(px);
bssl::UniquePtr<BIGNUM> py(BN_new());
ASSERT_TRUE(py);
auto check_point = [&](const EC_POINT *p) {
if (is_infinity) {
EXPECT_TRUE(EC_POINT_is_at_infinity(group, p));
} else {
ASSERT_TRUE(EC_POINT_get_affine_coordinates_GFp(
group, p, px.get(), py.get(), ctx.get()));
EXPECT_EQ(0, BN_cmp(x.get(), px.get()));
EXPECT_EQ(0, BN_cmp(y.get(), py.get()));
}
};
bssl::UniquePtr<BIGNUM> px(BN_new());
ASSERT_TRUE(px);
bssl::UniquePtr<BIGNUM> py(BN_new());
ASSERT_TRUE(py);
auto check_point = [&](const EC_POINT *p) {
if (is_infinity) {
EXPECT_TRUE(EC_POINT_is_at_infinity(group, p));
} else {
ASSERT_TRUE(EC_POINT_get_affine_coordinates_GFp(
group, p, px.get(), py.get(), ctx.get()));
EXPECT_EQ(0, BN_cmp(x.get(), px.get()));
EXPECT_EQ(0, BN_cmp(y.get(), py.get()));
}
};
const EC_POINT *g = EC_GROUP_get0_generator(group);
bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group));
ASSERT_TRUE(p);
// Test single-point multiplication.
ASSERT_TRUE(EC_POINT_mul(group, p.get(), n.get(), nullptr, nullptr,
ctx.get()));
check_point(p.get());
const EC_POINT *g = EC_GROUP_get0_generator(group);
bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group));
ASSERT_TRUE(p);
// Test single-point multiplication.
ASSERT_TRUE(
EC_POINT_mul(group, p.get(), n.get(), nullptr, nullptr, ctx.get()));
check_point(p.get());
ASSERT_TRUE(EC_POINT_mul(group, p.get(), nullptr, g, n.get(), ctx.get()));
check_point(p.get());
});
ASSERT_TRUE(
EC_POINT_mul(group, p.get(), nullptr, g, n.get(), ctx.get()));
check_point(p.get());
});
}
// These tests take a very long time, but are worth running when we make
@@ -1072,61 +1078,62 @@ TEST(ECTest, DISABLED_ScalarBaseMultVectorsTwoPoint) {
bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
ASSERT_TRUE(ctx);
FileTestGTest("crypto/fipsmodule/ec/ec_scalar_base_mult_tests.txt",
[&](FileTest *t) {
const EC_GROUP *group = GetCurve(t, "Curve");
ASSERT_TRUE(group);
bssl::UniquePtr<BIGNUM> n = GetBIGNUM(t, "N");
ASSERT_TRUE(n);
bssl::UniquePtr<BIGNUM> x = GetBIGNUM(t, "X");
ASSERT_TRUE(x);
bssl::UniquePtr<BIGNUM> y = GetBIGNUM(t, "Y");
ASSERT_TRUE(y);
bool is_infinity = BN_is_zero(x.get()) && BN_is_zero(y.get());
FileTestGTest(
"crypto/fipsmodule/ec/ec_scalar_base_mult_tests.txt", [&](FileTest *t) {
const EC_GROUP *group = GetCurve(t, "Curve");
ASSERT_TRUE(group);
bssl::UniquePtr<BIGNUM> n = GetBIGNUM(t, "N");
ASSERT_TRUE(n);
bssl::UniquePtr<BIGNUM> x = GetBIGNUM(t, "X");
ASSERT_TRUE(x);
bssl::UniquePtr<BIGNUM> y = GetBIGNUM(t, "Y");
ASSERT_TRUE(y);
bool is_infinity = BN_is_zero(x.get()) && BN_is_zero(y.get());
bssl::UniquePtr<BIGNUM> px(BN_new());
ASSERT_TRUE(px);
bssl::UniquePtr<BIGNUM> py(BN_new());
ASSERT_TRUE(py);
auto check_point = [&](const EC_POINT *p) {
if (is_infinity) {
EXPECT_TRUE(EC_POINT_is_at_infinity(group, p));
} else {
ASSERT_TRUE(EC_POINT_get_affine_coordinates_GFp(
group, p, px.get(), py.get(), ctx.get()));
EXPECT_EQ(0, BN_cmp(x.get(), px.get()));
EXPECT_EQ(0, BN_cmp(y.get(), py.get()));
}
};
bssl::UniquePtr<BIGNUM> px(BN_new());
ASSERT_TRUE(px);
bssl::UniquePtr<BIGNUM> py(BN_new());
ASSERT_TRUE(py);
auto check_point = [&](const EC_POINT *p) {
if (is_infinity) {
EXPECT_TRUE(EC_POINT_is_at_infinity(group, p));
} else {
ASSERT_TRUE(EC_POINT_get_affine_coordinates_GFp(
group, p, px.get(), py.get(), ctx.get()));
EXPECT_EQ(0, BN_cmp(x.get(), px.get()));
EXPECT_EQ(0, BN_cmp(y.get(), py.get()));
}
};
const EC_POINT *g = EC_GROUP_get0_generator(group);
bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group));
ASSERT_TRUE(p);
bssl::UniquePtr<BIGNUM> a(BN_new()), b(BN_new());
for (int i = -64; i < 64; i++) {
SCOPED_TRACE(i);
ASSERT_TRUE(BN_set_word(a.get(), abs(i)));
if (i < 0) {
ASSERT_TRUE(BN_sub(a.get(), EC_GROUP_get0_order(group), a.get()));
}
const EC_POINT *g = EC_GROUP_get0_generator(group);
bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group));
ASSERT_TRUE(p);
bssl::UniquePtr<BIGNUM> a(BN_new()), b(BN_new());
for (int i = -64; i < 64; i++) {
SCOPED_TRACE(i);
ASSERT_TRUE(BN_set_word(a.get(), abs(i)));
if (i < 0) {
ASSERT_TRUE(BN_sub(a.get(), EC_GROUP_get0_order(group), a.get()));
}
ASSERT_TRUE(BN_copy(b.get(), n.get()));
ASSERT_TRUE(BN_sub(b.get(), b.get(), a.get()));
if (BN_is_negative(b.get())) {
ASSERT_TRUE(BN_add(b.get(), b.get(), EC_GROUP_get0_order(group)));
}
ASSERT_TRUE(BN_copy(b.get(), n.get()));
ASSERT_TRUE(BN_sub(b.get(), b.get(), a.get()));
if (BN_is_negative(b.get())) {
ASSERT_TRUE(BN_add(b.get(), b.get(), EC_GROUP_get0_order(group)));
}
ASSERT_TRUE(EC_POINT_mul(group, p.get(), a.get(), g, b.get(), ctx.get()));
check_point(p.get());
ASSERT_TRUE(
EC_POINT_mul(group, p.get(), a.get(), g, b.get(), ctx.get()));
check_point(p.get());
EC_SCALAR a_scalar, b_scalar;
ASSERT_TRUE(ec_bignum_to_scalar(group, &a_scalar, a.get()));
ASSERT_TRUE(ec_bignum_to_scalar(group, &b_scalar, b.get()));
ASSERT_TRUE(ec_point_mul_scalar_public(group, &p->raw, &a_scalar, &g->raw,
&b_scalar));
check_point(p.get());
}
});
EC_SCALAR a_scalar, b_scalar;
ASSERT_TRUE(ec_bignum_to_scalar(group, &a_scalar, a.get()));
ASSERT_TRUE(ec_bignum_to_scalar(group, &b_scalar, b.get()));
ASSERT_TRUE(ec_point_mul_scalar_public(group, &p->raw, &a_scalar,
&g->raw, &b_scalar));
check_point(p.get());
}
});
}
static std::vector<uint8_t> HexToBytes(const char *str) {
@@ -1409,3 +1416,5 @@ TEST(ECTest, HashToScalar) {
EC_group_p224(), &scalar, kDST, sizeof(kDST), kMessage,
sizeof(kMessage)));
}
} // namespace
+6
View File
@@ -25,6 +25,8 @@
#include "../../test/wycheproof_util.h"
namespace {
struct HKDFTestVector {
const EVP_MD *(*md_func)(void);
const uint8_t ikm[80];
@@ -41,6 +43,7 @@ struct HKDFTestVector {
// These test vectors are from RFC 5869.
static const HKDFTestVector kTests[] = {
// clang-format off
{
EVP_sha256,
{
@@ -246,6 +249,7 @@ static const HKDFTestVector kTests[] = {
0x70, 0xcc, 0xe7, 0xac, 0xfc, 0x48
}
},
// clang-format on
};
TEST(HKDFTest, TestVectors) {
@@ -416,3 +420,5 @@ TEST(HKDFTest, WycheproofSHA512) {
RunWycheproofTest("third_party/wycheproof_testvectors/hkdf_sha512_test.txt",
EVP_sha512());
}
} // namespace
+2
View File
@@ -53,6 +53,7 @@ static const unsigned kReseedInterval = 4096;
// continuous random number generator test in FIPS 140-2, section 4.9.2.
#define CRNGT_BLOCK_SIZE 16
namespace {
// rand_thread_state contains the per-thread state for the RNG.
struct rand_thread_state {
CTR_DRBG_STATE drbg;
@@ -79,6 +80,7 @@ struct rand_thread_state {
CRYPTO_MUTEX clear_drbg_lock;
#endif
};
} // namespace
#if defined(BORINGSSL_FIPS)
// thread_states_list is the head of a linked-list of all |rand_thread_state|
@@ -30,7 +30,7 @@
#include <openssl/hmac.h>
#include <openssl/md4.h>
#include <openssl/md5.h>
#include <openssl/rand.h> // TODO(bbe): only for RAND_bytes call below, replace with BCM call
#include <openssl/rand.h> // TODO(bbe): only for RAND_bytes call below, replace with BCM call
#include <openssl/rsa.h>
#include <openssl/service_indicator.h>
@@ -42,6 +42,8 @@
#include "../tls/internal.h"
namespace {
using bssl::FIPSStatus;
static const uint8_t kAESKey[16] = {'A', 'W', 'S', '-', 'L', 'C', 'C', 'r',
@@ -2424,3 +2426,5 @@ TEST(ServiceIndicatorTest, BasicTest) {
}
#endif // BORINGSSL_FIPS
} // namespace
+4
View File
@@ -847,6 +847,7 @@ void HRSS_poly3_invert(struct poly3 *out, const struct poly3 *in) {
#define COEFFICIENTS_PER_VEC (sizeof(vec_t) / sizeof(uint16_t))
#define VECS_PER_POLY ((N + COEFFICIENTS_PER_VEC - 1) / COEFFICIENTS_PER_VEC)
namespace {
// poly represents a polynomial with coefficients mod Q. Note that, while Q is a
// power of two, this does not operate in GF(Q). That would be a binary field
// but this is simply mod Q. Thus the coefficients are not a field.
@@ -867,6 +868,7 @@ struct poly {
alignas(16) uint16_t v[N + 3];
#endif
};
} // namespace
// poly_normalize zeros out the excess elements of |x| which are included only
// for alignment.
@@ -882,6 +884,7 @@ static void poly_assert_normalized(const struct poly *x) {
assert(x->v[N + 2] == 0);
}
namespace {
// POLY_MUL_SCRATCH contains space for the working variables needed by
// |poly_mul|. The contents afterwards may be discarded, but the object may also
// be reused with future |poly_mul| calls to save heap allocations.
@@ -909,6 +912,7 @@ struct POLY_MUL_SCRATCH {
#endif
} u;
};
} // namespace
#if defined(HRSS_HAVE_VECTOR_UNIT)
+12 -7
View File
@@ -19,8 +19,8 @@
#include <string.h>
#include <algorithm>
#include <memory>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
@@ -32,6 +32,8 @@
#include "internal.h"
namespace {
DEFINE_LHASH_OF(char)
static std::unique_ptr<char[]> RandString(void) {
@@ -86,12 +88,13 @@ TEST(LHashTest, Basic) {
}
std::sort(expected.begin(), expected.end());
lh_char_doall_arg(lh.get(),
[](char *ptr, void *arg) {
ValueList *out = reinterpret_cast<ValueList *>(arg);
out->push_back(ptr);
},
&actual);
lh_char_doall_arg(
lh.get(),
[](char *ptr, void *arg) {
ValueList *out = reinterpret_cast<ValueList *>(arg);
out->push_back(ptr);
},
&actual);
std::sort(actual.begin(), actual.end());
EXPECT_EQ(expected, actual);
}
@@ -141,3 +144,5 @@ TEST(LHashTest, Basic) {
}
}
}
} // namespace
-14
View File
@@ -30,11 +30,8 @@ static_assert(MLKEM768_PUBLIC_KEY_BYTES == BCM_MLKEM768_PUBLIC_KEY_BYTES, "");
static_assert(MLKEM_SEED_BYTES == BCM_MLKEM_SEED_BYTES, "");
static_assert(MLKEM768_CIPHERTEXT_BYTES == BCM_MLKEM768_CIPHERTEXT_BYTES, "");
static_assert(MLKEM_SHARED_SECRET_BYTES == BCM_MLKEM_SHARED_SECRET_BYTES, "");
static_assert(MLKEM768_PRIVATE_KEY_BYTES == BCM_MLKEM768_PRIVATE_KEY_BYTES, "");
static_assert(MLKEM1024_PUBLIC_KEY_BYTES == BCM_MLKEM1024_PUBLIC_KEY_BYTES, "");
static_assert(MLKEM1024_CIPHERTEXT_BYTES == BCM_MLKEM1024_CIPHERTEXT_BYTES, "");
static_assert(MLKEM1024_PRIVATE_KEY_BYTES == BCM_MLKEM1024_PRIVATE_KEY_BYTES,
"");
void MLKEM768_generate_key(
uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES],
@@ -88,11 +85,6 @@ int MLKEM768_parse_public_key(struct MLKEM768_public_key *out_public_key,
reinterpret_cast<BCM_mlkem768_public_key *>(out_public_key), in));
}
int MLKEM768_parse_private_key(struct MLKEM768_private_key *out_private_key,
CBS *in) {
return bcm_success(BCM_mlkem768_parse_private_key(
reinterpret_cast<BCM_mlkem768_private_key *>(out_private_key), in));
}
static_assert(sizeof(BCM_mlkem1024_private_key) <=
sizeof(MLKEM1024_private_key),
@@ -158,9 +150,3 @@ int MLKEM1024_parse_public_key(struct MLKEM1024_public_key *out_public_key,
return bcm_success(BCM_mlkem1024_parse_public_key(
reinterpret_cast<BCM_mlkem1024_public_key *>(out_public_key), in));
}
int MLKEM1024_parse_private_key(struct MLKEM1024_private_key *out_private_key,
CBS *in) {
return bcm_success(BCM_mlkem1024_parse_private_key(
reinterpret_cast<BCM_mlkem1024_private_key *>(out_private_key), in));
}
+27 -15
View File
@@ -104,6 +104,18 @@ void wrapper_1024_encap_external_entropy(
reinterpret_cast<const BCM_mlkem1024_public_key *>(public_key), entropy);
}
int wrapper_768_parse_private_key(struct MLKEM768_private_key *out_private_key,
CBS *in) {
return bcm_success(BCM_mlkem768_parse_private_key(
reinterpret_cast<BCM_mlkem768_private_key *>(out_private_key), in));
}
int wrapper_1024_parse_private_key(
struct MLKEM1024_private_key *out_private_key, CBS *in) {
return bcm_success(BCM_mlkem1024_parse_private_key(
reinterpret_cast<BCM_mlkem1024_private_key *>(out_private_key), in));
}
template <typename PUBLIC_KEY, size_t PUBLIC_KEY_BYTES, typename PRIVATE_KEY,
size_t PRIVATE_KEY_BYTES,
void (*GENERATE)(uint8_t *, uint8_t *, PRIVATE_KEY *),
@@ -192,20 +204,20 @@ void BasicTest() {
TEST(MLKEMTest, Basic768) {
BasicTest<MLKEM768_public_key, MLKEM768_PUBLIC_KEY_BYTES,
MLKEM768_private_key, MLKEM768_PRIVATE_KEY_BYTES,
MLKEM768_private_key, BCM_MLKEM768_PRIVATE_KEY_BYTES,
MLKEM768_generate_key, MLKEM768_private_key_from_seed,
MLKEM768_public_from_private, MLKEM768_parse_public_key,
MLKEM768_marshal_public_key, MLKEM768_parse_private_key,
MLKEM768_marshal_public_key, wrapper_768_parse_private_key,
wrapper_768_marshal_private_key, MLKEM768_CIPHERTEXT_BYTES,
MLKEM768_encap, MLKEM768_decap>();
}
TEST(MLKEMTest, Basic1024) {
BasicTest<MLKEM1024_public_key, MLKEM1024_PUBLIC_KEY_BYTES,
MLKEM1024_private_key, MLKEM1024_PRIVATE_KEY_BYTES,
MLKEM1024_private_key, BCM_MLKEM1024_PRIVATE_KEY_BYTES,
MLKEM1024_generate_key, MLKEM1024_private_key_from_seed,
MLKEM1024_public_from_private, MLKEM1024_parse_public_key,
MLKEM1024_marshal_public_key, MLKEM1024_parse_private_key,
MLKEM1024_marshal_public_key, wrapper_1024_parse_private_key,
wrapper_1024_marshal_private_key, MLKEM1024_CIPHERTEXT_BYTES,
MLKEM1024_encap, MLKEM1024_decap>();
}
@@ -376,16 +388,16 @@ void MLKEMDecapFileTest(FileTest *t) {
TEST(MLKEMTest, Decap768TestVectors) {
FileTestGTest(
"crypto/mlkem/mlkem768_decap_tests.txt",
MLKEMDecapFileTest<MLKEM768_private_key, MLKEM768_PRIVATE_KEY_BYTES,
MLKEM768_parse_private_key, MLKEM768_CIPHERTEXT_BYTES,
MLKEM768_decap>);
MLKEMDecapFileTest<MLKEM768_private_key, BCM_MLKEM768_PRIVATE_KEY_BYTES,
wrapper_768_parse_private_key,
MLKEM768_CIPHERTEXT_BYTES, MLKEM768_decap>);
}
TEST(MLKEMTest, Decap1024TestVectors) {
FileTestGTest(
"crypto/mlkem/mlkem1024_decap_tests.txt",
MLKEMDecapFileTest<MLKEM1024_private_key, MLKEM1024_PRIVATE_KEY_BYTES,
MLKEM1024_parse_private_key,
MLKEMDecapFileTest<MLKEM1024_private_key, BCM_MLKEM1024_PRIVATE_KEY_BYTES,
wrapper_1024_parse_private_key,
MLKEM1024_CIPHERTEXT_BYTES, MLKEM1024_decap>);
}
@@ -413,15 +425,15 @@ void MLKEMNistDecapFileTest(FileTest *t) {
TEST(MLKEMTest, NistDecap768TestVectors) {
FileTestGTest(
"crypto/mlkem/mlkem768_nist_decap_tests.txt",
MLKEMNistDecapFileTest<MLKEM768_private_key, MLKEM768_parse_private_key,
MLKEM768_decap>);
MLKEMNistDecapFileTest<MLKEM768_private_key,
wrapper_768_parse_private_key, MLKEM768_decap>);
}
TEST(MLKEMTest, NistDecap1024TestVectors) {
FileTestGTest(
"crypto/mlkem/mlkem1024_nist_decap_tests.txt",
MLKEMNistDecapFileTest<MLKEM1024_private_key, MLKEM1024_parse_private_key,
MLKEM1024_decap>);
MLKEMNistDecapFileTest<MLKEM1024_private_key,
wrapper_1024_parse_private_key, MLKEM1024_decap>);
}
template <
@@ -482,7 +494,7 @@ TEST(MLKEMTest, Iterate768) {
// ML-KEM.
uint8_t result[32];
IteratedTest<MLKEM768_public_key, MLKEM768_PUBLIC_KEY_BYTES,
MLKEM768_private_key, MLKEM768_PRIVATE_KEY_BYTES,
MLKEM768_private_key, BCM_MLKEM768_PRIVATE_KEY_BYTES,
wrapper_768_generate_key_external_seed,
MLKEM768_public_from_private, wrapper_768_marshal_private_key,
MLKEM768_CIPHERTEXT_BYTES, wrapper_768_encap_external_entropy,
@@ -503,7 +515,7 @@ TEST(MLKEMTest, Iterate1024) {
// ML-KEM.
uint8_t result[32];
IteratedTest<MLKEM1024_public_key, MLKEM1024_PUBLIC_KEY_BYTES,
MLKEM1024_private_key, MLKEM1024_PRIVATE_KEY_BYTES,
MLKEM1024_private_key, BCM_MLKEM1024_PRIVATE_KEY_BYTES,
wrapper_1024_generate_key_external_seed,
MLKEM1024_public_from_private, wrapper_1024_marshal_private_key,
MLKEM1024_CIPHERTEXT_BYTES, wrapper_1024_encap_external_entropy,
+5 -1
View File
@@ -26,6 +26,8 @@
#include "../test/test_util.h"
namespace {
// Test that implausible ciphers, notably an IV-less RC4, aren't allowed in PEM.
// This is a regression test for https://github.com/openssl/openssl/issues/6347,
// though our fix differs from upstream.
@@ -53,7 +55,7 @@ static std::vector<uint8_t> DecodePEMBytes(const char *pem) {
char *name, *header;
uint8_t *data;
long len;
if (bio == nullptr ||
if (bio == nullptr || //
!PEM_read_bio(bio.get(), &name, &header, &data, &len)) {
return {};
}
@@ -313,3 +315,5 @@ Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB
}
}
}
} // namespace
+2
View File
@@ -416,11 +416,13 @@ out:
return ret;
}
namespace {
struct signer_info_data {
const X509 *sign_cert;
uint8_t *signature;
size_t signature_len;
};
} // namespace
// write_signer_info writes the SignerInfo structure from
// https://datatracker.ietf.org/doc/html/rfc2315#section-9.2 to |out|. It
+12 -6
View File
@@ -19,8 +19,8 @@
#include <openssl/ctrdrbg.h>
#include <openssl/rand.h>
#include "getrandom_fillin.h"
#include "../internal.h"
#include "getrandom_fillin.h"
#if (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \
@@ -36,6 +36,8 @@
#include <sys/un.h>
#include <sys/user.h>
namespace {
#if !defined(PTRACE_O_EXITKILL)
#define PTRACE_O_EXITKILL (1 << 20)
#endif
@@ -77,8 +79,9 @@ struct Event {
explicit Event(Syscall syscall) : type(syscall) {}
bool operator==(const Event &other) const {
return type == other.type && length == other.length &&
flags == other.flags &&
return type == other.type && //
length == other.length && //
flags == other.flags && //
filename == other.filename;
}
@@ -492,7 +495,8 @@ static void GetTrace(std::vector<Event> *out_trace, unsigned flags,
{
uintptr_t filename_ptr =
(regs.syscall == __NR_openat) ? regs.args[1] : regs.args[0];
const std::string filename = get_string_from_remote(child_pid, filename_ptr);
const std::string filename =
get_string_from_remote(child_pid, filename_ptr);
if (filename.find("/dev/__properties__/") == 0) {
// Android may try opening these files as part of SELinux support.
// They are ignored here.
@@ -722,7 +726,7 @@ static std::vector<Event> TestFunctionPRNGModel(unsigned flags) {
}
used_daemon = kUsesDaemon && AppendDaemonEvents(&ret, flags);
}
if (// Initialise CRNGT.
if ( // Initialise CRNGT.
(!used_daemon && !sysrand(true, kSeedLength + (kIsFIPS ? 16 : 0))) ||
// Personalisation draw if the daemon was used.
(used_daemon && !sysrand(false, CTR_DRBG_ENTROPY_LEN)) ||
@@ -794,7 +798,7 @@ TEST(URandomTest, Test) {
}
if (!has_getrandom && !(flags & NO_GETRANDOM)) {
continue;
continue;
}
TRACE_FLAG(NO_GETRANDOM);
@@ -819,6 +823,8 @@ TEST(URandomTest, Test) {
}
}
} // namespace
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
+43 -40
View File
@@ -79,11 +79,12 @@
#endif
namespace {
// kPlaintext is a sample plaintext.
static const uint8_t kPlaintext[] = {0x54, 0x85, 0x9b, 0x34,
0x2c, 0x49, 0xea, 0x2a};
// kKey1 is a DER-encoded 1024-bit RSAPrivateKey with e = 65537.
static const uint8_t kKey1[] = {
0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xa1,
@@ -690,8 +691,8 @@ TEST(RSATest, ASN1) {
ERR_clear_error();
// Public keys with negative moduli are invalid.
rsa.reset(RSA_public_key_from_bytes(kEstonianRSAKey,
sizeof(kEstonianRSAKey)));
rsa.reset(
RSA_public_key_from_bytes(kEstonianRSAKey, sizeof(kEstonianRSAKey)));
EXPECT_FALSE(rsa);
ERR_clear_error();
}
@@ -744,8 +745,7 @@ TEST(RSATest, RoundKeyLengths) {
}
TEST(RSATest, BlindingDisabled) {
bssl::UniquePtr<RSA> rsa(
RSA_private_key_from_bytes(kKey2, sizeof(kKey2)));
bssl::UniquePtr<RSA> rsa(RSA_private_key_from_bytes(kKey2, sizeof(kKey2)));
ASSERT_TRUE(rsa);
rsa->flags |= RSA_FLAG_NO_BLINDING;
@@ -956,9 +956,9 @@ TEST(RSATest, KeygenFail) {
// Cause RSA key generation after a prime has been generated, to test that
// |rsa| is left alone.
BN_GENCB cb;
BN_GENCB_set(&cb,
[](int event, int, BN_GENCB *) -> int { return event != 3; },
nullptr);
BN_GENCB_set(
&cb, [](int event, int, BN_GENCB *) -> int { return event != 3; },
nullptr);
bssl::UniquePtr<BIGNUM> e(BN_new());
ASSERT_TRUE(e);
@@ -1017,17 +1017,18 @@ TEST(RSATest, KeygenFailOnce) {
// Cause only the first iteration of RSA key generation to fail.
bool failed = false;
BN_GENCB cb;
BN_GENCB_set(&cb,
[](int event, int n, BN_GENCB *cb_ptr) -> int {
bool *failed_ptr = static_cast<bool *>(cb_ptr->arg);
if (*failed_ptr) {
ADD_FAILURE() << "Callback called multiple times.";
return 1;
}
*failed_ptr = true;
return 0;
},
&failed);
BN_GENCB_set(
&cb,
[](int event, int n, BN_GENCB *cb_ptr) -> int {
bool *failed_ptr = static_cast<bool *>(cb_ptr->arg);
if (*failed_ptr) {
ADD_FAILURE() << "Callback called multiple times.";
return 1;
}
*failed_ptr = true;
return 0;
},
&failed);
// Although key generation internally retries, the external behavior of
// |BN_GENCB| is preserved.
@@ -1044,20 +1045,21 @@ TEST(RSATest, KeygenInternalRetry) {
// Simulate one internal attempt at key generation failing.
bool failed = false;
BN_GENCB cb;
BN_GENCB_set(&cb,
[](int event, int n, BN_GENCB *cb_ptr) -> int {
bool *failed_ptr = static_cast<bool *>(cb_ptr->arg);
if (*failed_ptr) {
return 1;
}
*failed_ptr = true;
// This test does not test any public API behavior. It is just
// a hack to exercise the retry codepath and make sure it
// works.
OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_MANY_ITERATIONS);
return 0;
},
&failed);
BN_GENCB_set(
&cb,
[](int event, int n, BN_GENCB *cb_ptr) -> int {
bool *failed_ptr = static_cast<bool *>(cb_ptr->arg);
if (*failed_ptr) {
return 1;
}
*failed_ptr = true;
// This test does not test any public API behavior. It is just
// a hack to exercise the retry codepath and make sure it
// works.
OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_MANY_ITERATIONS);
return 0;
},
&failed);
// Key generation internally retries on RSA_R_TOO_MANY_ITERATIONS.
bssl::UniquePtr<BIGNUM> e(BN_new());
@@ -1083,8 +1085,8 @@ TEST(RSATest, OverwriteKey) {
ciphertext.resize(len);
std::vector<uint8_t> plaintext(RSA_size(key1.get()));
ASSERT_TRUE(RSA_decrypt(key1.get(), &len, plaintext.data(),
plaintext.size(), ciphertext.data(), ciphertext.size(),
ASSERT_TRUE(RSA_decrypt(key1.get(), &len, plaintext.data(), plaintext.size(),
ciphertext.data(), ciphertext.size(),
RSA_PKCS1_OAEP_PADDING));
plaintext.resize(len);
EXPECT_EQ(Bytes(plaintext), Bytes(kPlaintext));
@@ -1125,9 +1127,9 @@ TEST(RSATest, OverwriteKey) {
ciphertext.resize(len);
plaintext.resize(RSA_size(dec));
ASSERT_TRUE(RSA_decrypt(dec, &len, plaintext.data(),
plaintext.size(), ciphertext.data(),
ciphertext.size(), RSA_PKCS1_OAEP_PADDING));
ASSERT_TRUE(RSA_decrypt(dec, &len, plaintext.data(), plaintext.size(),
ciphertext.data(), ciphertext.size(),
RSA_PKCS1_OAEP_PADDING));
plaintext.resize(len);
EXPECT_EQ(Bytes(plaintext), Bytes(kPlaintext));
};
@@ -1206,8 +1208,7 @@ TEST(RSATest, Negative) {
return ret;
};
bssl::UniquePtr<RSA> key(
RSA_private_key_from_bytes(kKey1, sizeof(kKey1)));
bssl::UniquePtr<RSA> key(RSA_private_key_from_bytes(kKey1, sizeof(kKey1)));
ASSERT_TRUE(key);
const BIGNUM *n = RSA_get0_n(key.get());
bssl::UniquePtr<BIGNUM> neg_n = dup_neg(n);
@@ -1551,3 +1552,5 @@ TEST(RSATest, DISABLED_BlindingCacheConcurrency) {
#endif // TSAN || (X86_64 && !FREEBSD)
#endif // THREADS
} // namespace
+4
View File
@@ -48,6 +48,8 @@ static bssl::UniquePtr<TEST_INT> TEST_INT_new(int x) {
DEFINE_STACK_OF(TEST_INT)
namespace {
struct ShallowStackDeleter {
void operator()(STACK_OF(TEST_INT) *sk) const { sk_TEST_INT_free(sk); }
};
@@ -529,3 +531,5 @@ TEST(StackTest, NullIsEmpty) {
size_t index;
EXPECT_FALSE(sk_TEST_INT_find(nullptr, &index, value.get()));
}
} // namespace
+157 -178
View File
@@ -34,17 +34,19 @@
#include <openssl/pool.h>
#include <openssl/x509.h>
#include "internal.h"
#include "../internal.h"
#include "../test/file_util.h"
#include "../test/test_data.h"
#include "../test/test_util.h"
#include "internal.h"
#if defined(OPENSSL_THREADS)
#include <thread>
#endif
namespace {
static const char kCrossSigningRootPEM[] = R"(
-----BEGIN CERTIFICATE-----
MIICcTCCAdqgAwIBAgIIagJHiPvE0MowDQYJKoZIhvcNAQELBQAwPDEaMBgGA1UE
@@ -586,6 +588,8 @@ d5YVX0c90VMnUhF/dlrqS9U=
// |includeNetscapeExtension| and defining rootKeyPEM and rootCertPEM to be
// strings containing the kSANTypesRoot, above.
// clang-format off
// package main
// import (
@@ -659,6 +663,8 @@ d5YVX0c90VMnUhF/dlrqS9U=
// pem.Encode(os.Stdout, &pem.Block{Type: "CERTIFICATE", Bytes: leafDER})
// }
// clang-format on
// kNoBasicConstraintsCertSignIntermediate doesn't have isCA set, but contains
// certSign in the keyUsage.
static const char kNoBasicConstraintsCertSignIntermediate[] = R"(
@@ -931,14 +937,14 @@ static const char kCommonNameNotDNS[] = "Not a DNS name";
// Subject: pkix.Name{
// CommonName: "EKU msSGC",
// },
// NotBefore: time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC),
// NotAfter: time.Date(2099, time.January, 1, 0, 0, 0, 0, time.UTC),
// BasicConstraintsValid: true,
// ExtKeyUsage: []x509.ExtKeyUsage{FILL IN HERE},
// NotBefore: time.Date(2000, time.January, 1, 0, 0, 0, 0,
// time.UTC), NotAfter: time.Date(2099, time.January, 1, 0,
// 0, 0, 0, time.UTC), BasicConstraintsValid: true, ExtKeyUsage:
// []x509.ExtKeyUsage{FILL IN HERE},
// }
// leafKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
// leafDER, err := x509.CreateCertificate(rand.Reader, leafTemplate, root, &leafKey.PublicKey, rootPriv)
// if err != nil {
// leafDER, err := x509.CreateCertificate(rand.Reader, leafTemplate, root,
// &leafKey.PublicKey, rootPriv) if err != nil {
// panic(err)
// }
// pem.Encode(os.Stdout, &pem.Block{Type: "CERTIFICATE", Bytes: leafDER})
@@ -1112,15 +1118,15 @@ static int Verify(
CertsToStack(intermediates));
bssl::UniquePtr<STACK_OF(X509_CRL)> crls_stack(CRLsToStack(crls));
if (!roots_stack ||
!intermediates_stack ||
if (!roots_stack || //
!intermediates_stack || //
!crls_stack) {
return X509_V_ERR_UNSPECIFIED;
}
bssl::UniquePtr<X509_STORE_CTX> ctx(X509_STORE_CTX_new());
bssl::UniquePtr<X509_STORE> store(X509_STORE_new());
if (!ctx ||
if (!ctx || //
!store) {
return X509_V_ERR_UNSPECIFIED;
}
@@ -1376,12 +1382,10 @@ TEST(X509Test, StoreThreads) {
ASSERT_TRUE(X509_verify_cert(ctx.get()));
ASSERT_EQ(X509_STORE_CTX_get_error(ctx.get()), X509_V_OK);
});
threads.emplace_back([&] {
ASSERT_TRUE(X509_STORE_add_cert(store.get(), other1.get()));
});
threads.emplace_back([&] {
ASSERT_TRUE(X509_STORE_add_cert(store.get(), other2.get()));
});
threads.emplace_back(
[&] { ASSERT_TRUE(X509_STORE_add_cert(store.get(), other1.get())); });
threads.emplace_back(
[&] { ASSERT_TRUE(X509_STORE_add_cert(store.get(), other2.get())); });
threads.emplace_back([&] {
bssl::UniquePtr<STACK_OF(X509_OBJECT)> objs(
X509_STORE_get1_objects(store.get()));
@@ -1844,7 +1848,7 @@ static bool AddRevokedSerialU64(X509_CRL *crl, uint64_t serial,
}
static bool AddAuthorityKeyIdentifier(X509_CRL *crl,
bssl::Span<const uint8_t> key_id) {
bssl::Span<const uint8_t> key_id) {
bssl::UniquePtr<AUTHORITY_KEYID> akid(AUTHORITY_KEYID_new());
if (akid == nullptr) {
return false;
@@ -2725,31 +2729,31 @@ TEST(X509Test, TestPrintUTCTIME) {
static const struct {
const char *val, *want;
} asn1_utctime_tests[] = {
{"", "Bad time value"},
{"", "Bad time value"},
// Correct RFC 5280 form. Test years < 2000 and > 2000.
{"090303125425Z", "Mar 3 12:54:25 2009 GMT"},
{"900303125425Z", "Mar 3 12:54:25 1990 GMT"},
{"000303125425Z", "Mar 3 12:54:25 2000 GMT"},
// Correct RFC 5280 form. Test years < 2000 and > 2000.
{"090303125425Z", "Mar 3 12:54:25 2009 GMT"},
{"900303125425Z", "Mar 3 12:54:25 1990 GMT"},
{"000303125425Z", "Mar 3 12:54:25 2000 GMT"},
// Correct form, bad values.
{"000000000000Z", "Bad time value"},
{"999999999999Z", "Bad time value"},
// Correct form, bad values.
{"000000000000Z", "Bad time value"},
{"999999999999Z", "Bad time value"},
// Missing components.
{"090303125425", "Bad time value"},
{"9003031254", "Bad time value"},
{"9003031254Z", "Bad time value"},
// Missing components.
{"090303125425", "Bad time value"},
{"9003031254", "Bad time value"},
{"9003031254Z", "Bad time value"},
// GENERALIZEDTIME confused for UTCTIME.
{"20090303125425Z", "Bad time value"},
// GENERALIZEDTIME confused for UTCTIME.
{"20090303125425Z", "Bad time value"},
// Legal ASN.1, but not legal RFC 5280.
{"9003031254+0800", "Bad time value"},
{"9003031254-0800", "Bad time value"},
// Legal ASN.1, but not legal RFC 5280.
{"9003031254+0800", "Bad time value"},
{"9003031254-0800", "Bad time value"},
// Trailing garbage.
{"9003031254Z ", "Bad time value"},
// Trailing garbage.
{"9003031254Z ", "Bad time value"},
};
for (auto t : asn1_utctime_tests) {
@@ -2823,7 +2827,7 @@ TEST(X509Test, X509AlgorSetMd) {
X509_ALGOR_get0(&obj, &ptype, &pval, alg.get());
EXPECT_TRUE(obj);
EXPECT_EQ(OBJ_obj2nid(obj), NID_sha256);
EXPECT_EQ(ptype, V_ASN1_NULL); // OpenSSL has V_ASN1_UNDEF
EXPECT_EQ(ptype, V_ASN1_NULL); // OpenSSL has V_ASN1_UNDEF
EXPECT_EQ(pval, nullptr);
EXPECT_TRUE(X509_ALGOR_set_md(alg.get(), EVP_md5()));
X509_ALGOR_get0(&obj, &ptype, &pval, alg.get());
@@ -2998,8 +3002,7 @@ TEST(X509Test, PEMX509Info) {
// creates a new X509_INFO when a repeated type is seen.
std::string pem =
// The first few entries have one of everything in different orders.
cert + rsa + crl +
rsa + crl + cert +
cert + rsa + crl + rsa + crl + cert +
// Unknown types are ignored.
crl + unknown + cert + rsa +
// Seeing a new certificate starts a new entry, so now we have a bunch of
@@ -3017,19 +3020,19 @@ TEST(X509Test, PEMX509Info) {
const EVP_PKEY *key;
const X509_CRL *crl;
} kExpected[] = {
{cert_obj.get(), rsa_obj.get(), crl_obj.get()},
{cert_obj.get(), rsa_obj.get(), crl_obj.get()},
{cert_obj.get(), rsa_obj.get(), crl_obj.get()},
{cert_obj.get(), nullptr, nullptr},
{cert_obj.get(), nullptr, nullptr},
{cert_obj.get(), nullptr, nullptr},
{cert_obj.get(), rsa_obj.get(), nullptr},
{nullptr, rsa_obj.get(), nullptr},
{nullptr, rsa_obj.get(), nullptr},
{nullptr, rsa_obj.get(), nullptr},
{nullptr, rsa_obj.get(), crl_obj.get()},
{nullptr, nullptr, crl_obj.get()},
{nullptr, nullptr, crl_obj.get()},
{cert_obj.get(), rsa_obj.get(), crl_obj.get()},
{cert_obj.get(), rsa_obj.get(), crl_obj.get()},
{cert_obj.get(), rsa_obj.get(), crl_obj.get()},
{cert_obj.get(), nullptr, nullptr},
{cert_obj.get(), nullptr, nullptr},
{cert_obj.get(), nullptr, nullptr},
{cert_obj.get(), rsa_obj.get(), nullptr},
{nullptr, rsa_obj.get(), nullptr},
{nullptr, rsa_obj.get(), nullptr},
{nullptr, rsa_obj.get(), nullptr},
{nullptr, rsa_obj.get(), crl_obj.get()},
{nullptr, nullptr, crl_obj.get()},
{nullptr, nullptr, crl_obj.get()},
};
auto check_info = [](const ExpectedInfo *expected, const X509_INFO *info) {
@@ -3241,38 +3244,34 @@ TEST(X509Test, CommonNameFallback) {
}
TEST(X509Test, LooksLikeDNSName) {
static const char *kValid[] = {
"example.com",
"eXample123-.com",
"*.example.com",
"exa_mple.com",
"example.com.",
"project-dev:us-central1:main",
};
static const char *kInvalid[] = {
"-eXample123-.com",
"",
".",
"*",
"*.",
"example..com",
".example.com",
"example.com..",
"*foo.example.com",
"foo.*.example.com",
"foo,bar",
};
static const char *kValid[] = {
"example.com", "eXample123-.com", "*.example.com",
"exa_mple.com", "example.com.", "project-dev:us-central1:main",
};
static const char *kInvalid[] = {
"-eXample123-.com",
"",
".",
"*",
"*.",
"example..com",
".example.com",
"example.com..",
"*foo.example.com",
"foo.*.example.com",
"foo,bar",
};
for (const char *str : kValid) {
SCOPED_TRACE(str);
EXPECT_TRUE(x509v3_looks_like_dns_name(
reinterpret_cast<const uint8_t *>(str), strlen(str)));
}
for (const char *str : kInvalid) {
SCOPED_TRACE(str);
EXPECT_FALSE(x509v3_looks_like_dns_name(
reinterpret_cast<const uint8_t *>(str), strlen(str)));
}
for (const char *str : kValid) {
SCOPED_TRACE(str);
EXPECT_TRUE(x509v3_looks_like_dns_name(
reinterpret_cast<const uint8_t *>(str), strlen(str)));
}
for (const char *str : kInvalid) {
SCOPED_TRACE(str);
EXPECT_FALSE(x509v3_looks_like_dns_name(
reinterpret_cast<const uint8_t *>(str), strlen(str)));
}
}
TEST(X509Test, CommonNameAndNameConstraints) {
@@ -3369,8 +3368,8 @@ TEST(X509Test, ServerGatedCryptoEKUs) {
// The server-auth EKU is sufficient, and it doesn't matter if an SGC EKU is
// also included. Lastly, not specifying an EKU is also valid.
for (X509 *leaf : {server_eku.get(), server_eku_plus_ms_sgc.get(),
no_eku.get()}) {
for (X509 *leaf :
{server_eku.get(), server_eku_plus_ms_sgc.get(), no_eku.get()}) {
EXPECT_EQ(X509_V_OK, verify_cert(leaf));
}
}
@@ -3427,9 +3426,9 @@ TEST(X509Test, InvalidExtensions) {
ASSERT_TRUE(invalid_leaf);
bssl::UniquePtr<X509> trailing_leaf = CertFromPEM(
GetTestData((std::string("crypto/x509/test/trailing_data_leaf_") +
ext + ".pem")
.c_str())
GetTestData(
(std::string("crypto/x509/test/trailing_data_leaf_") + ext + ".pem")
.c_str())
.c_str());
ASSERT_TRUE(trailing_leaf);
@@ -3850,7 +3849,7 @@ TEST(X509Test, AlgorithmParameters) {
ErrorEquals(ERR_get_error(), ERR_LIB_X509, X509_R_INVALID_PARAMETER));
}
TEST(X509Test, GeneralName) {
TEST(X509Test, GeneralName) {
const std::vector<uint8_t> kNames[] = {
// [0] {
// OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
@@ -5366,7 +5365,7 @@ TEST(X509Test, NamePrint) {
"/CN= spaces ",
};
std::string oneline_expected;
for (const auto& component : kOnelineComponents) {
for (const auto &component : kOnelineComponents) {
oneline_expected += component;
}
@@ -5397,7 +5396,7 @@ TEST(X509Test, NamePrint) {
EXPECT_EQ(buf, X509_NAME_oneline(name.get(), buf, len));
std::string truncated;
for (const auto& component : kOnelineComponents) {
for (const auto &component : kOnelineComponents) {
if (truncated.size() + strlen(component) + 1 > len) {
break;
}
@@ -5441,7 +5440,7 @@ TEST(X509Test, Print) {
const uint8_t *data;
size_t data_len;
ASSERT_TRUE(BIO_mem_contents(bio.get(), &data, &data_len));
std::string print(reinterpret_cast<const char*>(data), data_len);
std::string print(reinterpret_cast<const char *>(data), data_len);
EXPECT_EQ(print, R"(Certificate:
Data:
Version: 3 (0x2)
@@ -5830,8 +5829,7 @@ TEST(X509Test, Policy) {
GetTestData("crypto/x509/test/policy_intermediate_invalid.pem").c_str()));
ASSERT_TRUE(intermediate_invalid);
bssl::UniquePtr<X509> intermediate_mapped(CertFromPEM(
GetTestData("crypto/x509/test/policy_intermediate_mapped.pem")
.c_str()));
GetTestData("crypto/x509/test/policy_intermediate_mapped.pem").c_str()));
ASSERT_TRUE(intermediate_mapped);
bssl::UniquePtr<X509> intermediate_mapped_any(CertFromPEM(
GetTestData("crypto/x509/test/policy_intermediate_mapped_any.pem")
@@ -5940,37 +5938,33 @@ TEST(X509Test, Policy) {
}));
// The policy extension cannot be parsed.
EXPECT_EQ(X509_V_ERR_INVALID_POLICY_EXTENSION,
Verify(leaf.get(), {root.get()}, {intermediate_invalid.get()},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) {
set_policies(ctx, {oid1.get()});
}));
EXPECT_EQ(X509_V_ERR_INVALID_POLICY_EXTENSION,
Verify(leaf_invalid.get(), {root.get()}, {intermediate.get()},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) {
set_policies(ctx, {oid1.get()});
}));
EXPECT_EQ(
X509_V_ERR_INVALID_POLICY_EXTENSION,
Verify(leaf.get(), {root.get()}, {intermediate_invalid.get()},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) { set_policies(ctx, {oid1.get()}); }));
EXPECT_EQ(
X509_V_ERR_INVALID_POLICY_EXTENSION,
Verify(leaf_invalid.get(), {root.get()}, {intermediate.get()},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) { set_policies(ctx, {oid1.get()}); }));
EXPECT_EQ(X509_V_ERR_INVALID_POLICY_EXTENSION,
Verify(leaf_invalid.get(), {root.get()}, {intermediate.get()},
/*crls=*/{}));
// There is a duplicate policy in the policy extension.
EXPECT_EQ(X509_V_ERR_INVALID_POLICY_EXTENSION,
Verify(leaf.get(), {root.get()}, {intermediate_duplicate.get()},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) {
set_policies(ctx, {oid1.get()});
}));
EXPECT_EQ(
X509_V_ERR_INVALID_POLICY_EXTENSION,
Verify(leaf.get(), {root.get()}, {intermediate_duplicate.get()},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) { set_policies(ctx, {oid1.get()}); }));
// The policy extension in the leaf cannot be parsed.
EXPECT_EQ(X509_V_ERR_INVALID_POLICY_EXTENSION,
Verify(leaf_duplicate.get(), {root.get()}, {intermediate.get()},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) {
set_policies(ctx, {oid1.get()});
}));
EXPECT_EQ(
X509_V_ERR_INVALID_POLICY_EXTENSION,
Verify(leaf_duplicate.get(), {root.get()}, {intermediate.get()},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) { set_policies(ctx, {oid1.get()}); }));
// Without |X509_V_FLAG_EXPLICIT_POLICY|, the policy tree is built and
// intersected with user-specified policies, but it is not required to result
@@ -6049,16 +6043,14 @@ TEST(X509Test, Policy) {
X509_V_ERR_NO_EXPLICIT_POLICY,
Verify(leaf_require1.get(), {root.get()}, {intermediate_require1.get()},
/*crls=*/{},
/*flags=*/0, [&](X509_STORE_CTX *ctx) {
set_policies(ctx, {oid3.get()});
}));
/*flags=*/0,
[&](X509_STORE_CTX *ctx) { set_policies(ctx, {oid3.get()}); }));
EXPECT_EQ(
X509_V_ERR_NO_EXPLICIT_POLICY,
Verify(leaf_require.get(), {root.get()}, {intermediate_require2.get()},
/*crls=*/{},
/*flags=*/0, [&](X509_STORE_CTX *ctx) {
set_policies(ctx, {oid3.get()});
}));
/*flags=*/0,
[&](X509_STORE_CTX *ctx) { set_policies(ctx, {oid3.get()}); }));
// An intermediate that requires an explicit policy, but then specifies no
// policies should fail verification as a result.
@@ -6083,44 +6075,38 @@ TEST(X509Test, Policy) {
EXPECT_EQ(
X509_V_OK,
Verify(leaf_any.get(), {root.get()}, {intermediate.get()}, /*crls=*/{},
X509_V_FLAG_EXPLICIT_POLICY, [&](X509_STORE_CTX *ctx) {
set_policies(ctx, {oid1.get()});
}));
X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) { set_policies(ctx, {oid1.get()}); }));
EXPECT_EQ(
X509_V_ERR_NO_EXPLICIT_POLICY,
Verify(leaf_any.get(), {root.get()}, {intermediate.get()}, /*crls=*/{},
X509_V_FLAG_EXPLICIT_POLICY, [&](X509_STORE_CTX *ctx) {
set_policies(ctx, {oid3.get()});
}));
X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) { set_policies(ctx, {oid3.get()}); }));
// The intermediate asserts anyPolicy, but the leaf does not. The resulting
// valid policies are the intersection.
EXPECT_EQ(
X509_V_OK,
Verify(leaf.get(), {root.get()}, {intermediate_any.get()}, /*crls=*/{},
X509_V_FLAG_EXPLICIT_POLICY, [&](X509_STORE_CTX *ctx) {
set_policies(ctx, {oid1.get()});
}));
X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) { set_policies(ctx, {oid1.get()}); }));
EXPECT_EQ(
X509_V_ERR_NO_EXPLICIT_POLICY,
Verify(leaf.get(), {root.get()}, {intermediate_any.get()}, /*crls=*/{},
X509_V_FLAG_EXPLICIT_POLICY, [&](X509_STORE_CTX *ctx) {
set_policies(ctx, {oid3.get()});
}));
X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) { set_policies(ctx, {oid3.get()}); }));
// Both assert anyPolicy. All policies are valid.
EXPECT_EQ(X509_V_OK,
Verify(leaf_any.get(), {root.get()}, {intermediate_any.get()},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) {
set_policies(ctx, {oid1.get()});
}));
EXPECT_EQ(X509_V_OK,
Verify(leaf_any.get(), {root.get()}, {intermediate_any.get()},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) {
set_policies(ctx, {oid3.get()});
}));
EXPECT_EQ(
X509_V_OK,
Verify(leaf_any.get(), {root.get()}, {intermediate_any.get()},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) { set_policies(ctx, {oid1.get()}); }));
EXPECT_EQ(
X509_V_OK,
Verify(leaf_any.get(), {root.get()}, {intermediate_any.get()},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) { set_policies(ctx, {oid3.get()}); }));
// With just a trust anchor, policy checking silently succeeds.
EXPECT_EQ(X509_V_OK, Verify(root.get(), {root.get()}, {},
@@ -6159,12 +6145,11 @@ TEST(X509Test, Policy) {
// If the intermediate's policies listed OIDs explicitly, OID3 at the leaf
// is not acceptable as OID3 at the root. OID3 has expected_polciy_set =
// {OID1, OID2} and no other node allows OID3.
EXPECT_EQ(use_any ? X509_V_OK : X509_V_ERR_NO_EXPLICIT_POLICY,
Verify(leaf_oid3.get(), {root.get()}, {cert},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) {
set_policies(ctx, {oid3.get()});
}));
EXPECT_EQ(
use_any ? X509_V_OK : X509_V_ERR_NO_EXPLICIT_POLICY,
Verify(leaf_oid3.get(), {root.get()}, {cert},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) { set_policies(ctx, {oid3.get()}); }));
// If the intermediate's policies were anyPolicy, OID1 at the leaf is no
// longer acceptable as OID1 at the root because policies only match
@@ -6173,12 +6158,11 @@ TEST(X509Test, Policy) {
// If the intermediate's policies listed OIDs explicitly, OID1 at the leaf
// is acceptable as OID1 at the root because it will match both OID1 and
// OID3 (mapped) policies.
EXPECT_EQ(use_any ? X509_V_ERR_NO_EXPLICIT_POLICY : X509_V_OK,
Verify(leaf_oid1.get(), {root.get()}, {cert},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) {
set_policies(ctx, {oid1.get()});
}));
EXPECT_EQ(
use_any ? X509_V_ERR_NO_EXPLICIT_POLICY : X509_V_OK,
Verify(leaf_oid1.get(), {root.get()}, {cert},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) { set_policies(ctx, {oid1.get()}); }));
// All pairs of OID4 and OID5 are mapped together, so either can stand for
// the other.
@@ -6212,19 +6196,16 @@ TEST(X509Test, Policy) {
// Although |intermediate_mapped_oid3| contains many mappings, it only accepts
// OID3. Nodes should not be created for the other mappings.
EXPECT_EQ(X509_V_OK, Verify(leaf_oid1.get(), {root.get()},
{intermediate_mapped_oid3.get()},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) {
set_policies(ctx, {oid3.get()});
}));
EXPECT_EQ(
X509_V_OK,
Verify(leaf_oid1.get(), {root.get()}, {intermediate_mapped_oid3.get()},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) { set_policies(ctx, {oid3.get()}); }));
EXPECT_EQ(
X509_V_ERR_NO_EXPLICIT_POLICY,
Verify(leaf_oid4.get(), {root.get()}, {intermediate_mapped_oid3.get()},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) {
set_policies(ctx, {oid4.get()});
}));
[&](X509_STORE_CTX *ctx) { set_policies(ctx, {oid4.get()}); }));
// Policy mapping can be inhibited, either by the caller or a certificate in
// the chain, in which case mapped policies are unassertable (apart from some
@@ -6233,17 +6214,13 @@ TEST(X509Test, Policy) {
X509_V_ERR_NO_EXPLICIT_POLICY,
Verify(leaf_oid1.get(), {root.get()}, {intermediate_mapped_oid3.get()},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY | X509_V_FLAG_INHIBIT_MAP,
[&](X509_STORE_CTX *ctx) {
set_policies(ctx, {oid3.get()});
}));
[&](X509_STORE_CTX *ctx) { set_policies(ctx, {oid3.get()}); }));
EXPECT_EQ(
X509_V_ERR_NO_EXPLICIT_POLICY,
Verify(leaf_oid1.get(), {root2.get()},
{intermediate_mapped_oid3.get(), root_cross_inhibit_mapping.get()},
/*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
[&](X509_STORE_CTX *ctx) {
set_policies(ctx, {oid3.get()});
}));
[&](X509_STORE_CTX *ctx) { set_policies(ctx, {oid3.get()}); }));
}
#if defined(OPENSSL_THREADS)
@@ -7410,7 +7387,7 @@ TEST(X509Test, ParamInheritance) {
EXPECT_EQ(X509_VERIFY_PARAM_get_depth(dest.get()), 5);
}
// |X509_VERIFY_PARAM_set1| with both unset.
// |X509_VERIFY_PARAM_set1| with both unset.
{
bssl::UniquePtr<X509_VERIFY_PARAM> dest(X509_VERIFY_PARAM_new());
ASSERT_TRUE(dest);
@@ -8360,8 +8337,8 @@ TEST(X509Test, DirHashThreads) {
return cert;
};
auto add_crl = [&](const std::string &name,
int this_update_offset_day, NameHash name_hash) -> bool {
auto add_crl = [&](const std::string &name, int this_update_offset_day,
NameHash name_hash) -> bool {
bssl::UniquePtr<X509_CRL> crl = MakeTestCRL(
name.c_str(), this_update_offset_day, /*next_update_offset_day=*/1);
return crl != nullptr &&
@@ -8656,3 +8633,5 @@ TEST(X509Test, ParseIPAddress) {
}
}
}
} // namespace
+5
View File
@@ -17,6 +17,9 @@
#include <gtest/gtest.h>
#include <openssl/asn1.h>
namespace {
struct TestData {
const char *data;
int type;
@@ -313,3 +316,5 @@ TEST(X509TimeTest, TestCmpTimeCurrent) {
ASSERT_EQ(-1, X509_cmp_time(asn1_before.get(), NULL));
ASSERT_EQ(1, X509_cmp_time(asn1_after.get(), NULL));
}
} // namespace
-24
View File
@@ -121,18 +121,6 @@ OPENSSL_EXPORT int MLKEM768_marshal_public_key(
OPENSSL_EXPORT int MLKEM768_parse_public_key(
struct MLKEM768_public_key *out_public_key, CBS *in);
// MLKEM768_PRIVATE_KEY_BYTES is the length of the data produced by
// |MLKEM768_marshal_private_key|.
#define MLKEM768_PRIVATE_KEY_BYTES 2400
// MLKEM768_parse_private_key parses a private key, in NIST's format for
// private keys, from |in| and writes the result to |out_private_key|. It
// returns one on success or zero on parse error or if there are trailing bytes
// in |in|. This format is verbose and should be avoided. Private keys should be
// stored as seeds and parsed using |MLKEM768_private_key_from_seed|.
OPENSSL_EXPORT int MLKEM768_parse_private_key(
struct MLKEM768_private_key *out_private_key, CBS *in);
// ML-KEM-1024
//
@@ -226,18 +214,6 @@ OPENSSL_EXPORT int MLKEM1024_marshal_public_key(
OPENSSL_EXPORT int MLKEM1024_parse_public_key(
struct MLKEM1024_public_key *out_public_key, CBS *in);
// MLKEM1024_PRIVATE_KEY_BYTES is the length of the data produced by
// |MLKEM1024_marshal_private_key|.
#define MLKEM1024_PRIVATE_KEY_BYTES 3168
// MLKEM1024_parse_private_key parses a private key, in NIST's format for
// private keys, from |in| and writes the result to |out_private_key|. It
// returns one on success or zero on parse error or if there are trailing bytes
// in |in|. This format is verbose and should be avoided. Private keys should be
// stored as seeds and parsed using |MLKEM1024_private_key_from_seed|.
OPENSSL_EXPORT int MLKEM1024_parse_private_key(
struct MLKEM1024_private_key *out_private_key, CBS *in);
#if defined(__cplusplus)
} // extern C
+3
View File
@@ -133,6 +133,9 @@ The other commands are as follows. (Note that you only need to implement the com
| ML-DSA-XX/keyGen | Seed | Public key, private key |
| ML-DSA-XX/sigGen | Private key, message, randomizer | Signature |
| ML-DSA-XX/sigVer | Public key, message, signature | Single-byte validity flag |
| ML-KEM-XX/keyGen | Seed | Public key, private key |
| ML-KEM-XX/encap | Public key, entropy | Ciphertext, shared secret |
| ML-KEM-XX/decap | Private key, ciphertext | Shared secret |
¹ The iterated tests would result in excessive numbers of round trips if the module wrapper handled only basic operations. Thus some ACVP logic is pushed down for these tests so that the inner loop can be handled locally. Either read the NIST documentation ([block-ciphers](https://pages.nist.gov/ACVP/draft-celi-acvp-symmetric.html#name-monte-carlo-tests-for-block) [hashes](https://pages.nist.gov/ACVP/draft-celi-acvp-sha.html#name-monte-carlo-tests-for-sha-1)) to understand the iteration count and return values or, probably more fruitfully, see how these functions are handled in the `modulewrapper` directory.
@@ -0,0 +1,236 @@
package subprocess
import (
"encoding/hex"
"encoding/json"
"fmt"
"strings"
)
// Common top-level structure to parse mode
type mlkemTestVectorSet struct {
Algorithm string `json:"algorithm"`
Mode string `json:"mode"`
Revision string `json:"revision"`
}
// Key generation specific structures
type mlkemKeyGenTestVectorSet struct {
Algorithm string `json:"algorithm"`
Mode string `json:"mode"`
Revision string `json:"revision"`
Groups []mlkemKeyGenTestGroup `json:"testGroups"`
}
type mlkemKeyGenTestGroup struct {
ID uint64 `json:"tgId"`
TestType string `json:"testType"`
ParameterSet string `json:"parameterSet"`
Tests []mlkemKeyGenTest `json:"tests"`
}
type mlkemKeyGenTest struct {
ID uint64 `json:"tcId"`
Z string `json:"z"`
D string `json:"d"`
}
type mlkemKeyGenTestGroupResponse struct {
ID uint64 `json:"tgId"`
Tests []mlkemKeyGenTestResponse `json:"tests"`
}
type mlkemKeyGenTestResponse struct {
ID uint64 `json:"tcId"`
EK string `json:"ek"`
DK string `json:"dk"`
}
type mlkemEncapDecapTestVectorSet struct {
Algorithm string `json:"algorithm"`
Mode string `json:"mode"`
Revision string `json:"revision"`
Groups []mlkemEncapDecapTestGroup `json:"testGroups"`
}
type mlkemEncapDecapTestGroup struct {
ID uint64 `json:"tgId"`
TestType string `json:"testType"`
ParameterSet string `json:"parameterSet"`
Function string `json:"function"`
DK string `json:"dk,omitempty"`
Tests []mlkemEncapDecapTest `json:"tests"`
}
type mlkemEncapDecapTest struct {
ID uint64 `json:"tcId"`
EK string `json:"ek,omitempty"`
M string `json:"m,omitempty"`
C string `json:"c,omitempty"`
}
type mlkemEncapDecapTestGroupResponse struct {
ID uint64 `json:"tgId"`
Tests []mlkemEncapDecapTestResponse `json:"tests"`
}
type mlkemEncapDecapTestResponse struct {
ID uint64 `json:"tcId"`
C string `json:"c,omitempty"`
K string `json:"k,omitempty"`
}
type mlkem struct{}
func (m *mlkem) Process(vectorSet []byte, t Transactable) (any, error) {
var common mlkemTestVectorSet
if err := json.Unmarshal(vectorSet, &common); err != nil {
return nil, fmt.Errorf("failed to unmarshal vector set: %v", err)
}
switch common.Mode {
case "keyGen":
return m.processKeyGen(vectorSet, t)
case "encapDecap":
return m.processEncapDecap(vectorSet, t)
default:
return nil, fmt.Errorf("unsupported ML-KEM mode: %q", common.Mode)
}
}
func (m *mlkem) processKeyGen(vectorSet []byte, t Transactable) (any, error) {
var parsed mlkemKeyGenTestVectorSet
if err := json.Unmarshal(vectorSet, &parsed); err != nil {
return nil, fmt.Errorf("failed to unmarshal keyGen vector set: %v", err)
}
var ret []mlkemKeyGenTestGroupResponse
for _, group := range parsed.Groups {
response := mlkemKeyGenTestGroupResponse{
ID: group.ID,
}
if !strings.HasPrefix(group.ParameterSet, "ML-KEM-") {
return nil, fmt.Errorf("invalid parameter set: %s", group.ParameterSet)
}
cmdName := group.ParameterSet + "/keyGen"
for _, test := range group.Tests {
// Concatenate d and z to form the seed
dBytes, err := hex.DecodeString(test.D)
if err != nil {
return nil, fmt.Errorf("failed to decode d in test case %d/%d: %s",
group.ID, test.ID, err)
}
zBytes, err := hex.DecodeString(test.Z)
if err != nil {
return nil, fmt.Errorf("failed to decode z in test case %d/%d: %s",
group.ID, test.ID, err)
}
seed := make([]byte, len(dBytes)+len(zBytes))
copy(seed, dBytes)
copy(seed[len(dBytes):], zBytes)
result, err := t.Transact(cmdName, 2, seed)
if err != nil {
return nil, fmt.Errorf("key generation failed for test case %d/%d: %s",
group.ID, test.ID, err)
}
response.Tests = append(response.Tests, mlkemKeyGenTestResponse{
ID: test.ID,
EK: hex.EncodeToString(result[0]),
DK: hex.EncodeToString(result[1]),
})
}
ret = append(ret, response)
}
return ret, nil
}
func (m *mlkem) processEncapDecap(vectorSet []byte, t Transactable) (any, error) {
var parsed mlkemEncapDecapTestVectorSet
if err := json.Unmarshal(vectorSet, &parsed); err != nil {
return nil, fmt.Errorf("failed to unmarshal encapDecap vector set: %v", err)
}
var ret []mlkemEncapDecapTestGroupResponse
for _, group := range parsed.Groups {
response := mlkemEncapDecapTestGroupResponse{
ID: group.ID,
}
if !strings.HasPrefix(group.ParameterSet, "ML-KEM-") {
return nil, fmt.Errorf("invalid parameter set: %s", group.ParameterSet)
}
switch group.Function {
case "encapsulation":
cmdName := group.ParameterSet + "/encap"
for _, test := range group.Tests {
ek, err := hex.DecodeString(test.EK)
if err != nil {
return nil, fmt.Errorf("failed to decode ek in test case %d/%d: %s",
group.ID, test.ID, err)
}
m, err := hex.DecodeString(test.M)
if err != nil {
return nil, fmt.Errorf("failed to decode m in test case %d/%d: %s",
group.ID, test.ID, err)
}
result, err := t.Transact(cmdName, 2, ek, m)
if err != nil {
return nil, fmt.Errorf("encapsulation failed for test case %d/%d: %s",
group.ID, test.ID, err)
}
response.Tests = append(response.Tests, mlkemEncapDecapTestResponse{
ID: test.ID,
C: hex.EncodeToString(result[0]),
K: hex.EncodeToString(result[1]),
})
}
case "decapsulation":
cmdName := group.ParameterSet + "/decap"
dk, err := hex.DecodeString(group.DK)
if err != nil {
return nil, fmt.Errorf("failed to decode dk in group %d: %s",
group.ID, err)
}
for _, test := range group.Tests {
c, err := hex.DecodeString(test.C)
if err != nil {
return nil, fmt.Errorf("failed to decode c in test case %d/%d: %s",
group.ID, test.ID, err)
}
result, err := t.Transact(cmdName, 1, dk, c)
if err != nil {
return nil, fmt.Errorf("decapsulation failed for test case %d/%d: %s",
group.ID, test.ID, err)
}
response.Tests = append(response.Tests, mlkemEncapDecapTestResponse{
ID: test.ID,
K: hex.EncodeToString(result[0]),
})
}
default:
return nil, fmt.Errorf("unsupported function: %s", group.Function)
}
ret = append(ret, response)
}
return ret, nil
}
@@ -145,6 +145,7 @@ func NewWithIO(cmd *exec.Cmd, in io.WriteCloser, out io.ReadCloser) *Subprocess
"KAS-FFC-SSC": &kasDH{},
"PBKDF": &pbkdf{},
"ML-DSA": &mldsa{},
"ML-KEM": &mlkem{},
}
m.primitives["ECDSA"] = &ecdsa{"ECDSA", map[string]bool{"P-224": true, "P-256": true, "P-384": true, "P-521": true}, m.primitives}
m.primitives["DetECDSA"] = &ecdsa{"DetECDSA", map[string]bool{"P-224": true, "P-256": true, "P-384": true, "P-521": true}, m.primitives}
@@ -26,6 +26,7 @@
{"Wrapper": "modulewrapper", "In": "vectors/KAS-FFC-SSC.bz2"},
{"Wrapper": "testmodulewrapper", "In": "vectors/KDF.bz2"},
{"Wrapper": "modulewrapper", "In": "vectors/ML-DSA.bz2", "Out": "expected/ML-DSA.bz2"},
{"Wrapper": "modulewrapper", "In": "vectors/ML-KEM.bz2", "Out": "expected/ML-KEM.bz2"},
{"Wrapper": "modulewrapper", "In": "vectors/RSA.bz2", "Out": "expected/RSA.bz2"},
{"Wrapper": "modulewrapper", "In": "vectors/SHA-1.bz2", "Out": "expected/SHA-1.bz2"},
{"Wrapper": "modulewrapper", "In": "vectors/SHA2-224.bz2", "Out": "expected/SHA2-224.bz2"},
@@ -982,6 +982,28 @@ static bool GetConfig(const Span<const uint8_t> args[],
"ML-DSA-65",
"ML-DSA-87"
]
},
{
"algorithm": "ML-KEM",
"mode": "keyGen",
"revision": "FIPS203",
"parameterSets": [
"ML-KEM-768",
"ML-KEM-1024"
]
},
{
"algorithm": "ML-KEM",
"mode": "encapDecap",
"revision": "FIPS203",
"parameterSets": [
"ML-KEM-768",
"ML-KEM-1024"
],
"functions": [
"encapsulation",
"decapsulation"
]
}
])";
return write_reply({Span<const uint8_t>(
@@ -2259,6 +2281,85 @@ static bool MLDSASigVer(const Span<const uint8_t> args[],
return write_reply({Span<const uint8_t>(&ok, sizeof(ok))});
}
template <typename PrivateKey, size_t PublicKeyBytes,
bcm_infallible (*KeyGen)(uint8_t *, PrivateKey *, const uint8_t *),
bcm_status (*MarshalPrivate)(CBB *, const PrivateKey *)>
static bool MLKEMKeyGen(const Span<const uint8_t> args[],
ReplyCallback write_reply) {
const Span<const uint8_t> seed = args[0];
if (seed.size() != BCM_MLKEM_SEED_BYTES) {
LOG_ERROR("Bad seed size.\n");
return false;
}
auto priv = std::make_unique<PrivateKey>();
uint8_t pub_key_bytes[PublicKeyBytes];
KeyGen(pub_key_bytes, priv.get(), seed.data());
ScopedCBB cbb;
if (!CBB_init(cbb.get(), BCM_MLKEM768_PRIVATE_KEY_BYTES) ||
!bcm_success(MarshalPrivate(cbb.get(), priv.get()))) {
LOG_ERROR("Failed to serialize private key.\n");
return false;
}
return write_reply(
{pub_key_bytes, MakeConstSpan(CBB_data(cbb.get()), CBB_len(cbb.get()))});
}
template <typename PublicKey, bcm_status (*ParsePublic)(PublicKey *, CBS *),
size_t CiphertextBytes,
bcm_infallible (*Encap)(uint8_t *, uint8_t *, const PublicKey *,
const uint8_t *)>
static bool MLKEMEncap(const Span<const uint8_t> args[],
ReplyCallback write_reply) {
const Span<const uint8_t> pub_key_bytes = args[0];
const Span<const uint8_t> entropy = args[1];
if (entropy.size() != BCM_MLKEM_ENCAP_ENTROPY) {
LOG_ERROR("Bad entropy size.\n");
return false;
}
auto pub = std::make_unique<PublicKey>();
CBS cbs = bssl::MakeConstSpan(pub_key_bytes);
if (!bcm_success(ParsePublic(pub.get(), &cbs)) || CBS_len(&cbs) != 0) {
LOG_ERROR("Failed to parse public key.\n");
return false;
}
uint8_t ciphertext[CiphertextBytes];
uint8_t shared_secret[BCM_MLKEM_SHARED_SECRET_BYTES];
Encap(ciphertext, shared_secret, pub.get(), entropy.data());
return write_reply({ciphertext, shared_secret});
}
template <typename PrivateKey, bcm_status (*ParsePrivate)(PrivateKey *, CBS *),
bcm_status (*Decap)(uint8_t *, const uint8_t *, size_t,
const PrivateKey *)>
static bool MLKEMDecap(const Span<const uint8_t> args[],
ReplyCallback write_reply) {
const Span<const uint8_t> priv_key_bytes = args[0];
const Span<const uint8_t> ciphertext = args[1];
auto priv = std::make_unique<PrivateKey>();
CBS cbs = bssl::MakeConstSpan(priv_key_bytes);
if (!bcm_success(ParsePrivate(priv.get(), &cbs))) {
LOG_ERROR("Failed to parse private key.\n");
return false;
}
uint8_t shared_secret[BCM_MLKEM_SHARED_SECRET_BYTES];
if (!bcm_success(Decap(shared_secret, ciphertext.data(), ciphertext.size(),
priv.get()))) {
LOG_ERROR("ML-KEM decapsulation failed.\n");
return false;
}
return write_reply({shared_secret});
}
static constexpr struct {
char name[kMaxNameLength + 1];
uint8_t num_expected_args;
@@ -2372,6 +2473,28 @@ static constexpr struct {
{"ML-DSA-87/sigVer", 3,
MLDSASigVer<BCM_mldsa87_public_key, BCM_MLDSA87_SIGNATURE_BYTES,
BCM_mldsa87_parse_public_key, BCM_mldsa87_verify_internal>},
{"ML-KEM-768/keyGen", 1,
MLKEMKeyGen<BCM_mlkem768_private_key, BCM_MLKEM768_PUBLIC_KEY_BYTES,
BCM_mlkem768_generate_key_external_seed,
BCM_mlkem768_marshal_private_key>},
{"ML-KEM-1024/keyGen", 1,
MLKEMKeyGen<BCM_mlkem1024_private_key, BCM_MLKEM1024_PUBLIC_KEY_BYTES,
BCM_mlkem1024_generate_key_external_seed,
BCM_mlkem1024_marshal_private_key>},
{"ML-KEM-768/encap", 2,
MLKEMEncap<BCM_mlkem768_public_key, BCM_mlkem768_parse_public_key,
BCM_MLKEM768_CIPHERTEXT_BYTES,
BCM_mlkem768_encap_external_entropy>},
{"ML-KEM-1024/encap", 2,
MLKEMEncap<BCM_mlkem1024_public_key, BCM_mlkem1024_parse_public_key,
BCM_MLKEM1024_CIPHERTEXT_BYTES,
BCM_mlkem1024_encap_external_entropy>},
{"ML-KEM-768/decap", 2,
MLKEMDecap<BCM_mlkem768_private_key, BCM_mlkem768_parse_private_key,
BCM_mlkem768_decap>},
{"ML-KEM-1024/decap", 2,
MLKEMDecap<BCM_mlkem1024_private_key, BCM_mlkem1024_parse_private_key,
BCM_mlkem1024_decap>},
};
Handler FindHandler(Span<const Span<const uint8_t>> args) {