diff --git a/example/ipsec/odp_ipsec_cache.c b/example/ipsec/odp_ipsec_cache.c
index b2a91c24..15617bc7 100644
--- a/example/ipsec/odp_ipsec_cache.c
+++ b/example/ipsec/odp_ipsec_cache.c
@@ -114,8 +114,8 @@ int create_ipsec_cache_entry(sa_db_entry_t *cipher_sa,
 			return -1;
 	}
 
-	/* Synchronous session create for now */
-	if (odp_crypto_session_create(&params, &session, &ses_create_rc))
+	session = odp_crypto_session_create(&params, &ses_create_rc);
+	if (ODP_CRYPTO_SESSION_INVALID == session)
 		return -1;
 	if (ODP_CRYPTO_SES_CREATE_ERR_NONE != ses_create_rc)
 		return -1;
diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h
index c47d3149..493e17f7 100644
--- a/include/odp/api/spec/crypto.h
+++ b/include/odp/api/spec/crypto.h
@@ -585,15 +585,15 @@ int odp_crypto_auth_capability(odp_auth_alg_t auth,
  * default values.
  *
  * @param param             Session parameters
- * @param session           Created session else ODP_CRYPTO_SESSION_INVALID
  * @param status            Failure code if unsuccessful
  *
- * @retval 0 on success
- * @retval <0 on failure
+ * @retval created session on success
+ * @retval ODP_CRYPTO_SESSION_INVALID on failure
  */
-int odp_crypto_session_create(odp_crypto_session_param_t *param,
-			      odp_crypto_session_t *session,
-			      odp_crypto_ses_create_err_t *status);
+odp_crypto_session_t odp_crypto_session_create(odp_crypto_session_param_t
+					       *param,
+					       odp_crypto_ses_create_err_t
+					       *status);
 
 /**
  * Crypto session destroy
diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c
index a993542f..11d3af3a 100644
--- a/platform/linux-generic/odp_crypto.c
+++ b/platform/linux-generic/odp_crypto.c
@@ -656,9 +656,8 @@ int odp_crypto_auth_capability(odp_auth_alg_t auth,
 	return num;
 }
 
-int
+odp_crypto_session_t
 odp_crypto_session_create(odp_crypto_session_param_t *param,
-			  odp_crypto_session_t *session_out,
 			  odp_crypto_ses_create_err_t *status)
 {
 	int rc;
@@ -672,7 +671,7 @@ odp_crypto_session_create(odp_crypto_session_param_t *param,
 	session = alloc_session();
 	if (NULL == session) {
 		*status = ODP_CRYPTO_SES_CREATE_ERR_ENOMEM;
-		return -1;
+		return ODP_CRYPTO_SESSION_INVALID;
 	}
 
 	/* Copy parameters */
@@ -683,7 +682,7 @@ odp_crypto_session_create(odp_crypto_session_param_t *param,
 		if (session->p.iv.length > MAX_IV_LEN) {
 			ODP_DBG("Maximum IV length exceeded\n");
 			free_session(session);
-			return -1;
+			return ODP_CRYPTO_SESSION_INVALID;
 		}
 
 		memcpy(session->cipher.iv_data, session->p.iv.data,
@@ -734,7 +733,7 @@ odp_crypto_session_create(odp_crypto_session_param_t *param,
 	if (rc) {
 		*status = ODP_CRYPTO_SES_CREATE_ERR_INV_CIPHER;
 		free_session(session);
-		return -1;
+		return ODP_CRYPTO_SESSION_INVALID;
 	}
 
 	aes_gcm = 0;
@@ -781,12 +780,11 @@ odp_crypto_session_create(odp_crypto_session_param_t *param,
 	if (rc) {
 		*status = ODP_CRYPTO_SES_CREATE_ERR_INV_AUTH;
 		free_session(session);
-		return -1;
+		return ODP_CRYPTO_SESSION_INVALID;
 	}
 
 	/* We're happy */
-	*session_out = (intptr_t)session;
-	return 0;
+	return (odp_crypto_session_t)(intptr_t)session;
 }
 
 int odp_crypto_session_destroy(odp_crypto_session_t session)
diff --git a/test/common_plat/performance/odp_crypto.c b/test/common_plat/performance/odp_crypto.c
index b3857973..95cc141c 100644
--- a/test/common_plat/performance/odp_crypto.c
+++ b/test/common_plat/performance/odp_crypto.c
@@ -415,13 +415,13 @@ print_mem(const char *msg,
 /**
  * Create ODP crypto session for given config.
  */
-static int
-create_session_from_config(odp_crypto_session_t *session,
-			   crypto_alg_config_t *config,
+static odp_crypto_session_t
+create_session_from_config(crypto_alg_config_t *config,
 			   crypto_args_t *cargs)
 {
 	odp_crypto_session_param_t params;
 	odp_crypto_ses_create_err_t ses_create_rc;
+	odp_crypto_session_t session;
 	odp_pool_t pkt_pool;
 	odp_queue_t out_queue;
 
@@ -434,7 +434,7 @@ create_session_from_config(odp_crypto_session_t *session,
 	pkt_pool = odp_pool_lookup("packet_pool");
 	if (pkt_pool == ODP_POOL_INVALID) {
 		app_err("packet_pool pool not found\n");
-		return -1;
+		return ODP_CRYPTO_SESSION_INVALID;
 	}
 	params.output_pool = pkt_pool;
 
@@ -442,20 +442,21 @@ create_session_from_config(odp_crypto_session_t *session,
 		out_queue = odp_queue_lookup("crypto-out");
 		if (out_queue == ODP_QUEUE_INVALID) {
 			app_err("crypto-out queue not found\n");
-			return -1;
+			return ODP_CRYPTO_SESSION_INVALID;
 		}
 		params.compl_queue = out_queue;
 
 	} else {
 		params.compl_queue = ODP_QUEUE_INVALID;
 	}
-	if (odp_crypto_session_create(&params, session,
-				      &ses_create_rc)) {
+
+	session = odp_crypto_session_create(&params,
+					    &ses_create_rc);
+
+	if (session == ODP_CRYPTO_SESSION_INVALID)
 		app_err("crypto session create failed.\n");
-		return -1;
-	}
 
-	return 0;
+	return session;
 }
 
 /**
@@ -664,35 +665,34 @@ run_measure_one_config(crypto_args_t *cargs,
 	odp_crypto_session_t session;
 	int rc = 0;
 
-	if (create_session_from_config(&session, config, cargs))
-		rc = -1;
-
-	if (!rc) {
-		if (cargs->payload_length) {
-			rc = run_measure_one(cargs, config, &session,
-					     cargs->payload_length, &result);
-			if (!rc) {
-				print_result_header();
-				print_result(cargs, cargs->payload_length,
-					     config, &result);
-			}
-		} else {
-			unsigned i;
+	session = create_session_from_config(config, cargs);
+	if (session == ODP_CRYPTO_SESSION_INVALID)
+		return -1;
 
+	if (cargs->payload_length) {
+		rc = run_measure_one(cargs, config, &session,
+				     cargs->payload_length, &result);
+		if (!rc) {
 			print_result_header();
-			for (i = 0; i < num_payloads; i++) {
-				rc = run_measure_one(cargs, config, &session,
-						     payloads[i], &result);
-				if (rc)
-					break;
-				print_result(cargs, payloads[i],
-					     config, &result);
-			}
+			print_result(cargs, cargs->payload_length,
+				     config, &result);
+		}
+	} else {
+		unsigned i;
+
+		print_result_header();
+		for (i = 0; i < num_payloads; i++) {
+			rc = run_measure_one(cargs, config, &session,
+					     payloads[i], &result);
+			if (rc)
+				break;
+			print_result(cargs, payloads[i],
+				     config, &result);
 		}
 	}
 
-	if (session != ODP_CRYPTO_SESSION_INVALID)
-		odp_crypto_session_destroy(session);
+	odp_crypto_session_destroy(session);
+
 	return rc;
 }
 
diff --git a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c
index bfc9da3c..dc5baf1e 100644
--- a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c
+++ b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c
@@ -202,11 +202,10 @@ static void alg_test(odp_crypto_op_t op,
 	ses_params.iv = ses_iv;
 	ses_params.auth_key = auth_key;
 
-	rc = odp_crypto_session_create(&ses_params, &session, &status);
-	CU_ASSERT_FATAL(!rc);
+	session = odp_crypto_session_create(&ses_params, &status);
+	CU_ASSERT_FATAL(odp_crypto_session_to_u64(session) !=
+			odp_crypto_session_to_u64(ODP_CRYPTO_SESSION_INVALID));
 	CU_ASSERT(status == ODP_CRYPTO_SES_CREATE_ERR_NONE);
-	CU_ASSERT(odp_crypto_session_to_u64(session) !=
-		  odp_crypto_session_to_u64(ODP_CRYPTO_SESSION_INVALID));
 
 	/* Prepare input data */
 	odp_packet_t pkt = odp_packet_alloc(suite_context.pool,
