Linux cryptographic layer development
 help / color / mirror / Atom feed
* Re: [PATCH] CPU Jitter RNG: inclusion into kernel crypto API and /dev/random
From: Stephan Mueller @ 2013-11-05 12:20 UTC (permalink / raw)
  To: Theodore Ts'o; +Cc: Pavel Machek, sandy harris, linux-kernel, linux-crypto
In-Reply-To: <20131103124135.GB32091@thunk.org>

Am Sonntag, 3. November 2013, 07:41:35 schrieb Theodore Ts'o:

Hi Theodore,

>On Sun, Nov 03, 2013 at 08:20:34AM +0100, Stephan Mueller wrote: 
>
>Sandy Harris pointed out a very good paper that I would definitely
>recommend that people read:
>
>http://lwn.net/images/conf/rtlws11/random-hardware.pdf
>
>It basically describes some efforts made in 2009 by folks to do
>exactly the sort of experiments I was advocating.  What I actually

I am wondering whether you have seen my last measurements where I 
effectively performed the tests you were asking for: disabling all 
possible CPU features and selectively enabling them.

The tests described in the above mentioned documents and much more are 
all already in the test suite and test results I present here.

>think is more important, though, is not the doing of the experiments,
>but the development the tools to do these experiments.  If people can
>create kernel modules (and they have to be done in the kernel, since
>you need to be able to disable interrupts, L1 caches, etc., while you
>run these tests), then it will be possible to do these experiments
>each time a new CPU comes out from Intel, or each time an ARM hardware
>vendor comes out with a new ARM SOC.

The test code is available and it is executed in kernel space.
>
>It's important that these tests are done all time, and not, "OK, we

Again, the code is there for the taking, including the analysis part. 
Yes, it can be easily converted into a fully automated test such that at 
the end a result of "CPU shows sufficient variations for the RNG" or 
not.

Therefore, I am asking again:

- Which other CPU mechanisms can I disable that I did not so far?

- The execution time measurements when disabling CPU features show that 
there is still significant variations available. Given the fact that an 
adversary is not able to disable the features as I did, he will not be 
able to reduce the variations induced by the features. He may alter them 
potentially, but there are still variations which he cannot affect, let 
alone predict. Therefore, how shall an adversary make predictions of the 
variations to weaken the RNG?

I heard a nice statement from the developer who implemented the 
/dev/random device of a different, respected operating system: the last 
step to accept the underlying root cause of uncertainty for an RNG 
always requires a leap of faith. Looking at typical noise sources that 
sounds about right. For example:

- how can we be sure that nobody who measures the key stroke interrupts 
can do that with a precision that is higher than the estimated entropy 
the key stroke is awarded (note, an adversary has the means to observe 
key strokes)? Same applies to mouse movements. Note that X11 allows you 
to measure these events precisely (the xev application should give a 
glimpse).

- how can we be sure that fast_pool exhibits no correlation with the 
other noise sources?

- how can we be sure that the HDD fluctuations are random?

We simply accept that these issues do not allow predicting sequences to 
the extent that weakens the RNG.

My goal is to give another seed source to add even more uncertainty into 
the Linux RNG in addition to the existing seed sources. This would also 
support environments that were typically left in the rain so far, such 
as virtual machines, early boot sequences, Live CDs, or headless systems 
without a spinning disk.

Ciao
Stephan

^ permalink raw reply

* Re: [PATCH] CPU Jitter RNG: inclusion into kernel crypto API and /dev/random
From: Stephan Mueller @ 2013-11-05 12:25 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Theodore Ts'o, sandy harris, linux-kernel, linux-crypto
In-Reply-To: <20131103233207.GA5105@amd.pavel.ucw.cz>

Am Montag, 4. November 2013, 00:32:07 schrieb Pavel Machek:

Hi Pavel,

>Hi!
>
>> Another friend of mine mentioned that he assumes the rise and fall
>> times of transistors varies very slightly and could be the main
>> reason for the jitter. I do not think that this is really the case,
>> because our gates that form the CPU instructions comprise of many
>> transistors. The combined raise/fall jitter should cancel each other
>> out.
>
>Plus, there's clock that should make sure that this jitter does not
>matter.
>
>> >There should be way to extract entropy more directly from various
>> >oscillator effects, no?
>> 
>> I am working a different way of measuring such oscillator effects by
>> using the high-resolution timer of the CPU and measure it with a
>> Jiffies-based snapshotting window. So, here I would combine two
>> timers
>> that are differently generated. If their frequencies would be
>> relative
>> prime to each other, we would measure a direct oscillator effect.
>
>I guess main problem is machines that do not have high-resolution
>timer on the CPU (rdtsc). They do not get enough entropy during boot,
>and the hell breaks loose.

That is right. That is also why I try to use the clocksource framework 
if the get_cycles righ-resolution timer is not available.
>
>But they usually _do_ have RTC or other clock, not driven by CPU
>oscilator. Good.
>
>What about just
>
>while (!enough_entropy) {
>      cur_time = read_rtc();
>      simulated_tsc = 0;
>      while (cur_time == read_rtc())
>      	    simulated_tsc++;
>      gain_entropy_from(simulated_tsc)
>}

That is an interesting piece of code -- what would you do in the 
gain_entropy_from function?
>
>(Where enough_entropy should be something like 128 bits).
>
>This should work, we know why it works (drift between rtc and cpu
>clock) and it does _not_ need rdtsc-style fast source.
>
>Disadvantage is that it burns cpu, but, well, you only need 128

That disadvantage should be no problem, because at the time we need 
entropy, burning some CPU cycles are ok. Encryption burns even more CPU 
cycles :-)

>bits. Asuming the rtc used has 100Hz resolution, enough entropy should
>be collected in under 2 seconds. That's acceptable adition to time it
>takes generating ssh keys on slow cpu.
>									
Pavel


Ciao
Stephan

^ permalink raw reply

* Re: [PATCH] CPU Jitter RNG: inclusion into kernel crypto API and /dev/random
From: Stephan Mueller @ 2013-11-05 13:45 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Theodore Ts'o, sandy harris, linux-kernel, linux-crypto
In-Reply-To: <4763730.CsXSbevC1J@tauon>

Am Dienstag, 5. November 2013, 13:25:40 schrieb Stephan Mueller:

Hi Pavel,

>Am Montag, 4. November 2013, 00:32:07 schrieb Pavel Machek:

>>But they usually _do_ have RTC or other clock, not driven by CPU
>>oscilator. Good.
>>
>>What about just
>>
>>while (!enough_entropy) {
>>
>>      cur_time = read_rtc();
>>      simulated_tsc = 0;
>>      while (cur_time == read_rtc())
>>      
>>      	    simulated_tsc++;
>>      
>>      gain_entropy_from(simulated_tsc)
>>
>>}
>
>That is an interesting piece of code -- what would you do in the
>gain_entropy_from function?

Please disregard my question.

I plugged that idea into my current Jitter RNG processing and disabled 
the other jitter measurements to get a clear, isolated picture.

The result is also a white noise! And it is even quite fast.

That means with this approach, even another noise source is available 
that I could combine with the jitter measurements. 

I will have to perform more tests on that noise source. But the smoke 
test is already quite interesting.


Ciao
Stephan

^ permalink raw reply

* Re: [PATCH] CPU Jitter RNG: inclusion into kernel crypto API and /dev/random
From: Stephan Mueller @ 2013-11-06 11:42 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Theodore Ts'o, sandy harris, linux-kernel, linux-crypto
In-Reply-To: <7447932.fADKoNoZRI@tauon>

Am Dienstag, 5. November 2013, 14:45:58 schrieb Stephan Mueller:

Hi Pavel,

>Am Dienstag, 5. November 2013, 13:25:40 schrieb Stephan Mueller:
>
>Hi Pavel,
>
>>Am Montag, 4. November 2013, 00:32:07 schrieb Pavel Machek:
>>>But they usually _do_ have RTC or other clock, not driven by CPU
>>>oscilator. Good.
>>>
>>>What about just
>>>
>>>while (!enough_entropy) {
>>>
>>>      cur_time = read_rtc();
>>>      simulated_tsc = 0;
>>>      while (cur_time == read_rtc())
>>>      
>>>      	    simulated_tsc++;
>>>      
>>>      gain_entropy_from(simulated_tsc)
>>>
>>>}
>>
>>That is an interesting piece of code -- what would you do in the
>>gain_entropy_from function?
>
>Please disregard my question.
>
>I plugged that idea into my current Jitter RNG processing and disabled
>the other jitter measurements to get a clear, isolated picture.
>
>The result is also a white noise! And it is even quite fast.

After doing some more research on this approach, I have to admit that 
the output not good (i.e. white noise) in all situations. Therefore, I 
dropped that (for now).

But thank you very much for your suggestion.

Ciao
Stephan

^ permalink raw reply

* Re: [PATCH] CPU Jitter RNG: inclusion into kernel crypto API and /dev/random
From: Stephan Mueller @ 2013-11-06 11:49 UTC (permalink / raw)
  To: Theodore Ts'o
  Cc: Pavel Machek, sandy harris, linux-kernel, linux-crypto,
	Nicholas Mc Guire
In-Reply-To: <1762585.cs6mj77ady@tauon>

Am Dienstag, 5. November 2013, 13:20:57 schrieb Stephan Mueller:

Hi Ted,

>Am Sonntag, 3. November 2013, 07:41:35 schrieb Theodore Ts'o:
>
>Hi Theodore,
>
>>On Sun, Nov 03, 2013 at 08:20:34AM +0100, Stephan Mueller wrote:
>>
>>Sandy Harris pointed out a very good paper that I would definitely
>>recommend that people read:
>>
>>http://lwn.net/images/conf/rtlws11/random-hardware.pdf
>>
>>It basically describes some efforts made in 2009 by folks to do
>>exactly the sort of experiments I was advocating.  What I actually
>
>I am wondering whether you have seen my last measurements where I
>effectively performed the tests you were asking for: disabling all
>possible CPU features and selectively enabling them.
>
>The tests described in the above mentioned documents and much more are
>all already in the test suite and test results I present here.

After this comment, I got back to one of the authors of the cited paper 
(he is in CC).

Here is a quote from his answer to my question whether he was able to 
identify the root cause:

"its inherent in the microtiming of Hardware and there is nothing you 
can do about it if you want the root cause is quantum physics"

That means, no matter how much CPU support you disable, you will always 
have some jitter -- as I showed in my latest test results in appendix 
F.46 of [1]. This statement is supported by my tests on even 
microkernels which have no other job running than my test application. 
Furthermore, as we see that phenomenon on every tested CPU type on every 
tested operating system with every tested compiler, I am wondering what 
else argument is needed to have this solution considered.

