* Re: [RFC v4 2/4] crypto: Introduce CRYPTO_ALG_BULK flag
From: Herbert Xu @ 2016-06-15 6:49 UTC (permalink / raw)
To: Baolin Wang
Cc: Jens Axboe, Alasdair G Kergon, Mike Snitzer,
open list:DEVICE-MAPPER (LVM), David Miller, Eric Biggers,
Joonsoo Kim, tadeusz.struk, smueller, Masanari Iida, Shaohua Li,
Dan Williams, Martin K. Petersen, Sagi Grimberg, Kent Overstreet,
Keith Busch, Tejun Heo, Ming Lei, Mark Brown, Arnd Bergmann,
linux-crypto, linux-block,
open list:SOFTWARE RAID (Multiple Disks) SUPPORT, LKML
In-Reply-To: <CAMz4kuKXJ5xUXj111VBb9hMH=kT3Y5P3_iVtgeS8kidbLZ+6TA@mail.gmail.com>
On Wed, Jun 15, 2016 at 02:27:04PM +0800, Baolin Wang wrote:
>
> After some investigation, I still think we should divide the bulk
> request from dm-crypt into small request (each one is 512bytes) if
> this algorithm is not support bulk mode (like CBC). We have talked
> with dm-crypt
> maintainers why dm-crypt always use 512 bytes as one request size in
> below thread, could you please check it?
> http://www.kernelhub.org/?p=2&msg=907022
That link only points to an email about an oops.
Diggin through that thread, the only objection I have seen is about
the fact that you have to generate a fresh IV for each sector, which
is precisely what I'm suggesting that you do.
IOW, implement the IV generators in the crypto API, and then you can
easily generate a new IV (if necessary) for each sector.
> That means if we move the IV handling into crypto API, we still can
> not use bulk interface for all algorithm, for example we still need to
> read/write with 512 bytes for CBC, you can't use 4k or more block on
> CBC (and most other encryption modes). If only a part of 4k block is
> written (and then system crash happens), CBC would corrupt the block
> completely. It means if we map one whole bio with bulk interface in
> dm-crypt, we need to divide into every 512 bytes requests in crypto
> layer. So I don't think we can handle every algorithm with bulk
> interface just moving the IV handling into crypto API. Thanks.
Of course you would do CBC in 512-byte blocks, but my point is that
you should do this in a crypto API algorithm, rather than dm-crypt
as we do now. Once you implement that then dm-crypt can treat
every algorithm as if they supported bulk processing.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [RFC v4 2/4] crypto: Introduce CRYPTO_ALG_BULK flag
From: Baolin Wang @ 2016-06-15 6:27 UTC (permalink / raw)
To: Herbert Xu
Cc: Jens Axboe, Alasdair G Kergon, Mike Snitzer,
open list:DEVICE-MAPPER (LVM), David Miller, Eric Biggers,
Joonsoo Kim, tadeusz.struk, smueller, Masanari Iida, Shaohua Li,
Dan Williams, Martin K. Petersen, Sagi Grimberg, Kent Overstreet,
Keith Busch, Tejun Heo, Ming Lei, Mark Brown, Arnd Bergmann,
linux-crypto, linux-block,
open list:SOFTWARE RAID (Multiple Disks) SUPPORT, LKML
In-Reply-To: <CAMz4kuLsAyo7pO3VhCV9QdyHJ8njc6dfvORf55Nc_JTDVR-inQ@mail.gmail.com>
Hi Herbert,
On 8 June 2016 at 10:00, Baolin Wang <baolin.wang@linaro.org> wrote:
> Hi Herbert,
>
> On 7 June 2016 at 22:16, Herbert Xu <herbert@gondor.apana.org.au> wrote:
>> On Tue, Jun 07, 2016 at 08:17:05PM +0800, Baolin Wang wrote:
>>> Now some cipher hardware engines prefer to handle bulk block rather than one
>>> sector (512 bytes) created by dm-crypt, cause these cipher engines can handle
>>> the intermediate values (IV) by themselves in one bulk block. This means we
>>> can increase the size of the request by merging request rather than always 512
>>> bytes and thus increase the hardware engine processing speed.
>>>
>>> So introduce 'CRYPTO_ALG_BULK' flag to indicate this cipher can support bulk
>>> mode.
>>>
>>> Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
>>
>> Nack. As I said before, please do it using explicit IV generators
>> like we do for IPsec.
>
> OK. I would like to try your suggestion. Thanks.
After some investigation, I still think we should divide the bulk
request from dm-crypt into small request (each one is 512bytes) if
this algorithm is not support bulk mode (like CBC). We have talked
with dm-crypt
maintainers why dm-crypt always use 512 bytes as one request size in
below thread, could you please check it?
http://www.kernelhub.org/?p=2&msg=907022
That means if we move the IV handling into crypto API, we still can
not use bulk interface for all algorithm, for example we still need to
read/write with 512 bytes for CBC, you can't use 4k or more block on
CBC (and most other encryption modes). If only a part of 4k block is
written (and then system crash happens), CBC would corrupt the block
completely. It means if we map one whole bio with bulk interface in
dm-crypt, we need to divide into every 512 bytes requests in crypto
layer. So I don't think we can handle every algorithm with bulk
interface just moving the IV handling into crypto API. Thanks.
>
>> --
>> Email: Herbert Xu <herbert@gondor.apana.org.au>
>> Home Page: http://gondor.apana.org.au/~herbert/
>> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
>
>
>
> --
> Baolin.wang
> Best Regards
--
Baolin.wang
Best Regards
^ permalink raw reply
* padata - is serial actually serial?
From: Jason A. Donenfeld @ 2016-06-14 21:00 UTC (permalink / raw)
To: Steffen Klassert; +Cc: linux-crypto, Netdev
Hi Steffen & Folks,
I submit a job to padata_do_parallel(). When the parallel() function
triggers, I do some things, and then call padata_do_serial(). Finally
the serial() function triggers, where I complete the job (check a
nonce, etc).
The padata API is very appealing because not only does it allow for
parallel computation, but it claims that the serial() functions will
execute in the order that jobs were originally submitted to
padata_do_parallel().
Unfortunately, in practice, I'm pretty sure I'm seeing deviations from
this. When I submit tons and tons of tasks at rapid speed to
padata_do_parallel(), it seems like the serial() function isn't being
called in the exactly the same order that tasks were submitted to
padata_do_parallel().
Is this known (expected) behavior? Or have I stumbled upon a potential
bug that's worthwhile for me to investigate more?
Thanks,
Jason
^ permalink raw reply
* Re: [PATCH v6 3/6] crypto: AF_ALG -- add asymmetric cipher interface
From: Mat Martineau @ 2016-06-14 17:22 UTC (permalink / raw)
To: smueller-T9tCv8IpfcWELgA04lAiVw
Cc: Tadeusz Struk, dhowells-H+wXaHxf7aLQT0dZR+AlfA,
herbert-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q,
linux-api-u79uwXL29TY76Z2rM5mHXA, marcel-kz+m5ild9QBg9hUCZPvPmw,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
keyrings-u79uwXL29TY76Z2rM5mHXA,
linux-crypto-u79uwXL29TY76Z2rM5mHXA, dwmw2-wEGCiKHe2LqWVfeAwA7xHQ,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <20160515041701.15888.53830.stgit@tstruk-mobl1>
Stephan,
On Sat, 14 May 2016, Tadeusz Struk wrote:
> From: Stephan Mueller <smueller-T9tCv8IpfcWELgA04lAiVw@public.gmane.org>
>
> This patch adds the user space interface for asymmetric ciphers. The
> interface allows the use of sendmsg as well as vmsplice to provide data.
>
> This version has been rebased on top of 4.6 and a few chackpatch issues
> have been fixed.
>
> Signed-off-by: Stephan Mueller <smueller-T9tCv8IpfcWELgA04lAiVw@public.gmane.org>
> Signed-off-by: Tadeusz Struk <tadeusz.struk-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> ---
> crypto/algif_akcipher.c | 542 +++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 542 insertions(+)
> create mode 100644 crypto/algif_akcipher.c
>
> diff --git a/crypto/algif_akcipher.c b/crypto/algif_akcipher.c
> new file mode 100644
> index 0000000..6342b6e
> --- /dev/null
> +++ b/crypto/algif_akcipher.c
> +
> +static int akcipher_sendmsg(struct socket *sock, struct msghdr *msg,
> + size_t size)
> +{
> + struct sock *sk = sock->sk;
> + struct alg_sock *ask = alg_sk(sk);
> + struct akcipher_ctx *ctx = ask->private;
> + struct akcipher_sg_list *sgl = &ctx->tsgl;
> + struct af_alg_control con = {};
> + long copied = 0;
> + int op = 0;
> + bool init = 0;
> + int err;
> +
> + if (msg->msg_controllen) {
> + err = af_alg_cmsg_send(msg, &con);
> + if (err)
> + return err;
> +
> + init = 1;
> + switch (con.op) {
> + case ALG_OP_VERIFY:
> + case ALG_OP_SIGN:
> + case ALG_OP_ENCRYPT:
> + case ALG_OP_DECRYPT:
> + op = con.op;
> + break;
> + default:
> + return -EINVAL;
> + }
> + }
> +
> + lock_sock(sk);
> + if (!ctx->more && ctx->used)
> + goto unlock;
err might be uninitialised at this goto. Should it be set to something
like -EALREADY to indicate that data is already queued for a different
crypto op?
<snip>
> +unlock:
> + akcipher_data_wakeup(sk);
> + release_sock(sk);
> +
> + return err ?: copied;
> +}
Regards,
--
Mat Martineau
Intel OTC
^ permalink raw reply
* RE: [PATCH v8 1/3] crypto: Key-agreement Protocol Primitives API (KPP)
From: Benedetto, Salvatore @ 2016-06-14 14:36 UTC (permalink / raw)
To: Herbert Xu; +Cc: linux-crypto@vger.kernel.org, Benedetto, Salvatore
In-Reply-To: <20160614113430.GA21063@gondor.apana.org.au>
> -----Original Message-----
> From: Herbert Xu [mailto:herbert@gondor.apana.org.au]
> Sent: Tuesday, June 14, 2016 12:35 PM
> To: Benedetto, Salvatore <salvatore.benedetto@intel.com>
> Cc: linux-crypto@vger.kernel.org
> Subject: Re: [PATCH v8 1/3] crypto: Key-agreement Protocol Primitives API
> (KPP)
>
> On Mon, Jun 13, 2016 at 10:55:46PM +0100, Salvatore Benedetto wrote:
> >
> > +struct kpp_alg {
> > + int (*set_secret)(struct crypto_kpp *tfm, void *buffer);
>
> Sorry I think we need to change this. Leaving this with no type checking
> between the user and the driver is a recipe for disaster.
>
> I think the easiest solution is to use either BER encoding like rsa.c or netlink
> encoding like authenc.c.
>
My very first patch used PKCS3 and there were some objections to that.
https://patchwork.kernel.org/patch/8311881/
Both Bluetooth or keyctl KEYCTL_DH_COMPUTE would have to first pack the
key to whatever format we choose and I don't see that very convinient. We
only want to provide the acceleration here, without bounding the user to a
certain key format.
akcipher is different as PKCS1 is a recognized standard for RSA keys.
Please don't get me wrong, it's not much of an issue for me to respin the
patchset and change that to PKCS3 for example, but I see no harm in leaving
it as it is and moving the key check format to whatever upper layer is using us
(like BT and keyctl). Just more work for who is using the API.
Could you reconsider that?
Thanks,
Salvatore
^ permalink raw reply
* RE: [PATCH v5] crypto: rsa - return raw integers for the ASN.1 parser
From: Tudor-Dan Ambarus @ 2016-06-14 14:35 UTC (permalink / raw)
To: Stephan Mueller, Herbert Xu; +Cc: linux-crypto@vger.kernel.org
In-Reply-To: <1920297.cMHx9vzUDS@tauon.atsec.com>
Hi Stephan,
> But then I need to refine my question: isn't rsa_parse_priv_key allocating
> the
> MPIs (at least rsa_parse_priv_key seems to hint to that considering the
> error
> code path)? So, shouldn't the MPIs be freed here with free_mpis()? This
> would
> apply to parse_pub_key too.
rsa_parse_priv_key is not allocating the MPIs, mpi_read_raw_data is.
MPIs are freed on error path. On success, they are freed when exiting
the tfm or when setting a new key.
Thanks,
ta
^ permalink raw reply
* Re: [PATCH v5] crypto: rsa - return raw integers for the ASN.1 parser
From: Stephan Mueller @ 2016-06-14 13:53 UTC (permalink / raw)
To: Herbert Xu; +Cc: Tudor Ambarus, linux-crypto
In-Reply-To: <20160614133806.GA22193@gondor.apana.org.au>
Am Dienstag, 14. Juni 2016, 21:38:06 schrieb Herbert Xu:
Hi Herbert,
> On Tue, Jun 14, 2016 at 03:20:06PM +0200, Stephan Mueller wrote:
> > memzero_explicit(raw_key) should be added here in success and failure code
> > paths.
>
> The raw_key is just a bunch of pointers, do we really need to
> zero it?
You are correct.
But then I need to refine my question: isn't rsa_parse_priv_key allocating the
MPIs (at least rsa_parse_priv_key seems to hint to that considering the error
code path)? So, shouldn't the MPIs be freed here with free_mpis()? This would
apply to parse_pub_key too.
Ciao
Stephan
^ permalink raw reply
* Re: [PATCH v5] crypto: rsa - return raw integers for the ASN.1 parser
From: Herbert Xu @ 2016-06-14 13:38 UTC (permalink / raw)
To: Stephan Mueller; +Cc: Tudor Ambarus, linux-crypto
In-Reply-To: <2066344.ohg9RiuaKP@tauon.atsec.com>
On Tue, Jun 14, 2016 at 03:20:06PM +0200, Stephan Mueller wrote:
>
> memzero_explicit(raw_key) should be added here in success and failure code
> paths.
The raw_key is just a bunch of pointers, do we really need to
zero it?
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH v5] crypto: rsa - return raw integers for the ASN.1 parser
From: Stephan Mueller @ 2016-06-14 13:20 UTC (permalink / raw)
To: Tudor Ambarus; +Cc: herbert, linux-crypto
In-Reply-To: <1465910098-16349-1-git-send-email-tudor-dan.ambarus@nxp.com>
Am Dienstag, 14. Juni 2016, 16:14:58 schrieb Tudor Ambarus:
Hi Tudor,
> static int rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key,
> unsigned int keylen)
> {
> - struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
> + struct rsa_mpi_key *mpi_key = akcipher_tfm_ctx(tfm);
> + struct rsa_key raw_key = {0};
> int ret;
>
> - ret = rsa_parse_priv_key(pkey, key, keylen);
> + /* Free the old MPI key if any */
> + rsa_free_mpi_key(mpi_key);
> +
> + ret = rsa_parse_priv_key(&raw_key, key, keylen);
> if (ret)
> return ret;
>
> - if (rsa_check_key_length(mpi_get_size(pkey->n) << 3)) {
> - rsa_free_key(pkey);
> - ret = -EINVAL;
> + mpi_key->d = mpi_read_raw_data(raw_key.d, raw_key.d_sz);
> + if (!mpi_key->d)
> + goto err;
> +
> + mpi_key->e = mpi_read_raw_data(raw_key.e, raw_key.e_sz);
> + if (!mpi_key->e)
> + goto err;
> +
> + mpi_key->n = mpi_read_raw_data(raw_key.n, raw_key.n_sz);
> + if (!mpi_key->n)
> + goto err;
> +
> + if (rsa_check_key_length(mpi_get_size(mpi_key->n) << 3)) {
> + rsa_free_mpi_key(mpi_key);
> + return -EINVAL;
> }
> - return ret;
> +
> + return 0;
> +
> +err:
> + rsa_free_mpi_key(mpi_key);
> + return -ENOMEM;
> }
memzero_explicit(raw_key) should be added here in success and failure code
paths.
Ciao
Stephan
^ permalink raw reply
* [PATCH v5] crypto: rsa - return raw integers for the ASN.1 parser
From: Tudor Ambarus @ 2016-06-14 13:14 UTC (permalink / raw)
To: herbert; +Cc: smueller, linux-crypto, Tudor Ambarus
Return the raw key with no other processing so that the caller
can copy it or MPI parse it, etc.
The scope is to have only one ANS.1 parser for all RSA
implementations.
Update the RSA software implementation so that it does
the MPI conversion on top.
Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
---
Changes in v5:
- store raw keys on stack
Changes in v4:
1. Remove the skipping of leading zeros from rsa_get_n/e/d helper functions.
2. Remove FIPS RSA key length checking for the RSA private exponent.
FIPS check is done only for the RSA modulus.
crypto/rsa.c | 105 +++++++++++++++++++++++++++++----------
crypto/rsa_helper.c | 111 +++++++++++++++---------------------------
include/crypto/internal/rsa.h | 22 ++++++---
3 files changed, 135 insertions(+), 103 deletions(-)
diff --git a/crypto/rsa.c b/crypto/rsa.c
index 77d737f..dc692d4 100644
--- a/crypto/rsa.c
+++ b/crypto/rsa.c
@@ -10,16 +10,23 @@
*/
#include <linux/module.h>
+#include <linux/mpi.h>
#include <crypto/internal/rsa.h>
#include <crypto/internal/akcipher.h>
#include <crypto/akcipher.h>
#include <crypto/algapi.h>
+struct rsa_mpi_key {
+ MPI n;
+ MPI e;
+ MPI d;
+};
+
/*
* RSAEP function [RFC3447 sec 5.1.1]
* c = m^e mod n;
*/
-static int _rsa_enc(const struct rsa_key *key, MPI c, MPI m)
+static int _rsa_enc(const struct rsa_mpi_key *key, MPI c, MPI m)
{
/* (1) Validate 0 <= m < n */
if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0)
@@ -33,7 +40,7 @@ static int _rsa_enc(const struct rsa_key *key, MPI c, MPI m)
* RSADP function [RFC3447 sec 5.1.2]
* m = c^d mod n;
*/
-static int _rsa_dec(const struct rsa_key *key, MPI m, MPI c)
+static int _rsa_dec(const struct rsa_mpi_key *key, MPI m, MPI c)
{
/* (1) Validate 0 <= c < n */
if (mpi_cmp_ui(c, 0) < 0 || mpi_cmp(c, key->n) >= 0)
@@ -47,7 +54,7 @@ static int _rsa_dec(const struct rsa_key *key, MPI m, MPI c)
* RSASP1 function [RFC3447 sec 5.2.1]
* s = m^d mod n
*/
-static int _rsa_sign(const struct rsa_key *key, MPI s, MPI m)
+static int _rsa_sign(const struct rsa_mpi_key *key, MPI s, MPI m)
{
/* (1) Validate 0 <= m < n */
if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0)
@@ -61,7 +68,7 @@ static int _rsa_sign(const struct rsa_key *key, MPI s, MPI m)
* RSAVP1 function [RFC3447 sec 5.2.2]
* m = s^e mod n;
*/
-static int _rsa_verify(const struct rsa_key *key, MPI m, MPI s)
+static int _rsa_verify(const struct rsa_mpi_key *key, MPI m, MPI s)
{
/* (1) Validate 0 <= s < n */
if (mpi_cmp_ui(s, 0) < 0 || mpi_cmp(s, key->n) >= 0)
@@ -71,7 +78,7 @@ static int _rsa_verify(const struct rsa_key *key, MPI m, MPI s)
return mpi_powm(m, s, key->e, key->n);
}
-static inline struct rsa_key *rsa_get_key(struct crypto_akcipher *tfm)
+static inline struct rsa_mpi_key *rsa_get_key(struct crypto_akcipher *tfm)
{
return akcipher_tfm_ctx(tfm);
}
@@ -79,7 +86,7 @@ static inline struct rsa_key *rsa_get_key(struct crypto_akcipher *tfm)
static int rsa_enc(struct akcipher_request *req)
{
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
- const struct rsa_key *pkey = rsa_get_key(tfm);
+ const struct rsa_mpi_key *pkey = rsa_get_key(tfm);
MPI m, c = mpi_alloc(0);
int ret = 0;
int sign;
@@ -118,7 +125,7 @@ err_free_c:
static int rsa_dec(struct akcipher_request *req)
{
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
- const struct rsa_key *pkey = rsa_get_key(tfm);
+ const struct rsa_mpi_key *pkey = rsa_get_key(tfm);
MPI c, m = mpi_alloc(0);
int ret = 0;
int sign;
@@ -156,7 +163,7 @@ err_free_m:
static int rsa_sign(struct akcipher_request *req)
{
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
- const struct rsa_key *pkey = rsa_get_key(tfm);
+ const struct rsa_mpi_key *pkey = rsa_get_key(tfm);
MPI m, s = mpi_alloc(0);
int ret = 0;
int sign;
@@ -195,7 +202,7 @@ err_free_s:
static int rsa_verify(struct akcipher_request *req)
{
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
- const struct rsa_key *pkey = rsa_get_key(tfm);
+ const struct rsa_mpi_key *pkey = rsa_get_key(tfm);
MPI s, m = mpi_alloc(0);
int ret = 0;
int sign;
@@ -233,6 +240,16 @@ err_free_m:
return ret;
}
+static void rsa_free_mpi_key(struct rsa_mpi_key *key)
+{
+ mpi_free(key->d);
+ mpi_free(key->e);
+ mpi_free(key->n);
+ key->d = NULL;
+ key->e = NULL;
+ key->n = NULL;
+}
+
static int rsa_check_key_length(unsigned int len)
{
switch (len) {
@@ -251,49 +268,87 @@ static int rsa_check_key_length(unsigned int len)
static int rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key,
unsigned int keylen)
{
- struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
+ struct rsa_mpi_key *mpi_key = akcipher_tfm_ctx(tfm);
+ struct rsa_key raw_key = {0};
int ret;
- ret = rsa_parse_pub_key(pkey, key, keylen);
+ /* Free the old MPI key if any */
+ rsa_free_mpi_key(mpi_key);
+
+ ret = rsa_parse_pub_key(&raw_key, key, keylen);
if (ret)
return ret;
- if (rsa_check_key_length(mpi_get_size(pkey->n) << 3)) {
- rsa_free_key(pkey);
- ret = -EINVAL;
+ mpi_key->e = mpi_read_raw_data(raw_key.e, raw_key.e_sz);
+ if (!mpi_key->e)
+ goto err;
+
+ mpi_key->n = mpi_read_raw_data(raw_key.n, raw_key.n_sz);
+ if (!mpi_key->n)
+ goto err;
+
+ if (rsa_check_key_length(mpi_get_size(mpi_key->n) << 3)) {
+ rsa_free_mpi_key(mpi_key);
+ return -EINVAL;
}
- return ret;
+
+ return 0;
+
+err:
+ rsa_free_mpi_key(mpi_key);
+ return -ENOMEM;
}
static int rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key,
unsigned int keylen)
{
- struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
+ struct rsa_mpi_key *mpi_key = akcipher_tfm_ctx(tfm);
+ struct rsa_key raw_key = {0};
int ret;
- ret = rsa_parse_priv_key(pkey, key, keylen);
+ /* Free the old MPI key if any */
+ rsa_free_mpi_key(mpi_key);
+
+ ret = rsa_parse_priv_key(&raw_key, key, keylen);
if (ret)
return ret;
- if (rsa_check_key_length(mpi_get_size(pkey->n) << 3)) {
- rsa_free_key(pkey);
- ret = -EINVAL;
+ mpi_key->d = mpi_read_raw_data(raw_key.d, raw_key.d_sz);
+ if (!mpi_key->d)
+ goto err;
+
+ mpi_key->e = mpi_read_raw_data(raw_key.e, raw_key.e_sz);
+ if (!mpi_key->e)
+ goto err;
+
+ mpi_key->n = mpi_read_raw_data(raw_key.n, raw_key.n_sz);
+ if (!mpi_key->n)
+ goto err;
+
+ if (rsa_check_key_length(mpi_get_size(mpi_key->n) << 3)) {
+ rsa_free_mpi_key(mpi_key);
+ return -EINVAL;
}
- return ret;
+
+ return 0;
+
+err:
+ rsa_free_mpi_key(mpi_key);
+ return -ENOMEM;
}
static int rsa_max_size(struct crypto_akcipher *tfm)
{
- struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
+ struct rsa_mpi_key *pkey = akcipher_tfm_ctx(tfm);
return pkey->n ? mpi_get_size(pkey->n) : -EINVAL;
}
static void rsa_exit_tfm(struct crypto_akcipher *tfm)
{
- struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
+ struct rsa_mpi_key *pkey = akcipher_tfm_ctx(tfm);
- rsa_free_key(pkey);
+ rsa_free_mpi_key(pkey);
}
static struct akcipher_alg rsa = {
@@ -310,7 +365,7 @@ static struct akcipher_alg rsa = {
.cra_driver_name = "rsa-generic",
.cra_priority = 100,
.cra_module = THIS_MODULE,
- .cra_ctxsize = sizeof(struct rsa_key),
+ .cra_ctxsize = sizeof(struct rsa_mpi_key),
},
};
diff --git a/crypto/rsa_helper.c b/crypto/rsa_helper.c
index d226f48..583656a 100644
--- a/crypto/rsa_helper.c
+++ b/crypto/rsa_helper.c
@@ -22,20 +22,29 @@ int rsa_get_n(void *context, size_t hdrlen, unsigned char tag,
const void *value, size_t vlen)
{
struct rsa_key *key = context;
+ const u8 *ptr = value;
+ size_t n_sz = vlen;
- key->n = mpi_read_raw_data(value, vlen);
-
- if (!key->n)
- return -ENOMEM;
-
- /* In FIPS mode only allow key size 2K & 3K */
- if (fips_enabled && (mpi_get_size(key->n) != 256 &&
- mpi_get_size(key->n) != 384)) {
- pr_err("RSA: key size not allowed in FIPS mode\n");
- mpi_free(key->n);
- key->n = NULL;
+ /* invalid key provided */
+ if (!value || !vlen)
return -EINVAL;
+
+ if (fips_enabled) {
+ while (!*ptr && n_sz) {
+ ptr++;
+ n_sz--;
+ }
+
+ /* In FIPS mode only allow key size 2K & 3K */
+ if (n_sz != 256 && n_sz != 384) {
+ pr_err("RSA: key size not allowed in FIPS mode\n");
+ return -EINVAL;
+ }
}
+
+ key->n = value;
+ key->n_sz = vlen;
+
return 0;
}
@@ -44,10 +53,12 @@ int rsa_get_e(void *context, size_t hdrlen, unsigned char tag,
{
struct rsa_key *key = context;
- key->e = mpi_read_raw_data(value, vlen);
+ /* invalid key provided */
+ if (!value || !key->n_sz || !vlen || vlen > key->n_sz)
+ return -EINVAL;
- if (!key->e)
- return -ENOMEM;
+ key->e = value;
+ key->e_sz = vlen;
return 0;
}
@@ -57,46 +68,20 @@ int rsa_get_d(void *context, size_t hdrlen, unsigned char tag,
{
struct rsa_key *key = context;
- key->d = mpi_read_raw_data(value, vlen);
-
- if (!key->d)
- return -ENOMEM;
-
- /* In FIPS mode only allow key size 2K & 3K */
- if (fips_enabled && (mpi_get_size(key->d) != 256 &&
- mpi_get_size(key->d) != 384)) {
- pr_err("RSA: key size not allowed in FIPS mode\n");
- mpi_free(key->d);
- key->d = NULL;
+ /* invalid key provided */
+ if (!value || !key->n_sz || !vlen || vlen > key->n_sz)
return -EINVAL;
- }
- return 0;
-}
-static void free_mpis(struct rsa_key *key)
-{
- mpi_free(key->n);
- mpi_free(key->e);
- mpi_free(key->d);
- key->n = NULL;
- key->e = NULL;
- key->d = NULL;
-}
+ key->d = value;
+ key->d_sz = vlen;
-/**
- * rsa_free_key() - frees rsa key allocated by rsa_parse_key()
- *
- * @rsa_key: struct rsa_key key representation
- */
-void rsa_free_key(struct rsa_key *key)
-{
- free_mpis(key);
+ return 0;
}
-EXPORT_SYMBOL_GPL(rsa_free_key);
/**
- * rsa_parse_pub_key() - extracts an rsa public key from BER encoded buffer
- * and stores it in the provided struct rsa_key
+ * rsa_parse_pub_key() - decodes the BER encoded buffer and stores in the
+ * provided struct rsa_key, pointers to the raw key as is,
+ * so that the caller can copy it or MPI parse it, etc.
*
* @rsa_key: struct rsa_key key representation
* @key: key in BER format
@@ -107,23 +92,15 @@ EXPORT_SYMBOL_GPL(rsa_free_key);
int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
unsigned int key_len)
{
- int ret;
-
- free_mpis(rsa_key);
- ret = asn1_ber_decoder(&rsapubkey_decoder, rsa_key, key, key_len);
- if (ret < 0)
- goto error;
-
- return 0;
-error:
- free_mpis(rsa_key);
- return ret;
+ return asn1_ber_decoder(&rsapubkey_decoder, rsa_key, key, key_len);
}
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_parse_priv_key() - decodes the BER encoded buffer and stores in the
+ * provided struct rsa_key, pointers to the raw key
+ * as is, so that the caller can copy it or MPI parse it,
+ * etc.
*
* @rsa_key: struct rsa_key key representation
* @key: key in BER format
@@ -134,16 +111,6 @@ EXPORT_SYMBOL_GPL(rsa_parse_pub_key);
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;
+ return asn1_ber_decoder(&rsaprivkey_decoder, rsa_key, key, key_len);
}
EXPORT_SYMBOL_GPL(rsa_parse_priv_key);
diff --git a/include/crypto/internal/rsa.h b/include/crypto/internal/rsa.h
index c7585bd..d6c042a 100644
--- a/include/crypto/internal/rsa.h
+++ b/include/crypto/internal/rsa.h
@@ -12,12 +12,24 @@
*/
#ifndef _RSA_HELPER_
#define _RSA_HELPER_
-#include <linux/mpi.h>
+#include <linux/types.h>
+/**
+ * rsa_key - RSA key structure
+ * @n : RSA modulus raw byte stream
+ * @e : RSA public exponent raw byte stream
+ * @d : RSA private exponent raw byte stream
+ * @n_sz : length in bytes of RSA modulus n
+ * @e_sz : length in bytes of RSA public exponent
+ * @d_sz : length in bytes of RSA private exponent
+ */
struct rsa_key {
- MPI n;
- MPI e;
- MPI d;
+ const u8 *n;
+ const u8 *e;
+ const u8 *d;
+ size_t n_sz;
+ size_t e_sz;
+ size_t d_sz;
};
int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
@@ -26,7 +38,5 @@ int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
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);
-
extern struct crypto_template rsa_pkcs1pad_tmpl;
#endif
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH v8 1/3] crypto: Key-agreement Protocol Primitives API (KPP)
From: Herbert Xu @ 2016-06-14 11:34 UTC (permalink / raw)
To: Salvatore Benedetto; +Cc: linux-crypto
In-Reply-To: <1465854948-9084-2-git-send-email-salvatore.benedetto@intel.com>
On Mon, Jun 13, 2016 at 10:55:46PM +0100, Salvatore Benedetto wrote:
>
> +struct kpp_alg {
> + int (*set_secret)(struct crypto_kpp *tfm, void *buffer);
Sorry I think we need to change this. Leaving this with no type
checking between the user and the driver is a recipe for disaster.
I think the easiest solution is to use either BER encoding like
rsa.c or netlink encoding like authenc.c.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH v4] crypto: rsa - return raw integers for the ASN.1 parser
From: Herbert Xu @ 2016-06-14 11:20 UTC (permalink / raw)
To: Tudor Ambarus; +Cc: smueller, linux-crypto
In-Reply-To: <1465827173-16916-1-git-send-email-tudor-dan.ambarus@nxp.com>
On Mon, Jun 13, 2016 at 05:12:53PM +0300, Tudor Ambarus wrote:
> +
> +struct rsa_ctx {
> + struct rsa_key key;
This isn't necessary and worse it may lead to bugs in future.
The raw keys will be invalid as soon as the setkey functions
return.
So just store it on the stack.
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH v2 0/3] hw_random: Add Amlogic Meson SoCs Random Generator driver
From: Herbert Xu @ 2016-06-14 10:33 UTC (permalink / raw)
To: Kevin Hilman
Cc: Neil Armstrong, linux-crypto, linux-amlogic, linux-kernel,
linux-arm-kernel, Matt Mackall
In-Reply-To: <m2wplsviy3.fsf@baylibre.com>
On Mon, Jun 13, 2016 at 03:10:28PM -0700, Kevin Hilman wrote:
> Could you take just the driver please?
>
> Due to lots of other activity in the DT, I'd prefer to send the DT &
> bindings though the arm-soc (via the amlogic tree.)
OK I will back out these two patches.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH v6 3/6] crypto: AF_ALG -- add asymmetric cipher interface
From: Andrew Zaborowski @ 2016-06-14 7:42 UTC (permalink / raw)
To: Stephan Mueller
Cc: Mat Martineau, Tadeusz Struk, David Howells, Herbert Xu,
linux-api-u79uwXL29TY76Z2rM5mHXA, marcel-kz+m5ild9QBg9hUCZPvPmw,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
keyrings-u79uwXL29TY76Z2rM5mHXA, Linux Crypto Mailing List,
David Woodhouse, davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <1759070.fi90mrsgKn-jJGQKZiSfeo1haGO/jJMPxvVK+yQ3ZXh@public.gmane.org>
Hi Stephan,
On 14 June 2016 at 07:12, Stephan Mueller <smueller-T9tCv8IpfcWELgA04lAiVw@public.gmane.org> wrote:
> Am Dienstag, 14. Juni 2016, 00:16:11 schrieb Andrew Zaborowski:
>> On 8 June 2016 at 21:14, Mat Martineau
>>
>> <mathew.j.martineau-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote:
>> > On Wed, 8 Jun 2016, Stephan Mueller wrote:
>> >> What is your concern?
>> >
>> > Userspace must allocate larger buffers than it knows are necessary for
>> > expected results.
>> >
>> > It looks like the software rsa implementation handles shorter output
>> > buffers ok (mpi_write_to_sgl will return EOVERFLOW if the the buffer is
>> > too small), however I see at least one hardware rsa driver that requires
>> > the output buffer to be the maximum size. But this inconsistency might be
>> > best addressed within the software cipher or drivers rather than in
>> > recvmsg.
>> Should the hardware drivers fix this instead? I've looked at the qat
>> and caam drivers, they both require the destination buffer size to be
>> the key size and in both cases there would be no penalty for dropping
>> this requirement as far as I see. Both do a memmove if the result
>> ends up being shorter than key size. In case the caller knows it is
>> expecting a specific output size, the driver will have to use a self
>> allocated buffer + a memcpy in those same cases where it would later
>> use memmove instead. Alternatively the sg passed to dma_map_sg can be
>> prepended with a dummy segment the right size to save the memcpy.
>>
>> akcipher.h only says:
>> @dst_len: Size of the output buffer. It needs to be at least as big as
>> the expected result depending on the operation
>>
>> Note that for random input data the memmove will be done about 1 in
>> 256 times but with PKCS#1 padding the signature always has a leading
>> zero.
>>
>> Requiring buffers bigger than needed makes the added work of dropping
>> the zero bytes from the sglist and potentially re-adding them in the
>> client difficult to justify. RSA doing this sets a precedent for a
>> future pkcs1pad (or other algorithm) implementation to do the same
>> thing and a portable client having to always know the key size and use
>> key-sized buffers.
>
> I think we have agreed on dropping the length enforcement at the interface
> level.
Separately from this there's a problem with the user being unable to
know if the algorithm is going to fail because of destination buffer
size != key size (including kernel users). For RSA, the qat
implementation will fail while the software implementation won't. For
pkcs1pad(...) there's currently just one implementation but the user
can't assume that.
Best regards
^ permalink raw reply
* [PATCH v2 4/4] crypto: CTR DRBG - avoid duplicate maintenance of key
From: Stephan Mueller @ 2016-06-14 5:36 UTC (permalink / raw)
To: herbert; +Cc: linux-crypto
In-Reply-To: <1842774.dgV8IOeQEu@positron.chronox.de>
The TFM object maintains the key for the CTR DRBG.
Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
crypto/drbg.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/crypto/drbg.c b/crypto/drbg.c
index 8ceb716..ded8638 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -517,8 +517,7 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed,
return ret;
/* 10.2.1.2 step 5 */
- memcpy(drbg->C, temp, drbg_keylen(drbg));
- ret = crypto_skcipher_setkey(drbg->ctr_handle, drbg->C,
+ ret = crypto_skcipher_setkey(drbg->ctr_handle, temp,
drbg_keylen(drbg));
if (ret)
goto out;
--
2.5.5
^ permalink raw reply related
* [PATCH v2 2/4] crypto: DRBG - use aligned buffers
From: Stephan Mueller @ 2016-06-14 5:35 UTC (permalink / raw)
To: herbert; +Cc: linux-crypto
In-Reply-To: <1842774.dgV8IOeQEu@positron.chronox.de>
Hardware cipher implementation may require aligned buffers. All buffers
that potentially are processed with a cipher are now aligned.
At the time of the allocation of the memory, we have not yet allocated
the cipher implementations. Hence, we cannot obtain the alignmask for
the used cipher yet. Therefore, the DRBG code uses an alignment which
should satisfy all cipher implementations.
Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
crypto/drbg.c | 44 ++++++++++++++++++++++++--------------------
include/crypto/drbg.h | 3 +++
2 files changed, 27 insertions(+), 20 deletions(-)
diff --git a/crypto/drbg.c b/crypto/drbg.c
index 4ee1a9c..8ac3ea1 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1139,11 +1139,11 @@ static inline void drbg_dealloc_state(struct drbg_state *drbg)
if (!drbg)
return;
kzfree(drbg->V);
- drbg->V = NULL;
+ drbg->Vbuf = NULL;
kzfree(drbg->C);
- drbg->C = NULL;
- kzfree(drbg->scratchpad);
- drbg->scratchpad = NULL;
+ drbg->Cbuf = NULL;
+ kzfree(drbg->scratchpadbuf);
+ drbg->scratchpadbuf = NULL;
drbg->reseed_ctr = 0;
drbg->d_ops = NULL;
drbg->core = NULL;
@@ -1179,12 +1179,18 @@ static inline int drbg_alloc_state(struct drbg_state *drbg)
goto err;
}
- drbg->V = kmalloc(drbg_statelen(drbg), GFP_KERNEL);
- if (!drbg->V)
- goto err;
- drbg->C = kmalloc(drbg_statelen(drbg), GFP_KERNEL);
- if (!drbg->C)
+ ret = drbg->d_ops->crypto_init(drbg);
+ if (ret < 0)
goto err;
+
+ drbg->Vbuf = kmalloc(drbg_statelen(drbg) + ret, GFP_KERNEL);
+ if (!drbg->Vbuf)
+ goto fini;
+ drbg->V = PTR_ALIGN(drbg->Vbuf, ret + 1);
+ drbg->Cbuf = kmalloc(drbg_statelen(drbg) + ret, GFP_KERNEL);
+ if (!drbg->Cbuf)
+ goto fini;
+ drbg->C = PTR_ALIGN(drbg->Cbuf, ret + 1);
/* scratchpad is only generated for CTR and Hash */
if (drbg->core->flags & DRBG_HMAC)
sb_size = 0;
@@ -1198,13 +1204,16 @@ static inline int drbg_alloc_state(struct drbg_state *drbg)
sb_size = drbg_statelen(drbg) + drbg_blocklen(drbg);
if (0 < sb_size) {
- drbg->scratchpad = kzalloc(sb_size, GFP_KERNEL);
- if (!drbg->scratchpad)
- goto err;
+ drbg->scratchpadbuf = kzalloc(sb_size + ret, GFP_KERNEL);
+ if (!drbg->scratchpadbuf)
+ goto fini;
+ drbg->scratchpad = PTR_ALIGN(drbg->scratchpadbuf, ret + 1);
}
return 0;
+fini:
+ drbg->d_ops->crypto_fini(drbg);
err:
drbg_dealloc_state(drbg);
return ret;
@@ -1472,10 +1481,6 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers,
if (ret)
goto unlock;
- ret = -EFAULT;
- if (drbg->d_ops->crypto_init(drbg))
- goto err;
-
ret = drbg_prepare_hrng(drbg);
if (ret)
goto free_everything;
@@ -1499,8 +1504,6 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers,
mutex_unlock(&drbg->drbg_mutex);
return ret;
-err:
- drbg_dealloc_state(drbg);
unlock:
mutex_unlock(&drbg->drbg_mutex);
return ret;
@@ -1585,7 +1588,8 @@ static int drbg_init_hash_kernel(struct drbg_state *drbg)
sdesc->shash.tfm = tfm;
sdesc->shash.flags = 0;
drbg->priv_data = sdesc;
- return 0;
+
+ return crypto_shash_alignmask(tfm);
}
static int drbg_fini_hash_kernel(struct drbg_state *drbg)
@@ -1705,7 +1709,7 @@ static int drbg_init_sym_kernel(struct drbg_state *drbg)
drbg->ctr_null_value = (u8 *)PTR_ALIGN(drbg->ctr_null_value_buf,
alignmask + 1);
- return 0;
+ return alignmask;
}
static void drbg_kcapi_symsetkey(struct drbg_state *drbg,
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index b2fe15d..61580b1 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -108,13 +108,16 @@ struct drbg_test_data {
struct drbg_state {
struct mutex drbg_mutex; /* lock around DRBG */
unsigned char *V; /* internal state 10.1.1.1 1a) */
+ unsigned char *Vbuf;
/* hash: static value 10.1.1.1 1b) hmac / ctr: key */
unsigned char *C;
+ unsigned char *Cbuf;
/* Number of RNG requests since last reseed -- 10.1.1.1 1c) */
size_t reseed_ctr;
size_t reseed_threshold;
/* some memory the DRBG can use for its operation */
unsigned char *scratchpad;
+ unsigned char *scratchpadbuf;
void *priv_data; /* Cipher handle */
struct crypto_skcipher *ctr_handle; /* CTR mode cipher handle */
--
2.5.5
^ permalink raw reply related
* [PATCH v2 3/4] crypto: CTR DRBG - use full CTR AES for update
From: Stephan Mueller @ 2016-06-14 5:35 UTC (permalink / raw)
To: herbert; +Cc: linux-crypto
In-Reply-To: <1842774.dgV8IOeQEu@positron.chronox.de>
The CTR DRBG update function performs a full CTR AES operation including
the XOR with "plaintext" data. Hence, remove the XOR from the code and
use the CTR mode to do the XOR.
Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
crypto/drbg.c | 30 +++++++++++++-----------------
1 file changed, 13 insertions(+), 17 deletions(-)
diff --git a/crypto/drbg.c b/crypto/drbg.c
index 8ac3ea1..8ceb716 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -258,7 +258,10 @@ static int drbg_kcapi_sym(struct drbg_state *drbg, unsigned char *outval,
const struct drbg_string *in);
static int drbg_init_sym_kernel(struct drbg_state *drbg);
static int drbg_fini_sym_kernel(struct drbg_state *drbg);
-static int drbg_kcapi_sym_ctr(struct drbg_state *drbg, u8 *outbuf, u32 outlen);
+static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
+ u8 *inbuf, u32 inbuflen,
+ u8 *outbuf, u32 outlen);
+#define DRBG_CTR_NULL_LEN 128
/* BCC function for CTR DRBG as defined in 10.4.3 */
static int drbg_ctr_bcc(struct drbg_state *drbg,
@@ -481,8 +484,6 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed,
unsigned char *temp = drbg->scratchpad;
unsigned char *df_data = drbg->scratchpad + drbg_statelen(drbg) +
drbg_blocklen(drbg);
- unsigned char *temp_p, *df_data_p; /* pointer to iterate over buffers */
- unsigned int len = 0;
if (3 > reseed)
memset(df_data, 0, drbg_statelen(drbg));
@@ -510,18 +511,11 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed,
goto out;
}
- ret = drbg_kcapi_sym_ctr(drbg, temp, drbg_statelen(drbg));
+ ret = drbg_kcapi_sym_ctr(drbg, df_data, drbg_statelen(drbg),
+ temp, drbg_statelen(drbg));
if (ret)
return ret;
- /* 10.2.1.2 step 4 */
- temp_p = temp;
- df_data_p = df_data;
- for (len = 0; len < drbg_statelen(drbg); len++) {
- *temp_p ^= *df_data_p;
- df_data_p++; temp_p++;
- }
-
/* 10.2.1.2 step 5 */
memcpy(drbg->C, temp, drbg_keylen(drbg));
ret = crypto_skcipher_setkey(drbg->ctr_handle, drbg->C,
@@ -561,7 +555,8 @@ static int drbg_ctr_generate(struct drbg_state *drbg,
}
/* 10.2.1.5.2 step 4.1 */
- ret = drbg_kcapi_sym_ctr(drbg, buf, len);
+ ret = drbg_kcapi_sym_ctr(drbg, drbg->ctr_null_value, DRBG_CTR_NULL_LEN,
+ buf, len);
if (ret)
return ret;
@@ -1657,7 +1652,6 @@ static void drbg_skcipher_cb(struct crypto_async_request *req, int error)
complete(&drbg->ctr_completion);
}
-#define DRBG_CTR_NULL_LEN 128
static int drbg_init_sym_kernel(struct drbg_state *drbg)
{
struct crypto_cipher *tfm;
@@ -1733,14 +1727,16 @@ static int drbg_kcapi_sym(struct drbg_state *drbg, unsigned char *outval,
return 0;
}
-static int drbg_kcapi_sym_ctr(struct drbg_state *drbg, u8 *outbuf, u32 outlen)
+static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
+ u8 *inbuf, u32 inlen,
+ u8 *outbuf, u32 outlen)
{
struct scatterlist sg_in;
- sg_init_one(&sg_in, drbg->ctr_null_value, DRBG_CTR_NULL_LEN);
+ sg_init_one(&sg_in, inbuf, inlen);
while (outlen) {
- u32 cryptlen = min_t(u32, outlen, DRBG_CTR_NULL_LEN);
+ u32 cryptlen = min_t(u32, inlen, outlen);
struct scatterlist sg_out;
int ret;
--
2.5.5
^ permalink raw reply related
* [PATCH v2 1/4] crypto: CTR DRBG - use CTR AES instead of ECB AES
From: Stephan Mueller @ 2016-06-14 5:34 UTC (permalink / raw)
To: herbert; +Cc: linux-crypto
In-Reply-To: <1842774.dgV8IOeQEu@positron.chronox.de>
The CTR DRBG derives its random data from the CTR that is encrypted with
AES.
This patch now changes the CTR DRBG implementation such that the
CTR AES mode is employed. This allows the use of steamlined CTR AES
implementation such as ctr-aes-aesni.
Unfortunately there are the following subtile changes we need to apply
when using the CTR AES mode:
- the CTR mode increments the counter after the cipher operation, but
the CTR DRBG requires the increment before the cipher op. Hence, the
crypto_inc is applied to the counter (drbg->V) once it is
recalculated.
- the CTR mode wants to encrypt data, but the CTR DRBG is interested in
the encrypted counter only. The full CTR mode is the XOR of the
encrypted counter with the plaintext data. To access the encrypted
counter, the patch uses a NULL data vector as plaintext to be
"encrypted".
Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
crypto/Kconfig | 1 +
crypto/drbg.c | 193 ++++++++++++++++++++++++++++++++++++--------------
include/crypto/drbg.h | 9 +++
3 files changed, 149 insertions(+), 54 deletions(-)
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 1d33beb..c903f18 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -1567,6 +1567,7 @@ config CRYPTO_DRBG_HASH
config CRYPTO_DRBG_CTR
bool "Enable CTR DRBG"
select CRYPTO_AES
+ depends on CRYPTO_CTR
help
Enable the CTR DRBG variant as defined in NIST SP800-90A.
diff --git a/crypto/drbg.c b/crypto/drbg.c
index 0aca2b9..4ee1a9c 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -258,6 +258,7 @@ static int drbg_kcapi_sym(struct drbg_state *drbg, unsigned char *outval,
const struct drbg_string *in);
static int drbg_init_sym_kernel(struct drbg_state *drbg);
static int drbg_fini_sym_kernel(struct drbg_state *drbg);
+static int drbg_kcapi_sym_ctr(struct drbg_state *drbg, u8 *outbuf, u32 outlen);
/* BCC function for CTR DRBG as defined in 10.4.3 */
static int drbg_ctr_bcc(struct drbg_state *drbg,
@@ -482,36 +483,37 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed,
drbg_blocklen(drbg);
unsigned char *temp_p, *df_data_p; /* pointer to iterate over buffers */
unsigned int len = 0;
- struct drbg_string cipherin;
if (3 > reseed)
memset(df_data, 0, drbg_statelen(drbg));
- /* 10.2.1.3.2 step 2 and 10.2.1.4.2 step 2 */
- if (seed) {
- ret = drbg_ctr_df(drbg, df_data, drbg_statelen(drbg), seed);
+ if (!reseed) {
+ /*
+ * The DRBG uses the CTR mode of the underlying AES cipher. The
+ * CTR mode increments the counter value after the AES operation
+ * but SP800-90A requires that the counter is incremented before
+ * the AES operation. Hence, we increment it at the time we set
+ * it by one.
+ */
+ crypto_inc(drbg->V, drbg_blocklen(drbg));
+
+ ret = crypto_skcipher_setkey(drbg->ctr_handle, drbg->C,
+ drbg_keylen(drbg));
if (ret)
goto out;
- drbg_kcapi_symsetkey(drbg, drbg->C);
}
- drbg_string_fill(&cipherin, drbg->V, drbg_blocklen(drbg));
- /*
- * 10.2.1.3.2 steps 2 and 3 are already covered as the allocation
- * zeroizes all memory during initialization
- */
- while (len < (drbg_statelen(drbg))) {
- /* 10.2.1.2 step 2.1 */
- crypto_inc(drbg->V, drbg_blocklen(drbg));
- /*
- * 10.2.1.2 step 2.2 */
- ret = drbg_kcapi_sym(drbg, temp + len, &cipherin);
+ /* 10.2.1.3.2 step 2 and 10.2.1.4.2 step 2 */
+ if (seed) {
+ ret = drbg_ctr_df(drbg, df_data, drbg_statelen(drbg), seed);
if (ret)
goto out;
- /* 10.2.1.2 step 2.3 and 3 */
- len += drbg_blocklen(drbg);
}
+ ret = drbg_kcapi_sym_ctr(drbg, temp, drbg_statelen(drbg));
+ if (ret)
+ return ret;
+
/* 10.2.1.2 step 4 */
temp_p = temp;
df_data_p = df_data;
@@ -522,9 +524,14 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed,
/* 10.2.1.2 step 5 */
memcpy(drbg->C, temp, drbg_keylen(drbg));
- drbg_kcapi_symsetkey(drbg, drbg->C);
+ ret = crypto_skcipher_setkey(drbg->ctr_handle, drbg->C,
+ drbg_keylen(drbg));
+ if (ret)
+ goto out;
/* 10.2.1.2 step 6 */
memcpy(drbg->V, temp + drbg_keylen(drbg), drbg_blocklen(drbg));
+ /* See above: increment counter by one to compensate timing of CTR op */
+ crypto_inc(drbg->V, drbg_blocklen(drbg));
ret = 0;
out:
@@ -543,46 +550,26 @@ static int drbg_ctr_generate(struct drbg_state *drbg,
unsigned char *buf, unsigned int buflen,
struct list_head *addtl)
{
- int len = 0;
- int ret = 0;
- struct drbg_string data;
+ int ret;
+ int len = min_t(int, buflen, INT_MAX);
/* 10.2.1.5.2 step 2 */
if (addtl && !list_empty(addtl)) {
ret = drbg_ctr_update(drbg, addtl, 2);
if (ret)
return 0;
- drbg_kcapi_symsetkey(drbg, drbg->C);
}
/* 10.2.1.5.2 step 4.1 */
- crypto_inc(drbg->V, drbg_blocklen(drbg));
- drbg_string_fill(&data, drbg->V, drbg_blocklen(drbg));
- while (len < buflen) {
- int outlen = 0;
- /* 10.2.1.5.2 step 4.2 */
- ret = drbg_kcapi_sym(drbg, drbg->scratchpad, &data);
- if (ret) {
- len = ret;
- goto out;
- }
- outlen = (drbg_blocklen(drbg) < (buflen - len)) ?
- drbg_blocklen(drbg) : (buflen - len);
- /* 10.2.1.5.2 step 4.3 */
- memcpy(buf + len, drbg->scratchpad, outlen);
- len += outlen;
- /* 10.2.1.5.2 step 6 */
- if (len < buflen)
- crypto_inc(drbg->V, drbg_blocklen(drbg));
- }
+ ret = drbg_kcapi_sym_ctr(drbg, buf, len);
+ if (ret)
+ return ret;
/* 10.2.1.5.2 step 6 */
ret = drbg_ctr_update(drbg, NULL, 3);
if (ret)
len = ret;
-out:
- memset(drbg->scratchpad, 0, drbg_blocklen(drbg));
return len;
}
@@ -1634,10 +1621,46 @@ static int drbg_kcapi_hash(struct drbg_state *drbg, unsigned char *outval,
#endif /* (CONFIG_CRYPTO_DRBG_HASH || CONFIG_CRYPTO_DRBG_HMAC) */
#ifdef CONFIG_CRYPTO_DRBG_CTR
+static int drbg_fini_sym_kernel(struct drbg_state *drbg)
+{
+ struct crypto_cipher *tfm =
+ (struct crypto_cipher *)drbg->priv_data;
+ if (tfm)
+ crypto_free_cipher(tfm);
+ drbg->priv_data = NULL;
+
+ if (drbg->ctr_handle)
+ crypto_free_skcipher(drbg->ctr_handle);
+ drbg->ctr_handle = NULL;
+
+ if (drbg->ctr_req)
+ skcipher_request_free(drbg->ctr_req);;
+ drbg->ctr_req = NULL;
+
+ kfree(drbg->ctr_null_value_buf);
+ drbg->ctr_null_value = NULL;
+
+ return 0;
+}
+
+static void drbg_skcipher_cb(struct crypto_async_request *req, int error)
+{
+ struct drbg_state *drbg = req->data;
+
+ if (error == -EINPROGRESS)
+ return;
+ drbg->ctr_async_err = error;
+ complete(&drbg->ctr_completion);
+}
+
+#define DRBG_CTR_NULL_LEN 128
static int drbg_init_sym_kernel(struct drbg_state *drbg)
{
- int ret = 0;
struct crypto_cipher *tfm;
+ struct crypto_skcipher *sk_tfm;
+ struct skcipher_request *req;
+ unsigned int alignmask;
+ char ctr_name[CRYPTO_MAX_ALG_NAME];
tfm = crypto_alloc_cipher(drbg->core->backend_cra_name, 0, 0);
if (IS_ERR(tfm)) {
@@ -1647,16 +1670,41 @@ static int drbg_init_sym_kernel(struct drbg_state *drbg)
}
BUG_ON(drbg_blocklen(drbg) != crypto_cipher_blocksize(tfm));
drbg->priv_data = tfm;
- return ret;
-}
-static int drbg_fini_sym_kernel(struct drbg_state *drbg)
-{
- struct crypto_cipher *tfm =
- (struct crypto_cipher *)drbg->priv_data;
- if (tfm)
- crypto_free_cipher(tfm);
- drbg->priv_data = NULL;
+ if (snprintf(ctr_name, CRYPTO_MAX_ALG_NAME, "ctr(%s)",
+ drbg->core->backend_cra_name) >= CRYPTO_MAX_ALG_NAME) {
+ drbg_fini_sym_kernel(drbg);
+ return -EINVAL;
+ }
+ sk_tfm = crypto_alloc_skcipher(ctr_name, 0, 0);
+ if (IS_ERR(sk_tfm)) {
+ pr_info("DRBG: could not allocate CTR cipher TFM handle: %s\n",
+ ctr_name);
+ drbg_fini_sym_kernel(drbg);
+ return PTR_ERR(sk_tfm);
+ }
+ drbg->ctr_handle = sk_tfm;
+
+ req = skcipher_request_alloc(sk_tfm, GFP_KERNEL);
+ if (!req) {
+ pr_info("DRBG: could not allocate request queue\n");
+ drbg_fini_sym_kernel(drbg);
+ return PTR_ERR(req);
+ }
+ drbg->ctr_req = req;
+ skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ drbg_skcipher_cb, drbg);
+
+ alignmask = crypto_skcipher_alignmask(sk_tfm);
+ drbg->ctr_null_value_buf = kzalloc(DRBG_CTR_NULL_LEN + alignmask,
+ GFP_KERNEL);
+ if (!drbg->ctr_null_value_buf) {
+ drbg_fini_sym_kernel(drbg);
+ return -ENOMEM;
+ }
+ drbg->ctr_null_value = (u8 *)PTR_ALIGN(drbg->ctr_null_value_buf,
+ alignmask + 1);
+
return 0;
}
@@ -1680,6 +1728,43 @@ static int drbg_kcapi_sym(struct drbg_state *drbg, unsigned char *outval,
crypto_cipher_encrypt_one(tfm, outval, in->buf);
return 0;
}
+
+static int drbg_kcapi_sym_ctr(struct drbg_state *drbg, u8 *outbuf, u32 outlen)
+{
+ struct scatterlist sg_in;
+
+ sg_init_one(&sg_in, drbg->ctr_null_value, DRBG_CTR_NULL_LEN);
+
+ while (outlen) {
+ u32 cryptlen = min_t(u32, outlen, DRBG_CTR_NULL_LEN);
+ struct scatterlist sg_out;
+ int ret;
+
+ sg_init_one(&sg_out, outbuf, cryptlen);
+ skcipher_request_set_crypt(drbg->ctr_req, &sg_in, &sg_out,
+ cryptlen, drbg->V);
+ ret = crypto_skcipher_encrypt(drbg->ctr_req);
+ switch (ret) {
+ case 0:
+ break;
+ case -EINPROGRESS:
+ case -EBUSY:
+ ret = wait_for_completion_interruptible(
+ &drbg->ctr_completion);
+ if (!ret && !drbg->ctr_async_err) {
+ reinit_completion(&drbg->ctr_completion);
+ break;
+ }
+ default:
+ return ret;
+ }
+ init_completion(&drbg->ctr_completion);
+
+ outlen -= cryptlen;
+ }
+
+ return 0;
+}
#endif /* CONFIG_CRYPTO_DRBG_CTR */
/***************************************************************
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index d961b2b..b2fe15d 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -43,6 +43,7 @@
#include <linux/random.h>
#include <linux/scatterlist.h>
#include <crypto/hash.h>
+#include <crypto/skcipher.h>
#include <linux/module.h>
#include <linux/crypto.h>
#include <linux/slab.h>
@@ -115,6 +116,14 @@ struct drbg_state {
/* some memory the DRBG can use for its operation */
unsigned char *scratchpad;
void *priv_data; /* Cipher handle */
+
+ struct crypto_skcipher *ctr_handle; /* CTR mode cipher handle */
+ struct skcipher_request *ctr_req; /* CTR mode request handle */
+ __u8 *ctr_null_value_buf; /* CTR mode unaligned buffer */
+ __u8 *ctr_null_value; /* CTR mode aligned zero buf */
+ struct completion ctr_completion; /* CTR mode async handler */
+ int ctr_async_err; /* CTR mode async error */
+
bool seeded; /* DRBG fully seeded? */
bool pr; /* Prediction resistance enabled? */
struct work_struct seed_work; /* asynchronous seeding support */
--
2.5.5
^ permalink raw reply related
* [PATCH v2 0/4] crypto: CTR DRBG - performance improvements
From: Stephan Mueller @ 2016-06-14 5:33 UTC (permalink / raw)
To: herbert, linux-crypto
Hi,
The following patch set is aimed to increase the performance of the CTR
DRBG, especially when assembler implementations of the CTR AES mode are
available.
The patch set increases the performance by 10% for random numbers of 16 bytes
and reaches 450% for random numbers reaching 4096 bytes (larger random
numbers will even have more performance gains). The performance gains were
measured when using ctr-aes-aesni.
Note, when using the C implementation of the CTR mode (cipher/ctr.c), the
performance of the CTR DRBG is slightly worse than it is now, but still it
is much faster than the Hash or HMAC DRBGs.
The patch set is CAVS tested.
Changes v2:
* the alignment patch is updated to use the alignment of the underlying TFM
Stephan Mueller (4):
crypto: CTR DRBG - use CTR AES instead of ECB AES
crypto: DRBG - use aligned buffers
crypto: CTR DRBG - use full CTR AES for update
crypto: CTR DRBG - avoid duplicate maintenance of key
crypto/Kconfig | 1 +
crypto/drbg.c | 252 +++++++++++++++++++++++++++++++++-----------------
include/crypto/drbg.h | 12 +++
3 files changed, 181 insertions(+), 84 deletions(-)
--
2.5.5
^ permalink raw reply
* Re: [PATCH v6 3/6] crypto: AF_ALG -- add asymmetric cipher interface
From: Stephan Mueller @ 2016-06-14 5:12 UTC (permalink / raw)
To: Andrew Zaborowski
Cc: Mat Martineau, Tadeusz Struk, David Howells, Herbert Xu,
linux-api, marcel, linux-kernel, keyrings,
Linux Crypto Mailing List, David Woodhouse, davem
In-Reply-To: <CAOq732J6J9b0NWuELRs7udiO7mApybfxjFaYX_UVdqHR+9Fvrw@mail.gmail.com>
Am Dienstag, 14. Juni 2016, 00:16:11 schrieb Andrew Zaborowski:
Hi Andrew,
> Hi,
>
> On 8 June 2016 at 21:14, Mat Martineau
>
> <mathew.j.martineau@linux.intel.com> wrote:
> > On Wed, 8 Jun 2016, Stephan Mueller wrote:
> >> What is your concern?
> >
> > Userspace must allocate larger buffers than it knows are necessary for
> > expected results.
> >
> > It looks like the software rsa implementation handles shorter output
> > buffers ok (mpi_write_to_sgl will return EOVERFLOW if the the buffer is
> > too small), however I see at least one hardware rsa driver that requires
> > the output buffer to be the maximum size. But this inconsistency might be
> > best addressed within the software cipher or drivers rather than in
> > recvmsg.
> Should the hardware drivers fix this instead? I've looked at the qat
> and caam drivers, they both require the destination buffer size to be
> the key size and in both cases there would be no penalty for dropping
> this requirement as far as I see. Both do a memmove if the result
> ends up being shorter than key size. In case the caller knows it is
> expecting a specific output size, the driver will have to use a self
> allocated buffer + a memcpy in those same cases where it would later
> use memmove instead. Alternatively the sg passed to dma_map_sg can be
> prepended with a dummy segment the right size to save the memcpy.
>
> akcipher.h only says:
> @dst_len: Size of the output buffer. It needs to be at least as big as
> the expected result depending on the operation
>
> Note that for random input data the memmove will be done about 1 in
> 256 times but with PKCS#1 padding the signature always has a leading
> zero.
>
> Requiring buffers bigger than needed makes the added work of dropping
> the zero bytes from the sglist and potentially re-adding them in the
> client difficult to justify. RSA doing this sets a precedent for a
> future pkcs1pad (or other algorithm) implementation to do the same
> thing and a portable client having to always know the key size and use
> key-sized buffers.
I think we have agreed on dropping the length enforcement at the interface
level.
Ciao
Stephan
^ permalink raw reply
* Re: [PATCH v2 3/3] ARM64: dts: meson-gxbb: Add Hardware Random Generator node
From: Neil Armstrong @ 2016-06-14 4:59 UTC (permalink / raw)
To: Kevin Hilman
Cc: Matt Mackall, Herbert Xu, devicetree, linux-kernel, linux-crypto,
linux-amlogic, linux-arm-kernel
In-Reply-To: <m2ziqoviz0.fsf@baylibre.com>
On 06/14/2016 12:09 AM, Kevin Hilman wrote:
> Hi Neil,
>
> Neil Armstrong <narmstrong@baylibre.com> writes:
>
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>> arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 5 +++++
>> 1 file changed, 5 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
>> index 832815d..8353621 100644
>> --- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
>> +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
>> @@ -167,6 +167,11 @@
>> };
>> };
>>
>> + rng {
>> + compatible = "amlogic,meson-rng";
>> + reg = <0x0 0xc8834000 0x0 0x4>;
>> + };
>
> This should be under the periphs bus, with an offset of 0x0 instead of
> at the top level.
>
> See the for-next branch in the linux-amlogic tree[1] which has separate
> busses for periphs and hiu.
Yes, It was introduced lately.
Herbert,
I'll repost this patch separately to arm-soc directly rebased on [1].
Thanks,
Neil
> Kevin
>
> [1] git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic.git
>
^ permalink raw reply
* Re: [PATCH] crypto : async implementation for sha1-mb
From: Herbert Xu @ 2016-06-14 4:34 UTC (permalink / raw)
To: Dey, Megha
Cc: tim.c.chen@linux.intel.com, davem@davemloft.net,
linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org,
Yu, Fenghua, Megha Dey
In-Reply-To: <C440BA31B54DCD4AAC682D2365C8FEE703CABA2C@ORSMSX111.amr.corp.intel.com>
On Mon, Jun 13, 2016 at 07:10:26PM +0000, Dey, Megha wrote:
>
> > In the current implementation, the inner algorithm is called directly, and we use the outer algorithm's callback. We do not use the callback in inner algorithm. We are actually calling the child functions directly and the child is using the parent's call back function. Probably I can add a comment before the set callback function.. will this be ok?
No this is a hack and you should not do that.
You can of course set the inner request's callback to that of the outer request.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH v6 3/6] crypto: AF_ALG -- add asymmetric cipher interface
From: Andrew Zaborowski @ 2016-06-13 22:16 UTC (permalink / raw)
To: Mat Martineau
Cc: Stephan Mueller, Tadeusz Struk, David Howells, Herbert Xu,
linux-api, marcel, linux-kernel, keyrings,
Linux Crypto Mailing List, David Woodhouse, davem
In-Reply-To: <alpine.OSX.2.20.1606081135160.16651@mjmartin-mac01.local>
Hi,
On 8 June 2016 at 21:14, Mat Martineau
<mathew.j.martineau@linux.intel.com> wrote:
> On Wed, 8 Jun 2016, Stephan Mueller wrote:
>> What is your concern?
> Userspace must allocate larger buffers than it knows are necessary for
> expected results.
>
> It looks like the software rsa implementation handles shorter output buffers
> ok (mpi_write_to_sgl will return EOVERFLOW if the the buffer is too small),
> however I see at least one hardware rsa driver that requires the output
> buffer to be the maximum size. But this inconsistency might be best
> addressed within the software cipher or drivers rather than in recvmsg.
Should the hardware drivers fix this instead? I've looked at the qat
and caam drivers, they both require the destination buffer size to be
the key size and in both cases there would be no penalty for dropping
this requirement as far as I see. Both do a memmove if the result
ends up being shorter than key size. In case the caller knows it is
expecting a specific output size, the driver will have to use a self
allocated buffer + a memcpy in those same cases where it would later
use memmove instead. Alternatively the sg passed to dma_map_sg can be
prepended with a dummy segment the right size to save the memcpy.
akcipher.h only says:
@dst_len: Size of the output buffer. It needs to be at least as big as
the expected result depending on the operation
Note that for random input data the memmove will be done about 1 in
256 times but with PKCS#1 padding the signature always has a leading
zero.
Requiring buffers bigger than needed makes the added work of dropping
the zero bytes from the sglist and potentially re-adding them in the
client difficult to justify. RSA doing this sets a precedent for a
future pkcs1pad (or other algorithm) implementation to do the same
thing and a portable client having to always know the key size and use
key-sized buffers.
Best regards
^ permalink raw reply
* Re: [PATCH v2 0/3] hw_random: Add Amlogic Meson SoCs Random Generator driver
From: Kevin Hilman @ 2016-06-13 22:10 UTC (permalink / raw)
To: Herbert Xu
Cc: Neil Armstrong, linux-crypto, linux-amlogic, linux-kernel,
linux-arm-kernel, Matt Mackall
In-Reply-To: <20160613123109.GA8674@gondor.apana.org.au>
Hi Herbert,
Herbert Xu <herbert@gondor.apana.org.au> writes:
> On Fri, Jun 10, 2016 at 10:21:52AM +0200, Neil Armstrong wrote:
>> Add support for the Amlogic Meson SoCs Hardware Random generator as a hw_random char driver.
>> The generator is a single 32bit wide register.
>> Also adds the Meson GXBB SoC DTSI node and corresponding DT bindings.
>>
>> Changes since v1 at http://lkml.kernel.org/r/1464943621-18278-1-git-send-email-narmstrong@baylibre.com :
>> - change to depend on ARCH_MESON || COMPILE_TEST
>> - check buffer max size in read
>>
>> Neil Armstrong (3):
>> char: hw_random: Add Amlogic Meson Hardware Random Generator
>> dt-bindings: hwrng: Add Amlogic Meson Hardware Random Generator
>> bindings
>> ARM64: dts: meson-gxbb: Add Hardware Random Generator node
>
> All applied. Thanks.
Could you take just the driver please?
Due to lots of other activity in the DT, I'd prefer to send the DT &
bindings though the arm-soc (via the amlogic tree.)
Thanks,
Kevin
^ permalink raw reply
* Re: [PATCH v2 3/3] ARM64: dts: meson-gxbb: Add Hardware Random Generator node
From: Kevin Hilman @ 2016-06-13 22:09 UTC (permalink / raw)
To: Neil Armstrong
Cc: Matt Mackall, Herbert Xu, devicetree, linux-kernel, linux-crypto,
linux-amlogic, linux-arm-kernel
In-Reply-To: <1465546915-24229-4-git-send-email-narmstrong@baylibre.com>
Hi Neil,
Neil Armstrong <narmstrong@baylibre.com> writes:
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
> arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
> index 832815d..8353621 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
> @@ -167,6 +167,11 @@
> };
> };
>
> + rng {
> + compatible = "amlogic,meson-rng";
> + reg = <0x0 0xc8834000 0x0 0x4>;
> + };
This should be under the periphs bus, with an offset of 0x0 instead of
at the top level.
See the for-next branch in the linux-amlogic tree[1] which has separate
busses for periphs and hiu.
Kevin
[1] git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic.git
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox