scsi: qla2xxx: edif: Add key update

Some FC adapters from Marvell offer the ability to encrypt data in flight
(EDIF). This feature requires an application to act as an authenticator.

As part of the authentication process, the authentication application will
generate a SADB entry (Security Association/SA, key, SPI value, etc). This
SADB is then passed to driver to be programmed into hardware. There will be
a pair of SADB's (Tx and Rx) for each connection.

After some period, the application can choose to change the key. At that
time, a new set of SADB pair is given to driver. The old set of SADB will
be deleted.

Add a new bsg call (QL_VND_SC_SA_UPDATE) to allow application to allow
adding or deleting SADB entries.  Driver will not keep the key in
memory. It will pass it to HW.

It is assumed that application will assign a unique SPI value to this SADB
(SA + key). Driver + hardware will assign a handle to track this unique
SPI/SADB.

Link: https://lore.kernel.org/r/20210624052606.21613-6-njavali@marvell.com
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Co-developed-by: Larry Wisneski <Larry.Wisneski@marvell.com>
Signed-off-by: Larry Wisneski <Larry.Wisneski@marvell.com>
Co-developed-by: Duane Grigsby <duane.grigsby@marvell.com>
Signed-off-by: Duane Grigsby <duane.grigsby@marvell.com>
Co-developed-by: Rick Hicksted Jr <rhicksted@marvell.com>
Signed-off-by: Rick Hicksted Jr <rhicksted@marvell.com>
Signed-off-by: Quinn Tran <qutran@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Quinn Tran 2021-06-23 22:26:00 -07:00 committed by Martin K. Petersen
parent fac2807946
commit dd30706e73
10 changed files with 1668 additions and 7 deletions

View File

