Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the CryptX CPAN distribution.

Report information
The Basics
Id: 89308
Status: resolved
Priority: 0/
Queue: CryptX

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

Bug Information
Severity: Important
Broken in: 0.017
Fixed in: (no value)



Subject: Invalid private keys being produced
During interoperability tests with Crypt::DSA::GMP, I found my simple key validation routine regularly failing for the CryptX produced keys. FIPS 186-2: "4. DSA parameters" page 8: x = a randomly or pseudorandomly generated integer with 0 < x < q FIPS 186-4: "4. DSA parameters" page 15: x = the private key that must remain secret; x is a randomly or pseudorandomly generated integer, such that 0 < x < q, i.e., x is in the range [1, q-1]. src/ltc/pk/dsa/dsa_make_key.c produces random x values of the same bit size as q (looping if x == 0), but that allows x to be >= q. Example: perl -MCrypt::PK::DSA -MMath::BigInt -E 'my $dsa1 = Crypt::PK::DSA->new(); do { $dsa1->generate_key(20, 128); my $pkhash = $dsa1->key2hash; die "$pkhash->{x} >= $pkhash->{q}" if Math::BigInt->from_hex($pkhash->{x}) >= Math::BigInt->from_hex($pkhash->{q}); } for 1..100' It looks like k in the signing function is also being generated with the bit size of q rather than mod q. This has been in libtomcrypt for some time I guess. I'm not sure if that project is still being worked on -- the last release was in 2007. I'm not certain that either the x or k ranges present a cryptographic flaw, but it's definitely wrong according to the specifications.
Show quoted text
> src/ltc/pk/dsa/dsa_make_key.c produces random x values of the same bit > size as q (looping if x == 0), but that allows x to be >= q.
I guess the following patch to dsa_make_key.c should fix this part: - } while (mp_cmp_d(key->x, 1) != LTC_MP_GT); + } while (mp_cmp_d(key->x, 1) != LTC_MP_GT || mp_cmp(key->x, key->q) != LTC_MP_LT); Correct?
And following patch to dsa_sign_hash.c should fix the second part: - /* k > 1 ? */ - if (mp_cmp_d(k, 1) != LTC_MP_GT) { goto retry; } + /* k > 1 and k < q ? */ + if (mp_cmp_d(k, 1) != LTC_MP_GT || mp_cmp(k, key->q) != LTC_MP_LT) { goto retry; }
On Wed Oct 09 14:43:17 2013, MIK wrote: Show quoted text
> proposed changes committed to git repo > > https://github.com/DCIT/perl- > CryptX/commit/734fefd8ee201f836b3d7b7aba91ffe983b5bd8e > > https://github.com/DCIT/perl- > CryptX/commit/4b5f4ef0f0dcde2714769de769cfd727a9a7caef
These look ok to me. I believe x and k are allowed to be == 1. That is a trivial matter so perhaps best left alone. I noticed PyCrypto has a validation method that also includes the range check on x in a pull request, so I think the changes are good for general interoperability.
fixed in CryptX-0.018 Thanks for your time.