static int caam_rsa_dec_priv_f3(struct akcipher_request *req) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); struct device *jrdev = ctx->dev; struct rsa_edesc *edesc; int ret; /* Allocate extended descriptor */ edesc = rsa_edesc_alloc(req, DESC_RSA_PRIV_F3_LEN); if (IS_ERR(edesc)) return PTR_ERR(edesc); /* Set RSA Decrypt Protocol Data Block - Private Key Form #3 */ ret = set_rsa_priv_f3_pdb(req, edesc); if (ret) goto init_fail; /* Initialize Job Descriptor */ init_rsa_priv_f3_desc(edesc->hw_desc, &edesc->pdb.priv_f3); ret = caam_jr_enqueue(jrdev, edesc->hw_desc, rsa_priv_f3_done, req); if (!ret) return -EINPROGRESS; rsa_priv_f3_unmap(jrdev, edesc, req); init_fail: rsa_io_unmap(jrdev, edesc, req); kfree(edesc); return ret; }
static int pkcs1pad_verify_complete(struct akcipher_request *req, int err) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); const struct rsa_asn1_template *digest_info; unsigned int pos; if (err == -EOVERFLOW) /* Decrypted value had no leading 0 byte */ err = -EINVAL; if (err) goto done; if (req_ctx->child_req.dst_len != ctx->key_size - 1) { err = -EINVAL; goto done; } err = -EBADMSG; if (req_ctx->out_buf[0] != 0x01) goto done; for (pos = 1; pos < req_ctx->child_req.dst_len; pos++) if (req_ctx->out_buf[pos] != 0xff) break; if (pos < 9 || pos == req_ctx->child_req.dst_len || req_ctx->out_buf[pos] != 0x00) goto done; pos++; if (ctx->hash_name) { digest_info = rsa_lookup_asn1(ctx->hash_name); if (!digest_info) goto done; if (memcmp(req_ctx->out_buf + pos, digest_info->data, digest_info->size)) goto done; pos += digest_info->size; } err = 0; if (req->dst_len < req_ctx->child_req.dst_len - pos) err = -EOVERFLOW; req->dst_len = req_ctx->child_req.dst_len - pos; if (!err) sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst, req->dst_len), req_ctx->out_buf + pos, req->dst_len); done: kzfree(req_ctx->out_buf); return err; }
static int caam_rsa_dec(struct akcipher_request *req) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); struct caam_rsa_key *key = &ctx->key; int ret; if (unlikely(!key->n || !key->d)) return -EINVAL; if (req->dst_len < key->n_sz) { req->dst_len = key->n_sz; dev_err(ctx->dev, "Output buffer length less than parameter n\n"); return -EOVERFLOW; } if (key->priv_form == FORM3) ret = caam_rsa_dec_priv_f3(req); else if (key->priv_form == FORM2) ret = caam_rsa_dec_priv_f2(req); else ret = caam_rsa_dec_priv_f1(req); return ret; }
/* * The verify operation is here for completeness similar to the verification * defined in RFC2313 section 10.2 except that block type 0 is not accepted, * as in RFC2437. RFC2437 section 9.2 doesn't define any operation to * retrieve the DigestInfo from a signature, instead the user is expected * to call the sign operation to generate the expected signature and compare * signatures instead of the message-digests. */ static int pkcs1pad_verify(struct akcipher_request *req) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); int err; if (!ctx->key_size || req->src_len < ctx->key_size) return -EINVAL; req_ctx->out_buf = kmalloc(ctx->key_size, GFP_KERNEL); if (!req_ctx->out_buf) return -ENOMEM; pkcs1pad_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf, ctx->key_size, NULL); akcipher_request_set_tfm(&req_ctx->child_req, ctx->child); akcipher_request_set_callback(&req_ctx->child_req, req->base.flags, pkcs1pad_verify_complete_cb, req); /* Reuse input buffer, output to a new buffer */ akcipher_request_set_crypt(&req_ctx->child_req, req->src, req_ctx->out_sg, req->src_len, ctx->key_size); err = crypto_akcipher_verify(&req_ctx->child_req); if (err != -EINPROGRESS && err != -EBUSY) return pkcs1pad_verify_complete(req, err); return err; }
static int caam_rsa_max_size(struct crypto_akcipher *tfm) { struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); struct caam_rsa_key *key = &ctx->key; return (key->n) ? key->n_sz : -EINVAL; }
/* Per session pkc's driver context cleanup function */ static void caam_rsa_exit_tfm(struct crypto_akcipher *tfm) { struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); struct caam_rsa_key *key = &ctx->key; caam_rsa_free_key(key); caam_jr_free(ctx->dev); }
static int pkcs1pad_sign(struct akcipher_request *req) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); struct akcipher_instance *inst = akcipher_alg_instance(tfm); struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst); const struct rsa_asn1_template *digest_info = ictx->digest_info; int err; unsigned int ps_end, digest_size = 0; if (!ctx->key_size) return -EINVAL; if (digest_info) digest_size = digest_info->size; if (req->src_len + digest_size > ctx->key_size - 11) return -EOVERFLOW; if (req->dst_len < ctx->key_size) { req->dst_len = ctx->key_size; return -EOVERFLOW; } req_ctx->in_buf = kmalloc(ctx->key_size - 1 - req->src_len, GFP_KERNEL); if (!req_ctx->in_buf) return -ENOMEM; ps_end = ctx->key_size - digest_size - req->src_len - 2; req_ctx->in_buf[0] = 0x01; memset(req_ctx->in_buf + 1, 0xff, ps_end - 1); req_ctx->in_buf[ps_end] = 0x00; if (digest_info) memcpy(req_ctx->in_buf + ps_end + 1, digest_info->data, digest_info->size); pkcs1pad_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf, ctx->key_size - 1 - req->src_len, req->src); akcipher_request_set_tfm(&req_ctx->child_req, ctx->child); akcipher_request_set_callback(&req_ctx->child_req, req->base.flags, pkcs1pad_encrypt_sign_complete_cb, req); /* Reuse output buffer */ akcipher_request_set_crypt(&req_ctx->child_req, req_ctx->in_sg, req->dst, ctx->key_size - 1, req->dst_len); err = crypto_akcipher_sign(&req_ctx->child_req); if (err != -EINPROGRESS && err != -EBUSY) return pkcs1pad_encrypt_sign_complete(req, err); return err; }
static void rsa_priv_f1_unmap(struct device *dev, struct rsa_edesc *edesc, struct akcipher_request *req) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); struct caam_rsa_key *key = &ctx->key; struct rsa_priv_f1_pdb *pdb = &edesc->pdb.priv_f1; dma_unmap_single(dev, pdb->n_dma, key->n_sz, DMA_TO_DEVICE); dma_unmap_single(dev, pdb->d_dma, key->d_sz, DMA_TO_DEVICE); }
static int caam_rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key, unsigned int keylen) { struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); struct rsa_key raw_key = {NULL}; struct caam_rsa_key *rsa_key = &ctx->key; int ret; /* Free the old RSA key if any */ caam_rsa_free_key(rsa_key); ret = rsa_parse_priv_key(&raw_key, key, keylen); if (ret) return ret; /* Copy key in DMA zone */ rsa_key->d = kzalloc(raw_key.d_sz, GFP_DMA | GFP_KERNEL); if (!rsa_key->d) goto err; rsa_key->e = kzalloc(raw_key.e_sz, GFP_DMA | GFP_KERNEL); if (!rsa_key->e) goto err; /* * Skip leading zeros and copy the positive integer to a buffer * allocated in the GFP_DMA | GFP_KERNEL zone. The decryption descriptor * expects a positive integer for the RSA modulus and uses its length as * decryption output length. */ rsa_key->n = caam_read_raw_data(raw_key.n, &raw_key.n_sz); if (!rsa_key->n) goto err; if (caam_rsa_check_key_length(raw_key.n_sz << 3)) { caam_rsa_free_key(rsa_key); return -EINVAL; } rsa_key->d_sz = raw_key.d_sz; rsa_key->e_sz = raw_key.e_sz; rsa_key->n_sz = raw_key.n_sz; memcpy(rsa_key->d, raw_key.d, raw_key.d_sz); memcpy(rsa_key->e, raw_key.e, raw_key.e_sz); caam_rsa_set_priv_key_form(ctx, &raw_key); return 0; err: caam_rsa_free_key(rsa_key); return -ENOMEM; }
static int pkcs1pad_get_max_size(struct crypto_akcipher *tfm) { struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); /* * The maximum destination buffer size for the encrypt/sign operations * will be the same as for RSA, even though it's smaller for * decrypt/verify. */ return ctx->key_size ?: -EINVAL; }
static int pkcs1pad_decrypt_complete(struct akcipher_request *req, int err) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); unsigned int dst_len; unsigned int pos; u8 *out_buf; if (err) goto done; err = -EINVAL; dst_len = req_ctx->child_req.dst_len; if (dst_len < ctx->key_size - 1) goto done; out_buf = req_ctx->out_buf; if (dst_len == ctx->key_size) { if (out_buf[0] != 0x00) /* Decrypted value had no leading 0 byte */ goto done; dst_len--; out_buf++; } if (out_buf[0] != 0x02) goto done; for (pos = 1; pos < dst_len; pos++) if (out_buf[pos] == 0x00) break; if (pos < 9 || pos == dst_len) goto done; pos++; err = 0; if (req->dst_len < dst_len - pos) err = -EOVERFLOW; req->dst_len = dst_len - pos; if (!err) sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst, req->dst_len), out_buf + pos, req->dst_len); done: kzfree(req_ctx->out_buf); return err; }
/* Per session pkc's driver context creation function */ static int caam_rsa_init_tfm(struct crypto_akcipher *tfm) { struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); ctx->dev = caam_jr_alloc(); if (IS_ERR(ctx->dev)) { pr_err("Job Ring Device allocation for transform failed\n"); return PTR_ERR(ctx->dev); } return 0; }
static int qat_rsa_init_tfm(struct crypto_akcipher *tfm) { struct qat_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); struct qat_crypto_instance *inst = qat_crypto_get_instance_node(get_current_node()); if (!inst) return -EINVAL; ctx->key_sz = 0; ctx->inst = inst; return 0; }
static int pkcs1pad_init_tfm(struct crypto_akcipher *tfm) { struct akcipher_instance *inst = akcipher_alg_instance(tfm); struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst); struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); struct crypto_akcipher *child_tfm; child_tfm = crypto_spawn_akcipher(&ictx->spawn); if (IS_ERR(child_tfm)) return PTR_ERR(child_tfm); ctx->child = child_tfm; return 0; }
static int qat_rsa_setkey(struct crypto_akcipher *tfm, const void *key, unsigned int keylen) { struct qat_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); struct device *dev = &GET_DEV(ctx->inst->accel_dev); int ret; /* Free the old key if any */ if (ctx->n) dma_free_coherent(dev, ctx->key_sz, ctx->n, ctx->dma_n); if (ctx->e) dma_free_coherent(dev, ctx->key_sz, ctx->e, ctx->dma_e); if (ctx->d) { memset(ctx->d, '\0', ctx->key_sz); dma_free_coherent(dev, ctx->key_sz, ctx->d, ctx->dma_d); } ctx->n = NULL; ctx->e = NULL; ctx->d = NULL; ret = asn1_ber_decoder(&qat_rsakey_decoder, ctx, key, keylen); if (ret < 0) goto free; if (!ctx->n || !ctx->e) { /* invalid key provided */ ret = -EINVAL; goto free; } return 0; free: if (ctx->d) { memset(ctx->d, '\0', ctx->key_sz); dma_free_coherent(dev, ctx->key_sz, ctx->d, ctx->dma_d); ctx->d = NULL; } if (ctx->e) { dma_free_coherent(dev, ctx->key_sz, ctx->e, ctx->dma_e); ctx->e = NULL; } if (ctx->n) { dma_free_coherent(dev, ctx->key_sz, ctx->n, ctx->dma_n); ctx->n = NULL; ctx->key_sz = 0; } return ret; }
static int rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key, unsigned int keylen) { struct rsa_key *pkey = akcipher_tfm_ctx(tfm); int ret; ret = rsa_parse_priv_key(pkey, key, keylen); if (ret) return ret; if (rsa_check_key_length(mpi_get_size(pkey->n) << 3)) { rsa_free_key(pkey); ret = -EINVAL; } return ret; }
static void rsa_priv_f2_unmap(struct device *dev, struct rsa_edesc *edesc, struct akcipher_request *req) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); struct caam_rsa_key *key = &ctx->key; struct rsa_priv_f2_pdb *pdb = &edesc->pdb.priv_f2; size_t p_sz = key->p_sz; size_t q_sz = key->q_sz; dma_unmap_single(dev, pdb->d_dma, key->d_sz, DMA_TO_DEVICE); dma_unmap_single(dev, pdb->p_dma, p_sz, DMA_TO_DEVICE); dma_unmap_single(dev, pdb->q_dma, q_sz, DMA_TO_DEVICE); dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL); dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_BIDIRECTIONAL); }
static int pkcs1pad_encrypt(struct akcipher_request *req) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); int err; unsigned int i, ps_end; if (!ctx->key_size) return -EINVAL; if (req->src_len > ctx->key_size - 11) return -EOVERFLOW; if (req->dst_len < ctx->key_size) { req->dst_len = ctx->key_size; return -EOVERFLOW; } req_ctx->in_buf = kmalloc(ctx->key_size - 1 - req->src_len, GFP_KERNEL); if (!req_ctx->in_buf) return -ENOMEM; ps_end = ctx->key_size - req->src_len - 2; req_ctx->in_buf[0] = 0x02; for (i = 1; i < ps_end; i++) req_ctx->in_buf[i] = 1 + prandom_u32_max(255); req_ctx->in_buf[ps_end] = 0x00; pkcs1pad_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf, ctx->key_size - 1 - req->src_len, req->src); akcipher_request_set_tfm(&req_ctx->child_req, ctx->child); akcipher_request_set_callback(&req_ctx->child_req, req->base.flags, pkcs1pad_encrypt_sign_complete_cb, req); /* Reuse output buffer */ akcipher_request_set_crypt(&req_ctx->child_req, req_ctx->in_sg, req->dst, ctx->key_size - 1, req->dst_len); err = crypto_akcipher_encrypt(&req_ctx->child_req); if (err != -EINPROGRESS && err != -EBUSY) return pkcs1pad_encrypt_sign_complete(req, err); return err; }
static void qat_rsa_exit_tfm(struct crypto_akcipher *tfm) { struct qat_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); struct device *dev = &GET_DEV(ctx->inst->accel_dev); if (ctx->n) dma_free_coherent(dev, ctx->key_sz, ctx->n, ctx->dma_n); if (ctx->e) dma_free_coherent(dev, ctx->key_sz, ctx->e, ctx->dma_e); if (ctx->d) { memset(ctx->d, '\0', ctx->key_sz); dma_free_coherent(dev, ctx->key_sz, ctx->d, ctx->dma_d); } qat_crypto_put_instance(ctx->inst); ctx->n = NULL; ctx->d = NULL; ctx->d = NULL; }
static int set_rsa_pub_pdb(struct akcipher_request *req, struct rsa_edesc *edesc) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); struct caam_rsa_key *key = &ctx->key; struct device *dev = ctx->dev; struct rsa_pub_pdb *pdb = &edesc->pdb.pub; int sec4_sg_index = 0; pdb->n_dma = dma_map_single(dev, key->n, key->n_sz, DMA_TO_DEVICE); if (dma_mapping_error(dev, pdb->n_dma)) { dev_err(dev, "Unable to map RSA modulus memory\n"); return -ENOMEM; } pdb->e_dma = dma_map_single(dev, key->e, key->e_sz, DMA_TO_DEVICE); if (dma_mapping_error(dev, pdb->e_dma)) { dev_err(dev, "Unable to map RSA public exponent memory\n"); dma_unmap_single(dev, pdb->n_dma, key->n_sz, DMA_TO_DEVICE); return -ENOMEM; } if (edesc->src_nents > 1) { pdb->sgf |= RSA_PDB_SGF_F; pdb->f_dma = edesc->sec4_sg_dma; sec4_sg_index += edesc->src_nents; } else { pdb->f_dma = sg_dma_address(req->src); } if (edesc->dst_nents > 1) { pdb->sgf |= RSA_PDB_SGF_G; pdb->g_dma = edesc->sec4_sg_dma + sec4_sg_index * sizeof(struct sec4_sg_entry); } else { pdb->g_dma = sg_dma_address(req->dst); } pdb->sgf |= (key->e_sz << RSA_PDB_E_SHIFT) | key->n_sz; pdb->f_len = req->src_len; return 0; }
static int pkcs1pad_set_priv_key(struct crypto_akcipher *tfm, const void *key, unsigned int keylen) { struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); int err, size; err = crypto_akcipher_set_priv_key(ctx->child, key, keylen); if (!err) { /* Find out new modulus size from rsa implementation */ size = crypto_akcipher_maxsize(ctx->child); ctx->key_size = size > 0 ? size : 0; if (size <= 0) err = size; } return err; }
static int caam_rsa_enc(struct akcipher_request *req) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); struct caam_rsa_key *key = &ctx->key; struct device *jrdev = ctx->dev; struct rsa_edesc *edesc; int ret; if (unlikely(!key->n || !key->e)) return -EINVAL; if (req->dst_len < key->n_sz) { req->dst_len = key->n_sz; dev_err(jrdev, "Output buffer length less than parameter n\n"); return -EOVERFLOW; } /* Allocate extended descriptor */ edesc = rsa_edesc_alloc(req, DESC_RSA_PUB_LEN); if (IS_ERR(edesc)) return PTR_ERR(edesc); /* Set RSA Encrypt Protocol Data Block */ ret = set_rsa_pub_pdb(req, edesc); if (ret) goto init_fail; /* Initialize Job Descriptor */ init_rsa_pub_desc(edesc->hw_desc, &edesc->pdb.pub); ret = caam_jr_enqueue(jrdev, edesc->hw_desc, rsa_pub_done, req); if (!ret) return -EINPROGRESS; rsa_pub_unmap(jrdev, edesc, req); init_fail: rsa_io_unmap(jrdev, edesc, req); kfree(edesc); return ret; }
static int pkcs1pad_set_priv_key(struct crypto_akcipher *tfm, const void *key, unsigned int keylen) { struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); int err; ctx->key_size = 0; err = crypto_akcipher_set_priv_key(ctx->child, key, keylen); if (err) return err; /* Find out new modulus size from rsa implementation */ err = crypto_akcipher_maxsize(ctx->child); if (err > PAGE_SIZE) return -ENOTSUPP; ctx->key_size = err; return 0; }
/* * The verify operation is here for completeness similar to the verification * defined in RFC2313 section 10.2 except that block type 0 is not accepted, * as in RFC2437. RFC2437 section 9.2 doesn't define any operation to * retrieve the DigestInfo from a signature, instead the user is expected * to call the sign operation to generate the expected signature and compare * signatures instead of the message-digests. */ static int pkcs1pad_verify(struct akcipher_request *req) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); int err; if (!ctx->key_size || req->src_len < ctx->key_size) return -EINVAL; if (ctx->key_size > PAGE_SIZE) return -ENOTSUPP; /* Reuse input buffer, output to a new buffer */ req_ctx->child_req.src = req->src; req_ctx->child_req.src_len = req->src_len; req_ctx->child_req.dst = req_ctx->out_sg; req_ctx->child_req.dst_len = ctx->key_size - 1; req_ctx->out_buf = kmalloc(ctx->key_size - 1, (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? GFP_KERNEL : GFP_ATOMIC); if (!req_ctx->out_buf) return -ENOMEM; pkcs1pad_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf, ctx->key_size - 1, NULL); akcipher_request_set_tfm(&req_ctx->child_req, ctx->child); akcipher_request_set_callback(&req_ctx->child_req, req->base.flags, pkcs1pad_verify_complete_cb, req); err = crypto_akcipher_verify(&req_ctx->child_req); if (err != -EINPROGRESS && (err != -EBUSY || !(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))) return pkcs1pad_verify_complete(req, err); return err; }
static int pkcs1pad_encrypt_sign_complete(struct akcipher_request *req, int err) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); size_t pad_len = ctx->key_size - req_ctx->child_req.dst_len; size_t chunk_len, pad_left; struct sg_mapping_iter miter; if (!err) { if (pad_len) { sg_miter_start(&miter, req->dst, sg_nents_for_len(req->dst, pad_len), SG_MITER_ATOMIC | SG_MITER_TO_SG); pad_left = pad_len; while (pad_left) { sg_miter_next(&miter); chunk_len = min(miter.length, pad_left); memset(miter.addr, 0, chunk_len); pad_left -= chunk_len; } sg_miter_stop(&miter); } sg_pcopy_from_buffer(req->dst, sg_nents_for_len(req->dst, ctx->key_size), req_ctx->out_buf, req_ctx->child_req.dst_len, pad_len); } req->dst_len = ctx->key_size; kfree(req_ctx->in_buf); kzfree(req_ctx->out_buf); return err; }
static int pkcs1pad_encrypt_sign_complete(struct akcipher_request *req, int err) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); unsigned int pad_len; unsigned int len; u8 *out_buf; if (err) goto out; len = req_ctx->child_req.dst_len; pad_len = ctx->key_size - len; /* Four billion to one */ if (likely(!pad_len)) goto out; out_buf = kzalloc(ctx->key_size, GFP_KERNEL); err = -ENOMEM; if (!out_buf) goto out; sg_copy_to_buffer(req->dst, sg_nents_for_len(req->dst, len), out_buf + pad_len, len); sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst, ctx->key_size), out_buf, ctx->key_size); kzfree(out_buf); out: req->dst_len = ctx->key_size; kfree(req_ctx->in_buf); return err; }
static unsigned int caam_rsa_max_size(struct crypto_akcipher *tfm) { struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); return ctx->key.n_sz; }
static int set_rsa_priv_f3_pdb(struct akcipher_request *req, struct rsa_edesc *edesc) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); struct caam_rsa_key *key = &ctx->key; struct device *dev = ctx->dev; struct rsa_priv_f3_pdb *pdb = &edesc->pdb.priv_f3; int sec4_sg_index = 0; size_t p_sz = key->p_sz; size_t q_sz = key->q_sz; pdb->p_dma = dma_map_single(dev, key->p, p_sz, DMA_TO_DEVICE); if (dma_mapping_error(dev, pdb->p_dma)) { dev_err(dev, "Unable to map RSA prime factor p memory\n"); return -ENOMEM; } pdb->q_dma = dma_map_single(dev, key->q, q_sz, DMA_TO_DEVICE); if (dma_mapping_error(dev, pdb->q_dma)) { dev_err(dev, "Unable to map RSA prime factor q memory\n"); goto unmap_p; } pdb->dp_dma = dma_map_single(dev, key->dp, p_sz, DMA_TO_DEVICE); if (dma_mapping_error(dev, pdb->dp_dma)) { dev_err(dev, "Unable to map RSA exponent dp memory\n"); goto unmap_q; } pdb->dq_dma = dma_map_single(dev, key->dq, q_sz, DMA_TO_DEVICE); if (dma_mapping_error(dev, pdb->dq_dma)) { dev_err(dev, "Unable to map RSA exponent dq memory\n"); goto unmap_dp; } pdb->c_dma = dma_map_single(dev, key->qinv, p_sz, DMA_TO_DEVICE); if (dma_mapping_error(dev, pdb->c_dma)) { dev_err(dev, "Unable to map RSA CRT coefficient qinv memory\n"); goto unmap_dq; } pdb->tmp1_dma = dma_map_single(dev, key->tmp1, p_sz, DMA_BIDIRECTIONAL); if (dma_mapping_error(dev, pdb->tmp1_dma)) { dev_err(dev, "Unable to map RSA tmp1 memory\n"); goto unmap_qinv; } pdb->tmp2_dma = dma_map_single(dev, key->tmp2, q_sz, DMA_BIDIRECTIONAL); if (dma_mapping_error(dev, pdb->tmp2_dma)) { dev_err(dev, "Unable to map RSA tmp2 memory\n"); goto unmap_tmp1; } if (edesc->src_nents > 1) { pdb->sgf |= RSA_PRIV_PDB_SGF_G; pdb->g_dma = edesc->sec4_sg_dma; sec4_sg_index += edesc->src_nents; } else { pdb->g_dma = sg_dma_address(req->src); } if (edesc->dst_nents > 1) { pdb->sgf |= RSA_PRIV_PDB_SGF_F; pdb->f_dma = edesc->sec4_sg_dma + sec4_sg_index * sizeof(struct sec4_sg_entry); } else { pdb->f_dma = sg_dma_address(req->dst); } pdb->sgf |= key->n_sz; pdb->p_q_len = (q_sz << RSA_PDB_Q_SHIFT) | p_sz; return 0; unmap_tmp1: dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL); unmap_qinv: dma_unmap_single(dev, pdb->c_dma, p_sz, DMA_TO_DEVICE); unmap_dq: dma_unmap_single(dev, pdb->dq_dma, q_sz, DMA_TO_DEVICE); unmap_dp: dma_unmap_single(dev, pdb->dp_dma, p_sz, DMA_TO_DEVICE); unmap_q: dma_unmap_single(dev, pdb->q_dma, q_sz, DMA_TO_DEVICE); unmap_p: dma_unmap_single(dev, pdb->p_dma, p_sz, DMA_TO_DEVICE); return -ENOMEM; }
static struct rsa_edesc *rsa_edesc_alloc(struct akcipher_request *req, size_t desclen) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); struct device *dev = ctx->dev; struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req); struct rsa_edesc *edesc; gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? GFP_KERNEL : GFP_ATOMIC; int sg_flags = (flags == GFP_ATOMIC) ? SG_MITER_ATOMIC : 0; int sgc; int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes; int src_nents, dst_nents; int lzeros; lzeros = caam_rsa_count_leading_zeros(req->src, req->src_len, sg_flags); if (lzeros < 0) return ERR_PTR(lzeros); req->src_len -= lzeros; req->src = scatterwalk_ffwd(req_ctx->src, req->src, lzeros); src_nents = sg_nents_for_len(req->src, req->src_len); dst_nents = sg_nents_for_len(req->dst, req->dst_len); if (src_nents > 1) sec4_sg_len = src_nents; if (dst_nents > 1) sec4_sg_len += dst_nents; sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry); /* allocate space for base edesc, hw desc commands and link tables */ edesc = kzalloc(sizeof(*edesc) + desclen + sec4_sg_bytes, GFP_DMA | flags); if (!edesc) return ERR_PTR(-ENOMEM); sgc = dma_map_sg(dev, req->src, src_nents, DMA_TO_DEVICE); if (unlikely(!sgc)) { dev_err(dev, "unable to map source\n"); goto src_fail; } sgc = dma_map_sg(dev, req->dst, dst_nents, DMA_FROM_DEVICE); if (unlikely(!sgc)) { dev_err(dev, "unable to map destination\n"); goto dst_fail; } edesc->sec4_sg = (void *)edesc + sizeof(*edesc) + desclen; sec4_sg_index = 0; if (src_nents > 1) { sg_to_sec4_sg_last(req->src, src_nents, edesc->sec4_sg, 0); sec4_sg_index += src_nents; } if (dst_nents > 1) sg_to_sec4_sg_last(req->dst, dst_nents, edesc->sec4_sg + sec4_sg_index, 0); /* Save nents for later use in Job Descriptor */ edesc->src_nents = src_nents; edesc->dst_nents = dst_nents; if (!sec4_sg_bytes) return edesc; edesc->sec4_sg_dma = dma_map_single(dev, edesc->sec4_sg, sec4_sg_bytes, DMA_TO_DEVICE); if (dma_mapping_error(dev, edesc->sec4_sg_dma)) { dev_err(dev, "unable to map S/G table\n"); goto sec4_sg_fail; } edesc->sec4_sg_bytes = sec4_sg_bytes; return edesc; sec4_sg_fail: dma_unmap_sg(dev, req->dst, dst_nents, DMA_FROM_DEVICE); dst_fail: dma_unmap_sg(dev, req->src, src_nents, DMA_TO_DEVICE); src_fail: kfree(edesc); return ERR_PTR(-ENOMEM); }
static int qat_rsa_dec(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->d)) 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_dec_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.dec.d = ctx->dma_d; qat_req->in.dec.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.dec.c, 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.dec.c = dma_map_single(dev, req->src, req->src_len, DMA_TO_DEVICE); } qat_req->in.in_tab[3] = 0; qat_req->out.dec.m = 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.dec.c, sizeof(struct qat_rsa_input_params), DMA_TO_DEVICE); qat_req->phy_out = dma_map_single(dev, &qat_req->out.dec.m, sizeof(struct qat_rsa_output_params), DMA_TO_DEVICE); if (unlikely((!qat_req->src_align && dma_mapping_error(dev, qat_req->in.dec.c)) || dma_mapping_error(dev, qat_req->out.dec.m) || 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.dec.c); else if (!dma_mapping_error(dev, qat_req->in.dec.c)) dma_unmap_single(dev, qat_req->in.dec.c, ctx->key_sz, DMA_TO_DEVICE); if (!dma_mapping_error(dev, qat_req->out.dec.m)) dma_unmap_single(dev, qat_req->out.dec.m, 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; }