1*e7b1675dSTing-Kang Chang // Copyright 2018 Google LLC
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/subtle/wycheproof_util.h"
18*e7b1675dSTing-Kang Chang
19*e7b1675dSTing-Kang Chang #include <fstream>
20*e7b1675dSTing-Kang Chang #include <iostream>
21*e7b1675dSTing-Kang Chang #include <memory>
22*e7b1675dSTing-Kang Chang #include <ostream>
23*e7b1675dSTing-Kang Chang #include <string>
24*e7b1675dSTing-Kang Chang
25*e7b1675dSTing-Kang Chang #include "absl/status/status.h"
26*e7b1675dSTing-Kang Chang #include "absl/strings/str_cat.h"
27*e7b1675dSTing-Kang Chang #include "absl/strings/string_view.h"
28*e7b1675dSTing-Kang Chang #include "include/rapidjson/document.h"
29*e7b1675dSTing-Kang Chang #include "include/rapidjson/istreamwrapper.h"
30*e7b1675dSTing-Kang Chang #include "tink/internal/test_file_util.h"
31*e7b1675dSTing-Kang Chang #include "tink/subtle/common_enums.h"
32*e7b1675dSTing-Kang Chang #include "tink/util/status.h"
33*e7b1675dSTing-Kang Chang #include "tink/util/statusor.h"
34*e7b1675dSTing-Kang Chang
35*e7b1675dSTing-Kang Chang namespace crypto {
36*e7b1675dSTing-Kang Chang namespace tink {
37*e7b1675dSTing-Kang Chang namespace subtle {
38*e7b1675dSTing-Kang Chang
39*e7b1675dSTing-Kang Chang namespace {
40*e7b1675dSTing-Kang Chang
41*e7b1675dSTing-Kang Chang // TODO(tholenst): factor these helpers out to an "util"-class.
HexDecode(absl::string_view hex)42*e7b1675dSTing-Kang Chang util::StatusOr<std::string> HexDecode(absl::string_view hex) {
43*e7b1675dSTing-Kang Chang if (hex.size() % 2 != 0) {
44*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
45*e7b1675dSTing-Kang Chang "Input has odd size.");
46*e7b1675dSTing-Kang Chang }
47*e7b1675dSTing-Kang Chang std::string decoded(hex.size() / 2, static_cast<char>(0));
48*e7b1675dSTing-Kang Chang for (size_t i = 0; i < hex.size(); ++i) {
49*e7b1675dSTing-Kang Chang char c = hex[i];
50*e7b1675dSTing-Kang Chang char val;
51*e7b1675dSTing-Kang Chang if ('0' <= c && c <= '9')
52*e7b1675dSTing-Kang Chang val = c - '0';
53*e7b1675dSTing-Kang Chang else if ('a' <= c && c <= 'f')
54*e7b1675dSTing-Kang Chang val = c - 'a' + 10;
55*e7b1675dSTing-Kang Chang else if ('A' <= c && c <= 'F')
56*e7b1675dSTing-Kang Chang val = c - 'A' + 10;
57*e7b1675dSTing-Kang Chang else
58*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
59*e7b1675dSTing-Kang Chang "Not hexadecimal");
60*e7b1675dSTing-Kang Chang decoded[i / 2] = (decoded[i / 2] << 4) | val;
61*e7b1675dSTing-Kang Chang }
62*e7b1675dSTing-Kang Chang return decoded;
63*e7b1675dSTing-Kang Chang }
64*e7b1675dSTing-Kang Chang
HexDecodeOrDie(absl::string_view hex)65*e7b1675dSTing-Kang Chang std::string HexDecodeOrDie(absl::string_view hex) {
66*e7b1675dSTing-Kang Chang return HexDecode(hex).value();
67*e7b1675dSTing-Kang Chang }
68*e7b1675dSTing-Kang Chang
69*e7b1675dSTing-Kang Chang } // namespace
70*e7b1675dSTing-Kang Chang
GetBytes(const rapidjson::Value & val)71*e7b1675dSTing-Kang Chang std::string WycheproofUtil::GetBytes(const rapidjson::Value &val) {
72*e7b1675dSTing-Kang Chang std::string s(val.GetString());
73*e7b1675dSTing-Kang Chang if (s.size() % 2 != 0) {
74*e7b1675dSTing-Kang Chang // ECDH private key may have odd length.
75*e7b1675dSTing-Kang Chang s = "0" + s;
76*e7b1675dSTing-Kang Chang }
77*e7b1675dSTing-Kang Chang return HexDecodeOrDie(s);
78*e7b1675dSTing-Kang Chang }
79*e7b1675dSTing-Kang Chang
ReadTestVectors(const std::string & filename)80*e7b1675dSTing-Kang Chang std::unique_ptr<rapidjson::Document> WycheproofUtil::ReadTestVectors(
81*e7b1675dSTing-Kang Chang const std::string &filename) {
82*e7b1675dSTing-Kang Chang std::string test_vectors_path = crypto::tink::internal::RunfilesPath(
83*e7b1675dSTing-Kang Chang absl::StrCat("testvectors/", filename));
84*e7b1675dSTing-Kang Chang std::ifstream input_stream;
85*e7b1675dSTing-Kang Chang input_stream.open(test_vectors_path);
86*e7b1675dSTing-Kang Chang rapidjson::IStreamWrapper input(input_stream);
87*e7b1675dSTing-Kang Chang std::unique_ptr<rapidjson::Document> root(
88*e7b1675dSTing-Kang Chang new rapidjson::Document(rapidjson::kObjectType));
89*e7b1675dSTing-Kang Chang if (root->ParseStream(input).HasParseError()) {
90*e7b1675dSTing-Kang Chang std::cerr << "Failure parsing of test vectors from "
91*e7b1675dSTing-Kang Chang << test_vectors_path << std::endl;
92*e7b1675dSTing-Kang Chang exit(1);
93*e7b1675dSTing-Kang Chang }
94*e7b1675dSTing-Kang Chang return root;
95*e7b1675dSTing-Kang Chang }
96*e7b1675dSTing-Kang Chang
GetHashType(const rapidjson::Value & val)97*e7b1675dSTing-Kang Chang HashType WycheproofUtil::GetHashType(const rapidjson::Value &val) {
98*e7b1675dSTing-Kang Chang std::string md(val.GetString());
99*e7b1675dSTing-Kang Chang if (md == "SHA-1") {
100*e7b1675dSTing-Kang Chang return HashType::SHA1;
101*e7b1675dSTing-Kang Chang } else if (md == "SHA-256") {
102*e7b1675dSTing-Kang Chang return HashType::SHA256;
103*e7b1675dSTing-Kang Chang } else if (md == "SHA-384") {
104*e7b1675dSTing-Kang Chang return HashType::UNKNOWN_HASH;
105*e7b1675dSTing-Kang Chang } else if (md == "SHA-512") {
106*e7b1675dSTing-Kang Chang return HashType::SHA512;
107*e7b1675dSTing-Kang Chang } else {
108*e7b1675dSTing-Kang Chang return HashType::UNKNOWN_HASH;
109*e7b1675dSTing-Kang Chang }
110*e7b1675dSTing-Kang Chang }
111*e7b1675dSTing-Kang Chang
GetEllipticCurveType(const rapidjson::Value & val)112*e7b1675dSTing-Kang Chang EllipticCurveType WycheproofUtil::GetEllipticCurveType(
113*e7b1675dSTing-Kang Chang const rapidjson::Value &val) {
114*e7b1675dSTing-Kang Chang std::string curve(val.GetString());
115*e7b1675dSTing-Kang Chang if (curve == "secp256r1") {
116*e7b1675dSTing-Kang Chang return EllipticCurveType::NIST_P256;
117*e7b1675dSTing-Kang Chang } else if (curve == "secp384r1") {
118*e7b1675dSTing-Kang Chang return EllipticCurveType::NIST_P384;
119*e7b1675dSTing-Kang Chang } else if (curve == "secp521r1") {
120*e7b1675dSTing-Kang Chang return EllipticCurveType::NIST_P521;
121*e7b1675dSTing-Kang Chang } else {
122*e7b1675dSTing-Kang Chang return EllipticCurveType::UNKNOWN_CURVE;
123*e7b1675dSTing-Kang Chang }
124*e7b1675dSTing-Kang Chang }
125*e7b1675dSTing-Kang Chang
GetInteger(const rapidjson::Value & val)126*e7b1675dSTing-Kang Chang std::string WycheproofUtil::GetInteger(const rapidjson::Value &val) {
127*e7b1675dSTing-Kang Chang std::string hex(val.GetString());
128*e7b1675dSTing-Kang Chang // Since val is a hexadecimal integer it can have an odd length.
129*e7b1675dSTing-Kang Chang if (hex.size() % 2 == 1) {
130*e7b1675dSTing-Kang Chang // Avoid a leading 0 byte.
131*e7b1675dSTing-Kang Chang if (hex[0] == '0') {
132*e7b1675dSTing-Kang Chang hex = std::string(hex, 1, hex.size() - 1);
133*e7b1675dSTing-Kang Chang } else {
134*e7b1675dSTing-Kang Chang hex = "0" + hex;
135*e7b1675dSTing-Kang Chang }
136*e7b1675dSTing-Kang Chang }
137*e7b1675dSTing-Kang Chang return HexDecode(hex).value();
138*e7b1675dSTing-Kang Chang }
139*e7b1675dSTing-Kang Chang
140*e7b1675dSTing-Kang Chang } // namespace subtle
141*e7b1675dSTing-Kang Chang } // namespace tink
142*e7b1675dSTing-Kang Chang } // namespace crypto
143