def test_asym_encrypt_decrypt(self, m_type, params, asym_keys, auth_session, valid_mechanisms): """ test encryption decryption calls of asym. crypto's :param m_type: mechanism flavor :param params: extra params :param asym_keys: key fixture :param auth_session: """ if asym_keys.get(ASYM_TABLE[m_type]) is None: pytest.fail("No valid key found for {}".format( MECHANISM_LOOKUP_EXT[m_type][0])) expected_retcode = ret_val(m_type, RAW, valid_mechanisms) pub_key, prv_key = asym_keys[ASYM_TABLE[m_type]] mech = {"mech_type": m_type, "params": params} ret, decrypt_this = c_encrypt(auth_session, pub_key, RAW, mechanism=mech) self.verify_ret(ret, expected_retcode) if expected_retcode == CKR_OK: ret, decrypted_data = c_decrypt(auth_session, prv_key, decrypt_this, mechanism=mech) self.verify_ret(ret, expected_retcode) self.verify_data(RAW, decrypted_data.replace(b"\x00", b""))
def test_sym_encrypt_decrypt(self, m_type, params, data, sym_keys, auth_session, valid_mechanisms): """ test encryption decryption calls of sym. crypto's :param m_type: mechanism flavor :param params: extra params :param data: testing data :param sym_keys: key fixture :param auth_session: """ # Auto-fail when key-generation fails if sym_keys.get(SYM_TABLE[m_type]) is None: pytest.fail("No valid key found for {}".format( MECHANISM_LOOKUP_EXT[m_type][0])) exp_ret = ret_val(m_type, data, valid_mechanisms) h_key = sym_keys[SYM_TABLE[m_type]] # AES_GCM Requires smaller data sizes. if m_type == CKM_AES_GCM and data == PAD: data = b"a" * 0xff0 mech = {"mech_type": m_type, "params": params} ret, encrypted = c_encrypt(auth_session, h_key, data, mechanism=mech) self.verify_ret(ret, exp_ret) # If not expecting error, proceed with testing if exp_ret in (CKR_OK, KEY_SIZE_RANGE): ret, end_data = c_decrypt(auth_session, h_key, encrypted, mechanism=mech) self.verify_ret(ret, exp_ret) self.verify_data(data, end_data)
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_encrypt_wrap_unwrap_decrypt_key(self, mech, k_type, keys): """ Test that encrypt/decrypt works with wrapped keys :param mech: encryption mech :param k_type: key gen mech :param keys: keys fixture """ unwrap_temp = self.generate_unwrap_temp(k_type) h_key, h_wrap_key = keys[k_type] extra_p = EXTRA_PARAM[mech] if h_key is None or h_wrap_key is None: pytest.skip("No valid key found for {}".format(LOOKUP[mech][0])) # Encrypt some data data_to_encrypt = b"a" * 512 enc_mech = {"mech_type": mech} ret, encrypted_data = c_encrypt(self.h_session, h_key, data_to_encrypt, mechanism=enc_mech) self.verify_ret(ret, CKR_OK) # Wrap the key wrap_mech = {"mech_type": mech, "params": extra_p} ret, wrapped_key = c_wrap_key(self.h_session, h_wrap_key, h_key, mechanism=wrap_mech) self.verify_ret(ret, CKR_OK) h_unwrapped_key = None try: # Unwrap the Key ret, h_unwrapped_key = c_unwrap_key(self.h_session, h_wrap_key, wrapped_key, unwrap_temp, mechanism=wrap_mech) self.verify_ret(ret, CKR_OK) # Decrypt the data ret, decrypted_string = c_decrypt(self.h_session, h_unwrapped_key, encrypted_data, mechanism=enc_mech) self.verify_ret(ret, CKR_OK) assert decrypted_string == data_to_encrypt, \ "The decrypted data should be the same as the data that was encrypted. " \ "Instead found " + str(decrypted_string) finally: if h_unwrapped_key: c_destroy_object(self.h_session, h_unwrapped_key)
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_multi_sym_encrypt_decrypt(self, m_type, params, data, sym_keys, auth_session, valid_mechanisms): """ test encryption decryption calls of sym. crypto's :param m_type: mechanism flavor :param params: extra params :param data: testing data :param sym_keys: key fixture :param auth_session: """ # Auto-fail when key-generation is fails if sym_keys.get(SYM_TABLE[m_type]) is None: pytest.fail("No valid key found for {}".format( MECHANISM_LOOKUP_EXT[m_type][0])) # AES_KW will fail on very large data sizes # AES_GCM requires smaller data sizes as well. if m_type in (CKM_AES_KW, CKM_AES_GCM) and data == PAD: data = b"a" * 256 exp_ret = ret_val(m_type, data, valid_mechanisms) h_key = sym_keys[SYM_TABLE[m_type]] encrypt_this = [data, data, data, data] mech = {"mech_type": m_type, "params": params} ret, encrypted = c_encrypt(auth_session, h_key, encrypt_this, mechanism=mech) self.verify_ret(ret, exp_ret) # If not expecting error, proceed with testing if exp_ret in (CKR_OK, KEY_SIZE_RANGE): if m_type not in PADDING_ALGORITHMS and m_type != CKM_AES_KW: assert len(encrypted) == len(b"".join(encrypt_this)) ret, end_data = c_decrypt(auth_session, h_key, encrypted, mechanism=mech) self.verify_ret(ret, exp_ret) if m_type in PADDING_ALGORITHMS: end_data = end_data.rstrip(b"\x00") self.verify_data(b"".join(encrypt_this), end_data)
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_multi_sym_encrypt_decrypt(self, m_type, params, data, sym_keys, auth_session, valid_mechanisms): """ test encryption decryption calls of sym. crypto's :param m_type: mechanism flavor :param params: extra params :param data: testing data :param sym_keys: key fixture :param auth_session: """ # Auto-fail when key-generation is fails if sym_keys.get(SYM_TABLE[m_type]) is None: pytest.skip("No valid key found for {}".format( MECHANISM_LOOKUP_EXT[m_type][0])) exp_ret = ret_val(m_type, data, valid_mechanisms) h_key = sym_keys[SYM_TABLE[m_type]] encrypt_this = data mech = {"mech_type": m_type, "params": params} ret, encrypted = c_encrypt( auth_session, h_key, encrypt_this, mechanism=mech, output_buffer=[0xffff, 0xffff, 0xffff, 0xffff]) self.verify_ret(ret, exp_ret) # If not expecting error, proceed with testing if exp_ret in (CKR_OK, KEY_SIZE_RANGE): ret, end_data = c_decrypt(auth_session, h_key, encrypted, mechanism=mech) self.verify_ret(ret, exp_ret) if m_type in PADDING_ALGORITHMS: end_data = end_data.rstrip(b"\x00") self.verify_data(b"".join(encrypt_this), end_data)
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"