2016-07-04 18:12:08 +08:00
|
|
|
/*
|
|
|
|
* caam - Freescale FSL CAAM support for Public Key Cryptography
|
|
|
|
*
|
|
|
|
* Copyright 2016 Freescale Semiconductor, Inc.
|
|
|
|
*
|
|
|
|
* There is no Shared Descriptor for PKC so that the Job Descriptor must carry
|
|
|
|
* all the desired key parameters, input and output pointers.
|
|
|
|
*/
|
|
|
|
#include "compat.h"
|
|
|
|
#include "regs.h"
|
|
|
|
#include "intern.h"
|
|
|
|
#include "jr.h"
|
|
|
|
#include "error.h"
|
|
|
|
#include "desc_constr.h"
|
|
|
|
#include "sg_sw_sec4.h"
|
|
|
|
#include "caampkc.h"
|
|
|
|
|
|
|
|
#define DESC_RSA_PUB_LEN (2 * CAAM_CMD_SZ + sizeof(struct rsa_pub_pdb))
|
|
|
|
#define DESC_RSA_PRIV_F1_LEN (2 * CAAM_CMD_SZ + \
|
|
|
|
sizeof(struct rsa_priv_f1_pdb))
|
crypto: caam - add support for RSA key form 2
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the second RSA private key
representation.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:38 +08:00
|
|
|
#define DESC_RSA_PRIV_F2_LEN (2 * CAAM_CMD_SZ + \
|
|
|
|
sizeof(struct rsa_priv_f2_pdb))
|
crypto: caam - add support for RSA key form 3
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the third RSA private key
representations and extends caampkc to use the fastest key when all
related components are present in the private key.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:39 +08:00
|
|
|
#define DESC_RSA_PRIV_F3_LEN (2 * CAAM_CMD_SZ + \
|
|
|
|
sizeof(struct rsa_priv_f3_pdb))
|
2016-07-04 18:12:08 +08:00
|
|
|
|
|
|
|
static void rsa_io_unmap(struct device *dev, struct rsa_edesc *edesc,
|
|
|
|
struct akcipher_request *req)
|
|
|
|
{
|
|
|
|
dma_unmap_sg(dev, req->dst, edesc->dst_nents, DMA_FROM_DEVICE);
|
|
|
|
dma_unmap_sg(dev, req->src, edesc->src_nents, DMA_TO_DEVICE);
|
|
|
|
|
|
|
|
if (edesc->sec4_sg_bytes)
|
|
|
|
dma_unmap_single(dev, edesc->sec4_sg_dma, edesc->sec4_sg_bytes,
|
|
|
|
DMA_TO_DEVICE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void rsa_pub_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_pub_pdb *pdb = &edesc->pdb.pub;
|
|
|
|
|
|
|
|
dma_unmap_single(dev, pdb->n_dma, key->n_sz, DMA_TO_DEVICE);
|
|
|
|
dma_unmap_single(dev, pdb->e_dma, key->e_sz, DMA_TO_DEVICE);
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
crypto: caam - add support for RSA key form 2
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the second RSA private key
representation.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:38 +08:00
|
|
|
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->p_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_TO_DEVICE);
|
|
|
|
dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_TO_DEVICE);
|
|
|
|
}
|
|
|
|
|
crypto: caam - add support for RSA key form 3
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the third RSA private key
representations and extends caampkc to use the fastest key when all
related components are present in the private key.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:39 +08:00
|
|
|
static void rsa_priv_f3_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_f3_pdb *pdb = &edesc->pdb.priv_f3;
|
|
|
|
size_t p_sz = key->p_sz;
|
|
|
|
size_t q_sz = key->p_sz;
|
|
|
|
|
|
|
|
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->dp_dma, p_sz, DMA_TO_DEVICE);
|
|
|
|
dma_unmap_single(dev, pdb->dq_dma, q_sz, DMA_TO_DEVICE);
|
|
|
|
dma_unmap_single(dev, pdb->c_dma, p_sz, DMA_TO_DEVICE);
|
|
|
|
dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_TO_DEVICE);
|
|
|
|
dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_TO_DEVICE);
|
|
|
|
}
|
|
|
|
|
2016-07-04 18:12:08 +08:00
|
|
|
/* RSA Job Completion handler */
|
|
|
|
static void rsa_pub_done(struct device *dev, u32 *desc, u32 err, void *context)
|
|
|
|
{
|
|
|
|
struct akcipher_request *req = context;
|
|
|
|
struct rsa_edesc *edesc;
|
|
|
|
|
|
|
|
if (err)
|
|
|
|
caam_jr_strstatus(dev, err);
|
|
|
|
|
|
|
|
edesc = container_of(desc, struct rsa_edesc, hw_desc[0]);
|
|
|
|
|
|
|
|
rsa_pub_unmap(dev, edesc, req);
|
|
|
|
rsa_io_unmap(dev, edesc, req);
|
|
|
|
kfree(edesc);
|
|
|
|
|
|
|
|
akcipher_request_complete(req, err);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void rsa_priv_f1_done(struct device *dev, u32 *desc, u32 err,
|
|
|
|
void *context)
|
|
|
|
{
|
|
|
|
struct akcipher_request *req = context;
|
|
|
|
struct rsa_edesc *edesc;
|
|
|
|
|
|
|
|
if (err)
|
|
|
|
caam_jr_strstatus(dev, err);
|
|
|
|
|
|
|
|
edesc = container_of(desc, struct rsa_edesc, hw_desc[0]);
|
|
|
|
|
|
|
|
rsa_priv_f1_unmap(dev, edesc, req);
|
|
|
|
rsa_io_unmap(dev, edesc, req);
|
|
|
|
kfree(edesc);
|
|
|
|
|
|
|
|
akcipher_request_complete(req, err);
|
|
|
|
}
|
|
|
|
|
crypto: caam - add support for RSA key form 2
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the second RSA private key
representation.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:38 +08:00
|
|
|
static void rsa_priv_f2_done(struct device *dev, u32 *desc, u32 err,
|
|
|
|
void *context)
|
|
|
|
{
|
|
|
|
struct akcipher_request *req = context;
|
|
|
|
struct rsa_edesc *edesc;
|
|
|
|
|
|
|
|
if (err)
|
|
|
|
caam_jr_strstatus(dev, err);
|
|
|
|
|
|
|
|
edesc = container_of(desc, struct rsa_edesc, hw_desc[0]);
|
|
|
|
|
|
|
|
rsa_priv_f2_unmap(dev, edesc, req);
|
|
|
|
rsa_io_unmap(dev, edesc, req);
|
|
|
|
kfree(edesc);
|
|
|
|
|
|
|
|
akcipher_request_complete(req, err);
|
|
|
|
}
|
|
|
|
|
crypto: caam - add support for RSA key form 3
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the third RSA private key
representations and extends caampkc to use the fastest key when all
related components are present in the private key.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:39 +08:00
|
|
|
static void rsa_priv_f3_done(struct device *dev, u32 *desc, u32 err,
|
|
|
|
void *context)
|
|
|
|
{
|
|
|
|
struct akcipher_request *req = context;
|
|
|
|
struct rsa_edesc *edesc;
|
|
|
|
|
|
|
|
if (err)
|
|
|
|
caam_jr_strstatus(dev, err);
|
|
|
|
|
|
|
|
edesc = container_of(desc, struct rsa_edesc, hw_desc[0]);
|
|
|
|
|
|
|
|
rsa_priv_f3_unmap(dev, edesc, req);
|
|
|
|
rsa_io_unmap(dev, edesc, req);
|
|
|
|
kfree(edesc);
|
|
|
|
|
|
|
|
akcipher_request_complete(req, err);
|
|
|
|
}
|
|
|
|
|
2016-07-04 18:12:08 +08:00
|
|
|
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 rsa_edesc *edesc;
|
2017-06-19 16:44:46 +08:00
|
|
|
gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
|
|
|
|
GFP_KERNEL : GFP_ATOMIC;
|
2016-07-04 18:12:08 +08:00
|
|
|
int sgc;
|
|
|
|
int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes;
|
|
|
|
int src_nents, dst_nents;
|
|
|
|
|
|
|
|
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 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 set_rsa_priv_f1_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_f1_pdb *pdb = &edesc->pdb.priv_f1;
|
|
|
|
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 modulus memory\n");
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
pdb->d_dma = dma_map_single(dev, key->d, key->d_sz, DMA_TO_DEVICE);
|
|
|
|
if (dma_mapping_error(dev, pdb->d_dma)) {
|
|
|
|
dev_err(dev, "Unable to map RSA private 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_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->d_sz << RSA_PDB_D_SHIFT) | key->n_sz;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
crypto: caam - add support for RSA key form 2
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the second RSA private key
representation.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:38 +08:00
|
|
|
static int set_rsa_priv_f2_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_f2_pdb *pdb = &edesc->pdb.priv_f2;
|
|
|
|
int sec4_sg_index = 0;
|
|
|
|
size_t p_sz = key->p_sz;
|
|
|
|
size_t q_sz = key->p_sz;
|
|
|
|
|
|
|
|
pdb->d_dma = dma_map_single(dev, key->d, key->d_sz, DMA_TO_DEVICE);
|
|
|
|
if (dma_mapping_error(dev, pdb->d_dma)) {
|
|
|
|
dev_err(dev, "Unable to map RSA private exponent memory\n");
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
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");
|
|
|
|
goto unmap_d;
|
|
|
|
}
|
|
|
|
|
|
|
|
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->tmp1_dma = dma_map_single(dev, key->tmp1, p_sz, DMA_TO_DEVICE);
|
|
|
|
if (dma_mapping_error(dev, pdb->tmp1_dma)) {
|
|
|
|
dev_err(dev, "Unable to map RSA tmp1 memory\n");
|
|
|
|
goto unmap_q;
|
|
|
|
}
|
|
|
|
|
|
|
|
pdb->tmp2_dma = dma_map_single(dev, key->tmp2, q_sz, DMA_TO_DEVICE);
|
|
|
|
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->d_sz << RSA_PDB_D_SHIFT) | 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_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);
|
|
|
|
unmap_d:
|
|
|
|
dma_unmap_single(dev, pdb->d_dma, key->d_sz, DMA_TO_DEVICE);
|
|
|
|
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
crypto: caam - add support for RSA key form 3
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the third RSA private key
representations and extends caampkc to use the fastest key when all
related components are present in the private key.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:39 +08:00
|
|
|
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->p_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_TO_DEVICE);
|
|
|
|
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_TO_DEVICE);
|
|
|
|
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_TO_DEVICE);
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2016-07-04 18:12:08 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
crypto: caam - add support for RSA key form 2
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the second RSA private key
representation.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:38 +08:00
|
|
|
static int caam_rsa_dec_priv_f1(struct akcipher_request *req)
|
2016-07-04 18:12:08 +08:00
|
|
|
{
|
|
|
|
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_F1_LEN);
|
|
|
|
if (IS_ERR(edesc))
|
|
|
|
return PTR_ERR(edesc);
|
|
|
|
|
|
|
|
/* Set RSA Decrypt Protocol Data Block - Private Key Form #1 */
|
|
|
|
ret = set_rsa_priv_f1_pdb(req, edesc);
|
|
|
|
if (ret)
|
|
|
|
goto init_fail;
|
|
|
|
|
|
|
|
/* Initialize Job Descriptor */
|
|
|
|
init_rsa_priv_f1_desc(edesc->hw_desc, &edesc->pdb.priv_f1);
|
|
|
|
|
|
|
|
ret = caam_jr_enqueue(jrdev, edesc->hw_desc, rsa_priv_f1_done, req);
|
|
|
|
if (!ret)
|
|
|
|
return -EINPROGRESS;
|
|
|
|
|
|
|
|
rsa_priv_f1_unmap(jrdev, edesc, req);
|
|
|
|
|
|
|
|
init_fail:
|
|
|
|
rsa_io_unmap(jrdev, edesc, req);
|
|
|
|
kfree(edesc);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
crypto: caam - add support for RSA key form 2
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the second RSA private key
representation.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:38 +08:00
|
|
|
static int caam_rsa_dec_priv_f2(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_F2_LEN);
|
|
|
|
if (IS_ERR(edesc))
|
|
|
|
return PTR_ERR(edesc);
|
|
|
|
|
|
|
|
/* Set RSA Decrypt Protocol Data Block - Private Key Form #2 */
|
|
|
|
ret = set_rsa_priv_f2_pdb(req, edesc);
|
|
|
|
if (ret)
|
|
|
|
goto init_fail;
|
|
|
|
|
|
|
|
/* Initialize Job Descriptor */
|
|
|
|
init_rsa_priv_f2_desc(edesc->hw_desc, &edesc->pdb.priv_f2);
|
|
|
|
|
|
|
|
ret = caam_jr_enqueue(jrdev, edesc->hw_desc, rsa_priv_f2_done, req);
|
|
|
|
if (!ret)
|
|
|
|
return -EINPROGRESS;
|
|
|
|
|
|
|
|
rsa_priv_f2_unmap(jrdev, edesc, req);
|
|
|
|
|
|
|
|
init_fail:
|
|
|
|
rsa_io_unmap(jrdev, edesc, req);
|
|
|
|
kfree(edesc);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
crypto: caam - add support for RSA key form 3
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the third RSA private key
representations and extends caampkc to use the fastest key when all
related components are present in the private key.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:39 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
crypto: caam - add support for RSA key form 2
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the second RSA private key
representation.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:38 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
crypto: caam - add support for RSA key form 3
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the third RSA private key
representations and extends caampkc to use the fastest key when all
related components are present in the private key.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:39 +08:00
|
|
|
if (key->priv_form == FORM3)
|
|
|
|
ret = caam_rsa_dec_priv_f3(req);
|
|
|
|
else if (key->priv_form == FORM2)
|
crypto: caam - add support for RSA key form 2
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the second RSA private key
representation.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:38 +08:00
|
|
|
ret = caam_rsa_dec_priv_f2(req);
|
|
|
|
else
|
|
|
|
ret = caam_rsa_dec_priv_f1(req);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-07-04 18:12:08 +08:00
|
|
|
static void caam_rsa_free_key(struct caam_rsa_key *key)
|
|
|
|
{
|
|
|
|
kzfree(key->d);
|
crypto: caam - add support for RSA key form 2
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the second RSA private key
representation.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:38 +08:00
|
|
|
kzfree(key->p);
|
|
|
|
kzfree(key->q);
|
crypto: caam - add support for RSA key form 3
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the third RSA private key
representations and extends caampkc to use the fastest key when all
related components are present in the private key.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:39 +08:00
|
|
|
kzfree(key->dp);
|
|
|
|
kzfree(key->dq);
|
|
|
|
kzfree(key->qinv);
|
crypto: caam - add support for RSA key form 2
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the second RSA private key
representation.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:38 +08:00
|
|
|
kzfree(key->tmp1);
|
|
|
|
kzfree(key->tmp2);
|
2016-07-04 18:12:08 +08:00
|
|
|
kfree(key->e);
|
|
|
|
kfree(key->n);
|
crypto: caam - add support for RSA key form 2
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the second RSA private key
representation.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:38 +08:00
|
|
|
memset(key, 0, sizeof(*key));
|
2016-07-04 18:12:08 +08:00
|
|
|
}
|
|
|
|
|
2017-04-25 21:26:37 +08:00
|
|
|
static void caam_rsa_drop_leading_zeros(const u8 **ptr, size_t *nbytes)
|
|
|
|
{
|
|
|
|
while (!**ptr && *nbytes) {
|
|
|
|
(*ptr)++;
|
|
|
|
(*nbytes)--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
crypto: caam - add support for RSA key form 3
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the third RSA private key
representations and extends caampkc to use the fastest key when all
related components are present in the private key.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:39 +08:00
|
|
|
/**
|
|
|
|
* caam_read_rsa_crt - Used for reading dP, dQ, qInv CRT members.
|
|
|
|
* dP, dQ and qInv could decode to less than corresponding p, q length, as the
|
|
|
|
* BER-encoding requires that the minimum number of bytes be used to encode the
|
|
|
|
* integer. dP, dQ, qInv decoded values have to be zero-padded to appropriate
|
|
|
|
* length.
|
|
|
|
*
|
|
|
|
* @ptr : pointer to {dP, dQ, qInv} CRT member
|
|
|
|
* @nbytes: length in bytes of {dP, dQ, qInv} CRT member
|
|
|
|
* @dstlen: length in bytes of corresponding p or q prime factor
|
|
|
|
*/
|
|
|
|
static u8 *caam_read_rsa_crt(const u8 *ptr, size_t nbytes, size_t dstlen)
|
|
|
|
{
|
|
|
|
u8 *dst;
|
|
|
|
|
|
|
|
caam_rsa_drop_leading_zeros(&ptr, &nbytes);
|
|
|
|
if (!nbytes)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
dst = kzalloc(dstlen, GFP_DMA | GFP_KERNEL);
|
|
|
|
if (!dst)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
memcpy(dst + (dstlen - nbytes), ptr, nbytes);
|
|
|
|
|
|
|
|
return dst;
|
|
|
|
}
|
|
|
|
|
2016-07-04 18:12:08 +08:00
|
|
|
/**
|
|
|
|
* caam_read_raw_data - Read a raw byte stream as a positive integer.
|
|
|
|
* The function skips buffer's leading zeros, copies the remained data
|
|
|
|
* to a buffer allocated in the GFP_DMA | GFP_KERNEL zone and returns
|
|
|
|
* the address of the new buffer.
|
|
|
|
*
|
|
|
|
* @buf : The data to read
|
|
|
|
* @nbytes: The amount of data to read
|
|
|
|
*/
|
|
|
|
static inline u8 *caam_read_raw_data(const u8 *buf, size_t *nbytes)
|
|
|
|
{
|
|
|
|
u8 *val;
|
|
|
|
|
2017-04-25 21:26:37 +08:00
|
|
|
caam_rsa_drop_leading_zeros(&buf, nbytes);
|
2017-04-25 21:26:36 +08:00
|
|
|
if (!*nbytes)
|
|
|
|
return NULL;
|
2016-07-04 18:12:08 +08:00
|
|
|
|
|
|
|
val = kzalloc(*nbytes, GFP_DMA | GFP_KERNEL);
|
|
|
|
if (!val)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
memcpy(val, buf, *nbytes);
|
|
|
|
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int caam_rsa_check_key_length(unsigned int len)
|
|
|
|
{
|
|
|
|
if (len > 4096)
|
|
|
|
return -EINVAL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int caam_rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key,
|
|
|
|
unsigned int keylen)
|
|
|
|
{
|
|
|
|
struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm);
|
2016-11-09 16:46:14 +08:00
|
|
|
struct rsa_key raw_key = {NULL};
|
2016-07-04 18:12:08 +08:00
|
|
|
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_pub_key(&raw_key, key, keylen);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
/* Copy key in DMA zone */
|
|
|
|
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->e_sz = raw_key.e_sz;
|
|
|
|
rsa_key->n_sz = raw_key.n_sz;
|
|
|
|
|
|
|
|
memcpy(rsa_key->e, raw_key.e, raw_key.e_sz);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
err:
|
|
|
|
caam_rsa_free_key(rsa_key);
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
crypto: caam - add support for RSA key form 2
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the second RSA private key
representation.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:38 +08:00
|
|
|
static void caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx,
|
|
|
|
struct rsa_key *raw_key)
|
|
|
|
{
|
|
|
|
struct caam_rsa_key *rsa_key = &ctx->key;
|
|
|
|
size_t p_sz = raw_key->p_sz;
|
|
|
|
size_t q_sz = raw_key->q_sz;
|
|
|
|
|
|
|
|
rsa_key->p = caam_read_raw_data(raw_key->p, &p_sz);
|
|
|
|
if (!rsa_key->p)
|
|
|
|
return;
|
|
|
|
rsa_key->p_sz = p_sz;
|
|
|
|
|
|
|
|
rsa_key->q = caam_read_raw_data(raw_key->q, &q_sz);
|
|
|
|
if (!rsa_key->q)
|
|
|
|
goto free_p;
|
|
|
|
rsa_key->q_sz = q_sz;
|
|
|
|
|
|
|
|
rsa_key->tmp1 = kzalloc(raw_key->p_sz, GFP_DMA | GFP_KERNEL);
|
|
|
|
if (!rsa_key->tmp1)
|
|
|
|
goto free_q;
|
|
|
|
|
|
|
|
rsa_key->tmp2 = kzalloc(raw_key->q_sz, GFP_DMA | GFP_KERNEL);
|
|
|
|
if (!rsa_key->tmp2)
|
|
|
|
goto free_tmp1;
|
|
|
|
|
|
|
|
rsa_key->priv_form = FORM2;
|
|
|
|
|
crypto: caam - add support for RSA key form 3
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the third RSA private key
representations and extends caampkc to use the fastest key when all
related components are present in the private key.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:39 +08:00
|
|
|
rsa_key->dp = caam_read_rsa_crt(raw_key->dp, raw_key->dp_sz, p_sz);
|
|
|
|
if (!rsa_key->dp)
|
|
|
|
goto free_tmp2;
|
|
|
|
|
|
|
|
rsa_key->dq = caam_read_rsa_crt(raw_key->dq, raw_key->dq_sz, q_sz);
|
|
|
|
if (!rsa_key->dq)
|
|
|
|
goto free_dp;
|
|
|
|
|
|
|
|
rsa_key->qinv = caam_read_rsa_crt(raw_key->qinv, raw_key->qinv_sz,
|
|
|
|
q_sz);
|
|
|
|
if (!rsa_key->qinv)
|
|
|
|
goto free_dq;
|
|
|
|
|
|
|
|
rsa_key->priv_form = FORM3;
|
|
|
|
|
crypto: caam - add support for RSA key form 2
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the second RSA private key
representation.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:38 +08:00
|
|
|
return;
|
|
|
|
|
crypto: caam - add support for RSA key form 3
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the third RSA private key
representations and extends caampkc to use the fastest key when all
related components are present in the private key.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:39 +08:00
|
|
|
free_dq:
|
|
|
|
kzfree(rsa_key->dq);
|
|
|
|
free_dp:
|
|
|
|
kzfree(rsa_key->dp);
|
|
|
|
free_tmp2:
|
|
|
|
kzfree(rsa_key->tmp2);
|
crypto: caam - add support for RSA key form 2
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the second RSA private key
representation.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:38 +08:00
|
|
|
free_tmp1:
|
|
|
|
kzfree(rsa_key->tmp1);
|
|
|
|
free_q:
|
|
|
|
kzfree(rsa_key->q);
|
|
|
|
free_p:
|
|
|
|
kzfree(rsa_key->p);
|
|
|
|
}
|
|
|
|
|
2016-07-04 18:12:08 +08:00
|
|
|
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);
|
2016-11-09 16:46:14 +08:00
|
|
|
struct rsa_key raw_key = {NULL};
|
2016-07-04 18:12:08 +08:00
|
|
|
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);
|
|
|
|
|
crypto: caam - add support for RSA key form 2
CAAM RSA private key may have either of three representations.
1. The first representation consists of the pair (n, d), where the
components have the following meanings:
n the RSA modulus
d the RSA private exponent
2. The second representation consists of the triplet (p, q, d), where
the
components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
d the RSA private exponent
3. The third representation consists of the quintuple (p, q, dP, dQ,
qInv),
where the components have the following meanings:
p the first prime factor of the RSA modulus n
q the second prime factor of the RSA modulus n
dP the first factors's CRT exponent
dQ the second factors's CRT exponent
qInv the (first) CRT coefficient
The benefit of using the third or the second key form is lower
computational cost for the decryption and signature operations.
This patch adds support for the second RSA private key
representation.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2017-04-25 21:26:38 +08:00
|
|
|
caam_rsa_set_priv_key_form(ctx, &raw_key);
|
|
|
|
|
2016-07-04 18:12:08 +08:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
err:
|
|
|
|
caam_rsa_free_key(rsa_key);
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
2017-05-25 15:18:14 +08:00
|
|
|
static unsigned int caam_rsa_max_size(struct crypto_akcipher *tfm)
|
2016-07-04 18:12:08 +08:00
|
|
|
{
|
|
|
|
struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm);
|
|
|
|
|
2017-05-25 15:18:14 +08:00
|
|
|
return ctx->key.n_sz;
|
2016-07-04 18:12:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 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)) {
|
2017-04-03 23:30:07 +08:00
|
|
|
pr_err("Job Ring Device allocation for transform failed\n");
|
2016-07-04 18:12:08 +08:00
|
|
|
return PTR_ERR(ctx->dev);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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 struct akcipher_alg caam_rsa = {
|
|
|
|
.encrypt = caam_rsa_enc,
|
|
|
|
.decrypt = caam_rsa_dec,
|
|
|
|
.sign = caam_rsa_dec,
|
|
|
|
.verify = caam_rsa_enc,
|
|
|
|
.set_pub_key = caam_rsa_set_pub_key,
|
|
|
|
.set_priv_key = caam_rsa_set_priv_key,
|
|
|
|
.max_size = caam_rsa_max_size,
|
|
|
|
.init = caam_rsa_init_tfm,
|
|
|
|
.exit = caam_rsa_exit_tfm,
|
|
|
|
.base = {
|
|
|
|
.cra_name = "rsa",
|
|
|
|
.cra_driver_name = "rsa-caam",
|
|
|
|
.cra_priority = 3000,
|
|
|
|
.cra_module = THIS_MODULE,
|
|
|
|
.cra_ctxsize = sizeof(struct caam_rsa_ctx),
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Public Key Cryptography module initialization handler */
|
|
|
|
static int __init caam_pkc_init(void)
|
|
|
|
{
|
|
|
|
struct device_node *dev_node;
|
|
|
|
struct platform_device *pdev;
|
|
|
|
struct device *ctrldev;
|
|
|
|
struct caam_drv_private *priv;
|
|
|
|
u32 cha_inst, pk_inst;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
|
|
|
|
if (!dev_node) {
|
|
|
|
dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
|
|
|
|
if (!dev_node)
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
|
|
|
|
|
|
|
pdev = of_find_device_by_node(dev_node);
|
|
|
|
if (!pdev) {
|
|
|
|
of_node_put(dev_node);
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctrldev = &pdev->dev;
|
|
|
|
priv = dev_get_drvdata(ctrldev);
|
|
|
|
of_node_put(dev_node);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If priv is NULL, it's probably because the caam driver wasn't
|
|
|
|
* properly initialized (e.g. RNG4 init failed). Thus, bail out here.
|
|
|
|
*/
|
|
|
|
if (!priv)
|
|
|
|
return -ENODEV;
|
|
|
|
|
|
|
|
/* Determine public key hardware accelerator presence. */
|
|
|
|
cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
|
|
|
|
pk_inst = (cha_inst & CHA_ID_LS_PK_MASK) >> CHA_ID_LS_PK_SHIFT;
|
|
|
|
|
|
|
|
/* Do not register algorithms if PKHA is not present. */
|
|
|
|
if (!pk_inst)
|
|
|
|
return -ENODEV;
|
|
|
|
|
|
|
|
err = crypto_register_akcipher(&caam_rsa);
|
|
|
|
if (err)
|
|
|
|
dev_warn(ctrldev, "%s alg registration failed\n",
|
|
|
|
caam_rsa.base.cra_driver_name);
|
|
|
|
else
|
|
|
|
dev_info(ctrldev, "caam pkc algorithms registered in /proc/crypto\n");
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void __exit caam_pkc_exit(void)
|
|
|
|
{
|
|
|
|
crypto_unregister_akcipher(&caam_rsa);
|
|
|
|
}
|
|
|
|
|
|
|
|
module_init(caam_pkc_init);
|
|
|
|
module_exit(caam_pkc_exit);
|
|
|
|
|
|
|
|
MODULE_LICENSE("Dual BSD/GPL");
|
|
|
|
MODULE_DESCRIPTION("FSL CAAM support for PKC functions of crypto API");
|
|
|
|
MODULE_AUTHOR("Freescale Semiconductor");
|