blob: e570c6df55af6a2827a48ae1ed5981925d3f5f67 [file]
# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB)
# Copyright (c) 2021 Nvidia, Inc. All rights reserved. See COPYING file
from libc.string cimport memcpy
from pyverbs.pyverbs_error import PyverbsRDMAError
cimport pyverbs.providers.mlx5.libmlx5 as dv
from pyverbs.base import PyverbsRDMAErrno
from pyverbs.pd cimport PD
cdef class Mlx5CryptoLoginAttr(PyverbsObject):
def __init__(self, credential, credential_id=0, import_kek_id=0):
"""
Initializes a Mlx5CryptoLoginAttr object representing
mlx5dv_crypto_login_attr C struct.
:param credential: The credential to login with. Must be provided
wrapped by the AES key wrap algorithm using the
import KEK indicated by *import_kek_id*.
:param credential_id: The index of credential that stored on the device.
:param import_kek_id: The index of import_kek that stored on the device.
"""
cdef char *credential_c = credential
self.mlx5dv_crypto_login_attr.credential_id = credential_id
self.mlx5dv_crypto_login_attr.import_kek_id = import_kek_id
memcpy(self.mlx5dv_crypto_login_attr.credential, credential_c, 48)
@property
def credential_id(self):
return self.mlx5dv_crypto_login_attr.credential_id
@property
def import_kek_id(self):
return self.mlx5dv_crypto_login_attr.import_kek_id
@property
def credential(self):
return self.mlx5dv_crypto_login_attr.credential
@property
def comp_mask(self):
return self.mlx5dv_crypto_login_attr.comp_mask
def __str__(self):
print_format = '{:20}: {:<20}\n'
return 'Mlx5CryptoLoginAttr:\n' +\
print_format.format('Credential id', self.credential_id) +\
print_format.format('Import KEK id', self.import_kek_id) +\
print_format.format('Credential', str(self.credential)) +\
print_format.format('Comp mask', self.comp_mask)
cdef class Mlx5CryptoExtLoginAttr(PyverbsObject):
def __init__(self, credential, credential_len, credential_id=0, import_kek_id=0):
"""
Initializes a Mlx5CryptoExtLoginAttr object representing
mlx5dv_crypto_login_attr_ex C struct.
:param credential: The credential to login with.
:param credential_len: The credential length. Must be provided.
:param credential_id: The index of credential that stored on the device.
:param import_kek_id: The index of import_kek that stored on the device.
"""
cdef char *credential_c = credential
self.mlx5dv_crypto_login_attr_ex.credential_id = credential_id
self.mlx5dv_crypto_login_attr_ex.import_kek_id = import_kek_id
self.mlx5dv_crypto_login_attr_ex.credential = <void*>credential_c
self.mlx5dv_crypto_login_attr_ex.credential_len = credential_len
self.credential = credential
@property
def credential_id(self):
return self.mlx5dv_crypto_login_attr_ex.credential_id
@property
def import_kek_id(self):
return self.mlx5dv_crypto_login_attr_ex.import_kek_id
@property
def credential(self):
return self.credential
@property
def credential_len(self):
return self.mlx5dv_crypto_login_attr_ex.credential_len
@property
def comp_mask(self):
return self.mlx5dv_crypto_login_attr_ex.comp_mask
def __str__(self):
print_format = '{:20}: {:<20}\n'
return 'Mlx5CryptoExtLoginAttr:\n' +\
print_format.format('Credential id', self.credential_id) +\
print_format.format('Import KEK id', self.import_kek_id) +\
print_format.format('Credential', str(self.credential)) +\
print_format.format('credential_len', self.credential_len) +\
print_format.format('Comp mask', self.comp_mask)
cdef class Mlx5DEKInitAttr(PyverbsObject):
def __init__(self, PD pd, key_size, has_keytag=False, key_purpose=0, opaque=bytes(),
key=bytes(), comp_mask=0, Mlx5CryptoLogin crypto_login=None):
"""
Initializes a Mlx5DEKInitAttr object representing mlx5dv_dek_init_attr
C struct.
:param pd: The protection domain to be associated with the DEK.
:param credential_id: The size of the key,
can be MLX5DV_CRYPTO_KEY_SIZE_128/256
:param has_keytag: Whether the DEK has a keytag or not. If set, the key
should include a 8 Bytes keytag.
:param key_purpose: The crypto purpose of the key.
:param opaque: Plaintext metadata to describe the key.
:param key: The key itself, wrapped by the crypto login session's
import KEK.
:param comp_mask: Reserved for future extension.
:param crypto_login: Crypto login object.
"""
cdef char *opaque_c = opaque
cdef char *key_c = key
self.pd = pd
self.mlx5dv_dek_init_attr.pd = pd.pd
self.mlx5dv_dek_init_attr.key_size = key_size
self.mlx5dv_dek_init_attr.has_keytag = has_keytag
self.mlx5dv_dek_init_attr.key_purpose = key_purpose
memcpy(self.mlx5dv_dek_init_attr.opaque, opaque_c, 8)
memcpy(self.mlx5dv_dek_init_attr.key, key_c, 128)
self.mlx5dv_dek_init_attr.comp_mask = comp_mask
self.mlx5dv_dek_init_attr.crypto_login = crypto_login.crypto_login_obj if crypto_login else NULL
@property
def key_size(self):
return self.mlx5dv_dek_init_attr.key_size
@property
def has_keytag(self):
return self.mlx5dv_dek_init_attr.has_keytag
@property
def key_purpose(self):
return self.mlx5dv_dek_init_attr.key_purpose
@property
def opaque(self):
return self.mlx5dv_dek_init_attr.opaque.decode()
@property
def key(self):
return self.mlx5dv_dek_init_attr.key.hex()
@property
def comp_mask(self):
return self.mlx5dv_dek_init_attr.comp_mask
def __str__(self):
print_format = '{:20}: {:<20}\n'
return 'Mlx5DEKInitAttr:\n' +\
print_format.format('key_size', self.key_size) +\
print_format.format('Has keytag', self.has_keytag) +\
print_format.format('Key purpose', self.key_purpose) +\
print_format.format('Opaque', self.opaque) +\
print_format.format('Key (in hex format)', self.key) +\
print_format.format('Comp mask', self.comp_mask)
cdef class Mlx5DEKAttr(PyverbsObject):
"""
Initializes a Mlx5DEKAttr object representing mlx5dv_dek_attr
C struct.
"""
@property
def state(self):
return self.mlx5dv_dek_attr.state
@property
def opaque(self):
return self.mlx5dv_dek_attr.opaque
@property
def comp_mask(self):
return self.mlx5dv_dek_attr.comp_mask
cdef class Mlx5CryptoAttr(PyverbsObject):
def __init__(self, crypto_standard=0, encrypt_on_tx=False, signature_crypto_order=0,
data_unit_size=0, initial_tweak=bytes(), Mlx5DEK dek=None,
keytag=bytes(), comp_mask=0):
"""
Initializes a Mlx5CryptoAttr object representing mlx5dv_crypto_attr
C struct.
:param crypto_standard: The encryption standard that should be used.
:param encrypt_on_tx: If set, memory data will be encrypted during TX
and wire data will be decrypted during RX.
:param signature_crypto_order: Controls the order between crypto and
signature operations. Relevant only if
signature is configured.
:param data_unit_size: The tweak is incremented after each
*data_unit_size* during the encryption.
:param initial_tweak: A value to be used during encryption of each data
unit. This value is incremented by the device for
every data unit in the message
:param dek: The DEK to be used for the crypto operations.
:param keytag: A tag that verifies that the correct DEK is being used.
:param comp_mask: Reserved for future extension.
"""
cdef char *initial_tweak_c = initial_tweak
cdef char *keytag_c = keytag
self.mlx5dv_crypto_attr.crypto_standard = crypto_standard
self.mlx5dv_crypto_attr.encrypt_on_tx = encrypt_on_tx
self.mlx5dv_crypto_attr.signature_crypto_order = signature_crypto_order
self.mlx5dv_crypto_attr.data_unit_size = data_unit_size
memcpy(self.mlx5dv_crypto_attr.initial_tweak, initial_tweak_c, 16)
self.mlx5dv_crypto_attr.dek = dek.mlx5dv_dek
memcpy(self.mlx5dv_crypto_attr.keytag, keytag_c, 8)
self.mlx5dv_crypto_attr.comp_mask = comp_mask
@property
def crypto_standard(self):
return self.mlx5dv_crypto_attr.crypto_standard
@property
def encrypt_on_tx(self):
return self.mlx5dv_crypto_attr.encrypt_on_tx
@property
def signature_crypto_order(self):
return self.mlx5dv_crypto_attr.signature_crypto_order
@property
def data_unit_size(self):
return self.mlx5dv_crypto_attr.data_unit_size
@property
def initial_tweak(self):
return self.mlx5dv_crypto_attr.initial_tweak.hex()
@property
def keytag(self):
print('@keytag')
return self.mlx5dv_crypto_attr.keytag.hex()
@property
def comp_mask(self):
return self.mlx5dv_crypto_attr.comp_mask
def __str__(self):
print_format = '{:30}: {:<20}\n'
return 'Mlx5CryptoAttr:\n' +\
print_format.format('Crypto standard', self.crypto_standard) +\
print_format.format('Encrypt on TX', self.encrypt_on_tx) +\
print_format.format('Signature crypto order', self.signature_crypto_order) +\
print_format.format('Data unit size', self.data_unit_size) +\
print_format.format('Initial tweak (in hex format)', self.initial_tweak) +\
print_format.format('keytag (in hex format)', self.keytag) +\
print_format.format('Comp mask', self.comp_mask)
cdef class Mlx5DEK(PyverbsCM):
def __init__(self, Context ctx, Mlx5DEKInitAttr dek_init_attr):
"""
Create a Mlx5DEK object.
:param context: Context to create the schedule resources on.
:param dek_init_attr: Mlx5DEKInitAttr, containing the DEK attributes.
"""
self.mlx5dv_dek = dv.mlx5dv_dek_create(ctx.context,
&dek_init_attr.mlx5dv_dek_init_attr)
if self.mlx5dv_dek == NULL:
raise PyverbsRDMAErrno('Failed to create DEK')
self.pd = dek_init_attr.pd
self.pd.deks.add(self)
def query(self):
"""
Query the dek state.
:return: Mlx5DEKAttr which contains the dek state and opaque.
"""
dek_attr = Mlx5DEKAttr()
rc = dv.mlx5dv_dek_query(self.mlx5dv_dek, &dek_attr.mlx5dv_dek_attr)
if rc:
raise PyverbsRDMAError('Failed to query the dek', rc)
return dek_attr
def __dealloc__(self):
self.close()
cpdef close(self):
if self.mlx5dv_dek != NULL:
rc = dv.mlx5dv_dek_destroy(self.mlx5dv_dek)
if rc:
raise PyverbsRDMAError('Failed to destroy a DEK', rc)
self.mlx5dv_dek = NULL
self.pd = None
cdef class Mlx5CryptoLogin(PyverbsCM):
def __init__(self, Context context, Mlx5CryptoExtLoginAttr crypto_attr):
"""
Create a Mlx5CryptoLogin object.
:param context: Context to create the schedule resources on.
:param crypto_ext_login_attr: Mlx5CryptoExtLoginAttr.
"""
self.crypto_login_obj = dv.mlx5dv_crypto_login_create(context.context,
&crypto_attr.mlx5dv_crypto_login_attr_ex)
if self.crypto_login_obj == NULL:
raise PyverbsRDMAErrno('Failed to create CryptoLoginObj')
self.context = context
context.crypto_logins.add(self)
def query(self):
"""
Queries the state of the current crypto login session.
:return: The login state.
"""
cdef dv.mlx5dv_crypto_login_query_attr query_attr
return dv.mlx5dv_crypto_login_query(self.crypto_login_obj, &query_attr)
def __dealloc__(self):
self.close()
cpdef close(self):
if self.crypto_login_obj != NULL:
rc = dv.mlx5dv_crypto_login_destroy(self.crypto_login_obj)
if rc:
raise PyverbsRDMAError('Failed to destroy a CryptoLoginObj', rc)
self.crypto_login_obj = NULL