xref: /aosp_15_r20/external/tink/cc/hybrid/internal/hpke_context.h (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 #ifndef TINK_HYBRID_INTERNAL_HPKE_CONTEXT_H_
18 #define TINK_HYBRID_INTERNAL_HPKE_CONTEXT_H_
19 
20 #include <stddef.h>
21 
22 #include <memory>
23 #include <string>
24 #include <utility>
25 
26 #include "absl/strings/string_view.h"
27 #include "tink/hybrid/internal/hpke_context_boringssl.h"
28 #include "tink/hybrid/internal/hpke_util.h"
29 #include "tink/util/secret_data.h"
30 #include "tink/util/statusor.h"
31 
32 namespace crypto {
33 namespace tink {
34 namespace internal {
35 
36 // Pair of string views for an HPKE payload (encapsulated key and ciphertext).
37 struct HpkePayloadView {
HpkePayloadViewHpkePayloadView38   HpkePayloadView(absl::string_view encapsulated_key,
39                   absl::string_view ciphertext)
40       : encapsulated_key(encapsulated_key), ciphertext(ciphertext) {}
41 
42   absl::string_view encapsulated_key;
43   absl::string_view ciphertext;
44 };
45 
46 // Creates HPKE payload `encapsulated_key` || `ciphertext` (i.e., Tink hybrid
47 // encryption wire format described at
48 // https://developers.google.com/tink/wire-format#hybrid_encryption).
49 std::string ConcatenatePayload(absl::string_view encapsulated_key,
50                                absl::string_view ciphertext);
51 
52 // Splits `payload` into an `HpkePayloadView` struct.  The `kem` parameter is
53 // used to determine how to split the payload.
54 //
55 // WARNING: The string pointed to by `payload` must outlive the returned object.
56 crypto::tink::util::StatusOr<HpkePayloadView> SplitPayload(
57     const HpkeKem& kem, absl::string_view payload);
58 
59 // Represents an HPKE context for either a sender or a recipient.
60 class HpkeContext {
61  public:
62   // Sets up an HPKE sender context.  Returns an error if initialization
63   // fails.  Otherwise, returns a unique pointer to the sender context.
64   //
65   //   `params`: HPKE parameters (KEM, KDF, and AEAD).
66   //   `recipient_public_key`: KEM-encoding of recipient public key.
67   //   `info`: Application-specific context for key derivation.
68   static crypto::tink::util::StatusOr<std::unique_ptr<HpkeContext>> SetupSender(
69       const HpkeParams& params, absl::string_view recipient_public_key,
70       absl::string_view info);
71 
72   // Sets up an HPKE recipient context.  Returns an error if initialization
73   // fails.  Otherwise, returns a unique pointer to the recipient context.
74   //
75   //   `params`: HPKE parameters (KEM, KDF, and AEAD).
76   //   `recipient_private_key`: Recipient private key.
77   //   `encapsulated_key`: Encapsulated key.
78   //   `info`: Application-specific context for key derivation.
79   static crypto::tink::util::StatusOr<std::unique_ptr<HpkeContext>>
80   SetupRecipient(const HpkeParams& params,
81                  const util::SecretData& recipient_private_key,
82                  absl::string_view encapsulated_key, absl::string_view info);
83 
EncapsulatedKey()84   absl::string_view EncapsulatedKey() const {
85     return encapsulated_key_;
86   }
87 
88   // Performs an AEAD encryption of `plaintext` with `associated_data`. Returns
89   // an error if encryption fails.  Otherwise, returns the ciphertext.
Seal(absl::string_view plaintext,absl::string_view associated_data)90   crypto::tink::util::StatusOr<std::string> Seal(
91       absl::string_view plaintext, absl::string_view associated_data) {
92     return context_->Seal(plaintext, associated_data);
93   }
94 
95   // Performs an AEAD decryption of `ciphertext` with `associated_data`. Returns
96   // an error if decryption fails.  Otherwise, returns the plaintext.
Open(absl::string_view ciphertext,absl::string_view associated_data)97   crypto::tink::util::StatusOr<std::string> Open(
98       absl::string_view ciphertext, absl::string_view associated_data) {
99     return context_->Open(ciphertext, associated_data);
100   }
101 
102   // Exports `secret_length` bytes of secret material using `exporter_context`
103   // for the input context.  Returns an error if export fails.  Otherwise,
104   // returns a secret of the requested length.
Export(absl::string_view exporter_context,size_t secret_length)105   crypto::tink::util::StatusOr<util::SecretData> Export(
106       absl::string_view exporter_context, size_t secret_length) {
107     return context_->Export(exporter_context, secret_length);
108   }
109 
110  private:
HpkeContext(absl::string_view encapsulated_key,std::unique_ptr<HpkeContextBoringSsl> context)111   explicit HpkeContext(absl::string_view encapsulated_key,
112                        std::unique_ptr<HpkeContextBoringSsl> context)
113       : encapsulated_key_(encapsulated_key), context_(std::move(context)) {}
114 
115   const std::string encapsulated_key_;
116   const std::unique_ptr<HpkeContextBoringSsl> context_;
117 };
118 
119 }  // namespace internal
120 }  // namespace tink
121 }  // namespace crypto
122 
123 #endif  // TINK_HYBRID_INTERNAL_HPKE_CONTEXT_H_
124