[1] http://www.chronox.de/jent/doc/CPU-Jitter-NPTRNG.html

Ciao
Stephan

^ permalink raw reply

* Re: [PATCH] CPU Jitter RNG: inclusion into kernel crypto API and /dev/random
From: Theodore Ts'o @ 2013-11-06 12:43 UTC (permalink / raw)
  To: Stephan Mueller
  Cc: Pavel Machek, sandy harris, linux-kernel, linux-crypto,
	Nicholas Mc Guire
In-Reply-To: <4306229.ErfOL470s2@tauon>

On Wed, Nov 06, 2013 at 12:49:45PM +0100, Stephan Mueller wrote:
> Here is a quote from his answer to my question whether he was able to 
> identify the root cause:
> 
> "its inherent in the microtiming of Hardware and there is nothing you 
> can do about it if you want the root cause is quantum physics"

That's unfortunate, since it leaves open the question of whether this
jitter is something that could be at least somewhat predictable if you
had a lot more information about the internal works of the CPU or not....

      	       		   	     	      - Ted

^ permalink raw reply

* Re: [PATCH] CPU Jitter RNG: inclusion into kernel crypto API and /dev/random
From: Stephan Mueller @ 2013-11-06 12:51 UTC (permalink / raw)
  To: Theodore Ts'o
  Cc: Pavel Machek, sandy harris, linux-kernel, linux-crypto,
	Nicholas Mc Guire
In-Reply-To: <20131106124354.GJ14235@thunk.org>

Am Mittwoch, 6. November 2013, 07:43:54 schrieb Theodore Ts'o:

Hi Theodore,

>On Wed, Nov 06, 2013 at 12:49:45PM +0100, Stephan Mueller wrote:
>> Here is a quote from his answer to my question whether he was able to
>> identify the root cause:
>> 
>> "its inherent in the microtiming of Hardware and there is nothing you
>> can do about it if you want the root cause is quantum physics"
>
>That's unfortunate, since it leaves open the question of whether this
>jitter is something that could be at least somewhat predictable if you
>had a lot more information about the internal works of the CPU or
>not....

I do not understand that answer: I thought we are talking about the 
search of non-predictable noise sources. If you cannot predict the 
sequence even if you have the state of the CPU, that is what we are 
looking for, is it not?

Besides, how on earth shall an attacker even gain knowledge about the 
state of the CPU or disable CPU mechanisms? Oh, I forgot, your NSA guy. 
But if he is able to do that, all discussions are moot because he simply 
disables any noise sources by flipping a bit, reads the memory that is 
used to hold the state of the RNG or just overwrites the memory 
locations where data is collected, because the general protection 
mechanisms offered by the kernel and the underlying hardware are broken.

Also, does your answer mean you would disregard radioactive decay that 
is not predictable due to quantum physics and Heisenberg?

Ciao
Stephan

^ permalink raw reply

* Re: [PATCH] CPU Jitter RNG: inclusion into kernel crypto API and /dev/random
From: Theodore Ts'o @ 2013-11-06 13:04 UTC (permalink / raw)
  To: Stephan Mueller
  Cc: Pavel Machek, sandy harris, linux-kernel, linux-crypto,
	Nicholas Mc Guire
In-Reply-To: <9172761.DO0L6FkY0c@tauon>

On Wed, Nov 06, 2013 at 01:51:17PM +0100, Stephan Mueller wrote:
> >That's unfortunate, since it leaves open the question of whether this
> >jitter is something that could be at least somewhat predictable if you
> >had a lot more information about the internal works of the CPU or
> >not....
> 
> I do not understand that answer: I thought we are talking about the 
> search of non-predictable noise sources. If you cannot predict the 
> sequence even if you have the state of the CPU, that is what we are 
> looking for, is it not?

I was asking the question about whether someone who knew more about
the internal _workings_ of the CPU, note of the state of the CPU.
This is not necessarily "the NSA guy", but someone who knows more
about the internal workings of the Intel CPU (such as an Intel
engineer --- and I've had Intel express misgivings about approaches
which depend on "CPU jitter" approaches), or just someone who has
spent a lot more time trying to examine the black box of the Intel CPU
from the outside.

I remember making my own home-grown encryption algorithm before I
entered college, secure in my arrogance that I had created something
so complicated that no one could crack it.  Of course, as I got older
and wiser, I realized that it just meant it was just something *I*
couldn't yet anaylze and crack.  The argument "the internal state of
the CPU is sooooo large, and the state transitions ar sooooo complex
that it *must* be unpredictable, because *I* can't predict them" seems
to be a very similar mistake that I made many years ago when I was in
high school.

Of course, some of the state in the CPU may not be unknown to the
attacker, if it is derived by external events that are not visible to
the attacker, such as a network interrupt.  But if that's the case,
why not measure network interrupts directly?  We're much less likely
to overestimate the amount of entropy we can extract the system in
that case.

> Also, does your answer mean you would disregard radioactive decay that 
> is not predictable due to quantum physics and Heisenberg?

No, because that's uncertainty that we can tie to a physical source.
My concern about CPU state is that we haven't yet tied that to a
physical source of entropy, or to exactly what external inputs that
are not available to an external attacker.  We know that quantum
events are not predictable.  We also know that digital circuits in
general are very carefully designed to *be* predictable.

Regards,

						- Ted

^ permalink raw reply

* Re: [PATCH] CPU Jitter RNG: inclusion into kernel crypto API and /dev/random
From: Pavel Machek @ 2013-11-06 13:24 UTC (permalink / raw)
  To: Theodore Ts'o, Stephan Mueller, sandy harris, linux-kernel,
	linux-crypto, Nicholas Mc Guire
In-Reply-To: <20131106130432.GK14235@thunk.org>

Hi!

> Of course, some of the state in the CPU may not be unknown to the
> attacker, if it is derived by external events that are not visible to
> the attacker, such as a network interrupt.  But if that's the case,
> why not measure network interrupts directly?  We're much less likely
> to overestimate the amount of entropy we can extract the system in
> that case.

Actually, I believe Stephan is up to something here.

We _can't_ measure network interrupts directly, because we do not have
TSC. (And TSC-less machines are the ones that are problematic, right?)

Extracting entropy from the CPU will allow us to pick up entropy from
network packets (and timer interrupt jitter) even on machines that
lack TSC. And that counts like very cool feature.

(And yes, we could just increment variable to get tsc emulation in
idle loop, and then extract entropy from that. But we would not be
able to enter low power states at that point, and it would not work
when cpu is busy computing.)

									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply

* Re: [PATCH] CPU Jitter RNG: inclusion into kernel crypto API and /dev/random
From: Pavel Machek @ 2013-11-06 13:26 UTC (permalink / raw)
  To: Stephan Mueller
  Cc: Theodore Ts'o, sandy harris, linux-kernel, linux-crypto
In-Reply-To: <6186307.PQMXWdkvke@tauon>

Hi!

> >I plugged that idea into my current Jitter RNG processing and disabled
> >the other jitter measurements to get a clear, isolated picture.
> >
> >The result is also a white noise! And it is even quite fast.
> 
> After doing some more research on this approach, I have to admit that 
> the output not good (i.e. white noise) in all situations. Therefore, I 
> dropped that (for now).

Is there chance to extract at least some entropy from it? (Can you
post the code you used for testing?) Because in this case we know
where the entropy comes from, which is important for Ted.

Thanks,
							Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply

* Re: [PATCH] CPU Jitter RNG: inclusion into kernel crypto API and /dev/random
From: Nicholas Mc Guire @ 2013-11-07  0:36 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Theodore Ts'o, Stephan Mueller, sandy harris, linux-kernel,
	linux-crypto
In-Reply-To: <20131106132457.GA13852@amd.pavel.ucw.cz>

On Wed, 06 Nov 2013, Pavel Machek wrote:

> Hi!
> 
> > Of course, some of the state in the CPU may not be unknown to the
> > attacker, if it is derived by external events that are not visible to
> > the attacker, such as a network interrupt.  But if that's the case,
> > why not measure network interrupts directly?  We're much less likely
> > to overestimate the amount of entropy we can extract the system in
> > that case.
> 
> Actually, I believe Stephan is up to something here.
> 
> We _can't_ measure network interrupts directly, because we do not have
> TSC. (And TSC-less machines are the ones that are problematic, right?)
>

If you are interested in entropy then there is no need to compare events against timestamps (which are just an event class) you can use any uncorrelated event (the assumption in using timestamps precisely is that they would be uncorrelated). If you are using jitter then the only question is how to extract it and how your
extracter can be assured to be sensitive to time differences that are smaller than what can be impacted by external events. Specifically this also means that no mater how you extract jitter you can not assume it is unbiased and you would need to unbias it (e.g. using Neuman/Peres method) - e.g. look at the jitter distributions in the OSADL QA-Farm - it is clear that they are in none of the cases bias-free.

E.g. practically all systems we looked at the jitter distribution is sensitive to the amount of memory in the box.
 
> Extracting entropy from the CPU will allow us to pick up entropy from
> network packets (and timer interrupt jitter) even on machines that
> lack TSC. And that counts like very cool feature.

if you use external events then I do not see the relation to using CPU inherent non-determinism - why do you want to bind the selectd events to an external and potentially contrtolable event at all ?

> 
> (And yes, we could just increment variable to get tsc emulation in
> idle loop, and then extract entropy from that. But we would not be
> able to enter low power states at that point, and it would not work
> when cpu is busy computing.)
>
there is so much global state information in the kernel that can be
used to harvest entropy I do not see why we would neeed to implement
a dedicated method (counter loop or the like) at all - rather
all that would be needed is an extracter.

Note that using global state though is not directly bound to microtiming (it
might be too complex to systematically scew never the less but that would need tto be demonstrated). The only think that I believe is directly bound to microttiming are race conditions (also not unbiased though).

thx!
hofrat

^ permalink raw reply

* Re: [PATCH] CPU Jitter RNG: inclusion into kernel crypto API and /dev/random
From: Nicholas Mc Guire @ 2013-11-07  1:03 UTC (permalink / raw)
  To: Stephan Mueller
  Cc: Theodore Ts'o, Pavel Machek, sandy harris, linux-kernel,
	linux-crypto
In-Reply-To: <9172761.DO0L6FkY0c@tauon>

