1# Copyright 2020 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"""This module defines the interface for Streaming AEAD.""" 15 16import abc 17from typing import BinaryIO 18 19 20class StreamingAead(metaclass=abc.ABCMeta): 21 """The interface for streaming authenticated encryption with associated data. 22 23 Streaming encryption is typically used for encrypting large plaintexts such 24 as large files. This interface supports a streaming interface for symmetric 25 encryption with authentication. The underlying encryption modes are selected 26 so that partial plaintext can be obtained fast by decrypting and 27 authenticating just a part of the ciphertext. 28 29 Note that we do not support non-blocking IO. 30 """ 31 32 @abc.abstractmethod 33 def new_encrypting_stream(self, ciphertext_destination: BinaryIO, 34 associated_data: bytes) -> BinaryIO: 35 """Returns an encrypting stream that writes to ciphertext_destination. 36 37 The returned stream implements a writable but not seekable io.BufferedIOBase 38 interface. It only accepts binary data. For text, it needs to be wrapped 39 with io.TextIOWrapper. 40 41 The ciphertext_destination's write() method is expected to present one of 42 the following three behaviours in the case of a partial or failed write(): 43 - return a non-negative integer number of bytes written 44 - return None (equivalent to returning 0) 45 - raise BlockingIOError with characters_written set correctly to a 46 non-negative integer (equivalent to returning that integer) 47 In the case of a full write, the number of bytes written should be returned. 48 The standard io.BufferedIOBase and io.RawIOBase base classes exhibit these 49 behaviours and are hence supported. 50 51 Args: 52 ciphertext_destination: A writable binary file object to which ciphertext 53 will be written. It must support write(), close(), closed, and 54 writable(). 55 associated_data: Associated data to be used by the AEAD encryption. It is 56 not included in the ciphertext and must be passed in as a parameter for 57 decryption. 58 59 Returns: 60 An implementation of the io.RawIOBase interface that wraps around 61 'ciphertext_destination', such that any bytes written to the wrapper are 62 AEAD-encrypted using 'associated_data' as associated authenticated data. 63 Closing this wrapper also closes the ciphertext_source. 64 Raises: 65 tink.TinkError if the creation fails. 66 """ 67 raise NotImplementedError() 68 69 @abc.abstractmethod 70 def new_decrypting_stream(self, ciphertext_source: BinaryIO, 71 associated_data: bytes) -> BinaryIO: 72 """Returns a decrypting stream that reads from ciphertext_source. 73 74 The returned stream implements a readable but not seekable io.BufferedIOBase 75 interface. It only accepts binary data. For text, it needs to be wrapped 76 with io.TextIOWrapper. 77 78 The cipertext_source's read() method is expected to return an empty bytes 79 object if the stream is already at EOF. In the case where the stream is not 80 at EOF yet but no data is available at the moment, it is expected to either 81 block until data is available, return None or raise BlockingIOError. 82 The standard io.BufferedIOBase and io.RawIOBase base classes exhibit these 83 behaviours and are hence supported. 84 85 Args: 86 ciphertext_source: A readable binary file object from which ciphertext 87 will be read. 88 associated_data: Associated data to be used by the AEAD decryption. It 89 must match the associated_data supplied for the encryption. 90 91 Returns: 92 A readable implementation of the io.BufferedIOBase interface in blocking 93 mode that wraps around 'ciphertext_source', such that any bytes read from 94 the wrapper are AEAD-decrypted using 'associated_data' as associated 95 authenticated data. 96 Closing the wrapper also closes the ciphertext_source. 97 Raises: 98 tink.TinkError if the creation fails. 99 """ 100 raise NotImplementedError() 101