summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Miko <karel.miko@gmail.com>2018-04-11 13:03:55 +0200
committerKarel Miko <karel.miko@gmail.com>2018-04-11 13:03:55 +0200
commit4324447058c6550955cebd9336ef1ad64be53dde (patch)
tree0d35b1402dbf7ba9722812d11dbe7f297dbe8c7e
parent2a90bfe087b2c1c1b0396a48dd371fc11f33927c (diff)
polish ECC
-rw-r--r--CryptX.xs17
-rw-r--r--inc/CryptX_PK_ECC.xs.inc3
-rw-r--r--lib/Crypt/PK/ECC.pm190
3 files changed, 71 insertions, 139 deletions
diff --git a/CryptX.xs b/CryptX.xs
index 98a4cae5..53db25a8 100644
--- a/CryptX.xs
+++ b/CryptX.xs
@@ -284,7 +284,7 @@ void _ecc_oid_lookup(ecc_key *key)
int _ecc_set_dp_from_SV(ecc_key *key, SV *curve)
{
dTHX; /* fetch context */
- HV *hc, *hl, *h;
+ HV *hc, *h;
SV *sv_crv, **pref;
SV **sv_cofactor, **sv_prime, **sv_A, **sv_B, **sv_order, **sv_Gx, **sv_Gy, **sv_oid;
char *ptr_crv;
@@ -296,20 +296,13 @@ int _ecc_set_dp_from_SV(ecc_key *key, SV *curve)
if (SvPOK(curve)) {
/* string */
ptr_crv = SvPV(curve, len_crv);
- if ((hl = get_hv("Crypt::PK::ECC::curve2ltc", 0)) == NULL) croak("FATAL: no curve2ltc register");
- pref = hv_fetch(hl, ptr_crv, (U32)len_crv, 0);
+ if ((hc = get_hv("Crypt::PK::ECC::curve", 0)) == NULL) croak("FATAL: no curve register");
+ pref = hv_fetch(hc, ptr_crv, (U32)len_crv, 0);
if (pref && SvOK(*pref)) {
- sv_crv = *pref; /* found in %cutve2ltc */
+ sv_crv = *pref; /* found in %curve */
}
else {
- if ((hc = get_hv("Crypt::PK::ECC::curve", 0)) == NULL) croak("FATAL: no curve register");
- pref = hv_fetch(hc, ptr_crv, (U32)len_crv, 0);
- if (pref && SvOK(*pref)) {
- sv_crv = *pref; /* found in %curve */
- }
- else {
- sv_crv = curve;
- }
+ sv_crv = curve;
}
}
else if (SvROK(curve)) {
diff --git a/inc/CryptX_PK_ECC.xs.inc b/inc/CryptX_PK_ECC.xs.inc
index 751b7d83..ce6cb2ec 100644
--- a/inc/CryptX_PK_ECC.xs.inc
+++ b/inc/CryptX_PK_ECC.xs.inc
@@ -202,13 +202,12 @@ key2hash(Crypt::PK::ECC self)
not_used = hv_store(rv_hash, "curve_oid", 9, oid, 0);
/* curve name -> "curve_name" */
- if ((h = get_hv("Crypt::PK::ECC::curve2ltc", 0)) != NULL) {
+ if ((h = get_hv("Crypt::PK::ECC::curve_oid2name", 0)) != NULL) {
pref = hv_fetch(h, oid_ptr, (U32)strlen(oid_ptr), 0);
if (pref) {
cname_ptr = SvPV(*pref, cname_len);
cname = newSVpv(cname_ptr, cname_len);
cname_ptr = SvPVX(cname);
- for (i=0; i<cname_len && cname_ptr[i]>0; i++) cname_ptr[i] = toLOWER(cname_ptr[i]);
not_used = hv_store(rv_hash, "curve_name", 10, cname, 0);
}
}
diff --git a/lib/Crypt/PK/ECC.pm b/lib/Crypt/PK/ECC.pm
index d42065f7..0e7ed919 100644
--- a/lib/Crypt/PK/ECC.pm
+++ b/lib/Crypt/PK/ECC.pm
@@ -16,39 +16,74 @@ use Crypt::Digest qw(digest_data digest_data_b64u);
use Crypt::Misc qw(read_rawfile encode_b64u decode_b64u encode_b64 decode_b64 pem_to_der der_to_pem);
use Crypt::PK;
-our %curve = (
- # extra curves not recognized by libtomcrypt
- 'wap-wsg-idm-ecid-wtls8' => {
- prime => "FFFFFFFFFFFFFFFFFFFFFFFFFDE7",
- A => "0000000000000000000000000000",
- B => "0000000000000000000000000003",
- order => "0100000000000001ECEA551AD837E9",
- Gx => "0000000000000000000000000001",
- Gy => "0000000000000000000000000002",
- cofactor => 1,
- oid => '2.23.43.1.4.8',
- },
- 'wap-wsg-idm-ecid-wtls9' => {
- prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC808F",
- A => "0000000000000000000000000000000000000000",
- B => "0000000000000000000000000000000000000003",
- order => "0100000000000000000001CDC98AE0E2DE574ABF33",
- Gx => "0000000000000000000000000000000000000001",
- Gy => "0000000000000000000000000000000000000002",
- cofactor => 1,
- oid => '2.23.43.1.4.9',
- },
+our %curve = ( # must be "our" as we use it from XS code
+ # extra curves not recognized by libtomcrypt
+ 'wap-wsg-idm-ecid-wtls8' => {
+ prime => "FFFFFFFFFFFFFFFFFFFFFFFFFDE7",
+ A => "0000000000000000000000000000",
+ B => "0000000000000000000000000003",
+ order => "0100000000000001ECEA551AD837E9",
+ Gx => "0000000000000000000000000001",
+ Gy => "0000000000000000000000000002",
+ cofactor => 1,
+ oid => '2.23.43.1.4.8',
+ },
+ 'wap-wsg-idm-ecid-wtls9' => {
+ prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC808F",
+ A => "0000000000000000000000000000000000000000",
+ B => "0000000000000000000000000000000000000003",
+ order => "0100000000000000000001CDC98AE0E2DE574ABF33",
+ Gx => "0000000000000000000000000000000000000001",
+ Gy => "0000000000000000000000000000000000000002",
+ cofactor => 1,
+ oid => '2.23.43.1.4.9',
+ },
+ # some unusual openssl names
+ "wap-wsg-idm-ecid-wtls6" => 'secp112r1',
+ "wap-wsg-idm-ecid-wtls7" => 'secp160r2',
+ "wap-wsg-idm-ecid-wtls12" => 'secp224r1',
);
-my %jwk2curve = (
- 'P-192' => 'secp192r1',
- 'P-224' => 'secp224r1',
- 'P-256' => 'secp256r1',
- 'P-384' => 'secp384r1',
- 'P-521' => 'secp521r1',
+our %curve_oid2name = ( # must be "our" as we use it from XS code
+ # the following are used to derive curve_name from OID in key2hash()
+ "1.2.840.10045.3.1.1" => "secp192r1",
+ "1.2.840.10045.3.1.2" => "prime192v2",
+ "1.2.840.10045.3.1.3" => "prime192v3",
+ "1.2.840.10045.3.1.4" => "prime239v1",
+ "1.2.840.10045.3.1.5" => "prime239v2",
+ "1.2.840.10045.3.1.6" => "prime239v3",
+ "1.2.840.10045.3.1.7" => "secp256r1",
+ "1.3.132.0.6" => "secp112r1",
+ "1.3.132.0.7" => "secp112r2",
+ "1.3.132.0.8" => "secp160r1",
+ "1.3.132.0.9" => "secp160k1",
+ "1.3.132.0.10" => "secp256k1",
+ "1.3.132.0.28" => "secp128r1",
+ "1.3.132.0.29" => "secp128r2",
+ "1.3.132.0.30" => "secp160r2",
+ "1.3.132.0.31" => "secp192k1",
+ "1.3.132.0.32" => "secp224k1",
+ "1.3.132.0.33" => "secp224r1",
+ "1.3.132.0.34" => "secp384r1",
+ "1.3.132.0.35" => "secp521r1",
+ "1.3.36.3.3.2.8.1.1.1" => "brainpoolp160r1",
+ "1.3.36.3.3.2.8.1.1.2" => "brainpoolp160t1",
+ "1.3.36.3.3.2.8.1.1.3" => "brainpoolp192r1",
+ "1.3.36.3.3.2.8.1.1.4" => "brainpoolp192t1",
+ "1.3.36.3.3.2.8.1.1.5" => "brainpoolp224r1",
+ "1.3.36.3.3.2.8.1.1.6" => "brainpoolp224t1",
+ "1.3.36.3.3.2.8.1.1.7" => "brainpoolp256r1",
+ "1.3.36.3.3.2.8.1.1.8" => "brainpoolp256t1",
+ "1.3.36.3.3.2.8.1.1.9" => "brainpoolp320r1",
+ "1.3.36.3.3.2.8.1.1.10" => "brainpoolp320t1",
+ "1.3.36.3.3.2.8.1.1.11" => "brainpoolp384r1",
+ "1.3.36.3.3.2.8.1.1.12" => "brainpoolp384t1",
+ "1.3.36.3.3.2.8.1.1.13" => "brainpoolp512r1",
+ "1.3.36.3.3.2.8.1.1.14" => "brainpoolp512t1",
);
my %curve2jwk = (
+ # necessary for conversion of curve_name_or_OID >> P-NNN
'1.2.840.10045.3.1.1' => 'P-192', # secp192r1
'1.3.132.0.33' => 'P-224', # secp224r1
'1.2.840.10045.3.1.7' => 'P-256', # secp256r1
@@ -68,95 +103,6 @@ my %curve2jwk = (
'secp521r1' => 'P-521',
);
-our %curve2ltc = ( # must be "our" as we use it from XS code
- # OIDs
- "1.2.840.10045.3.1.1" => "SECP192R1",
- "1.2.840.10045.3.1.2" => "PRIME192V2",
- "1.2.840.10045.3.1.3" => "PRIME192V3",
- "1.2.840.10045.3.1.4" => "PRIME239V1",
- "1.2.840.10045.3.1.5" => "PRIME239V2",
- "1.2.840.10045.3.1.6" => "PRIME239V3",
- "1.2.840.10045.3.1.7" => "SECP256R1",
- "1.3.132.0.10" => "SECP256K1",
- "1.3.132.0.28" => "SECP128R1",
- "1.3.132.0.29" => "SECP128R2",
- "1.3.132.0.30" => "SECP160R2",
- "1.3.132.0.31" => "SECP192K1",
- "1.3.132.0.32" => "SECP224K1",
- "1.3.132.0.33" => "SECP224R1",
- "1.3.132.0.34" => "SECP384R1",
- "1.3.132.0.35" => "SECP521R1",
- "1.3.132.0.6" => "SECP112R1",
- "1.3.132.0.7" => "SECP112R2",
- "1.3.132.0.8" => "SECP160R1",
- "1.3.132.0.9" => "SECP160K1",
- "1.3.36.3.3.2.8.1.1.1" => "BRAINPOOLP160R1",
- "1.3.36.3.3.2.8.1.1.11" => "BRAINPOOLP384R1",
- "1.3.36.3.3.2.8.1.1.13" => "BRAINPOOLP512R1",
- "1.3.36.3.3.2.8.1.1.3" => "BRAINPOOLP192R1",
- "1.3.36.3.3.2.8.1.1.5" => "BRAINPOOLP224R1",
- "1.3.36.3.3.2.8.1.1.7" => "BRAINPOOLP256R1",
- "1.3.36.3.3.2.8.1.1.9" => "BRAINPOOLP320R1",
- "1.3.36.3.3.2.8.1.1.10" => "BRAINPOOLP320T1",
- "1.3.36.3.3.2.8.1.1.12" => "BRAINPOOLP384T1",
- "1.3.36.3.3.2.8.1.1.14" => "BRAINPOOLP512T1",
- "1.3.36.3.3.2.8.1.1.2" => "BRAINPOOLP160T1",
- "1.3.36.3.3.2.8.1.1.4" => "BRAINPOOLP192T1",
- "1.3.36.3.3.2.8.1.1.6" => "BRAINPOOLP224T1",
- "1.3.36.3.3.2.8.1.1.8" => "BRAINPOOLP256T1",
- # JWT names
- "P-192" => "SECP192R1",
- "P-224" => "SECP224R1",
- "P-256" => "SECP256R1",
- "P-384" => "SECP384R1",
- "P-521" => "SECP521R1",
- # openssl names
- "brainpoolp160r1" => "BRAINPOOLP160R1",
- "brainpoolp192r1" => "BRAINPOOLP192R1",
- "brainpoolp224r1" => "BRAINPOOLP224R1",
- "brainpoolp256r1" => "BRAINPOOLP256R1",
- "brainpoolp320r1" => "BRAINPOOLP320R1",
- "brainpoolp384r1" => "BRAINPOOLP384R1",
- "brainpoolp512r1" => "BRAINPOOLP512R1",
- "brainpoolp160t1" => "BRAINPOOLP160T1",
- "brainpoolp192t1" => "BRAINPOOLP192T1",
- "brainpoolp224t1" => "BRAINPOOLP224T1",
- "brainpoolp256t1" => "BRAINPOOLP256T1",
- "brainpoolp320t1" => "BRAINPOOLP320T1",
- "brainpoolp384t1" => "BRAINPOOLP384T1",
- "brainpoolp512t1" => "BRAINPOOLP512T1",
- "nistp192" => "SECP192R1",
- "nistp224" => "SECP224R1",
- "nistp256" => "SECP256R1",
- "nistp384" => "SECP384R1",
- "nistp521" => "SECP521R1",
- "prime192v1" => "SECP192R1",
- "prime192v2" => "PRIME192V2",
- "prime192v3" => "PRIME192V3",
- "prime239v1" => "PRIME239V1",
- "prime239v2" => "PRIME239V2",
- "prime239v3" => "PRIME239V3",
- "prime256v1" => "SECP256R1",
- "secp112r1" => "SECP112R1",
- "secp112r2" => "SECP112R2",
- "secp128r1" => "SECP128R1",
- "secp128r2" => "SECP128R2",
- "secp160k1" => "SECP160K1",
- "secp160r1" => "SECP160R1",
- "secp160r2" => "SECP160R2",
- "secp192k1" => "SECP192K1",
- "secp192r1" => "SECP192R1",
- "secp224k1" => "SECP224K1",
- "secp224r1" => "SECP224R1",
- "secp256k1" => "SECP256K1",
- "secp256r1" => "SECP256R1",
- "secp384r1" => "SECP384R1",
- "secp521r1" => "SECP521R1",
- "wap-wsg-idm-ecid-wtls6" => 'SECP112R1',
- "wap-wsg-idm-ecid-wtls7" => 'SECP160R2',
- "wap-wsg-idm-ecid-wtls12" => 'SECP224R1',
-);
-
sub _import_hex {
my ($self, $x, $y, $k, $crv) = @_;
croak "FATAL: no curve" if !$crv;
@@ -250,10 +196,7 @@ sub import_key {
for (qw/x y d/) {
$key->{$_} = eval { unpack("H*", decode_b64u($key->{$_})) } if exists $key->{$_};
}
- if (my $curve_name = $jwk2curve{$key->{crv}}) {
- return $self->_import_hex($key->{x}, $key->{y}, $key->{d}, $curve_name);
- }
- # curve is not JWK compliant e.g. P-192 P-224 P-256 P-384 P-521 (we'll try to import anyway)
+ # names P-192 P-224 P-256 P-384 P-521 are recognized by libtomcrypt
return $self->_import_hex($key->{x}, $key->{y}, $key->{d}, $key->{crv});
}
croak "FATAL: unexpected ECC key hash";
@@ -291,10 +234,7 @@ sub import_key {
for (qw/x y d/) {
$h->{$_} = eval { unpack("H*", decode_b64u($h->{$_})) } if exists $h->{$_};
}
- if (my $curve_name = $jwk2curve{$h->{crv}}) {
- return $self->_import_hex($h->{x}, $h->{y}, $h->{d}, $curve_name);
- }
- # curve is not JWK compliant e.g. P-192 P-224 P-256 P-384 P-521 (we'll try to import anyway)
+ # names P-192 P-224 P-256 P-384 P-521 are recognized by libtomcrypt
return $self->_import_hex($h->{x}, $h->{y}, $h->{d}, $h->{crv});
}
}