@ -401,6 +401,7 @@ struct srb_cmd {
#define SRB_CRC_CTX_DSD_VALID BIT_5 /* DIF: dsd_list valid */
#define SRB_WAKEUP_ON_COMP BIT_6
#define SRB_DIF_BUNDL_DMA_VALID BIT_7 /* DIF: DMA list valid */
#define SRB_EDIF_CLEANUP_DELETE BIT_9
/* To identify if a srb is of T10-CRC type. @sp => srb_t pointer */
#define IS_PROT_IO(sp) (sp->flags & SRB_CRC_CTX_DSD_VALID)
@ -595,6 +596,10 @@ struct srb_iocb {
u16 cmd;
u16 vp_index;
} ctrlvp;
struct {
struct edif_sa_ctl *sa_ctl;
struct qla_sa_update_frame sa_frame;
} sa_update;
} u;
struct timer_list timer;
@ -2616,7 +2621,12 @@ typedef struct fc_port {
uint32_t app_stop:2;
uint32_t app_started:1;
uint32_t secured_login:1;
uint32_t aes_gmac:1;
uint32_t app_sess_online:1;
uint32_t tx_sa_set:1;
uint32_t rx_sa_set:1;
uint32_t tx_sa_pending:1;
uint32_t rx_sa_pending:1;
uint32_t tx_rekey_cnt;
uint32_t rx_rekey_cnt;
uint64_t tx_bytes;
@ -2624,6 +2634,12 @@ typedef struct fc_port {
uint8_t non_secured_login;
uint8_t auth_state;
uint16_t rekey_cnt;
struct list_head edif_indx_list;
spinlock_t indx_list_lock;
struct list_head tx_sa_list;
struct list_head rx_sa_list;
spinlock_t sa_list_lock;
} edif;
} fc_port_t;
@ -2679,6 +2695,7 @@ static const char * const port_dstate_str[] = {
#define FCF_CONF_COMP_SUPPORTED BIT_4
#define FCF_ASYNC_ACTIVE BIT_5
#define FCF_FCSP_DEVICE BIT_6
#define FCF_EDIF_DELETE BIT_7
/* No loop ID flag. */
#define FC_NO_LOOP_ID 0x1000
@ -3449,6 +3466,7 @@ enum qla_work_type {
QLA_EVT_SP_RETRY,
QLA_EVT_IIDMA,
QLA_EVT_ELS_PLOGI,
QLA_EVT_SA_REPLACE,
};
@ -3507,6 +3525,11 @@ struct qla_work_evt {
u8 fc4_type;
srb_t *sp;
} gpnft;
struct {
struct edif_sa_ctl *sa_ctl;
fc_port_t *fcport;
uint16_t nport_handle;
} sa_update;
} u;
};
@ -4684,6 +4707,16 @@ struct qla_hw_data {
u64 prev_cmd_cnt;
struct dma_pool *purex_dma_pool;
struct btree_head32 host_map;
#define EDIF_NUM_SA_INDEX 512
#define EDIF_TX_SA_INDEX_BASE EDIF_NUM_SA_INDEX
void *edif_rx_sa_id_map;
void *edif_tx_sa_id_map;
spinlock_t sadb_fp_lock;
struct list_head sadb_tx_index_list;
struct list_head sadb_rx_index_list;
spinlock_t sadb_lock; /* protects list */
struct els_reject elsrej;
};
@ -5160,7 +5193,43 @@ enum nexus_wait_type {
WAIT_LUN,
};
#define INVALID_EDIF_SA_INDEX 0xffff
#define RX_DELETE_NO_EDIF_SA_INDEX 0xfffe
#define QLA_SKIP_HANDLE QLA_TGT_SKIP_HANDLE
/* edif hash element */
struct edif_list_entry {
uint16_t handle; /* nport_handle */
uint32_t update_sa_index;
uint32_t delete_sa_index;
uint32_t count; /* counter for filtering sa_index */
#define EDIF_ENTRY_FLAGS_CLEANUP 0x01 /* this index is being cleaned up */
uint32_t flags; /* used by sadb cleanup code */
fc_port_t *fcport; /* needed by rx delay timer function */
struct timer_list timer; /* rx delay timer */
struct list_head next;
};
#define EDIF_TX_INDX_BASE 512
#define EDIF_RX_INDX_BASE 0
#define EDIF_RX_DELETE_FILTER_COUNT 3 /* delay queuing rx delete until this many */
/* entry in the sa_index free pool */
struct sa_index_pair {
uint16_t sa_index;
uint32_t spi;
};
/* edif sa_index data structure */
struct edif_sa_index_entry {
struct sa_index_pair sa_pair[2];
fc_port_t *fcport;
uint16_t handle;
struct list_head next;
};
/* Refer to SNIA SFF 8247 */
struct sff_8247_a0 {
u8 txid; /* transceiver id */

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,27 @@
struct qla_scsi_host;
#define EDIF_APP_ID 0x73730001
#define EDIF_MAX_INDEX 2048
struct edif_sa_ctl {
struct list_head next;
uint16_t del_index;
uint16_t index;
uint16_t slot;
uint16_t flags;
#define EDIF_SA_CTL_FLG_REPL BIT_0
#define EDIF_SA_CTL_FLG_DEL BIT_1
#define EDIF_SA_CTL_FLG_CLEANUP_DEL BIT_4
// Invalidate Index bit and mirrors QLA_SA_UPDATE_FLAGS_DELETE
unsigned long state;
#define EDIF_SA_CTL_USED 1 /* Active Sa update */
#define EDIF_SA_CTL_PEND 2 /* Waiting for slot */
#define EDIF_SA_CTL_REPL 3 /* Active Replace and Delete */
#define EDIF_SA_CTL_DEL 4 /* Delete Pending */
struct fc_port *fcport;
struct bsg_job *bsg_job;
struct qla_sa_update_frame sa_frame;
};
enum enode_flags_t {
ENODE_ACTIVE = 0x1,
};
@ -30,6 +51,46 @@ struct edif_dbell {
struct completion dbell;
};
#define SA_UPDATE_IOCB_TYPE 0x71 /* Security Association Update IOCB entry */
struct sa_update_28xx {
uint8_t entry_type; /* Entry type. */
uint8_t entry_count; /* Entry count. */
uint8_t sys_define; /* System Defined. */
uint8_t entry_status; /* Entry Status. */
uint32_t handle; /* IOCB System handle. */
union {
__le16 nport_handle; /* in: N_PORT handle. */
__le16 comp_sts; /* out: completion status */
#define CS_PORT_EDIF_SUPP_NOT_RDY 0x64
#define CS_PORT_EDIF_INV_REQ 0x66
} u;
uint8_t vp_index;
uint8_t reserved_1;
uint8_t port_id[3];
uint8_t flags;
#define SA_FLAG_INVALIDATE BIT_0
#define SA_FLAG_TX BIT_1 // 1=tx, 0=rx
uint8_t sa_key[32]; /* 256 bit key */
__le32 salt;
__le32 spi;
uint8_t sa_control;
#define SA_CNTL_ENC_FCSP (1 << 3)
#define SA_CNTL_ENC_OPD (2 << 3)
#define SA_CNTL_ENC_MSK (3 << 3) // mask bits 4,3
#define SA_CNTL_AES_GMAC (1 << 2)
#define SA_CNTL_KEY256 (2 << 0)
#define SA_CNTL_KEY128 0
uint8_t reserved_2;
__le16 sa_index; // reserve: bit 11-15
__le16 old_sa_info;
__le16 new_sa_info;
};
#define NUM_ENTRIES 256
#define MAX_PAYLOAD 1024
#define PUR_GET 1

View File

@ -611,6 +611,7 @@ struct sts_entry_24xx {
union {
__le16 reserved_1;
__le16 nvme_rsp_pyld_len;
__le16 edif_sa_index; /* edif sa_index used for initiator read data */
};
__le16 state_flags; /* State flags. */

View File

@ -130,6 +130,13 @@ void qla24xx_free_purex_item(struct purex_item *item);
extern bool qla24xx_risc_firmware_invalid(uint32_t *);
void qla_init_iocb_limit(scsi_qla_host_t *);
void qla_edif_sadb_release(struct qla_hw_data *ha);
int qla_edif_sadb_build_free_pool(struct qla_hw_data *ha);
void qla_edif_sadb_release_free_pool(struct qla_hw_data *ha);
void qla_chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha,
srb_t *sp, struct sts_entry_24xx *sts24);
void qlt_chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha, fc_port_t *fcport,
struct ctio7_from_24xx *ctio);
int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsgjob);
const char *sc_to_str(uint16_t cmd);
@ -238,6 +245,8 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
struct purex_item *pkt);
void qla_pci_set_eeh_busy(struct scsi_qla_host *);
void qla_schedule_eeh_work(struct scsi_qla_host *);
struct edif_sa_ctl *qla_edif_find_sa_ctl_by_index(fc_port_t *fcport,
int index, int dir);
/*
* Global Functions in qla_mid.c source file.
@ -313,6 +322,8 @@ extern int qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *, srb_t *,
struct dsd64 *, uint16_t, struct qla_tgt_cmd *);
extern int qla24xx_get_one_block_sg(uint32_t, struct qla2_sgx *, uint32_t *);
extern int qla24xx_configure_prot_mode(srb_t *, uint16_t *);
extern int qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha,
struct qla_work_evt *e);
/*
* Global Function Prototypes in qla_mbx.c source file.
@ -885,6 +896,9 @@ extern int qla2x00_issue_iocb_timeout(scsi_qla_host_t *, void *,
dma_addr_t, size_t, uint32_t);
extern int qla2x00_get_idma_speed(scsi_qla_host_t *, uint16_t,
uint16_t *, uint16_t *);
extern int qla24xx_sadb_update(struct bsg_job *bsg_job);
extern int qla_post_sa_replace_work(struct scsi_qla_host *vha,
fc_port_t *fcport, uint16_t nport_handle, struct edif_sa_ctl *sa_ctl);
/* 83xx related functions */
void qla83xx_fw_dump(scsi_qla_host_t *vha);
@ -957,12 +971,19 @@ extern void qla_nvme_abort_process_comp_status
/* nvme.c */
void qla_nvme_unregister_remote_port(struct fc_port *fcport);
/* qla_edif.c */
fc_port_t *qla2x00_find_fcport_by_pid(scsi_qla_host_t *vha, port_id_t *id);
void qla_edb_stop(scsi_qla_host_t *vha);
int32_t qla_edif_app_mgmt(struct bsg_job *bsg_job);
void qla_enode_init(scsi_qla_host_t *vha);
void qla_enode_stop(scsi_qla_host_t *vha);
void qla_edif_flush_sa_ctl_lists(fc_port_t *fcport);
void qla24xx_sa_update_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb);
void qla24xx_sa_replace_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb);
void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp);
void qla28xx_sa_update_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
struct sa_update_28xx *pkt);
void qla_handle_els_plogi_done(scsi_qla_host_t *vha, struct event_arg *ea);
#define QLA2XX_HW_ERROR BIT_0

View File

@ -5071,6 +5071,16 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
INIT_LIST_HEAD(&fcport->sess_cmd_list);
spin_lock_init(&fcport->sess_cmd_lock);
spin_lock_init(&fcport->edif.sa_list_lock);
INIT_LIST_HEAD(&fcport->edif.tx_sa_list);
INIT_LIST_HEAD(&fcport->edif.rx_sa_list);
if (vha->e_dbell.db_flags == EDB_ACTIVE)
fcport->edif.app_started = 1;
spin_lock_init(&fcport->edif.indx_list_lock);
INIT_LIST_HEAD(&fcport->edif.edif_indx_list);
return fcport;
}

View File

@ -3839,6 +3839,12 @@ qla2x00_start_sp(srb_t *sp)
case SRB_PRLO_CMD:
qla24xx_prlo_iocb(sp, pkt);
break;
case SRB_SA_UPDATE:
qla24xx_sa_update_iocb(sp, pkt);
break;
case SRB_SA_REPLACE:
qla24xx_sa_replace_iocb(sp, pkt);
break;
default:
break;
}

View File

@ -3191,6 +3191,8 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
sp->qpair->cmd_completion_cnt++;
/* Fast path completion. */
qla_chk_edif_rx_sa_delete_pending(vha, sp, sts24);
if (comp_status == CS_COMPLETE && scsi_status == 0) {
qla2x00_process_completed_request(vha, req, handle);
@ -3585,6 +3587,7 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt)
}
break;
case SA_UPDATE_IOCB_TYPE:
case ABTS_RESP_24XX:
case CTIO_TYPE7:
case CTIO_CRC2:
@ -3883,6 +3886,11 @@ process_err:
purex_entry->els_frame_payload[3]);
}
break;
case SA_UPDATE_IOCB_TYPE:
qla28xx_sa_update_iocb_entry(vha, rsp->req,
(struct sa_update_28xx *)pkt);
break;
default:
/* Type Not Supported. */
ql_dbg(ql_dbg_async, vha, 0x5042,

View File

@ -2835,6 +2835,17 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
spin_lock_init(&ha->tgt.sess_lock);
spin_lock_init(&ha->tgt.atio_lock);
spin_lock_init(&ha->sadb_lock);
INIT_LIST_HEAD(&ha->sadb_tx_index_list);
INIT_LIST_HEAD(&ha->sadb_rx_index_list);
spin_lock_init(&ha->sadb_fp_lock);
if (qla_edif_sadb_build_free_pool(ha)) {
kfree(ha);
goto disable_device;
}
atomic_set(&ha->nvme_active_aen_cnt, 0);
/* Clear our data area */
@ -3868,6 +3879,9 @@ qla2x00_free_device(scsi_qla_host_t *vha)
qla82xx_md_free(vha);
qla_edif_sadb_release_free_pool(ha);
qla_edif_sadb_release(ha);
qla2x00_free_queues(ha);
}
@ -5375,6 +5389,9 @@ qla2x00_do_work(struct scsi_qla_host *vha)
qla24xx_els_dcmd2_iocb(vha, ELS_DCMD_PLOGI,
e->u.fcport.fcport, false);
break;
case QLA_EVT_SA_REPLACE:
qla24xx_issue_sa_replace_iocb(vha, e);
break;
}
if (rc == EAGAIN) {

View File

@ -446,7 +446,7 @@ struct ctio7_from_24xx {
uint8_t vp_index;
uint8_t reserved1[5];
__le32 exchange_address;
__le16 reserved2;
__le16 edif_sa_index;
__le16 flags;
__le32 residual;
__le16 ox_id;