aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>2017-06-01 12:03:30 +0300
committerMaxim Uvarov <maxim.uvarov@linaro.org>2017-06-16 17:01:10 +0300
commitfec16fd81d4084340f0f9a6893c9772000608031 (patch)
treead378c950b0f63c1ab7548b0d8709cbe6decf2c5
parent2210dc7d26125ac9b8b51fa4de7b2b72e4e8f13e (diff)
linux-generic: crypto: make HMAC work across segmented packets
Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org> Reviewed-by: Petri Savolainen <petri.savolainen@linaro.org> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
-rw-r--r--platform/linux-generic/odp_crypto.c78
1 files changed, 45 insertions, 33 deletions
diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c
index 2ba077f9d..7ea90fb92 100644
--- a/platform/linux-generic/odp_crypto.c
+++ b/platform/linux-generic/odp_crypto.c
@@ -112,29 +112,53 @@ null_crypto_routine(odp_crypto_op_param_t *param ODP_UNUSED,
}
static
+void packet_hmac(odp_crypto_op_param_t *param,
+ odp_crypto_generic_session_t *session,
+ uint8_t *hash)
+{
+ odp_packet_t pkt = param->out_pkt;
+ uint32_t offset = param->auth_range.offset;
+ uint32_t len = param->auth_range.length;
+ HMAC_CTX ctx;
+
+ ODP_ASSERT(offset + len <= odp_packet_len(pkt));
+
+ /* Hash it */
+ HMAC_CTX_init(&ctx);
+ HMAC_Init_ex(&ctx,
+ session->auth.key,
+ session->auth.key_length,
+ session->auth.evp_md,
+ NULL);
+
+ while (len > 0) {
+ uint32_t seglen = 0; /* GCC */
+ void *mapaddr = odp_packet_offset(pkt, offset, &seglen, NULL);
+ uint32_t maclen = len > seglen ? seglen : len;
+
+ HMAC_Update(&ctx, mapaddr, maclen);
+ offset += maclen;
+ len -= maclen;
+ }
+
+ HMAC_Final(&ctx, hash, NULL);
+ HMAC_CTX_cleanup(&ctx);
+}
+
+static
odp_crypto_alg_err_t auth_gen(odp_crypto_op_param_t *param,
odp_crypto_generic_session_t *session)
{
- uint8_t *data = odp_packet_data(param->out_pkt);
- uint8_t *icv = data;
- uint32_t len = param->auth_range.length;
uint8_t hash[EVP_MAX_MD_SIZE];
- /* Adjust pointer for beginning of area to auth */
- data += param->auth_range.offset;
- icv += param->hash_result_offset;
-
/* Hash it */
- HMAC(session->auth.evp_md,
- session->auth.key,
- session->auth.key_length,
- data,
- len,
- hash,
- NULL);
+ packet_hmac(param, session, hash);
/* Copy to the output location */
- memcpy(icv, hash, session->auth.bytes);
+ odp_packet_copy_from_mem(param->out_pkt,
+ param->hash_result_offset,
+ session->auth.bytes,
+ hash);
return ODP_CRYPTO_ALG_ERR_NONE;
}
@@ -143,31 +167,19 @@ static
odp_crypto_alg_err_t auth_check(odp_crypto_op_param_t *param,
odp_crypto_generic_session_t *session)
{
- uint8_t *data = odp_packet_data(param->out_pkt);
- uint8_t *icv = data;
- uint32_t len = param->auth_range.length;
uint32_t bytes = session->auth.bytes;
uint8_t hash_in[EVP_MAX_MD_SIZE];
uint8_t hash_out[EVP_MAX_MD_SIZE];
- /* Adjust pointer for beginning of area to auth */
- data += param->auth_range.offset;
- icv += param->hash_result_offset;
-
/* Copy current value out and clear it before authentication */
- memset(hash_in, 0, sizeof(hash_in));
- memcpy(hash_in, icv, bytes);
- memset(icv, 0, bytes);
- memset(hash_out, 0, sizeof(hash_out));
+ odp_packet_copy_to_mem(param->out_pkt, param->hash_result_offset,
+ bytes, hash_in);
+
+ _odp_packet_set_data(param->out_pkt, param->hash_result_offset,
+ 0, bytes);
/* Hash it */
- HMAC(session->auth.evp_md,
- session->auth.key,
- session->auth.key_length,
- data,
- len,
- hash_out,
- NULL);
+ packet_hmac(param, session, hash_out);
/* Verify match */
if (0 != memcmp(hash_in, hash_out, bytes))