sma: added tweak mode in sma crypto
AES-XTS requires providing tweak. By definition tweak (128bits) represents logical position of the data being encrypted or decrypted, typically for nvme it is LBA. Various implementations of AES-XTS can treat that requirment in different way, because AES-XTS specification doesn't define how exactly tweak look like and how exactly LBA is transformed into tweak For example: - Tweak[127:0] = {1’b0, ~LBA[62:0], LBA[63:0]} - Tweak[127:0] = {LBA[127:0] + 1} - Tweak[127:0] = {LBA[63:0] + 1, 64'b0} So there's a need of specifying mode of tweak Signed-off-by: Michal Rozegnal <michal.rozegnal@intel.com> Change-Id: I92edc71f5f4dfeb0d08a34b73424675321e4740e Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16058 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com> Reviewed-by: Jacek Kalwas <jacek.kalwas@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
b82f1987b9
commit
3408399172
@ -33,6 +33,26 @@ message VolumeCryptoParameters {
|
||||
}
|
||||
// Cipher to use
|
||||
Cipher cipher = 3;
|
||||
// Tweak mode - determine how nvme LBA is converted into tweak
|
||||
enum TweakMode {
|
||||
// default for SPDK bdev_crypto
|
||||
// Tweak[127:0] = {64'b0, LBA[63:0]}
|
||||
TWEAK_MODE_SIMPLE_LBA = 0;
|
||||
|
||||
// Tweak[127:0] = {1’b0, ~LBA[62:0], LBA[63:0]}
|
||||
TWEAK_MODE_NOT_AND_LBA = 1;
|
||||
|
||||
// tweak is derived from nvme LBA that is internally incremented by 1 for every 512 bytes processed
|
||||
// so initial lba = (BLOCK_SIZE_IN_BYTES / 512) * LBA
|
||||
// Tweak[127:0] = {lba[127:0]}
|
||||
TWEAK_MODE_FORCE_512_FULL = 2;
|
||||
|
||||
// tweak is derived from nvme LBA that is internally incremented by 1 for every 512 bytes processed
|
||||
// so initial lba = (BLOCK_SIZE_IN_BYTES / 512) * LBA
|
||||
// Tweak[127:0] = {lba[63:0], 64'b0}
|
||||
TWEAK_MODE_FORCE_512_UPPER = 3;
|
||||
}
|
||||
TweakMode tweak_mode = 4;
|
||||
}
|
||||
|
||||
// Parameters describing a volume
|
||||
|
@ -23,7 +23,7 @@ class CryptoEngine:
|
||||
"""Initialize crypto engine"""
|
||||
self._client = client
|
||||
|
||||
def setup(self, volume_id, key, cipher, key2=None):
|
||||
def setup(self, volume_id, key, cipher, key2=None, tweak_mode=None):
|
||||
"""Set up crypto on a given volume"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@ -34,7 +34,7 @@ class CryptoEngine:
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def verify(self, volume_id, key, cipher, key2=None):
|
||||
def verify(self, volume_id, key, cipher, key2=None, tweak_mode=None):
|
||||
"""
|
||||
Verify that specified crypto parameters match those that are currently deployed on a given
|
||||
volume. If key is None, this mehtod ensures that the volume doesn't use crypto. If
|
||||
@ -56,13 +56,13 @@ class CryptoEngineNop(CryptoEngine):
|
||||
def __init__(self):
|
||||
super().__init__('nop')
|
||||
|
||||
def setup(self, volume_id, key, cipher, key2=None):
|
||||
def setup(self, volume_id, key, cipher, key2=None, tweak_mode=None):
|
||||
raise CryptoException(grpc.StatusCode.INVALID_ARGUMENT, 'Crypto is disabled')
|
||||
|
||||
def cleanup(self, volume_id):
|
||||
pass
|
||||
|
||||
def verify(self, volume_id, key, cipher, key2=None):
|
||||
def verify(self, volume_id, key, cipher, key2=None, tweak_mode=None):
|
||||
pass
|
||||
|
||||
def get_crypto_bdev(self, volume_id):
|
||||
|
@ -26,7 +26,7 @@ class CryptoEngineBdev(crypto.CryptoEngine):
|
||||
# _driver can be None
|
||||
self._driver = params.get('driver')
|
||||
|
||||
def setup(self, volume_id, key, cipher, key2=None):
|
||||
def setup(self, volume_id, key, cipher, key2=None, tweak_mode=None):
|
||||
try:
|
||||
with self._client() as client:
|
||||
cipher = self._ciphers.get(cipher)
|
||||
@ -41,6 +41,10 @@ class CryptoEngineBdev(crypto.CryptoEngine):
|
||||
params['crypto_pmd'] = self._driver
|
||||
if key2 is not None:
|
||||
params['key2'] = key2
|
||||
if tweak_mode is not None and tweak_mode != sma_pb2.VolumeCryptoParameters.TWEAK_MODE_SIMPLE_LBA:
|
||||
raise crypto.CryptoException(grpc.StatusCode.INVALID_ARGUMENT,
|
||||
'Invalid volume crypto configuration: bad tweak_mode')
|
||||
|
||||
log.info('Creating crypto bdev: {} on volume: {}'.format(
|
||||
params['name'], volume_id))
|
||||
client.call('bdev_crypto_create', params)
|
||||
@ -62,7 +66,7 @@ class CryptoEngineBdev(crypto.CryptoEngine):
|
||||
raise crypto.CryptoException(grpc.StatusCode.INTERNAL,
|
||||
'Failed to delete crypto bdev')
|
||||
|
||||
def verify(self, volume_id, key, cipher, key2=None):
|
||||
def verify(self, volume_id, key, cipher, key2=None, tweak_mode=None):
|
||||
crypto_bdev = self._get_crypto_bdev(volume_id)
|
||||
# Key being None/non-None defines whether we expect a bdev_crypto on top of a given volume
|
||||
if ((key is None and crypto_bdev is not None) or (key is not None and crypto_bdev is None)):
|
||||
@ -91,6 +95,9 @@ class CryptoEngineBdev(crypto.CryptoEngine):
|
||||
if crypto_key['name'].lower() != params['key_name'].lower():
|
||||
raise crypto.CryptoException(grpc.StatusCode.INVALID_ARGUMENT,
|
||||
'Invalid volume crypto configuration: key name does not match')
|
||||
if tweak_mode is not None and tweak_mode != sma_pb2.VolumeCryptoParameters.TWEAK_MODE_SIMPLE_LBA:
|
||||
raise crypto.CryptoException(grpc.StatusCode.INVALID_ARGUMENT,
|
||||
'Invalid volume crypto configuration: bad tweak_mode')
|
||||
|
||||
def _get_crypto_bdev(self, volume_id):
|
||||
try:
|
||||
|
@ -163,23 +163,25 @@ class VolumeManager:
|
||||
'Failed to stop discovery')
|
||||
|
||||
def _get_crypto_params(self, params):
|
||||
key, cipher, key2 = None, None, None
|
||||
key, cipher, key2, tweak_mode = None, None, None, None
|
||||
try:
|
||||
if params.HasField('crypto'):
|
||||
key, cipher = params.crypto.key.decode('ascii'), params.crypto.cipher
|
||||
if len(params.crypto.key2) > 0:
|
||||
key2 = params.crypto.key2.decode('ascii')
|
||||
if params.crypto.tweak_mode is not None:
|
||||
tweak_mode = params.crypto.tweak_mode
|
||||
except UnicodeDecodeError:
|
||||
raise VolumeException(grpc.StatusCode.INVALID_ARGUMENT,
|
||||
'Corrupted crypto key')
|
||||
return key, cipher, key2
|
||||
return key, cipher, key2, tweak_mode
|
||||
|
||||
def _setup_crypto(self, volume_id, params):
|
||||
try:
|
||||
if not params.HasField('crypto'):
|
||||
return
|
||||
key, cipher, key2 = self._get_crypto_params(params)
|
||||
crypto.get_crypto_engine().setup(volume_id, key, cipher, key2)
|
||||
key, cipher, key2, tweak_mode = self._get_crypto_params(params)
|
||||
crypto.get_crypto_engine().setup(volume_id, key, cipher, key2, tweak_mode)
|
||||
except crypto.CryptoException as ex:
|
||||
raise VolumeException(ex.code, ex.message)
|
||||
|
||||
@ -191,8 +193,8 @@ class VolumeManager:
|
||||
|
||||
def _verify_crypto(self, volume_id, params):
|
||||
try:
|
||||
key, cipher, key2 = self._get_crypto_params(params)
|
||||
crypto.get_crypto_engine().verify(volume_id, key, cipher, key2)
|
||||
key, cipher, key2, tweak_mode = self._get_crypto_params(params)
|
||||
crypto.get_crypto_engine().verify(volume_id, key, cipher, key2, tweak_mode)
|
||||
except crypto.CryptoException as ex:
|
||||
raise VolumeException(ex.code, ex.message)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user