def sym_key_params(request, auth_session, usage_set): """ Generate a key, setting the usage limit by the method described in ``usage_set`` Return that key handle. """ usage_type, limit = usage_set key_gen, mechanism = request.param key_template = get_session_template(get_default_key_template(key_gen)) usage_template = {CKA_USAGE_LIMIT: limit} if usage_type in ("create", "both", "create_then_use"): key_template.update(usage_template) h_key = c_generate_key_ex(auth_session, mechanism=key_gen, template=key_template) try: if usage_type in ("create_then_use", ): c_encrypt_ex(auth_session, h_key, b'a' * 2048, mechanism={"mech_type": mechanism}) if usage_type in ("setattr", "both", "create_then_use"): c_set_attribute_value_ex(auth_session, h_key, usage_template) yield SymParams(h_key, mechanism) finally: c_destroy_object(auth_session, h_key)
def test_usagelimit_exceed_sym(self, auth_session, sym_key_params): """Test that changing the usage limit works as expected Gen key w/ limit = 5 Set limit = 2 Use key 2x Verify next usage returns CKR_KEY_NOT_ACTIVE """ LOG.info( "Verify that crypto operation returns error CKR_KEY_NOT_ACTIVE \ if user try to use crypto object more than limit set on CKA_USAGE_LIMIT" ) usage_lim_template = {CKA_USAGE_LIMIT: 2} key, mechanism = sym_key_params c_set_attribute_value_ex(auth_session, key, usage_lim_template) c_encrypt_ex(auth_session, key, b'a' * 2048, mechanism=mechanism) c_encrypt_ex(auth_session, key, b'a' * 2048, mechanism=mechanism) return_val, data = c_encrypt(auth_session, key, b'a' * 2048, mechanism=mechanism) py_template = c_get_attribute_value_ex( auth_session, key, template={CKA_USAGE_COUNT: None}) usage_val_out = py_template[CKA_USAGE_COUNT] LOG.info("CKA_USAGE_COUNT reported by C_GetAttributeValue: %s", usage_val_out) assert return_val == CKR_KEY_NOT_ACTIVE, "Key should be inactive -- exceeded usage count!"
def test_usagelimit_sym(self, auth_session, sym_key_params, usage_set): """Test: Verify that CKA_USAGE_COUNT attribute increments as user uses the symmetric crypto object Gen key w/ limit set to 5 Use key 5x Verify usage count == 5 """ _, new_limit = usage_set LOG.info( "Test: Verify that CKA_USAGE_COUNT attribute increments as user \ uses the symmetric crypto object") key, mechanism = sym_key_params for _ in range(5): c_encrypt_ex(auth_session, key, b'a' * 2048, mechanism={"mech_type": mechanism}) py_template = c_get_attribute_value_ex( auth_session, key, template={CKA_USAGE_COUNT: None}) usage_val_out = py_template[CKA_USAGE_COUNT] LOG.info("CKA_USAGE_COUNT reported by C_GetAttributeValue: %s", usage_val_out) assert new_limit == usage_val_out, "reported USAGE LIMIT does not match"
def test_set_attribute_usage_count_check_error_CKR_KEY_NOT_ACTIVE_3des( self): """Test: Verify that crypto operation returns error CKR_KEY_NOT_ACTIVE if user try to use crypto object more than limit set on CKA_USAGE_LIMIT Procedure: Generate a 3DES key Use C_SetAttributeValue to set CKA_USAGE_LIMIT to 2 Use RSA public key 3 times for encryption """ LOG.info( "Verify that crypto operation returns error CKR_KEY_NOT_ACTIVE \ if user try to use crypto object more than limit set on CKA_USAGE_LIMIT" ) usage_lim_template = {CKA_USAGE_LIMIT: 2} h_key = c_generate_key_ex(self.h_session, mechanism=CKM_DES3_KEY_GEN, template=CKM_DES3_KEY_GEN_TEMP) LOG.info("Called c-generate: Key handle -" + str(h_key)) c_set_attribute_value_ex(self.h_session, h_key, usage_lim_template) c_encrypt_ex(self.h_session, h_key, b'a' * 2048, mechanism={"mech_type": CKM_DES3_ECB}) c_encrypt_ex(self.h_session, h_key, b'a' * 2048, mechanism={"mech_type": CKM_DES3_ECB}) return_val, data = c_encrypt(self.h_session, h_key, b'a' * 2048, mechanism={"mech_type": CKM_DES3_ECB}) LOG.info("Called C_Encrypt, return code: %s", return_val) py_template = c_get_attribute_value_ex( self.h_session, h_key, template={CKA_USAGE_COUNT: None}) usage_val_out = py_template[CKA_USAGE_COUNT] LOG.info("CKA_USAGE_COUNT reported by C_GetAttributeValue: %s", usage_val_out) assert return_val == CKR_KEY_NOT_ACTIVE, "reported error code does not match"
def test_usage_limit_attribute_check_Assym(self): """Test: Verify that CKA_USAGE_COUNT attribute increments as user use the assymetric crypto object Procedure: Generate a RSA Key pair Use C_SetAttributeValue to set CKA_USAGE_LIMIT to 2 Use RSA public key twice for encryption Use C_getAttributeValue to verify that CKA_USAGE_COUNT is 2 """ LOG.info( "Test: Verify that CKA_USAGE_COUNT attribute increments as user \ use the assymetric crypto object") usage_lim_template = {CKA_USAGE_LIMIT: 2} usage_count = 2 h_pbkey, h_prkey = c_generate_key_pair_ex( self.h_session, mechanism=CKM_RSA_PKCS_KEY_PAIR_GEN, pbkey_template=CKM_RSA_PKCS_KEY_PAIR_GEN_PUBTEMP, prkey_template=CKM_RSA_PKCS_KEY_PAIR_GEN_PRIVTEMP) LOG.info( "Called c-generate: Public Key handle -%s Private Key Handle -%s", h_pbkey, h_prkey) c_set_attribute_value_ex(self.h_session, h_pbkey, usage_lim_template) c_encrypt_ex(self.h_session, h_pbkey, b'a' * 20, mechanism={"mech_type": CKM_RSA_PKCS}) c_encrypt_ex(self.h_session, h_pbkey, b'a' * 20, mechanism={"mech_type": CKM_RSA_PKCS}) py_template = c_get_attribute_value_ex( self.h_session, h_pbkey, template={CKA_USAGE_COUNT: None}) usage_val_out = py_template[CKA_USAGE_COUNT] LOG.info("CKA_USAGE_COUNT reported by C_GetAttributeValue: %s", usage_val_out) assert usage_count == usage_val_out, "reported USAGE LIMIT does not match"
def test_set_attribute_usage_count_check_error_CKR_KEY_NOT_ACTIVE_rsa( self): """Test: Verify that crypto operation returns error CKR_KEY_NOT_ACTIVE if user try to use crypto object more than limit set on CKA_USAGE_LIMIT Procedure: Generate a RSA Key pair Use C_SetAttributeValue to set CKA_USAGE_LIMIT to 2 Use RSA public key 3 times for encryption """ usage_lim_template = {CKA_USAGE_LIMIT: 2} h_pbkey, h_prkey = c_generate_key_pair_ex( self.h_session, mechanism=CKM_RSA_PKCS_KEY_PAIR_GEN, pbkey_template=CKM_RSA_PKCS_KEY_PAIR_GEN_PUBTEMP, prkey_template=CKM_RSA_PKCS_KEY_PAIR_GEN_PRIVTEMP) LOG.info( "Called c-generate: Public Key handle -%s Private Key Handle - %s", h_pbkey, h_prkey) c_set_attribute_value_ex(self.h_session, h_pbkey, usage_lim_template) c_encrypt_ex(self.h_session, h_pbkey, b'a' * 20, mechanism={"mech_type": CKM_RSA_PKCS}) c_encrypt_ex(self.h_session, h_pbkey, b'a' * 20, mechanism={"mech_type": CKM_RSA_PKCS}) return_val, data = c_encrypt(self.h_session, h_pbkey, b'a' * 20, mechanism={"mech_type": CKM_RSA_PKCS}) LOG.info("Called C_Encrypt, return code: %s", return_val) py_template = c_get_attribute_value_ex( self.h_session, h_pbkey, template={CKA_USAGE_COUNT: None}) usage_val_out = py_template[CKA_USAGE_COUNT] assert return_val == CKR_KEY_NOT_ACTIVE, "reported error code does not match"
def test_usage_limit_attribute_check_sym_des(self): """Test: Verify that CKA_USAGE_COUNT attribute increments as user use the symmetric crypto object Procedure: Generate a DES Key Use C_SetAttributeValue to set CKA_USAGE_LIMIT to 2 Use des key twice for encryption Use C_getAttributeValue to verify that CKA_USAGE_COUNT is 2 """ LOG.info( "Test: Verify that CKA_USAGE_COUNT attribute increments as user \ use the symmetric crypto object") usage_lim_template = {CKA_USAGE_LIMIT: 2} usage_count = 2 h_key = c_generate_key_ex(self.h_session, mechanism=CKM_DES_KEY_GEN, template=CKM_DES_KEY_GEN_TEMP) LOG.info("Called c-generate: Key handle -%s", h_key) c_set_attribute_value_ex(self.h_session, h_key, usage_lim_template) c_encrypt_ex(self.h_session, h_key, b'a' * 2048, mechanism={"mech_type": CKM_DES_ECB}) c_encrypt_ex(self.h_session, h_key, b'a' * 2048, mechanism={"mech_type": CKM_DES_ECB}) py_template = c_get_attribute_value_ex( self.h_session, h_key, template={CKA_USAGE_COUNT: None}) usage_val_out = py_template[CKA_USAGE_COUNT] LOG.info("CKA_USAGE_COUNT reported by C_GetAttributeValue: %s", usage_val_out) assert usage_count == usage_val_out, "reported USAGE LIMIT does not match"
def encrypt(password, kek_label, plaintext_path): ''' Encrypt plain text to cipher text password - string CryptoUser role password kek_label - string label of decryption key in HSM plaintext_path - path of base64 encoded data to be encrypted ''' plaintext = open(plaintext_path, 'rb').read() encrypted = None i = 0 while i < 2: try: auth_session = None _initialize() auth_session = c_open_session_ex(i) login_ex(auth_session, i, password, CKU_CRYPTO_USER) kek_handle = None kek_handle = c_find_objects_ex(auth_session, { CKA_KEY_TYPE: CKK_AES, CKA_LABEL: kek_label }, 1) if kek_handle: params = {"iv": list(range(16)), "AAD": [], "ulTagBits": 128} mechanism = Mechanism(mech_type=CKM_AES_GCM, params=params) encrypted = c_encrypt_ex(auth_session, kek_handle[0], plaintext, mechanism) encrypted = array.array('B', list( range(16))).tostring() + encrypted break else: i += 1 except LunaCallException: print("Exception running key mgmt operation on slot " + str(i)) print(traceback.format_exc()) i += 1 finally: if auth_session: c_logout_ex(auth_session) c_close_session_ex(auth_session) c_finalize_ex() if encrypted: ciphertext = base64.b64encode(encrypted) return ciphertext else: raise Exception("Failed to encrypt DEK")
def test_x9_key_derive(self, auth_session, curve_type): """ Test we can do X9 key derivation """ derived_key2 = derived_key1 = pub_key1 = pub_key2 = prv_key2 = prv_key1 = None derived_template = { CKA_CLASS: CKO_SECRET_KEY, CKA_KEY_TYPE: CKK_DES, CKA_ENCRYPT: True, CKA_DECRYPT: True, CKA_PRIVATE: True, CKA_SENSITIVE: True } pub_temp, priv_temp = get_default_key_pair_template( CKM_ECDSA_KEY_PAIR_GEN) priv_temp = get_session_template(priv_temp) pub_temp = get_session_template(pub_temp) pub_temp[CKA_ECDSA_PARAMS] = curve_list[curve_type] pub_key1, prv_key1 = c_generate_key_pair_ex(auth_session, CKM_ECDSA_KEY_PAIR_GEN, pbkey_template=pub_temp, prkey_template=priv_temp) try: pub_key2, prv_key2 = c_generate_key_pair_ex( auth_session, CKM_ECDSA_KEY_PAIR_GEN, pbkey_template=pub_temp, prkey_template=priv_temp) pub_key1_raw = c_get_attribute_value_ex( auth_session, pub_key1, {CKA_EC_POINT: None})[CKA_EC_POINT] pub_key2_raw = c_get_attribute_value_ex( auth_session, pub_key2, {CKA_EC_POINT: None})[CKA_EC_POINT] derived_key1 = c_derive_key_ex(auth_session, h_base_key=prv_key2, template=derived_template, mechanism={ "mech_type": CKM_ECDH1_DERIVE, "params": { "kdf": CKD_NULL, "sharedData": None, "publicData": pub_key1_raw } }) derived_key2 = c_derive_key_ex(auth_session, h_base_key=prv_key1, template=derived_template, mechanism={ "mech_type": CKM_ECDH1_DERIVE, "params": { "kdf": CKD_NULL, "sharedData": None, "publicData": pub_key2_raw } }) cipher_data = c_encrypt_ex(auth_session, derived_key1, data=DATA, mechanism=CKM_DES_ECB) restored_text = c_decrypt_ex(auth_session, derived_key2, cipher_data, mechanism=CKM_DES_ECB) assert DATA == restored_text.rstrip(b'\x00') finally: for key in (pub_key1, prv_key1, pub_key2, prv_key2, derived_key1, derived_key2): if key: c_destroy_object(auth_session, key)
def test_symmetric_key_expiry_des(self): """Test: Verify that user is not able to use the symmetric object after date specified in CKA_END_DATE attribute Procedure: Generate a DES Key des1 Use des1 in encrypt operation. Should work fine Using audit role, change the date of HSM to 12/31/2013 Use des1 in encrypt operation """ logger.info( "Test: Verify that user is not able to use the symmetric object after date " "specified in \ CKA_END_DATE attribute") end_d = {'year': b"2013", 'month': b"12", 'day': b"31"} CKM_KEY_GEN_TEMP = { CKA_CLASS: CKO_SECRET_KEY, CKA_KEY_TYPE: CKK_DES, CKA_TOKEN: True, CKA_SENSITIVE: True, CKA_PRIVATE: True, CKA_ENCRYPT: True, CKA_DECRYPT: True, CKA_SIGN: True, CKA_VERIFY: True, CKA_WRAP: True, CKA_UNWRAP: True, CKA_DERIVE: True, CKA_VALUE_LEN: 8, CKA_EXTRACTABLE: True, CKA_LABEL: b"DES Key", CKA_END_DATE: end_d } h_key = c_generate_key_ex(self.h_session, flavor=CKM_DES_KEY_GEN, template=CKM_KEY_GEN_TEMP) logger.info("Called c-generate: Key handle -" + str(h_key)) c_encrypt_ex(self.h_session, CKM_DES_ECB, h_key, b"a" * 512) c_logout_ex(self.h_session) c_close_session_ex(self.h_session) ca_init_audit_ex(self.admin_slot, AUDITOR_PASSWORD, AUDITOR_LABEL) h_session2 = c_open_session_ex(slot_num=self.admin_slot, flags=(CKF_SERIAL_SESSION | CKF_AUDIT_SESSION)) login_ex(h_session2, self.admin_slot, AUDITOR_PASSWORD, CKU_AUDIT) dt = datetime(2014, 1, 31) epoch = datetime.utcfromtimestamp(0) delta = dt - epoch hsm_dt = delta.total_seconds() hsm_new_date = int(hsm_dt) ca_time_sync_ex(h_session2, hsm_new_date) hsm_time = ca_get_time_ex(h_session2) c_logout_ex(h_session2) c_close_session_ex(h_session2) h_session = c_open_session_ex(slot_num=self.admin_slot) login_ex(h_session, self.admin_slot, CO_PASSWORD, CKU_USER) return_val = c_encrypt(h_session, h_key, b"This is some data to sign .. ", CKM_DES_ECB) assert return_val == CKR_KEY_NOT_ACTIVE, "return value should be CKR_KEY_NOT_ACTIVE" c_logout_ex(h_session) c_close_session_ex(h_session)
def test_asymmetric_key_expiry_rsa(self): """Test: Verify that user is not able to use the rsa asymmetric object after date specified in CKA_END_DATE attribute Procedure: Generate a rsa Key rsa1 Use des1 in encrypt operation. Should work fine Using audit role, change the date of HSM to 12/31/2013 Use rsa1 in encrypt operation """ logger.info( "Test: Verify that user is not able to use the rsa asymmetric object after " "date specified in \ CKA_END_DATE attribute") end_d = {'year': b"2013", 'month': b"12", 'day': b"31"} CKM_RSA_PKCS_KEY_PAIR_GEN_PUBTEMP = { CKA_TOKEN: True, CKA_PRIVATE: True, CKA_MODIFIABLE: True, CKA_ENCRYPT: True, CKA_VERIFY: True, CKA_WRAP: True, CKA_MODULUS_BITS: 1024, # long 0 - MAX_RSA_KEY_NBITS CKA_PUBLIC_EXPONENT: 3, # byte CKA_END_DATE: end_d, CKA_LABEL: "RSA Public Key" } CKM_RSA_PKCS_KEY_PAIR_GEN_PRIVTEMP = { CKA_TOKEN: True, CKA_PRIVATE: True, CKA_SENSITIVE: True, CKA_MODIFIABLE: True, CKA_EXTRACTABLE: True, CKA_DECRYPT: True, CKA_SIGN: True, CKA_UNWRAP: True, CKA_END_DATE: end_d, CKA_LABEL: b"RSA Private Key" } h_pbkey, h_prkey = c_generate_key_pair_ex( self.h_session, flavor=CKM_RSA_PKCS_KEY_PAIR_GEN, pbkey_template=CKM_RSA_PKCS_KEY_PAIR_GEN_PUBTEMP, prkey_template=CKM_RSA_PKCS_KEY_PAIR_GEN_PRIVTEMP, mech=None) logger.info("Called c-generate: Public Key handle -" + str(h_pbkey) + "Private Key Handle" + str(h_prkey)) c_encrypt_ex(self.h_session, CKM_RSA_PKCS, h_pbkey, b"This is some data to sign .. ") c_logout_ex(self.h_session) c_close_session_ex(self.h_session) ca_init_audit_ex(self.admin_slot, AUDITOR_PASSWORD, AUDITOR_LABEL) h_session2 = c_open_session_ex(slot_num=self.admin_slot, flags=(CKF_SERIAL_SESSION | CKF_AUDIT_SESSION)) login(h_session2, self.admin_slot, AUDITOR_PASSWORD, CKU_AUDIT) dt = datetime(2014, 1, 31) epoch = datetime.utcfromtimestamp(0) delta = dt - epoch hsm_dt = delta.total_seconds() hsm_new_date = int(hsm_dt) ca_time_sync_ex(h_session2, hsm_new_date) hsm_time = ca_get_time_ex(h_session2) # print datetime.fromtimestamp(float(hsm_time.value)) c_logout_ex(h_session2) c_close_session_ex(h_session2) h_session = c_open_session_ex(slot_num=self.admin_slot) login_ex(h_session, self.admin_slot, CO_PASSWORD, CKU_USER) return_val = c_encrypt(h_session, h_pbkey, b"This is some data to sign .. ", CKM_RSA_PKCS) logger.info("Called C_Encrypt, return code: " + str(return_val)) assert return_val == CKR_KEY_NOT_ACTIVE, "Expected return code is CKR_KEY_NOT_ACTIVE"