Sfoglia il codice sorgente

Add ECDSA and RSA verify Wycheproof drivers.

Along the way, add some utility functions for getting common things
(curves, hashes, etc.) in the names Wycheproof uses.

Change-Id: I09c11ea2970cf2c8a11a8c2a861d85396efda125
Reviewed-on: https://boringssl-review.googlesource.com/27786
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
kris/onging/CECPQ3_patch15
David Benjamin 6 anni fa
committed by CQ bot account: commit-bot@chromium.org
parent
commit
40d76f4f7d
15 ha cambiato i file con 16835 aggiunte e 47 eliminazioni
  1. +52
    -0
      crypto/evp/evp_test.cc
  2. +1
    -0
      crypto/test/CMakeLists.txt
  3. +47
    -40
      crypto/test/file_test.cc
  4. +5
    -0
      crypto/test/file_test.h
  5. +91
    -0
      crypto/test/wycheproof_util.cc
  6. +45
    -0
      crypto/test/wycheproof_util.h
  7. +7
    -0
      sources.cmake
  8. +7
    -7
      third_party/wycheproof/convert_wycheproof.go
  9. +2333
    -0
      third_party/wycheproof/ecdsa_secp224r1_sha224_test.txt
  10. +2324
    -0
      third_party/wycheproof/ecdsa_secp224r1_sha256_test.txt
  11. +2404
    -0
      third_party/wycheproof/ecdsa_secp256r1_sha256_test.txt
  12. +2293
    -0
      third_party/wycheproof/ecdsa_secp384r1_sha384_test.txt
  13. +2302
    -0
      third_party/wycheproof/ecdsa_secp384r1_sha512_test.txt
  14. +2318
    -0
      third_party/wycheproof/ecdsa_secp521r1_sha512_test.txt
  15. +2606
    -0
      third_party/wycheproof/rsa_signature_test.txt

+ 52
- 0
crypto/evp/evp_test.cc Vedi File

@@ -79,6 +79,7 @@ OPENSSL_MSVC_PRAGMA(warning(pop))

#include "../test/file_test.h"
#include "../test/test_util.h"
#include "../test/wycheproof_util.h"


// evp_test dispatches between multiple test types. PrivateKey tests take a key
@@ -413,3 +414,54 @@ TEST(EVPTest, TestVectors) {
}
});
}

static void RunWycheproofTest(const char *path) {
SCOPED_TRACE(path);
FileTestGTest(path, [](FileTest *t) {
t->IgnoreInstruction("key.type");
// Extra ECDSA fields.
t->IgnoreInstruction("key.curve");
t->IgnoreInstruction("key.keySize");
t->IgnoreInstruction("key.wx");
t->IgnoreInstruction("key.wy");
// Extra RSA fields.
t->IgnoreInstruction("e");
t->IgnoreInstruction("keyAsn");
t->IgnoreInstruction("keysize");
t->IgnoreInstruction("n");
t->IgnoreAttribute("padding");

std::vector<uint8_t> der;
ASSERT_TRUE(t->GetInstructionBytes(&der, "keyDer"));
CBS cbs;
CBS_init(&cbs, der.data(), der.size());
bssl::UniquePtr<EVP_PKEY> key(EVP_parse_public_key(&cbs));
ASSERT_TRUE(key);

const EVP_MD *md = GetWycheproofDigest(t, "sha", true);
ASSERT_TRUE(md);
std::vector<uint8_t> msg;
ASSERT_TRUE(t->GetBytes(&msg, "msg"));
std::vector<uint8_t> sig;
ASSERT_TRUE(t->GetBytes(&sig, "sig"));

bssl::ScopedEVP_MD_CTX ctx;
ASSERT_TRUE(
EVP_DigestVerifyInit(ctx.get(), nullptr, md, nullptr, key.get()));
WycheproofResult result;
ASSERT_TRUE(GetWycheproofResult(t, &result));
EXPECT_EQ(result == WycheproofResult::kValid ? 1 : 0,
EVP_DigestVerify(ctx.get(), sig.data(), sig.size(), msg.data(),
msg.size()));
});
}

