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/crypto_format.h"
18
19 #include <string>
20
21 #include "absl/status/status.h"
22 #include "tink/util/errors.h"
23 #include "tink/util/statusor.h"
24 #include "proto/tink.pb.h"
25
26 using google::crypto::tink::OutputPrefixType;
27
28 namespace crypto {
29 namespace tink {
30
31 namespace {
32 // Writes bytes of 'value' in Big Endian order to 'buf'.
33 // 'buf' must have at least 4 bytes allocated.
uint32_as_big_endian(uint32_t value,char * buf)34 void uint32_as_big_endian(uint32_t value, char* buf) {
35 buf[0] = 0xff & (value >> 24);
36 buf[1] = 0xff & (value >> 16);
37 buf[2] = 0xff & (value >> 8);
38 buf[3] = 0xff & (value >> 0);
39 }
40
41 } // anonymous namespace
42
43 const int CryptoFormat::kNonRawPrefixSize;
44 const int CryptoFormat::kLegacyPrefixSize;
45 const uint8_t CryptoFormat::kLegacyStartByte;
46
47 const int CryptoFormat::kTinkPrefixSize;
48 const uint8_t CryptoFormat::kTinkStartByte;
49
50 const int CryptoFormat::kRawPrefixSize;
51 const absl::string_view CryptoFormat::kRawPrefix = "";
52
53 // static
GetOutputPrefix(const google::crypto::tink::KeysetInfo::KeyInfo & key_info)54 crypto::tink::util::StatusOr<std::string> CryptoFormat::GetOutputPrefix(
55 const google::crypto::tink::KeysetInfo::KeyInfo& key_info) {
56 switch (key_info.output_prefix_type()) {
57 case OutputPrefixType::TINK: {
58 std::string prefix;
59 prefix.assign(reinterpret_cast<const char*>(&kTinkStartByte), 1);
60 char key_id_buf[4];
61 uint32_as_big_endian(key_info.key_id(), key_id_buf);
62 prefix.append(key_id_buf, 4);
63 return prefix;
64 }
65 case OutputPrefixType::CRUNCHY:
66 // FALLTHROUGH
67 case OutputPrefixType::LEGACY: {
68 std::string prefix;
69 prefix.assign(reinterpret_cast<const char*>(&kLegacyStartByte), 1);
70 char key_id_buf[4];
71 uint32_as_big_endian(key_info.key_id(), key_id_buf);
72 prefix.append(key_id_buf, 4);
73 return prefix;
74 }
75 case OutputPrefixType::RAW:
76 return std::string(kRawPrefix);
77 default:
78 return util::Status(absl::StatusCode::kInvalidArgument,
79 "The given key has invalid OutputPrefixType.");
80 }
81 }
82
83 } // namespace tink
84 } // namespace crypto
85