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