diff --git a/python/streaming_aead/streaming_aead_key_templates.py b/python/streaming_aead/streaming_aead_key_templates.py new file mode 100644 index 0000000000000000000000000000000000000000..1576ab97bc59242e4167743021e887c9738be1b5 --- /dev/null +++ b/python/streaming_aead/streaming_aead_key_templates.py @@ -0,0 +1,105 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Pre-generated KeyTemplates for StreamingAead. + + +Currently, these templates cannot be used to generate keysets, but they can be +used to generate individual keys. +In the future, it will be possible to use these templates to generate a new +tink_pb2.Keyset with tink_pb2.KeysetHandle. To generate a new keyset that +contains a single aes_ctr_hmac_streaming_pb2.AesCtrHmacStreamingKey, one can do: +handle = keyset_handle.KeysetHandle( + streaming_aead_key_templates.AES256_CTR_HMAC_SHA256_4KB). +""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import google_type_annotations +from __future__ import print_function + +from tink.proto import aes_ctr_hmac_streaming_pb2 +from tink.proto import aes_gcm_hkdf_streaming_pb2 +from tink.proto import common_pb2 +from tink.proto import tink_pb2 + +_AES_GCM_HKDF_STREAMING_KEY_TYPE_URL = ( + 'type.googleapis.com/google.crypto.tink.AesGcmHkdfStreamingKey') +_AES_CTR_HMAC_STREAMING_KEY_TYPE_URL = ( + 'type.googleapis.com/google.crypto.tink.AesCtrHmacStreamingKey') + + +def create_aes_gcm_hkdf_streaming_key_template( + aes_key_size: int, hash_type: common_pb2.HashType, derived_key_size: int, + ciphertext_segment_size: int) -> tink_pb2.KeyTemplate: + """Creates an AES GCM HKDF Streaming KeyTemplate, and fills in its values.""" + key_format = aes_gcm_hkdf_streaming_pb2.AesGcmHkdfStreamingKeyFormat() + key_format.key_size = aes_key_size + key_format.params.hkdf_hash_type = hash_type + key_format.params.derived_key_size = derived_key_size + key_format.params.ciphertext_segment_size = ciphertext_segment_size + + key_template = tink_pb2.KeyTemplate() + key_template.value = key_format.SerializeToString() + key_template.type_url = _AES_GCM_HKDF_STREAMING_KEY_TYPE_URL + key_template.output_prefix_type = tink_pb2.RAW + return key_template + + +def create_aes_ctr_hmac_streaming_key_template( + aes_key_size: int, hkdf_hash_type: common_pb2.HashType, + derived_key_size: int, mac_hash_type: common_pb2.HashType, tag_size: int, + ciphertext_segment_size: int) -> tink_pb2.KeyTemplate: + """Creates an AES CTR HMAC Streaming KeyTemplate, and fills in its values.""" + key_format = aes_ctr_hmac_streaming_pb2.AesCtrHmacStreamingKeyFormat() + key_format.key_size = aes_key_size + + key_format.params.ciphertext_segment_size = ciphertext_segment_size + key_format.params.derived_key_size = derived_key_size + key_format.params.hkdf_hash_type = hkdf_hash_type + + key_format.params.hmac_params.hash = mac_hash_type + key_format.params.hmac_params.tag_size = tag_size + + key_template = tink_pb2.KeyTemplate() + key_template.value = key_format.SerializeToString() + key_template.type_url = _AES_CTR_HMAC_STREAMING_KEY_TYPE_URL + key_template.output_prefix_type = tink_pb2.RAW + return key_template + + +AES128_GCM_HKDF_4KB = create_aes_gcm_hkdf_streaming_key_template( + aes_key_size=16, + hash_type=common_pb2.HashType.SHA256, + derived_key_size=16, + ciphertext_segment_size=4096) + +AES256_GCM_HKDF_4KB = create_aes_gcm_hkdf_streaming_key_template( + aes_key_size=32, + hash_type=common_pb2.HashType.SHA256, + derived_key_size=32, + ciphertext_segment_size=4096) + +AES128_CTR_HMAC_SHA256_4KB = create_aes_ctr_hmac_streaming_key_template( + aes_key_size=16, + hkdf_hash_type=common_pb2.HashType.SHA256, + derived_key_size=16, + mac_hash_type=common_pb2.HashType.SHA256, + tag_size=32, + ciphertext_segment_size=4096) + +AES256_CTR_HMAC_SHA256_4KB = create_aes_ctr_hmac_streaming_key_template( + aes_key_size=32, + hkdf_hash_type=common_pb2.HashType.SHA256, + derived_key_size=32, + mac_hash_type=common_pb2.HashType.SHA256, + tag_size=32, + ciphertext_segment_size=4096) diff --git a/python/streaming_aead/streaming_aead_key_templates_test.py b/python/streaming_aead/streaming_aead_key_templates_test.py new file mode 100644 index 0000000000000000000000000000000000000000..14e031f2d02324a95339e157c2247d47baf2a837 --- /dev/null +++ b/python/streaming_aead/streaming_aead_key_templates_test.py @@ -0,0 +1,141 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for tink.python.streaming_aead_key_templates.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +from absl.testing import absltest +from tink.proto import aes_ctr_hmac_streaming_pb2 +from tink.proto import aes_gcm_hkdf_streaming_pb2 +from tink.proto import common_pb2 +from tink.proto import tink_pb2 +from tink.python.streaming_aead import streaming_aead_key_templates + + +class StreamingAeadKeyTemplatesTest(absltest.TestCase): + + def test_aes128_gcm_hkdf_4kb(self): + template = streaming_aead_key_templates.AES128_GCM_HKDF_4KB + self.assertEqual( + 'type.googleapis.com/google.crypto.tink.AesGcmHkdfStreamingKey', + template.type_url) + self.assertEqual(tink_pb2.RAW, template.output_prefix_type) + key_format = aes_gcm_hkdf_streaming_pb2.AesGcmHkdfStreamingKeyFormat() + key_format.ParseFromString(template.value) + + self.assertEqual(16, key_format.key_size) + self.assertEqual(common_pb2.HashType.SHA256, + key_format.params.hkdf_hash_type) + self.assertEqual(16, key_format.params.derived_key_size) + self.assertEqual(4096, key_format.params.ciphertext_segment_size) + + def test_aes256_gcm_hkdf_4kb(self): + template = streaming_aead_key_templates.AES256_GCM_HKDF_4KB + self.assertEqual( + 'type.googleapis.com/google.crypto.tink.AesGcmHkdfStreamingKey', + template.type_url) + self.assertEqual(tink_pb2.RAW, template.output_prefix_type) + key_format = aes_gcm_hkdf_streaming_pb2.AesGcmHkdfStreamingKeyFormat() + key_format.ParseFromString(template.value) + + self.assertEqual(32, key_format.key_size) + self.assertEqual(common_pb2.HashType.SHA256, + key_format.params.hkdf_hash_type) + self.assertEqual(32, key_format.params.derived_key_size) + self.assertEqual(4096, key_format.params.ciphertext_segment_size) + + def test_aes128_ctr_hmac_sha256_4kb(self): + template = streaming_aead_key_templates.AES128_CTR_HMAC_SHA256_4KB + self.assertEqual( + 'type.googleapis.com/google.crypto.tink.AesCtrHmacStreamingKey', + template.type_url) + self.assertEqual(tink_pb2.RAW, template.output_prefix_type) + key_format = aes_ctr_hmac_streaming_pb2.AesCtrHmacStreamingKeyFormat() + key_format.ParseFromString(template.value) + + self.assertEqual(16, key_format.key_size) + self.assertEqual(common_pb2.HashType.SHA256, + key_format.params.hkdf_hash_type) + self.assertEqual(16, key_format.params.derived_key_size) + self.assertEqual(common_pb2.HashType.SHA256, + key_format.params.hmac_params.hash) + self.assertEqual(32, key_format.params.hmac_params.tag_size) + self.assertEqual(4096, key_format.params.ciphertext_segment_size) + + def test_aes256_ctr_hmac_sha256_4kb(self): + template = streaming_aead_key_templates.AES256_CTR_HMAC_SHA256_4KB + self.assertEqual( + 'type.googleapis.com/google.crypto.tink.AesCtrHmacStreamingKey', + template.type_url) + self.assertEqual(tink_pb2.RAW, template.output_prefix_type) + key_format = aes_ctr_hmac_streaming_pb2.AesCtrHmacStreamingKeyFormat() + key_format.ParseFromString(template.value) + + self.assertEqual(32, key_format.key_size) + self.assertEqual(common_pb2.HashType.SHA256, + key_format.params.hkdf_hash_type) + self.assertEqual(32, key_format.params.derived_key_size) + self.assertEqual(common_pb2.HashType.SHA256, + key_format.params.hmac_params.hash) + self.assertEqual(32, key_format.params.hmac_params.tag_size) + self.assertEqual(4096, key_format.params.ciphertext_segment_size) + + def test_create_aes_gcm_hkdf_streaming_key_template(self): + # Intentionally using 'weird' or invalid values for parameters, + # to test that the function correctly puts them in the resulting template. + template = streaming_aead_key_templates.create_aes_gcm_hkdf_streaming_key_template( + aes_key_size=42, + hash_type=common_pb2.HashType.SHA1, + derived_key_size=76, + ciphertext_segment_size=64, + ) + self.assertEqual( + 'type.googleapis.com/google.crypto.tink.AesGcmHkdfStreamingKey', + template.type_url) + self.assertEqual(tink_pb2.RAW, template.output_prefix_type) + key_format = aes_gcm_hkdf_streaming_pb2.AesGcmHkdfStreamingKeyFormat() + key_format.ParseFromString(template.value) + self.assertEqual(42, key_format.key_size) + self.assertEqual(common_pb2.HashType.SHA1, key_format.params.hkdf_hash_type) + self.assertEqual(76, key_format.params.derived_key_size) + self.assertEqual(64, key_format.params.ciphertext_segment_size) + + def test_create_aes_ctr_hmac_streaming_key_template(self): + # Intentionally using 'weird' or invalid values for parameters, + # to test that the function correctly puts them in the resulting template. + template = streaming_aead_key_templates.create_aes_ctr_hmac_streaming_key_template( + aes_key_size=42, + hkdf_hash_type=common_pb2.HashType.SHA1, + derived_key_size=76, + mac_hash_type=common_pb2.HashType.UNKNOWN_HASH, + tag_size=39, + ciphertext_segment_size=64, + ) + self.assertEqual( + 'type.googleapis.com/google.crypto.tink.AesCtrHmacStreamingKey', + template.type_url) + self.assertEqual(tink_pb2.RAW, template.output_prefix_type) + key_format = aes_ctr_hmac_streaming_pb2.AesCtrHmacStreamingKeyFormat() + key_format.ParseFromString(template.value) + self.assertEqual(42, key_format.key_size) + self.assertEqual(common_pb2.HashType.SHA1, key_format.params.hkdf_hash_type) + self.assertEqual(76, key_format.params.derived_key_size) + self.assertEqual(common_pb2.HashType.UNKNOWN_HASH, + key_format.params.hmac_params.hash) + self.assertEqual(39, key_format.params.hmac_params.tag_size) + self.assertEqual(64, key_format.params.ciphertext_segment_size) + + +if __name__ == '__main__': + absltest.main()