forked from Minki/linux
crypto: akcipher - Changes to asymmetric key API
Setkey function has been split into set_priv_key and set_pub_key. Akcipher requests takes sgl for src and dst instead of void *. Users of the API i.e. two existing RSA implementation and test mgr code have been updated accordingly. Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
2d4d1eea54
commit
22287b0b59
@ -31,10 +31,13 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
|
|||||||
obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
|
obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
|
||||||
obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
|
obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
|
||||||
|
|
||||||
$(obj)/rsakey-asn1.o: $(obj)/rsakey-asn1.c $(obj)/rsakey-asn1.h
|
$(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
|
||||||
clean-files += rsakey-asn1.c rsakey-asn1.h
|
$(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
|
||||||
|
clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
|
||||||
|
clean-files += rsaprivkey-asn1.c rsaprivkey-asn1.h
|
||||||
|
|
||||||
rsa_generic-y := rsakey-asn1.o
|
rsa_generic-y := rsapubkey-asn1.o
|
||||||
|
rsa_generic-y += rsaprivkey-asn1.o
|
||||||
rsa_generic-y += rsa.o
|
rsa_generic-y += rsa.o
|
||||||
rsa_generic-y += rsa_helper.o
|
rsa_generic-y += rsa_helper.o
|
||||||
obj-$(CONFIG_CRYPTO_RSA) += rsa_generic.o
|
obj-$(CONFIG_CRYPTO_RSA) += rsa_generic.o
|
||||||
|
83
crypto/rsa.c
83
crypto/rsa.c
@ -97,24 +97,21 @@ static int rsa_enc(struct akcipher_request *req)
|
|||||||
goto err_free_c;
|
goto err_free_c;
|
||||||
}
|
}
|
||||||
|
|
||||||
m = mpi_read_raw_data(req->src, req->src_len);
|
ret = -ENOMEM;
|
||||||
if (!m) {
|
m = mpi_read_raw_from_sgl(req->src, req->src_len);
|
||||||
ret = -ENOMEM;
|
if (!m)
|
||||||
goto err_free_c;
|
goto err_free_c;
|
||||||
}
|
|
||||||
|
|
||||||
ret = _rsa_enc(pkey, c, m);
|
ret = _rsa_enc(pkey, c, m);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free_m;
|
goto err_free_m;
|
||||||
|
|
||||||
ret = mpi_read_buffer(c, req->dst, req->dst_len, &req->dst_len, &sign);
|
ret = mpi_write_to_sgl(c, req->dst, &req->dst_len, &sign);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free_m;
|
goto err_free_m;
|
||||||
|
|
||||||
if (sign < 0) {
|
if (sign < 0)
|
||||||
ret = -EBADMSG;
|
ret = -EBADMSG;
|
||||||
goto err_free_m;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_free_m:
|
err_free_m:
|
||||||
mpi_free(m);
|
mpi_free(m);
|
||||||
@ -145,25 +142,21 @@ static int rsa_dec(struct akcipher_request *req)
|
|||||||
goto err_free_m;
|
goto err_free_m;
|
||||||
}
|
}
|
||||||
|
|
||||||
c = mpi_read_raw_data(req->src, req->src_len);
|
ret = -ENOMEM;
|
||||||
if (!c) {
|
c = mpi_read_raw_from_sgl(req->src, req->src_len);
|
||||||
ret = -ENOMEM;
|
if (!c)
|
||||||
goto err_free_m;
|
goto err_free_m;
|
||||||
}
|
|
||||||
|
|
||||||
ret = _rsa_dec(pkey, m, c);
|
ret = _rsa_dec(pkey, m, c);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free_c;
|
goto err_free_c;
|
||||||
|
|
||||||
ret = mpi_read_buffer(m, req->dst, req->dst_len, &req->dst_len, &sign);
|
ret = mpi_write_to_sgl(m, req->dst, &req->dst_len, &sign);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free_c;
|
goto err_free_c;
|
||||||
|
|
||||||
if (sign < 0) {
|
if (sign < 0)
|
||||||
ret = -EBADMSG;
|
ret = -EBADMSG;
|
||||||
goto err_free_c;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_free_c:
|
err_free_c:
|
||||||
mpi_free(c);
|
mpi_free(c);
|
||||||
err_free_m:
|
err_free_m:
|
||||||
@ -193,24 +186,21 @@ static int rsa_sign(struct akcipher_request *req)
|
|||||||
goto err_free_s;
|
goto err_free_s;
|
||||||
}
|
}
|
||||||
|
|
||||||
m = mpi_read_raw_data(req->src, req->src_len);
|
ret = -ENOMEM;
|
||||||
if (!m) {
|
m = mpi_read_raw_from_sgl(req->src, req->src_len);
|
||||||
ret = -ENOMEM;
|
if (!m)
|
||||||
goto err_free_s;
|
goto err_free_s;
|
||||||
}
|
|
||||||
|
|
||||||
ret = _rsa_sign(pkey, s, m);
|
ret = _rsa_sign(pkey, s, m);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free_m;
|
goto err_free_m;
|
||||||
|
|
||||||
ret = mpi_read_buffer(s, req->dst, req->dst_len, &req->dst_len, &sign);
|
ret = mpi_write_to_sgl(s, req->dst, &req->dst_len, &sign);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free_m;
|
goto err_free_m;
|
||||||
|
|
||||||
if (sign < 0) {
|
if (sign < 0)
|
||||||
ret = -EBADMSG;
|
ret = -EBADMSG;
|
||||||
goto err_free_m;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_free_m:
|
err_free_m:
|
||||||
mpi_free(m);
|
mpi_free(m);
|
||||||
@ -241,7 +231,8 @@ static int rsa_verify(struct akcipher_request *req)
|
|||||||
goto err_free_m;
|
goto err_free_m;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = mpi_read_raw_data(req->src, req->src_len);
|
ret = -ENOMEM;
|
||||||
|
s = mpi_read_raw_from_sgl(req->src, req->src_len);
|
||||||
if (!s) {
|
if (!s) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto err_free_m;
|
goto err_free_m;
|
||||||
@ -251,14 +242,12 @@ static int rsa_verify(struct akcipher_request *req)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto err_free_s;
|
goto err_free_s;
|
||||||
|
|
||||||
ret = mpi_read_buffer(m, req->dst, req->dst_len, &req->dst_len, &sign);
|
ret = mpi_write_to_sgl(m, req->dst, &req->dst_len, &sign);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free_s;
|
goto err_free_s;
|
||||||
|
|
||||||
if (sign < 0) {
|
if (sign < 0)
|
||||||
ret = -EBADMSG;
|
ret = -EBADMSG;
|
||||||
goto err_free_s;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_free_s:
|
err_free_s:
|
||||||
mpi_free(s);
|
mpi_free(s);
|
||||||
@ -282,13 +271,13 @@ static int rsa_check_key_length(unsigned int len)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rsa_setkey(struct crypto_akcipher *tfm, const void *key,
|
static int rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key,
|
||||||
unsigned int keylen)
|
unsigned int keylen)
|
||||||
{
|
{
|
||||||
struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
|
struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = rsa_parse_key(pkey, key, keylen);
|
ret = rsa_parse_pub_key(pkey, key, keylen);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -299,6 +288,30 @@ static int rsa_setkey(struct crypto_akcipher *tfm, const void *key,
|
|||||||
return ret;
|
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 int rsa_max_size(struct crypto_akcipher *tfm)
|
||||||
|
{
|
||||||
|
struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
|
||||||
|
|
||||||
|
return pkey->n ? mpi_get_size(pkey->n) : -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
static void rsa_exit_tfm(struct crypto_akcipher *tfm)
|
static void rsa_exit_tfm(struct crypto_akcipher *tfm)
|
||||||
{
|
{
|
||||||
struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
|
struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
|
||||||
@ -311,7 +324,9 @@ static struct akcipher_alg rsa = {
|
|||||||
.decrypt = rsa_dec,
|
.decrypt = rsa_dec,
|
||||||
.sign = rsa_sign,
|
.sign = rsa_sign,
|
||||||
.verify = rsa_verify,
|
.verify = rsa_verify,
|
||||||
.setkey = rsa_setkey,
|
.set_priv_key = rsa_set_priv_key,
|
||||||
|
.set_pub_key = rsa_set_pub_key,
|
||||||
|
.max_size = rsa_max_size,
|
||||||
.exit = rsa_exit_tfm,
|
.exit = rsa_exit_tfm,
|
||||||
.base = {
|
.base = {
|
||||||
.cra_name = "rsa",
|
.cra_name = "rsa",
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/fips.h>
|
#include <linux/fips.h>
|
||||||
#include <crypto/internal/rsa.h>
|
#include <crypto/internal/rsa.h>
|
||||||
#include "rsakey-asn1.h"
|
#include "rsapubkey-asn1.h"
|
||||||
|
#include "rsaprivkey-asn1.h"
|
||||||
|
|
||||||
int rsa_get_n(void *context, size_t hdrlen, unsigned char tag,
|
int rsa_get_n(void *context, size_t hdrlen, unsigned char tag,
|
||||||
const void *value, size_t vlen)
|
const void *value, size_t vlen)
|
||||||
@ -94,8 +95,8 @@ void rsa_free_key(struct rsa_key *key)
|
|||||||
EXPORT_SYMBOL_GPL(rsa_free_key);
|
EXPORT_SYMBOL_GPL(rsa_free_key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rsa_parse_key() - extracts an rsa key from BER encoded buffer
|
* rsa_parse_pub_key() - extracts an rsa public key from BER encoded buffer
|
||||||
* and stores it in the provided struct rsa_key
|
* and stores it in the provided struct rsa_key
|
||||||
*
|
*
|
||||||
* @rsa_key: struct rsa_key key representation
|
* @rsa_key: struct rsa_key key representation
|
||||||
* @key: key in BER format
|
* @key: key in BER format
|
||||||
@ -103,13 +104,13 @@ EXPORT_SYMBOL_GPL(rsa_free_key);
|
|||||||
*
|
*
|
||||||
* Return: 0 on success or error code in case of error
|
* Return: 0 on success or error code in case of error
|
||||||
*/
|
*/
|
||||||
int rsa_parse_key(struct rsa_key *rsa_key, const void *key,
|
int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
|
||||||
unsigned int key_len)
|
unsigned int key_len)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
free_mpis(rsa_key);
|
free_mpis(rsa_key);
|
||||||
ret = asn1_ber_decoder(&rsakey_decoder, rsa_key, key, key_len);
|
ret = asn1_ber_decoder(&rsapubkey_decoder, rsa_key, key, key_len);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@ -118,4 +119,31 @@ error:
|
|||||||
free_mpis(rsa_key);
|
free_mpis(rsa_key);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rsa_parse_key);
|
EXPORT_SYMBOL_GPL(rsa_parse_pub_key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rsa_parse_pub_key() - extracts an rsa private key from BER encoded buffer
|
||||||
|
* and stores it in the provided struct rsa_key
|
||||||
|
*
|
||||||
|
* @rsa_key: struct rsa_key key representation
|
||||||
|
* @key: key in BER format
|
||||||
|
* @key_len: length of key
|
||||||
|
*
|
||||||
|
* Return: 0 on success or error code in case of error
|
||||||
|
*/
|
||||||
|
int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key,
|
||||||
|
unsigned int key_len)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
free_mpis(rsa_key);
|
||||||
|
ret = asn1_ber_decoder(&rsaprivkey_decoder, rsa_key, key, key_len);
|
||||||
|
if (ret < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
free_mpis(rsa_key);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(rsa_parse_priv_key);
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
RsaKey ::= SEQUENCE {
|
|
||||||
n INTEGER ({ rsa_get_n }),
|
|
||||||
e INTEGER ({ rsa_get_e }),
|
|
||||||
d INTEGER ({ rsa_get_d })
|
|
||||||
}
|
|
11
crypto/rsaprivkey.asn1
Normal file
11
crypto/rsaprivkey.asn1
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
RsaPrivKey ::= SEQUENCE {
|
||||||
|
version INTEGER,
|
||||||
|
n INTEGER ({ rsa_get_n }),
|
||||||
|
e INTEGER ({ rsa_get_e }),
|
||||||
|
d INTEGER ({ rsa_get_d }),
|
||||||
|
prime1 INTEGER,
|
||||||
|
prime2 INTEGER,
|
||||||
|
exponent1 INTEGER,
|
||||||
|
exponent2 INTEGER,
|
||||||
|
coefficient INTEGER
|
||||||
|
}
|
4
crypto/rsapubkey.asn1
Normal file
4
crypto/rsapubkey.asn1
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
RsaPubKey ::= SEQUENCE {
|
||||||
|
n INTEGER ({ rsa_get_n }),
|
||||||
|
e INTEGER ({ rsa_get_e })
|
||||||
|
}
|
@ -1845,34 +1845,34 @@ static int do_test_rsa(struct crypto_akcipher *tfm,
|
|||||||
struct tcrypt_result result;
|
struct tcrypt_result result;
|
||||||
unsigned int out_len_max, out_len = 0;
|
unsigned int out_len_max, out_len = 0;
|
||||||
int err = -ENOMEM;
|
int err = -ENOMEM;
|
||||||
|
struct scatterlist src, dst, src_tab[2];
|
||||||
|
|
||||||
req = akcipher_request_alloc(tfm, GFP_KERNEL);
|
req = akcipher_request_alloc(tfm, GFP_KERNEL);
|
||||||
if (!req)
|
if (!req)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
init_completion(&result.completion);
|
init_completion(&result.completion);
|
||||||
err = crypto_akcipher_setkey(tfm, vecs->key, vecs->key_len);
|
|
||||||
|
if (vecs->public_key_vec)
|
||||||
|
err = crypto_akcipher_set_pub_key(tfm, vecs->key,
|
||||||
|
vecs->key_len);
|
||||||
|
else
|
||||||
|
err = crypto_akcipher_set_priv_key(tfm, vecs->key,
|
||||||
|
vecs->key_len);
|
||||||
if (err)
|
if (err)
|
||||||
goto free_req;
|
goto free_req;
|
||||||
|
|
||||||
akcipher_request_set_crypt(req, vecs->m, outbuf_enc, vecs->m_size,
|
out_len_max = crypto_akcipher_maxsize(tfm);
|
||||||
out_len);
|
|
||||||
/* expect this to fail, and update the required buf len */
|
|
||||||
crypto_akcipher_encrypt(req);
|
|
||||||
out_len = req->dst_len;
|
|
||||||
if (!out_len) {
|
|
||||||
err = -EINVAL;
|
|
||||||
goto free_req;
|
|
||||||
}
|
|
||||||
|
|
||||||
out_len_max = out_len;
|
|
||||||
err = -ENOMEM;
|
|
||||||
outbuf_enc = kzalloc(out_len_max, GFP_KERNEL);
|
outbuf_enc = kzalloc(out_len_max, GFP_KERNEL);
|
||||||
if (!outbuf_enc)
|
if (!outbuf_enc)
|
||||||
goto free_req;
|
goto free_req;
|
||||||
|
|
||||||
akcipher_request_set_crypt(req, vecs->m, outbuf_enc, vecs->m_size,
|
sg_init_table(src_tab, 2);
|
||||||
out_len);
|
sg_set_buf(&src_tab[0], vecs->m, 8);
|
||||||
|
sg_set_buf(&src_tab[1], vecs->m + 8, vecs->m_size - 8);
|
||||||
|
sg_init_one(&dst, outbuf_enc, out_len_max);
|
||||||
|
akcipher_request_set_crypt(req, src_tab, &dst, vecs->m_size,
|
||||||
|
out_len_max);
|
||||||
akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||||
tcrypt_complete, &result);
|
tcrypt_complete, &result);
|
||||||
|
|
||||||
@ -1882,13 +1882,13 @@ static int do_test_rsa(struct crypto_akcipher *tfm,
|
|||||||
pr_err("alg: rsa: encrypt test failed. err %d\n", err);
|
pr_err("alg: rsa: encrypt test failed. err %d\n", err);
|
||||||
goto free_all;
|
goto free_all;
|
||||||
}
|
}
|
||||||
if (out_len != vecs->c_size) {
|
if (req->dst_len != vecs->c_size) {
|
||||||
pr_err("alg: rsa: encrypt test failed. Invalid output len\n");
|
pr_err("alg: rsa: encrypt test failed. Invalid output len\n");
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto free_all;
|
goto free_all;
|
||||||
}
|
}
|
||||||
/* verify that encrypted message is equal to expected */
|
/* verify that encrypted message is equal to expected */
|
||||||
if (memcmp(vecs->c, outbuf_enc, vecs->c_size)) {
|
if (memcmp(vecs->c, sg_virt(req->dst), vecs->c_size)) {
|
||||||
pr_err("alg: rsa: encrypt test failed. Invalid output\n");
|
pr_err("alg: rsa: encrypt test failed. Invalid output\n");
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto free_all;
|
goto free_all;
|
||||||
@ -1903,9 +1903,10 @@ static int do_test_rsa(struct crypto_akcipher *tfm,
|
|||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto free_all;
|
goto free_all;
|
||||||
}
|
}
|
||||||
|
sg_init_one(&src, vecs->c, vecs->c_size);
|
||||||
|
sg_init_one(&dst, outbuf_dec, out_len_max);
|
||||||
init_completion(&result.completion);
|
init_completion(&result.completion);
|
||||||
akcipher_request_set_crypt(req, outbuf_enc, outbuf_dec, vecs->c_size,
|
akcipher_request_set_crypt(req, &src, &dst, vecs->c_size, out_len_max);
|
||||||
out_len);
|
|
||||||
|
|
||||||
/* Run RSA decrypt - m = c^d mod n;*/
|
/* Run RSA decrypt - m = c^d mod n;*/
|
||||||
err = wait_async_op(&result, crypto_akcipher_decrypt(req));
|
err = wait_async_op(&result, crypto_akcipher_decrypt(req));
|
||||||
|
@ -149,7 +149,8 @@ static struct akcipher_testvec rsa_tv_template[] = {
|
|||||||
{
|
{
|
||||||
#ifndef CONFIG_CRYPTO_FIPS
|
#ifndef CONFIG_CRYPTO_FIPS
|
||||||
.key =
|
.key =
|
||||||
"\x30\x81\x88" /* sequence of 136 bytes */
|
"\x30\x81\x9A" /* sequence of 154 bytes */
|
||||||
|
"\x02\x01\x01" /* version - integer of 1 byte */
|
||||||
"\x02\x41" /* modulus - integer of 65 bytes */
|
"\x02\x41" /* modulus - integer of 65 bytes */
|
||||||
"\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F"
|
"\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F"
|
||||||
"\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5"
|
"\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5"
|
||||||
@ -161,19 +162,25 @@ static struct akcipher_testvec rsa_tv_template[] = {
|
|||||||
"\x0A\x03\x37\x48\x62\x64\x87\x69\x5F\x5F\x30\xBC\x38\xB9\x8B\x44"
|
"\x0A\x03\x37\x48\x62\x64\x87\x69\x5F\x5F\x30\xBC\x38\xB9\x8B\x44"
|
||||||
"\xC2\xCD\x2D\xFF\x43\x40\x98\xCD\x20\xD8\xA1\x38\xD0\x90\xBF\x64"
|
"\xC2\xCD\x2D\xFF\x43\x40\x98\xCD\x20\xD8\xA1\x38\xD0\x90\xBF\x64"
|
||||||
"\x79\x7C\x3F\xA7\xA2\xCD\xCB\x3C\xD1\xE0\xBD\xBA\x26\x54\xB4\xF9"
|
"\x79\x7C\x3F\xA7\xA2\xCD\xCB\x3C\xD1\xE0\xBD\xBA\x26\x54\xB4\xF9"
|
||||||
"\xDF\x8E\x8A\xE5\x9D\x73\x3D\x9F\x33\xB3\x01\x62\x4A\xFD\x1D\x51",
|
"\xDF\x8E\x8A\xE5\x9D\x73\x3D\x9F\x33\xB3\x01\x62\x4A\xFD\x1D\x51"
|
||||||
|
"\x02\x01\x00" /* prime1 - integer of 1 byte */
|
||||||
|
"\x02\x01\x00" /* prime2 - integer of 1 byte */
|
||||||
|
"\x02\x01\x00" /* exponent1 - integer of 1 byte */
|
||||||
|
"\x02\x01\x00" /* exponent2 - integer of 1 byte */
|
||||||
|
"\x02\x01\x00", /* coefficient - integer of 1 byte */
|
||||||
.m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a",
|
.m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a",
|
||||||
.c =
|
.c =
|
||||||
"\x63\x1c\xcd\x7b\xe1\x7e\xe4\xde\xc9\xa8\x89\xa1\x74\xcb\x3c\x63"
|
"\x63\x1c\xcd\x7b\xe1\x7e\xe4\xde\xc9\xa8\x89\xa1\x74\xcb\x3c\x63"
|
||||||
"\x7d\x24\xec\x83\xc3\x15\xe4\x7f\x73\x05\x34\xd1\xec\x22\xbb\x8a"
|
"\x7d\x24\xec\x83\xc3\x15\xe4\x7f\x73\x05\x34\xd1\xec\x22\xbb\x8a"
|
||||||
"\x5e\x32\x39\x6d\xc1\x1d\x7d\x50\x3b\x9f\x7a\xad\xf0\x2e\x25\x53"
|
"\x5e\x32\x39\x6d\xc1\x1d\x7d\x50\x3b\x9f\x7a\xad\xf0\x2e\x25\x53"
|
||||||
"\x9f\x6e\xbd\x4c\x55\x84\x0c\x9b\xcf\x1a\x4b\x51\x1e\x9e\x0c\x06",
|
"\x9f\x6e\xbd\x4c\x55\x84\x0c\x9b\xcf\x1a\x4b\x51\x1e\x9e\x0c\x06",
|
||||||
.key_len = 139,
|
.key_len = 157,
|
||||||
.m_size = 8,
|
.m_size = 8,
|
||||||
.c_size = 64,
|
.c_size = 64,
|
||||||
}, {
|
}, {
|
||||||
.key =
|
.key =
|
||||||
"\x30\x82\x01\x0B" /* sequence of 267 bytes */
|
"\x30\x82\x01\x1D" /* sequence of 285 bytes */
|
||||||
|
"\x02\x01\x01" /* version - integer of 1 byte */
|
||||||
"\x02\x81\x81" /* modulus - integer of 129 bytes */
|
"\x02\x81\x81" /* modulus - integer of 129 bytes */
|
||||||
"\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71"
|
"\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71"
|
||||||
"\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5"
|
"\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5"
|
||||||
@ -194,8 +201,13 @@ static struct akcipher_testvec rsa_tv_template[] = {
|
|||||||
"\x44\xE5\x6A\xAF\x68\xC5\x6C\x09\x2C\xD3\x8D\xC3\xBE\xF5\xD2\x0A"
|
"\x44\xE5\x6A\xAF\x68\xC5\x6C\x09\x2C\xD3\x8D\xC3\xBE\xF5\xD2\x0A"
|
||||||
"\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94"
|
"\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94"
|
||||||
"\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3"
|
"\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3"
|
||||||
"\xC1",
|
"\xC1"
|
||||||
.key_len = 271,
|
"\x02\x01\x00" /* prime1 - integer of 1 byte */
|
||||||
|
"\x02\x01\x00" /* prime2 - integer of 1 byte */
|
||||||
|
"\x02\x01\x00" /* exponent1 - integer of 1 byte */
|
||||||
|
"\x02\x01\x00" /* exponent2 - integer of 1 byte */
|
||||||
|
"\x02\x01\x00", /* coefficient - integer of 1 byte */
|
||||||
|
.key_len = 289,
|
||||||
.m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a",
|
.m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a",
|
||||||
.c =
|
.c =
|
||||||
"\x74\x1b\x55\xac\x47\xb5\x08\x0a\x6e\x2b\x2d\xf7\x94\xb8\x8a\x95"
|
"\x74\x1b\x55\xac\x47\xb5\x08\x0a\x6e\x2b\x2d\xf7\x94\xb8\x8a\x95"
|
||||||
@ -211,7 +223,8 @@ static struct akcipher_testvec rsa_tv_template[] = {
|
|||||||
}, {
|
}, {
|
||||||
#endif
|
#endif
|
||||||
.key =
|
.key =
|
||||||
"\x30\x82\x02\x0D" /* sequence of 525 bytes */
|
"\x30\x82\x02\x1F" /* sequence of 543 bytes */
|
||||||
|
"\x02\x01\x01" /* version - integer of 1 byte */
|
||||||
"\x02\x82\x01\x00" /* modulus - integer of 256 bytes */
|
"\x02\x82\x01\x00" /* modulus - integer of 256 bytes */
|
||||||
"\xDB\x10\x1A\xC2\xA3\xF1\xDC\xFF\x13\x6B\xED\x44\xDF\xF0\x02\x6D"
|
"\xDB\x10\x1A\xC2\xA3\xF1\xDC\xFF\x13\x6B\xED\x44\xDF\xF0\x02\x6D"
|
||||||
"\x13\xC7\x88\xDA\x70\x6B\x54\xF1\xE8\x27\xDC\xC3\x0F\x99\x6A\xFA"
|
"\x13\xC7\x88\xDA\x70\x6B\x54\xF1\xE8\x27\xDC\xC3\x0F\x99\x6A\xFA"
|
||||||
@ -246,8 +259,13 @@ static struct akcipher_testvec rsa_tv_template[] = {
|
|||||||
"\x77\xAF\x51\x27\x5B\x5E\x69\xB8\x81\xE6\x11\xC5\x43\x23\x81\x04"
|
"\x77\xAF\x51\x27\x5B\x5E\x69\xB8\x81\xE6\x11\xC5\x43\x23\x81\x04"
|
||||||
"\x62\xFF\xE9\x46\xB8\xD8\x44\xDB\xA5\xCC\x31\x54\x34\xCE\x3E\x82"
|
"\x62\xFF\xE9\x46\xB8\xD8\x44\xDB\xA5\xCC\x31\x54\x34\xCE\x3E\x82"
|
||||||
"\xD6\xBF\x7A\x0B\x64\x21\x6D\x88\x7E\x5B\x45\x12\x1E\x63\x8D\x49"
|
"\xD6\xBF\x7A\x0B\x64\x21\x6D\x88\x7E\x5B\x45\x12\x1E\x63\x8D\x49"
|
||||||
"\xA7\x1D\xD9\x1E\x06\xCD\xE8\xBA\x2C\x8C\x69\x32\xEA\xBE\x60\x71",
|
"\xA7\x1D\xD9\x1E\x06\xCD\xE8\xBA\x2C\x8C\x69\x32\xEA\xBE\x60\x71"
|
||||||
.key_len = 529,
|
"\x02\x01\x00" /* prime1 - integer of 1 byte */
|
||||||
|
"\x02\x01\x00" /* prime2 - integer of 1 byte */
|
||||||
|
"\x02\x01\x00" /* exponent1 - integer of 1 byte */
|
||||||
|
"\x02\x01\x00" /* exponent2 - integer of 1 byte */
|
||||||
|
"\x02\x01\x00", /* coefficient - integer of 1 byte */
|
||||||
|
.key_len = 547,
|
||||||
.m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a",
|
.m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a",
|
||||||
.c =
|
.c =
|
||||||
"\xb2\x97\x76\xb4\xae\x3e\x38\x3c\x7e\x64\x1f\xcc\xa2\x7f\xf6\xbe"
|
"\xb2\x97\x76\xb4\xae\x3e\x38\x3c\x7e\x64\x1f\xcc\xa2\x7f\xf6\xbe"
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
$(obj)/qat_rsakey-asn1.o: $(obj)/qat_rsakey-asn1.c $(obj)/qat_rsakey-asn1.h
|
$(obj)/qat_rsapubkey-asn1.o: $(obj)/qat_rsapubkey-asn1.c \
|
||||||
clean-files += qat_rsakey-asn1.c qat_rsakey-asn1.h
|
$(obj)/qat_rsapubkey-asn1.h
|
||||||
|
$(obj)/qat_rsaprivkey-asn1.o: $(obj)/qat_rsaprivkey-asn1.c \
|
||||||
|
$(obj)/qat_rsaprivkey-asn1.h
|
||||||
|
|
||||||
|
clean-files += qat_rsapubkey-asn1.c qat_rsapubkey-asn1.h
|
||||||
|
clean-files += qat_rsaprivkey-asn1.c qat_rsapvivkey-asn1.h
|
||||||
|
|
||||||
obj-$(CONFIG_CRYPTO_DEV_QAT) += intel_qat.o
|
obj-$(CONFIG_CRYPTO_DEV_QAT) += intel_qat.o
|
||||||
intel_qat-objs := adf_cfg.o \
|
intel_qat-objs := adf_cfg.o \
|
||||||
@ -13,7 +18,8 @@ intel_qat-objs := adf_cfg.o \
|
|||||||
adf_hw_arbiter.o \
|
adf_hw_arbiter.o \
|
||||||
qat_crypto.o \
|
qat_crypto.o \
|
||||||
qat_algs.o \
|
qat_algs.o \
|
||||||
qat_rsakey-asn1.o \
|
qat_rsapubkey-asn1.o \
|
||||||
|
qat_rsaprivkey-asn1.o \
|
||||||
qat_asym_algs.o \
|
qat_asym_algs.o \
|
||||||
qat_uclo.o \
|
qat_uclo.o \
|
||||||
qat_hal.o
|
qat_hal.o
|
||||||
|
@ -51,7 +51,9 @@
|
|||||||
#include <crypto/akcipher.h>
|
#include <crypto/akcipher.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/fips.h>
|
#include <linux/fips.h>
|
||||||
#include "qat_rsakey-asn1.h"
|
#include <crypto/scatterwalk.h>
|
||||||
|
#include "qat_rsapubkey-asn1.h"
|
||||||
|
#include "qat_rsaprivkey-asn1.h"
|
||||||
#include "icp_qat_fw_pke.h"
|
#include "icp_qat_fw_pke.h"
|
||||||
#include "adf_accel_devices.h"
|
#include "adf_accel_devices.h"
|
||||||
#include "adf_transport.h"
|
#include "adf_transport.h"
|
||||||
@ -106,6 +108,7 @@ struct qat_rsa_request {
|
|||||||
dma_addr_t phy_in;
|
dma_addr_t phy_in;
|
||||||
dma_addr_t phy_out;
|
dma_addr_t phy_out;
|
||||||
char *src_align;
|
char *src_align;
|
||||||
|
char *dst_align;
|
||||||
struct icp_qat_fw_pke_request req;
|
struct icp_qat_fw_pke_request req;
|
||||||
struct qat_rsa_ctx *ctx;
|
struct qat_rsa_ctx *ctx;
|
||||||
int err;
|
int err;
|
||||||
@ -118,7 +121,6 @@ static void qat_rsa_cb(struct icp_qat_fw_pke_resp *resp)
|
|||||||
struct device *dev = &GET_DEV(req->ctx->inst->accel_dev);
|
struct device *dev = &GET_DEV(req->ctx->inst->accel_dev);
|
||||||
int err = ICP_QAT_FW_PKE_RESP_PKE_STAT_GET(
|
int err = ICP_QAT_FW_PKE_RESP_PKE_STAT_GET(
|
||||||
resp->pke_resp_hdr.comn_resp_flags);
|
resp->pke_resp_hdr.comn_resp_flags);
|
||||||
char *ptr = areq->dst;
|
|
||||||
|
|
||||||
err = (err == ICP_QAT_FW_COMN_STATUS_FLAG_OK) ? 0 : -EINVAL;
|
err = (err == ICP_QAT_FW_COMN_STATUS_FLAG_OK) ? 0 : -EINVAL;
|
||||||
|
|
||||||
@ -129,24 +131,44 @@ static void qat_rsa_cb(struct icp_qat_fw_pke_resp *resp)
|
|||||||
dma_unmap_single(dev, req->in.enc.m, req->ctx->key_sz,
|
dma_unmap_single(dev, req->in.enc.m, req->ctx->key_sz,
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
|
|
||||||
dma_unmap_single(dev, req->out.enc.c, req->ctx->key_sz,
|
areq->dst_len = req->ctx->key_sz;
|
||||||
DMA_FROM_DEVICE);
|
if (req->dst_align) {
|
||||||
|
char *ptr = req->dst_align;
|
||||||
|
|
||||||
|
while (!(*ptr) && areq->dst_len) {
|
||||||
|
areq->dst_len--;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (areq->dst_len != req->ctx->key_sz)
|
||||||
|
memmove(req->dst_align, ptr, areq->dst_len);
|
||||||
|
|
||||||
|
scatterwalk_map_and_copy(req->dst_align, areq->dst, 0,
|
||||||
|
areq->dst_len, 1);
|
||||||
|
|
||||||
|
dma_free_coherent(dev, req->ctx->key_sz, req->dst_align,
|
||||||
|
req->out.enc.c);
|
||||||
|
} else {
|
||||||
|
char *ptr = sg_virt(areq->dst);
|
||||||
|
|
||||||
|
while (!(*ptr) && areq->dst_len) {
|
||||||
|
areq->dst_len--;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sg_virt(areq->dst) != ptr && areq->dst_len)
|
||||||
|
memmove(sg_virt(areq->dst), ptr, areq->dst_len);
|
||||||
|
|
||||||
|
dma_unmap_single(dev, req->out.enc.c, req->ctx->key_sz,
|
||||||
|
DMA_FROM_DEVICE);
|
||||||
|
}
|
||||||
|
|
||||||
dma_unmap_single(dev, req->phy_in, sizeof(struct qat_rsa_input_params),
|
dma_unmap_single(dev, req->phy_in, sizeof(struct qat_rsa_input_params),
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
dma_unmap_single(dev, req->phy_out,
|
dma_unmap_single(dev, req->phy_out,
|
||||||
sizeof(struct qat_rsa_output_params),
|
sizeof(struct qat_rsa_output_params),
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
|
|
||||||
areq->dst_len = req->ctx->key_sz;
|
|
||||||
/* Need to set the corect length of the output */
|
|
||||||
while (!(*ptr) && areq->dst_len) {
|
|
||||||
areq->dst_len--;
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (areq->dst_len != req->ctx->key_sz)
|
|
||||||
memmove(areq->dst, ptr, areq->dst_len);
|
|
||||||
|
|
||||||
akcipher_request_complete(areq, err);
|
akcipher_request_complete(areq, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,8 +277,16 @@ static int qat_rsa_enc(struct akcipher_request *req)
|
|||||||
* same as modulo n so in case it is different we need to allocate a
|
* same as modulo n so in case it is different we need to allocate a
|
||||||
* new buf and copy src data.
|
* new buf and copy src data.
|
||||||
* In other case we just need to map the user provided buffer.
|
* In other case we just need to map the user provided buffer.
|
||||||
|
* Also need to make sure that it is in contiguous buffer.
|
||||||
*/
|
*/
|
||||||
if (req->src_len < ctx->key_sz) {
|
if (sg_is_last(req->src) && req->src_len == ctx->key_sz) {
|
||||||
|
qat_req->src_align = NULL;
|
||||||
|
qat_req->in.enc.m = dma_map_single(dev, sg_virt(req->src),
|
||||||
|
req->src_len, DMA_TO_DEVICE);
|
||||||
|
if (unlikely(dma_mapping_error(dev, qat_req->in.enc.m)))
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
} else {
|
||||||
int shift = ctx->key_sz - req->src_len;
|
int shift = ctx->key_sz - req->src_len;
|
||||||
|
|
||||||
qat_req->src_align = dma_zalloc_coherent(dev, ctx->key_sz,
|
qat_req->src_align = dma_zalloc_coherent(dev, ctx->key_sz,
|
||||||
@ -265,29 +295,39 @@ static int qat_rsa_enc(struct akcipher_request *req)
|
|||||||
if (unlikely(!qat_req->src_align))
|
if (unlikely(!qat_req->src_align))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
memcpy(qat_req->src_align + shift, req->src, req->src_len);
|
scatterwalk_map_and_copy(qat_req->src_align + shift, req->src,
|
||||||
|
0, req->src_len, 0);
|
||||||
|
}
|
||||||
|
if (sg_is_last(req->dst) && req->dst_len == ctx->key_sz) {
|
||||||
|
qat_req->dst_align = NULL;
|
||||||
|
qat_req->out.enc.c = dma_map_single(dev, sg_virt(req->dst),
|
||||||
|
req->dst_len,
|
||||||
|
DMA_FROM_DEVICE);
|
||||||
|
|
||||||
|
if (unlikely(dma_mapping_error(dev, qat_req->out.enc.c)))
|
||||||
|
goto unmap_src;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
qat_req->src_align = NULL;
|
qat_req->dst_align = dma_zalloc_coherent(dev, ctx->key_sz,
|
||||||
qat_req->in.enc.m = dma_map_single(dev, req->src, req->src_len,
|
&qat_req->out.enc.c,
|
||||||
DMA_TO_DEVICE);
|
GFP_KERNEL);
|
||||||
|
if (unlikely(!qat_req->dst_align))
|
||||||
|
goto unmap_src;
|
||||||
|
|
||||||
}
|
}
|
||||||
qat_req->in.in_tab[3] = 0;
|
qat_req->in.in_tab[3] = 0;
|
||||||
qat_req->out.enc.c = dma_map_single(dev, req->dst, req->dst_len,
|
|
||||||
DMA_FROM_DEVICE);
|
|
||||||
qat_req->out.out_tab[1] = 0;
|
qat_req->out.out_tab[1] = 0;
|
||||||
qat_req->phy_in = dma_map_single(dev, &qat_req->in.enc.m,
|
qat_req->phy_in = dma_map_single(dev, &qat_req->in.enc.m,
|
||||||
sizeof(struct qat_rsa_input_params),
|
sizeof(struct qat_rsa_input_params),
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
|
if (unlikely(dma_mapping_error(dev, qat_req->phy_in)))
|
||||||
|
goto unmap_dst;
|
||||||
|
|
||||||
qat_req->phy_out = dma_map_single(dev, &qat_req->out.enc.c,
|
qat_req->phy_out = dma_map_single(dev, &qat_req->out.enc.c,
|
||||||
sizeof(struct qat_rsa_output_params),
|
sizeof(struct qat_rsa_output_params),
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
|
if (unlikely(dma_mapping_error(dev, qat_req->phy_out)))
|
||||||
if (unlikely((!qat_req->src_align &&
|
goto unmap_in_params;
|
||||||
dma_mapping_error(dev, qat_req->in.enc.m)) ||
|
|
||||||
dma_mapping_error(dev, qat_req->out.enc.c) ||
|
|
||||||
dma_mapping_error(dev, qat_req->phy_in) ||
|
|
||||||
dma_mapping_error(dev, qat_req->phy_out)))
|
|
||||||
goto unmap;
|
|
||||||
|
|
||||||
msg->pke_mid.src_data_addr = qat_req->phy_in;
|
msg->pke_mid.src_data_addr = qat_req->phy_in;
|
||||||
msg->pke_mid.dest_data_addr = qat_req->phy_out;
|
msg->pke_mid.dest_data_addr = qat_req->phy_out;
|
||||||
@ -300,7 +340,7 @@ static int qat_rsa_enc(struct akcipher_request *req)
|
|||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return -EINPROGRESS;
|
return -EINPROGRESS;
|
||||||
unmap:
|
unmap_src:
|
||||||
if (qat_req->src_align)
|
if (qat_req->src_align)
|
||||||
dma_free_coherent(dev, ctx->key_sz, qat_req->src_align,
|
dma_free_coherent(dev, ctx->key_sz, qat_req->src_align,
|
||||||
qat_req->in.enc.m);
|
qat_req->in.enc.m);
|
||||||
@ -308,9 +348,15 @@ unmap:
|
|||||||
if (!dma_mapping_error(dev, qat_req->in.enc.m))
|
if (!dma_mapping_error(dev, qat_req->in.enc.m))
|
||||||
dma_unmap_single(dev, qat_req->in.enc.m, ctx->key_sz,
|
dma_unmap_single(dev, qat_req->in.enc.m, ctx->key_sz,
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
if (!dma_mapping_error(dev, qat_req->out.enc.c))
|
unmap_dst:
|
||||||
dma_unmap_single(dev, qat_req->out.enc.c, ctx->key_sz,
|
if (qat_req->dst_align)
|
||||||
DMA_FROM_DEVICE);
|
dma_free_coherent(dev, ctx->key_sz, qat_req->dst_align,
|
||||||
|
qat_req->out.enc.c);
|
||||||
|
else
|
||||||
|
if (!dma_mapping_error(dev, qat_req->out.enc.c))
|
||||||
|
dma_unmap_single(dev, qat_req->out.enc.c, ctx->key_sz,
|
||||||
|
DMA_FROM_DEVICE);
|
||||||
|
unmap_in_params:
|
||||||
if (!dma_mapping_error(dev, qat_req->phy_in))
|
if (!dma_mapping_error(dev, qat_req->phy_in))
|
||||||
dma_unmap_single(dev, qat_req->phy_in,
|
dma_unmap_single(dev, qat_req->phy_in,
|
||||||
sizeof(struct qat_rsa_input_params),
|
sizeof(struct qat_rsa_input_params),
|
||||||
@ -362,8 +408,16 @@ static int qat_rsa_dec(struct akcipher_request *req)
|
|||||||
* same as modulo n so in case it is different we need to allocate a
|
* same as modulo n so in case it is different we need to allocate a
|
||||||
* new buf and copy src data.
|
* new buf and copy src data.
|
||||||
* In other case we just need to map the user provided buffer.
|
* In other case we just need to map the user provided buffer.
|
||||||
|
* Also need to make sure that it is in contiguous buffer.
|
||||||
*/
|
*/
|
||||||
if (req->src_len < ctx->key_sz) {
|
if (sg_is_last(req->src) && req->src_len == ctx->key_sz) {
|
||||||
|
qat_req->src_align = NULL;
|
||||||
|
qat_req->in.dec.c = dma_map_single(dev, sg_virt(req->src),
|
||||||
|
req->dst_len, DMA_TO_DEVICE);
|
||||||
|
if (unlikely(dma_mapping_error(dev, qat_req->in.dec.c)))
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
} else {
|
||||||
int shift = ctx->key_sz - req->src_len;
|
int shift = ctx->key_sz - req->src_len;
|
||||||
|
|
||||||
qat_req->src_align = dma_zalloc_coherent(dev, ctx->key_sz,
|
qat_req->src_align = dma_zalloc_coherent(dev, ctx->key_sz,
|
||||||
@ -372,29 +426,40 @@ static int qat_rsa_dec(struct akcipher_request *req)
|
|||||||
if (unlikely(!qat_req->src_align))
|
if (unlikely(!qat_req->src_align))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
memcpy(qat_req->src_align + shift, req->src, req->src_len);
|
scatterwalk_map_and_copy(qat_req->src_align + shift, req->src,
|
||||||
} else {
|
0, req->src_len, 0);
|
||||||
qat_req->src_align = NULL;
|
|
||||||
qat_req->in.dec.c = dma_map_single(dev, req->src, req->src_len,
|
|
||||||
DMA_TO_DEVICE);
|
|
||||||
}
|
}
|
||||||
|
if (sg_is_last(req->dst) && req->dst_len == ctx->key_sz) {
|
||||||
|
qat_req->dst_align = NULL;
|
||||||
|
qat_req->out.dec.m = dma_map_single(dev, sg_virt(req->dst),
|
||||||
|
req->dst_len,
|
||||||
|
DMA_FROM_DEVICE);
|
||||||
|
|
||||||
|
if (unlikely(dma_mapping_error(dev, qat_req->out.dec.m)))
|
||||||
|
goto unmap_src;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
qat_req->dst_align = dma_zalloc_coherent(dev, ctx->key_sz,
|
||||||
|
&qat_req->out.dec.m,
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (unlikely(!qat_req->dst_align))
|
||||||
|
goto unmap_src;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
qat_req->in.in_tab[3] = 0;
|
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->out.out_tab[1] = 0;
|
||||||
qat_req->phy_in = dma_map_single(dev, &qat_req->in.dec.c,
|
qat_req->phy_in = dma_map_single(dev, &qat_req->in.dec.c,
|
||||||
sizeof(struct qat_rsa_input_params),
|
sizeof(struct qat_rsa_input_params),
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
|
if (unlikely(dma_mapping_error(dev, qat_req->phy_in)))
|
||||||
|
goto unmap_dst;
|
||||||
|
|
||||||
qat_req->phy_out = dma_map_single(dev, &qat_req->out.dec.m,
|
qat_req->phy_out = dma_map_single(dev, &qat_req->out.dec.m,
|
||||||
sizeof(struct qat_rsa_output_params),
|
sizeof(struct qat_rsa_output_params),
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
|
if (unlikely(dma_mapping_error(dev, qat_req->phy_out)))
|
||||||
if (unlikely((!qat_req->src_align &&
|
goto unmap_in_params;
|
||||||
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.src_data_addr = qat_req->phy_in;
|
||||||
msg->pke_mid.dest_data_addr = qat_req->phy_out;
|
msg->pke_mid.dest_data_addr = qat_req->phy_out;
|
||||||
@ -407,7 +472,7 @@ static int qat_rsa_dec(struct akcipher_request *req)
|
|||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return -EINPROGRESS;
|
return -EINPROGRESS;
|
||||||
unmap:
|
unmap_src:
|
||||||
if (qat_req->src_align)
|
if (qat_req->src_align)
|
||||||
dma_free_coherent(dev, ctx->key_sz, qat_req->src_align,
|
dma_free_coherent(dev, ctx->key_sz, qat_req->src_align,
|
||||||
qat_req->in.dec.c);
|
qat_req->in.dec.c);
|
||||||
@ -415,9 +480,15 @@ unmap:
|
|||||||
if (!dma_mapping_error(dev, qat_req->in.dec.c))
|
if (!dma_mapping_error(dev, qat_req->in.dec.c))
|
||||||
dma_unmap_single(dev, qat_req->in.dec.c, ctx->key_sz,
|
dma_unmap_single(dev, qat_req->in.dec.c, ctx->key_sz,
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
if (!dma_mapping_error(dev, qat_req->out.dec.m))
|
unmap_dst:
|
||||||
dma_unmap_single(dev, qat_req->out.dec.m, ctx->key_sz,
|
if (qat_req->dst_align)
|
||||||
DMA_FROM_DEVICE);
|
dma_free_coherent(dev, ctx->key_sz, qat_req->dst_align,
|
||||||
|
qat_req->out.dec.m);
|
||||||
|
else
|
||||||
|
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);
|
||||||
|
unmap_in_params:
|
||||||
if (!dma_mapping_error(dev, qat_req->phy_in))
|
if (!dma_mapping_error(dev, qat_req->phy_in))
|
||||||
dma_unmap_single(dev, qat_req->phy_in,
|
dma_unmap_single(dev, qat_req->phy_in,
|
||||||
sizeof(struct qat_rsa_input_params),
|
sizeof(struct qat_rsa_input_params),
|
||||||
@ -531,7 +602,7 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int qat_rsa_setkey(struct crypto_akcipher *tfm, const void *key,
|
static int qat_rsa_setkey(struct crypto_akcipher *tfm, const void *key,
|
||||||
unsigned int keylen)
|
unsigned int keylen, bool private)
|
||||||
{
|
{
|
||||||
struct qat_rsa_ctx *ctx = akcipher_tfm_ctx(tfm);
|
struct qat_rsa_ctx *ctx = akcipher_tfm_ctx(tfm);
|
||||||
struct device *dev = &GET_DEV(ctx->inst->accel_dev);
|
struct device *dev = &GET_DEV(ctx->inst->accel_dev);
|
||||||
@ -550,7 +621,13 @@ static int qat_rsa_setkey(struct crypto_akcipher *tfm, const void *key,
|
|||||||
ctx->n = NULL;
|
ctx->n = NULL;
|
||||||
ctx->e = NULL;
|
ctx->e = NULL;
|
||||||
ctx->d = NULL;
|
ctx->d = NULL;
|
||||||
ret = asn1_ber_decoder(&qat_rsakey_decoder, ctx, key, keylen);
|
|
||||||
|
if (private)
|
||||||
|
ret = asn1_ber_decoder(&qat_rsaprivkey_decoder, ctx, key,
|
||||||
|
keylen);
|
||||||
|
else
|
||||||
|
ret = asn1_ber_decoder(&qat_rsapubkey_decoder, ctx, key,
|
||||||
|
keylen);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto free;
|
goto free;
|
||||||
|
|
||||||
@ -559,6 +636,11 @@ static int qat_rsa_setkey(struct crypto_akcipher *tfm, const void *key,
|
|||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto free;
|
goto free;
|
||||||
}
|
}
|
||||||
|
if (private && !ctx->d) {
|
||||||
|
/* invalid private key provided */
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto free;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
free:
|
free:
|
||||||
@ -579,6 +661,25 @@ free:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int qat_rsa_setpubkey(struct crypto_akcipher *tfm, const void *key,
|
||||||
|
unsigned int keylen)
|
||||||
|
{
|
||||||
|
return qat_rsa_setkey(tfm, key, keylen, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int qat_rsa_setprivkey(struct crypto_akcipher *tfm, const void *key,
|
||||||
|
unsigned int keylen)
|
||||||
|
{
|
||||||
|
return qat_rsa_setkey(tfm, key, keylen, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int qat_rsa_max_size(struct crypto_akcipher *tfm)
|
||||||
|
{
|
||||||
|
struct qat_rsa_ctx *ctx = akcipher_tfm_ctx(tfm);
|
||||||
|
|
||||||
|
return (ctx->n) ? ctx->key_sz : -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
static int qat_rsa_init_tfm(struct crypto_akcipher *tfm)
|
static int qat_rsa_init_tfm(struct crypto_akcipher *tfm)
|
||||||
{
|
{
|
||||||
struct qat_rsa_ctx *ctx = akcipher_tfm_ctx(tfm);
|
struct qat_rsa_ctx *ctx = akcipher_tfm_ctx(tfm);
|
||||||
@ -617,7 +718,9 @@ static struct akcipher_alg rsa = {
|
|||||||
.decrypt = qat_rsa_dec,
|
.decrypt = qat_rsa_dec,
|
||||||
.sign = qat_rsa_dec,
|
.sign = qat_rsa_dec,
|
||||||
.verify = qat_rsa_enc,
|
.verify = qat_rsa_enc,
|
||||||
.setkey = qat_rsa_setkey,
|
.set_pub_key = qat_rsa_setpubkey,
|
||||||
|
.set_priv_key = qat_rsa_setprivkey,
|
||||||
|
.max_size = qat_rsa_max_size,
|
||||||
.init = qat_rsa_init_tfm,
|
.init = qat_rsa_init_tfm,
|
||||||
.exit = qat_rsa_exit_tfm,
|
.exit = qat_rsa_exit_tfm,
|
||||||
.reqsize = sizeof(struct qat_rsa_request) + 64,
|
.reqsize = sizeof(struct qat_rsa_request) + 64,
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
RsaKey ::= SEQUENCE {
|
|
||||||
n INTEGER ({ qat_rsa_get_n }),
|
|
||||||
e INTEGER ({ qat_rsa_get_e }),
|
|
||||||
d INTEGER ({ qat_rsa_get_d })
|
|
||||||
}
|
|
11
drivers/crypto/qat/qat_common/qat_rsaprivkey.asn1
Normal file
11
drivers/crypto/qat/qat_common/qat_rsaprivkey.asn1
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
RsaPrivKey ::= SEQUENCE {
|
||||||
|
version INTEGER,
|
||||||
|
n INTEGER ({ qat_rsa_get_n }),
|
||||||
|
e INTEGER ({ qat_rsa_get_e }),
|
||||||
|
d INTEGER ({ qat_rsa_get_d }),
|
||||||
|
prime1 INTEGER,
|
||||||
|
prime2 INTEGER,
|
||||||
|
exponent1 INTEGER,
|
||||||
|
exponent2 INTEGER,
|
||||||
|
coefficient INTEGER
|
||||||
|
}
|
4
drivers/crypto/qat/qat_common/qat_rsapubkey.asn1
Normal file
4
drivers/crypto/qat/qat_common/qat_rsapubkey.asn1
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
RsaPubKey ::= SEQUENCE {
|
||||||
|
n INTEGER ({ qat_rsa_get_n }),
|
||||||
|
e INTEGER ({ qat_rsa_get_e })
|
||||||
|
}
|
@ -18,21 +18,21 @@
|
|||||||
* struct akcipher_request - public key request
|
* struct akcipher_request - public key request
|
||||||
*
|
*
|
||||||
* @base: Common attributes for async crypto requests
|
* @base: Common attributes for async crypto requests
|
||||||
* @src: Pointer to memory containing the input parameters
|
* @src: Source data
|
||||||
* The format of the parameter(s) is expeted to be Octet String
|
* @dst: Destination data
|
||||||
* @dst: Pointer to memory whare the result will be stored
|
* @src_len: Size of the input buffer
|
||||||
* @src_len: Size of the input parameter
|
|
||||||
* @dst_len: Size of the output buffer. It needs to be at leaset
|
* @dst_len: Size of the output buffer. It needs to be at leaset
|
||||||
* as big as the expected result depending on the operation
|
* as big as the expected result depending on the operation
|
||||||
* After operation it will be updated with the acctual size of the
|
* After operation it will be updated with the acctual size of the
|
||||||
* result. In case of error, where the dst_len was insufficient,
|
* result.
|
||||||
|
* In case of error where the dst sgl size was insufficient,
|
||||||
* it will be updated to the size required for the operation.
|
* it will be updated to the size required for the operation.
|
||||||
* @__ctx: Start of private context data
|
* @__ctx: Start of private context data
|
||||||
*/
|
*/
|
||||||
struct akcipher_request {
|
struct akcipher_request {
|
||||||
struct crypto_async_request base;
|
struct crypto_async_request base;
|
||||||
void *src;
|
struct scatterlist *src;
|
||||||
void *dst;
|
struct scatterlist *dst;
|
||||||
unsigned int src_len;
|
unsigned int src_len;
|
||||||
unsigned int dst_len;
|
unsigned int dst_len;
|
||||||
void *__ctx[] CRYPTO_MINALIGN_ATTR;
|
void *__ctx[] CRYPTO_MINALIGN_ATTR;
|
||||||
@ -67,8 +67,13 @@ struct crypto_akcipher {
|
|||||||
* algorithm. In case of error, where the dst_len was insufficient,
|
* algorithm. In case of error, where the dst_len was insufficient,
|
||||||
* the req->dst_len will be updated to the size required for the
|
* the req->dst_len will be updated to the size required for the
|
||||||
* operation
|
* operation
|
||||||
* @setkey: Function invokes the algorithm specific set key function, which
|
* @set_pub_key: Function invokes the algorithm specific set public key
|
||||||
* knows how to decode and interpret the BER encoded key
|
* function, which knows how to decode and interpret
|
||||||
|
* the BER encoded public key
|
||||||
|
* @set_priv_key: Function invokes the algorithm specific set private key
|
||||||
|
* function, which knows how to decode and interpret
|
||||||
|
* the BER encoded private key
|
||||||
|
* @max_size: Function returns dest buffer size reqired for a given key.
|
||||||
* @init: Initialize the cryptographic transformation object.
|
* @init: Initialize the cryptographic transformation object.
|
||||||
* This function is used to initialize the cryptographic
|
* This function is used to initialize the cryptographic
|
||||||
* transformation object. This function is called only once at
|
* transformation object. This function is called only once at
|
||||||
@ -89,8 +94,11 @@ struct akcipher_alg {
|
|||||||
int (*verify)(struct akcipher_request *req);
|
int (*verify)(struct akcipher_request *req);
|
||||||
int (*encrypt)(struct akcipher_request *req);
|
int (*encrypt)(struct akcipher_request *req);
|
||||||
int (*decrypt)(struct akcipher_request *req);
|
int (*decrypt)(struct akcipher_request *req);
|
||||||
int (*setkey)(struct crypto_akcipher *tfm, const void *key,
|
int (*set_pub_key)(struct crypto_akcipher *tfm, const void *key,
|
||||||
unsigned int keylen);
|
unsigned int keylen);
|
||||||
|
int (*set_priv_key)(struct crypto_akcipher *tfm, const void *key,
|
||||||
|
unsigned int keylen);
|
||||||
|
int (*max_size)(struct crypto_akcipher *tfm);
|
||||||
int (*init)(struct crypto_akcipher *tfm);
|
int (*init)(struct crypto_akcipher *tfm);
|
||||||
void (*exit)(struct crypto_akcipher *tfm);
|
void (*exit)(struct crypto_akcipher *tfm);
|
||||||
|
|
||||||
@ -229,14 +237,14 @@ static inline void akcipher_request_set_callback(struct akcipher_request *req,
|
|||||||
* Sets parameters required by crypto operation
|
* Sets parameters required by crypto operation
|
||||||
*
|
*
|
||||||
* @req: public key request
|
* @req: public key request
|
||||||
* @src: ptr to input parameter
|
* @src: ptr to input scatter list
|
||||||
* @dst: ptr of output parameter
|
* @dst: ptr to output scatter list
|
||||||
* @src_len: size of the input buffer
|
* @src_len: size of the src input scatter list to be processed
|
||||||
* @dst_len: size of the output buffer. It will be updated by the
|
* @dst_len: size of the dst output scatter list
|
||||||
* implementation to reflect the acctual size of the result
|
|
||||||
*/
|
*/
|
||||||
static inline void akcipher_request_set_crypt(struct akcipher_request *req,
|
static inline void akcipher_request_set_crypt(struct akcipher_request *req,
|
||||||
void *src, void *dst,
|
struct scatterlist *src,
|
||||||
|
struct scatterlist *dst,
|
||||||
unsigned int src_len,
|
unsigned int src_len,
|
||||||
unsigned int dst_len)
|
unsigned int dst_len)
|
||||||
{
|
{
|
||||||
@ -246,6 +254,22 @@ static inline void akcipher_request_set_crypt(struct akcipher_request *req,
|
|||||||
req->dst_len = dst_len;
|
req->dst_len = dst_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* crypto_akcipher_maxsize() -- Get len for output buffer
|
||||||
|
*
|
||||||
|
* Function returns the dest buffer size required for a given key
|
||||||
|
*
|
||||||
|
* @tfm: AKCIPHER tfm handle allocated with crypto_alloc_akcipher()
|
||||||
|
*
|
||||||
|
* Return: minimum len for output buffer or error code in key hasn't been set
|
||||||
|
*/
|
||||||
|
static inline int crypto_akcipher_maxsize(struct crypto_akcipher *tfm)
|
||||||
|
{
|
||||||
|
struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
|
||||||
|
|
||||||
|
return alg->max_size(tfm);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* crypto_akcipher_encrypt() -- Invoke public key encrypt operation
|
* crypto_akcipher_encrypt() -- Invoke public key encrypt operation
|
||||||
*
|
*
|
||||||
@ -319,22 +343,44 @@ static inline int crypto_akcipher_verify(struct akcipher_request *req)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* crypto_akcipher_setkey() -- Invoke public key setkey operation
|
* crypto_akcipher_set_pub_key() -- Invoke set public key operation
|
||||||
*
|
*
|
||||||
* Function invokes the algorithm specific set key function, which knows
|
* Function invokes the algorithm specific set key function, which knows
|
||||||
* how to decode and interpret the encoded key
|
* how to decode and interpret the encoded key
|
||||||
*
|
*
|
||||||
* @tfm: tfm handle
|
* @tfm: tfm handle
|
||||||
* @key: BER encoded private or public key
|
* @key: BER encoded public key
|
||||||
* @keylen: length of the key
|
* @keylen: length of the key
|
||||||
*
|
*
|
||||||
* Return: zero on success; error code in case of error
|
* Return: zero on success; error code in case of error
|
||||||
*/
|
*/
|
||||||
static inline int crypto_akcipher_setkey(struct crypto_akcipher *tfm, void *key,
|
static inline int crypto_akcipher_set_pub_key(struct crypto_akcipher *tfm,
|
||||||
unsigned int keylen)
|
const void *key,
|
||||||
|
unsigned int keylen)
|
||||||
{
|
{
|
||||||
struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
|
struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
|
||||||
|
|
||||||
return alg->setkey(tfm, key, keylen);
|
return alg->set_pub_key(tfm, key, keylen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* crypto_akcipher_set_priv_key() -- Invoke set private key operation
|
||||||
|
*
|
||||||
|
* Function invokes the algorithm specific set key function, which knows
|
||||||
|
* how to decode and interpret the encoded key
|
||||||
|
*
|
||||||
|
* @tfm: tfm handle
|
||||||
|
* @key: BER encoded private key
|
||||||
|
* @keylen: length of the key
|
||||||
|
*
|
||||||
|
* Return: zero on success; error code in case of error
|
||||||
|
*/
|
||||||
|
static inline int crypto_akcipher_set_priv_key(struct crypto_akcipher *tfm,
|
||||||
|
const void *key,
|
||||||
|
unsigned int keylen)
|
||||||
|
{
|
||||||
|
struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
|
||||||
|
|
||||||
|
return alg->set_priv_key(tfm, key, keylen);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -20,8 +20,11 @@ struct rsa_key {
|
|||||||
MPI d;
|
MPI d;
|
||||||
};
|
};
|
||||||
|
|
||||||
int rsa_parse_key(struct rsa_key *rsa_key, const void *key,
|
int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
|
||||||
unsigned int key_len);
|
unsigned int key_len);
|
||||||
|
|
||||||
|
int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key,
|
||||||
|
unsigned int key_len);
|
||||||
|
|
||||||
void rsa_free_key(struct rsa_key *rsa_key);
|
void rsa_free_key(struct rsa_key *rsa_key);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user