diff options
Diffstat (limited to 'platform/linux-generic/odp_crypto_openssl.c')
-rw-r--r-- | platform/linux-generic/odp_crypto_openssl.c | 115 |
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); } |