[-- Attachment #1: Type: text/plain, Size: 2667 bytes --]

On Wed, 06 Nov 2013, Stephan Mueller wrote:

> Am Mittwoch, 6. November 2013, 07:43:54 schrieb Theodore Ts'o:
> 
> Hi Theodore,
> 
> >On Wed, Nov 06, 2013 at 12:49:45PM +0100, Stephan Mueller wrote:
> >> Here is a quote from his answer to my question whether he was able to
> >> identify the root cause:
> >> 
> >> "its inherent in the microtiming of Hardware and there is nothing you
> >> can do about it if you want the root cause is quantum physics"
> >
> >That's unfortunate, since it leaves open the question of whether this
> >jitter is something that could be at least somewhat predictable if you
> >had a lot more information about the internal works of the CPU or
> >not....
> 
> I do not understand that answer: I thought we are talking about the 
> search of non-predictable noise sources. If you cannot predict the 
> sequence even if you have the state of the CPU, that is what we are 
> looking for, is it not?

unpredictabilitty of the individual event does not imply that you do not have
the ability to "guess" with more than 50% - that is just because it is not 
predictable
does not mean itt is bias-free (and more importantly here that the bias is not 
influenced by controllable factors like load). Attached is a simple 
demonstration of this problem (gauss.c) that runs in user-space and harvestts 
entropy by race occurrence, while the distribution is a nice normal 
distribution (on multticore it is an overlay of multtiple normal 
distributions - one per core-pairing possible) it is not load independent. 
Never the less the individual event (race/no-race) is not predictable.

> 
> Besides, how on earth shall an attacker even gain knowledge about the 
> state of the CPU or disable CPU mechanisms? Oh, I forgot, your NSA guy. 
> But if he is able to do that, all discussions are moot because he simply 
> disables any noise sources by flipping a bit, reads the memory that is 
> used to hold the state of the RNG or just overwrites the memory 
> locations where data is collected, because the general protection 
> mechanisms offered by the kernel and the underlying hardware are broken.

No need to gain knowledge of the internal CPU state itt would be
sufficient to be able to put the CPU in a sub-state-space in which
the distribution is shifted. it may be enough to reduce the truely random
bits of some key only by a few bits to make it suceptible to brute force
attacks.

> 
> Also, does your answer mean you would disregard radioactive decay that 
> is not predictable due to quantum physics and Heisenberg?
>
maybe I missed something - but what does radioactive decay induced 
emission have to do with Heissenberg ? 

thx!
hofrat
 

[-- Attachment #2: gauss.c --]
[-- Type: text/x-csrc, Size: 4360 bytes --]

/* gauss.c: 
 * A complicated way of producing normal distribution plots with a
 * modern CPU by harvesting the intherent randomness.
 *
 * This code is striped of almost all error checking and all argument
 * handling - this is intended to show the prinicple only.
 *
 * compile: gcc -O2 gause.c -o gause -lpthread
 * run: ./gause | tee logfile
 * 
 * be patient - this will take time if you want a smoth curve (hours..days !)
 * once you have a suitably long recording plot the distribution - brute force
 * might be 
 * sort -n logfile | uniq -c > data
 * gnuplot
 * ...
 * gnuplot> plot "data" using 2:1 with lines
 *
 * this will give you a nice gauss cure on all systems - if it does not then
 * your N needs adjusting !
 *
 * The only thing you must adjust to your hardware is N
 * here are some examples 32 bit:
 * AMD Duron UP         : 12000000
 * 32 bit install:
 * AMD Sempron UP       : 5000000
 * Core Duo E7400 SMP   : 100000
 * 64 bit intsll:
 * Intel Nehalem 8 core : 10000
 * Intel CoreDuo 2 Quad : 5000
 *
 * if the runs shows all samples close to 0 then increas N
 * if you get values all samples close to SAMPLES decrease N
 *
 * One could now speculate that this number actually is a metric for the
 * complexity of the CPU...
 *
 * further NUM_THREADS can be adjusted - in general 3 seems to be the best
 * though I have no clue why. Default 2 gives nice curves eventually as well.
 * if you fiddle with NUM_THREADS you also need to re-adjust N.
 *
 * what is this doing ? Its letting a set of threads race on a unprotected
 * global variable cnt - the run of the thread set is equivalent to drawing
 * a ball from an urn of infinetly many read and blue balls. If a race is
 * detected (cnt != N*NUM_THREADS) we assign this the color red, otherwise
 * blue.
 * The claim is that the occurance of red/blue is truely random and as evidence
 * this code produces close to perfect gause curves on and IDLE system. So this
 * is not driven by any peripheral interrupts or the like, in fact on high
 * loads things get a bit distorted... In my opinion this demonstrates that at
 * the core of a modern CPU there is in fact a true entropy source at work :)
 *
 * Copyright Der Herr Hofrat <der.herr@hofr.at> 2009,2010,2011
 * License GPL V2 or later (http://www.gnu.org/copyleft/gpl.html)
 *
 * If you use this code for anything useful I would be happy to here from you !
 *
 * thx!
 * hofrat
 */
#include <pthread.h>	/* pthread_* */
#include <stdio.h>      /* printf,perror,fflush */
#include <stdlib.h>     /* exit */

#define NUM_THREADS 2		/* number of concurrent threas */
volatile long cnt = 0;          /* the global object to race on */
unsigned long SAMPLES=256;	/* how many balls to draw from the urn */
unsigned long NUM_TRIALS=262144;	/* how many samples to draW */
unsigned long N=10000000;	/* some large number - depends on hardware */

void *Thread(void *);

/* This is the ESRNG that emits a ball
 * cnt describes the color of the ball
 */
void * Thread(void *v)
{
	unsigned long n;
	for (n = 1; n <= N; ++n) {
		++cnt;
	}
	return NULL;
}

/* draw the requested sampls from urn 
 * returns number of red balls 
 *
 * Note that return values of pthread_create/join
 * are checked as this would be critical if they failed
 * silent - all "unnecessary" error checking through was
 * removed.
 */
int draw_balls(int *samples){
	int i,n;
	unsigned long red;
	pthread_t t[NUM_THREADS];

	red=0;

	for(i=0;i<*samples;i++){
		cnt=0;

		/* sample the urn */
		for (n = 0; n < NUM_THREADS; ++n){
			if(pthread_create( t+n, NULL, Thread, NULL)){
 				perror("pthread_create");
				exit(-1);
			}
		}
		/* wait for the sample to complete */
		for (n = 0; n < NUM_THREADS; ++n){
			if(pthread_join(t[n],NULL)){
				perror("pthread_join");
				exit(-1);
			}
		}

		/* check the color 
		 * race occurs => red
 		 * no race     => blue
		 */
		if(N*NUM_THREADS - cnt){
		/* count the red */
			red++;
		}
	}
	return red;
}

/* simply get NUM_TRIALS sets of balls from 
 * the urn and print out how many were red 
 * and how many blue - plot this to get a 
 * nice gause curv.
 */
int main(int argc, char **argv)
{
	int i;
	int num_red,num_blue;
	int sample_size=SAMPLES;

	i=0;
	while(i++<NUM_TRIALS){
		num_red=draw_balls(&sample_size);
		num_blue=sample_size-num_red;
		printf("%d %d\n",num_red,num_blue);
		fflush(stdout);
	}
	return 0;
}

^ permalink raw reply

* Re: [PATCH] CPU Jitter RNG: inclusion into kernel crypto API and /dev/random
From: Stephan Mueller @ 2013-11-07  3:12 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Theodore Ts'o, sandy harris, linux-kernel, linux-crypto
In-Reply-To: <20131106132635.GA25971@amd.pavel.ucw.cz>

Am Mittwoch, 6. November 2013, 14:26:35 schrieb Pavel Machek:

Hi Pavel,

>Hi!
>
>> >I plugged that idea into my current Jitter RNG processing and
>> >disabled
>> >the other jitter measurements to get a clear, isolated picture.
>> >
>> >The result is also a white noise! And it is even quite fast.
>> 
>> After doing some more research on this approach, I have to admit that
>> the output not good (i.e. white noise) in all situations. Therefore,
>> I
>> dropped that (for now).
>
>Is there chance to extract at least some entropy from it? (Can you
>post the code you used for testing?) Because in this case we know
>where the entropy comes from, which is important for Ted.

The code is as follows -- it hooks into the framework of the RNG I 
already have, so the code folds the obtained data into one bit (use the 
following function as a drop-in replacement to my RNG code.

static __u64 jent_measure_jitter(struct rand_data *entropy_collector)
{
        __u64 starttime = 0;
        __u64 currtime = 0;
        __u64 counter = 0;
        __u64 data = 0;

        jent_get_ustime(&starttime);
        jent_get_ustime(&currtime);
        while(starttime == currtime)
        {
                jent_get_ustime(&currtime);
                counter++;
        }
        jent_fold_time(counter, &data, 1);
        return data;
}

Consider the following in addition:

static inline void jent_get_ustime(__u64 *out)
{
        __u64 tmp = 0;
        struct timeval time;
        if(gettimeofday(&time, NULL) == 0)
                tmp = time.tv_usec;
        *out = tmp;
}

For the kernel land, I implemented jent_get_ustime to be identical to 
do_gettimeofday().

The result is the following on my i7 2nd gen without using the Von-
Neumann unbias operation:

- user space: looks like good white noise based on the results of ent 
(Chi square, etc). When I print out the counter variable above and 
calculate the Shannon Entropy, I get about 1.5 bits, so we have 
variations. But when you look at the data manually, you see quite some 
streaks that alternate between two values. Here is an example:

4
6
10
2
3
2
3
4
4
4
4
4
5
3
4
5
4
4
4
5
4
4
5
4
4
5
4
4
5
4
4
5
4
4
4
5
4
4


- kernel space: the resulting binary string is not very good: the chi 
square is very bad. Moreover, the resulting data string is slightly 
skewed. The reason is simple by looking at the counter value which I 
obtained with another debugfs file: there are very very long streaks of 
the same or alternating values.

So, I guess you may get some entropy, but I am not sure how much.

Also, when I enlarge the timer value to look something like that:

        if(gettimeofday(&time, NULL) == 0)
                tmp = time.tv_usec>>3;

the counter value is not getting really better, it is still alternating 
between two or three values.


>
>Thanks,
>							Pavel


Ciao
Stephan

^ permalink raw reply

* Re: [PATCH] CPU Jitter RNG: inclusion into kernel crypto API and /dev/random
From: Stephan Mueller @ 2013-11-07  5:21 UTC (permalink / raw)
  To: Theodore Ts'o
  Cc: Pavel Machek, sandy harris, linux-kernel, linux-crypto,
	Nicholas Mc Guire
In-Reply-To: <20131106130432.GK14235@thunk.org>

Am Mittwoch, 6. November 2013, 08:04:32 schrieb Theodore Ts'o:

Hi Theodore,

>On Wed, Nov 06, 2013 at 01:51:17PM +0100, Stephan Mueller wrote:
>> >That's unfortunate, since it leaves open the question of whether
>> >this
>> >jitter is something that could be at least somewhat predictable if
>> >you
>> >had a lot more information about the internal works of the CPU or
>> >not....
>> 
>> I do not understand that answer: I thought we are talking about the
>> search of non-predictable noise sources. If you cannot predict the
>> sequence even if you have the state of the CPU, that is what we are
>> looking for, is it not?
>
>I was asking the question about whether someone who knew more about
>the internal _workings_ of the CPU, note of the state of the CPU.
>This is not necessarily "the NSA guy", but someone who knows more
>about the internal workings of the Intel CPU (such as an Intel
>engineer --- and I've had Intel express misgivings about approaches
>which depend on "CPU jitter" approaches), or just someone who has
>spent a lot more time trying to examine the black box of the Intel CPU
>from the outside.

I try to get more information from my contacts to other vendors. But I 
am wondering what shall we do if the answer is (maybe even proven with 
some test results) that they see the same issue themselves and have no 
handle on it?

I mean, what is it that I would need to test and demonstrate to prove or 
disprove my RNG? We can certainly test very much, but one thing we 
cannot prove, and that is the fundamental jitter, provided it is a 
result of quantum fluctuations. Just as with any other noise source, 
basic fundamental principles are hard if not impossible to test.

I would again like to stress the fact that we see the root cause to a 
similar degree on all major CPUs that we have around us. All of these 
CPUs work differently and yet they show a common behavior, the execution 
time variations. I wonder whether this is already a good indication 
>
>I remember making my own home-grown encryption algorithm before I
>entered college, secure in my arrogance that I had created something
>so complicated that no one could crack it.  Of course, as I got older
>and wiser, I realized that it just meant it was just something *I*
>couldn't yet anaylze and crack.  The argument "the internal state of
>the CPU is sooooo large, and the state transitions ar sooooo complex
>that it *must* be unpredictable, because *I* can't predict them" seems
>to be a very similar mistake that I made many years ago when I was in
>high school.

Agreed, I do not want to state that nobody is able to obtain the state 
(especially considering that the CPUs *must* have some hardware 
debugging hooks somewhere that should allow dumping out the current 
state of the entire CPU to aid CPU development). However, we also have 
to consider our threat model: to me, an attacker can only reside in user 
state of the CPU. All that he can observe there can be used against us. 
Anything that he can only do when in supervisor state is not of 
interest, because gathering and maintaining entropy is the least of our 
worries in this case.
>
>Of course, some of the state in the CPU may not be unknown to the
>attacker, if it is derived by external events that are not visible to
>the attacker, such as a network interrupt.  But if that's the case,
>why not measure network interrupts directly?  We're much less likely
>to overestimate the amount of entropy we can extract the system in
>that case.

To aid that discussion, let us assume that the variations are solely 
based on the CPU state (which indications show that this is not the 
case). When you focus on only the interrupts (or only one interrupt for 
that matter) we limit the base from which we try to obtain entropy.

If you are concerned about the entropy level we add with the proposed 
jitter RNG, what about the following:

- when mixing in bits from the jitter RNG into the entropy pools of 
random.c, we increase the entropy estimator not by the equivalent amount 
of bits, but some fraction. For example:

...
ret = jent_read_entropy(&r->entropy_collector, rand, JENTBLOCKSIZE);
...
_mix_pool_bytes(r, rand, ret, NULL);
credit_entropy_bits(r, (ret * 8) / 2);

This code would only increase the entropy estimator by half of the 
obtained bits

- The jitter RNG allows specifying an oversampling rate where it 
oversamples the jitter by multiples of the given value. The default is 1 
(i.e. no oversampling). But we could set it to 2 (double oversampling). 
The code is here:

r->entropy_collector.osr = 1;

Ciao
Stephan

^ permalink raw reply

* Re: [PATCH] CPU Jitter RNG: inclusion into kernel crypto API and /dev/random
From: Stephan Mueller @ 2013-11-07  5:26 UTC (permalink / raw)
  To: Nicholas Mc Guire
  Cc: Theodore Ts'o, Pavel Machek, sandy harris, linux-kernel,
	linux-crypto
In-Reply-To: <20131107010357.GC1950@opentech.at>

Am Donnerstag, 7. November 2013, 02:03:57 schrieb Nicholas Mc Guire:

Hi Nicholas,

>On Wed, 06 Nov 2013, Stephan Mueller wrote:
>> Am Mittwoch, 6. November 2013, 07:43:54 schrieb Theodore Ts'o:
>> 
>> Hi Theodore,
>> 
>> >On Wed, Nov 06, 2013 at 12:49:45PM +0100, Stephan Mueller wrote:
>> >> Here is a quote from his answer to my question whether he was able
>> >> to
>> >> identify the root cause:
>> >> 
>> >> "its inherent in the microtiming of Hardware and there is nothing
>> >> you
>> >> can do about it if you want the root cause is quantum physics"
>> >
>> >That's unfortunate, since it leaves open the question of whether
>> >this
>> >jitter is something that could be at least somewhat predictable if
>> >you
>> >had a lot more information about the internal works of the CPU or
>> >not....
>> 
>> I do not understand that answer: I thought we are talking about the
>> search of non-predictable noise sources. If you cannot predict the
>> sequence even if you have the state of the CPU, that is what we are
>> looking for, is it not?
>
>unpredictabilitty of the individual event does not imply that you do
>not have the ability to "guess" with more than 50% - that is just
>because it is not predictable
>does not mean itt is bias-free (and more importantly here that the bias
>is not influenced by controllable factors like load). Attached is a
>simple demonstration of this problem (gauss.c) that runs in user-space
>and harvestts entropy by race occurrence, while the distribution is a
>nice normal distribution (on multticore it is an overlay of multtiple
>normal distributions - one per core-pairing possible) it is not load
>independent. Never the less the individual event (race/no-race) is not
>predictable.

Thank you for sharing your ideas and code.

There is one deviation of my RNG from your considerations. My RNG is not 
around race contention (i.e. your software-based uncertainty) but a 
simple measurement of how long some instruction take to execute.

So, how can I induce skews? By trying to disable CPU logic or fudge with 
the CPU support (like cache attacks, etc). My tests have shown that 
disabling some CPU logic may diminish timing variations, but they are 
still sufficiently large to support the RNG.

So, when we already have variations that are sufficient (i.e. the 
entropy is sufficient), using the CPU features that initially have been 
disabled but are now added on top of an already sufficient set of 
variations cannot diminish the entropy that is already present. Even 
when we assume we have full control over the CPU features, I do not see 
a way how we can use these features to cancel already existing 
variations out.

Or do you have an idea how that can be established? Note, we all must 
assume that an attacker is only in user state. Anything else is 
meaningless.

>> Besides, how on earth shall an attacker even gain knowledge about the
>> state of the CPU or disable CPU mechanisms? Oh, I forgot, your NSA
>> guy. But if he is able to do that, all discussions are moot because
>> he simply disables any noise sources by flipping a bit, reads the
>> memory that is used to hold the state of the RNG or just overwrites
>> the memory locations where data is collected, because the general
>> protection mechanisms offered by the kernel and the underlying
>> hardware are broken.
>No need to gain knowledge of the internal CPU state itt would be
>sufficient to be able to put the CPU in a sub-state-space in which
>the distribution is shifted. it may be enough to reduce the truely
>random bits of some key only by a few bits to make it suceptible to
>brute force attacks.

Note, the proposed RNG contains an unbias operation (the Von-Neumann 
unbiaser) which is proven to remove any bias when it is established that 
the individual observations are independent. And the way the 
observations are generated ensures that they are independent. Thus, a 
skew should not be a concern here.

Ciao
Stephan

^ permalink raw reply

* Crypto Update for 3.13
From: Herbert Xu @ 2013-11-07  8:01 UTC (permalink / raw)
  To: Linus Torvalds, David S. Miller, Linux Kernel Mailing List,
	Linux Crypto Mailing List
In-Reply-To: <20130907035544.GA22658@gondor.apana.org.au>

Hi Linus:

Here is the crypto update for 3.13:

* Made x86 ablk_helper generic for ARM.
* Phase out chainiv in favour of eseqiv (affects IPsec).
* Fixed aes-cbc IV corruption on s390.
* Added constant-time crypto_memneq which replaces memcmp.

* Fixed aes-ctr in omap-aes.
* Added OMAP3 ROM RNG support.
* Add PRNG support for MSM SoC's
* Add and use Job Ring API in caam.

* Misc fixes.


Please pull from

git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6.git



Alex Porosanu (7):
      crypto: caam - fix RNG state handle instantiation descriptor
      crypto: caam - fix hash, alg and rng registration if CAAM driver not initialized
      crypto: caam - fix RNG4 instantiation
      crypto: caam - split RNG4 instantiation function
      crypto: caam - uninstantiate RNG state handle 0 if instantiated by caam driver
      crypto: caam - fix RNG4 AAI defines
      crypto: caam - enable instantiation of all RNG4 state handles

Ard Biesheuvel (2):
      crypto: create generic version of ablk_helper
      crypto: move x86 to the generic version of ablk_helper

Ben Hutchings (1):
      hwrng: via-rng - Mark device ID table as __maybe_unused

Fabio Estevam (4):
      crypto: dcp - Use devm_ioremap_resource()
      crypto: dcp - Use devm_request_irq()
      crypto: dcp - Fix the path for releasing the resources
      crypto: dcp - Check the return value from devm_ioremap_resource()

Herbert Xu (2):
      crypto: skcipher - Use eseqiv even on UP machines
      crypto: s390 - Fix aes-cbc IV corruption

James Yonan (1):
      crypto: crypto_memneq - add equality testing of memory regions w/o timing leaks

Joel Fernandes (1):
      crypto: omap-aes - Fix CTR mode counter length

Joni Lapilainen (1):
      crypto: omap-sham - Add missing modalias

Jussi Kivilinna (2):
      crypto: sha256_ssse3 - use correct module alias for sha224
      crypto: x86 - restore avx2_supported check

Linus Walleij (1):
      crypto: tegra - use kernel entropy instead of ad-hoc

Mathias Krause (6):
      crypto: authenc - Export key parsing helper function
      crypto: authencesn - Simplify key parsing
      crypto: ixp4xx - Simplify and harden key parsing
      crypto: picoxcell - Simplify and harden key parsing
      crypto: talitos - Simplify key parsing
      padata: make the sequence counter an atomic_t

Michael Ellerman (2):
      hwrng: pseries - Use KBUILD_MODNAME in pseries-rng.c
      hwrng: pseries - Return errors to upper levels in pseries-rng.c

Michael Opdenacker (1):
      crypto: mv_cesa: remove deprecated IRQF_DISABLED

Neil Horman (1):
      crypto: ansi_cprng - Fix off by one error in non-block size request

Oliver Neukum (1):
      crypto: sha256_ssse3 - also test for BMI2

Pali Rohár (1):
      hwrng: OMAP3 ROM Random Number Generator support

Ruchika Gupta (3):
      crypto: caam - Add Platform driver for Job Ring
      crypto: caam - Add API's to allocate/free Job Rings
      crypto: caam - Modify the interface layers to use JR API's

Sachin Kamat (7):
      crypto: mv_cesa - Staticize local symbols
      crypto: omap-aes - Staticize local symbols
      crypto: tegra-aes - Staticize tegra_aes_cra_exit
      crypto: tegra-aes - Fix NULL pointer dereference
      crypto: tegra-aes - Use devm_clk_get
      crypto: sahara - Remove redundant of_match_ptr
      crypto: mv_cesa - Remove redundant of_match_ptr

Stanimir Varbanov (2):
      ARM: DT: msm: Add Qualcomm's PRNG driver binding document
      hwrng: msm - Add PRNG support for MSM SoC's

Stephen Warren (1):
      ARM: tegra: remove tegra_chip_uid()

Yashpal Dutta (1):
      crypto: caam - map src buffer before access

kbuild test robot (1):
      crypto: ablk_helper - Replace memcpy with struct assignment

 .../devicetree/bindings/rng/qcom,prng.txt          |   17 +
 arch/arm/mach-tegra/fuse.c                         |   10 -
 arch/s390/crypto/aes_s390.c                        |   19 +-
 arch/x86/crypto/Makefile                           |    3 +-
 arch/x86/crypto/aesni-intel_glue.c                 |    2 +-
 arch/x86/crypto/camellia_aesni_avx2_glue.c         |    2 +-
 arch/x86/crypto/camellia_aesni_avx_glue.c          |    2 +-
 arch/x86/crypto/cast5_avx_glue.c                   |    2 +-
 arch/x86/crypto/cast6_avx_glue.c                   |    2 +-
 arch/x86/crypto/serpent_avx2_glue.c                |    2 +-
 arch/x86/crypto/serpent_avx_glue.c                 |    2 +-
 arch/x86/crypto/serpent_sse2_glue.c                |    2 +-
 arch/x86/crypto/sha256_ssse3_glue.c                |    4 +-
 arch/x86/crypto/twofish_avx_glue.c                 |    2 +-
 arch/x86/include/asm/simd.h                        |   11 +
 crypto/Kconfig                                     |   23 +-
 crypto/Makefile                                    |    8 +-
 {arch/x86/crypto => crypto}/ablk_helper.c          |   13 +-
 crypto/ablkcipher.c                                |   21 +-
 crypto/ansi_cprng.c                                |    4 +-
 crypto/asymmetric_keys/rsa.c                       |    5 +-
 crypto/authenc.c                                   |   54 ++-
 crypto/authencesn.c                                |   34 +--
 crypto/ccm.c                                       |    4 +-
 crypto/gcm.c                                       |    2 +-
 crypto/memneq.c                                    |  138 +++++++
 drivers/char/hw_random/Kconfig                     |   25 ++
 drivers/char/hw_random/Makefile                    |    2 +
 drivers/char/hw_random/msm-rng.c                   |  197 +++++++++
 drivers/char/hw_random/omap3-rom-rng.c             |  141 +++++++
 drivers/char/hw_random/pseries-rng.c               |   19 +-
 drivers/char/hw_random/via-rng.c                   |    2 +-
 drivers/crypto/caam/Kconfig                        |   25 +-
 drivers/crypto/caam/Makefile                       |    4 +-
 drivers/crypto/caam/caamalg.c                      |   83 +---
 drivers/crypto/caam/caamhash.c                     |   88 ++---
 drivers/crypto/caam/caamrng.c                      |   29 +-
 drivers/crypto/caam/ctrl.c                         |  418 ++++++++++++++++----
 drivers/crypto/caam/desc.h                         |   17 +-
 drivers/crypto/caam/intern.h                       |   20 +-
 drivers/crypto/caam/jr.c                           |  339 +++++++++++-----
 drivers/crypto/caam/jr.h                           |    5 +-
 drivers/crypto/caam/regs.h                         |   14 +-
 drivers/crypto/caam/sg_sw_sec4.h                   |   34 ++-
 drivers/crypto/dcp.c                               |   49 +--
 drivers/crypto/ixp4xx_crypto.c                     |   26 +-
 drivers/crypto/mv_cesa.c                           |   14 +-
 drivers/crypto/omap-aes.c                          |    6 +-
 drivers/crypto/omap-sham.c                         |    1 +
 drivers/crypto/picoxcell_crypto.c                  |   32 +--
 drivers/crypto/sahara.c                            |    2 +-
 drivers/crypto/talitos.c                           |   35 +--
 drivers/crypto/tegra-aes.c                         |   26 +-
 include/asm-generic/simd.h                         |   14 +
 .../include/asm => include}/crypto/ablk_helper.h   |    0
 include/crypto/algapi.h                            |   18 +-
 include/crypto/authenc.h                           |   12 +-
 include/linux/padata.h                             |    3 +-
 kernel/padata.c                                    |    9 +-
 59 files changed, 1454 insertions(+), 643 deletions(-)

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

* [PATCH RESEND 1/7] ARM: at91/dt/trivial: use macro for AES irq type
From: Nicolas Ferre @ 2013-11-08 15:08 UTC (permalink / raw)
  To: linux-arm-kernel, herbert, linux-crypto; +Cc: linux-kernel, eric, Nicolas Ferre
In-Reply-To: <cover.1383922546.git.nicolas.ferre@atmel.com>

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 arch/arm/boot/dts/sama5d3.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi
index b7f4961..fca56c7 100644
--- a/arch/arm/boot/dts/sama5d3.dtsi
+++ b/arch/arm/boot/dts/sama5d3.dtsi
@@ -359,7 +359,7 @@
 			aes@f8038000 {
 				compatible = "atmel,sam9g46-aes";
 				reg = <0xf8038000 0x100>;
-				interrupts = <43 4 0>;
+				interrupts = <43 IRQ_TYPE_LEVEL_HIGH 0>;
 			};
 
 			tdes@f803c000 {
-- 
1.8.2.2

^ permalink raw reply related

* [PATCH RESEND 6/7] crypto: atmel-sha - add support for Device Tree
From: Nicolas Ferre @ 2013-11-08 15:08 UTC (permalink / raw)
  To: linux-arm-kernel, herbert, linux-crypto; +Cc: linux-kernel, eric, Nicolas Ferre
In-Reply-To: <cover.1383922546.git.nicolas.ferre@atmel.com>

Add support for Device Tree and use of the DMA DT API to
get the channels if needed.
Documentation is added for these DT nodes.

Initial code by: Nicolas Royer and Eukrea.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 .../devicetree/bindings/crypto/atmel-crypto.txt    | 22 +++++
 drivers/crypto/atmel-sha.c                         | 99 ++++++++++++++++------
 2 files changed, 97 insertions(+), 24 deletions(-)

diff --git a/Documentation/devicetree/bindings/crypto/atmel-crypto.txt b/Documentation/devicetree/bindings/crypto/atmel-crypto.txt
index 9a24fd9..f2aab3d 100644
--- a/Documentation/devicetree/bindings/crypto/atmel-crypto.txt
+++ b/Documentation/devicetree/bindings/crypto/atmel-crypto.txt
@@ -44,3 +44,25 @@ tdes@f803c000 {
 	       <&dma1 2 21>;
 	dma-names = "tx", "rx";
 };
+
+* Secure Hash Algorithm (SHA)
+
+Required properties:
+- compatible : Should be "atmel,at91sam9g46-sha".
+- reg: Should contain SHA registers location and length.
+- interrupts: Should contain the IRQ line for the SHA.
+
+Optional properties:
+- dmas: One DMA specifiers as described in
+        atmel-dma.txt and dma.txt files.
+- dma-names: Contains one identifier string for each DMA specifier
+             in the dmas property. Only one "tx" string needed.
+
+Example:
+sha@f8034000 {
+	compatible = "atmel,at91sam9g46-sha";
+	reg = <0xf8034000 0x100>;
+	interrupts = <42 4 0>;
+	dmas = <&dma1 2 17>;
+	dma-names = "tx";
+};
diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c
index eaed8bf..ecfdf72 100644
--- a/drivers/crypto/atmel-sha.c
+++ b/drivers/crypto/atmel-sha.c
@@ -30,6 +30,7 @@
 #include <linux/irq.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
+#include <linux/of_device.h>
 #include <linux/delay.h>
 #include <linux/crypto.h>
 #include <linux/cryptohash.h>
@@ -1263,32 +1264,29 @@ static int atmel_sha_dma_init(struct atmel_sha_dev *dd,
 	int err = -ENOMEM;
 	dma_cap_mask_t mask_in;
 
-	if (pdata && pdata->dma_slave->rxdata.dma_dev) {
-		/* Try to grab DMA channel */
-		dma_cap_zero(mask_in);
-		dma_cap_set(DMA_SLAVE, mask_in);
+	/* Try to grab DMA channel */
+	dma_cap_zero(mask_in);
+	dma_cap_set(DMA_SLAVE, mask_in);
 
-		dd->dma_lch_in.chan = dma_request_channel(mask_in,
-				atmel_sha_filter, &pdata->dma_slave->rxdata);
-
-		if (!dd->dma_lch_in.chan)
-			return err;
-
-		dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV;
-		dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base +
-			SHA_REG_DIN(0);
-		dd->dma_lch_in.dma_conf.src_maxburst = 1;
-		dd->dma_lch_in.dma_conf.src_addr_width =
-			DMA_SLAVE_BUSWIDTH_4_BYTES;
-		dd->dma_lch_in.dma_conf.dst_maxburst = 1;
-		dd->dma_lch_in.dma_conf.dst_addr_width =
-			DMA_SLAVE_BUSWIDTH_4_BYTES;
-		dd->dma_lch_in.dma_conf.device_fc = false;
-
-		return 0;
+	dd->dma_lch_in.chan = dma_request_slave_channel_compat(mask_in,
+			atmel_sha_filter, &pdata->dma_slave->rxdata, dd->dev, "tx");
+	if (!dd->dma_lch_in.chan) {
+		dev_warn(dd->dev, "no DMA channel available\n");
+		return err;
 	}
 
-	return -ENODEV;
+	dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV;
+	dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base +
+		SHA_REG_DIN(0);
+	dd->dma_lch_in.dma_conf.src_maxburst = 1;
+	dd->dma_lch_in.dma_conf.src_addr_width =
+		DMA_SLAVE_BUSWIDTH_4_BYTES;
+	dd->dma_lch_in.dma_conf.dst_maxburst = 1;
+	dd->dma_lch_in.dma_conf.dst_addr_width =
+		DMA_SLAVE_BUSWIDTH_4_BYTES;
+	dd->dma_lch_in.dma_conf.device_fc = false;
+
+	return 0;
 }
 
 static void atmel_sha_dma_cleanup(struct atmel_sha_dev *dd)
@@ -1326,6 +1324,48 @@ static void atmel_sha_get_cap(struct atmel_sha_dev *dd)
 	}
 }
 
+#if defined(CONFIG_OF)
+static const struct of_device_id atmel_sha_dt_ids[] = {
+	{ .compatible = "atmel,at91sam9g46-sha" },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, atmel_sha_dt_ids);
+
+static struct crypto_platform_data *atmel_sha_of_init(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct crypto_platform_data *pdata;
+
+	if (!np) {
+		dev_err(&pdev->dev, "device node not found\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(&pdev->dev, "could not allocate memory for pdata\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	pdata->dma_slave = devm_kzalloc(&pdev->dev,
+					sizeof(*(pdata->dma_slave)),
+					GFP_KERNEL);
+	if (!pdata->dma_slave) {
+		dev_err(&pdev->dev, "could not allocate memory for dma_slave\n");
+		devm_kfree(&pdev->dev, pdata);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	return pdata;
+}
+#else /* CONFIG_OF */
+static inline struct crypto_platform_data *atmel_sha_of_init(struct platform_device *dev)
+{
+	return ERR_PTR(-EINVAL);
+}
+#endif
+
 static int atmel_sha_probe(struct platform_device *pdev)
 {
 	struct atmel_sha_dev *sha_dd;
@@ -1402,13 +1442,23 @@ static int atmel_sha_probe(struct platform_device *pdev)
 	if (sha_dd->caps.has_dma) {
 		pdata = pdev->dev.platform_data;
 		if (!pdata) {
-			dev_err(&pdev->dev, "platform data not available\n");
+			pdata = atmel_sha_of_init(pdev);
+			if (IS_ERR(pdata)) {
+				dev_err(&pdev->dev, "platform data not available\n");
+				err = PTR_ERR(pdata);
+				goto err_pdata;
+			}
+		}
+		if (!pdata->dma_slave) {
 			err = -ENXIO;
 			goto err_pdata;
 		}
 		err = atmel_sha_dma_init(sha_dd, pdata);
 		if (err)
 			goto err_sha_dma;
+
+		dev_info(dev, "using %s for DMA transfers\n",
+				dma_chan_name(sha_dd->dma_lch_in.chan));
 	}
 
 	spin_lock(&atmel_sha.lock);
@@ -1483,6 +1533,7 @@ static struct platform_driver atmel_sha_driver = {
 	.driver		= {
 		.name	= "atmel_sha",
 		.owner	= THIS_MODULE,
+		.of_match_table	= of_match_ptr(atmel_sha_dt_ids),
 	},
 };
 
-- 
1.8.2.2

^ permalink raw reply related

* [PATCH RESEND 0/7] crypto: at91/atmel: add Device Tree support
From: Nicolas Ferre @ 2013-11-08 15:08 UTC (permalink / raw)
  To: linux-arm-kernel, herbert, linux-crypto; +Cc: linux-kernel, eric, Nicolas Ferre

This series adds Device Tree support to the Atmel crypto drivers 
(AES/[T]DES/SHA). The Device Tree entries are very simple and only
declare the reg/irq values and the link to DMA.

Some trivial patches are preceding this move to Device Tree to clean
things up beforehand.

The series has already been sent but a little bit scattered. So I collect
everything, this time.

Nicolas Ferre (7):
  ARM: at91/dt/trivial: use macro for AES irq type
  ARM: at91/dt/trivial: before sama5d3, Atmel MPU were using at91 prefix
  ARM: at91/dt/sama5d3: add DMA information to SHA/AES/TDES nodes
  crypto: atmel-aes - add support for Device Tree
  crypto: atmel-tdes - add support for Device Tree
  crypto: atmel-sha - add support for Device Tree
  crypto: atmel-sha - add sha information to the log

 .../devicetree/bindings/crypto/atmel-crypto.txt    |  68 ++++++++++
 arch/arm/boot/dts/sama5d3.dtsi                     |  16 ++-
 drivers/crypto/atmel-aes.c                         | 143 ++++++++++++++-------
 drivers/crypto/atmel-sha.c                         | 103 +++++++++++----
 drivers/crypto/atmel-tdes.c                        | 143 ++++++++++++++-------
 5 files changed, 346 insertions(+), 127 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/crypto/atmel-crypto.txt

-- 
1.8.2.2

^ permalink raw reply

* [PATCH RESEND 2/7] ARM: at91/dt/trivial: before sama5d3, Atmel MPU were using at91 prefix
From: Nicolas Ferre @ 2013-11-08 15:08 UTC (permalink / raw)
  To: linux-arm-kernel, herbert, linux-crypto; +Cc: linux-kernel, eric, Nicolas Ferre
In-Reply-To: <cover.1383922546.git.nicolas.ferre@atmel.com>

Change the sha/aes/tdes compatibility string to match common
case for the at91sam9g45 family which is to keep the at91 prefix.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 arch/arm/boot/dts/sama5d3.dtsi | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi
index fca56c7..8716fc2 100644
--- a/arch/arm/boot/dts/sama5d3.dtsi
+++ b/arch/arm/boot/dts/sama5d3.dtsi
@@ -351,19 +351,19 @@
 			};
 
 			sha@f8034000 {
-				compatible = "atmel,sam9g46-sha";
+				compatible = "atmel,at91sam9g46-sha";
 				reg = <0xf8034000 0x100>;
 				interrupts = <42 IRQ_TYPE_LEVEL_HIGH 0>;
 			};
 
 			aes@f8038000 {
-				compatible = "atmel,sam9g46-aes";
+				compatible = "atmel,at91sam9g46-aes";
 				reg = <0xf8038000 0x100>;
 				interrupts = <43 IRQ_TYPE_LEVEL_HIGH 0>;
 			};
 
 			tdes@f803c000 {
-				compatible = "atmel,sam9g46-tdes";
+				compatible = "atmel,at91sam9g46-tdes";
 				reg = <0xf803c000 0x100>;
 				interrupts = <44 IRQ_TYPE_LEVEL_HIGH 0>;
 			};
-- 
1.8.2.2

^ permalink raw reply related

* [PATCH RESEND 3/7] ARM: at91/dt/sama5d3: add DMA information to SHA/AES/TDES nodes
From: Nicolas Ferre @ 2013-11-08 15:08 UTC (permalink / raw)
  To: linux-arm-kernel, herbert, linux-crypto; +Cc: linux-kernel, eric, Nicolas Ferre
In-Reply-To: <cover.1383922546.git.nicolas.ferre@atmel.com>

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 arch/arm/boot/dts/sama5d3.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi
index 8716fc2..56c3b01 100644
--- a/arch/arm/boot/dts/sama5d3.dtsi
+++ b/arch/arm/boot/dts/sama5d3.dtsi
@@ -354,18 +354,26 @@
 				compatible = "atmel,at91sam9g46-sha";
 				reg = <0xf8034000 0x100>;
 				interrupts = <42 IRQ_TYPE_LEVEL_HIGH 0>;
+				dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(17)>;
+				dma-names = "tx";
 			};
 
 			aes@f8038000 {
 				compatible = "atmel,at91sam9g46-aes";
 				reg = <0xf8038000 0x100>;
 				interrupts = <43 IRQ_TYPE_LEVEL_HIGH 0>;
+				dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(18)>,
+				       <&dma1 2 AT91_DMA_CFG_PER_ID(19)>;
+				dma-names = "tx", "rx";
 			};
 
 			tdes@f803c000 {
 				compatible = "atmel,at91sam9g46-tdes";
 				reg = <0xf803c000 0x100>;
 				interrupts = <44 IRQ_TYPE_LEVEL_HIGH 0>;
+				dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(20)>,
+				       <&dma1 2 AT91_DMA_CFG_PER_ID(21)>;
+				dma-names = "tx", "rx";
 			};
 
 			dma0: dma-controller@ffffe600 {
-- 
1.8.2.2

^ permalink raw reply related

* [PATCH RESEND 4/7] crypto: atmel-aes - add support for Device Tree
From: Nicolas Ferre @ 2013-11-08 15:08 UTC (permalink / raw)
  To: linux-arm-kernel, herbert, linux-crypto; +Cc: linux-kernel, eric, Nicolas Ferre
In-Reply-To: <cover.1383922546.git.nicolas.ferre@atmel.com>

Add support for Device Tree and use of the DMA DT API to
get the needed channels.
Documentation is added for these DT nodes.

Initial code by: Nicolas Royer and Eukrea.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 .../devicetree/bindings/crypto/atmel-crypto.txt    |  23 ++++
 drivers/crypto/atmel-aes.c                         | 143 ++++++++++++++-------
 2 files changed, 117 insertions(+), 49 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/crypto/atmel-crypto.txt

diff --git a/Documentation/devicetree/bindings/crypto/atmel-crypto.txt b/Documentation/devicetree/bindings/crypto/atmel-crypto.txt
new file mode 100644
index 0000000..d273f0b
--- /dev/null
+++ b/Documentation/devicetree/bindings/crypto/atmel-crypto.txt
@@ -0,0 +1,23 @@
+* Atmel HW cryptographic accelerators
+
+These are the HW cryptographic accelerators found on some Atmel products.
+
+* Advanced Encryption Standard (AES)
+
+Required properties:
+- compatible : Should be "atmel,at91sam9g46-aes".
+- reg: Should contain AES registers location and length.
+- interrupts: Should contain the IRQ line for the AES.
+- dmas: List of two DMA specifiers as described in
+        atmel-dma.txt and dma.txt files.
+- dma-names: Contains one identifier string for each DMA specifier
+             in the dmas property.
+
+Example:
+aes@f8038000 {
+	compatible = "atmel,at91sam9g46-aes";
+	reg = <0xf8038000 0x100>;
+	interrupts = <43 4 0>;
+	dmas = <&dma1 2 18>,
+	       <&dma1 2 19>;
+	dma-names = "tx", "rx";
diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c
index c1efd91..d7c9e31 100644
--- a/drivers/crypto/atmel-aes.c
+++ b/drivers/crypto/atmel-aes.c
@@ -30,6 +30,7 @@
 #include <linux/irq.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
+#include <linux/of_device.h>
 #include <linux/delay.h>
 #include <linux/crypto.h>
 #include <linux/cryptohash.h>
@@ -39,6 +40,7 @@
 #include <crypto/hash.h>
 #include <crypto/internal/hash.h>
 #include <linux/platform_data/crypto-atmel.h>
+#include <dt-bindings/dma/at91.h>
 #include "atmel-aes-regs.h"
 
 #define CFB8_BLOCK_SIZE		1
@@ -747,59 +749,50 @@ static int atmel_aes_dma_init(struct atmel_aes_dev *dd,
 	struct crypto_platform_data *pdata)
 {
 	int err = -ENOMEM;
-	dma_cap_mask_t mask_in, mask_out;
+	dma_cap_mask_t mask;
+
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+
+	/* Try to grab 2 DMA channels */
+	dd->dma_lch_in.chan = dma_request_slave_channel_compat(mask,
+			atmel_aes_filter, &pdata->dma_slave->rxdata, dd->dev, "tx");
+	if (!dd->dma_lch_in.chan)
+		goto err_dma_in;
+
+	dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV;
+	dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base +
+		AES_IDATAR(0);
+	dd->dma_lch_in.dma_conf.src_maxburst = dd->caps.max_burst_size;
+	dd->dma_lch_in.dma_conf.src_addr_width =
+		DMA_SLAVE_BUSWIDTH_4_BYTES;
+	dd->dma_lch_in.dma_conf.dst_maxburst = dd->caps.max_burst_size;
+	dd->dma_lch_in.dma_conf.dst_addr_width =
+		DMA_SLAVE_BUSWIDTH_4_BYTES;
+	dd->dma_lch_in.dma_conf.device_fc = false;
+
+	dd->dma_lch_out.chan = dma_request_slave_channel_compat(mask,
+			atmel_aes_filter, &pdata->dma_slave->txdata, dd->dev, "rx");
+	if (!dd->dma_lch_out.chan)
+		goto err_dma_out;
+
+	dd->dma_lch_out.dma_conf.direction = DMA_DEV_TO_MEM;
+	dd->dma_lch_out.dma_conf.src_addr = dd->phys_base +
+		AES_ODATAR(0);
+	dd->dma_lch_out.dma_conf.src_maxburst = dd->caps.max_burst_size;
+	dd->dma_lch_out.dma_conf.src_addr_width =
+		DMA_SLAVE_BUSWIDTH_4_BYTES;
+	dd->dma_lch_out.dma_conf.dst_maxburst = dd->caps.max_burst_size;
+	dd->dma_lch_out.dma_conf.dst_addr_width =
+		DMA_SLAVE_BUSWIDTH_4_BYTES;
+	dd->dma_lch_out.dma_conf.device_fc = false;
 
-	if (pdata && pdata->dma_slave->txdata.dma_dev &&
-		pdata->dma_slave->rxdata.dma_dev) {
-
-		/* Try to grab 2 DMA channels */
-		dma_cap_zero(mask_in);
-		dma_cap_set(DMA_SLAVE, mask_in);
-
-		dd->dma_lch_in.chan = dma_request_channel(mask_in,
-				atmel_aes_filter, &pdata->dma_slave->rxdata);
-
-		if (!dd->dma_lch_in.chan)
-			goto err_dma_in;
-
-		dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV;
-		dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base +
-			AES_IDATAR(0);
-		dd->dma_lch_in.dma_conf.src_maxburst = dd->caps.max_burst_size;
-		dd->dma_lch_in.dma_conf.src_addr_width =
-			DMA_SLAVE_BUSWIDTH_4_BYTES;
-		dd->dma_lch_in.dma_conf.dst_maxburst = dd->caps.max_burst_size;
-		dd->dma_lch_in.dma_conf.dst_addr_width =
-			DMA_SLAVE_BUSWIDTH_4_BYTES;
-		dd->dma_lch_in.dma_conf.device_fc = false;
-
-		dma_cap_zero(mask_out);
-		dma_cap_set(DMA_SLAVE, mask_out);
-		dd->dma_lch_out.chan = dma_request_channel(mask_out,
-				atmel_aes_filter, &pdata->dma_slave->txdata);
-
-		if (!dd->dma_lch_out.chan)
-			goto err_dma_out;
-
-		dd->dma_lch_out.dma_conf.direction = DMA_DEV_TO_MEM;
-		dd->dma_lch_out.dma_conf.src_addr = dd->phys_base +
-			AES_ODATAR(0);
-		dd->dma_lch_out.dma_conf.src_maxburst = dd->caps.max_burst_size;
-		dd->dma_lch_out.dma_conf.src_addr_width =
-			DMA_SLAVE_BUSWIDTH_4_BYTES;
-		dd->dma_lch_out.dma_conf.dst_maxburst = dd->caps.max_burst_size;
-		dd->dma_lch_out.dma_conf.dst_addr_width =
-			DMA_SLAVE_BUSWIDTH_4_BYTES;
-		dd->dma_lch_out.dma_conf.device_fc = false;
-
-		return 0;
-	} else {
-		return -ENODEV;
-	}
+	return 0;
 
 err_dma_out:
 	dma_release_channel(dd->dma_lch_in.chan);
 err_dma_in:
+	dev_warn(dd->dev, "no DMA channel available\n");
 	return err;
 }
 
@@ -1261,6 +1254,47 @@ static void atmel_aes_get_cap(struct atmel_aes_dev *dd)
 	}
 }
 
+#if defined(CONFIG_OF)
+static const struct of_device_id atmel_aes_dt_ids[] = {
+	{ .compatible = "atmel,at91sam9g46-aes" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, atmel_aes_dt_ids);
+
+static struct crypto_platform_data *atmel_aes_of_init(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct crypto_platform_data *pdata;
+
+	if (!np) {
+		dev_err(&pdev->dev, "device node not found\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(&pdev->dev, "could not allocate memory for pdata\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	pdata->dma_slave = devm_kzalloc(&pdev->dev,
+					sizeof(*(pdata->dma_slave)),
+					GFP_KERNEL);
+	if (!pdata->dma_slave) {
+		dev_err(&pdev->dev, "could not allocate memory for dma_slave\n");
+		devm_kfree(&pdev->dev, pdata);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	return pdata;
+}
+#else
+static inline struct crypto_platform_data *atmel_aes_of_init(struct platform_device *pdev)
+{
+	return ERR_PTR(-EINVAL);
+}
+#endif
+
 static int atmel_aes_probe(struct platform_device *pdev)
 {
 	struct atmel_aes_dev *aes_dd;
@@ -1272,6 +1306,14 @@ static int atmel_aes_probe(struct platform_device *pdev)
 
 	pdata = pdev->dev.platform_data;
 	if (!pdata) {
+		pdata = atmel_aes_of_init(pdev);
+		if (IS_ERR(pdata)) {
+			err = PTR_ERR(pdata);
+			goto aes_dd_err;
+		}
+	}
+
+	if (!pdata->dma_slave) {
 		err = -ENXIO;
 		goto aes_dd_err;
 	}
@@ -1358,7 +1400,9 @@ static int atmel_aes_probe(struct platform_device *pdev)
 	if (err)
 		goto err_algs;
 
-	dev_info(dev, "Atmel AES\n");
+	dev_info(dev, "Atmel AES - Using %s, %s for DMA transfers\n",
+			dma_chan_name(aes_dd->dma_lch_in.chan),
+			dma_chan_name(aes_dd->dma_lch_out.chan));
 
 	return 0;
 
@@ -1424,6 +1468,7 @@ static struct platform_driver atmel_aes_driver = {
 	.driver		= {
 		.name	= "atmel_aes",
 		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(atmel_aes_dt_ids),
 	},
 };
 
-- 
1.8.2.2

^ permalink raw reply related

* [PATCH RESEND 5/7] crypto: atmel-tdes - add support for Device Tree
From: Nicolas Ferre @ 2013-11-08 15:08 UTC (permalink / raw)
  To: linux-arm-kernel, herbert, linux-crypto; +Cc: linux-kernel, eric, Nicolas Ferre
In-Reply-To: <cover.1383922546.git.nicolas.ferre@atmel.com>

Add support for Device Tree and use of the DMA DT API to
get the channels if needed.
Documentation is added for these DT nodes.

Initial code by: Nicolas Royer and Eukrea.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 .../devicetree/bindings/crypto/atmel-crypto.txt    |  23 ++++
 drivers/crypto/atmel-tdes.c                        | 143 ++++++++++++++-------
 2 files changed, 117 insertions(+), 49 deletions(-)

diff --git a/Documentation/devicetree/bindings/crypto/atmel-crypto.txt b/Documentation/devicetree/bindings/crypto/atmel-crypto.txt
index d273f0b..9a24fd9 100644
--- a/Documentation/devicetree/bindings/crypto/atmel-crypto.txt
+++ b/Documentation/devicetree/bindings/crypto/atmel-crypto.txt
@@ -21,3 +21,26 @@ aes@f8038000 {
 	dmas = <&dma1 2 18>,
 	       <&dma1 2 19>;
 	dma-names = "tx", "rx";
+
+* Triple Data Encryption Standard (Triple DES)
+
+Required properties:
+- compatible : Should be "atmel,at91sam9g46-tdes".
+- reg: Should contain TDES registers location and length.
+- interrupts: Should contain the IRQ line for the TDES.
+
+Optional properties:
+- dmas: List of two DMA specifiers as described in
+        atmel-dma.txt and dma.txt files.
+- dma-names: Contains one identifier string for each DMA specifier
+             in the dmas property.
+
+Example:
+tdes@f803c000 {
+	compatible = "atmel,at91sam9g46-tdes";
+	reg = <0xf803c000 0x100>;
+	interrupts = <44 4 0>;
+	dmas = <&dma1 2 20>,
+	       <&dma1 2 21>;
+	dma-names = "tx", "rx";
+};
diff --git a/drivers/crypto/atmel-tdes.c b/drivers/crypto/atmel-tdes.c
index 4a99564..6cde5b5 100644
--- a/drivers/crypto/atmel-tdes.c
+++ b/drivers/crypto/atmel-tdes.c
@@ -30,6 +30,7 @@
 #include <linux/irq.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
+#include <linux/of_device.h>
 #include <linux/delay.h>
 #include <linux/crypto.h>
 #include <linux/cryptohash.h>
@@ -716,59 +717,50 @@ static int atmel_tdes_dma_init(struct atmel_tdes_dev *dd,
 			struct crypto_platform_data *pdata)
 {
 	int err = -ENOMEM;
-	dma_cap_mask_t mask_in, mask_out;
+	dma_cap_mask_t mask;
+
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+
+	/* Try to grab 2 DMA channels */
+	dd->dma_lch_in.chan = dma_request_slave_channel_compat(mask,
+			atmel_tdes_filter, &pdata->dma_slave->rxdata, dd->dev, "tx");
+	if (!dd->dma_lch_in.chan)
+		goto err_dma_in;
+
+	dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV;
+	dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base +
+		TDES_IDATA1R;
+	dd->dma_lch_in.dma_conf.src_maxburst = 1;
+	dd->dma_lch_in.dma_conf.src_addr_width =
+		DMA_SLAVE_BUSWIDTH_4_BYTES;
+	dd->dma_lch_in.dma_conf.dst_maxburst = 1;
+	dd->dma_lch_in.dma_conf.dst_addr_width =
+		DMA_SLAVE_BUSWIDTH_4_BYTES;
+	dd->dma_lch_in.dma_conf.device_fc = false;
+
+	dd->dma_lch_out.chan = dma_request_slave_channel_compat(mask,
+			atmel_tdes_filter, &pdata->dma_slave->txdata, dd->dev, "rx");
+	if (!dd->dma_lch_out.chan)
+		goto err_dma_out;
+
+	dd->dma_lch_out.dma_conf.direction = DMA_DEV_TO_MEM;
+	dd->dma_lch_out.dma_conf.src_addr = dd->phys_base +
+		TDES_ODATA1R;
+	dd->dma_lch_out.dma_conf.src_maxburst = 1;
+	dd->dma_lch_out.dma_conf.src_addr_width =
+		DMA_SLAVE_BUSWIDTH_4_BYTES;
+	dd->dma_lch_out.dma_conf.dst_maxburst = 1;
+	dd->dma_lch_out.dma_conf.dst_addr_width =
+		DMA_SLAVE_BUSWIDTH_4_BYTES;
+	dd->dma_lch_out.dma_conf.device_fc = false;
 
-	if (pdata && pdata->dma_slave->txdata.dma_dev &&
-		pdata->dma_slave->rxdata.dma_dev) {
-
-		/* Try to grab 2 DMA channels */
-		dma_cap_zero(mask_in);
-		dma_cap_set(DMA_SLAVE, mask_in);
-
-		dd->dma_lch_in.chan = dma_request_channel(mask_in,
-				atmel_tdes_filter, &pdata->dma_slave->rxdata);
-
-		if (!dd->dma_lch_in.chan)
-			goto err_dma_in;
-
-		dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV;
-		dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base +
-			TDES_IDATA1R;
-		dd->dma_lch_in.dma_conf.src_maxburst = 1;
-		dd->dma_lch_in.dma_conf.src_addr_width =
-			DMA_SLAVE_BUSWIDTH_4_BYTES;
-		dd->dma_lch_in.dma_conf.dst_maxburst = 1;
-		dd->dma_lch_in.dma_conf.dst_addr_width =
-			DMA_SLAVE_BUSWIDTH_4_BYTES;
-		dd->dma_lch_in.dma_conf.device_fc = false;
-
-		dma_cap_zero(mask_out);
-		dma_cap_set(DMA_SLAVE, mask_out);
-		dd->dma_lch_out.chan = dma_request_channel(mask_out,
-				atmel_tdes_filter, &pdata->dma_slave->txdata);
-
-		if (!dd->dma_lch_out.chan)
-			goto err_dma_out;
-
-		dd->dma_lch_out.dma_conf.direction = DMA_DEV_TO_MEM;
-		dd->dma_lch_out.dma_conf.src_addr = dd->phys_base +
-			TDES_ODATA1R;
-		dd->dma_lch_out.dma_conf.src_maxburst = 1;
-		dd->dma_lch_out.dma_conf.src_addr_width =
-			DMA_SLAVE_BUSWIDTH_4_BYTES;
-		dd->dma_lch_out.dma_conf.dst_maxburst = 1;
-		dd->dma_lch_out.dma_conf.dst_addr_width =
-			DMA_SLAVE_BUSWIDTH_4_BYTES;
-		dd->dma_lch_out.dma_conf.device_fc = false;
-
-		return 0;
-	} else {
-		return -ENODEV;
-	}
+	return 0;
 
 err_dma_out:
 	dma_release_channel(dd->dma_lch_in.chan);
 err_dma_in:
+	dev_warn(dd->dev, "no DMA channel available\n");
 	return err;
 }
 
@@ -1317,6 +1309,47 @@ static void atmel_tdes_get_cap(struct atmel_tdes_dev *dd)
 	}
 }
 
+#if defined(CONFIG_OF)
+static const struct of_device_id atmel_tdes_dt_ids[] = {
+	{ .compatible = "atmel,at91sam9g46-tdes" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, atmel_tdes_dt_ids);
+
+static struct crypto_platform_data *atmel_tdes_of_init(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct crypto_platform_data *pdata;
+
+	if (!np) {
+		dev_err(&pdev->dev, "device node not found\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(&pdev->dev, "could not allocate memory for pdata\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	pdata->dma_slave = devm_kzalloc(&pdev->dev,
+					sizeof(*(pdata->dma_slave)),
+					GFP_KERNEL);
+	if (!pdata->dma_slave) {
+		dev_err(&pdev->dev, "could not allocate memory for dma_slave\n");
+		devm_kfree(&pdev->dev, pdata);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	return pdata;
+}
+#else /* CONFIG_OF */
+static inline struct crypto_platform_data *atmel_tdes_of_init(struct platform_device *pdev)
+{
+	return ERR_PTR(-EINVAL);
+}
+#endif
+
 static int atmel_tdes_probe(struct platform_device *pdev)
 {
 	struct atmel_tdes_dev *tdes_dd;
@@ -1399,13 +1432,24 @@ static int atmel_tdes_probe(struct platform_device *pdev)
 	if (tdes_dd->caps.has_dma) {
 		pdata = pdev->dev.platform_data;
 		if (!pdata) {
-			dev_err(&pdev->dev, "platform data not available\n");
+			pdata = atmel_tdes_of_init(pdev);
+			if (IS_ERR(pdata)) {
+				dev_err(&pdev->dev, "platform data not available\n");
+				err = PTR_ERR(pdata);
+				goto err_pdata;
+			}
+		}
+		if (!pdata->dma_slave) {
 			err = -ENXIO;
 			goto err_pdata;
 		}
 		err = atmel_tdes_dma_init(tdes_dd, pdata);
 		if (err)
 			goto err_tdes_dma;
+
+		dev_info(dev, "using %s, %s for DMA transfers\n",
+				dma_chan_name(tdes_dd->dma_lch_in.chan),
+				dma_chan_name(tdes_dd->dma_lch_out.chan));
 	}
 
 	spin_lock(&atmel_tdes.lock);
@@ -1487,6 +1531,7 @@ static struct platform_driver atmel_tdes_driver = {
 	.driver		= {
 		.name	= "atmel_tdes",
 		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(atmel_tdes_dt_ids),
 	},
 };
 
-- 
1.8.2.2

^ permalink raw reply related

* [PATCH RESEND 7/7] crypto: atmel-sha - add sha information to the log
From: Nicolas Ferre @ 2013-11-08 15:08 UTC (permalink / raw)
  To: linux-arm-kernel, herbert, linux-crypto; +Cc: linux-kernel, eric, Nicolas Ferre
In-Reply-To: <cover.1383922546.git.nicolas.ferre@atmel.com>

Depending on peripheral capabilities, print SHA information at the end
of the probe function.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 drivers/crypto/atmel-sha.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c
index ecfdf72..0618be0 100644
--- a/drivers/crypto/atmel-sha.c
+++ b/drivers/crypto/atmel-sha.c
@@ -1469,7 +1469,9 @@ static int atmel_sha_probe(struct platform_device *pdev)
 	if (err)
 		goto err_algs;
 
-	dev_info(dev, "Atmel SHA1/SHA256\n");
+	dev_info(dev, "Atmel SHA1/SHA256%s%s\n",
+			sha_dd->caps.has_sha224 ? "/SHA224" : "",
+			sha_dd->caps.has_sha_384_512 ? "/SHA384/SHA512" : "");
 
 	return 0;
 
-- 
1.8.2.2

^ permalink raw reply related

* [PATCH] CRYPTO: async_tx: Fixed a couple of typos
From: Mickael Maison @ 2013-11-09 17:30 UTC (permalink / raw)
  To: dan.j.williams; +Cc: herbert, davem, linux-crypto, linux-kernel, Mickael Maison

Fixed 2 typos in async_xor.c
---
 crypto/async_tx/async_xor.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c
index 8ade0a0..bcaa1e9 100644
--- a/crypto/async_tx/async_xor.c
+++ b/crypto/async_tx/async_xor.c
@@ -48,7 +48,7 @@ do_async_xor(struct dma_chan *chan, struct page *dest, struct page **src_list,
 	int xor_src_cnt = 0;
 	dma_addr_t dma_dest;
 
-	/* map the dest bidrectional in case it is re-used as a source */
+	/* map the dest bidirectional in case it is re-used as a source */
 	dma_dest = dma_map_page(dma->dev, dest, offset, len, DMA_BIDIRECTIONAL);
 	for (i = 0; i < src_cnt; i++) {
 		/* only map the dest once */
@@ -175,7 +175,7 @@ do_sync_xor(struct page *dest, struct page **src_list, unsigned int offset,
  * xor_blocks always uses the dest as a source so the
  * ASYNC_TX_XOR_ZERO_DST flag must be set to not include dest data in
  * the calculation.  The assumption with dma eninges is that they only
- * use the destination buffer as a source when it is explicity specified
+ * use the destination buffer as a source when it is explicitly specified
  * in the source list.
  *
  * src_list note: if the dest is also a source it must be at index zero.
-- 
1.7.10.4

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox