xref: /aosp_15_r20/external/tink/cc/subtle/ecies_hkdf_recipient_kem_boringssl_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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/ecies_hkdf_recipient_kem_boringssl.h"
18 
19 #include <string>
20 #include <utility>
21 #include <vector>
22 
23 #include "gtest/gtest.h"
24 #include "absl/status/status.h"
25 #include "absl/strings/escaping.h"
26 #include "tink/config/tink_fips.h"
27 #include "tink/subtle/common_enums.h"
28 #include "tink/util/secret_data.h"
29 #include "tink/util/status.h"
30 #include "tink/util/statusor.h"
31 #include "tink/util/test_matchers.h"
32 
33 namespace crypto {
34 namespace tink {
35 namespace subtle {
36 namespace {
37 
38 using ::crypto::tink::test::StatusIs;
39 
40 class EciesHkdfRecipientKemBoringSslTest : public ::testing::Test {};
41 
42 struct TestVector {
43   EllipticCurveType curve;
44   HashType hash;
45   EcPointFormat point_format;
46   std::string pub_encoded_hex;
47   std::string priv_hex;
48   std::string salt_hex;
49   std::string info_hex;
50   int out_len;
51   std::string out_key_hex;
52 };
53 
54 static const char kSaltHex[] = "0b0b0b0b";
55 static const char kInfoHex[] = "0b0b0b0b0b0b0b0b";
56 
57 static const char kNistP256PublicValueHex[] =
58     "04700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287db71e509"
59     "e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac";
60 static const char kNistP256PrivateKeyHex[] =
61     "7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534";
62 static const char kNistP256SharedKeyHex[] =
63     "0f19c0f322fc0a4b73b32bac6a66baa274de261db38a57f11ee4896ede24dbba";
64 
65 static const char kX25519PublicValueHex[] =
66     "bef00c1a15e0601678ef4899a8506f751cd0c1f4d210a2852ac9d42151d0e160";
67 static const char kX25519PrivateKeyHex[] =
68     "df4320cecfd87a5a928355241c9d0e491be499cedf7b2b70687193124039eb92";
69 static const char kX25519SharedKeyHex[] =
70     "4c77c4d086e2d267052bad906f8c00092f8ea944fc1dc69eb2fe8bb29df400cc";
71 
72 static const std::vector<TestVector> test_vector(
73     {{EllipticCurveType::NIST_P256, HashType::SHA256,
74       EcPointFormat::UNCOMPRESSED, kNistP256PublicValueHex,
75       kNistP256PrivateKeyHex, kSaltHex, kInfoHex, 32, kNistP256SharedKeyHex},
76      {EllipticCurveType::CURVE25519, HashType::SHA256,
77       EcPointFormat::COMPRESSED, kX25519PublicValueHex, kX25519PrivateKeyHex,
78       kSaltHex, kInfoHex, 32, kX25519SharedKeyHex}});
79 
TEST_F(EciesHkdfRecipientKemBoringSslTest,TestBasic)80 TEST_F(EciesHkdfRecipientKemBoringSslTest, TestBasic) {
81   if (IsFipsModeEnabled()) {
82     GTEST_SKIP() << "Not supported in FIPS-only mode";
83   }
84   for (const TestVector& test : test_vector) {
85     auto ecies_kem_or = EciesHkdfRecipientKemBoringSsl::New(
86         test.curve,
87         util::SecretDataFromStringView(absl::HexStringToBytes(test.priv_hex)));
88     ASSERT_TRUE(ecies_kem_or.ok());
89     auto ecies_kem = std::move(ecies_kem_or).value();
90     auto kem_key_or = ecies_kem->GenerateKey(
91         absl::HexStringToBytes(test.pub_encoded_hex), test.hash,
92         absl::HexStringToBytes(test.salt_hex),
93         absl::HexStringToBytes(test.info_hex), test.out_len, test.point_format);
94     ASSERT_TRUE(kem_key_or.ok());
95     EXPECT_EQ(test.out_key_hex,
96               absl::BytesToHexString(
97                   util::SecretDataAsStringView(kem_key_or.value())));
98   }
99 }
100 
TEST_F(EciesHkdfRecipientKemBoringSslTest,TestNewUnimplementedCurve)101 TEST_F(EciesHkdfRecipientKemBoringSslTest, TestNewUnimplementedCurve) {
102   if (IsFipsModeEnabled()) {
103     GTEST_SKIP() << "Not supported in FIPS-only mode";
104   }
105   auto status_or_recipient_kem =
106       EciesHkdfRecipientKemBoringSsl::New(EllipticCurveType::UNKNOWN_CURVE, {});
107   EXPECT_EQ(status_or_recipient_kem.status().code(),
108             absl::StatusCode::kUnimplemented);
109 }
110 
111 class EciesHkdfNistPCurveRecipientKemBoringSslTest : public ::testing::Test {};
112 
TEST_F(EciesHkdfNistPCurveRecipientKemBoringSslTest,TestNew)113 TEST_F(EciesHkdfNistPCurveRecipientKemBoringSslTest, TestNew) {
114   if (IsFipsModeEnabled()) {
115     GTEST_SKIP() << "Not supported in FIPS-only mode";
116   }
117   auto status_or_recipient_kem = EciesHkdfNistPCurveRecipientKemBoringSsl::New(
118       EllipticCurveType::NIST_P256,
119       util::SecretDataFromStringView(
120           absl::HexStringToBytes(kNistP256PrivateKeyHex)));
121   ASSERT_TRUE(status_or_recipient_kem.ok());
122 }
123 
TEST_F(EciesHkdfNistPCurveRecipientKemBoringSslTest,TestNewInvalidCurve)124 TEST_F(EciesHkdfNistPCurveRecipientKemBoringSslTest, TestNewInvalidCurve) {
125   if (IsFipsModeEnabled()) {
126     GTEST_SKIP() << "Not supported in FIPS-only mode";
127   }
128   auto status_or_recipient_kem = EciesHkdfNistPCurveRecipientKemBoringSsl::New(
129       EllipticCurveType::CURVE25519,
130       util::SecretDataFromStringView(
131           absl::HexStringToBytes(kNistP256PrivateKeyHex)));
132   EXPECT_EQ(status_or_recipient_kem.status().code(),
133             absl::StatusCode::kUnimplemented);
134 }
135 
TEST_F(EciesHkdfNistPCurveRecipientKemBoringSslTest,TestNewEmptyPrivateKey)136 TEST_F(EciesHkdfNistPCurveRecipientKemBoringSslTest, TestNewEmptyPrivateKey) {
137   if (IsFipsModeEnabled()) {
138     GTEST_SKIP() << "Not supported in FIPS-only mode";
139   }
140   auto status_or_recipient_kem = EciesHkdfNistPCurveRecipientKemBoringSsl::New(
141       EllipticCurveType::CURVE25519, {});
142   EXPECT_EQ(status_or_recipient_kem.status().code(),
143             absl::StatusCode::kInvalidArgument);
144 }
145 
TEST_F(EciesHkdfNistPCurveRecipientKemBoringSslTest,TestGenerateKey)146 TEST_F(EciesHkdfNistPCurveRecipientKemBoringSslTest, TestGenerateKey) {
147   if (IsFipsModeEnabled()) {
148     GTEST_SKIP() << "Not supported in FIPS-only mode";
149   }
150   auto status_or_recipient_kem = EciesHkdfNistPCurveRecipientKemBoringSsl::New(
151       EllipticCurveType::NIST_P256,
152       util::SecretDataFromStringView(
153           absl::HexStringToBytes(kNistP256PrivateKeyHex)));
154   ASSERT_TRUE(status_or_recipient_kem.ok());
155   auto recipient_kem = std::move(status_or_recipient_kem.value());
156 
157   auto status_or_shared_key = recipient_kem->GenerateKey(
158       absl::HexStringToBytes(kNistP256PublicValueHex), HashType::SHA256,
159       absl::HexStringToBytes(kSaltHex), absl::HexStringToBytes(kInfoHex), 32,
160       EcPointFormat::UNCOMPRESSED);
161   ASSERT_TRUE(status_or_shared_key.ok());
162 
163   EXPECT_EQ(absl::BytesToHexString(
164                 util::SecretDataAsStringView(status_or_shared_key.value())),
165             kNistP256SharedKeyHex);
166 }
167 
168 class EciesHkdfX25519RecipientKemBoringSslTest : public ::testing::Test {};
169 
TEST_F(EciesHkdfX25519RecipientKemBoringSslTest,TestNew)170 TEST_F(EciesHkdfX25519RecipientKemBoringSslTest, TestNew) {
171   if (IsFipsModeEnabled()) {
172     GTEST_SKIP() << "Not supported in FIPS-only mode";
173   }
174   auto status_or_recipient_kem = EciesHkdfX25519RecipientKemBoringSsl::New(
175       EllipticCurveType::CURVE25519,
176       util::SecretDataFromStringView(
177           absl::HexStringToBytes(kX25519PrivateKeyHex)));
178   ASSERT_TRUE(status_or_recipient_kem.ok());
179 }
180 
TEST_F(EciesHkdfX25519RecipientKemBoringSslTest,TestNewInvalidCurve)181 TEST_F(EciesHkdfX25519RecipientKemBoringSslTest, TestNewInvalidCurve) {
182   if (IsFipsModeEnabled()) {
183     GTEST_SKIP() << "Not supported in FIPS-only mode";
184   }
185   auto status_or_recipient_kem = EciesHkdfX25519RecipientKemBoringSsl::New(
186       EllipticCurveType::NIST_P256,
187       util::SecretDataFromStringView(
188           absl::HexStringToBytes(kX25519PrivateKeyHex)));
189   EXPECT_EQ(status_or_recipient_kem.status().code(),
190             absl::StatusCode::kInvalidArgument);
191 }
192 
TEST_F(EciesHkdfX25519RecipientKemBoringSslTest,TestNewShortKey)193 TEST_F(EciesHkdfX25519RecipientKemBoringSslTest, TestNewShortKey) {
194   if (IsFipsModeEnabled()) {
195     GTEST_SKIP() << "Not supported in FIPS-only mode";
196   }
197   util::SecretData private_key = util::SecretDataFromStringView(
198       absl::HexStringToBytes(kX25519PrivateKeyHex));
199   private_key.resize(private_key.size() / 2);
200   auto status_or_recipient_kem = EciesHkdfX25519RecipientKemBoringSsl::New(
201       EllipticCurveType::CURVE25519, private_key);
202   EXPECT_EQ(status_or_recipient_kem.status().code(),
203             absl::StatusCode::kInvalidArgument);
204 }
205 
206 // Tests for FIPS only mode
TEST_F(EciesHkdfNistPCurveRecipientKemBoringSslTest,TestFipsOnly)207 TEST_F(EciesHkdfNistPCurveRecipientKemBoringSslTest, TestFipsOnly) {
208   if (!IsFipsModeEnabled()) {
209     GTEST_SKIP() << "Only supported in FIPS-only mode";
210   }
211   util::SecretData private_key = util::SecretDataFromStringView(
212       absl::HexStringToBytes(kNistP256PrivateKeyHex));
213   EXPECT_THAT(EciesHkdfRecipientKemBoringSsl::New(EllipticCurveType::NIST_P256,
214                                                   private_key)
215                   .status(),
216               StatusIs(absl::StatusCode::kInternal));
217 }
218 
TEST_F(EciesHkdfX25519RecipientKemBoringSslTest,TestFipsOnly)219 TEST_F(EciesHkdfX25519RecipientKemBoringSslTest, TestFipsOnly) {
220   if (!IsFipsModeEnabled()) {
221     GTEST_SKIP() << "Only supported in FIPS-only mode";
222   }
223   util::SecretData private_key = util::SecretDataFromStringView(
224       absl::HexStringToBytes(kX25519PrivateKeyHex));
225   EXPECT_THAT(EciesHkdfX25519RecipientKemBoringSsl::New(
226                   EllipticCurveType::CURVE25519, private_key)
227                   .status(),
228               StatusIs(absl::StatusCode::kInternal));
229 }
230 
231 }  // namespace
232 }  // namespace subtle
233 }  // namespace tink
234 }  // namespace crypto
235