aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-generic/odp_crypto_openssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linux-generic/odp_crypto_openssl.c')
-rw-r--r--platform/linux-generic/odp_crypto_openssl.c115
1 files changed, 65 insertions, 50 deletions
diff --git a/platform/linux-generic/odp_crypto_openssl.c b/platform/linux-generic/odp_crypto_openssl.c
index d4c7a3f1a..26c9ce7b7 100644
--- a/platform/linux-generic/odp_crypto_openssl.c
+++ b/platform/linux-generic/odp_crypto_openssl.c
@@ -55,7 +55,6 @@
* Keep sorted: first by key length, then by IV length
*/
static const odp_crypto_cipher_capability_t cipher_capa_null[] = {
-{.key_len = 0, .iv_len = 0},
{.key_len = 0, .iv_len = 0, .bit_mode = 1} };
static const odp_crypto_cipher_capability_t cipher_capa_trides_cbc[] = {
@@ -115,9 +114,7 @@ static const odp_crypto_cipher_capability_t cipher_capa_aes_eea2[] = {
* Keep sorted: first by digest length, then by key length
*/
static const odp_crypto_auth_capability_t auth_capa_null[] = {
-{.digest_len = 0, .key_len = 0, .aad_len = {.min = 0, .max = 0, .inc = 0},
- .bit_mode = 1},
-{.digest_len = 0, .key_len = 0, .aad_len = {.min = 0, .max = 0, .inc = 0} } };
+{.digest_len = 0, .key_len = 0, .aad_len = {.min = 0, .max = 0, .inc = 0}, .bit_mode = 1} };
static const odp_crypto_auth_capability_t auth_capa_md5_hmac[] = {
{.digest_len = 12, .key_len = 16, .aad_len = {.min = 0, .max = 0, .inc = 0} },
@@ -217,8 +214,8 @@ struct odp_crypto_generic_session_t {
odp_crypto_session_param_t p;
odp_bool_t do_cipher_first;
- uint8_t cipher_bit_mode : 1;
- uint8_t cipher_range_used : 1;
+ uint8_t cipher_range_in_bits : 1;
+ uint8_t auth_range_in_bits : 1;
uint8_t auth_range_used : 1;
struct {
@@ -1122,70 +1119,72 @@ static int process_cipher_param(odp_crypto_generic_session_t *session,
return 0;
}
-static
-odp_crypto_alg_err_t cipher_encrypt_bits(odp_packet_t pkt,
- const odp_crypto_packet_op_param_t
- *param,
- odp_crypto_generic_session_t *session)
+static odp_crypto_alg_err_t cipher_encrypt_bytes(odp_packet_t pkt,
+ const odp_crypto_packet_op_param_t *param,
+ odp_crypto_generic_session_t *session)
{
EVP_CIPHER_CTX *ctx = local.cipher_ctx[session->idx];
int dummy_len = 0;
int cipher_len;
- uint32_t in_len = (param->cipher_range.length + 7) / 8;
+ uint32_t in_len = param->cipher_range.length;
+ uint32_t offset = param->cipher_range.offset;
uint8_t data[in_len];
int ret;
- uint32_t offset;
-
- /* Range offset is in bits in bit mode but must be divisible by 8. */
- offset = param->cipher_range.offset / 8;
EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, param->cipher_iv_ptr);
-
odp_packet_copy_to_mem(pkt, offset, in_len, data);
-
EVP_EncryptUpdate(ctx, data, &cipher_len, data, in_len);
-
ret = EVP_EncryptFinal_ex(ctx, data + cipher_len, &dummy_len);
cipher_len += dummy_len;
-
odp_packet_copy_from_mem(pkt, offset, in_len, data);
-
return ret <= 0 ? ODP_CRYPTO_ALG_ERR_DATA_SIZE :
ODP_CRYPTO_ALG_ERR_NONE;
}
-static
-odp_crypto_alg_err_t cipher_decrypt_bits(odp_packet_t pkt,
- const odp_crypto_packet_op_param_t
- *param,
- odp_crypto_generic_session_t *session)
+static odp_crypto_alg_err_t cipher_decrypt_bytes(odp_packet_t pkt,
+ const odp_crypto_packet_op_param_t *param,
+ odp_crypto_generic_session_t *session)
{
EVP_CIPHER_CTX *ctx = local.cipher_ctx[session->idx];
int dummy_len = 0;
int cipher_len;
- uint32_t in_len = (param->cipher_range.length + 7) / 8;
+ uint32_t in_len = param->cipher_range.length;
+ uint32_t offset = param->cipher_range.offset;
uint8_t data[in_len];
int ret;
- uint32_t offset;
-
- /* Range offset is in bits in bit mode but must be divisible by 8. */
- offset = param->cipher_range.offset / 8;
EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, param->cipher_iv_ptr);
-
odp_packet_copy_to_mem(pkt, offset, in_len, data);
-
EVP_DecryptUpdate(ctx, data, &cipher_len, data, in_len);
-
ret = EVP_DecryptFinal_ex(ctx, data + cipher_len, &dummy_len);
cipher_len += dummy_len;
-
odp_packet_copy_from_mem(pkt, offset, in_len, data);
-
return ret <= 0 ? ODP_CRYPTO_ALG_ERR_DATA_SIZE :
ODP_CRYPTO_ALG_ERR_NONE;
}
+static odp_crypto_alg_err_t cipher_encrypt_bits(odp_packet_t pkt,
+ const odp_crypto_packet_op_param_t *param,
+ odp_crypto_generic_session_t *session)
+{
+ odp_crypto_packet_op_param_t new_param = *param;
+
+ new_param.cipher_range.offset /= 8;
+ new_param.cipher_range.length = (new_param.cipher_range.length + 7) / 8;
+ return cipher_encrypt_bytes(pkt, &new_param, session);
+}
+
+static odp_crypto_alg_err_t cipher_decrypt_bits(odp_packet_t pkt,
+ const odp_crypto_packet_op_param_t *param,
+ odp_crypto_generic_session_t *session)
+{
+ odp_crypto_packet_op_param_t new_param = *param;
+
+ new_param.cipher_range.offset /= 8;
+ new_param.cipher_range.length = (new_param.cipher_range.length + 7) / 8;
+ return cipher_decrypt_bytes(pkt, &new_param, session);
+}
+
static int process_cipher_param_bits(odp_crypto_generic_session_t *session,
const EVP_CIPHER *cipher)
{
@@ -1199,7 +1198,6 @@ static int process_cipher_param_bits(odp_crypto_generic_session_t *session,
session->p.cipher_iv_len)
return -1;
- session->cipher_bit_mode = 1;
session->cipher.evp_cipher = cipher;
memcpy(session->cipher.key_data, session->p.cipher_key.data,
@@ -1207,11 +1205,14 @@ static int process_cipher_param_bits(odp_crypto_generic_session_t *session,
/* Set function */
if (ODP_CRYPTO_OP_ENCODE == session->p.op) {
- session->cipher.func = cipher_encrypt_bits;
session->cipher.init = cipher_encrypt_init;
+ session->cipher.func = session->cipher_range_in_bits ? cipher_encrypt_bits
+ : cipher_encrypt_bytes;
+
} else {
- session->cipher.func = cipher_decrypt_bits;
session->cipher.init = cipher_decrypt_init;
+ session->cipher.func = session->cipher_range_in_bits ? cipher_decrypt_bits
+ : cipher_decrypt_bytes;
}
return 0;
@@ -1813,7 +1814,7 @@ int odp_crypto_capability(odp_crypto_capability_t *capa)
#if _ODP_HAVE_CHACHA20_POLY1305
capa->ciphers.bit.chacha20_poly1305 = 1;
#endif
- capa->ciphers.bit.aes_eea2 = 1;
+ capa->ciphers.bit.aes_eea2 = 1;
capa->auths.bit.null = 1;
capa->auths.bit.md5_hmac = 1;
@@ -2022,6 +2023,8 @@ odp_crypto_session_create(const odp_crypto_session_param_t *param,
{
int rc;
odp_crypto_generic_session_t *session;
+ int cipher_bit_mode_supported = 0;
+ int auth_bit_mode_supported = 0;
if (odp_global_ro.disable.crypto) {
_ODP_ERR("Crypto is disabled\n");
@@ -2052,9 +2055,9 @@ odp_crypto_session_create(const odp_crypto_session_param_t *param,
/* Copy parameters */
session->p = *param;
- session->cipher_bit_mode = 0;
+ session->cipher_range_in_bits = !!param->cipher_range_in_bits;
+ session->auth_range_in_bits = !!param->auth_range_in_bits;
session->auth_range_used = 1;
- session->cipher_range_used = 1;
if (session->p.cipher_iv_len > EVP_MAX_IV_LENGTH) {
_ODP_DBG("Maximum IV length exceeded\n");
@@ -2079,7 +2082,7 @@ odp_crypto_session_create(const odp_crypto_session_param_t *param,
case ODP_CIPHER_ALG_NULL:
session->cipher.func = null_crypto_routine;
session->cipher.init = null_crypto_init_routine;
- session->cipher_range_used = 0;
+ cipher_bit_mode_supported = 1;
rc = 0;
break;
case ODP_CIPHER_ALG_3DES_CBC:
@@ -2184,11 +2187,15 @@ odp_crypto_session_create(const odp_crypto_session_param_t *param,
EVP_aes_128_ctr());
else
rc = -1;
+ cipher_bit_mode_supported = 1;
break;
default:
rc = -1;
}
+ if (session->cipher_range_in_bits && !cipher_bit_mode_supported)
+ rc = -1;
+
/* Check result */
if (rc) {
*status = ODP_CRYPTO_SES_ERR_CIPHER;
@@ -2200,7 +2207,7 @@ odp_crypto_session_create(const odp_crypto_session_param_t *param,
case ODP_AUTH_ALG_NULL:
session->auth.func = null_crypto_routine;
session->auth.init = null_crypto_init_routine;
- session->auth_range_used = 0;
+ auth_bit_mode_supported = 1;
rc = 0;
break;
case ODP_AUTH_ALG_MD5_HMAC:
@@ -2314,6 +2321,9 @@ odp_crypto_session_create(const odp_crypto_session_param_t *param,
rc = -1;
}
+ if (session->auth_range_in_bits && !auth_bit_mode_supported)
+ rc = -1;
+
/* Check result */
if (rc) {
*status = ODP_CRYPTO_SES_ERR_AUTH;
@@ -2632,12 +2642,16 @@ static void copy_ranges(odp_packet_t dst,
int32_t shift = param->dst_offset_shift;
int rc;
- if (session->cipher_bit_mode) {
+ if (session->cipher_range_in_bits) {
c_range.offset /= 8;
c_range.length = (c_range.length + 7) / 8;
}
+ if (session->auth_range_in_bits) {
+ a_range.offset /= 8;
+ a_range.length = (a_range.length + 7) / 8;
+ }
- if (session->cipher_range_used) {
+ if (c_range.length > 0) {
rc = odp_packet_copy_from_pkt(dst, c_range.offset + shift,
src, c_range.offset,
c_range.length);
@@ -2646,7 +2660,7 @@ static void copy_ranges(odp_packet_t dst,
return;
}
}
- if (session->auth_range_used) {
+ if (session->auth_range_used && a_range.length > 0) {
rc = odp_packet_copy_from_pkt(dst, a_range.offset + shift,
src, a_range.offset,
a_range.length);
@@ -2663,12 +2677,13 @@ static int crypto_int_oop_encode(odp_packet_t pkt_in,
const odp_crypto_packet_op_param_t *param)
{
odp_crypto_packet_op_param_t new_param = *param;
- const uint32_t scale = session->cipher_bit_mode ? 8 : 1;
+ const uint32_t c_scale = session->cipher_range_in_bits ? 8 : 1;
+ const uint32_t a_scale = session->auth_range_in_bits ? 8 : 1;
copy_ranges(*pkt_out, pkt_in, session, param);
- new_param.cipher_range.offset += param->dst_offset_shift * scale;
- new_param.auth_range.offset += param->dst_offset_shift;
+ new_param.cipher_range.offset += param->dst_offset_shift * c_scale;
+ new_param.auth_range.offset += param->dst_offset_shift * a_scale;
return crypto_int(*pkt_out, pkt_out, &new_param);
}