int qat_rsa_set_n(struct qat_rsa_ctx *ctx, const char *value, size_t vlen)
{
	struct qat_crypto_instance *inst = ctx->inst;
	struct device *dev = &GET_DEV(inst->accel_dev);
	const char *ptr = value;
	int ret;

	while (!*ptr && vlen) {
		ptr++;
		vlen--;
	}

	ctx->key_sz = vlen;
	ret = -EINVAL;
	/* invalid key size provided */
	if (!qat_rsa_enc_fn_id(ctx->key_sz))
		goto err;

	ret = -ENOMEM;
	ctx->n = dma_zalloc_coherent(dev, ctx->key_sz, &ctx->dma_n, GFP_KERNEL);
	if (!ctx->n)
		goto err;

	memcpy(ctx->n, ptr, ctx->key_sz);
	return 0;
err:
	ctx->key_sz = 0;
	ctx->n = NULL;
	return ret;
}
Exemplo n.º 2
0
int qat_rsa_get_n(void *context, size_t hdrlen, unsigned char tag,
		  const void *value, size_t vlen)
{
	struct qat_rsa_ctx *ctx = context;
	struct qat_crypto_instance *inst = ctx->inst;
	struct device *dev = &GET_DEV(inst->accel_dev);
	const char *ptr = value;
	int ret;

	while (!*ptr && vlen) {
		ptr++;
		vlen--;
	}

	ctx->key_sz = vlen;
	ret = -EINVAL;
	/* In FIPS mode only allow key size 2K & 3K */
	if (fips_enabled && (ctx->key_sz != 256 && ctx->key_sz != 384)) {
		pr_err("QAT: RSA: key size not allowed in FIPS mode\n");
		goto err;
	}
	/* invalid key size provided */
	if (!qat_rsa_enc_fn_id(ctx->key_sz))
		goto err;

	ret = -ENOMEM;
	ctx->n = dma_zalloc_coherent(dev, ctx->key_sz, &ctx->dma_n, GFP_KERNEL);
	if (!ctx->n)
		goto err;

	memcpy(ctx->n, ptr, ctx->key_sz);
	return 0;
err:
	ctx->key_sz = 0;
	ctx->n = NULL;
	return ret;
}
Exemplo n.º 3
0
static int qat_rsa_enc(struct akcipher_request *req)
{
	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
	struct qat_rsa_ctx *ctx = akcipher_tfm_ctx(tfm);
	struct qat_crypto_instance *inst = ctx->inst;
	struct device *dev = &GET_DEV(inst->accel_dev);
	struct qat_rsa_request *qat_req =
			PTR_ALIGN(akcipher_request_ctx(req), 64);
	struct icp_qat_fw_pke_request *msg = &qat_req->req;
	int ret, ctr = 0;

	if (unlikely(!ctx->n || !ctx->e))
		return -EINVAL;

	if (req->dst_len < ctx->key_sz) {
		req->dst_len = ctx->key_sz;
		return -EOVERFLOW;
	}
	memset(msg, '\0', sizeof(*msg));
	ICP_QAT_FW_PKE_HDR_VALID_FLAG_SET(msg->pke_hdr,
					  ICP_QAT_FW_COMN_REQ_FLAG_SET);
	msg->pke_hdr.cd_pars.func_id = qat_rsa_enc_fn_id(ctx->key_sz);
	if (unlikely(!msg->pke_hdr.cd_pars.func_id))
		return -EINVAL;

	qat_req->ctx = ctx;
	msg->pke_hdr.service_type = ICP_QAT_FW_COMN_REQ_CPM_FW_PKE;
	msg->pke_hdr.comn_req_flags =
		ICP_QAT_FW_COMN_FLAGS_BUILD(QAT_COMN_PTR_TYPE_FLAT,
					    QAT_COMN_CD_FLD_TYPE_64BIT_ADR);

	qat_req->in.enc.e = ctx->dma_e;
	qat_req->in.enc.n = ctx->dma_n;
	ret = -ENOMEM;

	/*
	 * src can be of any size in valid range, but HW expects it to be the
	 * same as modulo n so in case it is different we need to allocate a
	 * new buf and copy src data.
	 * In other case we just need to map the user provided buffer.
	 */
	if (req->src_len < ctx->key_sz) {
		int shift = ctx->key_sz - req->src_len;

		qat_req->src_align = dma_zalloc_coherent(dev, ctx->key_sz,
							 &qat_req->in.enc.m,
							 GFP_KERNEL);
		if (unlikely(!qat_req->src_align))
			return ret;

		memcpy(qat_req->src_align + shift, req->src, req->src_len);
	} else {
		qat_req->src_align = NULL;
		qat_req->in.enc.m = dma_map_single(dev, req->src, req->src_len,
					   DMA_TO_DEVICE);
	}
	qat_req->in.in_tab[3] = 0;
	qat_req->out.enc.c = dma_map_single(dev, req->dst, req->dst_len,
					    DMA_FROM_DEVICE);
	qat_req->out.out_tab[1] = 0;
	qat_req->phy_in = dma_map_single(dev, &qat_req->in.enc.m,
					 sizeof(struct qat_rsa_input_params),
					 DMA_TO_DEVICE);
	qat_req->phy_out = dma_map_single(dev, &qat_req->out.enc.c,
					  sizeof(struct qat_rsa_output_params),
					    DMA_TO_DEVICE);

	if (unlikely((!qat_req->src_align &&
		      dma_mapping_error(dev, qat_req->in.enc.m)) ||
		     dma_mapping_error(dev, qat_req->out.enc.c) ||
		     dma_mapping_error(dev, qat_req->phy_in) ||
		     dma_mapping_error(dev, qat_req->phy_out)))
		goto unmap;

	msg->pke_mid.src_data_addr = qat_req->phy_in;
	msg->pke_mid.dest_data_addr = qat_req->phy_out;
	msg->pke_mid.opaque = (uint64_t)(__force long)req;
	msg->input_param_count = 3;
	msg->output_param_count = 1;
	do {
		ret = adf_send_message(ctx->inst->pke_tx, (uint32_t *)msg);
	} while (ret == -EBUSY && ctr++ < 100);

	if (!ret)
		return -EINPROGRESS;
unmap:
	if (qat_req->src_align)
		dma_free_coherent(dev, ctx->key_sz, qat_req->src_align,
				  qat_req->in.enc.m);
	else
		if (!dma_mapping_error(dev, qat_req->in.enc.m))
			dma_unmap_single(dev, qat_req->in.enc.m, ctx->key_sz,
					 DMA_TO_DEVICE);
	if (!dma_mapping_error(dev, qat_req->out.enc.c))
		dma_unmap_single(dev, qat_req->out.enc.c, ctx->key_sz,
				 DMA_FROM_DEVICE);
	if (!dma_mapping_error(dev, qat_req->phy_in))
		dma_unmap_single(dev, qat_req->phy_in,
				 sizeof(struct qat_rsa_input_params),
				 DMA_TO_DEVICE);
	if (!dma_mapping_error(dev, qat_req->phy_out))
		dma_unmap_single(dev, qat_req->phy_out,
				 sizeof(struct qat_rsa_output_params),
				 DMA_TO_DEVICE);
	return ret;
}