POWER9: Is there a way to improve the random number generation on PPC64?
Volker Simonis
volker.simonis at gmail.com
Mon Dec 4 14:00:55 UTC 2017
The solution is quite simple (took me a while though as well to see it
:) - you have to define the intrinsic with the correct access flags.
I.e.
do_intrinsic(_darn, securerandom, darn_name,
serializePropertiesToByteArray_signature, F_R)
instead of using "F_S" as you did in your first attempt. The access
flags are defined at the bottom of vmSymbols.hpp:
F_R, // !static ?native !synchronized (R="regular")
F_S, // static ?native !synchronized
If they don't correspond to the actual function, it won't be matched.
If you'll do this right you'll get the following error:
Compiler intrinsic is defined for method
[java.security.SecureRandom.darn()[B], but the method is not annotated
with @HotSpotIntrinsicCandidate. Exiting.
which can be pacified by using "-XX:-CheckIntrinisics" or better by
using the @HotSpotIntrinsicCandidate annotation on the
SEcureRandom.darn()
Notice that in the real implementation you won't be able to add a
public method to SecureRandom.
Regards,
Volker
On Fri, Dec 1, 2017 at 10:44 PM, Gustavo Romero
<gromero at linux.vnet.ibm.com> wrote:
> Hi Volker,
>
> On 29-11-2017 11:21, Volker Simonis wrote:
>> On Wed, Nov 29, 2017 at 2:04 PM, Gustavo Romero
>> <gromero at linux.vnet.ibm.com> wrote:
>>> Hi Volker,
>>>
>>> On 24-11-2017 20:04, Volker Simonis wrote:
>>>> in one of my talks [1,2] I have an example on how to intrinsify
>>>> Random.nextInt() in C2 by using the Intel 'rdrandl' instruction. But
>>>> please notice that this is just a "toy" example - it is not production
>>>> ready. In fact I think the right way would be to create a new
>>>> SecureRandom provider where you may implement "engineNextBytes" by
>>>> using the new Power instruction (maybe by calling a native function).
>>>> This special implementation of "engineNextBytes" could then be
>>>> intrinsified as described in the talk.
>>>
>>> I've implemented a simple interpreter intrinsic for 'darn' for a given
>>> class/method provided by the user, similarly to what you did for
>>> Helloword.sayHello() in your example. Thanks! I'm now looking for the correct
>>> way to call back from the intrinsic a Java method to act as a fallback method,
>>> since ISA says [1]:
>>>
>>> When the error value is obtained [i.e. 'darn' did not return a random number],
>>> software is expected to repeat the operation. If a non-error value has not been
>>> obtained after several attempts, a software random number generation method
>>> should be used. The recommended number of attempts may be implementation
>>> specific. In the absence of other guidance, ten attempts should be adequate.
>>>
>>> and so I need to call back from the intrinsic, let's say, SecureRandom.netInt()
>>> non-intrinsified method after about 10 failures to get the random number so it
>>> can take over the task again. You did something like that here:
>>>
>>> https://github.com/simonis/JBreak2016/blob/master/examples/hs_patches/JBreak_HelloWorldIntrinsic.patch#L55
>>>
>>> but for fputs() from libc.
>>>
>>> Do you know if it's possible to call, for instance, a loaded method like
>>> SecureRandom.nextInt() from the instrinsic?
>>>
>>
>> I don't think that would be easy to do (if possible at all).
>>
>> The correct way to handle such situations would be to define a Java
>> method with the exact semantics of your 'darn' instruction. All the
>> other logic should be implemented in Java. So for example you would
>> implement SecureRandom.darn() and call it from engineNextBytes(). At
>> the call site of darn() you check the error value and dispatch to the
>> corresponding Java implementation if necessary.
>
> I've implemented a Java SecureRandom.darn() method [1]. I works as expected,
> i.e. it returns 8 bytes of fake random number (using [3] example). However, when
> I proceeded to intrinsify it [2, 0] as I did for the method provided by the user
> (similarly to your HelloWorld example and for a user provided darn() method as I
> mentioned previously) I hit the following check:
>
> Compiler intrinsic is defined for method [_darn: static SecureRandom.darn()[B], but the method is not available in class [java/security/SecureRandom]. Exiting.
>
> SecureRandom.darn() signature looks correct and I know that
> java/security/SecureRandom::darn() is present in core libs because before trying
> to intrinsify it worked ok (I've got the 8 bytes of fake random number - using
> darning.java, below in references) and also 'javap' shows it's in .class:
>
> gromero at gromero16:~/hg/jdk10/hs$ javap -c -s ./build/linux-ppc64le-normal-server-slowdebug/jdk/modules/java.base/java/security/SecureRandom.class | fgrep -i darn
> public byte[] darn();
>
> I thought that no additional hack was necessary to get that intrinsic working as
> it's in core libs, hence nothing like this is needed:
>
> https://github.com/simonis/JBreak2016/blob/master/examples/hs_patches/JBreak2JavaZone.patch#L57-L59
>
> On the other hand if I add @HotSpotIntrinsicCandidate to SecureRandom.darn() I
> get:
>
> Method [java.security.SecureRandom.darn()[B] is annotated with @HotSpotIntrinsicCandidate, but no compiler intrinsic is defined for the method. Exiting.
>
> Any clue on what I'm missing? Is it correct to assume that since darn() now
> is in core libs no check is necessary?
>
> Thanks a lot!
>
> Regards,
> Gustavo
>
> The hs patches:
>
> [0] https://github.com/gromero/darn/blob/master/patches/0_darn_macroassembler.patch
> [1] https://github.com/gromero/darn/blob/master/patches/1_SecureRandom_darn_Java.patch
> [2] https://github.com/gromero/darn/blob/master/patches/2_SecureRandom_darn_intrinsic.patch
>
> and the test-case:
>
> [3] https://github.com/gromero/darn/blob/master/patches/darning.java
>
>>> Thanks!
>>>
>>> Regards,
>>> Gustavo
>>>
>>>> Also, before you start this, please contact the security mailing list
>>>> just to make sure you're not going into the wrong direction (I'm not a
>>>> security expert :)
>>>>
>>>> Regards,
>>>> Volker
>>>>
>>>> [1] https://vimeo.com/182074382
>>>> [2] https://rawgit.com/simonis/JBreak2016/master/jbreak2016.xhtml#/
>>>>
>>>> On Fri, Nov 24, 2017 at 12:58 PM, Gustavo Romero
>>>> <gromero at linux.vnet.ibm.com> wrote:
>>>>> Hi,
>>>>>
>>>>> POWER9 processors introduced a new single instruction to generate a random
>>>>> number called 'darn' (Deliver A Random Number) [1, 2]. The random number
>>>>> generator behind this instruction is NIST SP800-90B and SP800-90C compliant and
>>>>> provides a minimum of 0.5 bits of entropy per bit. That instruction is as simple
>>>>> as "darn RT, L", where RT is general 64-bit purpose register and L is a 2-bit
>>>>> operand to select the random number format. One can call 'darn' many times to
>>>>> obtain a new random number each time.
>>>>>
>>>>> Initially I think it can help on the improving (throughput) of SecureRandom.generateSeed()
>>>>> method & friends from JCE (NativePRNG provider). If that holds, so it has to
>>>>> be done both for Interpreter and JIT.
>>>>>
>>>>> Currently generateSeed() from NativePRNG basically reads from /dev/random by
>>>>> default (which blocks from time to time) or /dev/urandom if instructed to do so.
>>>>> Could somebody please help me to figure out the appropriate place to exploit
>>>>> such a P9 instruction for interpreted mode, given that code for generateSeed()
>>>>> is pure Java and behind scenes just opens /dev/random file and reads from
>>>>> it? For instance, is it correct to exploit it on a C/C++ code and attach that
>>>>> by means of a JNI?
>>>>>
>>>>> Finally, for JITed mode, I think that a way to exploit such a feature would be
>>>>> by matching an specific sub-tree in Ideal Graph and from that emit a `darn`
>>>>> instruction, however I could not figure one sound sub-tree with known nodes
>>>>> (AddI, LoadN, Parm, etc) that could be matched for that purpose. How do porters
>>>>> usually proceed in this case?
>>>>>
>>>>> Any comments shedding some light on that is much appreciated.
>>>>>
>>>>> Thanks and best regards,
>>>>> Gustavo
>>>>>
>>>>> [1] https://www.docdroid.net/tWT7hjD/powerisa-v30.pdf, p. 79
>>>>> [2] https://openpowerfoundation.org/?resource_lib=power-isa-version-3-0
>>>>>
>>>>
>>>
>>
>
More information about the ppc-aix-port-dev
mailing list