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_STREAM_SEGMENT_ENCRYPTER_H_ 18 #define TINK_SUBTLE_STREAM_SEGMENT_ENCRYPTER_H_ 19 20 #include <cstdint> 21 #include <vector> 22 23 #include "tink/util/status.h" 24 25 namespace crypto { 26 namespace tink { 27 namespace subtle { 28 29 // StreamSegmentEncrypter is a helper class that encrypts individual 30 // segments of a stream. 31 // 32 // Instances of this are passed to an ...EncryptingStream. Each instance 33 // of a segment encrypter is used to encrypt one stream. 34 // 35 // Typically, construction of a new StreamSegmentEncrypter results 36 // in a generation of a new symmetric key, which is used to 37 // the segments of the stream. The key itself wrapped with or derived 38 // from the key from StreamingAead instance. The wrapped key or the salt 39 // used to derive the symmetric key is part of the header. 40 // 41 // StreamSegmentEncrypter has a state: it keeps the number of segments 42 // encrypted so far. This state is used to encrypt each segment with different 43 // parameters, so that segments in the ciphertext cannot be switched. 44 // 45 // Values returned by StreamSegmentEncrypter's methods effectively define 46 // the layout of the resulting ciphertext stream: 47 // 48 // | other | header | 1st ciphertext segment | 49 // | ...... 2nd ciphertext segment ..... | 50 // | ...... 3rd ciphertext segment ..... | 51 // | ...... ... ..... | 52 // | ...... last ciphertext segment | 53 // 54 // where the following holds: 55 // * each line above, except for the last one, 56 // contains get_ciphertext_segment_size() bytes 57 // * each segment, except for the 1st and the last one, 58 // encrypts get_plaintext_segment_size() bytes of plaintext 59 // * if the ciphertext stream encrypts at least one byte of plaintext, 60 // then the last segment encrypts at least one byte of plaintext 61 // * 'other' is get_ciphertext_offset() bytes long, and represents potential 62 // other bytes already written to the stream; the purpose of ciphertext 63 // offset is to allow alignment of ciphertext segments with segments 64 // of the underlying storage or transmission stream. 65 class StreamSegmentEncrypter { 66 public: 67 // Encrypts 'plaintext' as a segment, and writes the resulting ciphertext 68 // to 'ciphertext_buffer', adjusting its size as needed. 69 // 'plaintext' and 'ciphertext_buffer' must refer to distinct and 70 // non-overlapping space. 71 // Encryption uses the current value returned by get_segment_number() 72 // as the segment number, and subsequently increments the current 73 // segment number. 74 virtual util::Status EncryptSegment( 75 const std::vector<uint8_t>& plaintext, 76 bool is_last_segment, 77 std::vector<uint8_t>* ciphertext_buffer) = 0; 78 79 // Returns the header of the ciphertext stream. 80 virtual const std::vector<uint8_t>& get_header() const = 0; 81 82 // Returns the segment number that will be used for encryption 83 // of the next segment. 84 virtual int64_t get_segment_number() const = 0; 85 86 // Returns the size (in bytes) of a plaintext segment. 87 virtual int get_plaintext_segment_size() const = 0; 88 89 // Returns the size (in bytes) of a ciphertext segment. 90 virtual int get_ciphertext_segment_size() const = 0; 91 92 // Returns the offset (in bytes) of the ciphertext within an encrypted stream. 93 // The offset is non-negative, and not larger than 94 // ciphertext_segment_size - (header_size + segment_overhead) 95 // where 96 // ciphertext_segment_size = get_ciphertext_segment_size() 97 // header_size = get_header().size() 98 // segment_overhead = ciphertext_segment_size - get_plaintext_segment_size() 99 virtual int get_ciphertext_offset() const = 0; 100 101 virtual ~StreamSegmentEncrypter() = default; 102 103 protected: 104 // Increments the segment number. 105 virtual void IncSegmentNumber() = 0; 106 }; 107 108 } // namespace subtle 109 } // namespace tink 110 } // namespace crypto 111 112 #endif // TINK_SUBTLE_STREAM_SEGMENT_ENCRYPTER_H_ 113