xref: /aosp_15_r20/external/tink/cc/subtle/aes_gcm_hkdf_stream_segment_decrypter.h (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2019 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 #ifndef TINK_SUBTLE_AES_GCM_HKDF_STREAM_SEGMENT_DECRYPTER_H_
18 #define TINK_SUBTLE_AES_GCM_HKDF_STREAM_SEGMENT_DECRYPTER_H_
19 
20 #include <cstdint>
21 #include <memory>
22 #include <string>
23 #include <vector>
24 
25 #include "tink/aead/internal/ssl_aead.h"
26 #include "tink/subtle/common_enums.h"
27 #include "tink/subtle/stream_segment_decrypter.h"
28 #include "tink/util/secret_data.h"
29 #include "tink/util/statusor.h"
30 
31 namespace crypto {
32 namespace tink {
33 namespace subtle {
34 
35 // StreamSegmentDecrypter for streaming decryption using AES-GCM with HKDF as
36 // key derivation function.
37 //
38 // Each ciphertext uses a new AES-GCM key that is derived from the key
39 // derivation key, a randomly chosen salt of the same size as the key and a
40 // nonce prefix.
41 //
42 // The format of a ciphertext is
43 //   other || header || segment_0 || segment_1 || ... || segment_k.
44 // where:
45 //  - segment_i is the i-th segment of the ciphertext.
46 //  - the size of segment_1 .. segment_{k-1} is get_ciphertext_segment_size()
47 //  - segment_0 is shorter, so that segment_0, the header, and other information
48 //    of size get_ciphertext_offset() align with get_ciphertext_segment_size().
49 //
50 // The format of the header is
51 //   header_size || salt || nonce_prefix
52 // where
53 //  - header_size is 1 byte determining the size of the header
54 //  - salt is a salt used in the key derivation
55 //  - nonce_prefix is the prefix of the nonce
56 //
57 // In principle header_size is redundant information, since the length of the
58 // header can be determined from the key size.
59 
60 class AesGcmHkdfStreamSegmentDecrypter : public StreamSegmentDecrypter {
61  public:
62   // All sizes are in bytes.
63   struct Params {
64     util::SecretData ikm;
65     HashType hkdf_hash;
66     int derived_key_size;
67     int ciphertext_offset;
68     int ciphertext_segment_size;
69     std::string associated_data;
70   };
71 
72   static util::StatusOr<std::unique_ptr<StreamSegmentDecrypter>> New(
73       Params params);
74 
75   util::Status Init(const std::vector<uint8_t>& header) override;
76 
77   util::Status DecryptSegment(
78       const std::vector<uint8_t>& ciphertext,
79       int64_t segment_number,
80       bool is_last_segment,
81       std::vector<uint8_t>* plaintext_buffer) override;
82 
get_header_size()83   int get_header_size() const override {
84     return header_size_;
85   }
86 
87   int get_plaintext_segment_size() const override;
88 
get_ciphertext_segment_size()89   int get_ciphertext_segment_size() const override {
90     return ciphertext_segment_size_;
91   }
get_ciphertext_offset()92   int get_ciphertext_offset() const override {
93     return ciphertext_offset_;
94   }
95 
96  private:
97   explicit AesGcmHkdfStreamSegmentDecrypter(Params params);
98 
99   // Parameters set upon decrypter creation.
100   // All sizes are in bytes.
101   const util::SecretData ikm_;
102   const HashType hkdf_hash_;
103   const int derived_key_size_;
104   const int ciphertext_offset_;
105   const int ciphertext_segment_size_;
106   const std::string associated_data_;
107   const int header_size_;
108 
109   // Parameters set when initializing with data from stream header.
110   bool is_initialized_ = false;
111   std::vector<uint8_t> salt_;
112   std::vector<uint8_t> nonce_prefix_;
113 
114   std::unique_ptr<internal::SslOneShotAead> aead_;
115 };
116 
117 }  // namespace subtle
118 }  // namespace tink
119 }  // namespace crypto
120 
121 #endif  // TINK_SUBTLE_AES_GCM_HKDF_STREAM_SEGMENT_DECRYPTER_H_
122