1 // Copyright 2023 Google LLC
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/config/fips_140_2.h"
18
19 #include <memory>
20 #include <string>
21
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 #include "tink/aead.h"
25 #include "tink/aead/aead_key_templates.h"
26 #include "tink/aead/aes_ctr_hmac_aead_key_manager.h"
27 #include "tink/aead/aes_gcm_key_manager.h"
28 #include "tink/chunked_mac.h"
29 #include "tink/config/key_gen_fips_140_2.h"
30 #include "tink/internal/configuration_impl.h"
31 #include "tink/internal/fips_utils.h"
32 #include "tink/internal/key_type_info_store.h"
33 #include "tink/keyset_handle.h"
34 #include "tink/mac.h"
35 #include "tink/mac/aes_cmac_key_manager.h"
36 #include "tink/mac/hmac_key_manager.h"
37 #include "tink/prf/hmac_prf_key_manager.h"
38 #include "tink/public_key_sign.h"
39 #include "tink/public_key_verify.h"
40 #include "tink/signature/ecdsa_verify_key_manager.h"
41 #include "tink/signature/rsa_ssa_pkcs1_verify_key_manager.h"
42 #include "tink/signature/rsa_ssa_pss_verify_key_manager.h"
43 #include "tink/util/test_matchers.h"
44
45 namespace crypto {
46 namespace tink {
47 namespace {
48
49 using ::crypto::tink::test::IsOk;
50 using ::crypto::tink::test::IsOkAndHolds;
51 using ::crypto::tink::test::StatusIs;
52
53 class Fips1402Test : public ::testing::Test {
54 protected:
TearDown()55 void TearDown() override { internal::UnSetFipsRestricted(); }
56 };
57
TEST_F(Fips1402Test,PrimitiveWrappers)58 TEST_F(Fips1402Test, PrimitiveWrappers) {
59 if (!internal::IsFipsEnabledInSsl()) {
60 GTEST_SKIP() << "Only test in FIPS mode";
61 }
62
63 util::StatusOr<const internal::KeysetWrapperStore*> store =
64 internal::ConfigurationImpl::GetKeysetWrapperStore(ConfigFips140_2());
65 ASSERT_THAT(store, IsOk());
66
67 EXPECT_THAT((*store)->Get<Mac>(), IsOk());
68 EXPECT_THAT((*store)->Get<ChunkedMac>(), IsOk());
69 EXPECT_THAT((*store)->Get<Aead>(), IsOk());
70 EXPECT_THAT((*store)->Get<PrfSet>(), IsOk());
71 EXPECT_THAT((*store)->Get<PublicKeySign>(), IsOk());
72 EXPECT_THAT((*store)->Get<PublicKeyVerify>(), IsOk());
73 }
74
TEST_F(Fips1402Test,KeyManagers)75 TEST_F(Fips1402Test, KeyManagers) {
76 if (!internal::IsFipsEnabledInSsl()) {
77 GTEST_SKIP() << "Only test in FIPS mode";
78 }
79
80 util::StatusOr<const internal::KeyTypeInfoStore*> store =
81 internal::ConfigurationImpl::GetKeyTypeInfoStore(ConfigFips140_2());
82 ASSERT_THAT(store, IsOk());
83
84 EXPECT_THAT((*store)->Get(HmacKeyManager().get_key_type()), IsOk());
85 EXPECT_THAT((*store)->Get(AesCtrHmacAeadKeyManager().get_key_type()), IsOk());
86 EXPECT_THAT((*store)->Get(AesGcmKeyManager().get_key_type()), IsOk());
87 EXPECT_THAT((*store)->Get(HmacPrfKeyManager().get_key_type()), IsOk());
88 EXPECT_THAT((*store)->Get(EcdsaVerifyKeyManager().get_key_type()), IsOk());
89 EXPECT_THAT((*store)->Get(RsaSsaPssVerifyKeyManager().get_key_type()),
90 IsOk());
91 EXPECT_THAT((*store)->Get(RsaSsaPkcs1VerifyKeyManager().get_key_type()),
92 IsOk());
93 }
94
TEST_F(Fips1402Test,FailsInNonFipsMode)95 TEST_F(Fips1402Test, FailsInNonFipsMode) {
96 if (internal::IsFipsEnabledInSsl()) {
97 GTEST_SKIP() << "Only test in non-FIPS mode";
98 }
99
100 EXPECT_DEATH_IF_SUPPORTED(
101 ConfigFips140_2(), "BoringSSL not built with the BoringCrypto module.");
102 }
103
TEST_F(Fips1402Test,NonFipsTypeNotPresent)104 TEST_F(Fips1402Test, NonFipsTypeNotPresent) {
105 if (!internal::IsFipsEnabledInSsl()) {
106 GTEST_SKIP() << "Only test in FIPS mode";
107 }
108
109 util::StatusOr<const internal::KeyTypeInfoStore*> store =
110 internal::ConfigurationImpl::GetKeyTypeInfoStore(ConfigFips140_2());
111 ASSERT_THAT(store, IsOk());
112 EXPECT_THAT((*store)->Get(AesCmacKeyManager().get_key_type()).status(),
113 StatusIs(absl::StatusCode::kNotFound));
114 }
115
TEST_F(Fips1402Test,GetPrimitive)116 TEST_F(Fips1402Test, GetPrimitive) {
117 if (!internal::IsFipsEnabledInSsl()) {
118 GTEST_SKIP() << "Only test in FIPS mode";
119 }
120
121 util::StatusOr<std::unique_ptr<KeysetHandle>> handle =
122 KeysetHandle::GenerateNew(AeadKeyTemplates::Aes128Gcm(),
123 KeyGenConfigFips140_2());
124 ASSERT_THAT(handle, IsOk());
125
126 util::StatusOr<std::unique_ptr<Aead>> aead =
127 (*handle)->GetPrimitive<Aead>(ConfigFips140_2());
128 ASSERT_THAT(aead, IsOk());
129
130 std::string plaintext = "plaintext";
131 std::string ad = "ad";
132 util::StatusOr<std::string> ciphertext = (*aead)->Encrypt(plaintext, ad);
133 ASSERT_THAT(ciphertext, IsOk());
134 EXPECT_THAT((*aead)->Decrypt(*ciphertext, ad), IsOkAndHolds(plaintext));
135 }
136
137 } // namespace
138 } // namespace tink
139 } // namespace crypto
140