1 /* Copyright (c) 2017, Google Inc. 2 * 3 * Permission to use, copy, modify, and/or distribute this software for any 4 * purpose with or without fee is hereby granted, provided that the above 5 * copyright notice and this permission notice appear in all copies. 6 * 7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 14 15 // cavp_ecdsa2_sigver_test processes a NIST CAVP ECDSA2 SigVer test vector 16 // request file and emits the corresponding response. 17 18 #include <vector> 19 20 #include <openssl/bn.h> 21 #include <openssl/crypto.h> 22 #include <openssl/digest.h> 23 #include <openssl/ec_key.h> 24 #include <openssl/ecdsa.h> 25 #include <openssl/err.h> 26 #include <openssl/nid.h> 27 28 #include "../crypto/test/file_test.h" 29 #include "cavp_test_util.h" 30 31 32 static bool TestECDSA2SigVer(FileTest *t, void *arg) { 33 int nid = GetECGroupNIDFromInstruction(t); 34 const EVP_MD *md = GetDigestFromInstruction(t); 35 if (nid == NID_undef || md == nullptr) { 36 return false; 37 } 38 bssl::UniquePtr<ECDSA_SIG> sig(ECDSA_SIG_new()); 39 bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(nid)); 40 bssl::UniquePtr<BIGNUM> qx = GetBIGNUM(t, "Qx"); 41 bssl::UniquePtr<BIGNUM> qy = GetBIGNUM(t, "Qy"); 42 bssl::UniquePtr<BIGNUM> r = GetBIGNUM(t, "R"); 43 bssl::UniquePtr<BIGNUM> s = GetBIGNUM(t, "S"); 44 std::vector<uint8_t> msg; 45 uint8_t digest[EVP_MAX_MD_SIZE]; 46 unsigned digest_len; 47 if (!sig || !key || !qx || !qy || !r || !s || 48 !EC_KEY_set_public_key_affine_coordinates(key.get(), qx.get(), 49 qy.get()) || 50 !t->GetBytes(&msg, "Msg") || 51 !EVP_Digest(msg.data(), msg.size(), digest, &digest_len, md, nullptr)) { 52 return false; 53 } 54 55 BN_free(sig->r); 56 sig->r = r.release(); 57 BN_free(sig->s); 58 sig->s = s.release(); 59 60 if (ECDSA_do_verify(digest, digest_len, sig.get(), key.get())) { 61 printf("%sResult = P\r\n\r\n", t->CurrentTestToString().c_str()); 62 } else { 63 char buf[256]; 64 ERR_error_string_n(ERR_get_error(), buf, sizeof(buf)); 65 printf("%sResult = F (%s)\r\n\r\n", t->CurrentTestToString().c_str(), buf); 66 } 67 ERR_clear_error(); 68 return true; 69 } 70 71 int cavp_ecdsa2_sigver_test_main(int argc, char **argv) { 72 if (argc != 2) { 73 fprintf(stderr, "usage: %s <test file>\n", 74 argv[0]); 75 return 1; 76 } 77 78 FileTest::Options opts; 79 opts.path = argv[1]; 80 opts.callback = TestECDSA2SigVer; 81 opts.silent = true; 82 opts.comment_callback = EchoComment; 83 return FileTestMain(opts); 84 } 85