Ejemplo n.º 1
0
static void qat_alg_init_common_hdr(struct icp_qat_fw_comn_req_hdr *header)
{
	header->hdr_flags =
		ICP_QAT_FW_COMN_HDR_FLAGS_BUILD(ICP_QAT_FW_COMN_REQ_FLAG_SET);
	header->service_type = ICP_QAT_FW_COMN_REQ_CPM_FW_LA;
	header->comn_req_flags =
		ICP_QAT_FW_COMN_FLAGS_BUILD(QAT_COMN_CD_FLD_TYPE_64BIT_ADR,
					    QAT_COMN_PTR_TYPE_SGL);
	ICP_QAT_FW_LA_DIGEST_IN_BUFFER_SET(header->serv_specif_flags,
					   ICP_QAT_FW_LA_DIGEST_IN_BUFFER);
	ICP_QAT_FW_LA_PARTIAL_SET(header->serv_specif_flags,
				  ICP_QAT_FW_LA_PARTIAL_NONE);
	ICP_QAT_FW_LA_CIPH_IV_FLD_FLAG_SET(header->serv_specif_flags,
					   ICP_QAT_FW_CIPH_IV_16BYTE_DATA);
	ICP_QAT_FW_LA_PROTO_SET(header->serv_specif_flags,
				ICP_QAT_FW_LA_NO_PROTO);
	ICP_QAT_FW_LA_UPDATE_STATE_SET(header->serv_specif_flags,
				       ICP_QAT_FW_LA_NO_UPDATE_STATE);
}
Ejemplo n.º 2
0
static int qat_alg_aead_init_dec_session(struct crypto_aead *aead_tfm,
					 int alg,
					 struct crypto_authenc_keys *keys,
					 int mode)
{
	struct qat_alg_aead_ctx *ctx = crypto_aead_ctx(aead_tfm);
	unsigned int digestsize = crypto_aead_authsize(aead_tfm);
	struct qat_dec *dec_ctx = &ctx->dec_cd->qat_dec_cd;
	struct icp_qat_hw_auth_algo_blk *hash = &dec_ctx->hash;
	struct icp_qat_hw_cipher_algo_blk *cipher =
		(struct icp_qat_hw_cipher_algo_blk *)((char *)dec_ctx +
		sizeof(struct icp_qat_hw_auth_setup) +
		roundup(crypto_shash_digestsize(ctx->hash_tfm), 8) * 2);
	struct icp_qat_fw_la_bulk_req *req_tmpl = &ctx->dec_fw_req;
	struct icp_qat_fw_comn_req_hdr_cd_pars *cd_pars = &req_tmpl->cd_pars;
	struct icp_qat_fw_comn_req_hdr *header = &req_tmpl->comn_hdr;
	void *ptr = &req_tmpl->cd_ctrl;
	struct icp_qat_fw_cipher_cd_ctrl_hdr *cipher_cd_ctrl = ptr;
	struct icp_qat_fw_auth_cd_ctrl_hdr *hash_cd_ctrl = ptr;
	struct icp_qat_fw_la_auth_req_params *auth_param =
		(struct icp_qat_fw_la_auth_req_params *)
		((char *)&req_tmpl->serv_specif_rqpars +
		sizeof(struct icp_qat_fw_la_cipher_req_params));

	/* CD setup */
	cipher->aes.cipher_config.val = QAT_AES_HW_CONFIG_DEC(alg, mode);
	memcpy(cipher->aes.key, keys->enckey, keys->enckeylen);
	hash->sha.inner_setup.auth_config.config =
		ICP_QAT_HW_AUTH_CONFIG_BUILD(ICP_QAT_HW_AUTH_MODE1,
					     ctx->qat_hash_alg,
					     digestsize);
	hash->sha.inner_setup.auth_counter.counter =
		cpu_to_be32(crypto_shash_blocksize(ctx->hash_tfm));

	if (qat_alg_do_precomputes(hash, ctx, keys->authkey, keys->authkeylen))
		return -EFAULT;

	/* Request setup */
	qat_alg_init_common_hdr(header);
	header->service_cmd_id = ICP_QAT_FW_LA_CMD_HASH_CIPHER;
	ICP_QAT_FW_LA_DIGEST_IN_BUFFER_SET(header->serv_specif_flags,
					   ICP_QAT_FW_LA_DIGEST_IN_BUFFER);
	ICP_QAT_FW_LA_RET_AUTH_SET(header->serv_specif_flags,
				   ICP_QAT_FW_LA_NO_RET_AUTH_RES);
	ICP_QAT_FW_LA_CMP_AUTH_SET(header->serv_specif_flags,
				   ICP_QAT_FW_LA_CMP_AUTH_RES);
	cd_pars->u.s.content_desc_addr = ctx->dec_cd_paddr;
	cd_pars->u.s.content_desc_params_sz = sizeof(struct qat_alg_cd) >> 3;

	/* Cipher CD config setup */
	cipher_cd_ctrl->cipher_key_sz = keys->enckeylen >> 3;
	cipher_cd_ctrl->cipher_state_sz = AES_BLOCK_SIZE >> 3;
	cipher_cd_ctrl->cipher_cfg_offset =
		(sizeof(struct icp_qat_hw_auth_setup) +
		 roundup(crypto_shash_digestsize(ctx->hash_tfm), 8) * 2) >> 3;
	ICP_QAT_FW_COMN_CURR_ID_SET(cipher_cd_ctrl, ICP_QAT_FW_SLICE_CIPHER);
	ICP_QAT_FW_COMN_NEXT_ID_SET(cipher_cd_ctrl, ICP_QAT_FW_SLICE_DRAM_WR);

	/* Auth CD config setup */
	hash_cd_ctrl->hash_cfg_offset = 0;
	hash_cd_ctrl->hash_flags = ICP_QAT_FW_AUTH_HDR_FLAG_NO_NESTED;
	hash_cd_ctrl->inner_res_sz = digestsize;
	hash_cd_ctrl->final_sz = digestsize;

	switch (ctx->qat_hash_alg) {
	case ICP_QAT_HW_AUTH_ALGO_SHA1:
		hash_cd_ctrl->inner_state1_sz =
			round_up(ICP_QAT_HW_SHA1_STATE1_SZ, 8);
		hash_cd_ctrl->inner_state2_sz =
			round_up(ICP_QAT_HW_SHA1_STATE2_SZ, 8);
		break;
	case ICP_QAT_HW_AUTH_ALGO_SHA256:
		hash_cd_ctrl->inner_state1_sz = ICP_QAT_HW_SHA256_STATE1_SZ;
		hash_cd_ctrl->inner_state2_sz = ICP_QAT_HW_SHA256_STATE2_SZ;
		break;
	case ICP_QAT_HW_AUTH_ALGO_SHA512:
		hash_cd_ctrl->inner_state1_sz = ICP_QAT_HW_SHA512_STATE1_SZ;
		hash_cd_ctrl->inner_state2_sz = ICP_QAT_HW_SHA512_STATE2_SZ;
		break;
	default:
		break;
	}

	hash_cd_ctrl->inner_state2_offset = hash_cd_ctrl->hash_cfg_offset +
			((sizeof(struct icp_qat_hw_auth_setup) +
			 round_up(hash_cd_ctrl->inner_state1_sz, 8)) >> 3);
	auth_param->auth_res_sz = digestsize;
	ICP_QAT_FW_COMN_CURR_ID_SET(hash_cd_ctrl, ICP_QAT_FW_SLICE_AUTH);
	ICP_QAT_FW_COMN_NEXT_ID_SET(hash_cd_ctrl, ICP_QAT_FW_SLICE_CIPHER);
	return 0;
}
Ejemplo n.º 3
0
int qat_alg_aead_session_create_content_desc(struct qat_session *cdesc,
        uint8_t *cipherkey, uint32_t cipherkeylen,
        uint8_t *authkey, uint32_t authkeylen,
        uint32_t add_auth_data_length,
        uint32_t digestsize)
{
    struct qat_alg_cd *content_desc = &cdesc->cd;
    struct icp_qat_hw_cipher_algo_blk *cipher = &content_desc->cipher;
    struct icp_qat_hw_auth_algo_blk *hash = &content_desc->hash;
    struct icp_qat_fw_la_bulk_req *req_tmpl = &cdesc->fw_req;
    struct icp_qat_fw_comn_req_hdr_cd_pars *cd_pars = &req_tmpl->cd_pars;
    struct icp_qat_fw_comn_req_hdr *header = &req_tmpl->comn_hdr;
    void *ptr = &req_tmpl->cd_ctrl;
    struct icp_qat_fw_cipher_cd_ctrl_hdr *cipher_cd_ctrl = ptr;
    struct icp_qat_fw_auth_cd_ctrl_hdr *hash_cd_ctrl = ptr;
    struct icp_qat_fw_la_auth_req_params *auth_param =
        (struct icp_qat_fw_la_auth_req_params *)
        ((char *)&req_tmpl->serv_specif_rqpars +
         sizeof(struct icp_qat_fw_la_cipher_req_params));
    enum icp_qat_hw_cipher_convert key_convert;
    uint16_t proto = ICP_QAT_FW_LA_NO_PROTO; /* no CCM/GCM/Snow3G */
    uint16_t state1_size = 0;
    uint16_t state2_size = 0;

    PMD_INIT_FUNC_TRACE();

    /* CD setup */
    if (cdesc->qat_dir == ICP_QAT_HW_CIPHER_ENCRYPT) {
        key_convert = ICP_QAT_HW_CIPHER_NO_CONVERT;
        ICP_QAT_FW_LA_RET_AUTH_SET(header->serv_specif_flags,
                                   ICP_QAT_FW_LA_RET_AUTH_RES);
        ICP_QAT_FW_LA_CMP_AUTH_SET(header->serv_specif_flags,
                                   ICP_QAT_FW_LA_NO_CMP_AUTH_RES);
    } else {
        key_convert = ICP_QAT_HW_CIPHER_KEY_CONVERT;
        ICP_QAT_FW_LA_RET_AUTH_SET(header->serv_specif_flags,
                                   ICP_QAT_FW_LA_NO_RET_AUTH_RES);
        ICP_QAT_FW_LA_CMP_AUTH_SET(header->serv_specif_flags,
                                   ICP_QAT_FW_LA_CMP_AUTH_RES);
    }

    cipher->aes.cipher_config.val = ICP_QAT_HW_CIPHER_CONFIG_BUILD(
                                        cdesc->qat_mode, cdesc->qat_cipher_alg, key_convert,
                                        cdesc->qat_dir);
    memcpy(cipher->aes.key, cipherkey, cipherkeylen);

    hash->sha.inner_setup.auth_config.reserved = 0;
    hash->sha.inner_setup.auth_config.config =
        ICP_QAT_HW_AUTH_CONFIG_BUILD(ICP_QAT_HW_AUTH_MODE1,
                                     cdesc->qat_hash_alg, digestsize);
    hash->sha.inner_setup.auth_counter.counter =
        rte_bswap32(qat_hash_get_block_size(cdesc->qat_hash_alg));

    /* Do precomputes */
    if (cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC) {
        if (qat_alg_do_precomputes(cdesc->qat_hash_alg,
                                   authkey, authkeylen, (uint8_t *)(hash->sha.state1 +
                                           ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ), &state2_size)) {
            PMD_DRV_LOG(ERR, "(XCBC)precompute failed");
            return -EFAULT;
        }
    } else if ((cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_128) ||
               (cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_64)) {
        if (qat_alg_do_precomputes(cdesc->qat_hash_alg,
                                   cipherkey, cipherkeylen, (uint8_t *)(hash->sha.state1 +
                                           ICP_QAT_HW_GALOIS_128_STATE1_SZ), &state2_size)) {
            PMD_DRV_LOG(ERR, "(GCM)precompute failed");
            return -EFAULT;
        }
        /*
         * Write (the length of AAD) into bytes 16-19 of state2
         * in big-endian format. This field is 8 bytes
         */
        *(uint32_t *)&(hash->sha.state1[
                           ICP_QAT_HW_GALOIS_128_STATE1_SZ +
                           ICP_QAT_HW_GALOIS_H_SZ]) =
                               rte_bswap32(add_auth_data_length);
        proto = ICP_QAT_FW_LA_GCM_PROTO;
    } else {
        if (qat_alg_do_precomputes(cdesc->qat_hash_alg,
                                   authkey, authkeylen, (uint8_t *)(hash->sha.state1),
                                   &state1_size)) {
            PMD_DRV_LOG(ERR, "(SHA)precompute failed");
            return -EFAULT;
        }
    }

    /* Request template setup */
    qat_alg_init_common_hdr(header);
    header->service_cmd_id = cdesc->qat_cmd;
    ICP_QAT_FW_LA_DIGEST_IN_BUFFER_SET(header->serv_specif_flags,
                                       ICP_QAT_FW_LA_DIGEST_IN_BUFFER);
    /* Configure the common header protocol flags */
    ICP_QAT_FW_LA_PROTO_SET(header->serv_specif_flags, proto);
    cd_pars->u.s.content_desc_addr = cdesc->cd_paddr;
    cd_pars->u.s.content_desc_params_sz = sizeof(struct qat_alg_cd) >> 3;

    /* Cipher CD config setup */
    cipher_cd_ctrl->cipher_key_sz = cipherkeylen >> 3;
    cipher_cd_ctrl->cipher_state_sz = ICP_QAT_HW_AES_BLK_SZ >> 3;
    cipher_cd_ctrl->cipher_cfg_offset = 0;

    /* Auth CD config setup */
    hash_cd_ctrl->hash_cfg_offset = ((char *)hash - (char *)cipher) >> 3;
    hash_cd_ctrl->hash_flags = ICP_QAT_FW_AUTH_HDR_FLAG_NO_NESTED;
    hash_cd_ctrl->inner_res_sz = digestsize;
    hash_cd_ctrl->final_sz = digestsize;
    hash_cd_ctrl->inner_state1_sz = state1_size;

    switch (cdesc->qat_hash_alg) {
    case ICP_QAT_HW_AUTH_ALGO_SHA1:
        hash_cd_ctrl->inner_state2_sz =
            RTE_ALIGN_CEIL(ICP_QAT_HW_SHA1_STATE2_SZ, 8);
        break;
    case ICP_QAT_HW_AUTH_ALGO_SHA256:
        hash_cd_ctrl->inner_state2_sz = ICP_QAT_HW_SHA256_STATE2_SZ;
        break;
    case ICP_QAT_HW_AUTH_ALGO_SHA512:
        hash_cd_ctrl->inner_state2_sz = ICP_QAT_HW_SHA512_STATE2_SZ;
        break;
    case ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC:
        hash_cd_ctrl->inner_state2_sz =
            ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ;
        hash_cd_ctrl->inner_state1_sz =
            ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ;
        memset(hash->sha.state1, 0, ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ);
        break;
    case ICP_QAT_HW_AUTH_ALGO_GALOIS_128:
    case ICP_QAT_HW_AUTH_ALGO_GALOIS_64:
        hash_cd_ctrl->inner_state2_sz = ICP_QAT_HW_GALOIS_H_SZ +
                                        ICP_QAT_HW_GALOIS_LEN_A_SZ +
                                        ICP_QAT_HW_GALOIS_E_CTR0_SZ;
        hash_cd_ctrl->inner_state1_sz = ICP_QAT_HW_GALOIS_128_STATE1_SZ;
        memset(hash->sha.state1, 0, ICP_QAT_HW_GALOIS_128_STATE1_SZ);
        break;
    default:
        PMD_DRV_LOG(ERR, "invalid HASH alg %u", cdesc->qat_hash_alg);
        return -EFAULT;
    }

    hash_cd_ctrl->inner_state2_offset = hash_cd_ctrl->hash_cfg_offset +
                                        ((sizeof(struct icp_qat_hw_auth_setup) +
                                          RTE_ALIGN_CEIL(hash_cd_ctrl->inner_state1_sz, 8))
                                         >> 3);
    auth_param->auth_res_sz = digestsize;


    if (cdesc->qat_cmd == ICP_QAT_FW_LA_CMD_CIPHER_HASH) {
        ICP_QAT_FW_COMN_CURR_ID_SET(cipher_cd_ctrl,
                                    ICP_QAT_FW_SLICE_CIPHER);
        ICP_QAT_FW_COMN_NEXT_ID_SET(cipher_cd_ctrl,
                                    ICP_QAT_FW_SLICE_AUTH);
        ICP_QAT_FW_COMN_CURR_ID_SET(hash_cd_ctrl,
                                    ICP_QAT_FW_SLICE_AUTH);
        ICP_QAT_FW_COMN_NEXT_ID_SET(hash_cd_ctrl,
                                    ICP_QAT_FW_SLICE_DRAM_WR);
    } else if (cdesc->qat_cmd == ICP_QAT_FW_LA_CMD_HASH_CIPHER) {
        ICP_QAT_FW_COMN_CURR_ID_SET(hash_cd_ctrl,
                                    ICP_QAT_FW_SLICE_AUTH);
        ICP_QAT_FW_COMN_NEXT_ID_SET(hash_cd_ctrl,
                                    ICP_QAT_FW_SLICE_CIPHER);
        ICP_QAT_FW_COMN_CURR_ID_SET(cipher_cd_ctrl,
                                    ICP_QAT_FW_SLICE_CIPHER);
        ICP_QAT_FW_COMN_NEXT_ID_SET(cipher_cd_ctrl,
                                    ICP_QAT_FW_SLICE_DRAM_WR);
    } else {
        PMD_DRV_LOG(ERR, "invalid param, only authenticated "
                    "encryption supported");
        return -EFAULT;
    }
    return 0;
}