1 // Copyright 2018 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/rsa_ssa_pkcs1_sign_boringssl.h"
18
19 #include <cstdint>
20
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
23 #include "absl/status/status.h"
24 #include "absl/strings/escaping.h"
25 #include "openssl/bn.h"
26 #include "openssl/crypto.h"
27 #include "openssl/rsa.h"
28 #include "tink/internal/fips_utils.h"
29 #include "tink/internal/rsa_util.h"
30 #include "tink/internal/ssl_unique_ptr.h"
31 #include "tink/subtle/rsa_ssa_pkcs1_verify_boringssl.h"
32 #include "tink/util/test_matchers.h"
33
34 namespace crypto {
35 namespace tink {
36 namespace subtle {
37 namespace {
38
39 using ::crypto::tink::test::IsOk;
40 using ::crypto::tink::test::StatusIs;
41 using ::testing::IsEmpty;
42 using ::testing::Not;
43
44 class RsaPkcs1SignBoringsslTest : public ::testing::Test {
45 public:
RsaPkcs1SignBoringsslTest()46 RsaPkcs1SignBoringsslTest() : rsa_f4_(BN_new()) {
47 EXPECT_TRUE(BN_set_word(rsa_f4_.get(), RSA_F4));
48 EXPECT_THAT(
49 internal::NewRsaKeyPair(/*modulus_size_in_bits=*/2048, rsa_f4_.get(),
50 &private_key_, &public_key_),
51 IsOk());
52 }
53
54 protected:
55 internal::SslUniquePtr<BIGNUM> rsa_f4_;
56 internal::RsaPrivateKey private_key_;
57 internal::RsaPublicKey public_key_;
58 };
59
TEST_F(RsaPkcs1SignBoringsslTest,EncodesPkcs1)60 TEST_F(RsaPkcs1SignBoringsslTest, EncodesPkcs1) {
61 if (internal::IsFipsModeEnabled()) {
62 GTEST_SKIP() << "Test not run in FIPS-only mode";
63 }
64
65 internal::RsaSsaPkcs1Params params{/*sig_hash=*/HashType::SHA256};
66
67 auto signer_or = RsaSsaPkcs1SignBoringSsl::New(private_key_, params);
68 ASSERT_THAT(signer_or, IsOk());
69
70 auto signature_or = signer_or.value()->Sign("testdata");
71 ASSERT_THAT(signature_or, IsOk());
72 EXPECT_THAT(signature_or.value(), Not(IsEmpty()));
73
74 auto verifier_or = RsaSsaPkcs1VerifyBoringSsl::New(public_key_, params);
75 ASSERT_THAT(verifier_or, IsOk());
76 EXPECT_THAT(verifier_or.value()->Verify(signature_or.value(), "testdata"),
77 IsOk());
78 }
79
TEST_F(RsaPkcs1SignBoringsslTest,EncodesPkcs1WithSeparateHashes)80 TEST_F(RsaPkcs1SignBoringsslTest, EncodesPkcs1WithSeparateHashes) {
81 if (internal::IsFipsModeEnabled()) {
82 GTEST_SKIP() << "Test not run in FIPS-only mode";
83 }
84
85 internal::RsaSsaPkcs1Params params{/*sig_hash=*/HashType::SHA256};
86
87 auto signer_or = RsaSsaPkcs1SignBoringSsl::New(private_key_, params);
88 ASSERT_THAT(signer_or, IsOk());
89
90 auto signature_or = signer_or.value()->Sign("testdata");
91 ASSERT_THAT(signature_or, IsOk());
92 EXPECT_THAT(signature_or.value(), Not(IsEmpty()));
93
94 auto verifier_or = RsaSsaPkcs1VerifyBoringSsl::New(public_key_, params);
95 ASSERT_THAT(verifier_or, IsOk());
96 EXPECT_THAT(verifier_or.value()->Verify(signature_or.value(), "testdata"),
97 IsOk());
98 }
99
TEST_F(RsaPkcs1SignBoringsslTest,RejectsUnsafeHash)100 TEST_F(RsaPkcs1SignBoringsslTest, RejectsUnsafeHash) {
101 if (internal::IsFipsModeEnabled()) {
102 GTEST_SKIP() << "Test not run in FIPS-only mode";
103 }
104
105 internal::RsaSsaPkcs1Params params{/*sig_hash=*/HashType::SHA1};
106 ASSERT_THAT(RsaSsaPkcs1SignBoringSsl::New(private_key_, params).status(),
107 StatusIs(absl::StatusCode::kInvalidArgument));
108 }
109
TEST_F(RsaPkcs1SignBoringsslTest,RejectsInvalidCrtParams)110 TEST_F(RsaPkcs1SignBoringsslTest, RejectsInvalidCrtParams) {
111 if (internal::IsFipsModeEnabled()) {
112 GTEST_SKIP() << "Test not run in FIPS-only mode";
113 }
114
115 internal::RsaSsaPkcs1Params params{/*sig_hash=*/HashType::SHA256};
116 ASSERT_THAT(private_key_.crt, Not(IsEmpty()));
117 ASSERT_THAT(private_key_.dq, Not(IsEmpty()));
118 ASSERT_THAT(private_key_.dp, Not(IsEmpty()));
119
120 // Flip a few bits in the CRT parameters; check that creation fails.
121 {
122 internal::RsaPrivateKey key = private_key_;
123 key.crt[0] ^= 0x80;
124 auto signer_or = RsaSsaPkcs1SignBoringSsl::New(key, params);
125 EXPECT_THAT(signer_or.status(),
126 StatusIs(absl::StatusCode::kInvalidArgument));
127 }
128 {
129 internal::RsaPrivateKey key = private_key_;
130 key.dq[0] ^= 0x08;
131 auto signer_or = RsaSsaPkcs1SignBoringSsl::New(key, params);
132 EXPECT_THAT(signer_or.status(),
133 StatusIs(absl::StatusCode::kInvalidArgument));
134 }
135 {
136 internal::RsaPrivateKey key = private_key_;
137 key.dp[0] ^= 0x04;
138 auto signer_or = RsaSsaPkcs1SignBoringSsl::New(key, params);
139 EXPECT_THAT(signer_or.status(),
140 StatusIs(absl::StatusCode::kInvalidArgument));
141 }
142 }
143
144 // FIPS-only mode test
TEST_F(RsaPkcs1SignBoringsslTest,TestFipsFailWithoutBoringCrypto)145 TEST_F(RsaPkcs1SignBoringsslTest, TestFipsFailWithoutBoringCrypto) {
146 if (!internal::IsFipsModeEnabled() || internal::IsFipsEnabledInSsl()) {
147 GTEST_SKIP()
148 << "Test assumes kOnlyUseFips but BoringCrypto is unavailable.";
149 }
150
151 internal::RsaSsaPkcs1Params params{/*sig_hash=*/HashType::SHA256};
152 EXPECT_THAT(RsaSsaPkcs1SignBoringSsl::New(private_key_, params).status(),
153 StatusIs(absl::StatusCode::kInternal));
154 }
155
TEST_F(RsaPkcs1SignBoringsslTest,TestRestrictedFipsModuli)156 TEST_F(RsaPkcs1SignBoringsslTest, TestRestrictedFipsModuli) {
157 if (!internal::IsFipsModeEnabled() || !internal::IsFipsEnabledInSsl()) {
158 GTEST_SKIP() << "Test assumes kOnlyUseFips and BoringCrypto.";
159 }
160
161 internal::RsaPrivateKey private_key;
162 internal::RsaPublicKey public_key;
163
164 EXPECT_THAT(internal::NewRsaKeyPair(/*modulus_size_in_bits=*/4096,
165 rsa_f4_.get(), &private_key, &public_key),
166 IsOk());
167
168 internal::RsaSsaPkcs1Params params{/*sig_hash=*/HashType::SHA256};
169 EXPECT_THAT(RsaSsaPkcs1SignBoringSsl::New(private_key, params).status(),
170 StatusIs(absl::StatusCode::kInternal));
171 }
172
TEST_F(RsaPkcs1SignBoringsslTest,TestAllowedFipsModuli)173 TEST_F(RsaPkcs1SignBoringsslTest, TestAllowedFipsModuli) {
174 if (!internal::IsFipsModeEnabled() || !internal::IsFipsEnabledInSsl()) {
175 GTEST_SKIP() << "Test assumes kOnlyUseFips and BoringCrypto.";
176 }
177
178 internal::RsaPrivateKey private_key;
179 internal::RsaPublicKey public_key;
180
181 EXPECT_THAT(internal::NewRsaKeyPair(/*modulus_size_in_bits=*/3072,
182 rsa_f4_.get(), &private_key, &public_key),
183 IsOk());
184
185 internal::RsaSsaPkcs1Params params{/*sig_hash=*/HashType::SHA256};
186 EXPECT_THAT(RsaSsaPkcs1SignBoringSsl::New(private_key, params).status(),
187 IsOk());
188 }
189
190 } // namespace
191 } // namespace subtle
192 } // namespace tink
193 } // namespace crypto
194