Merge "Made HMAC Key Wrap mechanism configurable"
This commit is contained in:
commit
4c0ddda941
@ -184,9 +184,14 @@ class HSMCommands(object):
|
||||
help='Password to login to PKCS11 session')
|
||||
@args('--label', '-L', metavar='<label>', default='primarymkek',
|
||||
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'
|
||||
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)
|
||||
self.pkcs11.return_session(self.session)
|
||||
if not handle:
|
||||
@ -208,11 +213,15 @@ class HSMCommands(object):
|
||||
@args('--length', '-l', metavar='<length>', default=32,
|
||||
help='The length in bytes of the Master Key Encryption Key'
|
||||
' (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,
|
||||
length=None):
|
||||
length=None, hmacwrap=None):
|
||||
CKK_AES = 'CKK_AES'
|
||||
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.pkcs11.generate_key(CKK_AES, int(length), CKM_AES_KEY_GEN,
|
||||
self.session, str(label),
|
||||
@ -234,9 +243,13 @@ class HSMCommands(object):
|
||||
help='The label of the Master HMAC key')
|
||||
@args('--key-type', '-t', metavar='<key type>', dest='keytype',
|
||||
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,
|
||||
keytype=None):
|
||||
self._create_pkcs11_session(str(passphrase), str(libpath), int(slotid))
|
||||
keytype=None, hmacwrap=None):
|
||||
self._create_pkcs11_session(str(passphrase), str(libpath),
|
||||
int(slotid), str(hmacwrap))
|
||||
handle = self.pkcs11.get_key_handle(str(keytype), str(label),
|
||||
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)')
|
||||
@args('--mechanism', '-m', metavar='<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,
|
||||
keytype=None, mechanism=None, length=None):
|
||||
self._create_pkcs11_session(str(passphrase), str(libpath), int(slotid))
|
||||
keytype=None, mechanism=None, length=None, hmacwrap=None):
|
||||
self._create_pkcs11_session(str(passphrase), str(libpath), int(slotid),
|
||||
str(hmacwrap))
|
||||
self._verify_label_does_not_exist(str(keytype), str(label),
|
||||
self.session)
|
||||
self.pkcs11.generate_key(str(keytype), int(length), str(mechanism),
|
||||
@ -282,11 +299,13 @@ class HSMCommands(object):
|
||||
rewrapper.execute(dryrun)
|
||||
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(
|
||||
library_path=libpath, login_passphrase=passphrase,
|
||||
rw_session=True, slot_id=slotid,
|
||||
encryption_mechanism='CKM_AES_CBC',
|
||||
hmac_keywrap_mechanism=hmacwrap
|
||||
)
|
||||
self.session = self.pkcs11.get_session()
|
||||
|
||||
|
@ -69,6 +69,9 @@ p11_crypto_plugin_opts = [
|
||||
cfg.StrOpt('hmac_keygen_mechanism',
|
||||
help=u._('HMAC Key Generation Algorithm'),
|
||||
default='CKM_AES_KEY_GEN'),
|
||||
cfg.StrOpt('hmac_keywrap_mechanism',
|
||||
help=u._('HMAC key wrap mechanism'),
|
||||
default='CKM_SHA256_HMAC'),
|
||||
cfg.StrOpt('seed_file',
|
||||
help=u._('File to pull entropy for seeding RNG'),
|
||||
default=''),
|
||||
@ -307,6 +310,7 @@ class P11CryptoPlugin(plugin.CryptoPluginBase):
|
||||
seed_random_buffer=seed_random_buffer,
|
||||
generate_iv=plugin_conf.aes_gcm_generate_iv,
|
||||
always_set_cka_sensitive=plugin_conf.always_set_cka_sensitive,
|
||||
hmac_keywrap_mechanism=plugin_conf.hmac_keywrap_mechanism
|
||||
)
|
||||
|
||||
def _reinitialize_pkcs11(self):
|
||||
|
@ -134,6 +134,7 @@ CKA_SUPPORTED_CMS_ATTRIBUTES = 0x503
|
||||
CKM_SHA256_HMAC = 0x251
|
||||
CKM_AES_KEY_GEN = 0x1080
|
||||
CKM_AES_CBC = 0x1082
|
||||
CKM_AES_MAC = 0x1083
|
||||
CKM_AES_CBC_PAD = 0x1085
|
||||
CKM_AES_GCM = 0x1087
|
||||
CKM_AES_KEY_WRAP = 0x1090
|
||||
@ -158,9 +159,15 @@ _KEY_GEN_MECHANISMS = {
|
||||
'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.update(_ENCRYPTION_MECHANISMS)
|
||||
CKM_NAMES.update(_KEY_GEN_MECHANISMS)
|
||||
CKM_NAMES.update(_KEY_WRAP_MECHANISMS)
|
||||
|
||||
ERROR_CODES = {
|
||||
1: 'CKR_CANCEL',
|
||||
@ -356,7 +363,8 @@ class PKCS11(object):
|
||||
encryption_mechanism=None,
|
||||
ffi=None, algorithm=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:
|
||||
LOG.warning("WARNING: Using deprecated 'algorithm' argument.")
|
||||
encryption_mechanism = encryption_mechanism or algorithm
|
||||
@ -369,6 +377,9 @@ class PKCS11(object):
|
||||
'_{}_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.lib = self.ffi.dlopen(library_path)
|
||||
rv = self.lib.C_Initialize(self.ffi.NULL)
|
||||
@ -386,6 +397,7 @@ class PKCS11(object):
|
||||
self.gcmtagsize = 16
|
||||
self.generate_iv = generate_iv
|
||||
self.always_set_cka_sensitive = always_set_cka_sensitive
|
||||
self.hmac_keywrap_mechanism = CKM_NAMES[hmac_keywrap_mechanism]
|
||||
|
||||
# Validate configuration and RNG
|
||||
session = self.get_session()
|
||||
@ -674,7 +686,7 @@ class PKCS11(object):
|
||||
|
||||
def compute_hmac(self, hmac_key, data, session):
|
||||
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)
|
||||
self._check_error(rv)
|
||||
|
||||
@ -687,7 +699,7 @@ class PKCS11(object):
|
||||
|
||||
def verify_hmac(self, hmac_key, sig, data, session):
|
||||
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)
|
||||
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.seed_file = ''
|
||||
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.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.slot_id = 1
|
||||
self.cfg_mock.encryption_mechanism = 'CKM_AES_CBC'
|
||||
self.cfg_mock.hmac_keywrap_mechanism = 'CKM_SHA256_HMAC'
|
||||
|
||||
self.pkcs11 = pkcs11.PKCS11(
|
||||
self.cfg_mock.library_path, self.cfg_mock.login_passphrase,
|
||||
self.cfg_mock.rw_session, self.cfg_mock.slot_id,
|
||||
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):
|
||||
|
@ -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…
Reference in New Issue
Block a user