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; }
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; }
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; }