* Re: [PATCH v6 3/6] crypto: AF_ALG -- add asymmetric cipher interface
From: Stephan Mueller @ 2016-06-09 9:28 UTC (permalink / raw)
To: Mat Martineau
Cc: Tadeusz Struk, dhowells, herbert, linux-api, marcel, linux-kernel,
keyrings, linux-crypto, dwmw2, davem
In-Reply-To: <alpine.OSX.2.20.1606081135160.16651@mjmartin-mac01.local>
Am Mittwoch, 8. Juni 2016, 12:14:49 schrieb Mat Martineau:
Hi Mat,
> On Wed, 8 Jun 2016, Stephan Mueller wrote:
> > Am Dienstag, 7. Juni 2016, 17:28:07 schrieb Mat Martineau:
> >
> > Hi Mat,
> >
> >>> + used = ctx->used;
> >>> +
> >>> + /* convert iovecs of output buffers into scatterlists */
> >>> + while (iov_iter_count(&msg->msg_iter)) {
> >>> + /* make one iovec available as scatterlist */
> >>> + err = af_alg_make_sg(&ctx->rsgl[cnt], &msg->msg_iter,
> >>> + iov_iter_count(&msg->msg_iter));
> >>> + if (err < 0)
> >>> + goto unlock;
> >>> + usedpages += err;
> >>> + /* chain the new scatterlist with previous one */
> >>> + if (cnt)
> >>> + af_alg_link_sg(&ctx->rsgl[cnt - 1], &ctx->rsgl[cnt]);
> >>> +
> >>> + iov_iter_advance(&msg->msg_iter, err);
> >>> + cnt++;
> >>> + }
> >>> +
> >>> + /* ensure output buffer is sufficiently large */
> >>> + if (usedpages < akcipher_calcsize(ctx)) {
> >>> + err = -EMSGSIZE;
> >>> + goto unlock;
> >>> + }
> >>
> >> Why is the size of the output buffer enforced here instead of depending
> >> on
> >> the algorithm implementation?
> >
> > akcipher_calcsize calls crypto_akcipher_maxsize to get the maximum size
> > the
> > algorithm generates as output during its operation.
> >
> > The code ensures that the caller provided at least that amount of memory
> > for the kernel to store its data in. This check therefore is present to
> > ensure the kernel does not overstep memory boundaries in user space.
>
> Yes, it's understood that the userspace buffer length must not be
> exceeded. But dst_len is part of the akcipher_request struct, so why does
> it need to be checked *here* when it is also checked later?
I am always uneasy when the kernel has a user space interface and expects
layers deep down inside the kernel to check for user space related boundaries.
Note, we do not hand the __user flag down, so sparse and other tools cannot
detect whether a particular cipher implementation has the right checks.
I therefore always would like to check parameters at the interface handling
logic. Cryptographers rightly should worry about their code implementing the
cipher correctly. But I do not think that the cipher implementations should
worry about security implications since they may be called from user space.
>
> > 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.
Is your concern that we have a double check check for lengths here? If yes, I
think we can live with an additional if() here.
Or is your concern that the user space interface restricts things too much and
thus prevents a valid use case?
Ciao
Stephan
^ permalink raw reply
* Re: [PATCH v6 3/6] crypto: AF_ALG -- add asymmetric cipher interface
From: Mat Martineau @ 2016-06-09 18:18 UTC (permalink / raw)
To: Stephan Mueller
Cc: Mat Martineau, Tadeusz Struk, dhowells, herbert, linux-api,
marcel, linux-kernel, keyrings, linux-crypto, dwmw2, davem
In-Reply-To: <8115473.hELPVzZyL0@tauon.atsec.com>
On Thu, 9 Jun 2016, Stephan Mueller wrote:
> Am Mittwoch, 8. Juni 2016, 12:14:49 schrieb Mat Martineau:
>
> Hi Mat,
>
>> On Wed, 8 Jun 2016, Stephan Mueller wrote:
>>> Am Dienstag, 7. Juni 2016, 17:28:07 schrieb Mat Martineau:
>>>
>>> Hi Mat,
>>>
>>>>> + used = ctx->used;
>>>>> +
>>>>> + /* convert iovecs of output buffers into scatterlists */
>>>>> + while (iov_iter_count(&msg->msg_iter)) {
>>>>> + /* make one iovec available as scatterlist */
>>>>> + err = af_alg_make_sg(&ctx->rsgl[cnt], &msg->msg_iter,
>>>>> + iov_iter_count(&msg->msg_iter));
>>>>> + if (err < 0)
>>>>> + goto unlock;
>>>>> + usedpages += err;
>>>>> + /* chain the new scatterlist with previous one */
>>>>> + if (cnt)
>>>>> + af_alg_link_sg(&ctx->rsgl[cnt - 1], &ctx->rsgl[cnt]);
>>>>> +
>>>>> + iov_iter_advance(&msg->msg_iter, err);
>>>>> + cnt++;
>>>>> + }
>>>>> +
>>>>> + /* ensure output buffer is sufficiently large */
>>>>> + if (usedpages < akcipher_calcsize(ctx)) {
>>>>> + err = -EMSGSIZE;
>>>>> + goto unlock;
>>>>> + }
>>>>
>>>> Why is the size of the output buffer enforced here instead of
>>>> depending on the algorithm implementation?
>>>
>>> akcipher_calcsize calls crypto_akcipher_maxsize to get the maximum
>>> size the algorithm generates as output during its operation.
>>>
>>> The code ensures that the caller provided at least that amount of memory
>>> for the kernel to store its data in. This check therefore is present to
>>> ensure the kernel does not overstep memory boundaries in user space.
>>
>> Yes, it's understood that the userspace buffer length must not be
>> exceeded. But dst_len is part of the akcipher_request struct, so why does
>> it need to be checked *here* when it is also checked later?
>
> I am always uneasy when the kernel has a user space interface and expects
> layers deep down inside the kernel to check for user space related boundaries.
> Note, we do not hand the __user flag down, so sparse and other tools cannot
> detect whether a particular cipher implementation has the right checks.
>
> I therefore always would like to check parameters at the interface handling
> logic. Cryptographers rightly should worry about their code implementing the
> cipher correctly. But I do not think that the cipher implementations should
> worry about security implications since they may be called from user space.
Userspace or not, buffer lengths need to be strictly checked.
>>
>>> 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.
>
> Is your concern that we have a double check check for lengths here? If yes, I
> think we can live with an additional if() here.
>
> Or is your concern that the user space interface restricts things too much and
> thus prevents a valid use case?
The latter - my primary concern is the constraint this places on userspace
by forcing larger buffer sizes than might be necessary for the operation.
struct akcipher_request has separate members for src_len and dst_len, and
dst_len is documented as needing "to be at least as big as the expected
result depending on the operation". Not the maximum result, the expected
result. It's also documented that the cipher will generate an error if
dst_len is insufficient and update the value with the required size.
I'm updating some userspace TLS code that worked with an earlier, unmerged
patch set for AF_ALG akcipher (from last year). The read calls with
shorter buffers were the main porting problem.
--
Mat Martineau
Intel OTC
^ permalink raw reply
* Re: [PATCH v6 3/6] crypto: AF_ALG -- add asymmetric cipher interface
From: Stephan Mueller @ 2016-06-09 18:24 UTC (permalink / raw)
To: Mat Martineau
Cc: Tadeusz Struk, dhowells, herbert, linux-api, marcel, linux-kernel,
keyrings, linux-crypto, dwmw2, davem
In-Reply-To: <alpine.OSX.2.20.1606091020130.21471@mjmartin-mac01.local>
Am Donnerstag, 9. Juni 2016, 11:18:04 schrieb Mat Martineau:
Hi Mat,
> > Or is your concern that the user space interface restricts things too much
> > and thus prevents a valid use case?
>
> The latter - my primary concern is the constraint this places on userspace
> by forcing larger buffer sizes than might be necessary for the operation.
> struct akcipher_request has separate members for src_len and dst_len, and
> dst_len is documented as needing "to be at least as big as the expected
> result depending on the operation". Not the maximum result, the expected
> result. It's also documented that the cipher will generate an error if
> dst_len is insufficient and update the value with the required size.
>
> I'm updating some userspace TLS code that worked with an earlier, unmerged
> patch set for AF_ALG akcipher (from last year). The read calls with
> shorter buffers were the main porting problem.
I see -- are you proposing to drop that check entirely?
Ciao
Stephan
^ permalink raw reply
* Re: [PATCH v6 3/6] crypto: AF_ALG -- add asymmetric cipher interface
From: Mat Martineau @ 2016-06-09 18:27 UTC (permalink / raw)
To: Stephan Mueller
Cc: Mat Martineau, Tadeusz Struk, dhowells, herbert, linux-api,
marcel, linux-kernel, keyrings, linux-crypto, dwmw2, davem
In-Reply-To: <1499283.NSekfIF0FQ@tauon.atsec.com>
On Thu, 9 Jun 2016, Stephan Mueller wrote:
> Am Donnerstag, 9. Juni 2016, 11:18:04 schrieb Mat Martineau:
>
> Hi Mat,
>
>>> Or is your concern that the user space interface restricts things too much
>>> and thus prevents a valid use case?
>>
>> The latter - my primary concern is the constraint this places on userspace
>> by forcing larger buffer sizes than might be necessary for the operation.
>> struct akcipher_request has separate members for src_len and dst_len, and
>> dst_len is documented as needing "to be at least as big as the expected
>> result depending on the operation". Not the maximum result, the expected
>> result. It's also documented that the cipher will generate an error if
>> dst_len is insufficient and update the value with the required size.
>>
>> I'm updating some userspace TLS code that worked with an earlier, unmerged
>> patch set for AF_ALG akcipher (from last year). The read calls with
>> shorter buffers were the main porting problem.
>
> I see -- are you proposing to drop that check entirely?
Yes.
Best regards,
--
Mat Martineau
Intel OTC
^ permalink raw reply
* Re: [PATCH v6 3/6] crypto: AF_ALG -- add asymmetric cipher interface
From: Stephan Mueller @ 2016-06-09 18:36 UTC (permalink / raw)
To: Mat Martineau, tadeusz.struk-ral2JQCrhuEAvxtiuMwx3w
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: <alpine.OSX.2.20.1606091126420.21471-zaFMaa3cLiZe6KzckbbZvYT4S9po1h25@public.gmane.org>
Am Donnerstag, 9. Juni 2016, 11:27:13 schrieb Mat Martineau:
Hi Mat, Tadeusz,
> On Thu, 9 Jun 2016, Stephan Mueller wrote:
> > Am Donnerstag, 9. Juni 2016, 11:18:04 schrieb Mat Martineau:
> >
> > Hi Mat,
> >
> >>> Or is your concern that the user space interface restricts things too
> >>> much
> >>> and thus prevents a valid use case?
> >>
> >> The latter - my primary concern is the constraint this places on
> >> userspace
> >> by forcing larger buffer sizes than might be necessary for the operation.
> >> struct akcipher_request has separate members for src_len and dst_len, and
> >> dst_len is documented as needing "to be at least as big as the expected
> >> result depending on the operation". Not the maximum result, the expected
> >> result. It's also documented that the cipher will generate an error if
> >> dst_len is insufficient and update the value with the required size.
> >>
> >> I'm updating some userspace TLS code that worked with an earlier,
> >> unmerged
> >> patch set for AF_ALG akcipher (from last year). The read calls with
> >> shorter buffers were the main porting problem.
> >
> > I see -- are you proposing to drop that check entirely?
>
> Yes.
Ok, after checking the code again, I think that dropping that sanity check
should be ok given that this length is part of the akcipher API.
Tadeusz, as you are currently managing that patch set, would you re-spin it
with the following check removed?
+ if (usedpages < akcipher_calcsize(ctx)) {
+ err = -EMSGSIZE;
+ goto unlock;
+ }
Ciao
Stephan
^ permalink raw reply
* [PATCH 3/4] crypto: CTR DRBG - use full CTR AES for update
From: Stephan Mueller @ 2016-06-10 5:57 UTC (permalink / raw)
To: herbert; +Cc: linux-crypto
In-Reply-To: <3932580.AnntHTzK82@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 0ac2f19..6afbce0 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;
@@ -1658,7 +1653,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;
@@ -1734,14 +1728,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 0/4] crypto: CTR DRBG - performance improvements
From: Stephan Mueller @ 2016-06-10 5:55 UTC (permalink / raw)
To: herbert; +Cc: 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.
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 | 233 ++++++++++++++++++++++++++++++++++----------------
include/crypto/drbg.h | 12 +++
3 files changed, 172 insertions(+), 74 deletions(-)
--
2.5.5
^ permalink raw reply
* [PATCH 2/4] crypto: DRBG - use aligned buffers
From: Stephan Mueller @ 2016-06-10 5:56 UTC (permalink / raw)
To: herbert; +Cc: linux-crypto
In-Reply-To: <3932580.AnntHTzK82@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 | 25 +++++++++++++++----------
include/crypto/drbg.h | 3 +++
2 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/crypto/drbg.c b/crypto/drbg.c
index 4ee1a9c..0ac2f19 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;
@@ -1157,6 +1157,8 @@ static inline int drbg_alloc_state(struct drbg_state *drbg)
{
int ret = -ENOMEM;
unsigned int sb_size = 0;
+/* Alignmask which should cover all cipher implementations */
+#define DRBG_ALIGN 8
switch (drbg->core->flags & DRBG_TYPE_MASK) {
#ifdef CONFIG_CRYPTO_DRBG_HMAC
@@ -1179,12 +1181,14 @@ static inline int drbg_alloc_state(struct drbg_state *drbg)
goto err;
}
- drbg->V = kmalloc(drbg_statelen(drbg), GFP_KERNEL);
- if (!drbg->V)
+ drbg->Vbuf = kmalloc(drbg_statelen(drbg) + DRBG_ALIGN, GFP_KERNEL);
+ if (!drbg->Vbuf)
goto err;
- drbg->C = kmalloc(drbg_statelen(drbg), GFP_KERNEL);
- if (!drbg->C)
+ drbg->V = PTR_ALIGN(drbg->Vbuf, DRBG_ALIGN);
+ drbg->Cbuf = kmalloc(drbg_statelen(drbg) + DRBG_ALIGN, GFP_KERNEL);
+ if (!drbg->Cbuf)
goto err;
+ drbg->C = PTR_ALIGN(drbg->Cbuf, DRBG_ALIGN);
/* scratchpad is only generated for CTR and Hash */
if (drbg->core->flags & DRBG_HMAC)
sb_size = 0;
@@ -1198,9 +1202,10 @@ 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)
+ drbg->scratchpadbuf = kzalloc(sb_size + DRBG_ALIGN, GFP_KERNEL);
+ if (!drbg->scratchpadbuf)
goto err;
+ drbg->scratchpad = PTR_ALIGN(drbg->scratchpadbuf, DRBG_ALIGN);
}
return 0;
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 4/4] crypto: CTR DRBG - avoid duplicate maintenance of key
From: Stephan Mueller @ 2016-06-10 5:58 UTC (permalink / raw)
To: herbert; +Cc: linux-crypto
In-Reply-To: <3932580.AnntHTzK82@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 6afbce0..0a7b56f 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 1/4] crypto: CTR DRBG - use CTR AES instead of ECB AES
From: Stephan Mueller @ 2016-06-10 5:56 UTC (permalink / raw)
To: herbert; +Cc: linux-crypto
In-Reply-To: <3932580.AnntHTzK82@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 1/2] crypto: vmx: Fix ABI detection
From: Anton Blanchard @ 2016-06-10 6:47 UTC (permalink / raw)
To: pfsmorigo, benh, paulus, mpe, herbert, davem, strosake
Cc: linux-crypto, linuxppc-dev
From: Anton Blanchard <anton@samba.org>
When calling ppc-xlate.pl, we pass it either linux-ppc64 or
linux-ppc64le. The script however was expecting linux64le, a result
of its OpenSSL origins. This means we aren't obeying the ppc64le
ABIv2 rules.
Fix this by checking for linux-ppc64le.
Fixes: 5ca55738201c ("crypto: vmx - comply with ABIs that specify vrsave as reserved.")
Cc: stable@vger.kernel.org
Signed-off-by: Anton Blanchard <anton@samba.org>
---
drivers/crypto/vmx/ppc-xlate.pl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/crypto/vmx/ppc-xlate.pl b/drivers/crypto/vmx/ppc-xlate.pl
index 9f4994c..b18e67d 100644
--- a/drivers/crypto/vmx/ppc-xlate.pl
+++ b/drivers/crypto/vmx/ppc-xlate.pl
@@ -141,7 +141,7 @@ my $vmr = sub {
# Some ABIs specify vrsave, special-purpose register #256, as reserved
# for system use.
-my $no_vrsave = ($flavour =~ /aix|linux64le/);
+my $no_vrsave = ($flavour =~ /linux-ppc64le/);
my $mtspr = sub {
my ($f,$idx,$ra) = @_;
if ($idx == 256 && $no_vrsave) {
--
2.7.4
^ permalink raw reply related
* [PATCH 2/2] crypto: vmx: Increase priority of aes-cbc cipher
From: Anton Blanchard @ 2016-06-10 6:47 UTC (permalink / raw)
To: pfsmorigo, benh, paulus, mpe, herbert, davem, strosake
Cc: linux-crypto, linuxppc-dev
In-Reply-To: <1465541223-17537-1-git-send-email-anton@ozlabs.org>
From: Anton Blanchard <anton@samba.org>
All of the VMX AES ciphers (AES, AES-CBC and AES-CTR) are set at
priority 1000. Unfortunately this means we never use AES-CBC and
AES-CTR, because the base AES-CBC cipher that is implemented on
top of AES inherits its priority.
To fix this, AES-CBC and AES-CTR have to be a higher priority. Set
them to 2000.
Testing on a POWER8 with:
cryptsetup benchmark --cipher aes --key-size 256
Shows decryption speed increase from 402.4 MB/s to 3069.2 MB/s,
over 7x faster. Thanks to Mike Strosaker for helping me debug
this issue.
Fixes: 8c755ace357c ("crypto: vmx - Adding CBC routines for VMX module")
Cc: stable@vger.kernel.org
Signed-off-by: Anton Blanchard <anton@samba.org>
---
drivers/crypto/vmx/aes_cbc.c | 2 +-
drivers/crypto/vmx/aes_ctr.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/vmx/aes_cbc.c b/drivers/crypto/vmx/aes_cbc.c
index 495577b..94ad5c0 100644
--- a/drivers/crypto/vmx/aes_cbc.c
+++ b/drivers/crypto/vmx/aes_cbc.c
@@ -182,7 +182,7 @@ struct crypto_alg p8_aes_cbc_alg = {
.cra_name = "cbc(aes)",
.cra_driver_name = "p8_aes_cbc",
.cra_module = THIS_MODULE,
- .cra_priority = 1000,
+ .cra_priority = 2000,
.cra_type = &crypto_blkcipher_type,
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | CRYPTO_ALG_NEED_FALLBACK,
.cra_alignmask = 0,
diff --git a/drivers/crypto/vmx/aes_ctr.c b/drivers/crypto/vmx/aes_ctr.c
index 0a3c1b0..38ed10d 100644
--- a/drivers/crypto/vmx/aes_ctr.c
+++ b/drivers/crypto/vmx/aes_ctr.c
@@ -166,7 +166,7 @@ struct crypto_alg p8_aes_ctr_alg = {
.cra_name = "ctr(aes)",
.cra_driver_name = "p8_aes_ctr",
.cra_module = THIS_MODULE,
- .cra_priority = 1000,
+ .cra_priority = 2000,
.cra_type = &crypto_blkcipher_type,
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | CRYPTO_ALG_NEED_FALLBACK,
.cra_alignmask = 0,
--
2.7.4
^ permalink raw reply related
* [PATCH v2 0/3] hw_random: Add Amlogic Meson SoCs Random Generator driver
From: Neil Armstrong @ 2016-06-10 8:21 UTC (permalink / raw)
To: Matt Mackall, Herbert Xu
Cc: Neil Armstrong, linux-arm-kernel, linux-amlogic, linux-kernel,
linux-crypto
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
.../devicetree/bindings/rng/amlogic,meson-rng.txt | 14 +++
arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 5 +
drivers/char/hw_random/Kconfig | 14 +++
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/meson-rng.c | 131 +++++++++++++++++++++
5 files changed, 165 insertions(+)
create mode 100644 Documentation/devicetree/bindings/rng/amlogic,meson-rng.txt
create mode 100644 drivers/char/hw_random/meson-rng.c
--
2.7.0
^ permalink raw reply
* [PATCH v2 2/3] dt-bindings: hwrng: Add Amlogic Meson Hardware Random Generator bindings
From: Neil Armstrong @ 2016-06-10 8:21 UTC (permalink / raw)
To: Matt Mackall, Herbert Xu
Cc: devicetree, Neil Armstrong, linux-kernel, linux-crypto,
linux-amlogic, linux-arm-kernel
In-Reply-To: <1465546915-24229-1-git-send-email-narmstrong@baylibre.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
.../devicetree/bindings/rng/amlogic,meson-rng.txt | 14 ++++++++++++++
1 file changed, 14 insertions(+)
create mode 100644 Documentation/devicetree/bindings/rng/amlogic,meson-rng.txt
diff --git a/Documentation/devicetree/bindings/rng/amlogic,meson-rng.txt b/Documentation/devicetree/bindings/rng/amlogic,meson-rng.txt
new file mode 100644
index 0000000..202f2d0
--- /dev/null
+++ b/Documentation/devicetree/bindings/rng/amlogic,meson-rng.txt
@@ -0,0 +1,14 @@
+Amlogic Meson Random number generator
+=====================================
+
+Required properties:
+
+- compatible : should be "amlogic,meson-rng"
+- reg : Specifies base physical address and size of the registers.
+
+Example:
+
+rng {
+ compatible = "amlogic,meson-rng";
+ reg = <0x0 0xc8834000 0x0 0x4>;
+};
--
2.7.0
^ permalink raw reply related
* [PATCH v2 3/3] ARM64: dts: meson-gxbb: Add Hardware Random Generator node
From: Neil Armstrong @ 2016-06-10 8:21 UTC (permalink / raw)
To: Matt Mackall, Herbert Xu
Cc: Neil Armstrong, linux-arm-kernel, linux-amlogic, linux-kernel,
linux-crypto, devicetree
In-Reply-To: <1465546915-24229-1-git-send-email-narmstrong@baylibre.com>
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>;
+ };
+
apb: apb@d0000000 {
compatible = "simple-bus";
reg = <0x0 0xd0000000 0x0 0x200000>;
--
2.7.0
^ permalink raw reply related
* [PATCH v2 1/3] char: hw_random: Add Amlogic Meson Hardware Random Generator
From: Neil Armstrong @ 2016-06-10 8:21 UTC (permalink / raw)
To: Matt Mackall, Herbert Xu
Cc: Neil Armstrong, linux-arm-kernel, linux-amlogic, linux-kernel,
linux-crypto
In-Reply-To: <1465546915-24229-1-git-send-email-narmstrong@baylibre.com>
Add support for the Amlogic Meson SoCs hardware random generator.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/char/hw_random/Kconfig | 14 ++++
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/meson-rng.c | 131 +++++++++++++++++++++++++++++++++++++
3 files changed, 146 insertions(+)
create mode 100644 drivers/char/hw_random/meson-rng.c
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index ac51149..8558a61 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -396,6 +396,20 @@ config HW_RANDOM_PIC32
If unsure, say Y.
+config HW_RANDOM_MESON
+ tristate "Amlogic Meson Random Number Generator support"
+ depends on HW_RANDOM
+ depends on ARCH_MESON || COMPILE_TEST
+ default y
+ ---help---
+ This driver provides kernel-side support for the Random Number
+ Generator hardware found on Amlogic Meson SoCs.
+
+ To compile this driver as a module, choose M here. the
+ module will be called meson-rng.
+
+ If unsure, say Y.
+
endif # HW_RANDOM
config UML_RANDOM
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 63022b4..04bb0b0 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -34,3 +34,4 @@ obj-$(CONFIG_HW_RANDOM_ST) += st-rng.o
obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o
obj-$(CONFIG_HW_RANDOM_STM32) += stm32-rng.o
obj-$(CONFIG_HW_RANDOM_PIC32) += pic32-rng.o
+obj-$(CONFIG_HW_RANDOM_MESON) += meson-rng.o
diff --git a/drivers/char/hw_random/meson-rng.c b/drivers/char/hw_random/meson-rng.c
new file mode 100644
index 0000000..0cfd81b
--- /dev/null
+++ b/drivers/char/hw_random/meson-rng.c
@@ -0,0 +1,131 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright (c) 2016 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (C) 2014 Amlogic, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * The full GNU General Public License is included in this distribution
+ * in the file called COPYING.
+ *
+ * BSD LICENSE
+ *
+ * Copyright (c) 2016 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (C) 2014 Amlogic, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/hw_random.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/of.h>
+
+#define RNG_DATA 0x00
+
+struct meson_rng_data {
+ void __iomem *base;
+ struct platform_device *pdev;
+ struct hwrng rng;
+};
+
+static int meson_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+{
+ struct meson_rng_data *data =
+ container_of(rng, struct meson_rng_data, rng);
+
+ if (max < sizeof(u32))
+ return 0;
+
+ *(u32 *)buf = readl_relaxed(data->base + RNG_DATA);
+
+ return sizeof(u32);
+}
+
+static int meson_rng_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct meson_rng_data *data;
+ struct resource *res;
+
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->pdev = pdev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ data->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(data->base))
+ return PTR_ERR(data->base);
+
+ data->rng.name = pdev->name;
+ data->rng.read = meson_rng_read;
+
+ platform_set_drvdata(pdev, data);
+
+ return devm_hwrng_register(dev, &data->rng);
+}
+
+static const struct of_device_id meson_rng_of_match[] = {
+ { .compatible = "amlogic,meson-rng", },
+ {},
+};
+
+static struct platform_driver meson_rng_driver = {
+ .probe = meson_rng_probe,
+ .driver = {
+ .name = "meson-rng",
+ .of_match_table = meson_rng_of_match,
+ },
+};
+
+module_platform_driver(meson_rng_driver);
+
+MODULE_ALIAS("platform:meson-rng");
+MODULE_DESCRIPTION("Meson H/W Random Number Generator driver");
+MODULE_AUTHOR("Lawrence Mok <lawrence.mok@amlogic.com>");
+MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_LICENSE("Dual BSD/GPL");
--
2.7.0
^ permalink raw reply related
* Re: [PATCH 23/28] ARM: dts: DRA7: Add DT node for DES IP
From: Tony Lindgren @ 2016-06-10 11:38 UTC (permalink / raw)
To: Tero Kristo
Cc: linux-omap, linux-crypto, herbert, davem, linux-arm-kernel,
lokeshvutla
In-Reply-To: <1464772006-11254-4-git-send-email-t-kristo@ti.com>
* Tero Kristo <t-kristo@ti.com> [160601 02:09]:
> From: Joel Fernandes <joelf@ti.com>
>
> DRA7xx SoCs have a DES3DES IP. Add DT data for the same.
Are these dts changes safe to apply separately or do they
cause issues like extra warnings during boot?
Regards,
Tony
^ permalink raw reply
* Re: [PATCH v6 3/6] crypto: AF_ALG -- add asymmetric cipher interface
From: Tadeusz Struk @ 2016-06-10 14:42 UTC (permalink / raw)
To: Stephan Mueller, Mat Martineau
Cc: dhowells, herbert, linux-api, marcel, linux-kernel, keyrings,
linux-crypto, dwmw2, davem
In-Reply-To: <3072103.TY3EQcF1Bz@tauon.atsec.com>
On 06/09/2016 11:36 AM, Stephan Mueller wrote:
> Am Donnerstag, 9. Juni 2016, 11:27:13 schrieb Mat Martineau:
>
> Hi Mat, Tadeusz,
>
>> On Thu, 9 Jun 2016, Stephan Mueller wrote:
>>> Am Donnerstag, 9. Juni 2016, 11:18:04 schrieb Mat Martineau:
>>>
>>> Hi Mat,
>>>
>>>>> Or is your concern that the user space interface restricts things too
>>>>> much
>>>>> and thus prevents a valid use case?
>>>>
>>>> The latter - my primary concern is the constraint this places on
>>>> userspace
>>>> by forcing larger buffer sizes than might be necessary for the operation.
>>>> struct akcipher_request has separate members for src_len and dst_len, and
>>>> dst_len is documented as needing "to be at least as big as the expected
>>>> result depending on the operation". Not the maximum result, the expected
>>>> result. It's also documented that the cipher will generate an error if
>>>> dst_len is insufficient and update the value with the required size.
>>>>
>>>> I'm updating some userspace TLS code that worked with an earlier,
>>>> unmerged
>>>> patch set for AF_ALG akcipher (from last year). The read calls with
>>>> shorter buffers were the main porting problem.
>>>
>>> I see -- are you proposing to drop that check entirely?
>>
>> Yes.
>
> Ok, after checking the code again, I think that dropping that sanity check
> should be ok given that this length is part of the akcipher API.
>
> Tadeusz, as you are currently managing that patch set, would you re-spin it
> with the following check removed?
>
> + if (usedpages < akcipher_calcsize(ctx)) {
> + err = -EMSGSIZE;
> + goto unlock;
> + }
>
Ok, I'll update the patch.
Thanks,
--
TS
^ permalink raw reply
* Re: [PATCH v3 1/1] crypto: engine: permit to enqueue ashash_request
From: LABBE Corentin @ 2016-06-10 14:43 UTC (permalink / raw)
To: Herbert Xu; +Cc: davem, baolin.wang, linux-crypto, linux-kernel
In-Reply-To: <20160607103139.GA325@gondor.apana.org.au>
On Tue, Jun 07, 2016 at 06:31:39PM +0800, Herbert Xu wrote:
> On Thu, Jun 02, 2016 at 03:13:32PM +0200, LABBE Corentin wrote:
> >
> > static int omap_aes_prepare_req(struct crypto_engine *engine,
> > - struct ablkcipher_request *req)
> > + struct crypto_async_request *areq)
> > {
> > + struct ablkcipher_request *req = ablkcipher_request_cast(areq);
>
> You're still doing casting in the driver.
>
> I want this to be moved into the crypto engine API. There should
> be separate function pointers for each request type.
>
> Thanks,
> --
So I need to split do_one_request to cipher_one_request/hash_one_request.
Same with prepare_request to prepare_hash_request/prepare_cipher_request.
With the choice of each function done in crypto_engine.c.
Since this modification need to add <crypto/hash.h> to algapi.h, I think it is necessary to move all crypto engine stuff to crypto/engine.h
Do you agree ?
Regards
^ permalink raw reply
* Re: [PATCH] crypto: qat: Remove deprecated create_workqueue
From: Tejun Heo @ 2016-06-11 22:46 UTC (permalink / raw)
To: Bhaktipriya Shridhar
Cc: Tadeusz Struk, Herbert Xu, David S. Miller, Julia Lawall,
Conor McLoughlin, Pingchao Yang, Ahsan Atta, John Griffin,
Wu Fengguang, qat-linux, linux-crypto, linux-kernel
In-Reply-To: <20160607211746.GA17667@Karyakshetra>
On Wed, Jun 08, 2016 at 02:47:47AM +0530, Bhaktipriya Shridhar wrote:
> alloc_workqueue replaces deprecated create_workqueue().
>
> The workqueue device_reset_wq has workitem &reset_data->reset_work per
> adf_reset_dev_data. The workqueue pf2vf_resp_wq is a workqueue for
> PF2VF responses has workitem &pf2vf_resp->pf2vf_resp_work per pf2vf_resp.
> The workqueue adf_vf_stop_wq is used to call adf_dev_stop()
> asynchronously.
>
> Dedicated workqueues have been used in all cases since the workitems
> on the workqueues are involved in operation of crypto which can be used in
> the IO path which is depended upon during memory reclaim. Hence,
> WQ_MEM_RECLAIM has been set to gurantee forward progress under memory
> pressure.
> Since there are only a fixed number of work items, explicit concurrency
> limit is unnecessary.
>
> Signed-off-by: Bhaktipriya Shridhar <bhaktipriya96@gmail.com>
Acked-by: Tejun Heo <tj@kernel.org>
Thanks.
--
tejun
^ permalink raw reply
* Re: CTR mode: Kconfig cyclic dependency
From: Herbert Xu @ 2016-06-12 10:58 UTC (permalink / raw)
To: Stephan Mueller; +Cc: linux-crypto
In-Reply-To: <1465466750.NsZ2X8r4WP@positron.chronox.de>
On Thu, Jun 09, 2016 at 11:07:06AM +0200, Stephan Mueller wrote:
>
> during the finalization of my patch set for converting the CTR DRBG over to
> CTR AES, I ran into a Kconfig problem. Maybe you have an idea how to resolve
> it.
Once I finish the skcipher conversion CTR will no longer need SEQIV.
If it's stopping your work right now I think you can just kill the
SEQIV selection by CTR right now since the only user IPsec doesn't
select CTR anyway.
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 v3 1/1] crypto: engine: permit to enqueue ashash_request
From: Herbert Xu @ 2016-06-12 11:01 UTC (permalink / raw)
To: LABBE Corentin; +Cc: davem, baolin.wang, linux-crypto, linux-kernel
In-Reply-To: <20160610144309.GA25816@Red>
On Fri, Jun 10, 2016 at 04:43:09PM +0200, LABBE Corentin wrote:
>
> So I need to split do_one_request to cipher_one_request/hash_one_request.
> Same with prepare_request to prepare_hash_request/prepare_cipher_request.
> With the choice of each function done in crypto_engine.c.
Yes. As a general rule we should make sure that the API exposed
to driver authors is strongly typed so that they don't have to do
casts at all.
> Since this modification need to add <crypto/hash.h> to algapi.h, I think it is necessary to move all crypto engine stuff to crypto/engine.h
> Do you agree ?
That sounds like a good idea.
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: CTR mode: Kconfig cyclic dependency
From: Stephan Mueller @ 2016-06-12 11:05 UTC (permalink / raw)
To: Herbert Xu; +Cc: linux-crypto
In-Reply-To: <20160612105828.GB807@gondor.apana.org.au>
Am Sonntag, 12. Juni 2016, 18:58:28 schrieb Herbert Xu:
Hi Herbert,
> On Thu, Jun 09, 2016 at 11:07:06AM +0200, Stephan Mueller wrote:
> > during the finalization of my patch set for converting the CTR DRBG over
> > to
> > CTR AES, I ran into a Kconfig problem. Maybe you have an idea how to
> > resolve it.
>
> Once I finish the skcipher conversion CTR will no longer need SEQIV.
> If it's stopping your work right now I think you can just kill the
> SEQIV selection by CTR right now since the only user IPsec doesn't
> select CTR anyway.
For now, I use depends on just to ensure a basic consistency. I think I can
wait for your skcipher conversion.
Thanks.
Ciao
Stephan
^ permalink raw reply
* Re: [PATCH] crypto : async implementation for sha1-mb
From: Herbert Xu @ 2016-06-13 8:22 UTC (permalink / raw)
To: Megha Dey
Cc: tim.c.chen, davem, linux-crypto, linux-kernel, fenghua.yu,
Megha Dey
In-Reply-To: <1465323282-2235-1-git-send-email-megha.dey@intel.com>
On Tue, Jun 07, 2016 at 11:14:42AM -0700, Megha Dey wrote:
>
> - desc->tfm = child;
> - desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
> + ahash_request_set_tfm(desc, child);
> + ahash_request_set_callback(desc, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
Why are the callbacks set to NULL/NULL? The child is async so you
should have a valid callback function here.
Instead of continuing to do the broken callback handling outside
of the API (i.e., rctx->complete) please use the API mechanism that
is provided for this purpose.
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 v6 2/8] crypto: add driver-side scomp interface
From: Herbert Xu @ 2016-06-13 8:56 UTC (permalink / raw)
To: Giovanni Cabiddu; +Cc: linux-crypto
In-Reply-To: <1465373818-29720-3-git-send-email-giovanni.cabiddu@intel.com>
On Wed, Jun 08, 2016 at 09:16:52AM +0100, Giovanni Cabiddu wrote:
>
> +static void *scomp_map(struct scatterlist *sg, unsigned int len,
> + gfp_t gfp_flags)
> +{
> + void *buf;
> +
> + if (sg_is_last(sg))
> + return kmap_atomic(sg_page(sg)) + sg->offset;
This doesn't work, because kmap_atomic maps a single page only
bug an SG entry can be a super-page, e.g., a set of contiguous
pages.
> + buf = kmalloc(len, gfp_flags);
The backup path is also very unlikely to work because we'll be
hitting this with 64K sizes and this just won't work with a 4K
page size.
So up until now we've getting around this 64K issue with vmalloc,
and then we try to conserve the precious vmalloc resource by using
per-cpu allocation.
This totally breaks down once you go to DMA, where an SG list is
required. Unfortunately, this means that there is no easy way
to linearise the data for our software implementations.
There is no easy way out I'm afraid. I think we'll have to bite
the bullet and refit our software algos so that they handle SG
lists.
Not only will this solve the problem at hand, it'll also mean that
acomp users will never have to do vmalloc so it's a win-win. It
also means that we won't need the scomp interface at all.
This does bring up another question of who should be allocating the
output memory. Up until now it has been up to the user to do so.
However, if our algos can actually handle SG lists then I think it
should be fairly easy to make them do the allocation instead. What
do you think?
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
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