xref: /aosp_15_r20/external/tink/cc/subtle/rsa_ssa_pkcs1_sign_boringssl_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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