proxygen
ECSignatureTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree.
7  */
8 
9 #include <gtest/gtest.h>
10 
11 #include <fizz/crypto/ECCurve.h>
13 #include <folly/String.h>
14 
15 using namespace folly;
16 using namespace folly::ssl;
17 
18 namespace fizz {
19 namespace testing {
20 
21 struct Params {
26 };
27 
28 class ECDSATest : public ::testing::TestWithParam<Params> {
29  void SetUp() override {
30  OpenSSL_add_all_algorithms();
31  }
32 };
33 
34 class ECDSA256Test : public ECDSATest {};
35 class ECDSA384Test : public ECDSATest {};
36 class ECDSA521Test : public ECDSATest {};
37 
39  auto binX = unhexlify(x);
40  auto binY = unhexlify(y);
41  BIGNUMUniquePtr numX(BN_bin2bn((uint8_t*)binX.data(), binX.size(), nullptr));
42  BIGNUMUniquePtr numY(BN_bin2bn((uint8_t*)binY.data(), binY.size(), nullptr));
43  EC_KEY_set_public_key_affine_coordinates(key.get(), numX.get(), numY.get());
44 }
45 
46 EvpPkeyUniquePtr getKey(int nid, const Params& param) {
47  auto privKeyBin = unhexlify(param.priv);
48  BIGNUMUniquePtr privateBn(
49  BN_bin2bn((uint8_t*)privKeyBin.c_str(), privKeyBin.size(), nullptr));
50  EcKeyUniquePtr privateKey(EC_KEY_new_by_curve_name(nid));
51  EC_KEY_set_private_key(privateKey.get(), privateBn.get());
52  setPoint(privateKey, param.pubX, param.pubY);
53  EvpPkeyUniquePtr pkeyPrivateKey(EVP_PKEY_new());
54  EVP_PKEY_set1_EC_KEY(pkeyPrivateKey.get(), privateKey.get());
55  return pkeyPrivateKey;
56 }
57 
59  auto& sigPtr = sig->writableData()[10];
60  if (sigPtr == 1) {
61  sigPtr = 2;
62  } else {
63  sigPtr = 1;
64  }
65 }
66 
68  auto& sigPtr = sig->writableData()[10];
69  if (sigPtr == 1) {
70  sigPtr = 2;
71  } else {
72  sigPtr = 1;
73  }
74  auto& msgPtr = msg[2];
75  if (msgPtr == 1) {
76  msgPtr = 2;
77  } else {
78  msgPtr = 1;
79  }
80 }
81 
82 TEST_P(ECDSA256Test, TestSignature) {
83  auto key = getKey(P256::curveNid, GetParam());
85  ecdsa.setKey(std::move(key));
86  {
87  std::string msg = GetParam().msg;
88  auto sig = ecdsa.sign<SignatureScheme::ecdsa_secp256r1_sha256>(
89  IOBuf::copyBuffer(msg)->coalesce());
90  ecdsa.verify<SignatureScheme::ecdsa_secp256r1_sha256>(
91  IOBuf::copyBuffer(msg)->coalesce(), sig->coalesce());
92  }
93  {
94  std::string msg = GetParam().msg;
95  auto sig = ecdsa.sign<SignatureScheme::ecdsa_secp256r1_sha256>(
96  IOBuf::copyBuffer(msg)->coalesce());
97  modifySig(sig.get());
99  ecdsa.verify<SignatureScheme::ecdsa_secp256r1_sha256>(
100  IOBuf::copyBuffer(msg)->coalesce(), sig->coalesce()),
101  std::runtime_error);
102  }
103  {
104  std::string msg = GetParam().msg;
105  auto sig = ecdsa.sign<SignatureScheme::ecdsa_secp256r1_sha256>(
106  IOBuf::copyBuffer(msg)->coalesce());
107  modifyData(sig.get(), msg);
108  EXPECT_THROW(
109  ecdsa.verify<SignatureScheme::ecdsa_secp256r1_sha256>(
110  IOBuf::copyBuffer(msg)->coalesce(), sig->coalesce()),
111  std::runtime_error);
112  }
113 }
114 
115 TEST_P(ECDSA384Test, TestSignature) {
116  auto key = getKey(P384::curveNid, GetParam());
118  ecdsa.setKey(std::move(key));
119  {
120  std::string msg = GetParam().msg;
121  auto sig = ecdsa.sign<SignatureScheme::ecdsa_secp384r1_sha384>(
122  IOBuf::copyBuffer(msg)->coalesce());
123  ecdsa.verify<SignatureScheme::ecdsa_secp384r1_sha384>(
124  IOBuf::copyBuffer(msg)->coalesce(), sig->coalesce());
125  }
126  {
127  std::string msg = GetParam().msg;
128  auto sig = ecdsa.sign<SignatureScheme::ecdsa_secp384r1_sha384>(
129  IOBuf::copyBuffer(msg)->coalesce());
130  modifySig(sig.get());
131  EXPECT_THROW(
132  ecdsa.verify<SignatureScheme::ecdsa_secp384r1_sha384>(
133  IOBuf::copyBuffer(msg)->coalesce(), sig->coalesce()),
134  std::runtime_error);
135  }
136  {
137  std::string msg = GetParam().msg;
138  auto sig = ecdsa.sign<SignatureScheme::ecdsa_secp384r1_sha384>(
139  IOBuf::copyBuffer(msg)->coalesce());
140  modifyData(sig.get(), msg);
141  EXPECT_THROW(
142  ecdsa.verify<SignatureScheme::ecdsa_secp384r1_sha384>(
143  IOBuf::copyBuffer(msg)->coalesce(), sig->coalesce()),
144  std::runtime_error);
145  }
146 }
147 
148 TEST_P(ECDSA521Test, TestSignature) {
149  auto key = getKey(P521::curveNid, GetParam());
151  ecdsa.setKey(std::move(key));
152  {
153  std::string msg = GetParam().msg;
154  auto sig = ecdsa.sign<SignatureScheme::ecdsa_secp521r1_sha512>(
155  IOBuf::copyBuffer(msg)->coalesce());
156  ecdsa.verify<SignatureScheme::ecdsa_secp521r1_sha512>(
157  IOBuf::copyBuffer(msg)->coalesce(), sig->coalesce());
158  }
159  {
160  std::string msg = GetParam().msg;
161  auto sig = ecdsa.sign<SignatureScheme::ecdsa_secp521r1_sha512>(
162  IOBuf::copyBuffer(msg)->coalesce());
163  modifySig(sig.get());
164  EXPECT_THROW(
165  ecdsa.verify<SignatureScheme::ecdsa_secp521r1_sha512>(
166  IOBuf::copyBuffer(msg)->coalesce(), sig->coalesce()),
167  std::runtime_error);
168  }
169  {
170  std::string msg = GetParam().msg;
171  auto sig = ecdsa.sign<SignatureScheme::ecdsa_secp521r1_sha512>(
172  IOBuf::copyBuffer(msg)->coalesce());
173  modifyData(sig.get(), msg);
174  EXPECT_THROW(
175  ecdsa.verify<SignatureScheme::ecdsa_secp521r1_sha512>(
176  IOBuf::copyBuffer(msg)->coalesce(), sig->coalesce()),
177  std::runtime_error);
178  }
179 }
180 
181 // Test vector from https://tools.ietf.org/html/rfc6979#appendix-A.2.5
182 // We can't test those directly since we'd need to use the more complicated
183 // API of actually setting k and dealing with ECDSA_sig objects directly.
185  TestVectors,
186  ECDSA256Test,
187  ::testing::Values(Params{
188  "sample",
189  "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721",
190  "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6",
191  "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299"}));
193  TestVectors,
194  ECDSA384Test,
195  ::testing::Values(Params{
196  "sample",
197  "6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D8"
198  "96D5724E4C70A825F872C9EA60D2EDF5",
199  "EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64"
200  "DEF8F0EA9055866064A254515480BC13",
201  "8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1"
202  "288B231C3AE0D4FE7344FD2533264720"}));
204  TestVectors,
205  ECDSA521Test,
206  ::testing::Values(Params{
207  "sample",
208  // NOTE these are 0 padded at the beginning for unhexlify
209  "00FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75C"
210  "AA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83"
211  "538",
212  "01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD3"
213  "71123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F502"
214  "3A4",
215  "00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A2"
216  "8A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDF"
217  "CF5"}));
218 } // namespace testing
219 } // namespace fizz
Definition: InvokeTest.cpp:58
bool unhexlify(const InputString &input, OutputString &output)
Definition: String-inl.h:616
void setPoint(EcKeyUniquePtr &key, std::string x, std::string y)
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::unique_ptr< folly::IOBuf > sign(folly::ByteRange data) const
Definition: Signature-inl.h:69
std::unique_ptr< EVP_PKEY, EvpPkeyDeleter > EvpPkeyUniquePtr
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
std::unique_ptr< BIGNUM, BIGNUMDeleter > BIGNUMUniquePtr
std::unique_ptr< EC_KEY, EcKeyDeleter > EcKeyUniquePtr
uint8_t * writableData()
Definition: IOBuf.h:509
void verify(folly::ByteRange data, folly::ByteRange signature) const
Definition: Signature-inl.h:86
constexpr detail::Sig< Sig > const sig
Definition: Poly.h:1165
Definition: Actions.h:16
INSTANTIATE_TEST_CASE_P(TestVectors, ECDSA521Test,::testing::Values(Params{"sample","00FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75C""AA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83""538","01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD3""71123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F502""3A4","00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A2""8A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDF""CF5"}))
TrafficKey getKey()
const char * string
Definition: Conv.cpp:212
Definition: InvokeTest.cpp:65
void modifySig(folly::IOBuf *sig)
static std::unique_ptr< IOBuf > copyBuffer(const void *buf, std::size_t size, std::size_t headroom=0, std::size_t minTailroom=0)
Definition: IOBuf.h:1587
void setKey(folly::ssl::EvpPkeyUniquePtr pkey)
TEST_P(ECDSA521Test, TestSignature)
void modifyData(folly::IOBuf *sig, std::string &msg)