xref: /aosp_15_r20/external/tink/cc/core/crypto_format.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/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