Made HMAC Key Wrap mechanism configurable
Introduced the parameter 'hmac_keywrap_mechanism' in group '[p11_crypto_plugin]' in Barbican config. The default value, which were hard coded before, is 'CKM_SHA256_HMAC'. This defines the machanism used to compute the HMAC from an wrapped PKEK. However with Utimaco HSMs this leads to an CKR_MECHANISM_INVALID error. Therefore for Utimaco HSMs 'hmac_keywrap_mechanism' has to be changed to 'CKM_AES_MAC'. Change-Id: I53537a96bc4b2acb30be5fa85e10bac89917851f Story: 2004833 Task: 29027
This commit is contained in:
parent
6dc5259012
commit
b7da1f771c
@ -184,9 +184,14 @@ class HSMCommands(object):
|
|||||||
help='Password to login to PKCS11 session')
|
help='Password to login to PKCS11 session')
|
||||||
@args('--label', '-L', metavar='<label>', default='primarymkek',
|
@args('--label', '-L', metavar='<label>', default='primarymkek',
|
||||||
help='The label of the Master Key Encrypt Key')
|
help='The label of the Master Key Encrypt Key')
|
||||||
def check_mkek(self, passphrase, libpath=None, slotid=None, label=None):
|
@args('--hmac-wrap-mechanism', metavar='<hmac key wrap mechanism>',
|
||||||
|
dest='hmacwrap', default='CKM_SHA256_HMAC',
|
||||||
|
help='HMAC Key wrap mechanism, default is CKM_SHA256_HMAC')
|
||||||
|
def check_mkek(self, passphrase, libpath=None, slotid=None, label=None,
|
||||||
|
hmacwrap=None):
|
||||||
CKK_AES = 'CKK_AES'
|
CKK_AES = 'CKK_AES'
|
||||||
self._create_pkcs11_session(str(passphrase), str(libpath), int(slotid))
|
self._create_pkcs11_session(str(passphrase), str(libpath),
|
||||||
|
int(slotid), str(hmacwrap))
|
||||||
handle = self.pkcs11.get_key_handle(CKK_AES, str(label), self.session)
|
handle = self.pkcs11.get_key_handle(CKK_AES, str(label), self.session)
|
||||||
self.pkcs11.return_session(self.session)
|
self.pkcs11.return_session(self.session)
|
||||||
if not handle:
|
if not handle:
|
||||||
@ -208,11 +213,15 @@ class HSMCommands(object):
|
|||||||
@args('--length', '-l', metavar='<length>', default=32,
|
@args('--length', '-l', metavar='<length>', default=32,
|
||||||
help='The length in bytes of the Master Key Encryption Key'
|
help='The length in bytes of the Master Key Encryption Key'
|
||||||
' (default is 32)')
|
' (default is 32)')
|
||||||
|
@args('--hmac-wrap-mechanism', metavar='<hmac key wrap mechanism>',
|
||||||
|
dest='hmacwrap', default='CKM_SHA256_HMAC',
|
||||||
|
help='HMAC Key wrap mechanism, default is CKM_SHA256_HMAC')
|
||||||
def gen_mkek(self, passphrase, libpath=None, slotid=None, label=None,
|
def gen_mkek(self, passphrase, libpath=None, slotid=None, label=None,
|
||||||
length=None):
|
length=None, hmacwrap=None):
|
||||||
CKK_AES = 'CKK_AES'
|
CKK_AES = 'CKK_AES'
|
||||||
CKM_AES_KEY_GEN = 'CKM_AES_KEY_GEN'
|
CKM_AES_KEY_GEN = 'CKM_AES_KEY_GEN'
|
||||||
self._create_pkcs11_session(str(passphrase), str(libpath), int(slotid))
|
self._create_pkcs11_session(str(passphrase), str(libpath),
|
||||||
|
int(slotid), str(hmacwrap))
|
||||||
self._verify_label_does_not_exist(CKK_AES, str(label), self.session)
|
self._verify_label_does_not_exist(CKK_AES, str(label), self.session)
|
||||||
self.pkcs11.generate_key(CKK_AES, int(length), CKM_AES_KEY_GEN,
|
self.pkcs11.generate_key(CKK_AES, int(length), CKM_AES_KEY_GEN,
|
||||||
self.session, str(label),
|
self.session, str(label),
|
||||||
@ -234,9 +243,13 @@ class HSMCommands(object):
|
|||||||
help='The label of the Master HMAC key')
|
help='The label of the Master HMAC key')
|
||||||
@args('--key-type', '-t', metavar='<key type>', dest='keytype',
|
@args('--key-type', '-t', metavar='<key type>', dest='keytype',
|
||||||
default='CKK_AES', help='The HMAC Key Type (e.g. CKK_AES)')
|
default='CKK_AES', help='The HMAC Key Type (e.g. CKK_AES)')
|
||||||
|
@args('--hmac-wrap-mechanism', metavar='<hmac key wrap mechanism>',
|
||||||
|
dest='hmacwrap', default='CKM_SHA256_HMAC',
|
||||||
|
help='HMAC Key wrap mechanism, default is CKM_SHA256_HMAC')
|
||||||
def check_hmac(self, passphrase, libpath=None, slotid=None, label=None,
|
def check_hmac(self, passphrase, libpath=None, slotid=None, label=None,
|
||||||
keytype=None):
|
keytype=None, hmacwrap=None):
|
||||||
self._create_pkcs11_session(str(passphrase), str(libpath), int(slotid))
|
self._create_pkcs11_session(str(passphrase), str(libpath),
|
||||||
|
int(slotid), str(hmacwrap))
|
||||||
handle = self.pkcs11.get_key_handle(str(keytype), str(label),
|
handle = self.pkcs11.get_key_handle(str(keytype), str(label),
|
||||||
self.session)
|
self.session)
|
||||||
self.pkcs11.return_session(self.session)
|
self.pkcs11.return_session(self.session)
|
||||||
@ -262,9 +275,13 @@ class HSMCommands(object):
|
|||||||
help='The length in bytes of the Master HMAC Key (default is 32)')
|
help='The length in bytes of the Master HMAC Key (default is 32)')
|
||||||
@args('--mechanism', '-m', metavar='<mechanism>',
|
@args('--mechanism', '-m', metavar='<mechanism>',
|
||||||
default='CKM_AES_KEY_GEN', help='The HMAC Key Generation mechanism')
|
default='CKM_AES_KEY_GEN', help='The HMAC Key Generation mechanism')
|
||||||
|
@args('--hmac-wrap-mechanism', metavar='<hmac key wrap mechanism>',
|
||||||
|
dest='hmacwrap', default='CKM_SHA256_HMAC',
|
||||||
|
help='HMAC Key wrap mechanism, default is CKM_SHA256_HMAC')
|
||||||
def gen_hmac(self, passphrase, libpath=None, slotid=None, label=None,
|
def gen_hmac(self, passphrase, libpath=None, slotid=None, label=None,
|
||||||
keytype=None, mechanism=None, length=None):
|
keytype=None, mechanism=None, length=None, hmacwrap=None):
|
||||||
self._create_pkcs11_session(str(passphrase), str(libpath), int(slotid))
|
self._create_pkcs11_session(str(passphrase), str(libpath), int(slotid),
|
||||||
|
str(hmacwrap))
|
||||||
self._verify_label_does_not_exist(str(keytype), str(label),
|
self._verify_label_does_not_exist(str(keytype), str(label),
|
||||||
self.session)
|
self.session)
|
||||||
self.pkcs11.generate_key(str(keytype), int(length), str(mechanism),
|
self.pkcs11.generate_key(str(keytype), int(length), str(mechanism),
|
||||||
@ -282,11 +299,13 @@ class HSMCommands(object):
|
|||||||
rewrapper.execute(dryrun)
|
rewrapper.execute(dryrun)
|
||||||
rewrapper.pkcs11.return_session(rewrapper.hsm_session)
|
rewrapper.pkcs11.return_session(rewrapper.hsm_session)
|
||||||
|
|
||||||
def _create_pkcs11_session(self, passphrase, libpath, slotid):
|
def _create_pkcs11_session(self, passphrase, libpath, slotid,
|
||||||
|
hmacwrap):
|
||||||
self.pkcs11 = pkcs11.PKCS11(
|
self.pkcs11 = pkcs11.PKCS11(
|
||||||
library_path=libpath, login_passphrase=passphrase,
|
library_path=libpath, login_passphrase=passphrase,
|
||||||
rw_session=True, slot_id=slotid,
|
rw_session=True, slot_id=slotid,
|
||||||
encryption_mechanism='CKM_AES_CBC',
|
encryption_mechanism='CKM_AES_CBC',
|
||||||
|
hmac_keywrap_mechanism=hmacwrap
|
||||||
)
|
)
|
||||||
self.session = self.pkcs11.get_session()
|
self.session = self.pkcs11.get_session()
|
||||||
|
|
||||||
|
@ -69,6 +69,9 @@ p11_crypto_plugin_opts = [
|
|||||||
cfg.StrOpt('hmac_keygen_mechanism',
|
cfg.StrOpt('hmac_keygen_mechanism',
|
||||||
help=u._('HMAC Key Generation Algorithm'),
|
help=u._('HMAC Key Generation Algorithm'),
|
||||||
default='CKM_AES_KEY_GEN'),
|
default='CKM_AES_KEY_GEN'),
|
||||||
|
cfg.StrOpt('hmac_keywrap_mechanism',
|
||||||
|
help=u._('HMAC key wrap mechanism'),
|
||||||
|
default='CKM_SHA256_HMAC'),
|
||||||
cfg.StrOpt('seed_file',
|
cfg.StrOpt('seed_file',
|
||||||
help=u._('File to pull entropy for seeding RNG'),
|
help=u._('File to pull entropy for seeding RNG'),
|
||||||
default=''),
|
default=''),
|
||||||
@ -307,6 +310,7 @@ class P11CryptoPlugin(plugin.CryptoPluginBase):
|
|||||||
seed_random_buffer=seed_random_buffer,
|
seed_random_buffer=seed_random_buffer,
|
||||||
generate_iv=plugin_conf.aes_gcm_generate_iv,
|
generate_iv=plugin_conf.aes_gcm_generate_iv,
|
||||||
always_set_cka_sensitive=plugin_conf.always_set_cka_sensitive,
|
always_set_cka_sensitive=plugin_conf.always_set_cka_sensitive,
|
||||||
|
hmac_keywrap_mechanism=plugin_conf.hmac_keywrap_mechanism
|
||||||
)
|
)
|
||||||
|
|
||||||
def _reinitialize_pkcs11(self):
|
def _reinitialize_pkcs11(self):
|
||||||
|
@ -134,6 +134,7 @@ CKA_SUPPORTED_CMS_ATTRIBUTES = 0x503
|
|||||||
CKM_SHA256_HMAC = 0x251
|
CKM_SHA256_HMAC = 0x251
|
||||||
CKM_AES_KEY_GEN = 0x1080
|
CKM_AES_KEY_GEN = 0x1080
|
||||||
CKM_AES_CBC = 0x1082
|
CKM_AES_CBC = 0x1082
|
||||||
|
CKM_AES_MAC = 0x1083
|
||||||
CKM_AES_CBC_PAD = 0x1085
|
CKM_AES_CBC_PAD = 0x1085
|
||||||
CKM_AES_GCM = 0x1087
|
CKM_AES_GCM = 0x1087
|
||||||
CKM_AES_KEY_WRAP = 0x1090
|
CKM_AES_KEY_WRAP = 0x1090
|
||||||
@ -158,9 +159,15 @@ _KEY_GEN_MECHANISMS = {
|
|||||||
'CKM_GENERIC_SECRET_KEY_GEN': CKM_GENERIC_SECRET_KEY_GEN,
|
'CKM_GENERIC_SECRET_KEY_GEN': CKM_GENERIC_SECRET_KEY_GEN,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_KEY_WRAP_MECHANISMS = {
|
||||||
|
'CKM_SHA256_HMAC': CKM_SHA256_HMAC,
|
||||||
|
'CKM_AES_MAC': CKM_AES_MAC
|
||||||
|
}
|
||||||
|
|
||||||
CKM_NAMES = dict()
|
CKM_NAMES = dict()
|
||||||
CKM_NAMES.update(_ENCRYPTION_MECHANISMS)
|
CKM_NAMES.update(_ENCRYPTION_MECHANISMS)
|
||||||
CKM_NAMES.update(_KEY_GEN_MECHANISMS)
|
CKM_NAMES.update(_KEY_GEN_MECHANISMS)
|
||||||
|
CKM_NAMES.update(_KEY_WRAP_MECHANISMS)
|
||||||
|
|
||||||
ERROR_CODES = {
|
ERROR_CODES = {
|
||||||
1: 'CKR_CANCEL',
|
1: 'CKR_CANCEL',
|
||||||
@ -356,7 +363,8 @@ class PKCS11(object):
|
|||||||
encryption_mechanism=None,
|
encryption_mechanism=None,
|
||||||
ffi=None, algorithm=None,
|
ffi=None, algorithm=None,
|
||||||
seed_random_buffer=None,
|
seed_random_buffer=None,
|
||||||
generate_iv=None, always_set_cka_sensitive=None):
|
generate_iv=None, always_set_cka_sensitive=None,
|
||||||
|
hmac_keywrap_mechanism='CKM_SHA256_HMAC'):
|
||||||
if algorithm:
|
if algorithm:
|
||||||
LOG.warning("WARNING: Using deprecated 'algorithm' argument.")
|
LOG.warning("WARNING: Using deprecated 'algorithm' argument.")
|
||||||
encryption_mechanism = encryption_mechanism or algorithm
|
encryption_mechanism = encryption_mechanism or algorithm
|
||||||
@ -369,6 +377,9 @@ class PKCS11(object):
|
|||||||
'_{}_encrypt'.format(encryption_mechanism)
|
'_{}_encrypt'.format(encryption_mechanism)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if hmac_keywrap_mechanism not in _KEY_WRAP_MECHANISMS:
|
||||||
|
raise ValueError("Invalid HMAC keywrap mechanism")
|
||||||
|
|
||||||
self.ffi = ffi or build_ffi()
|
self.ffi = ffi or build_ffi()
|
||||||
self.lib = self.ffi.dlopen(library_path)
|
self.lib = self.ffi.dlopen(library_path)
|
||||||
rv = self.lib.C_Initialize(self.ffi.NULL)
|
rv = self.lib.C_Initialize(self.ffi.NULL)
|
||||||
@ -386,6 +397,7 @@ class PKCS11(object):
|
|||||||
self.gcmtagsize = 16
|
self.gcmtagsize = 16
|
||||||
self.generate_iv = generate_iv
|
self.generate_iv = generate_iv
|
||||||
self.always_set_cka_sensitive = always_set_cka_sensitive
|
self.always_set_cka_sensitive = always_set_cka_sensitive
|
||||||
|
self.hmac_keywrap_mechanism = CKM_NAMES[hmac_keywrap_mechanism]
|
||||||
|
|
||||||
# Validate configuration and RNG
|
# Validate configuration and RNG
|
||||||
session = self.get_session()
|
session = self.get_session()
|
||||||
@ -674,7 +686,7 @@ class PKCS11(object):
|
|||||||
|
|
||||||
def compute_hmac(self, hmac_key, data, session):
|
def compute_hmac(self, hmac_key, data, session):
|
||||||
mech = self.ffi.new("CK_MECHANISM *")
|
mech = self.ffi.new("CK_MECHANISM *")
|
||||||
mech.mechanism = CKM_SHA256_HMAC
|
mech.mechanism = self.hmac_keywrap_mechanism
|
||||||
rv = self.lib.C_SignInit(session, mech, hmac_key)
|
rv = self.lib.C_SignInit(session, mech, hmac_key)
|
||||||
self._check_error(rv)
|
self._check_error(rv)
|
||||||
|
|
||||||
@ -687,7 +699,7 @@ class PKCS11(object):
|
|||||||
|
|
||||||
def verify_hmac(self, hmac_key, sig, data, session):
|
def verify_hmac(self, hmac_key, sig, data, session):
|
||||||
mech = self.ffi.new("CK_MECHANISM *")
|
mech = self.ffi.new("CK_MECHANISM *")
|
||||||
mech.mechanism = CKM_SHA256_HMAC
|
mech.mechanism = self.hmac_keywrap_mechanism
|
||||||
|
|
||||||
rv = self.lib.C_VerifyInit(session, mech, hmac_key)
|
rv = self.lib.C_VerifyInit(session, mech, hmac_key)
|
||||||
self._check_error(rv)
|
self._check_error(rv)
|
||||||
|
@ -63,6 +63,8 @@ class WhenTestingP11CryptoPlugin(utils.BaseTestCase):
|
|||||||
self.cfg_mock.p11_crypto_plugin.encryption_mechanism = 'CKM_AES_CBC'
|
self.cfg_mock.p11_crypto_plugin.encryption_mechanism = 'CKM_AES_CBC'
|
||||||
self.cfg_mock.p11_crypto_plugin.seed_file = ''
|
self.cfg_mock.p11_crypto_plugin.seed_file = ''
|
||||||
self.cfg_mock.p11_crypto_plugin.seed_length = 32
|
self.cfg_mock.p11_crypto_plugin.seed_length = 32
|
||||||
|
self.cfg_mock.p11_crypto_plugin.hmac_keywrap_mechanism = \
|
||||||
|
'CKM_SHA256_HMAC'
|
||||||
|
|
||||||
self.plugin_name = 'Test PKCS11 plugin'
|
self.plugin_name = 'Test PKCS11 plugin'
|
||||||
self.cfg_mock.p11_crypto_plugin.plugin_name = self.plugin_name
|
self.cfg_mock.p11_crypto_plugin.plugin_name = self.plugin_name
|
||||||
|
@ -60,12 +60,14 @@ class WhenTestingPKCS11(utils.BaseTestCase):
|
|||||||
self.cfg_mock.rw_session = False
|
self.cfg_mock.rw_session = False
|
||||||
self.cfg_mock.slot_id = 1
|
self.cfg_mock.slot_id = 1
|
||||||
self.cfg_mock.encryption_mechanism = 'CKM_AES_CBC'
|
self.cfg_mock.encryption_mechanism = 'CKM_AES_CBC'
|
||||||
|
self.cfg_mock.hmac_keywrap_mechanism = 'CKM_SHA256_HMAC'
|
||||||
|
|
||||||
self.pkcs11 = pkcs11.PKCS11(
|
self.pkcs11 = pkcs11.PKCS11(
|
||||||
self.cfg_mock.library_path, self.cfg_mock.login_passphrase,
|
self.cfg_mock.library_path, self.cfg_mock.login_passphrase,
|
||||||
self.cfg_mock.rw_session, self.cfg_mock.slot_id,
|
self.cfg_mock.rw_session, self.cfg_mock.slot_id,
|
||||||
self.cfg_mock.encryption_mechanism,
|
self.cfg_mock.encryption_mechanism,
|
||||||
ffi=self.ffi
|
ffi=self.ffi,
|
||||||
|
hmac_keywrap_mechanism=self.cfg_mock.hmac_keywrap_mechanism
|
||||||
)
|
)
|
||||||
|
|
||||||
def _generate_random(self, session, buf, length):
|
def _generate_random(self, session, buf, length):
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- |
|
||||||
|
Fixed Story #2004734: Added a new option 'hmac_keywrap_mechanism' to make
|
||||||
|
the mechanism used to calculate a HMAC from an wrapped PKEK configurable.
|
||||||
|
This was introduced because of an problem with Utimaco HSMs which throw an
|
||||||
|
'CKR_MECHANISM_INVALID' error, e.g. when a new PKEK is generated. For
|
||||||
|
Utimaco HSMs, 'hmac_keywrap_mechanism' should be set to 'CKM_AES_MAC' in
|
||||||
|
barbican.conf.
|
Loading…
x
Reference in New Issue
Block a user