1*e7b1675dSTing-Kang Chang // Copyright 2017 Google Inc.
2*e7b1675dSTing-Kang Chang //
3*e7b1675dSTing-Kang Chang // Licensed under the Apache License, Version 2.0 (the "License");
4*e7b1675dSTing-Kang Chang // you may not use this file except in compliance with the License.
5*e7b1675dSTing-Kang Chang // You may obtain a copy of the License at
6*e7b1675dSTing-Kang Chang //
7*e7b1675dSTing-Kang Chang // http://www.apache.org/licenses/LICENSE-2.0
8*e7b1675dSTing-Kang Chang //
9*e7b1675dSTing-Kang Chang // Unless required by applicable law or agreed to in writing, software
10*e7b1675dSTing-Kang Chang // distributed under the License is distributed on an "AS IS" BASIS,
11*e7b1675dSTing-Kang Chang // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*e7b1675dSTing-Kang Chang // See the License for the specific language governing permissions and
13*e7b1675dSTing-Kang Chang // limitations under the License.
14*e7b1675dSTing-Kang Chang //
15*e7b1675dSTing-Kang Chang ///////////////////////////////////////////////////////////////////////////////
16*e7b1675dSTing-Kang Chang
17*e7b1675dSTing-Kang Chang #include "tink/util/test_util.h"
18*e7b1675dSTing-Kang Chang
19*e7b1675dSTing-Kang Chang #include <stdarg.h>
20*e7b1675dSTing-Kang Chang #include <stdlib.h>
21*e7b1675dSTing-Kang Chang
22*e7b1675dSTing-Kang Chang #include <cmath>
23*e7b1675dSTing-Kang Chang #include <cstdint>
24*e7b1675dSTing-Kang Chang #include <cstdlib>
25*e7b1675dSTing-Kang Chang #include <fstream>
26*e7b1675dSTing-Kang Chang #include <ios>
27*e7b1675dSTing-Kang Chang #include <iostream>
28*e7b1675dSTing-Kang Chang #include <memory>
29*e7b1675dSTing-Kang Chang #include <ostream>
30*e7b1675dSTing-Kang Chang #include <sstream>
31*e7b1675dSTing-Kang Chang #include <string>
32*e7b1675dSTing-Kang Chang #include <vector>
33*e7b1675dSTing-Kang Chang
34*e7b1675dSTing-Kang Chang #include "absl/memory/memory.h"
35*e7b1675dSTing-Kang Chang #include "absl/status/status.h"
36*e7b1675dSTing-Kang Chang #include "absl/strings/str_cat.h"
37*e7b1675dSTing-Kang Chang #include "absl/strings/str_join.h"
38*e7b1675dSTing-Kang Chang #include "tink/aead/aes_ctr_hmac_aead_key_manager.h"
39*e7b1675dSTing-Kang Chang #include "tink/aead/aes_gcm_key_manager.h"
40*e7b1675dSTing-Kang Chang #include "tink/aead/xchacha20_poly1305_key_manager.h"
41*e7b1675dSTing-Kang Chang #include "tink/cleartext_keyset_handle.h"
42*e7b1675dSTing-Kang Chang #include "tink/daead/aes_siv_key_manager.h"
43*e7b1675dSTing-Kang Chang #include "tink/internal/ec_util.h"
44*e7b1675dSTing-Kang Chang #include "tink/keyset_handle.h"
45*e7b1675dSTing-Kang Chang #include "tink/subtle/common_enums.h"
46*e7b1675dSTing-Kang Chang #include "tink/subtle/random.h"
47*e7b1675dSTing-Kang Chang #include "tink/util/enums.h"
48*e7b1675dSTing-Kang Chang #include "tink/util/protobuf_helper.h"
49*e7b1675dSTing-Kang Chang #include "tink/util/secret_data.h"
50*e7b1675dSTing-Kang Chang #include "tink/util/status.h"
51*e7b1675dSTing-Kang Chang #include "tink/util/statusor.h"
52*e7b1675dSTing-Kang Chang #include "proto/aes_ctr.pb.h"
53*e7b1675dSTing-Kang Chang #include "proto/aes_ctr_hmac_aead.pb.h"
54*e7b1675dSTing-Kang Chang #include "proto/aes_siv.pb.h"
55*e7b1675dSTing-Kang Chang #include "proto/common.pb.h"
56*e7b1675dSTing-Kang Chang #include "proto/ecdsa.pb.h"
57*e7b1675dSTing-Kang Chang #include "proto/ecies_aead_hkdf.pb.h"
58*e7b1675dSTing-Kang Chang #include "proto/ed25519.pb.h"
59*e7b1675dSTing-Kang Chang #include "proto/hmac.pb.h"
60*e7b1675dSTing-Kang Chang #include "proto/tink.pb.h"
61*e7b1675dSTing-Kang Chang #include "proto/xchacha20_poly1305.pb.h"
62*e7b1675dSTing-Kang Chang
63*e7b1675dSTing-Kang Chang using crypto::tink::util::Enums;
64*e7b1675dSTing-Kang Chang using crypto::tink::util::Status;
65*e7b1675dSTing-Kang Chang using google::crypto::tink::AesGcmKeyFormat;
66*e7b1675dSTing-Kang Chang using google::crypto::tink::EcdsaPrivateKey;
67*e7b1675dSTing-Kang Chang using google::crypto::tink::EciesAeadHkdfPrivateKey;
68*e7b1675dSTing-Kang Chang using google::crypto::tink::Ed25519PrivateKey;
69*e7b1675dSTing-Kang Chang using google::crypto::tink::Keyset;
70*e7b1675dSTing-Kang Chang using google::crypto::tink::OutputPrefixType;
71*e7b1675dSTing-Kang Chang
72*e7b1675dSTing-Kang Chang namespace crypto {
73*e7b1675dSTing-Kang Chang namespace tink {
74*e7b1675dSTing-Kang Chang namespace test {
75*e7b1675dSTing-Kang Chang
ReadTestFile(absl::string_view filename)76*e7b1675dSTing-Kang Chang std::string ReadTestFile(absl::string_view filename) {
77*e7b1675dSTing-Kang Chang std::string full_filename = absl::StrCat(test::TmpDir(), "/", filename);
78*e7b1675dSTing-Kang Chang std::ifstream input_stream(full_filename, std::ios::binary);
79*e7b1675dSTing-Kang Chang if (!input_stream) {
80*e7b1675dSTing-Kang Chang std::clog << "Cannot open file " << full_filename << std::endl;
81*e7b1675dSTing-Kang Chang exit(1);
82*e7b1675dSTing-Kang Chang }
83*e7b1675dSTing-Kang Chang std::stringstream buffer;
84*e7b1675dSTing-Kang Chang buffer << input_stream.rdbuf();
85*e7b1675dSTing-Kang Chang return buffer.str();
86*e7b1675dSTing-Kang Chang }
87*e7b1675dSTing-Kang Chang
HexDecode(absl::string_view hex)88*e7b1675dSTing-Kang Chang util::StatusOr<std::string> HexDecode(absl::string_view hex) {
89*e7b1675dSTing-Kang Chang if (hex.size() % 2 != 0) {
90*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
91*e7b1675dSTing-Kang Chang "Input has odd size.");
92*e7b1675dSTing-Kang Chang }
93*e7b1675dSTing-Kang Chang std::string decoded(hex.size() / 2, static_cast<char>(0));
94*e7b1675dSTing-Kang Chang for (size_t i = 0; i < hex.size(); ++i) {
95*e7b1675dSTing-Kang Chang char c = hex[i];
96*e7b1675dSTing-Kang Chang char val;
97*e7b1675dSTing-Kang Chang if ('0' <= c && c <= '9')
98*e7b1675dSTing-Kang Chang val = c - '0';
99*e7b1675dSTing-Kang Chang else if ('a' <= c && c <= 'f')
100*e7b1675dSTing-Kang Chang val = c - 'a' + 10;
101*e7b1675dSTing-Kang Chang else if ('A' <= c && c <= 'F')
102*e7b1675dSTing-Kang Chang val = c - 'A' + 10;
103*e7b1675dSTing-Kang Chang else
104*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
105*e7b1675dSTing-Kang Chang "Not hexadecimal");
106*e7b1675dSTing-Kang Chang decoded[i / 2] = (decoded[i / 2] << 4) | val;
107*e7b1675dSTing-Kang Chang }
108*e7b1675dSTing-Kang Chang return decoded;
109*e7b1675dSTing-Kang Chang }
110*e7b1675dSTing-Kang Chang
HexDecodeOrDie(absl::string_view hex)111*e7b1675dSTing-Kang Chang std::string HexDecodeOrDie(absl::string_view hex) {
112*e7b1675dSTing-Kang Chang return HexDecode(hex).value();
113*e7b1675dSTing-Kang Chang }
114*e7b1675dSTing-Kang Chang
HexEncode(absl::string_view bytes)115*e7b1675dSTing-Kang Chang std::string HexEncode(absl::string_view bytes) {
116*e7b1675dSTing-Kang Chang std::string hexchars = "0123456789abcdef";
117*e7b1675dSTing-Kang Chang std::string res(bytes.size() * 2, static_cast<char>(255));
118*e7b1675dSTing-Kang Chang for (size_t i = 0; i < bytes.size(); ++i) {
119*e7b1675dSTing-Kang Chang uint8_t c = static_cast<uint8_t>(bytes[i]);
120*e7b1675dSTing-Kang Chang res[2 * i] = hexchars[c / 16];
121*e7b1675dSTing-Kang Chang res[2 * i + 1] = hexchars[c % 16];
122*e7b1675dSTing-Kang Chang }
123*e7b1675dSTing-Kang Chang return res;
124*e7b1675dSTing-Kang Chang }
125*e7b1675dSTing-Kang Chang
TmpDir()126*e7b1675dSTing-Kang Chang std::string TmpDir() {
127*e7b1675dSTing-Kang Chang // Try the following environment variables in order:
128*e7b1675dSTing-Kang Chang // - TEST_TMPDIR: Set by `bazel test`.
129*e7b1675dSTing-Kang Chang // - TMPDIR: Set by some Tink tests.
130*e7b1675dSTing-Kang Chang // - TEMP, TMP: Set on Windows; they contain the tmp dir's path.
131*e7b1675dSTing-Kang Chang for (const std::string& tmp_env_variable :
132*e7b1675dSTing-Kang Chang {"TEST_TMPDIR", "TMPDIR", "TEMP", "TMP"}) {
133*e7b1675dSTing-Kang Chang const char* env = getenv(tmp_env_variable.c_str());
134*e7b1675dSTing-Kang Chang if (env && env[0] != '\0') {
135*e7b1675dSTing-Kang Chang return env;
136*e7b1675dSTing-Kang Chang }
137*e7b1675dSTing-Kang Chang }
138*e7b1675dSTing-Kang Chang // Tmp dir on Linux/macOS.
139*e7b1675dSTing-Kang Chang return "/tmp";
140*e7b1675dSTing-Kang Chang }
141*e7b1675dSTing-Kang Chang
AddKeyData(const google::crypto::tink::KeyData & key_data,uint32_t key_id,google::crypto::tink::OutputPrefixType output_prefix,google::crypto::tink::KeyStatusType key_status,google::crypto::tink::Keyset * keyset)142*e7b1675dSTing-Kang Chang void AddKeyData(const google::crypto::tink::KeyData& key_data, uint32_t key_id,
143*e7b1675dSTing-Kang Chang google::crypto::tink::OutputPrefixType output_prefix,
144*e7b1675dSTing-Kang Chang google::crypto::tink::KeyStatusType key_status,
145*e7b1675dSTing-Kang Chang google::crypto::tink::Keyset* keyset) {
146*e7b1675dSTing-Kang Chang Keyset::Key* key = keyset->add_key();
147*e7b1675dSTing-Kang Chang key->set_output_prefix_type(output_prefix);
148*e7b1675dSTing-Kang Chang key->set_key_id(key_id);
149*e7b1675dSTing-Kang Chang key->set_status(key_status);
150*e7b1675dSTing-Kang Chang *key->mutable_key_data() = key_data;
151*e7b1675dSTing-Kang Chang }
152*e7b1675dSTing-Kang Chang
AddKey(const std::string & key_type,uint32_t key_id,const portable_proto::MessageLite & new_key,google::crypto::tink::OutputPrefixType output_prefix,google::crypto::tink::KeyStatusType key_status,google::crypto::tink::KeyData::KeyMaterialType material_type,google::crypto::tink::Keyset * keyset)153*e7b1675dSTing-Kang Chang void AddKey(const std::string& key_type, uint32_t key_id,
154*e7b1675dSTing-Kang Chang const portable_proto::MessageLite& new_key,
155*e7b1675dSTing-Kang Chang google::crypto::tink::OutputPrefixType output_prefix,
156*e7b1675dSTing-Kang Chang google::crypto::tink::KeyStatusType key_status,
157*e7b1675dSTing-Kang Chang google::crypto::tink::KeyData::KeyMaterialType material_type,
158*e7b1675dSTing-Kang Chang google::crypto::tink::Keyset* keyset) {
159*e7b1675dSTing-Kang Chang google::crypto::tink::KeyData key_data;
160*e7b1675dSTing-Kang Chang key_data.set_type_url(key_type);
161*e7b1675dSTing-Kang Chang key_data.set_key_material_type(material_type);
162*e7b1675dSTing-Kang Chang key_data.set_value(new_key.SerializeAsString());
163*e7b1675dSTing-Kang Chang AddKeyData(key_data, key_id, output_prefix, key_status, keyset);
164*e7b1675dSTing-Kang Chang }
165*e7b1675dSTing-Kang Chang
AddTinkKey(const std::string & key_type,uint32_t key_id,const portable_proto::MessageLite & key,google::crypto::tink::KeyStatusType key_status,google::crypto::tink::KeyData::KeyMaterialType material_type,google::crypto::tink::Keyset * keyset)166*e7b1675dSTing-Kang Chang void AddTinkKey(const std::string& key_type, uint32_t key_id,
167*e7b1675dSTing-Kang Chang const portable_proto::MessageLite& key,
168*e7b1675dSTing-Kang Chang google::crypto::tink::KeyStatusType key_status,
169*e7b1675dSTing-Kang Chang google::crypto::tink::KeyData::KeyMaterialType material_type,
170*e7b1675dSTing-Kang Chang google::crypto::tink::Keyset* keyset) {
171*e7b1675dSTing-Kang Chang AddKey(key_type, key_id, key, OutputPrefixType::TINK,
172*e7b1675dSTing-Kang Chang key_status, material_type, keyset);
173*e7b1675dSTing-Kang Chang }
174*e7b1675dSTing-Kang Chang
AddLegacyKey(const std::string & key_type,uint32_t key_id,const portable_proto::MessageLite & key,google::crypto::tink::KeyStatusType key_status,google::crypto::tink::KeyData::KeyMaterialType material_type,google::crypto::tink::Keyset * keyset)175*e7b1675dSTing-Kang Chang void AddLegacyKey(const std::string& key_type, uint32_t key_id,
176*e7b1675dSTing-Kang Chang const portable_proto::MessageLite& key,
177*e7b1675dSTing-Kang Chang google::crypto::tink::KeyStatusType key_status,
178*e7b1675dSTing-Kang Chang google::crypto::tink::KeyData::KeyMaterialType material_type,
179*e7b1675dSTing-Kang Chang google::crypto::tink::Keyset* keyset) {
180*e7b1675dSTing-Kang Chang AddKey(key_type, key_id, key, OutputPrefixType::LEGACY,
181*e7b1675dSTing-Kang Chang key_status, material_type, keyset);
182*e7b1675dSTing-Kang Chang }
183*e7b1675dSTing-Kang Chang
AddRawKey(const std::string & key_type,uint32_t key_id,const portable_proto::MessageLite & key,google::crypto::tink::KeyStatusType key_status,google::crypto::tink::KeyData::KeyMaterialType material_type,google::crypto::tink::Keyset * keyset)184*e7b1675dSTing-Kang Chang void AddRawKey(const std::string& key_type, uint32_t key_id,
185*e7b1675dSTing-Kang Chang const portable_proto::MessageLite& key,
186*e7b1675dSTing-Kang Chang google::crypto::tink::KeyStatusType key_status,
187*e7b1675dSTing-Kang Chang google::crypto::tink::KeyData::KeyMaterialType material_type,
188*e7b1675dSTing-Kang Chang google::crypto::tink::Keyset* keyset) {
189*e7b1675dSTing-Kang Chang AddKey(key_type, key_id, key, OutputPrefixType::RAW,
190*e7b1675dSTing-Kang Chang key_status, material_type, keyset);
191*e7b1675dSTing-Kang Chang }
192*e7b1675dSTing-Kang Chang
GetEciesAesGcmHkdfTestKey(subtle::EllipticCurveType curve_type,subtle::EcPointFormat ec_point_format,subtle::HashType hash_type,uint32_t aes_gcm_key_size)193*e7b1675dSTing-Kang Chang EciesAeadHkdfPrivateKey GetEciesAesGcmHkdfTestKey(
194*e7b1675dSTing-Kang Chang subtle::EllipticCurveType curve_type,
195*e7b1675dSTing-Kang Chang subtle::EcPointFormat ec_point_format,
196*e7b1675dSTing-Kang Chang subtle::HashType hash_type,
197*e7b1675dSTing-Kang Chang uint32_t aes_gcm_key_size) {
198*e7b1675dSTing-Kang Chang return GetEciesAesGcmHkdfTestKey(
199*e7b1675dSTing-Kang Chang Enums::SubtleToProto(curve_type),
200*e7b1675dSTing-Kang Chang Enums::SubtleToProto(ec_point_format),
201*e7b1675dSTing-Kang Chang Enums::SubtleToProto(hash_type),
202*e7b1675dSTing-Kang Chang aes_gcm_key_size);
203*e7b1675dSTing-Kang Chang }
204*e7b1675dSTing-Kang Chang
GetEciesAeadHkdfTestKey(google::crypto::tink::EllipticCurveType curve_type,google::crypto::tink::EcPointFormat ec_point_format,google::crypto::tink::HashType hash_type)205*e7b1675dSTing-Kang Chang EciesAeadHkdfPrivateKey GetEciesAeadHkdfTestKey(
206*e7b1675dSTing-Kang Chang google::crypto::tink::EllipticCurveType curve_type,
207*e7b1675dSTing-Kang Chang google::crypto::tink::EcPointFormat ec_point_format,
208*e7b1675dSTing-Kang Chang google::crypto::tink::HashType hash_type) {
209*e7b1675dSTing-Kang Chang auto test_key = internal::NewEcKey(Enums::ProtoToSubtle(curve_type)).value();
210*e7b1675dSTing-Kang Chang EciesAeadHkdfPrivateKey ecies_key;
211*e7b1675dSTing-Kang Chang ecies_key.set_version(0);
212*e7b1675dSTing-Kang Chang ecies_key.set_key_value(
213*e7b1675dSTing-Kang Chang std::string(util::SecretDataAsStringView(test_key.priv)));
214*e7b1675dSTing-Kang Chang auto public_key = ecies_key.mutable_public_key();
215*e7b1675dSTing-Kang Chang public_key->set_version(0);
216*e7b1675dSTing-Kang Chang public_key->set_x(test_key.pub_x);
217*e7b1675dSTing-Kang Chang public_key->set_y(test_key.pub_y);
218*e7b1675dSTing-Kang Chang auto params = public_key->mutable_params();
219*e7b1675dSTing-Kang Chang params->set_ec_point_format(ec_point_format);
220*e7b1675dSTing-Kang Chang params->mutable_kem_params()->set_curve_type(curve_type);
221*e7b1675dSTing-Kang Chang params->mutable_kem_params()->set_hkdf_hash_type(hash_type);
222*e7b1675dSTing-Kang Chang
223*e7b1675dSTing-Kang Chang return ecies_key;
224*e7b1675dSTing-Kang Chang }
225*e7b1675dSTing-Kang Chang
GetEciesAesGcmHkdfTestKey(google::crypto::tink::EllipticCurveType curve_type,google::crypto::tink::EcPointFormat ec_point_format,google::crypto::tink::HashType hash_type,uint32_t aes_gcm_key_size)226*e7b1675dSTing-Kang Chang EciesAeadHkdfPrivateKey GetEciesAesGcmHkdfTestKey(
227*e7b1675dSTing-Kang Chang google::crypto::tink::EllipticCurveType curve_type,
228*e7b1675dSTing-Kang Chang google::crypto::tink::EcPointFormat ec_point_format,
229*e7b1675dSTing-Kang Chang google::crypto::tink::HashType hash_type, uint32_t aes_gcm_key_size) {
230*e7b1675dSTing-Kang Chang auto ecies_key =
231*e7b1675dSTing-Kang Chang GetEciesAeadHkdfTestKey(curve_type, ec_point_format, hash_type);
232*e7b1675dSTing-Kang Chang auto params = ecies_key.mutable_public_key()->mutable_params();
233*e7b1675dSTing-Kang Chang
234*e7b1675dSTing-Kang Chang AesGcmKeyFormat key_format;
235*e7b1675dSTing-Kang Chang key_format.set_key_size(aes_gcm_key_size);
236*e7b1675dSTing-Kang Chang auto aead_dem = params->mutable_dem_params()->mutable_aead_dem();
237*e7b1675dSTing-Kang Chang std::unique_ptr<AesGcmKeyManager> key_manager(new AesGcmKeyManager());
238*e7b1675dSTing-Kang Chang std::string dem_key_type = key_manager->get_key_type();
239*e7b1675dSTing-Kang Chang aead_dem->set_type_url(dem_key_type);
240*e7b1675dSTing-Kang Chang aead_dem->set_value(key_format.SerializeAsString());
241*e7b1675dSTing-Kang Chang return ecies_key;
242*e7b1675dSTing-Kang Chang }
243*e7b1675dSTing-Kang Chang
GetEciesAesCtrHmacHkdfTestKey(google::crypto::tink::EllipticCurveType curve_type,google::crypto::tink::EcPointFormat ec_point_format,google::crypto::tink::HashType hash_type,uint32_t aes_ctr_key_size,uint32_t aes_ctr_iv_size,google::crypto::tink::HashType hmac_hash_type,uint32_t hmac_tag_size,uint32_t hmac_key_size)244*e7b1675dSTing-Kang Chang EciesAeadHkdfPrivateKey GetEciesAesCtrHmacHkdfTestKey(
245*e7b1675dSTing-Kang Chang google::crypto::tink::EllipticCurveType curve_type,
246*e7b1675dSTing-Kang Chang google::crypto::tink::EcPointFormat ec_point_format,
247*e7b1675dSTing-Kang Chang google::crypto::tink::HashType hash_type, uint32_t aes_ctr_key_size,
248*e7b1675dSTing-Kang Chang uint32_t aes_ctr_iv_size, google::crypto::tink::HashType hmac_hash_type,
249*e7b1675dSTing-Kang Chang uint32_t hmac_tag_size, uint32_t hmac_key_size) {
250*e7b1675dSTing-Kang Chang auto ecies_key =
251*e7b1675dSTing-Kang Chang GetEciesAeadHkdfTestKey(curve_type, ec_point_format, hash_type);
252*e7b1675dSTing-Kang Chang
253*e7b1675dSTing-Kang Chang google::crypto::tink::AesCtrHmacAeadKeyFormat key_format;
254*e7b1675dSTing-Kang Chang auto aes_ctr_key_format = key_format.mutable_aes_ctr_key_format();
255*e7b1675dSTing-Kang Chang auto aes_ctr_params = aes_ctr_key_format->mutable_params();
256*e7b1675dSTing-Kang Chang aes_ctr_params->set_iv_size(aes_ctr_iv_size);
257*e7b1675dSTing-Kang Chang aes_ctr_key_format->set_key_size(aes_ctr_key_size);
258*e7b1675dSTing-Kang Chang
259*e7b1675dSTing-Kang Chang auto hmac_key_format = key_format.mutable_hmac_key_format();
260*e7b1675dSTing-Kang Chang auto hmac_params = hmac_key_format->mutable_params();
261*e7b1675dSTing-Kang Chang hmac_params->set_hash(hmac_hash_type);
262*e7b1675dSTing-Kang Chang hmac_params->set_tag_size(hmac_tag_size);
263*e7b1675dSTing-Kang Chang hmac_key_format->set_key_size(hmac_key_size);
264*e7b1675dSTing-Kang Chang
265*e7b1675dSTing-Kang Chang auto params = ecies_key.mutable_public_key()->mutable_params();
266*e7b1675dSTing-Kang Chang auto aead_dem = params->mutable_dem_params()->mutable_aead_dem();
267*e7b1675dSTing-Kang Chang
268*e7b1675dSTing-Kang Chang std::unique_ptr<AesCtrHmacAeadKeyManager> key_manager(
269*e7b1675dSTing-Kang Chang new AesCtrHmacAeadKeyManager());
270*e7b1675dSTing-Kang Chang std::string dem_key_type = key_manager->get_key_type();
271*e7b1675dSTing-Kang Chang aead_dem->set_type_url(dem_key_type);
272*e7b1675dSTing-Kang Chang aead_dem->set_value(key_format.SerializeAsString());
273*e7b1675dSTing-Kang Chang return ecies_key;
274*e7b1675dSTing-Kang Chang }
275*e7b1675dSTing-Kang Chang
GetEciesXChaCha20Poly1305HkdfTestKey(google::crypto::tink::EllipticCurveType curve_type,google::crypto::tink::EcPointFormat ec_point_format,google::crypto::tink::HashType hash_type)276*e7b1675dSTing-Kang Chang EciesAeadHkdfPrivateKey GetEciesXChaCha20Poly1305HkdfTestKey(
277*e7b1675dSTing-Kang Chang google::crypto::tink::EllipticCurveType curve_type,
278*e7b1675dSTing-Kang Chang google::crypto::tink::EcPointFormat ec_point_format,
279*e7b1675dSTing-Kang Chang google::crypto::tink::HashType hash_type) {
280*e7b1675dSTing-Kang Chang auto ecies_key =
281*e7b1675dSTing-Kang Chang GetEciesAeadHkdfTestKey(curve_type, ec_point_format, hash_type);
282*e7b1675dSTing-Kang Chang auto params = ecies_key.mutable_public_key()->mutable_params();
283*e7b1675dSTing-Kang Chang
284*e7b1675dSTing-Kang Chang google::crypto::tink::XChaCha20Poly1305KeyFormat key_format;
285*e7b1675dSTing-Kang Chang auto aead_dem = params->mutable_dem_params()->mutable_aead_dem();
286*e7b1675dSTing-Kang Chang std::unique_ptr<XChaCha20Poly1305KeyManager> key_manager(
287*e7b1675dSTing-Kang Chang new XChaCha20Poly1305KeyManager());
288*e7b1675dSTing-Kang Chang std::string dem_key_type = key_manager->get_key_type();
289*e7b1675dSTing-Kang Chang aead_dem->set_type_url(dem_key_type);
290*e7b1675dSTing-Kang Chang aead_dem->set_value(key_format.SerializeAsString());
291*e7b1675dSTing-Kang Chang return ecies_key;
292*e7b1675dSTing-Kang Chang }
293*e7b1675dSTing-Kang Chang
GetEciesAesSivHkdfTestKey(google::crypto::tink::EllipticCurveType curve_type,google::crypto::tink::EcPointFormat ec_point_format,google::crypto::tink::HashType hash_type)294*e7b1675dSTing-Kang Chang google::crypto::tink::EciesAeadHkdfPrivateKey GetEciesAesSivHkdfTestKey(
295*e7b1675dSTing-Kang Chang google::crypto::tink::EllipticCurveType curve_type,
296*e7b1675dSTing-Kang Chang google::crypto::tink::EcPointFormat ec_point_format,
297*e7b1675dSTing-Kang Chang google::crypto::tink::HashType hash_type) {
298*e7b1675dSTing-Kang Chang auto ecies_key =
299*e7b1675dSTing-Kang Chang GetEciesAeadHkdfTestKey(curve_type, ec_point_format, hash_type);
300*e7b1675dSTing-Kang Chang auto params = ecies_key.mutable_public_key()->mutable_params();
301*e7b1675dSTing-Kang Chang
302*e7b1675dSTing-Kang Chang google::crypto::tink::AesSivKeyFormat key_format;
303*e7b1675dSTing-Kang Chang key_format.set_key_size(64);
304*e7b1675dSTing-Kang Chang auto aead_dem = params->mutable_dem_params()->mutable_aead_dem();
305*e7b1675dSTing-Kang Chang AesSivKeyManager key_manager;
306*e7b1675dSTing-Kang Chang std::string dem_key_type = key_manager.get_key_type();
307*e7b1675dSTing-Kang Chang aead_dem->set_type_url(dem_key_type);
308*e7b1675dSTing-Kang Chang aead_dem->set_value(key_format.SerializeAsString());
309*e7b1675dSTing-Kang Chang return ecies_key;
310*e7b1675dSTing-Kang Chang }
311*e7b1675dSTing-Kang Chang
GetEcdsaTestPrivateKey(subtle::EllipticCurveType curve_type,subtle::HashType hash_type,subtle::EcdsaSignatureEncoding encoding)312*e7b1675dSTing-Kang Chang EcdsaPrivateKey GetEcdsaTestPrivateKey(
313*e7b1675dSTing-Kang Chang subtle::EllipticCurveType curve_type, subtle::HashType hash_type,
314*e7b1675dSTing-Kang Chang subtle::EcdsaSignatureEncoding encoding) {
315*e7b1675dSTing-Kang Chang return GetEcdsaTestPrivateKey(Enums::SubtleToProto(curve_type),
316*e7b1675dSTing-Kang Chang Enums::SubtleToProto(hash_type),
317*e7b1675dSTing-Kang Chang Enums::SubtleToProto(encoding));
318*e7b1675dSTing-Kang Chang }
319*e7b1675dSTing-Kang Chang
GetEcdsaTestPrivateKey(google::crypto::tink::EllipticCurveType curve_type,google::crypto::tink::HashType hash_type,google::crypto::tink::EcdsaSignatureEncoding encoding)320*e7b1675dSTing-Kang Chang EcdsaPrivateKey GetEcdsaTestPrivateKey(
321*e7b1675dSTing-Kang Chang google::crypto::tink::EllipticCurveType curve_type,
322*e7b1675dSTing-Kang Chang google::crypto::tink::HashType hash_type,
323*e7b1675dSTing-Kang Chang google::crypto::tink::EcdsaSignatureEncoding encoding) {
324*e7b1675dSTing-Kang Chang auto test_key = internal::NewEcKey(Enums::ProtoToSubtle(curve_type)).value();
325*e7b1675dSTing-Kang Chang EcdsaPrivateKey ecdsa_key;
326*e7b1675dSTing-Kang Chang ecdsa_key.set_version(0);
327*e7b1675dSTing-Kang Chang ecdsa_key.set_key_value(
328*e7b1675dSTing-Kang Chang std::string(util::SecretDataAsStringView(test_key.priv)));
329*e7b1675dSTing-Kang Chang auto public_key = ecdsa_key.mutable_public_key();
330*e7b1675dSTing-Kang Chang public_key->set_version(0);
331*e7b1675dSTing-Kang Chang public_key->set_x(test_key.pub_x);
332*e7b1675dSTing-Kang Chang public_key->set_y(test_key.pub_y);
333*e7b1675dSTing-Kang Chang auto params = public_key->mutable_params();
334*e7b1675dSTing-Kang Chang params->set_hash_type(hash_type);
335*e7b1675dSTing-Kang Chang params->set_curve(curve_type);
336*e7b1675dSTing-Kang Chang params->set_encoding(encoding);
337*e7b1675dSTing-Kang Chang return ecdsa_key;
338*e7b1675dSTing-Kang Chang }
339*e7b1675dSTing-Kang Chang
GetEd25519TestPrivateKey()340*e7b1675dSTing-Kang Chang Ed25519PrivateKey GetEd25519TestPrivateKey() {
341*e7b1675dSTing-Kang Chang auto test_key = internal::NewEd25519Key().value();
342*e7b1675dSTing-Kang Chang Ed25519PrivateKey ed25519_key;
343*e7b1675dSTing-Kang Chang ed25519_key.set_version(0);
344*e7b1675dSTing-Kang Chang ed25519_key.set_key_value(test_key->private_key);
345*e7b1675dSTing-Kang Chang
346*e7b1675dSTing-Kang Chang auto public_key = ed25519_key.mutable_public_key();
347*e7b1675dSTing-Kang Chang public_key->set_version(0);
348*e7b1675dSTing-Kang Chang public_key->set_key_value(test_key->public_key);
349*e7b1675dSTing-Kang Chang
350*e7b1675dSTing-Kang Chang return ed25519_key;
351*e7b1675dSTing-Kang Chang }
352*e7b1675dSTing-Kang Chang
ZTestUniformString(absl::string_view bytes)353*e7b1675dSTing-Kang Chang util::Status ZTestUniformString(absl::string_view bytes) {
354*e7b1675dSTing-Kang Chang double expected = bytes.size() * 8.0 / 2.0;
355*e7b1675dSTing-Kang Chang double stddev = std::sqrt(static_cast<double>(bytes.size()) * 8.0 / 4.0);
356*e7b1675dSTing-Kang Chang uint64_t num_set_bits = 0;
357*e7b1675dSTing-Kang Chang for (uint8_t byte : bytes) {
358*e7b1675dSTing-Kang Chang // Counting the number of bits set in byte:
359*e7b1675dSTing-Kang Chang while (byte != 0) {
360*e7b1675dSTing-Kang Chang num_set_bits++;
361*e7b1675dSTing-Kang Chang byte = byte & (byte - 1);
362*e7b1675dSTing-Kang Chang }
363*e7b1675dSTing-Kang Chang }
364*e7b1675dSTing-Kang Chang // Check that the number of bits is within 10 stddevs.
365*e7b1675dSTing-Kang Chang if (abs(static_cast<double>(num_set_bits) - expected) < 10.0 * stddev) {
366*e7b1675dSTing-Kang Chang return util::OkStatus();
367*e7b1675dSTing-Kang Chang }
368*e7b1675dSTing-Kang Chang return util::Status(
369*e7b1675dSTing-Kang Chang absl::StatusCode::kInternal,
370*e7b1675dSTing-Kang Chang absl::StrCat("Z test for uniformly distributed variable out of bounds; "
371*e7b1675dSTing-Kang Chang "Actual number of set bits was ",
372*e7b1675dSTing-Kang Chang num_set_bits, " expected was ", expected,
373*e7b1675dSTing-Kang Chang " 10 * standard deviation is 10 * ", stddev, " = ",
374*e7b1675dSTing-Kang Chang 10.0 * stddev));
375*e7b1675dSTing-Kang Chang }
376*e7b1675dSTing-Kang Chang
Rotate(absl::string_view bytes)377*e7b1675dSTing-Kang Chang std::string Rotate(absl::string_view bytes) {
378*e7b1675dSTing-Kang Chang std::string result(bytes.size(), '\0');
379*e7b1675dSTing-Kang Chang for (int i = 0; i < bytes.size(); i++) {
380*e7b1675dSTing-Kang Chang result[i] = (static_cast<uint8_t>(bytes[i]) >> 1) |
381*e7b1675dSTing-Kang Chang (bytes[(i == 0 ? bytes.size() : i) - 1] << 7);
382*e7b1675dSTing-Kang Chang }
383*e7b1675dSTing-Kang Chang return result;
384*e7b1675dSTing-Kang Chang }
385*e7b1675dSTing-Kang Chang
ZTestCrosscorrelationUniformStrings(absl::string_view bytes1,absl::string_view bytes2)386*e7b1675dSTing-Kang Chang util::Status ZTestCrosscorrelationUniformStrings(absl::string_view bytes1,
387*e7b1675dSTing-Kang Chang absl::string_view bytes2) {
388*e7b1675dSTing-Kang Chang if (bytes1.size() != bytes2.size()) {
389*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
390*e7b1675dSTing-Kang Chang "Strings are not of equal length");
391*e7b1675dSTing-Kang Chang }
392*e7b1675dSTing-Kang Chang std::string crossed(bytes1.size(), '\0');
393*e7b1675dSTing-Kang Chang for (int i = 0; i < bytes1.size(); i++) {
394*e7b1675dSTing-Kang Chang crossed[i] = bytes1[i] ^ bytes2[i];
395*e7b1675dSTing-Kang Chang }
396*e7b1675dSTing-Kang Chang return ZTestUniformString(crossed);
397*e7b1675dSTing-Kang Chang }
398*e7b1675dSTing-Kang Chang
ZTestAutocorrelationUniformString(absl::string_view bytes)399*e7b1675dSTing-Kang Chang util::Status ZTestAutocorrelationUniformString(absl::string_view bytes) {
400*e7b1675dSTing-Kang Chang std::string rotated(bytes);
401*e7b1675dSTing-Kang Chang std::vector<int> violations;
402*e7b1675dSTing-Kang Chang for (int i = 1; i < bytes.size() * 8; i++) {
403*e7b1675dSTing-Kang Chang rotated = Rotate(rotated);
404*e7b1675dSTing-Kang Chang auto status = ZTestCrosscorrelationUniformStrings(bytes, rotated);
405*e7b1675dSTing-Kang Chang if (!status.ok()) {
406*e7b1675dSTing-Kang Chang violations.push_back(i);
407*e7b1675dSTing-Kang Chang }
408*e7b1675dSTing-Kang Chang }
409*e7b1675dSTing-Kang Chang if (violations.empty()) {
410*e7b1675dSTing-Kang Chang return util::OkStatus();
411*e7b1675dSTing-Kang Chang }
412*e7b1675dSTing-Kang Chang return util::Status(
413*e7b1675dSTing-Kang Chang absl::StatusCode::kInternal,
414*e7b1675dSTing-Kang Chang absl::StrCat("Autocorrelation exceeded 10 standard deviation at ",
415*e7b1675dSTing-Kang Chang violations.size(),
416*e7b1675dSTing-Kang Chang " indices: ", absl::StrJoin(violations, ", ")));
417*e7b1675dSTing-Kang Chang }
418*e7b1675dSTing-Kang Chang
419*e7b1675dSTing-Kang Chang } // namespace test
420*e7b1675dSTing-Kang Chang } // namespace tink
421*e7b1675dSTing-Kang Chang } // namespace crypto
422