blob: c7e43ccedbb899e952be75a3134124f87e0d64fd [file] [log] [blame]
# Copyright 2019 Google LLC.
#
# 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.aead_key_manager."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from absl.testing import absltest
from tink.proto import aes_eax_pb2
from tink.proto import aes_gcm_pb2
from tink.proto import tink_pb2
from tink.python import tink_config
from tink.python.aead import aead
from tink.python.aead import aead_key_manager
from tink.python.core import tink_error
def setUpModule():
tink_config.register()
class AeadKeyManagerTest(absltest.TestCase):
def setUp(self):
super(AeadKeyManagerTest, self).setUp()
self.key_manager_eax = aead_key_manager.from_cc_registry(
'type.googleapis.com/google.crypto.tink.AesEaxKey')
self.key_manager_gcm = aead_key_manager.from_cc_registry(
'type.googleapis.com/google.crypto.tink.AesGcmKey')
def new_aes_eax_key_template(self, iv_size, key_size):
key_format = aes_eax_pb2.AesEaxKeyFormat()
key_format.params.iv_size = iv_size
key_format.key_size = key_size
key_template = tink_pb2.KeyTemplate()
key_template.type_url = ('type.googleapis.com/google.crypto.tink.AesEaxKey')
key_template.value = key_format.SerializeToString()
return key_template
def new_aes_gcm_key_template(self, key_size):
key_format = aes_gcm_pb2.AesGcmKeyFormat()
key_format.key_size = key_size
key_template = tink_pb2.KeyTemplate()
key_template.type_url = ('type.googleapis.com/google.crypto.tink.AesGcmKey')
key_template.value = key_format.SerializeToString()
return key_template
def test_primitive_class(self):
self.assertEqual(self.key_manager_eax.primitive_class(), aead.Aead)
self.assertEqual(self.key_manager_gcm.primitive_class(), aead.Aead)
def test_key_type(self):
self.assertEqual(self.key_manager_eax.key_type(),
'type.googleapis.com/google.crypto.tink.AesEaxKey')
self.assertEqual(self.key_manager_gcm.key_type(),
'type.googleapis.com/google.crypto.tink.AesGcmKey')
def test_new_key_data(self):
# AES EAX
key_template = self.new_aes_eax_key_template(12, 16)
key_data = self.key_manager_eax.new_key_data(key_template)
self.assertEqual(key_data.type_url, self.key_manager_eax.key_type())
self.assertEqual(key_data.key_material_type, tink_pb2.KeyData.SYMMETRIC)
key = aes_eax_pb2.AesEaxKey()
key.ParseFromString(key_data.value)
self.assertEqual(key.version, 0)
self.assertEqual(key.params.iv_size, 12)
self.assertLen(key.key_value, 16)
# AES GCM
key_template = self.new_aes_gcm_key_template(16)
key_data = self.key_manager_gcm.new_key_data(key_template)
self.assertEqual(key_data.type_url, self.key_manager_gcm.key_type())
self.assertEqual(key_data.key_material_type, tink_pb2.KeyData.SYMMETRIC)
key = aes_gcm_pb2.AesGcmKey()
key.ParseFromString(key_data.value)
self.assertEqual(key.version, 0)
self.assertLen(key.key_value, 16)
def test_invalid_params_throw_exception(self):
key_template = self.new_aes_eax_key_template(9, 16)
with self.assertRaisesRegex(tink_error.TinkError,
'Invalid IV size'):
self.key_manager_eax.new_key_data(key_template)
key_template = self.new_aes_gcm_key_template(17)
with self.assertRaisesRegex(tink_error.TinkError,
'supported sizes: 16 or 32 bytes'):
self.key_manager_gcm.new_key_data(key_template)
def test_encrypt_decrypt(self):
# AES EAX
primitive = self.key_manager_eax.primitive(
self.key_manager_eax.new_key_data(
self.new_aes_eax_key_template(12, 16)))
plaintext = b'plaintext'
associated_data = b'associated_data'
ciphertext = primitive.encrypt(plaintext, associated_data)
self.assertEqual(primitive.decrypt(ciphertext, associated_data), plaintext)
# AES GCM
primitive = self.key_manager_gcm.primitive(
self.key_manager_gcm.new_key_data(self.new_aes_gcm_key_template(16)))
plaintext = b'plaintext'
associated_data = b'associated_data'
ciphertext = primitive.encrypt(plaintext, associated_data)
self.assertEqual(primitive.decrypt(ciphertext, associated_data), plaintext)
def test_invalid_decrypt_raises_error(self):
primitive = self.key_manager_eax.primitive(
self.key_manager_eax.new_key_data(
self.new_aes_eax_key_template(12, 16)))
with self.assertRaisesRegex(tink_error.TinkError, 'Ciphertext too short'):
primitive.decrypt(b'invalid ciphertext', 'ad')
if __name__ == '__main__':
absltest.main()