@@ -36,9 +36,7 @@
* 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},
-/* Special case for GMAC */
-{.key_len = 0, .iv_len = 12} };
+{.key_len = 0, .iv_len = 0} };
static const odp_crypto_cipher_capability_t cipher_capa_trides_cbc[] = {
{.key_len = 24, .iv_len = 8} };
@@ -86,7 +84,8 @@ static const odp_crypto_auth_capability_t auth_capa_aes_gcm[] = {
{.digest_len = 16, .key_len = 0, .aad_len = {.min = 8, .max = 12, .inc = 4} } };
static const odp_crypto_auth_capability_t auth_capa_aes_gmac[] = {
-{.digest_len = 16, .key_len = 16, .aad_len = {.min = 0, .max = 0, .inc = 0} } };
+{.digest_len = 16, .key_len = 16, .aad_len = {.min = 0, .max = 0, .inc = 0},
+ .iv_len = 12 } };
/** Forward declaration of session structure */
typedef struct odp_crypto_generic_session_t odp_crypto_generic_session_t;
@@ -121,6 +120,7 @@ struct odp_crypto_generic_session_t {
struct {
uint8_t key[EVP_MAX_KEY_LENGTH];
+ uint8_t iv_data[EVP_MAX_IV_LENGTH];
uint32_t key_length;
uint32_t bytes;
union {
@@ -640,10 +640,10 @@ odp_crypto_alg_err_t aes_gmac_gen(odp_packet_t pkt,
uint8_t block[EVP_MAX_MD_SIZE];
int ret;
- if (param->override_iv_ptr)
- iv_ptr = param->override_iv_ptr;
- else if (session->p.iv.data)
- iv_ptr = session->cipher.iv_data;
+ if (param->override_auth_iv_ptr)
+ iv_ptr = param->override_auth_iv_ptr;
+ else if (session->p.auth_iv.data)
+ iv_ptr = session->auth.iv_data;
else
return ODP_CRYPTO_ALG_ERR_IV_INVALID;
@@ -679,10 +679,10 @@ odp_crypto_alg_err_t aes_gmac_check(odp_packet_t pkt,
uint8_t block[EVP_MAX_MD_SIZE];
int ret;
- if (param->override_iv_ptr)
- iv_ptr = param->override_iv_ptr;
- else if (session->p.iv.data)
- iv_ptr = session->cipher.iv_data;
+ if (param->override_auth_iv_ptr)
+ iv_ptr = param->override_auth_iv_ptr;
+ else if (session->p.auth_iv.data)
+ iv_ptr = session->auth.iv_data;
else
return ODP_CRYPTO_ALG_ERR_IV_INVALID;
@@ -905,11 +905,21 @@ odp_crypto_session_create(odp_crypto_session_param_t *param,
goto err;
}
+ if (session->p.auth_iv.length > EVP_MAX_IV_LENGTH) {
+ ODP_DBG("Maximum auth IV length exceeded\n");
+ *status = ODP_CRYPTO_SES_CREATE_ERR_INV_CIPHER;
+ goto err;
+ }
+
/* Copy IV data */
if (session->p.iv.data)
memcpy(session->cipher.iv_data, session->p.iv.data,
session->p.iv.length);
+ if (session->p.auth_iv.data)
+ memcpy(session->auth.iv_data, session->p.auth_iv.data,
+ session->p.auth_iv.length);
+
/* Derive order */
if (ODP_CRYPTO_OP_ENCODE == param->op)
session->do_cipher_first = param->auth_cipher_text;
@@ -1098,6 +1108,7 @@ odp_crypto_operation(odp_crypto_op_param_t *param,
packet_param.session = param->session;
packet_param.override_iv_ptr = param->override_iv_ptr;
+ packet_param.override_auth_iv_ptr = param->override_auth_iv_ptr;
packet_param.hash_result_offset = param->hash_result_offset;
packet_param.aad_ptr = param->aad_ptr;
packet_param.cipher_range = param->cipher_range;
@@ -478,6 +478,7 @@ static int ipsec_in_esp(odp_packet_t *pkt,
state->in.hdr_len -
ipsec_sa->icv_len;
param->override_iv_ptr = state->iv;
+ param->override_auth_iv_ptr = state->iv;
state->esp.aad.spi = esp.spi;
state->esp.aad.seq_no = esp.seq_no;
@@ -560,7 +561,7 @@ static int ipsec_in_ah(odp_packet_t *pkt,
return -1;
}
- param->override_iv_ptr = state->iv;
+ param->override_auth_iv_ptr = state->iv;
state->in.hdr_len = (ah.ah_len + 2) * 4;
state->in.trl_len = 0;
@@ -1080,6 +1081,7 @@ static int ipsec_out_esp(odp_packet_t *pkt,
}
param->override_iv_ptr = state->iv;
+ param->override_auth_iv_ptr = state->iv;
memset(&esp, 0, sizeof(esp));
esp.spi = odp_cpu_to_be_32(ipsec_sa->spi);
@@ -1229,7 +1231,7 @@ static int ipsec_out_ah(odp_packet_t *pkt,
return -1;
}
- param->override_iv_ptr = state->iv;
+ param->override_auth_iv_ptr = state->iv;
if (odp_packet_extend_head(pkt, hdr_len, NULL, NULL) < 0) {
status->error.alg = 1;
@@ -409,7 +409,7 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param)
ipsec_sa->use_counter_iv = 1;
ipsec_sa->esp_iv_len = 8;
ipsec_sa->esp_block_len = 16;
- crypto_param.iv.length = 12;
+ crypto_param.auth_iv.length = 12;
break;
default:
break;