TEST(EVPTest, Wycheproof) {
RunWycheproofTest("third_party/wycheproof/ecdsa_secp224r1_sha224_test.txt");
RunWycheproofTest("third_party/wycheproof/ecdsa_secp224r1_sha256_test.txt");
RunWycheproofTest("third_party/wycheproof/ecdsa_secp256r1_sha256_test.txt");
RunWycheproofTest("third_party/wycheproof/ecdsa_secp384r1_sha384_test.txt");
RunWycheproofTest("third_party/wycheproof/ecdsa_secp384r1_sha512_test.txt");
RunWycheproofTest("third_party/wycheproof/ecdsa_secp521r1_sha512_test.txt");
RunWycheproofTest("third_party/wycheproof/rsa_signature_test.txt");
}

+ 1
- 0
crypto/test/CMakeLists.txt Vedi File

@@ -6,6 +6,7 @@ add_library(
file_test.cc
malloc.cc
test_util.cc
wycheproof_util.cc
)

add_library(


+ 47
- 40
crypto/test/file_test.cc Vedi File

@@ -286,52 +286,19 @@ bool FileTest::GetInstruction(std::string *out_value, const std::string &key) {
return true;
}

const std::string &FileTest::CurrentTestToString() const {
return current_test_;
bool FileTest::GetInstructionBytes(std::vector<uint8_t> *out,
const std::string &key) {
std::string value;
return GetInstruction(&value, key) && ConvertToBytes(out, value);
}

static bool FromHexDigit(uint8_t *out, char c) {
if ('0' <= c && c <= '9') {
*out = c - '0';
return true;
}
if ('a' <= c && c <= 'f') {
*out = c - 'a' + 10;
return true;
}
if ('A' <= c && c <= 'F') {
*out = c - 'A' + 10;
return true;
}
return false;
const std::string &FileTest::CurrentTestToString() const {
return current_test_;
}

bool FileTest::GetBytes(std::vector<uint8_t> *out, const std::string &key) {
std::string value;
if (!GetAttribute(&value, key)) {
return false;
}

if (value.size() >= 2 && value[0] == '"' && value[value.size() - 1] == '"') {
out->assign(value.begin() + 1, value.end() - 1);
return true;
}

if (value.size() % 2 != 0) {
PrintLine("Error decoding value: %s", value.c_str());
return false;
}
out->clear();
out->reserve(value.size() / 2);
for (size_t i = 0; i < value.size(); i += 2) {
uint8_t hi, lo;
if (!FromHexDigit(&hi, value[i]) || !FromHexDigit(&lo, value[i + 1])) {
PrintLine("Error decoding value: %s", value.c_str());
return false;
}
out->push_back((hi << 4) | lo);
}
return true;
return GetAttribute(&value, key) && ConvertToBytes(out, value);
}

static std::string EncodeHex(const uint8_t *in, size_t in_len) {
@@ -381,6 +348,46 @@ void FileTest::OnInstructionUsed(const std::string &key) {
unused_instructions_.erase(key);
}

static bool FromHexDigit(uint8_t *out, char c) {
if ('0' <= c && c <= '9') {
*out = c - '0';
return true;
}
if ('a' <= c && c <= 'f') {
*out = c - 'a' + 10;
return true;
}
if ('A' <= c && c <= 'F') {
*out = c - 'A' + 10;
return true;
}
return false;
}

bool FileTest::ConvertToBytes(std::vector<uint8_t> *out,
const std::string &value) {
if (value.size() >= 2 && value[0] == '"' && value[value.size() - 1] == '"') {
out->assign(value.begin() + 1, value.end() - 1);
return true;
}

if (value.size() % 2 != 0) {
PrintLine("Error decoding value: %s", value.c_str());
return false;
}
out->clear();
out->reserve(value.size() / 2);
for (size_t i = 0; i < value.size(); i += 2) {
uint8_t hi, lo;
if (!FromHexDigit(&hi, value[i]) || !FromHexDigit(&lo, value[i + 1])) {
PrintLine("Error decoding value: %s", value.c_str());
return false;
}
out->push_back((hi << 4) | lo);
}
return true;
}

bool FileTest::IsAtNewInstructionBlock() const {
return is_at_new_instruction_block_;
}


+ 5
- 0
crypto/test/file_test.h Vedi File

@@ -185,6 +185,10 @@ class FileTest {
// otherwise.
bool GetInstruction(std::string *out_value, const std::string &key);

// GetInstructionBytes behaves like GetBytes, but looks up the corresponding
// instruction.
bool GetInstructionBytes(std::vector<uint8_t> *out, const std::string &key);

// CurrentTestToString returns the file content parsed for the current test.
// If the current test was preceded by an instruction block, the return test
// case is preceded by the instruction block and a single blank line. All
@@ -203,6 +207,7 @@ class FileTest {
void ClearInstructions();
void OnKeyUsed(const std::string &key);
void OnInstructionUsed(const std::string &key);
bool ConvertToBytes(std::vector<uint8_t> *out, const std::string &value);

std::unique_ptr<LineReader> reader_;
// line_ is the number of lines read.


+ 91
- 0
crypto/test/wycheproof_util.cc Vedi File

@@ -0,0 +1,91 @@
/* Copyright (c) 2018, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include "./wycheproof_util.h"

#include <openssl/digest.h>
#include <openssl/ec.h>
#include <openssl/nid.h>

#include "./file_test.h"


bool GetWycheproofResult(FileTest *t, WycheproofResult *out) {
std::string result;
if (!t->GetAttribute(&result, "result")) {
return false;
}
if (result == "valid") {
*out = WycheproofResult::kValid;
} else if (result == "invalid") {
*out = WycheproofResult::kInvalid;
} else if (result == "acceptable") {
*out = WycheproofResult::kAcceptable;
} else {
t->PrintLine("Bad result string '%s'", result.c_str());
return false;
}
return true;
}

const EVP_MD *GetWycheproofDigest(FileTest *t, const char *key,
bool instruction) {
std::string name;
bool ok =
instruction ? t->GetInstruction(&name, key) : t->GetAttribute(&name, key);
if (!ok) {
return nullptr;
}
if (name == "SHA-1") {
return EVP_sha1();
}
if (name == "SHA-224") {
return EVP_sha224();
}
if (name == "SHA-256") {
return EVP_sha256();
}
if (name == "SHA-384") {
return EVP_sha384();
}
if (name == "SHA-512") {
return EVP_sha512();
}
t->PrintLine("Unknown digest '%s'", name.c_str());
return nullptr;
}

bssl::UniquePtr<EC_GROUP> GetWycheproofCurve(FileTest *t, const char *key,
bool instruction) {
std::string name;
bool ok =
instruction ? t->GetInstruction(&name, key) : t->GetAttribute(&name, key);
if (!ok) {
return nullptr;
}
int nid;
if (name == "secp224r1") {
nid = NID_secp224r1;
} else if (name == "secp256r1") {
nid = NID_X9_62_prime256v1;
} else if (name == "secp384r1") {
nid = NID_secp384r1;
} else if (name == "secp521r1") {
nid = NID_secp521r1;
} else {
t->PrintLine("Unknown curve '%s'", name.c_str());
return nullptr;
}
return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(nid));
}

+ 45
- 0
crypto/test/wycheproof_util.h Vedi File

@@ -0,0 +1,45 @@
/* Copyright (c) 2018, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#ifndef OPENSSL_HEADER_CRYPTO_TEST_WYCHEPROOF_UTIL_H
#define OPENSSL_HEADER_CRYPTO_TEST_WYCHEPROOF_UTIL_H

#include <openssl/base.h>


// This header contains convenience functions for Wycheproof tests.

class FileTest;

enum class WycheproofResult {
kValid,
kInvalid,
kAcceptable,
};

// GetWycheproofResult sets |*out| to the parsed "result" key of |t|.
bool GetWycheproofResult(FileTest *t, WycheproofResult *out);

// GetWycheproofDigest returns a digest function using the Wycheproof name, or
// nullptr on error.
const EVP_MD *GetWycheproofDigest(FileTest *t, const char *key,
bool instruction);

// GetWycheproofCurve returns a curve using the Wycheproof name, or nullptr on
// error.
bssl::UniquePtr<EC_GROUP> GetWycheproofCurve(FileTest *t, const char *key,
bool instruction);


#endif // OPENSSL_HEADER_CRYPTO_TEST_WYCHEPROOF_UTIL_H

+ 7
- 0
sources.cmake Vedi File

@@ -59,5 +59,12 @@ set(
crypto/x509/some_names1.pem
crypto/x509/some_names2.pem
crypto/x509/some_names3.pem
third_party/wycheproof/ecdsa_secp224r1_sha224_test.txt
third_party/wycheproof/ecdsa_secp224r1_sha256_test.txt
third_party/wycheproof/ecdsa_secp256r1_sha256_test.txt
third_party/wycheproof/ecdsa_secp384r1_sha384_test.txt
third_party/wycheproof/ecdsa_secp384r1_sha512_test.txt
third_party/wycheproof/ecdsa_secp521r1_sha512_test.txt
third_party/wycheproof/rsa_signature_test.txt
third_party/wycheproof/x25519_test.txt
)

+ 7
- 7
third_party/wycheproof/convert_wycheproof.go Vedi File

@@ -224,6 +224,13 @@ func convertWycheproof(jsonPath, txtPath string) error {

func main() {
jsonPaths := []string{
"ecdsa_secp224r1_sha224_test.json",
"ecdsa_secp224r1_sha256_test.json",
"ecdsa_secp256r1_sha256_test.json",
"ecdsa_secp384r1_sha384_test.json",
"ecdsa_secp384r1_sha512_test.json",
"ecdsa_secp521r1_sha512_test.json",
"rsa_signature_test.json",
"x25519_test.json",

// TODO(davidben): The following tests still need test drivers.
@@ -233,14 +240,7 @@ func main() {
// "chacha20_poly1305_test.json",
// "dsa_test.json",
// "ecdh_test.json",
// "ecdsa_secp224r1_sha224_test.json",
// "ecdsa_secp224r1_sha256_test.json",
// "ecdsa_secp256r1_sha256_test.json",
// "ecdsa_secp384r1_sha384_test.json",
// "ecdsa_secp384r1_sha512_test.json",
// "ecdsa_secp521r1_sha512_test.json",
// "eddsa_test.json",
// "rsa_signature_test.json",
}
for _, jsonPath := range jsonPaths {
if !strings.HasSuffix(jsonPath, ".json") {


+ 2333
- 0
third_party/wycheproof/ecdsa_secp224r1_sha224_test.txt
File diff soppresso perché troppo grande
Vedi File


+ 2324
- 0
third_party/wycheproof/ecdsa_secp224r1_sha256_test.txt
File diff soppresso perché troppo grande
Vedi File


+ 2404
- 0
third_party/wycheproof/ecdsa_secp256r1_sha256_test.txt
File diff soppresso perché troppo grande
Vedi File


+ 2293
- 0
third_party/wycheproof/ecdsa_secp384r1_sha384_test.txt
File diff soppresso perché troppo grande
Vedi File


+ 2302
- 0
third_party/wycheproof/ecdsa_secp384r1_sha512_test.txt
File diff soppresso perché troppo grande
Vedi File


+ 2318
- 0
third_party/wycheproof/ecdsa_secp521r1_sha512_test.txt
File diff soppresso perché troppo grande
Vedi File


+ 2606
- 0
third_party/wycheproof/rsa_signature_test.txt
File diff soppresso perché troppo grande
Vedi File


Caricamento…
Annulla
Salva