xref: /aosp_15_r20/external/tink/cc/hybrid/internal/hpke_context.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2022 Google LLC
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/hybrid/internal/hpke_context.h"
18 
19 #include <memory>
20 #include <string>
21 #include <utility>
22 
23 #include "absl/status/status.h"
24 #include "absl/strings/string_view.h"
25 #include "tink/hybrid/internal/hpke_context_boringssl.h"
26 #include "tink/util/secret_data.h"
27 #include "tink/util/status.h"
28 #include "tink/util/statusor.h"
29 
30 namespace crypto {
31 namespace tink {
32 namespace internal {
33 
34 constexpr int kX25519KemEncodingLengthInBytes = 32;
35 
ConcatenatePayload(absl::string_view encapsulated_key,absl::string_view ciphertext)36 std::string ConcatenatePayload(absl::string_view encapsulated_key,
37                                absl::string_view ciphertext) {
38   return absl::StrCat(encapsulated_key, ciphertext);
39 }
40 
SplitPayload(const HpkeKem & kem,absl::string_view payload)41 util::StatusOr<HpkePayloadView> SplitPayload(const HpkeKem& kem,
42                                              absl::string_view payload) {
43   if (kem == HpkeKem::kX25519HkdfSha256) {
44     return HpkePayloadView(payload.substr(0, kX25519KemEncodingLengthInBytes),
45                            payload.substr(kX25519KemEncodingLengthInBytes));
46   }
47   return util::Status(
48       absl::StatusCode::kInvalidArgument,
49       absl::StrCat("Unable to split HPKE payload for KEM type ", kem));
50 }
51 
SetupSender(const HpkeParams & params,absl::string_view recipient_public_key,absl::string_view info)52 util::StatusOr<std::unique_ptr<HpkeContext>> HpkeContext::SetupSender(
53     const HpkeParams& params, absl::string_view recipient_public_key,
54     absl::string_view info) {
55   if (recipient_public_key.empty()) {
56     return util::Status(absl::StatusCode::kInvalidArgument,
57                         "Recipient public key is empty.");
58   }
59   util::StatusOr<SenderHpkeContextBoringSsl> sender_context =
60       HpkeContextBoringSsl::SetupSender(params, recipient_public_key, info);
61   if (!sender_context.ok()) {
62     return sender_context.status();
63   }
64   return {absl::WrapUnique(new HpkeContext(
65       sender_context->encapsulated_key, std::move(sender_context->context)))};
66 }
67 
SetupRecipient(const HpkeParams & params,const util::SecretData & recipient_private_key,absl::string_view encapsulated_key,absl::string_view info)68 util::StatusOr<std::unique_ptr<HpkeContext>> HpkeContext::SetupRecipient(
69     const HpkeParams& params, const util::SecretData& recipient_private_key,
70     absl::string_view encapsulated_key, absl::string_view info) {
71   if (recipient_private_key.empty()) {
72     return util::Status(absl::StatusCode::kInvalidArgument,
73                         "Recipient private key is empty.");
74   }
75   if (encapsulated_key.empty()) {
76     return util::Status(absl::StatusCode::kInvalidArgument,
77                         "Encapsulated key is empty.");
78   }
79   util::StatusOr<std::unique_ptr<HpkeContextBoringSsl>> context =
80       HpkeContextBoringSsl::SetupRecipient(params, recipient_private_key,
81                                            encapsulated_key, info);
82   if (!context.ok()) {
83     return context.status();
84   }
85   return {absl::WrapUnique(
86       new HpkeContext(encapsulated_key, *std::move(context)))};
87 }
88 
89 }  // namespace internal
90 }  // namespace tink
91 }  // namespace crypto
92