{
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- crypto_digest_digest(tcp_conn->tx_tfm, &buf->sg, 1, crc);
- buf->sg.length += sizeof(uint32_t);
+ crypto_hash_digest(&tcp_conn->tx_hash, &buf->sg, buf->sg.length, crc);
+ buf->sg.length = tcp_conn->hdr_size;
}
static inline int
sg_init_one(&sg, (u8 *)hdr,
sizeof(struct iscsi_hdr) + ahslen);
- crypto_digest_digest(tcp_conn->rx_tfm, &sg, 1, (u8 *)&cdgst);
+ crypto_hash_digest(&tcp_conn->rx_hash, &sg, sg.length,
+ (u8 *)&cdgst);
rdgst = *(uint32_t*)((char*)hdr + sizeof(struct iscsi_hdr) +
ahslen);
if (cdgst != rdgst) {
* byte counters.
**/
static inline int
-iscsi_tcp_copy(struct iscsi_conn *conn)
+iscsi_tcp_copy(struct iscsi_conn *conn, int buf_size)
{
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- int buf_size = tcp_conn->in.datalen;
int buf_left = buf_size - tcp_conn->data_copied;
int size = min(tcp_conn->in.copy, buf_left);
int rc;
}
static inline void
-partial_sg_digest_update(struct crypto_tfm *tfm, struct scatterlist *sg,
+partial_sg_digest_update(struct hash_desc *desc, struct scatterlist *sg,
int offset, int length)
{
struct scatterlist temp;
memcpy(&temp, sg, sizeof(struct scatterlist));
temp.offset = offset;
temp.length = length;
- crypto_digest_update(tfm, &temp, 1);
+ crypto_hash_update(desc, &temp, length);
}
static void
struct scatterlist tmp;
sg_init_one(&tmp, buf, len);
- crypto_digest_update(tcp_conn->data_rx_tfm, &tmp, 1);
+ crypto_hash_update(&tcp_conn->rx_hash, &tmp, len);
}
static int iscsi_scsi_data_in(struct iscsi_conn *conn)
if (!rc) {
if (conn->datadgst_en) {
if (!offset)
- crypto_digest_update(
- tcp_conn->data_rx_tfm,
+ crypto_hash_update(
+ &tcp_conn->rx_hash,
&sg[i], 1);
else
partial_sg_digest_update(
- tcp_conn->data_rx_tfm,
+ &tcp_conn->rx_hash,
&sg[i],
sg[i].offset + offset,
sg[i].length - offset);
/*
* data-in is complete, but buffer not...
*/
- partial_sg_digest_update(tcp_conn->data_rx_tfm,
- &sg[i],
- sg[i].offset, sg[i].length-rc);
+ partial_sg_digest_update(&tcp_conn->rx_hash,
+ &sg[i],
+ sg[i].offset,
+ sg[i].length-rc);
rc = 0;
break;
}
* Collect data segment to the connection's data
* placeholder
*/
- if (iscsi_tcp_copy(conn)) {
+ if (iscsi_tcp_copy(conn, tcp_conn->in.datalen)) {
rc = -EAGAIN;
goto exit;
}
*/
rc = iscsi_tcp_hdr_recv(conn);
if (!rc && tcp_conn->in.datalen) {
- if (conn->datadgst_en) {
- BUG_ON(!tcp_conn->data_rx_tfm);
- crypto_digest_init(tcp_conn->data_rx_tfm);
- }
+ if (conn->datadgst_en)
+ crypto_hash_init(&tcp_conn->rx_hash);
tcp_conn->in_progress = IN_PROGRESS_DATA_RECV;
} else if (rc) {
iscsi_conn_failure(conn, rc);
debug_tcp("extra data_recv offset %d copy %d\n",
tcp_conn->in.offset, tcp_conn->in.copy);
- skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset,
- &recv_digest, 4);
- tcp_conn->in.offset += 4;
- tcp_conn->in.copy -= 4;
+ rc = iscsi_tcp_copy(conn, sizeof(uint32_t));
+ if (rc) {
+ if (rc == -EAGAIN)
+ goto again;
+ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+ return 0;
+ }
+
+ memcpy(&recv_digest, conn->data, sizeof(uint32_t));
if (recv_digest != tcp_conn->in.datadgst) {
debug_tcp("iscsi_tcp: data digest error!"
"0x%x != 0x%x\n", recv_digest,
tcp_conn->in.padding);
memset(pad, 0, tcp_conn->in.padding);
sg_init_one(&sg, pad, tcp_conn->in.padding);
- crypto_digest_update(tcp_conn->data_rx_tfm,
- &sg, 1);
+ crypto_hash_update(&tcp_conn->rx_hash,
+ &sg, sg.length);
}
- crypto_digest_final(tcp_conn->data_rx_tfm,
- (u8 *) & tcp_conn->in.datadgst);
+ crypto_hash_final(&tcp_conn->rx_hash,
+ (u8 *) &tcp_conn->in.datadgst);
debug_tcp("rx digest 0x%x\n", tcp_conn->in.datadgst);
tcp_conn->in_progress = IN_PROGRESS_DDIGEST_RECV;
+ tcp_conn->data_copied = 0;
} else
tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
}
iscsi_data_digest_init(struct iscsi_tcp_conn *tcp_conn,
struct iscsi_tcp_cmd_task *tcp_ctask)
{
- crypto_digest_init(tcp_conn->data_tx_tfm);
+ crypto_hash_init(&tcp_conn->tx_hash);
tcp_ctask->digest_count = 4;
}
iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad,
tcp_ctask->pad_count);
if (conn->datadgst_en)
- crypto_digest_update(tcp_conn->data_tx_tfm,
- &tcp_ctask->sendbuf.sg, 1);
+ crypto_hash_update(&tcp_conn->tx_hash,
+ &tcp_ctask->sendbuf.sg,
+ tcp_ctask->sendbuf.sg.length);
} else if (!(tcp_ctask->xmstate & XMSTATE_W_RESEND_PAD))
return 0;
tcp_conn = conn->dd_data;
if (!(tcp_ctask->xmstate & XMSTATE_W_RESEND_DATA_DIGEST)) {
- crypto_digest_final(tcp_conn->data_tx_tfm, (u8*)digest);
+ crypto_hash_final(&tcp_conn->tx_hash, (u8*)digest);
iscsi_buf_init_iov(buf, (char*)digest, 4);
}
tcp_ctask->xmstate &= ~XMSTATE_W_RESEND_DATA_DIGEST;
rc = iscsi_sendpage(conn, sendbuf, count, &buf_sent);
*sent = *sent + buf_sent;
if (buf_sent && conn->datadgst_en)
- partial_sg_digest_update(tcp_conn->data_tx_tfm,
+ partial_sg_digest_update(&tcp_conn->tx_hash,
&sendbuf->sg, sendbuf->sg.offset + offset,
buf_sent);
if (!iscsi_buf_left(sendbuf) && *sg != tcp_ctask->bad_sg) {
if (conn->hdrdgst_en)
iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
(u8*)dtask->hdrext);
- if (conn->datadgst_en) {
- iscsi_data_digest_init(ctask->conn->dd_data, tcp_ctask);
- dtask->digest = 0;
- }
tcp_ctask->xmstate &= ~XMSTATE_UNS_INIT;
iscsi_set_padding(tcp_ctask, ctask->data_count);
return rc;
}
+ if (conn->datadgst_en) {
+ dtask = &tcp_ctask->unsol_dtask;
+ iscsi_data_digest_init(ctask->conn->dd_data, tcp_ctask);
+ dtask->digest = 0;
+ }
+
debug_scsi("uns dout [itt 0x%x dlen %d sent %d]\n",
ctask->itt, ctask->unsol_count, tcp_ctask->sent);
return 0;
if (conn->hdrdgst_en)
iscsi_hdr_digest(conn, &r2t->headbuf,
(u8*)dtask->hdrext);
-
- if (conn->datadgst_en) {
- iscsi_data_digest_init(conn->dd_data, tcp_ctask);
- dtask->digest = 0;
- }
-
rc = iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count);
if (rc) {
tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA;
return rc;
}
+ if (conn->datadgst_en) {
+ iscsi_data_digest_init(conn->dd_data, tcp_ctask);
+ dtask->digest = 0;
+ }
+
iscsi_set_padding(tcp_ctask, r2t->data_count);
debug_scsi("sol dout [dsn %d itt 0x%x dlen %d sent %d]\n",
r2t->solicit_datasn - 1, ctask->itt, r2t->data_count,
/* initial operational parameters */
tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
+ tcp_conn->tx_hash.tfm = crypto_alloc_hash("crc32c", 0,
+ CRYPTO_ALG_ASYNC);
+ tcp_conn->tx_hash.flags = 0;
+ if (!tcp_conn->tx_hash.tfm)
+ goto free_tcp_conn;
+
+ tcp_conn->rx_hash.tfm = crypto_alloc_hash("crc32c", 0,
+ CRYPTO_ALG_ASYNC);
+ tcp_conn->rx_hash.flags = 0;
+ if (!tcp_conn->rx_hash.tfm)
+ goto free_tx_tfm;
+
return cls_conn;
+free_tx_tfm:
+ crypto_free_hash(tcp_conn->tx_hash.tfm);
+free_tcp_conn:
+ kfree(tcp_conn);
tcp_conn_alloc_fail:
iscsi_conn_teardown(cls_conn);
return NULL;
/* now free tcp_conn */
if (digest) {
- if (tcp_conn->tx_tfm)
- crypto_free_tfm(tcp_conn->tx_tfm);
- if (tcp_conn->rx_tfm)
- crypto_free_tfm(tcp_conn->rx_tfm);
- if (tcp_conn->data_tx_tfm)
- crypto_free_tfm(tcp_conn->data_tx_tfm);
- if (tcp_conn->data_rx_tfm)
- crypto_free_tfm(tcp_conn->data_rx_tfm);
+ if (tcp_conn->tx_hash.tfm)
+ crypto_free_hash(tcp_conn->tx_hash.tfm);
+ if (tcp_conn->rx_hash.tfm)
+ crypto_free_hash(tcp_conn->rx_hash.tfm);
}
kfree(tcp_conn);
iscsi_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
{
struct iscsi_conn *conn = cls_conn->dd_data;
+ struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
iscsi_conn_stop(cls_conn, flag);
iscsi_tcp_release_conn(conn);
+ tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
}
static int
case ISCSI_PARAM_HDRDGST_EN:
iscsi_set_param(cls_conn, param, buf, buflen);
tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
- if (conn->hdrdgst_en) {
+ if (conn->hdrdgst_en)
tcp_conn->hdr_size += sizeof(__u32);
- if (!tcp_conn->tx_tfm)
- tcp_conn->tx_tfm = crypto_alloc_tfm("crc32c",
- 0);
- if (!tcp_conn->tx_tfm)
- return -ENOMEM;
- if (!tcp_conn->rx_tfm)
- tcp_conn->rx_tfm = crypto_alloc_tfm("crc32c",
- 0);
- if (!tcp_conn->rx_tfm) {
- crypto_free_tfm(tcp_conn->tx_tfm);
- return -ENOMEM;
- }
- } else {
- if (tcp_conn->tx_tfm)
- crypto_free_tfm(tcp_conn->tx_tfm);
- if (tcp_conn->rx_tfm)
- crypto_free_tfm(tcp_conn->rx_tfm);
- }
break;
case ISCSI_PARAM_DATADGST_EN:
iscsi_set_param(cls_conn, param, buf, buflen);
- if (conn->datadgst_en) {
- if (!tcp_conn->data_tx_tfm)
- tcp_conn->data_tx_tfm =
- crypto_alloc_tfm("crc32c", 0);
- if (!tcp_conn->data_tx_tfm)
- return -ENOMEM;
- if (!tcp_conn->data_rx_tfm)
- tcp_conn->data_rx_tfm =
- crypto_alloc_tfm("crc32c", 0);
- if (!tcp_conn->data_rx_tfm) {
- crypto_free_tfm(tcp_conn->data_tx_tfm);
- return -ENOMEM;
- }
- } else {
- if (tcp_conn->data_tx_tfm)
- crypto_free_tfm(tcp_conn->data_tx_tfm);
- if (tcp_conn->data_rx_tfm)
- crypto_free_tfm(tcp_conn->data_rx_tfm);
- }
tcp_conn->sendpage = conn->datadgst_en ?
sock_no_sendpage : tcp_conn->sock->ops->sendpage;
break;