1 // Copyright 2017 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ////////////////////////////////////////////////////////////////////////////////
16
17 #include "tink/subtle/ecdsa_sign_boringssl.h"
18
19 #include <string>
20 #include <utility>
21
22 #include "gtest/gtest.h"
23 #include "absl/status/status.h"
24 #include "tink/internal/ec_util.h"
25 #include "tink/internal/fips_utils.h"
26 #include "tink/public_key_sign.h"
27 #include "tink/public_key_verify.h"
28 #include "tink/subtle/common_enums.h"
29 #include "tink/subtle/ecdsa_verify_boringssl.h"
30 #include "tink/subtle/subtle_util_boringssl.h"
31 #include "tink/util/status.h"
32 #include "tink/util/statusor.h"
33 #include "tink/util/test_matchers.h"
34
35 namespace crypto {
36 namespace tink {
37 namespace subtle {
38 namespace {
39
40 using ::crypto::tink::test::IsOk;
41 using ::crypto::tink::test::StatusIs;
42
43 class EcdsaSignBoringSslTest : public ::testing::Test {};
44
TEST_F(EcdsaSignBoringSslTest,testBasicSigning)45 TEST_F(EcdsaSignBoringSslTest, testBasicSigning) {
46 if (internal::IsFipsModeEnabled() && !internal::IsFipsEnabledInSsl()) {
47 GTEST_SKIP()
48 << "Test is skipped if kOnlyUseFips but BoringCrypto is unavailable.";
49 }
50 subtle::EcdsaSignatureEncoding encodings[2] = {
51 EcdsaSignatureEncoding::DER, EcdsaSignatureEncoding::IEEE_P1363};
52 for (EcdsaSignatureEncoding encoding : encodings) {
53 auto ec_key =
54 SubtleUtilBoringSSL::GetNewEcKey(EllipticCurveType::NIST_P256).value();
55 auto signer_result =
56 EcdsaSignBoringSsl::New(ec_key, HashType::SHA256, encoding);
57 ASSERT_TRUE(signer_result.ok()) << signer_result.status();
58 auto signer = std::move(signer_result.value());
59
60 auto verifier_result =
61 EcdsaVerifyBoringSsl::New(ec_key, HashType::SHA256, encoding);
62 ASSERT_TRUE(verifier_result.ok()) << verifier_result.status();
63 auto verifier = std::move(verifier_result.value());
64
65 std::string message = "some data to be signed";
66 std::string signature = signer->Sign(message).value();
67 EXPECT_NE(signature, message);
68 auto status = verifier->Verify(signature, message);
69 EXPECT_TRUE(status.ok()) << status;
70
71 status = verifier->Verify("some bad signature", message);
72 EXPECT_FALSE(status.ok());
73
74 status = verifier->Verify(signature, "some bad message");
75 EXPECT_FALSE(status.ok());
76
77 // Message is a null string_view.
78 const absl::string_view empty_message;
79 signature = signer->Sign(empty_message).value();
80 EXPECT_NE(signature, empty_message);
81 status = verifier->Verify(signature, empty_message);
82 EXPECT_TRUE(status.ok()) << status;
83 }
84 }
85
TEST_F(EcdsaSignBoringSslTest,testEncodingsMismatch)86 TEST_F(EcdsaSignBoringSslTest, testEncodingsMismatch) {
87 if (internal::IsFipsModeEnabled() && !internal::IsFipsEnabledInSsl()) {
88 GTEST_SKIP()
89 << "Test is skipped if kOnlyUseFips but BoringCrypto is unavailable.";
90 }
91 subtle::EcdsaSignatureEncoding encodings[2] = {
92 EcdsaSignatureEncoding::DER, EcdsaSignatureEncoding::IEEE_P1363};
93 for (EcdsaSignatureEncoding encoding : encodings) {
94 auto ec_key =
95 SubtleUtilBoringSSL::GetNewEcKey(EllipticCurveType::NIST_P256).value();
96 auto signer_result =
97 EcdsaSignBoringSsl::New(ec_key, HashType::SHA256, encoding);
98 ASSERT_TRUE(signer_result.ok()) << signer_result.status();
99 auto signer = std::move(signer_result.value());
100
101 auto verifier_result =
102 EcdsaVerifyBoringSsl::New(ec_key, HashType::SHA256,
103 encoding == EcdsaSignatureEncoding::DER
104 ? EcdsaSignatureEncoding::IEEE_P1363
105 : EcdsaSignatureEncoding::DER);
106 ASSERT_TRUE(verifier_result.ok()) << verifier_result.status();
107 auto verifier = std::move(verifier_result.value());
108
109 std::string message = "some data to be signed";
110 std::string signature = signer->Sign(message).value();
111 EXPECT_NE(signature, message);
112 auto status = verifier->Verify(signature, message);
113 EXPECT_FALSE(status.ok()) << status;
114 }
115 }
116
TEST_F(EcdsaSignBoringSslTest,testSignatureSizesWithIEEE_P1364Encoding)117 TEST_F(EcdsaSignBoringSslTest, testSignatureSizesWithIEEE_P1364Encoding) {
118 if (internal::IsFipsModeEnabled() && !internal::IsFipsEnabledInSsl()) {
119 GTEST_SKIP()
120 << "Test is skipped if kOnlyUseFips but BoringCrypto is unavailable.";
121 }
122 EllipticCurveType curves[3] = {EllipticCurveType::NIST_P256,
123 EllipticCurveType::NIST_P384,
124 EllipticCurveType::NIST_P521};
125 for (EllipticCurveType curve : curves) {
126 auto ec_key = SubtleUtilBoringSSL::GetNewEcKey(curve).value();
127 auto signer_result = EcdsaSignBoringSsl::New(
128 ec_key, HashType::SHA256, EcdsaSignatureEncoding::IEEE_P1363);
129 ASSERT_TRUE(signer_result.ok()) << signer_result.status();
130 auto signer = std::move(signer_result.value());
131
132 auto verifier_result = EcdsaVerifyBoringSsl::New(
133 ec_key, HashType::SHA256, EcdsaSignatureEncoding::IEEE_P1363);
134 ASSERT_TRUE(verifier_result.ok()) << verifier_result.status();
135 auto verifier = std::move(verifier_result.value());
136
137 std::string message = "some data to be signed";
138 std::string signature = signer->Sign(message).value();
139 EXPECT_NE(signature, message);
140 auto status = verifier->Verify(signature, message);
141 EXPECT_TRUE(status.ok()) << status;
142
143 // Check signature size.
144 util::StatusOr<int32_t> field_size_in_bytes =
145 internal::EcFieldSizeInBytes(curve);
146 ASSERT_THAT(field_size_in_bytes, IsOk());
147 EXPECT_EQ(signature.size(), 2 * (*field_size_in_bytes));
148 }
149 }
150
TEST_F(EcdsaSignBoringSslTest,testNewErrors)151 TEST_F(EcdsaSignBoringSslTest, testNewErrors) {
152 if (internal::IsFipsModeEnabled() && !internal::IsFipsEnabledInSsl()) {
153 GTEST_SKIP()
154 << "Test is skipped if kOnlyUseFips but BoringCrypto is unavailable.";
155 }
156 auto ec_key =
157 SubtleUtilBoringSSL::GetNewEcKey(EllipticCurveType::NIST_P256).value();
158 auto signer_result = EcdsaSignBoringSsl::New(ec_key, HashType::SHA1,
159 EcdsaSignatureEncoding::DER);
160 EXPECT_FALSE(signer_result.ok()) << signer_result.status();
161 }
162
163 // TODO(bleichen): add Wycheproof tests.
164
165 // FIPS-only mode test
TEST_F(EcdsaSignBoringSslTest,TestFipsFailWithoutBoringCrypto)166 TEST_F(EcdsaSignBoringSslTest, TestFipsFailWithoutBoringCrypto) {
167 if (!internal::IsFipsModeEnabled() || internal::IsFipsEnabledInSsl()) {
168 GTEST_SKIP()
169 << "Test assumes kOnlyUseFips but BoringCrypto is unavailable.";
170 }
171
172 auto ec_key =
173 SubtleUtilBoringSSL::GetNewEcKey(EllipticCurveType::NIST_P256).value();
174 EXPECT_THAT(EcdsaSignBoringSsl::New(ec_key, HashType::SHA256,
175 EcdsaSignatureEncoding::DER)
176 .status(),
177 StatusIs(absl::StatusCode::kInternal));
178
179 ec_key =
180 SubtleUtilBoringSSL::GetNewEcKey(EllipticCurveType::NIST_P384).value();
181 EXPECT_THAT(EcdsaSignBoringSsl::New(ec_key, HashType::SHA256,
182 EcdsaSignatureEncoding::DER)
183 .status(),
184 StatusIs(absl::StatusCode::kInternal));
185
186 ec_key =
187 SubtleUtilBoringSSL::GetNewEcKey(EllipticCurveType::NIST_P521).value();
188 EXPECT_THAT(EcdsaSignBoringSsl::New(ec_key, HashType::SHA256,
189 EcdsaSignatureEncoding::DER)
190 .status(),
191 StatusIs(absl::StatusCode::kInternal));
192 }
193
194 } // namespace
195 } // namespace subtle
196 } // namespace tink
197 } // namespace crypto
198