Hardware v2 digest needs to check the zero byte packet in the
frist and middle bd.Add a function that get the hash bd type.
It can simplify the code of the process of hash bd type checking.
Signed-off-by: Kai Ye <yekai13(a)huawei.com>
---
drv/hisi_sec.c | 72 +++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 62 insertions(+), 10 deletions(-)
diff --git a/drv/hisi_sec.c b/drv/hisi_sec.c
index c30b653..116424e 100644
--- a/drv/hisi_sec.c
+++ b/drv/hisi_sec.c
@@ -187,6 +187,13 @@ enum sec_c_width {
C_WIDTH_CS3 = 0x3,
};
+enum hash_bd_type {
+ HASH_SINGLE_BD,
+ HASH_FRIST_BD,
+ HASH_MIDDLE_BD,
+ HASH_END_BD,
+};
+
struct hisi_sec_ctx {
struct wd_ctx_config_internal config;
};
@@ -1379,9 +1386,29 @@ static int long_hash_param_check(handle_t h_qp, struct wd_digest_msg *msg)
return 0;
}
+static enum hash_bd_type get_hash_bd_type(struct wd_digest_msg *msg)
+{
+ /*
+ * [has_next , iv_bytes]
+ * [ 1 , 0 ] = long hash(frist bd)
+ * [ 1 , 1 ] = long hash(middle bd)
+ * [ 0 , 1 ] = long hash(end bd)
+ * [ 0 , 0 ] = block hash(single bd)
+ */
+ if (msg->has_next && !msg->iv_bytes)
+ return HASH_FRIST_BD;
+ else if (msg->has_next && msg->iv_bytes)
+ return HASH_MIDDLE_BD;
+ else if (!msg->has_next && msg->iv_bytes)
+ return HASH_END_BD;
+ else
+ return HASH_SINGLE_BD;
+}
+
static int fill_digest_long_hash(handle_t h_qp, struct wd_digest_msg *msg,
struct hisi_sec_sqe *sqe)
{
+ enum hash_bd_type bd_type = get_hash_bd_type(msg);
__u64 total_bits;
int ret;
@@ -1389,20 +1416,20 @@ static int fill_digest_long_hash(handle_t h_qp, struct wd_digest_msg *msg,
if (ret)
return ret;
- if (msg->has_next && !msg->iv_bytes) {
+ if (bd_type == HASH_FRIST_BD) {
/* Long hash first */
sqe->ai_apd_cs = AI_GEN_INNER;
sqe->ai_apd_cs |= AUTHPAD_NOPAD << AUTHPAD_OFFSET;
}
- if (msg->has_next && msg->iv_bytes) {
+ if (bd_type == HASH_MIDDLE_BD) {
/* Long hash middle */
sqe->ai_apd_cs = AI_GEN_IVIN_ADDR;
sqe->ai_apd_cs |= AUTHPAD_NOPAD << AUTHPAD_OFFSET;
sqe->type2.a_ivin_addr = sqe->type2.mac_addr;
}
- if (!msg->has_next && msg->iv_bytes) {
+ if (bd_type == HASH_END_BD) {
/* Long hash end */
sqe->ai_apd_cs = AI_GEN_IVIN_ADDR;
sqe->ai_apd_cs |= AUTHPAD_PAD << AUTHPAD_OFFSET;
@@ -1478,14 +1505,38 @@ static int aes_auth_len_check(struct wd_digest_msg *msg)
return 0;
}
+static int digest_bd2_zero_packet_check(struct wd_digest_msg *msg)
+{
+ enum hash_bd_type type = get_hash_bd_type(msg);
+
+ /* Long hash first and middle bd */
+ if (type == HASH_FRIST_BD || type == HASH_MIDDLE_BD) {
+ WD_ERR("hardware v2 not supports 0 size in long hash!\n");
+ return -WD_EINVAL;
+ }
+
+ /* Block mode hash bd */
+ if (type == HASH_SINGLE_BD) {
+ WD_ERR("hardware v2 not supports 0 size in block hash!\n");
+ return -WD_EINVAL;
+ }
+
+ return 0;
+}
+
static int digest_len_check(struct wd_digest_msg *msg, enum sec_bd_type type)
{
int ret;
- /* End BD not need to check the input zero bytes */
- if (unlikely(type == BD_TYPE2 && !msg->has_next && !msg->in_bytes)) {
- WD_ERR("kunpeng 920, digest mode not support 0 size!\n");
- return -WD_EINVAL;
+ /*
+ * Hardware v2 needs to check the zero byte packet in the block
+ * and long hash mode. Frist and Middle bd not supports 0 size,
+ * final bd not need to check it. Hardware v3 has fixed it.
+ */
+ if (type == BD_TYPE2 && !msg->in_bytes) {
+ ret = digest_bd2_zero_packet_check(msg);
+ if (ret)
+ return ret;
}
if (type == BD_TYPE3) {
@@ -1714,6 +1765,7 @@ static int aes_auth_long_hash_check(struct wd_digest_msg *msg)
static int fill_digest_long_hash3(handle_t h_qp, struct wd_digest_msg *msg,
struct hisi_sec_sqe3 *sqe)
{
+ enum hash_bd_type bd_type = get_hash_bd_type(msg);
__u64 total_bits;
int ret;
@@ -1725,20 +1777,20 @@ static int fill_digest_long_hash3(handle_t h_qp, struct wd_digest_msg *msg,
if (ret)
return ret;
- if (msg->has_next && !msg->iv_bytes) {
+ if (bd_type == HASH_FRIST_BD) {
/* Long hash first */
sqe->auth_mac_key |= AI_GEN_INNER << SEC_AI_GEN_OFFSET_V3;
sqe->stream_scene.stream_auth_pad = AUTHPAD_NOPAD;
}
- if (msg->has_next && msg->iv_bytes) {
+ if (bd_type == HASH_MIDDLE_BD) {
/* Long hash middle */
sqe->auth_mac_key |= AI_GEN_IVIN_ADDR << SEC_AI_GEN_OFFSET_V3;
sqe->stream_scene.stream_auth_pad = AUTHPAD_NOPAD;
sqe->auth_ivin.a_ivin_addr = sqe->mac_addr;
}
- if (!msg->has_next && msg->iv_bytes) {
+ if (bd_type == HASH_END_BD) {
/* Long hash end */
sqe->auth_mac_key |= AI_GEN_IVIN_ADDR << SEC_AI_GEN_OFFSET_V3;
sqe->stream_scene.stream_auth_pad = AUTHPAD_PAD;
--
2.17.1