Skip Menu |

This queue is for tickets about the Crypt-DSA CPAN distribution.

Report information
The Basics
Id: 88429
Status: new
Priority: 0/
Queue: Crypt-DSA

People
Owner: Nobody in particular
Requestors: DANAJ [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 1.17
Fixed in: (no value)



Subject: Key generation issues
This is recording some of the issues I've found and fixed in KeyChain/generate_params while writing Crypt::DSA::GMP. Most of this is the difference between OpenSSL (1.0.1) and the Perl code, but there is also a critical defect in the 'p' generation where we will output composites. OpenSSL silently uses min(bits, 512), hence if we ask for 256 bits we actually get 512. On the other hand, the Perl code does not do this -- it will accept any bit size other than 0. This means: = bit sizes < 0 will output: Can't locate object method "copy" via package "NaN" = bit sizes <= 160 will always create keys with composite p. = bit sizes not much larger than 160 will often create keys with composite p. = bit sizes from 1 to 511 will create different results from OpenSSL (we honor the Size, OpenSSL does not). My solution was to (1) not use OpenSSL anywhere, which solves a host of problems, (2) croak if Size < 256, and (3) redo the q/p selection if the counter overflows, as specified in FIPS 186-3/4. If we are unlucky with the p selection and take 4096 tries, we will output composite p values. This happens regardless of bit size. Solution #3 above takes care of this. OpenSSL bumps the 'q' size to 256 when Size >= 2048. The Perl code is always 160 since it is using the obsolete SHA1 method (FIPS 186-3/4 A.1.1.1). This leads to fundamentally different keys. My solution (not ideal, suggestions welcome) was to: 1) if a Seed is given and its length is 20, use the old SHA-1 method with 'q' size 160. This makes t/06-fips.t pass, and should retain backward compatibility. 2) if a Seed is not given or its size is not 20, then use the approved A.1.1.1 method using SHA256 as the hash, and set the 'q' size as 160 if <= 2048, 256 otherwise. I may later add a parameter for setting the 'q' size directly. Other RT's already mention two other issues which are solved in Crypt::DSA::GMP: - the Perl code does not use strong enough primality testing for FIPS compliance (I'm using the Lucas+MR tests by default, and an option for a proof of q, p, or both). - we should use a strong randomness source (e.g. /dev/random or Win32's API).
Two more issues found and fixed: (1) [minor] kinv is stored in the key. There is no reason to export k or kinv outside of the signing function. It is not used, and it gives out information that isn't necessary. (2) [important] k generation does not produce enough bits. k should be generated in [1,q-1]. The code in DSA.pm generates a random N-bit number then subtracts q if k >= q. This leaves a hole of size q-2^(N-1), which means we will leave out up to half of the possible k values.