xref: /aosp_15_r20/external/tink/cc/hybrid/internal/hpke_encrypt_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2021 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/hybrid/internal/hpke_encrypt.h"
18 
19 #include <memory>
20 #include <string>
21 #include <vector>
22 
23 #include "gtest/gtest.h"
24 #include "absl/status/status.h"
25 #include "absl/strings/str_cat.h"
26 #include "tink/hybrid/internal/hpke_test_util.h"
27 #include "tink/hybrid/internal/hpke_util.h"
28 #include "tink/util/test_matchers.h"
29 #include "proto/hpke.pb.h"
30 
31 namespace crypto {
32 namespace tink {
33 namespace {
34 
35 using ::crypto::tink::internal::CreateHpkeParams;
36 using ::crypto::tink::internal::CreateHpkePublicKey;
37 using ::crypto::tink::internal::CreateHpkeTestParams;
38 using ::crypto::tink::internal::DefaultHpkeTestParams;
39 using ::crypto::tink::internal::HpkeTestParams;
40 using ::crypto::tink::test::IsOk;
41 using ::crypto::tink::test::IsOkAndHolds;
42 using ::crypto::tink::test::StatusIs;
43 using ::google::crypto::tink::HpkeAead;
44 using ::google::crypto::tink::HpkeKdf;
45 using ::google::crypto::tink::HpkeKem;
46 using ::google::crypto::tink::HpkeParams;
47 using ::google::crypto::tink::HpkePublicKey;
48 using ::testing::SizeIs;
49 using ::testing::Values;
50 
51 constexpr int kTagLength = 16;  // Tag length (in bytes) for GCM and Poly1305.
52 
53 class HpkeEncryptTest : public testing::TestWithParam<HpkeParams> {};
54 
55 INSTANTIATE_TEST_SUITE_P(
56     HpkeEncryptionTestSuite, HpkeEncryptTest,
57     Values(CreateHpkeParams(HpkeKem::DHKEM_X25519_HKDF_SHA256,
58                             HpkeKdf::HKDF_SHA256, HpkeAead::AES_128_GCM),
59            CreateHpkeParams(HpkeKem::DHKEM_X25519_HKDF_SHA256,
60                             HpkeKdf::HKDF_SHA256, HpkeAead::CHACHA20_POLY1305),
61            CreateHpkeParams(HpkeKem::DHKEM_X25519_HKDF_SHA256,
62                             HpkeKdf::HKDF_SHA256, HpkeAead::AES_256_GCM)));
63 
TEST_P(HpkeEncryptTest,SetupSenderContextAndEncrypt)64 TEST_P(HpkeEncryptTest, SetupSenderContextAndEncrypt) {
65   HpkeParams hpke_params = GetParam();
66   util::StatusOr<uint32_t> encapsulated_key_length =
67       internal::HpkeEncapsulatedKeyLength(hpke_params.kem());
68   ASSERT_THAT(encapsulated_key_length, IsOk());
69 
70   util::StatusOr<HpkeTestParams> params = CreateHpkeTestParams(hpke_params);
71   ASSERT_THAT(params, IsOk());
72   HpkePublicKey recipient_key =
73       CreateHpkePublicKey(hpke_params, params->recipient_public_key);
74   util::StatusOr<std::unique_ptr<HybridEncrypt>> hpke_encrypt =
75       HpkeEncrypt::New(recipient_key);
76   ASSERT_THAT(hpke_encrypt, IsOk());
77 
78   std::vector<std::string> plaintexts = {"", params->plaintext};
79   std::vector<std::string> context_infos = {"", params->application_info};
80   for (const std::string& plaintext : plaintexts) {
81     for (const std::string& context_info : context_infos) {
82       SCOPED_TRACE(absl::StrCat("plaintext: '", plaintext, "', context_info: '",
83                                 context_info, "'"));
84       int expected_ciphertext_length =
85           *encapsulated_key_length + plaintext.size() + kTagLength;
86       util::StatusOr<std::string> encryption_result =
87           (*hpke_encrypt)->Encrypt(plaintext, context_info);
88       EXPECT_THAT(encryption_result,
89                   IsOkAndHolds(SizeIs(expected_ciphertext_length)));
90     }
91   }
92 }
93 
94 class HpkeEncryptWithBadParamTest : public testing::TestWithParam<HpkeParams> {
95 };
96 
97 INSTANTIATE_TEST_SUITE_P(
98     HpkeEncryptionWithBadParamTestSuite, HpkeEncryptWithBadParamTest,
99     Values(CreateHpkeParams(HpkeKem::KEM_UNKNOWN, HpkeKdf::HKDF_SHA256,
100                             HpkeAead::AES_128_GCM),
101            CreateHpkeParams(HpkeKem::DHKEM_X25519_HKDF_SHA256,
102                             HpkeKdf::KDF_UNKNOWN, HpkeAead::AES_128_GCM),
103            CreateHpkeParams(HpkeKem::DHKEM_X25519_HKDF_SHA256,
104                             HpkeKdf::HKDF_SHA256, HpkeAead::AEAD_UNKNOWN)));
105 
TEST_P(HpkeEncryptWithBadParamTest,BadParamFails)106 TEST_P(HpkeEncryptWithBadParamTest, BadParamFails) {
107   HpkeParams hpke_params = GetParam();
108   HpkeTestParams params = DefaultHpkeTestParams();
109   HpkePublicKey recipient_key =
110       CreateHpkePublicKey(hpke_params, params.recipient_public_key);
111   util::StatusOr<std::unique_ptr<HybridEncrypt>> hpke_encrypt =
112       HpkeEncrypt::New(recipient_key);
113   ASSERT_THAT(hpke_encrypt, IsOk());
114 
115   util::StatusOr<std::string> encryption_result =
116       (*hpke_encrypt)->Encrypt(params.plaintext, params.application_info);
117 
118   EXPECT_THAT(encryption_result.status(),
119               StatusIs(absl::StatusCode::kInvalidArgument));
120 }
121 
TEST(HpkeEncryptWithZeroLengthPublicKey,ZeroLengthPublicKeyFails)122 TEST(HpkeEncryptWithZeroLengthPublicKey, ZeroLengthPublicKeyFails) {
123   HpkeParams hpke_params =
124       CreateHpkeParams(HpkeKem::DHKEM_X25519_HKDF_SHA256, HpkeKdf::HKDF_SHA256,
125                        HpkeAead::AES_128_GCM);
126   HpkeTestParams params = DefaultHpkeTestParams();
127   HpkePublicKey recipient_key =
128       CreateHpkePublicKey(hpke_params, /*raw_key_bytes=*/"");
129 
130   util::StatusOr<std::unique_ptr<HybridEncrypt>> hpke_encrypt =
131       HpkeEncrypt::New(recipient_key);
132 
133   EXPECT_THAT(hpke_encrypt.status(),
134               StatusIs(absl::StatusCode::kInvalidArgument));
135 }
136 
137 }  // namespace
138 }  // namespace tink
139 }  // namespace crypto
140