2
0
mirror of https://github.com/openkmip/pykmip synced 2026-01-06 02:23:25 +00:00

Add support for AES GCM mode.

This commit is contained in:
oleksiys
2019-08-06 17:53:51 -07:00
committed by Peter Hamilton
parent 44d55f2550
commit 26c1c71fff
7 changed files with 596 additions and 64 deletions

View File

@@ -33,13 +33,16 @@ class EncryptRequestPayload(primitives.Struct):
data: The data to be encrypted in the form of a binary string.
iv_counter_nonce: An IV/counter/nonce to be used with the encryption
algorithm. Comes in the form of a binary string.
auth_additional_data: Any additional data to be authenticated via the
Authenticated Encryption Tag. Added in KMIP 1.4.
"""
def __init__(self,
unique_identifier=None,
cryptographic_parameters=None,
data=None,
iv_counter_nonce=None):
iv_counter_nonce=None,
auth_additional_data=None):
"""
Construct an Encrypt request payload struct.
@@ -56,6 +59,9 @@ class EncryptRequestPayload(primitives.Struct):
encoding and decoding.
iv_counter_nonce (bytes): The IV/counter/nonce value to be used
with the encryption algorithm. Optional, defaults to None.
auth_additional_data (bytes): Any additional data to be
authenticated via the Authenticated Encryption Tag.
Added in KMIP 1.4.
"""
super(EncryptRequestPayload, self).__init__(
enums.Tags.REQUEST_PAYLOAD
@@ -65,11 +71,13 @@ class EncryptRequestPayload(primitives.Struct):
self._cryptographic_parameters = None
self._data = None
self._iv_counter_nonce = None
self._auth_additional_data = None
self.unique_identifier = unique_identifier
self.cryptographic_parameters = cryptographic_parameters
self.data = data
self.iv_counter_nonce = iv_counter_nonce
self.auth_additional_data = auth_additional_data
@property
def unique_identifier(self):
@@ -144,6 +152,25 @@ class EncryptRequestPayload(primitives.Struct):
else:
raise TypeError("IV/counter/nonce must be bytes")
@property
def auth_additional_data(self):
if self._auth_additional_data:
return self._auth_additional_data.value
else:
return None
@auth_additional_data.setter
def auth_additional_data(self, value):
if value is None:
self._auth_additional_data = None
elif isinstance(value, six.binary_type):
self._auth_additional_data = primitives.ByteString(
value=value,
tag=enums.Tags.AUTHENTICATED_ENCRYPTION_ADDITIONAL_DATA
)
else:
raise TypeError("authenticated additional data must be bytes")
def read(self, input_stream, kmip_version=enums.KMIPVersion.KMIP_1_0):
"""
Read the data encoding the Encrypt request payload and decode it
@@ -202,6 +229,19 @@ class EncryptRequestPayload(primitives.Struct):
kmip_version=kmip_version
)
if kmip_version >= enums.KMIPVersion.KMIP_1_4:
if self.is_tag_next(
enums.Tags.AUTHENTICATED_ENCRYPTION_ADDITIONAL_DATA,
local_stream
):
self._auth_additional_data = primitives.ByteString(
tag=enums.Tags.AUTHENTICATED_ENCRYPTION_ADDITIONAL_DATA
)
self._auth_additional_data.read(
local_stream,
kmip_version=kmip_version
)
self.is_oversized(local_stream)
def write(self, output_stream, kmip_version=enums.KMIPVersion.KMIP_1_0):
@@ -243,6 +283,13 @@ class EncryptRequestPayload(primitives.Struct):
kmip_version=kmip_version
)
if kmip_version >= enums.KMIPVersion.KMIP_1_4:
if self._auth_additional_data:
self._auth_additional_data.write(
local_stream,
kmip_version=kmip_version
)
self.length = local_stream.length()
super(EncryptRequestPayload, self).write(
output_stream,
@@ -261,6 +308,8 @@ class EncryptRequestPayload(primitives.Struct):
return False
elif self.iv_counter_nonce != other.iv_counter_nonce:
return False
elif self.auth_additional_data != other.auth_additional_data:
return False
else:
return True
else:
@@ -279,7 +328,8 @@ class EncryptRequestPayload(primitives.Struct):
repr(self.cryptographic_parameters)
),
"data={0}".format(self.data),
"iv_counter_nonce={0}".format(self.iv_counter_nonce)
"iv_counter_nonce={0}".format(self.iv_counter_nonce),
"auth_additional_data={0}".format(self.auth_additional_data)
])
return "EncryptRequestPayload({0})".format(args)
@@ -288,7 +338,8 @@ class EncryptRequestPayload(primitives.Struct):
'unique_identifier': self.unique_identifier,
'cryptographic_parameters': self.cryptographic_parameters,
'data': self.data,
'iv_counter_nonce': self.iv_counter_nonce
'iv_counter_nonce': self.iv_counter_nonce,
'auth_additional_data': self.auth_additional_data
})
@@ -302,12 +353,18 @@ class EncryptResponsePayload(primitives.Struct):
data: The encrypted data in the form of a binary string.
iv_counter_nonce: The IV/counter/nonce used with the encryption
algorithm. Comes in the form of a binary string.
auth_tag: Specifies the tag that will be needed to
authenticate the decrypted data. Only returned on completion
of the encryption of the last of the plaintext by an
authenticated encryption cipher. Optional, defaults to None.
Added in KMIP 1.4.
"""
def __init__(self,
unique_identifier=None,
data=None,
iv_counter_nonce=None):
iv_counter_nonce=None,
auth_tag=None):
"""
Construct an Encrypt response payload struct.
@@ -321,6 +378,11 @@ class EncryptResponsePayload(primitives.Struct):
the encryption algorithm if it was required and if this
value was not originally specified by the client. Optional,
defaults to None.
auth_tag (bytes): Specifies the tag that will be needed to
authenticate the decrypted data. Only returned on completion
of the encryption of the last of the plaintext by an
authenticated encryption cipher. Optional, defaults to None.
Added in KMIP 1.4.
"""
super(EncryptResponsePayload, self).__init__(
enums.Tags.RESPONSE_PAYLOAD
@@ -329,10 +391,12 @@ class EncryptResponsePayload(primitives.Struct):
self._unique_identifier = None
self._data = None
self._iv_counter_nonce = None
self._auth_tag = None
self.unique_identifier = unique_identifier
self.data = data
self.iv_counter_nonce = iv_counter_nonce
self.auth_tag = auth_tag
@property
def unique_identifier(self):
@@ -391,6 +455,25 @@ class EncryptResponsePayload(primitives.Struct):
else:
raise TypeError("IV/counter/nonce must be bytes")
@property
def auth_tag(self):
if self._auth_tag:
return self._auth_tag.value
else:
return None
@auth_tag.setter
def auth_tag(self, value):
if value is None:
self._auth_tag = None
elif isinstance(value, six.binary_type):
self._auth_tag = primitives.ByteString(
value=value,
tag=enums.Tags.AUTHENTICATED_ENCRYPTION_TAG
)
else:
raise TypeError("authenticated encryption tag must be bytes")
def read(self, input_stream, kmip_version=enums.KMIPVersion.KMIP_1_0):
"""
Read the data encoding the Encrypt response payload and decode it
@@ -445,6 +528,18 @@ class EncryptResponsePayload(primitives.Struct):
kmip_version=kmip_version
)
if kmip_version >= enums.KMIPVersion.KMIP_1_4:
if self.is_tag_next(
enums.Tags.AUTHENTICATED_ENCRYPTION_TAG, local_stream
):
self._auth_tag = primitives.ByteString(
tag=enums.Tags.AUTHENTICATED_ENCRYPTION_TAG
)
self._auth_tag.read(
local_stream,
kmip_version=kmip_version
)
self.is_oversized(local_stream)
def write(self, output_stream, kmip_version=enums.KMIPVersion.KMIP_1_0):
@@ -486,6 +581,13 @@ class EncryptResponsePayload(primitives.Struct):
kmip_version=kmip_version
)
if kmip_version >= enums.KMIPVersion.KMIP_1_4:
if self._auth_tag:
self._auth_tag.write(
local_stream,
kmip_version=kmip_version
)
self.length = local_stream.length()
super(EncryptResponsePayload, self).write(
output_stream,
@@ -501,6 +603,8 @@ class EncryptResponsePayload(primitives.Struct):
return False
elif self.iv_counter_nonce != other.iv_counter_nonce:
return False
elif self.auth_tag != other.auth_tag:
return False
else:
return True
else:
@@ -516,7 +620,8 @@ class EncryptResponsePayload(primitives.Struct):
args = ", ".join([
"unique_identifier='{0}'".format(self.unique_identifier),
"data={0}".format(self.data),
"iv_counter_nonce={0}".format(self.iv_counter_nonce)
"iv_counter_nonce={0}".format(self.iv_counter_nonce),
"auth_tag={0}".format(self.auth_tag)
])
return "EncryptResponsePayload({0})".format(args)
@@ -524,5 +629,6 @@ class EncryptResponsePayload(primitives.Struct):
return str({
'unique_identifier': self.unique_identifier,
'data': self.data,
'iv_counter_nonce': self.iv_counter_nonce
'iv_counter_nonce': self.iv_counter_nonce,
'auth_tag': self.auth_tag
})