From: Wenkai Lin linwenkai6@hisilicon.com
For the aead stream mode, packets are sent in three phases: first, middle and final, user may deliver the decrypt mac through the first or final message.
Currently uadk stores the first message's mac to the session, then restore it when process the final message, it can't work when the first message does not carry a valid decrypt mac.
Now uadk can cache the mac calculated based on the first message and the middle message to the session and use the decrypt mac until the final message is processed.
Signed-off-by: Wenkai Lin linwenkai6@hisilicon.com --- drv/hisi_sec.c | 4 ++-- include/drv/wd_aead_drv.h | 2 +- wd_aead.c | 14 +++++++++----- 3 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/drv/hisi_sec.c b/drv/hisi_sec.c index 3341b09..b0dcbba 100644 --- a/drv/hisi_sec.c +++ b/drv/hisi_sec.c @@ -2264,7 +2264,7 @@ static void gcm_auth_ivin(struct wd_aead_msg *msg)
/* Use the user's origin mac for decrypt icv check */ if (msg->op_type == WD_CIPHER_DECRYPTION_DIGEST) - memcpy(msg->mac, msg->mac_bak, msg->auth_bytes); + memcpy(msg->mac, msg->dec_mac, msg->auth_bytes); }
static void fill_gcm_first_bd2(struct wd_aead_msg *msg, struct hisi_sec_sqe *sqe) @@ -2357,7 +2357,7 @@ static int gcm_do_soft_mac(struct wd_aead_msg *msg) msg->mac[i] = g[i] ^ ctr_r[i];
if (msg->op_type == WD_CIPHER_DECRYPTION_DIGEST) { - ret = memcmp(msg->mac, msg->mac_bak, msg->auth_bytes); + ret = memcmp(msg->mac, msg->dec_mac, msg->auth_bytes); if (ret) { msg->result = WD_IN_EPARA; WD_ERR("failed to do the gcm authentication!\n"); diff --git a/include/drv/wd_aead_drv.h b/include/drv/wd_aead_drv.h index 5e4f73a..a9c0e7c 100644 --- a/include/drv/wd_aead_drv.h +++ b/include/drv/wd_aead_drv.h @@ -64,7 +64,7 @@ struct wd_aead_msg { /* mac */ __u8 *mac; /* mac data pointer for decrypto as stream mode */ - __u8 mac_bak[AES_BLOCK_SIZE]; + __u8 *dec_mac; /* total of data for stream mode */ __u64 long_data_len; enum wd_aead_msg_state msg_state; diff --git a/wd_aead.c b/wd_aead.c index e5e1b19..87d61c3 100644 --- a/wd_aead.c +++ b/wd_aead.c @@ -635,20 +635,24 @@ static void fill_stream_msg(struct wd_aead_msg *msg, struct wd_aead_req *req, memset(sess->iv, 0, MAX_IV_SIZE); memcpy(sess->iv, req->iv, GCM_IV_SIZE);
- /* Store the original mac of first message to session */ if (msg->op_type == WD_CIPHER_DECRYPTION_DIGEST) - memcpy(sess->mac_bak, req->mac, sess->auth_bytes); + msg->mac = sess->mac_bak; break; case AEAD_MSG_MIDDLE: /* Middle messages need to store the stream's total length to session */ sess->long_data_len += req->in_bytes;
msg->long_data_len = sess->long_data_len; + + if (msg->op_type == WD_CIPHER_DECRYPTION_DIGEST) + msg->mac = sess->mac_bak; break; case AEAD_MSG_END: - /* Sets the original mac for final message */ - if (msg->op_type == WD_CIPHER_DECRYPTION_DIGEST) - memcpy(msg->mac_bak, sess->mac_bak, sess->auth_bytes); + if (msg->op_type == WD_CIPHER_DECRYPTION_DIGEST) { + /* Sets the original mac for final message */ + msg->dec_mac = req->mac; + msg->mac = sess->mac_bak; + }
msg->long_data_len = sess->long_data_len + req->in_bytes; /* Reset the session's long_data_len */