diff --git a/CryptX.xs b/CryptX.xs index ebca25b..53bfff7 100644 --- a/CryptX.xs +++ b/CryptX.xs @@ -262,30 +262,30 @@ int err; unsigned i; void *tmp; - const ltc_ecc_set_type *set; + const ltc_ecc_curve *cu; key->dp.oidlen = 0; if ((err = ltc_mp.init(&tmp)) != CRYPT_OK) return; - for (set = ltc_ecc_sets; set->name != NULL; set++) { - if ((err = mp_read_radix(tmp, set->prime, 16)) != CRYPT_OK) continue; + for (cu = ltc_ecc_curves; cu->prime != NULL; cu++) { + if ((err = mp_read_radix(tmp, cu->prime, 16)) != CRYPT_OK) continue; if ((mp_cmp(tmp, key->dp.prime) != LTC_MP_EQ)) continue; - if ((err = mp_read_radix(tmp, set->order, 16)) != CRYPT_OK) continue; + if ((err = mp_read_radix(tmp, cu->order, 16)) != CRYPT_OK) continue; if ((mp_cmp(tmp, key->dp.order) != LTC_MP_EQ)) continue; - if ((err = mp_read_radix(tmp, set->A, 16)) != CRYPT_OK) continue; + if ((err = mp_read_radix(tmp, cu->A, 16)) != CRYPT_OK) continue; if ((mp_cmp(tmp, key->dp.A) != LTC_MP_EQ)) continue; - if ((err = mp_read_radix(tmp, set->B, 16)) != CRYPT_OK) continue; + if ((err = mp_read_radix(tmp, cu->B, 16)) != CRYPT_OK) continue; if ((mp_cmp(tmp, key->dp.B) != LTC_MP_EQ)) continue; - if ((err = mp_read_radix(tmp, set->Gx, 16)) != CRYPT_OK) continue; + if ((err = mp_read_radix(tmp, cu->Gx, 16)) != CRYPT_OK) continue; if ((mp_cmp(tmp, key->dp.base.x) != LTC_MP_EQ)) continue; - if ((err = mp_read_radix(tmp, set->Gy, 16)) != CRYPT_OK) continue; + if ((err = mp_read_radix(tmp, cu->Gy, 16)) != CRYPT_OK) continue; if ((mp_cmp(tmp, key->dp.base.y) != LTC_MP_EQ)) continue; - if (key->dp.cofactor != set->cofactor) continue; + if (key->dp.cofactor != cu->cofactor) continue; break; /* found */ } ltc_mp.deinit(tmp); - if (set->name != NULL) { - key->dp.oidlen = set->oidlen; - for(i = 0; i < set->oidlen; i++) key->dp.oid[i] = set->oid[i]; + if (cu->prime != NULL) { + key->dp.oidlen = cu->oidlen; + for(i = 0; i < cu->oidlen; i++) key->dp.oid[i] = cu->oid[i]; } } @@ -330,14 +330,14 @@ if (SvPOK(sv_crv)) { /* string - curve name */ - const ltc_ecc_set_type *dp; + const ltc_ecc_curve *cu; ch_name = SvPV(sv_crv, l_name); - if (ecc_get_set_by_name(ch_name, &dp) != CRYPT_OK) croak("FATAL: ecparams: unknown curve '%s'", ch_name); - return ecc_set_dp(dp, key); + if (ecc_get_curve_by_name(ch_name, &cu) != CRYPT_OK) croak("FATAL: ecparams: unknown curve '%s'", ch_name); + return ecc_set_dp(cu, key); } else { /* hashref */ - ltc_ecc_set_type set = { 0 }; + ltc_ecc_curve cu = { 0 }; if ((h = (HV*)(SvRV(sv_crv))) == NULL) croak("FATAL: ecparams: param is not valid hashref"); @@ -357,15 +357,14 @@ if (!SvOK(*sv_Gy )) croak("FATAL: ecparams: undefined param Gy"); if (!SvOK(*sv_cofactor)) croak("FATAL: ecparams: undefined param cofactor"); - set.prime = SvPV_nolen(*sv_prime); - set.A = SvPV_nolen(*sv_A); - set.B = SvPV_nolen(*sv_B); - set.order = SvPV_nolen(*sv_order); - set.Gx = SvPV_nolen(*sv_Gx); - set.Gy = SvPV_nolen(*sv_Gy); - set.cofactor = (unsigned long)SvUV(*sv_cofactor), - set.name = NULL; - set.oidlen = 0; + cu.prime = SvPV_nolen(*sv_prime); + cu.A = SvPV_nolen(*sv_A); + cu.B = SvPV_nolen(*sv_B); + cu.order = SvPV_nolen(*sv_order); + cu.Gx = SvPV_nolen(*sv_Gx); + cu.Gy = SvPV_nolen(*sv_Gy); + cu.cofactor = (unsigned long)SvUV(*sv_cofactor), + cu.oidlen = 0; sv_oid = hv_fetchs(h, "oid", 0); if (sv_oid && SvPOK(*sv_oid)) { @@ -375,17 +374,17 @@ if (++j >= 16) return CRYPT_ERROR; } else if(ch_name[i] >= '0' && ch_name[i] <= '9') { - set.oid[j] = set.oid[j] * 10 + (ch_name[i] - '0'); + cu.oid[j] = cu.oid[j] * 10 + (ch_name[i] - '0'); } else { return CRYPT_ERROR; } } if (j == 0) return CRYPT_ERROR; - set.oidlen = j + 1; - } - - if ((err = ecc_set_dp(&set, key)) != CRYPT_OK) return err; + cu.oidlen = j + 1; + } + + if ((err = ecc_set_dp(&cu, key)) != CRYPT_OK) return err; if (key->dp.oidlen == 0) _ecc_oid_lookup(key); return CRYPT_OK; } @@ -533,7 +532,7 @@ SvREFCNT_dec(RETVAL); XSRETURN_UNDEF; } - SvCUR_set(RETVAL, out_len); + SvCUR_set(RETVAL, strlen(out_data)); } } OUTPUT: @@ -561,9 +560,9 @@ SvPOK_only(RETVAL); out_data = (unsigned char *)SvPVX(RETVAL); if (ix == 1) - rv = base64url_decode(in_data, (unsigned long)in_len, out_data, &out_len); + rv = base64url_sane_decode(in_data, (unsigned long)in_len, out_data, &out_len); else - rv = base64_decode(in_data, (unsigned long)in_len, out_data, &out_len); + rv = base64_sane_decode(in_data, (unsigned long)in_len, out_data, &out_len); if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); XSRETURN_UNDEF; @@ -586,7 +585,7 @@ unsigned long out_len; unsigned char *in_data; char *out_data; - int id = -1; + int id = -1, err; if (!SvPOK(in)) XSRETURN_UNDEF; if (ix == 0) id = BASE32_RFC4648; @@ -599,15 +598,16 @@ RETVAL = newSVpvn("", 0); } else { - out_len = (unsigned long)((8 * in_len + 4) / 5); + out_len = (unsigned long)((8 * in_len + 4) / 5 + 1); RETVAL = NEWSV(0, out_len); /* avoid zero! */ SvPOK_only(RETVAL); out_data = SvPVX(RETVAL); - if (base32_encode(in_data, (unsigned long)in_len, out_data, &out_len, id) != CRYPT_OK) { + err = base32_encode(in_data, (unsigned long)in_len, out_data, &out_len, id); + if (err != CRYPT_OK) { SvREFCNT_dec(RETVAL); XSRETURN_UNDEF; } - SvCUR_set(RETVAL, out_len); + SvCUR_set(RETVAL, strlen(out_data)); } } OUTPUT: @@ -625,7 +625,7 @@ unsigned long out_len; unsigned char *out_data; char *in_data; - int id = -1; + int id = -1, err; if (!SvPOK(in)) XSRETURN_UNDEF; if (ix == 0) id = BASE32_RFC4648; @@ -642,7 +642,8 @@ RETVAL = NEWSV(0, out_len); /* avoid zero! */ SvPOK_only(RETVAL); out_data = (unsigned char *)SvPVX(RETVAL); - if (base32_decode(in_data, (unsigned long)in_len, out_data, &out_len, id) != CRYPT_OK) { + err = base32_decode(in_data, (unsigned long)in_len, out_data, &out_len, id); + if (err != CRYPT_OK) { SvREFCNT_dec(RETVAL); XSRETURN_UNDEF; } diff --git a/src/Makefile b/src/Makefile index 8c198fa..cdd64e2 100644 --- a/src/Makefile +++ b/src/Makefile @@ -102,8 +102,8 @@ ltc/pk/dsa/dsa_set_pqg_dsaparam.o ltc/pk/dsa/dsa_shared_secret.o ltc/pk/dsa/dsa_sign_hash.o \ ltc/pk/dsa/dsa_verify_hash.o ltc/pk/dsa/dsa_verify_key.o ltc/pk/ecc/ecc.o ltc/pk/ecc/ecc_ansi_x963_export.o \ ltc/pk/ecc/ecc_ansi_x963_import.o ltc/pk/ecc/ecc_decrypt_key.o ltc/pk/ecc/ecc_encrypt_key.o \ -ltc/pk/ecc/ecc_export.o ltc/pk/ecc/ecc_export_openssl.o ltc/pk/ecc/ecc_free.o ltc/pk/ecc/ecc_get_key.o \ -ltc/pk/ecc/ecc_get_set.o ltc/pk/ecc/ecc_get_size.o ltc/pk/ecc/ecc_import.o ltc/pk/ecc/ecc_import_openssl.o \ +ltc/pk/ecc/ecc_export.o ltc/pk/ecc/ecc_export_openssl.o ltc/pk/ecc/ecc_free.o ltc/pk/ecc/ecc_get_curve_by_name.o \ +ltc/pk/ecc/ecc_get_key.o ltc/pk/ecc/ecc_get_size.o ltc/pk/ecc/ecc_import.o ltc/pk/ecc/ecc_import_openssl.o \ ltc/pk/ecc/ecc_import_pkcs8.o ltc/pk/ecc/ecc_import_x509.o ltc/pk/ecc/ecc_make_key.o \ ltc/pk/ecc/ecc_set_dp.o ltc/pk/ecc/ecc_set_dp_internal.o ltc/pk/ecc/ecc_set_key.o \ ltc/pk/ecc/ecc_shared_secret.o ltc/pk/ecc/ecc_sign_hash.o ltc/pk/ecc/ecc_sizes.o \ diff --git a/src/Makefile.nmake b/src/Makefile.nmake index 04fe343..b42d42d 100644 --- a/src/Makefile.nmake +++ b/src/Makefile.nmake @@ -110,7 +110,7 @@ ltc/pk/dsa/dsa_verify_key.obj ltc/pk/ecc/ecc.obj ltc/pk/ecc/ecc_ansi_x963_export.obj \ ltc/pk/ecc/ecc_ansi_x963_import.obj ltc/pk/ecc/ecc_decrypt_key.obj ltc/pk/ecc/ecc_encrypt_key.obj \ ltc/pk/ecc/ecc_export.obj ltc/pk/ecc/ecc_export_openssl.obj ltc/pk/ecc/ecc_free.obj \ -ltc/pk/ecc/ecc_get_key.obj ltc/pk/ecc/ecc_get_set.obj ltc/pk/ecc/ecc_get_size.obj \ +ltc/pk/ecc/ecc_get_curve_by_name.obj ltc/pk/ecc/ecc_get_key.obj ltc/pk/ecc/ecc_get_size.obj \ ltc/pk/ecc/ecc_import.obj ltc/pk/ecc/ecc_import_openssl.obj ltc/pk/ecc/ecc_import_pkcs8.obj \ ltc/pk/ecc/ecc_import_x509.obj ltc/pk/ecc/ecc_make_key.obj ltc/pk/ecc/ecc_set_dp.obj \ ltc/pk/ecc/ecc_set_dp_internal.obj ltc/pk/ecc/ecc_set_key.obj ltc/pk/ecc/ecc_shared_secret.obj \ diff --git a/src/ltc/headers/tomcrypt_misc.h b/src/ltc/headers/tomcrypt_misc.h index 865f2dd..b04fc40 100644 --- a/src/ltc/headers/tomcrypt_misc.h +++ b/src/ltc/headers/tomcrypt_misc.h @@ -10,23 +10,27 @@ /* ---- LTC_BASE64 Routines ---- */ #ifdef LTC_BASE64 int base64_encode(const unsigned char *in, unsigned long len, + char *out, unsigned long *outlen); + +int base64_decode(const char *in, unsigned long len, unsigned char *out, unsigned long *outlen); - -int base64_decode(const unsigned char *in, unsigned long len, +int base64_strict_decode(const char *in, unsigned long len, unsigned char *out, unsigned long *outlen); -int base64_strict_decode(const unsigned char *in, unsigned long len, +int base64_sane_decode(const char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); #endif #ifdef LTC_BASE64_URL int base64url_encode(const unsigned char *in, unsigned long len, + char *out, unsigned long *outlen); +int base64url_strict_encode(const unsigned char *in, unsigned long inlen, + char *out, unsigned long *outlen); + +int base64url_decode(const char *in, unsigned long len, unsigned char *out, unsigned long *outlen); -int base64url_strict_encode(const unsigned char *in, unsigned long inlen, +int base64url_strict_decode(const char *in, unsigned long len, unsigned char *out, unsigned long *outlen); - -int base64url_decode(const unsigned char *in, unsigned long len, - unsigned char *out, unsigned long *outlen); -int base64url_strict_decode(const unsigned char *in, unsigned long len, +int base64url_sane_decode(const char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); #endif @@ -51,7 +55,7 @@ int base16_encode(const unsigned char *in, unsigned long inlen, char *out, unsigned long *outlen, int caps); -int base16_decode(const char *in, +int base16_decode(const char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); #endif diff --git a/src/ltc/headers/tomcrypt_pk.h b/src/ltc/headers/tomcrypt_pk.h index 3f685d7..84e9604 100644 --- a/src/ltc/headers/tomcrypt_pk.h +++ b/src/ltc/headers/tomcrypt_pk.h @@ -259,7 +259,7 @@ /** Structure defines a GF(p) curve */ typedef struct { /** name of curve */ - const char *name; + const char *names[6]; /** The prime that defines the field the curve is in (encoded in hex) */ const char *prime; @@ -285,7 +285,7 @@ /** The OID */ unsigned long oid[16]; unsigned long oidlen; -} ltc_ecc_set_type; +} ltc_ecc_curve; /** A point on a ECC curve, stored in Jacbobian format such that (x,y,z) => (x/z^2, y/z^3, 1) when interpretted as affine */ typedef struct { @@ -336,29 +336,29 @@ } ecc_key; /** the ECC params provided */ -extern const ltc_ecc_set_type ltc_ecc_sets[]; +extern const ltc_ecc_curve ltc_ecc_curves[]; int ecc_test(void); void ecc_sizes(int *low, int *high); int ecc_get_size(ecc_key *key); -int ecc_get_set_by_name(const char* name, const ltc_ecc_set_type** dp); -int ecc_set_dp(const ltc_ecc_set_type *set, ecc_key *key); +int ecc_get_curve_by_name(const char* name, const ltc_ecc_curve** cu); +int ecc_set_dp(const ltc_ecc_curve *cu, ecc_key *key); int ecc_generate_key(prng_state *prng, int wprng, ecc_key *key); int ecc_set_key(const unsigned char *in, unsigned long inlen, int type, ecc_key *key); int ecc_get_key(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key); -int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp); +int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_curve *cu); void ecc_free(ecc_key *key); int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key); -int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp); +int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_curve *cu); int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen); int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key); -int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp); +int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_curve *cu); int ecc_export_openssl(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); int ecc_import_openssl(const unsigned char *in, unsigned long inlen, ecc_key *key); @@ -397,16 +397,18 @@ #ifdef LTC_SOURCE /* INTERNAL ONLY - it should be later moved to src/headers/tomcrypt_internal.h */ -int ecc_set_dp_bn(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key); -int ecc_set_dp_oid(unsigned long *oid, unsigned long oidsize, ecc_key *key); -int ecc_set_dp_copy(ecc_key *srckey, ecc_key *key); -int ecc_set_dp_size(int size, ecc_key *key); +int ecc_set_dp_from_mpis(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key); +int ecc_set_dp_by_oid(unsigned long *oid, unsigned long oidsize, ecc_key *key); +int ecc_copy_dp(const ecc_key *srckey, ecc_key *key); +int ecc_set_dp_by_size(int size, ecc_key *key); /* low level functions */ ecc_point *ltc_ecc_new_point(void); void ltc_ecc_del_point(ecc_point *p); +int ltc_ecc_set_point_xyz(ltc_mp_digit x, ltc_mp_digit y, ltc_mp_digit z, ecc_point *p); +int ltc_ecc_copy_point(const ecc_point *src, ecc_point *dst); int ltc_ecc_is_point(const ltc_ecc_dp *dp, void *x, void *y); -int ltc_ecc_is_point_at_infinity(const ecc_point *p, void *modulus); +int ltc_ecc_is_point_at_infinity(const ecc_point *P, void *modulus, int *retval); int ltc_ecc_import_point(const unsigned char *in, unsigned long inlen, void *prime, void *a, void *b, void *x, void *y); int ltc_ecc_export_point(unsigned char *out, unsigned long *outlen, void *x, void *y, unsigned long size, int compressed); int ltc_ecc_verify_key(ecc_key *key); diff --git a/src/ltc/math/tfm_desc.c b/src/ltc/math/tfm_desc.c index 9247db6..81f14b8 100644 --- a/src/ltc/math/tfm_desc.c +++ b/src/ltc/math/tfm_desc.c @@ -265,15 +265,7 @@ return CRYPT_OK; } -/* sqrtmod_prime */ -static int sqrtmod_prime(void *a, void *b, void *c) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - LTC_ARGCHK(c != NULL); - fprintf(stderr, "TFM does not support sqrtmod_prime\n"); /* XXX-FIXME */ - return CRYPT_ERROR; -} +/* sqrtmod_prime - NOT SUPPORTED */ /* div */ static int divide(void *a, void *b, void *c, void *d) @@ -438,6 +430,7 @@ { fp_int t1, t2; fp_digit mp; + int err, inf; LTC_ARGCHK(P != NULL); LTC_ARGCHK(R != NULL); @@ -455,7 +448,8 @@ fp_copy(P->z, R->z); } - if (ltc_ecc_is_point_at_infinity(P, modulus)) { + if ((err = ltc_ecc_is_point_at_infinity(P, modulus, &inf)) != CRYPT_OK) return err; + if (inf) { /* if P is point at infinity >> Result = point at infinity */ ltc_mp.set_int(R->x, 1); ltc_mp.set_int(R->y, 1); @@ -591,6 +585,7 @@ { fp_int t1, t2, x, y, z; fp_digit mp; + int err, inf; LTC_ARGCHK(P != NULL); LTC_ARGCHK(Q != NULL); @@ -606,7 +601,8 @@ fp_init(&y); fp_init(&z); - if (ltc_ecc_is_point_at_infinity(P, modulus)) { + if ((err = ltc_ecc_is_point_at_infinity(P, modulus, &inf)) != CRYPT_OK) return err; + if (inf) { /* P is point at infinity >> Result = Q */ ltc_mp.copy(Q->x, R->x); ltc_mp.copy(Q->y, R->y); @@ -614,7 +610,8 @@ return CRYPT_OK; } - if (ltc_ecc_is_point_at_infinity(Q, modulus)) { + if ((err = ltc_ecc_is_point_at_infinity(Q, modulus, &inf)) != CRYPT_OK) return err; + if (inf) { /* Q is point at infinity >> Result = P */ ltc_mp.copy(P->x, R->x); ltc_mp.copy(P->y, R->y); @@ -803,7 +800,7 @@ &mul, &muli, &sqr, - &sqrtmod_prime, + NULL, /* TODO: &sqrtmod_prime */ ÷, &div_2, &modi, diff --git a/src/ltc/misc/base16/base16_decode.c b/src/ltc/misc/base16/base16_decode.c index 5743be9..6738285 100644 --- a/src/ltc/misc/base16/base16_decode.c +++ b/src/ltc/misc/base16/base16_decode.c @@ -25,33 +25,42 @@ @param outlen [in/out] The max size and resulting size of the decoded data @return CRYPT_OK if successful */ -int base16_decode(const char *in, +int base16_decode(const char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { - unsigned long pos, in_len, out_len; - unsigned char idx0; - unsigned char idx1; + unsigned long pos, out_len; + unsigned char idx0, idx1; + char in0, in1; const unsigned char hashmap[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 01234567 */ - 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 89:;<=>? */ - 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, /* @ABCDEFG */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* HIJKLMNO */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* PQRSTUVW */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* XYZ[\]^_ */ - 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, /* `abcdefg */ + 0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 89:;<=>? */ + 0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, /* @ABCDEFG */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* HIJKLMNO */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* PQRSTUVW */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* XYZ[\]^_ */ + 0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, /* `abcdefg */ }; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); - in_len = strlen(in); - if ((in_len % 2) == 1) return CRYPT_INVALID_PACKET; + if ((inlen % 2) == 1) return CRYPT_INVALID_PACKET; out_len = *outlen * 2; - for (pos = 0; ((pos + 1 < out_len) && (pos + 1 < in_len)); pos += 2) { - idx0 = (unsigned char) (in[pos + 0] & 0x1F) ^ 0x10; - idx1 = (unsigned char) (in[pos + 1] & 0x1F) ^ 0x10; + for (pos = 0; ((pos + 1 < out_len) && (pos + 1 < inlen)); pos += 2) { + in0 = in[pos + 0]; + in1 = in[pos + 1]; + + if ((in0 < '0') || (in0 > 'g')) return CRYPT_INVALID_PACKET; + if ((in1 < '0') || (in1 > 'g')) return CRYPT_INVALID_PACKET; + + idx0 = (unsigned char) (in0 & 0x1F) ^ 0x10; + idx1 = (unsigned char) (in1 & 0x1F) ^ 0x10; + + if (hashmap[idx0] == 0xff) return CRYPT_INVALID_PACKET; + if (hashmap[idx1] == 0xff) return CRYPT_INVALID_PACKET; + out[pos / 2] = (unsigned char) (hashmap[idx0] << 4) | hashmap[idx1]; } *outlen = pos / 2; diff --git a/src/ltc/misc/base32/base32_encode.c b/src/ltc/misc/base32/base32_encode.c index 0e07263..13c7ce0 100644 --- a/src/ltc/misc/base32/base32_encode.c +++ b/src/ltc/misc/base32/base32_encode.c @@ -39,19 +39,19 @@ LTC_ARGCHK(id >= BASE32_RFC4648); LTC_ARGCHK(id <= BASE32_CROCKFORD); - /* no input, nothing to do */ - if (inlen == 0) { - *outlen = 0; - return CRYPT_OK; - } - - /* check the size of output buffer */ - x = (8 * inlen + 4) / 5; + /* check the size of output buffer +1 byte for terminating NUL */ + x = (8 * inlen + 4) / 5 + 1; if (*outlen < x) { *outlen = x; return CRYPT_BUFFER_OVERFLOW; } *outlen = x; + + /* no input, nothing to do */ + if (inlen == 0) { + *out = '\0'; + return CRYPT_OK; + } codes = alphabet[id]; x = 5 * (inlen / 5); @@ -79,12 +79,13 @@ } if (i+2 < inlen) { *out++ = codes[(((c & 0xF) << 1) + (d >> 7)) & 0x1F]; - *out++ = codes[(d >> 2) & 0x1F]; } if (i+3 < inlen) { + *out++ = codes[(d >> 2) & 0x1F]; *out++ = codes[((d & 0x3) << 3) & 0x1F]; } } + *out = '\0'; return CRYPT_OK; } diff --git a/src/ltc/misc/base64/base64_decode.c b/src/ltc/misc/base64/base64_decode.c index 90d7451..6af4eb5 100644 --- a/src/ltc/misc/base64/base64_decode.c +++ b/src/ltc/misc/base64/base64_decode.c @@ -17,9 +17,9 @@ #if defined(LTC_BASE64) || defined (LTC_BASE64_URL) -/* 253 - ignored in "relaxed" mode: TAB(9), CR(13), LF(10), space(32) +/* 253 - ignored in "relaxed" + "insane" mode: TAB(9), CR(13), LF(10), space(32) * 254 - padding character '=' (allowed only at the end) - * 255 - invalid character (not allowed even in relaxed mode) + * 255 - ignored in "insane" mode, but not allowed in "relaxed" + "strict" mode */ #if defined(LTC_BASE64) @@ -76,13 +76,14 @@ }; enum { - relaxed = 0, - strict = 1 + insane = 0, + strict = 1, + relaxed = 2 }; -static int _base64_decode_internal(const unsigned char *in, unsigned long inlen, +static int _base64_decode_internal(const char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, - const unsigned char *map, int is_strict) + const unsigned char *map, int mode) { unsigned long t, x, y, z; unsigned char c; @@ -94,23 +95,28 @@ g = 0; /* '=' counter */ for (x = y = z = t = 0; x < inlen; x++) { - if (in[x] == 0 && x == (inlen - 1)) continue; /* allow the last byte to be NUL */ - c = map[in[x]&0xFF]; + if ((in[x] == 0) && (x == (inlen - 1)) && (mode != strict)) { + continue; /* allow the last byte to be NUL (relaxed+insane) */ + } + c = map[(unsigned char)in[x]&0xFF]; if (c == 254) { g++; continue; } if (c == 253) { - if (is_strict) + if (mode == strict) return CRYPT_INVALID_PACKET; else - continue; + continue; /* allow to ignore white-spaces (relaxed+insane) */ } if (c == 255) { - return CRYPT_INVALID_PACKET; - } - if (g > 0) { - /* we only allow '=' to be at the end */ + if (mode == insane) + continue; /* allow to ignore invalid garbage (insane) */ + else + return CRYPT_INVALID_PACKET; + } + if ((g > 0) && (mode != insane)) { + /* we only allow '=' to be at the end (strict+relaxed) */ return CRYPT_INVALID_PACKET; } @@ -127,7 +133,7 @@ if (y != 0) { if (y == 1) return CRYPT_INVALID_PACKET; - if ((y + g) != 4 && is_strict && map != map_base64url) return CRYPT_INVALID_PACKET; + if (((y + g) != 4) && (mode == strict) && (map != map_base64url)) return CRYPT_INVALID_PACKET; t = t << (6 * (4 - y)); if (z + y - 1 > *outlen) return CRYPT_BUFFER_OVERFLOW; if (y >= 2) out[z++] = (unsigned char) ((t >> 16) & 255); @@ -139,17 +145,17 @@ #if defined(LTC_BASE64) /** - Relaxed base64 decode a block of memory - @param in The base64 data to decode - @param inlen The length of the base64 data - @param out [out] The destination of the binary decoded data - @param outlen [in/out] The max size and resulting size of the decoded data - @return CRYPT_OK if successful -*/ -int base64_decode(const unsigned char *in, unsigned long inlen, + Dangerously relaxed base64 decode a block of memory + @param in The base64 data to decode + @param inlen The length of the base64 data + @param out [out] The destination of the binary decoded data + @param outlen [in/out] The max size and resulting size of the decoded data + @return CRYPT_OK if successful +*/ +int base64_decode(const char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { - return _base64_decode_internal(in, inlen, out, outlen, map_base64, relaxed); + return _base64_decode_internal(in, inlen, out, outlen, map_base64, insane); } /** @@ -160,40 +166,68 @@ @param outlen [in/out] The max size and resulting size of the decoded data @return CRYPT_OK if successful */ -int base64_strict_decode(const unsigned char *in, unsigned long inlen, +int base64_strict_decode(const char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { return _base64_decode_internal(in, inlen, out, outlen, map_base64, strict); } + +/** + Sane base64 decode a block of memory + @param in The base64 data to decode + @param inlen The length of the base64 data + @param out [out] The destination of the binary decoded data + @param outlen [in/out] The max size and resulting size of the decoded data + @return CRYPT_OK if successful +*/ +int base64_sane_decode(const char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + return _base64_decode_internal(in, inlen, out, outlen, map_base64, relaxed); +} #endif /* LTC_BASE64 */ #if defined(LTC_BASE64_URL) /** - Relaxed base64 (URL Safe, RFC 4648 section 5) decode a block of memory - @param in The base64 data to decode - @param inlen The length of the base64 data - @param out [out] The destination of the binary decoded data - @param outlen [in/out] The max size and resulting size of the decoded data - @return CRYPT_OK if successful -*/ -int base64url_decode(const unsigned char *in, unsigned long inlen, + Dangerously relaxed base64 (URL Safe, RFC 4648 section 5) decode a block of memory + @param in The base64 data to decode + @param inlen The length of the base64 data + @param out [out] The destination of the binary decoded data + @param outlen [in/out] The max size and resulting size of the decoded data + @return CRYPT_OK if successful +*/ +int base64url_decode(const char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { + return _base64_decode_internal(in, inlen, out, outlen, map_base64url, insane); +} + +/** + Strict base64 (URL Safe, RFC 4648 section 5) decode a block of memory + @param in The base64 data to decode + @param inlen The length of the base64 data + @param out [out] The destination of the binary decoded data + @param outlen [in/out] The max size and resulting size of the decoded data + @return CRYPT_OK if successful +*/ +int base64url_strict_decode(const char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + return _base64_decode_internal(in, inlen, out, outlen, map_base64url, strict); +} + +/** + Sane base64 (URL Safe, RFC 4648 section 5) decode a block of memory + @param in The base64 data to decode + @param inlen The length of the base64 data + @param out [out] The destination of the binary decoded data + @param outlen [in/out] The max size and resulting size of the decoded data + @return CRYPT_OK if successful +*/ +int base64url_sane_decode(const char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ return _base64_decode_internal(in, inlen, out, outlen, map_base64url, relaxed); -} - -/** - Strict base64 (URL Safe, RFC 4648 section 5) decode a block of memory - @param in The base64 data to decode - @param inlen The length of the base64 data - @param out [out] The destination of the binary decoded data - @param outlen [in/out] The max size and resulting size of the decoded data - @return CRYPT_OK if successful -*/ -int base64url_strict_decode(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen) -{ - return _base64_decode_internal(in, inlen, out, outlen, map_base64url, strict); } #endif /* LTC_BASE64_URL */ diff --git a/src/ltc/misc/base64/base64_encode.c b/src/ltc/misc/base64/base64_encode.c index 5c26e60..985ba8d 100644 --- a/src/ltc/misc/base64/base64_encode.c +++ b/src/ltc/misc/base64/base64_encode.c @@ -28,11 +28,11 @@ #endif /* LTC_BASE64_URL */ static int _base64_encode_internal(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, + char *out, unsigned long *outlen, const char *codes, int pad) { unsigned long i, len2, leven; - unsigned char *p; + char *p; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); @@ -87,7 +87,7 @@ @return CRYPT_OK if successful */ int base64_encode(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen) + char *out, unsigned long *outlen) { return _base64_encode_internal(in, inlen, out, outlen, codes_base64, 1); } @@ -104,13 +104,13 @@ @return CRYPT_OK if successful */ int base64url_encode(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen) + char *out, unsigned long *outlen) { return _base64_encode_internal(in, inlen, out, outlen, codes_base64url, 0); } int base64url_strict_encode(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen) + char *out, unsigned long *outlen) { return _base64_encode_internal(in, inlen, out, outlen, codes_base64url, 1); } diff --git a/src/ltc/misc/crypt/crypt_sizes.c b/src/ltc/misc/crypt/crypt_sizes.c index c4b16b5..af70061 100644 --- a/src/ltc/misc/crypt/crypt_sizes.c +++ b/src/ltc/misc/crypt/crypt_sizes.c @@ -245,7 +245,7 @@ _SZ_STRINGIFY_T(dh_key), #endif #ifdef LTC_MECC - _SZ_STRINGIFY_T(ltc_ecc_set_type), + _SZ_STRINGIFY_T(ltc_ecc_curve), _SZ_STRINGIFY_T(ecc_point), _SZ_STRINGIFY_T(ecc_key), #endif diff --git a/src/ltc/modes/ctr/ctr_encrypt.c b/src/ltc/modes/ctr/ctr_encrypt.c index 7319cf5..eb7328c 100644 --- a/src/ltc/modes/ctr/ctr_encrypt.c +++ b/src/ltc/modes/ctr/ctr_encrypt.c @@ -17,46 +17,16 @@ #ifdef LTC_CTR_MODE /** - CTR encrypt + CTR encrypt software implementation @param pt Plaintext @param ct [out] Ciphertext @param len Length of plaintext (octets) @param ctr CTR state @return CRYPT_OK if successful */ -int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr) +static int _ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr) { int x, err; - - LTC_ARGCHK(pt != NULL); - LTC_ARGCHK(ct != NULL); - LTC_ARGCHK(ctr != NULL); - - if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { - return err; - } - - /* is blocklen/padlen valid? */ - if (ctr->blocklen < 1 || ctr->blocklen > (int)sizeof(ctr->ctr) || - ctr->padlen < 0 || ctr->padlen > (int)sizeof(ctr->pad)) { - return CRYPT_INVALID_ARG; - } - -#ifdef LTC_FAST - if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) { - return CRYPT_INVALID_ARG; - } -#endif - - /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */ - if ((ctr->padlen == ctr->blocklen) && cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL && (len >= (unsigned long)ctr->blocklen)) { - if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) { - return err; - } - pt += (len / ctr->blocklen) * ctr->blocklen; - ct += (len / ctr->blocklen) * ctr->blocklen; - len %= ctr->blocklen; - } while (len) { /* is the pad empty? */ @@ -87,7 +57,7 @@ ctr->padlen = 0; } #ifdef LTC_FAST - if (ctr->padlen == 0 && len >= (unsigned long)ctr->blocklen) { + if ((ctr->padlen == 0) && (len >= (unsigned long)ctr->blocklen)) { for (x = 0; x < ctr->blocklen; x += sizeof(LTC_FAST_TYPE)) { *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) ^ *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ctr->pad + x)); @@ -105,6 +75,63 @@ return CRYPT_OK; } +/** + CTR encrypt + @param pt Plaintext + @param ct [out] Ciphertext + @param len Length of plaintext (octets) + @param ctr CTR state + @return CRYPT_OK if successful +*/ +int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr) +{ + int err, fr; + + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(ctr != NULL); + + if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen/padlen valid? */ + if ((ctr->blocklen < 1) || (ctr->blocklen > (int)sizeof(ctr->ctr)) || + (ctr->padlen < 0) || (ctr->padlen > (int)sizeof(ctr->pad))) { + return CRYPT_INVALID_ARG; + } + +#ifdef LTC_FAST + if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */ + if ((cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL) && (len >= (unsigned long)ctr->blocklen)) { + if (ctr->padlen < ctr->blocklen) { + fr = ctr->blocklen - ctr->padlen; + if ((err = _ctr_encrypt(pt, ct, fr, ctr)) != CRYPT_OK) { + return err; + } + pt += fr; + ct += fr; + len -= fr; + } + + if (len >= (unsigned long)ctr->blocklen) { + if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) { + return err; + } + pt += (len / ctr->blocklen) * ctr->blocklen; + ct += (len / ctr->blocklen) * ctr->blocklen; + len %= ctr->blocklen; + } + } + + return _ctr_encrypt(pt, ct, len, ctr); +} + #endif /* ref: $Format:%D$ */ diff --git a/src/ltc/pk/ecc/ecc.c b/src/ltc/pk/ecc/ecc.c index b90afc7..f6d69e4 100644 --- a/src/ltc/pk/ecc/ecc.c +++ b/src/ltc/pk/ecc/ecc.c @@ -23,10 +23,10 @@ * - ANS X9.62 (named: PRIMEP*) * - http://www.ecc-brainpool.org/download/Domain-parameters.pdf (named: BRAINPOOLP*) */ -const ltc_ecc_set_type ltc_ecc_sets[] = { +const ltc_ecc_curve ltc_ecc_curves[] = { #if defined(LTC_ECC_SECP112R1) || defined(LTC_ECC112) { - /* curve name */ "SECP112R1", + /* curve name */ { "SECP112R1", "ECC-112", NULL }, /* prime */ "DB7C2ABF62E35E668076BEAD208B", /* A */ "DB7C2ABF62E35E668076BEAD2088", /* B */ "659EF8BA043916EEDE8911702B22", @@ -39,7 +39,7 @@ #endif #ifdef LTC_ECC_SECP112R2 { - /* curve name */ "SECP112R2", + /* curve name */ { "SECP112R2", NULL }, /* prime */ "DB7C2ABF62E35E668076BEAD208B", /* A */ "6127C24C05F38A0AAAF65C0EF02C", /* B */ "51DEF1815DB5ED74FCC34C85D709", @@ -52,7 +52,7 @@ #endif #if defined(LTC_ECC_SECP128R1) || defined(LTC_ECC128) { - /* curve name */ "SECP128R1", + /* curve name */ { "SECP128R1", "ECC-128", NULL }, /* prime */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* A */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", /* B */ "E87579C11079F43DD824993C2CEE5ED3", @@ -65,7 +65,7 @@ #endif #ifdef LTC_ECC_SECP128R2 { - /* curve name */ "SECP128R2", + /* curve name */ { "SECP128R2", NULL }, /* prime */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* A */ "D6031998D1B3BBFEBF59CC9BBFF9AEE1", /* B */ "5EEEFCA380D02919DC2C6558BB6D8A5D", @@ -78,7 +78,7 @@ #endif #if defined(LTC_ECC_SECP160R1) || defined(LTC_ECC160) { - /* curve name */ "SECP160R1", + /* curve name */ { "SECP160R1", "ECC-160", NULL }, /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", /* B */ "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", @@ -91,7 +91,7 @@ #endif #ifdef LTC_ECC_SECP160R2 { - /* curve name */ "SECP160R2", + /* curve name */ { "SECP160R2", NULL }, /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", /* B */ "B4E134D3FB59EB8BAB57274904664D5AF50388BA", @@ -104,7 +104,7 @@ #endif #ifdef LTC_ECC_SECP160K1 { - /* curve name */ "SECP160K1", + /* curve name */ { "SECP160K1", NULL }, /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* A */ "0000000000000000000000000000000000000000", /* B */ "0000000000000000000000000000000000000007", @@ -117,7 +117,7 @@ #endif #if defined(LTC_ECC_SECP192R1) || defined(LTC_ECC192) { - /* curve name */ "SECP192R1", /* same as: NISTP192 PRIME192V1, old libtomcrypt name: ECC-192 */ + /* curve name */ { "SECP192R1", "NISTP192", "PRIME192V1", "ECC-192", "P-192", NULL }, /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* B */ "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", @@ -130,7 +130,7 @@ #endif #ifdef LTC_ECC_PRIME192V2 { - /* curve name */ "PRIME192V2", + /* curve name */ { "PRIME192V2", NULL }, /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* B */ "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", @@ -143,7 +143,7 @@ #endif #ifdef LTC_ECC_PRIME192V3 { - /* curve name */ "PRIME192V3", + /* curve name */ { "PRIME192V3", NULL }, /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* B */ "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", @@ -156,7 +156,7 @@ #endif #ifdef LTC_ECC_SECP192K1 { - /* curve name */ "SECP192K1", + /* curve name */ { "SECP192K1", NULL }, /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* A */ "000000000000000000000000000000000000000000000000", /* B */ "000000000000000000000000000000000000000000000003", @@ -169,7 +169,7 @@ #endif #if defined(LTC_ECC_SECP224R1) || defined(LTC_ECC224) { - /* curve name */ "SECP224R1", /* same as: NISTP224, old libtomcrypt name: ECC-224 */ + /* curve name */ { "SECP224R1", "NISTP224", "ECC-224", "P-224", NULL }, /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* B */ "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", @@ -182,7 +182,7 @@ #endif #ifdef LTC_ECC_SECP224K1 { - /* curve name */ "SECP224K1", + /* curve name */ { "SECP224K1", NULL }, /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* A */ "00000000000000000000000000000000000000000000000000000000", /* B */ "00000000000000000000000000000000000000000000000000000005", @@ -195,7 +195,7 @@ #endif #if defined(LTC_ECC_SECP256R1) || defined(LTC_ECC256) { - /* curve name */ "SECP256R1", /* same as: NISTP256 PRIME256V1, old libtomcrypt name: ECC-256 */ + /* curve name */ { "SECP256R1", "NISTP256", "PRIME256V1", "ECC-256", "P-256", NULL }, /* prime */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* A */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* B */ "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", @@ -208,7 +208,7 @@ #endif #ifdef LTC_ECC_SECP256K1 { - /* curve name */ "SECP256K1", + /* curve name */ { "SECP256K1", NULL }, /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* A */ "0000000000000000000000000000000000000000000000000000000000000000", /* B */ "0000000000000000000000000000000000000000000000000000000000000007", @@ -221,7 +221,7 @@ #endif #if defined(LTC_ECC_SECP384R1) || defined(LTC_ECC384) { - /* curve name */ "SECP384R1", /* same as: NISTP384, old libtomcrypt name: ECC-384 */ + /* curve name */ { "SECP384R1", "NISTP384", "ECC-384", "P-384", NULL }, /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* B */ "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", @@ -234,7 +234,7 @@ #endif #if defined(LTC_ECC_SECP521R1) || defined(LTC_ECC521) { - /* curve name */ "SECP521R1", /* same as: NISTP521, old libtomcrypt name: ECC-521 */ + /* curve name */ { "SECP521R1", "NISTP521", "ECC-521", "P-521", NULL }, /* prime */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* A */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* B */ "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", @@ -247,7 +247,7 @@ #endif #ifdef LTC_ECC_PRIME239V1 { - /* curve name */ "PRIME239V1", + /* curve name */ { "PRIME239V1", NULL }, /* prime */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* A */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* B */ "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", @@ -260,7 +260,7 @@ #endif #ifdef LTC_ECC_PRIME239V2 { - /* curve name */ "PRIME239V2", + /* curve name */ { "PRIME239V2", NULL }, /* prime */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* A */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* B */ "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", @@ -273,7 +273,7 @@ #endif #ifdef LTC_ECC_PRIME239V3 { - /* curve name */ "PRIME239V3", + /* curve name */ { "PRIME239V3", NULL }, /* prime */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* A */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* B */ "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", @@ -286,7 +286,7 @@ #endif #ifdef LTC_ECC_BRAINPOOLP160R1 { - /* curve name */ "BRAINPOOLP160R1", + /* curve name */ { "BRAINPOOLP160R1", NULL }, /* prime */ "E95E4A5F737059DC60DFC7AD95B3D8139515620F", /* A */ "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", /* B */ "1E589A8595423412134FAA2DBDEC95C8D8675E58", @@ -299,7 +299,7 @@ #endif #ifdef LTC_ECC_BRAINPOOLP192R1 { - /* curve name */ "BRAINPOOLP192R1", + /* curve name */ { "BRAINPOOLP192R1", NULL }, /* prime */ "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", /* A */ "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", /* B */ "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", @@ -312,7 +312,7 @@ #endif #ifdef LTC_ECC_BRAINPOOLP224R1 { - /* curve name */ "BRAINPOOLP224R1", + /* curve name */ { "BRAINPOOLP224R1", NULL }, /* prime */ "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", /* A */ "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", /* B */ "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", @@ -325,7 +325,7 @@ #endif #ifdef LTC_ECC_BRAINPOOLP256R1 { - /* curve name */ "BRAINPOOLP256R1", + /* curve name */ { "BRAINPOOLP256R1", NULL }, /* prime */ "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* A */ "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* B */ "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", @@ -338,7 +338,7 @@ #endif #ifdef LTC_ECC_BRAINPOOLP320R1 { - /* curve name */ "BRAINPOOLP320R1", + /* curve name */ { "BRAINPOOLP320R1", NULL }, /* prime */ "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", /* A */ "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", /* B */ "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", @@ -351,7 +351,7 @@ #endif #ifdef LTC_ECC_BRAINPOOLP384R1 { - /* curve name */ "BRAINPOOLP384R1", + /* curve name */ { "BRAINPOOLP384R1", NULL }, /* prime */ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* A */ "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* B */ "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", @@ -364,7 +364,7 @@ #endif #ifdef LTC_ECC_BRAINPOOLP512R1 { - /* curve name */ "BRAINPOOLP512R1", + /* curve name */ { "BRAINPOOLP512R1", NULL }, /* prime */ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* A */ "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* B */ "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", @@ -377,7 +377,7 @@ #endif #ifdef LTC_ECC_BRAINPOOLP160T1 { - /* curve name */ "BRAINPOOLP160T1", + /* curve name */ { "BRAINPOOLP160T1", NULL }, /* prime */ "E95E4A5F737059DC60DFC7AD95B3D8139515620F", /* A */ "E95E4A5F737059DC60DFC7AD95B3D8139515620C", /* B */ "7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380", @@ -390,7 +390,7 @@ #endif #ifdef LTC_ECC_BRAINPOOLP192T1 { - /* curve name */ "BRAINPOOLP192T1", + /* curve name */ { "BRAINPOOLP192T1", NULL }, /* prime */ "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", /* A */ "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294", /* B */ "13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79", @@ -403,7 +403,7 @@ #endif #ifdef LTC_ECC_BRAINPOOLP224T1 { - /* curve name */ "BRAINPOOLP224T1", + /* curve name */ { "BRAINPOOLP224T1", NULL }, /* prime */ "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", /* A */ "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC", /* B */ "4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D", @@ -416,7 +416,7 @@ #endif #ifdef LTC_ECC_BRAINPOOLP256T1 { - /* curve name */ "BRAINPOOLP256T1", + /* curve name */ { "BRAINPOOLP256T1", NULL }, /* prime */ "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* A */ "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374", /* B */ "662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04", @@ -429,7 +429,7 @@ #endif #ifdef LTC_ECC_BRAINPOOLP320T1 { - /* curve name */ "BRAINPOOLP320T1", + /* curve name */ { "BRAINPOOLP320T1", NULL }, /* prime */ "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", /* A */ "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E24", /* B */ "A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CEB5B4FEF422340353", @@ -442,7 +442,7 @@ #endif #ifdef LTC_ECC_BRAINPOOLP384T1 { - /* curve name */ "BRAINPOOLP384T1", + /* curve name */ { "BRAINPOOLP384T1", NULL }, /* prime */ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* A */ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC50", /* B */ "7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B88805CED70355A33B471EE", @@ -455,7 +455,7 @@ #endif #ifdef LTC_ECC_BRAINPOOLP512T1 { - /* curve name */ "BRAINPOOLP512T1", + /* curve name */ { "BRAINPOOLP512T1", NULL }, /* prime */ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* A */ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0", /* B */ "7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E", @@ -467,7 +467,8 @@ }, #endif { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, + { NULL }, + NULL, NULL, NULL, NULL, NULL, NULL, 0, { 0 }, 0 } diff --git a/src/ltc/pk/ecc/ecc_ansi_x963_import.c b/src/ltc/pk/ecc/ecc_ansi_x963_import.c index bcc8575..12b034d 100644 --- a/src/ltc/pk/ecc/ecc_ansi_x963_import.c +++ b/src/ltc/pk/ecc/ecc_ansi_x963_import.c @@ -26,7 +26,7 @@ return ecc_ansi_x963_import_ex(in, inlen, key, NULL); } -int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp) +int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_curve *cu) { int err; @@ -39,13 +39,13 @@ } /* initialize key->dp */ - if (dp == NULL) { + if (cu == NULL) { /* this case works only for uncompressed public keys */ - if ((err = ecc_set_dp_size((inlen-1)>>1, key)) != CRYPT_OK) { return err; } + if ((err = ecc_set_dp_by_size((inlen-1)>>1, key)) != CRYPT_OK) { return err; } } else { /* this one works for both compressed / uncompressed pubkeys */ - if ((err = ecc_set_dp(dp, key)) != CRYPT_OK) { return err; } + if ((err = ecc_set_dp(cu, key)) != CRYPT_OK) { return err; } } /* load public key */ diff --git a/src/ltc/pk/ecc/ecc_decrypt_key.c b/src/ltc/pk/ecc/ecc_decrypt_key.c index ebfa515..b5298d2 100644 --- a/src/ltc/pk/ecc/ecc_decrypt_key.c +++ b/src/ltc/pk/ecc/ecc_decrypt_key.c @@ -85,7 +85,7 @@ } /* import ECC key from packet */ - if ((err = ecc_set_dp_copy(key, &pubkey)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = ecc_copy_dp(key, &pubkey)) != CRYPT_OK) { goto LBL_ERR; } if ((err = ecc_set_key(decode[1].data, decode[1].size, PK_PUBLIC, &pubkey)) != CRYPT_OK) { goto LBL_ERR; } /* make shared key */ diff --git a/src/ltc/pk/ecc/ecc_encrypt_key.c b/src/ltc/pk/ecc/ecc_encrypt_key.c index 530eadd..1ccfd71 100644 --- a/src/ltc/pk/ecc/ecc_encrypt_key.c +++ b/src/ltc/pk/ecc/ecc_encrypt_key.c @@ -57,7 +57,7 @@ } /* make a random key and export the public copy */ - if ((err = ecc_set_dp_copy(key, &pubkey)) != CRYPT_OK) { return err; } + if ((err = ecc_copy_dp(key, &pubkey)) != CRYPT_OK) { return err; } if ((err = ecc_generate_key(prng, wprng, &pubkey)) != CRYPT_OK) { return err; } pub_expt = XMALLOC(ECC_BUF_SIZE); @@ -78,12 +78,14 @@ } pubkeysize = ECC_BUF_SIZE; -#ifdef USE_TFM - /* XXX-FIXME: TFM does not support sqrtmod_prime */ - if ((err = ecc_get_key(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { -#else - if ((err = ecc_get_key(pub_expt, &pubkeysize, PK_PUBLIC|PK_COMPRESSED, &pubkey)) != CRYPT_OK) { -#endif + if (ltc_mp.sqrtmod_prime != NULL) { + /* PK_COMPRESSED requires sqrtmod_prime */ + err = ecc_get_key(pub_expt, &pubkeysize, PK_PUBLIC|PK_COMPRESSED, &pubkey); + } + else { + err = ecc_get_key(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey); + } + if (err != CRYPT_OK) { ecc_free(&pubkey); goto LBL_ERR; } diff --git a/src/ltc/pk/ecc/ecc_free.c b/src/ltc/pk/ecc/ecc_free.c index c8033b3..47d3129 100644 --- a/src/ltc/pk/ecc/ecc_free.c +++ b/src/ltc/pk/ecc/ecc_free.c @@ -23,14 +23,12 @@ void ecc_free(ecc_key *key) { LTC_ARGCHKVD(key != NULL); - /* clean dp */ + mp_cleanup_multi(&key->dp.prime, &key->dp.order, &key->dp.A, &key->dp.B, &key->dp.base.x, &key->dp.base.y, &key->dp.base.z, - NULL); - - /* clean key */ - mp_cleanup_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL); + &key->pubkey.x, &key->pubkey.y, &key->pubkey.z, + &key->k, NULL); } #endif diff --git a/src/ltc/pk/ecc/ecc_get_curve_by_name.c b/src/ltc/pk/ecc/ecc_get_curve_by_name.c new file mode 100644 index 0000000..48db6d2 --- /dev/null +++ b/src/ltc/pk/ecc/ecc_get_curve_by_name.c @@ -0,0 +1,63 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +#include "tomcrypt.h" + +#ifdef LTC_MECC + +/* case-insensitive match + ignore '-', '_', ' ' */ +static int _name_match(const char *left, const char *right) +{ + char lc_r, lc_l; + + while ((*left != '\0') && (*right != '\0')) { + while ((*left == ' ') || (*left == '-') || (*left == '_')) left++; + while ((*right == ' ') || (*right == '-') || (*right == '_')) right++; + if (*left == '\0' || *right == '\0') break; + lc_r = *right; + lc_l = *left; + if ((lc_r >= 'A') && (lc_r <= 'Z')) lc_r += 32; + if ((lc_l >= 'A') && (lc_l <= 'Z')) lc_l += 32; + if (lc_l != lc_r) return 0; + left++; + right++; + } + + if ((*left == '\0') && (*right == '\0')) + return 1; + else + return 0; +} + +int ecc_get_curve_by_name(const char *name, const ltc_ecc_curve **cu) +{ + int i, j; + + LTC_ARGCHK(cu != NULL); + LTC_ARGCHK(name != NULL); + + *cu = NULL; + + for (i = 0; ltc_ecc_curves[i].prime != NULL; i++) { + for (j = 0; ltc_ecc_curves[i].names[j] != NULL; j++) { + if (_name_match(ltc_ecc_curves[i].names[j], name)) { + *cu = <c_ecc_curves[i]; + return CRYPT_OK; + } + } + } + + return CRYPT_INVALID_ARG; /* not found */ +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/ecc/ecc_get_set.c b/src/ltc/pk/ecc/ecc_get_set.c deleted file mode 100644 index f00cf45..0000000 --- a/src/ltc/pk/ecc/ecc_get_set.c +++ /dev/null @@ -1,40 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - */ - -#include "tomcrypt.h" - -#ifdef LTC_MECC - -int ecc_get_set_by_name(const char* name, const ltc_ecc_set_type** dp) -{ - int i; - - LTC_ARGCHK(dp != NULL); - LTC_ARGCHK(name != NULL); - - *dp = NULL; - - for (i = 0; ltc_ecc_sets[i].name != NULL; i++) { - if (XSTRCMP(ltc_ecc_sets[i].name, name) == 0) break; - } - - if (ltc_ecc_sets[i].name == NULL) { - /* not found */ - return CRYPT_INVALID_ARG; - } - - *dp = <c_ecc_sets[i]; - return CRYPT_OK; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/ecc/ecc_import.c b/src/ltc/pk/ecc/ecc_import.c index 3a1dcc5..6deea28 100644 --- a/src/ltc/pk/ecc/ecc_import.c +++ b/src/ltc/pk/ecc/ecc_import.c @@ -33,10 +33,10 @@ @param in The packet to import @param inlen The length of the packet @param key [out] The destination of the import - @param dp pointer to user supplied params; must be the same as the params used when exporting + @param cu pointer to user supplied params; must be the same as the params used when exporting @return CRYPT_OK if successful, upon error all allocated memory will be freed */ -int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp) +int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_curve *cu) { unsigned long key_size; unsigned char flags[1]; @@ -55,10 +55,10 @@ } /* allocate & initialize the key */ - if (dp == NULL) { - if ((err = ecc_set_dp_size(key_size, key)) != CRYPT_OK) { goto done; } + if (cu == NULL) { + if ((err = ecc_set_dp_by_size(key_size, key)) != CRYPT_OK) { goto done; } } else { - if ((err = ecc_set_dp(dp, key)) != CRYPT_OK) { goto done; } + if ((err = ecc_set_dp(cu, key)) != CRYPT_OK) { goto done; } } if (flags[0] == 1) { diff --git a/src/ltc/pk/ecc/ecc_import_openssl.c b/src/ltc/pk/ecc/ecc_import_openssl.c index 18316ee..489b975 100644 --- a/src/ltc/pk/ecc/ecc_import_openssl.c +++ b/src/ltc/pk/ecc/ecc_import_openssl.c @@ -31,7 +31,7 @@ err = x509_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy, LTC_ASN1_OBJECT_IDENTIFIER, (void *)curveoid, &len_oid); if (err == CRYPT_OK) { /* load curve parameters for given curve OID */ - if ((err = ecc_set_dp_oid(curveoid, len_oid, key)) != CRYPT_OK) { goto error; } + if ((err = ecc_set_dp_by_oid(curveoid, len_oid, key)) != CRYPT_OK) { goto error; } /* load public key */ if ((err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key)) != CRYPT_OK) { goto error; } goto success; @@ -69,7 +69,7 @@ if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; } if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; } /* load curve parameters */ - if ((err = ecc_set_dp_bn(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; } + if ((err = ecc_set_dp_from_mpis(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; } /* load public key */ if ((err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key)) != CRYPT_OK) { goto error; } goto success; @@ -89,7 +89,7 @@ err = der_decode_sequence(in, inlen, seq_priv, 4); if (err == CRYPT_OK) { /* load curve parameters for given curve OID */ - if ((err = ecc_set_dp_oid(curveoid, custom[0].size, key)) != CRYPT_OK) { goto error; } + if ((err = ecc_set_dp_by_oid(curveoid, custom[0].size, key)) != CRYPT_OK) { goto error; } /* load private+public key */ if ((err = ecc_set_key(bin_k, seq_priv[1].size, PK_PRIVATE, key)) != CRYPT_OK) { goto error; } goto success; @@ -133,7 +133,7 @@ if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; } if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; } /* load curve parameters */ - if ((err = ecc_set_dp_bn(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; } + if ((err = ecc_set_dp_from_mpis(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; } /* load private+public key */ if ((err = ecc_set_key(bin_k, len_k, PK_PRIVATE, key)) != CRYPT_OK) { goto error; } goto success; diff --git a/src/ltc/pk/ecc/ecc_import_pkcs8.c b/src/ltc/pk/ecc/ecc_import_pkcs8.c index 6b5b0c7..01aa525 100644 --- a/src/ltc/pk/ecc/ecc_import_pkcs8.c +++ b/src/ltc/pk/ecc/ecc_import_pkcs8.c @@ -500,7 +500,7 @@ * 23:d=1 hl=2 l= 77 prim: OCTET STRING :bytes (== privatekey) */ ltc_asn1_list *loid = lseq->child->next; - if ((err = ecc_set_dp_oid(loid->data, loid->size, key)) != CRYPT_OK) { + if ((err = ecc_set_dp_by_oid(loid->data, loid->size, key)) != CRYPT_OK) { goto LBL_DONE; } } @@ -553,7 +553,7 @@ if ((err = ltc_ecc_import_point(lg->data, lg->size, lprime->data, a, b, gx, gy)) != CRYPT_OK) { goto LBL_DONE; } - if ((err = ecc_set_dp_bn(a, b, lprime->data, lorder->data, gx, gy, cofactor, key)) != CRYPT_OK) { + if ((err = ecc_set_dp_from_mpis(a, b, lprime->data, lorder->data, gx, gy, cofactor, key)) != CRYPT_OK) { goto LBL_DONE; } } diff --git a/src/ltc/pk/ecc/ecc_make_key.c b/src/ltc/pk/ecc/ecc_make_key.c index 4617bef..1666017 100644 --- a/src/ltc/pk/ecc/ecc_make_key.c +++ b/src/ltc/pk/ecc/ecc_make_key.c @@ -28,15 +28,15 @@ { int err; - if ((err = ecc_set_dp_size(keysize, key)) != CRYPT_OK) { return err; } + if ((err = ecc_set_dp_by_size(keysize, key)) != CRYPT_OK) { return err; } if ((err = ecc_generate_key(prng, wprng, key)) != CRYPT_OK) { return err; } return CRYPT_OK; } -int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp) +int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_curve *cu) { int err; - if ((err = ecc_set_dp(dp, key)) != CRYPT_OK) { return err; } + if ((err = ecc_set_dp(cu, key)) != CRYPT_OK) { return err; } if ((err = ecc_generate_key(prng, wprng, key)) != CRYPT_OK) { return err; } return CRYPT_OK; } diff --git a/src/ltc/pk/ecc/ecc_set_dp.c b/src/ltc/pk/ecc/ecc_set_dp.c index 17a0d2a..52a10dc 100644 --- a/src/ltc/pk/ecc/ecc_set_dp.c +++ b/src/ltc/pk/ecc/ecc_set_dp.c @@ -11,13 +11,13 @@ #ifdef LTC_MECC -int ecc_set_dp(const ltc_ecc_set_type *set, ecc_key *key) +int ecc_set_dp(const ltc_ecc_curve *curve, ecc_key *key) { unsigned long i; int err; LTC_ARGCHK(key != NULL); - LTC_ARGCHK(set != NULL); + LTC_ARGCHK(curve != NULL); if ((err = mp_init_multi(&key->dp.prime, &key->dp.order, &key->dp.A, &key->dp.B, &key->dp.base.x, &key->dp.base.y, &key->dp.base.z, @@ -27,19 +27,19 @@ } /* A, B, order, prime, Gx, Gy */ - if ((err = mp_read_radix(key->dp.prime, set->prime, 16)) != CRYPT_OK) { goto error; } - if ((err = mp_read_radix(key->dp.order, set->order, 16)) != CRYPT_OK) { goto error; } - if ((err = mp_read_radix(key->dp.A, set->A, 16)) != CRYPT_OK) { goto error; } - if ((err = mp_read_radix(key->dp.B, set->B, 16)) != CRYPT_OK) { goto error; } - if ((err = mp_read_radix(key->dp.base.x, set->Gx, 16)) != CRYPT_OK) { goto error; } - if ((err = mp_read_radix(key->dp.base.y, set->Gy, 16)) != CRYPT_OK) { goto error; } - if ((err = mp_set(key->dp.base.z, 1)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(key->dp.prime, curve->prime, 16)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(key->dp.order, curve->order, 16)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(key->dp.A, curve->A, 16)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(key->dp.B, curve->B, 16)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(key->dp.base.x, curve->Gx, 16)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(key->dp.base.y, curve->Gy, 16)) != CRYPT_OK) { goto error; } + if ((err = mp_set(key->dp.base.z, 1)) != CRYPT_OK) { goto error; } /* cofactor & size */ - key->dp.cofactor = set->cofactor; + key->dp.cofactor = curve->cofactor; key->dp.size = mp_unsigned_bin_size(key->dp.prime); /* OID */ - key->dp.oidlen = set->oidlen; - for (i = 0; i < key->dp.oidlen; i++) key->dp.oid[i] = set->oid[i]; + key->dp.oidlen = curve->oidlen; + for (i = 0; i < key->dp.oidlen; i++) key->dp.oid[i] = curve->oid[i]; /* success */ return CRYPT_OK; @@ -48,44 +48,38 @@ return err; } -int ecc_set_dp_size(int size, ecc_key *key) +int ecc_set_dp_by_size(int size, ecc_key *key) { - const ltc_ecc_set_type *dp = NULL; - int err; + const ltc_ecc_curve *cu = NULL; + int err = CRYPT_ERROR; /* for compatibility with libtomcrypt-1.17 the sizes below must match the specific curves */ if (size <= 14) { - if ((err = ecc_get_set_by_name("SECP112R1", &dp)) != CRYPT_OK) return err; - return ecc_set_dp(dp, key); + err = ecc_get_curve_by_name("SECP112R1", &cu); } else if (size <= 16) { - if ((err = ecc_get_set_by_name("SECP128R1", &dp)) != CRYPT_OK) return err; - return ecc_set_dp(dp, key); + err = ecc_get_curve_by_name("SECP128R1", &cu); } else if (size <= 20) { - if ((err = ecc_get_set_by_name("SECP160R1", &dp)) != CRYPT_OK) return err; - return ecc_set_dp(dp, key); + err = ecc_get_curve_by_name("SECP160R1", &cu); } else if (size <= 24) { - if ((err = ecc_get_set_by_name("SECP192R1", &dp)) != CRYPT_OK) return err; - return ecc_set_dp(dp, key); + err = ecc_get_curve_by_name("SECP192R1", &cu); } else if (size <= 28) { - if ((err = ecc_get_set_by_name("SECP224R1", &dp)) != CRYPT_OK) return err; - return ecc_set_dp(dp, key); + err = ecc_get_curve_by_name("SECP224R1", &cu); } else if (size <= 32) { - if ((err = ecc_get_set_by_name("SECP256R1", &dp)) != CRYPT_OK) return err; - return ecc_set_dp(dp, key); + err = ecc_get_curve_by_name("SECP256R1", &cu); } else if (size <= 48) { - if ((err = ecc_get_set_by_name("SECP384R1", &dp)) != CRYPT_OK) return err; - return ecc_set_dp(dp, key); + err = ecc_get_curve_by_name("SECP384R1", &cu); } else if (size <= 66) { - if ((err = ecc_get_set_by_name("SECP521R1", &dp)) != CRYPT_OK) return err; - return ecc_set_dp(dp, key); + err = ecc_get_curve_by_name("SECP521R1", &cu); } + + if (err == CRYPT_OK && cu != NULL) return ecc_set_dp(cu, key); return CRYPT_INVALID_ARG; } diff --git a/src/ltc/pk/ecc/ecc_set_dp_internal.c b/src/ltc/pk/ecc/ecc_set_dp_internal.c index bd7c040..8114048 100644 --- a/src/ltc/pk/ecc/ecc_set_dp_internal.c +++ b/src/ltc/pk/ecc/ecc_set_dp_internal.c @@ -16,52 +16,52 @@ int err; unsigned i; void *tmp; - const ltc_ecc_set_type *set; + const ltc_ecc_curve *curve; key->dp.oidlen = 0; if ((err = mp_init(&tmp)) != CRYPT_OK) return; - for (set = ltc_ecc_sets; set->name != NULL; set++) { - if ((err = mp_read_radix(tmp, set->prime, 16)) != CRYPT_OK) continue; + for (curve = ltc_ecc_curves; curve->prime != NULL; curve++) { + if ((err = mp_read_radix(tmp, curve->prime, 16)) != CRYPT_OK) continue; if ((mp_cmp(tmp, key->dp.prime) != LTC_MP_EQ)) continue; - if ((err = mp_read_radix(tmp, set->order, 16)) != CRYPT_OK) continue; + if ((err = mp_read_radix(tmp, curve->order, 16)) != CRYPT_OK) continue; if ((mp_cmp(tmp, key->dp.order) != LTC_MP_EQ)) continue; - if ((err = mp_read_radix(tmp, set->A, 16)) != CRYPT_OK) continue; + if ((err = mp_read_radix(tmp, curve->A, 16)) != CRYPT_OK) continue; if ((mp_cmp(tmp, key->dp.A) != LTC_MP_EQ)) continue; - if ((err = mp_read_radix(tmp, set->B, 16)) != CRYPT_OK) continue; + if ((err = mp_read_radix(tmp, curve->B, 16)) != CRYPT_OK) continue; if ((mp_cmp(tmp, key->dp.B) != LTC_MP_EQ)) continue; - if ((err = mp_read_radix(tmp, set->Gx, 16)) != CRYPT_OK) continue; + if ((err = mp_read_radix(tmp, curve->Gx, 16)) != CRYPT_OK) continue; if ((mp_cmp(tmp, key->dp.base.x) != LTC_MP_EQ)) continue; - if ((err = mp_read_radix(tmp, set->Gy, 16)) != CRYPT_OK) continue; + if ((err = mp_read_radix(tmp, curve->Gy, 16)) != CRYPT_OK) continue; if ((mp_cmp(tmp, key->dp.base.y) != LTC_MP_EQ)) continue; - if (key->dp.cofactor != set->cofactor) continue; + if (key->dp.cofactor != curve->cofactor) continue; break; /* found */ } mp_clear(tmp); - if (set->name != NULL) { + if (curve->prime != NULL) { /* OID found */ - key->dp.oidlen = set->oidlen; - for(i = 0; i < set->oidlen; i++) key->dp.oid[i] = set->oid[i]; + key->dp.oidlen = curve->oidlen; + for(i = 0; i < curve->oidlen; i++) key->dp.oid[i] = curve->oid[i]; } } -int ecc_set_dp_oid(unsigned long *oid, unsigned long oidsize, ecc_key *key) +int ecc_set_dp_by_oid(unsigned long *oid, unsigned long oidsize, ecc_key *key) { int i; LTC_ARGCHK(oid != NULL); LTC_ARGCHK(oidsize > 0); - for(i = 0; ltc_ecc_sets[i].name != NULL; i++) { - if ((oidsize == ltc_ecc_sets[i].oidlen) && - (XMEM_NEQ(oid, ltc_ecc_sets[i].oid, sizeof(unsigned long) * ltc_ecc_sets[i].oidlen) == 0)) { + for(i = 0; ltc_ecc_curves[i].prime != NULL; i++) { + if ((oidsize == ltc_ecc_curves[i].oidlen) && + (XMEM_NEQ(oid, ltc_ecc_curves[i].oid, sizeof(unsigned long) * ltc_ecc_curves[i].oidlen) == 0)) { break; } } - if (ltc_ecc_sets[i].name == NULL) return CRYPT_ERROR; /* not found */ - return ecc_set_dp(<c_ecc_sets[i], key); + if (ltc_ecc_curves[i].prime == NULL) return CRYPT_ERROR; /* not found */ + return ecc_set_dp(<c_ecc_curves[i], key); } -int ecc_set_dp_copy(ecc_key *srckey, ecc_key *key) +int ecc_copy_dp(const ecc_key *srckey, ecc_key *key) { unsigned long i; int err; @@ -81,9 +81,7 @@ if ((err = mp_copy(srckey->dp.order, key->dp.order )) != CRYPT_OK) { goto error; } if ((err = mp_copy(srckey->dp.A, key->dp.A )) != CRYPT_OK) { goto error; } if ((err = mp_copy(srckey->dp.B, key->dp.B )) != CRYPT_OK) { goto error; } - if ((err = mp_copy(srckey->dp.base.x, key->dp.base.x)) != CRYPT_OK) { goto error; } - if ((err = mp_copy(srckey->dp.base.y, key->dp.base.y)) != CRYPT_OK) { goto error; } - if ((err = mp_copy(srckey->dp.base.z, key->dp.base.z)) != CRYPT_OK) { goto error; } + if ((err = ltc_ecc_copy_point(&srckey->dp.base, &key->dp.base)) != CRYPT_OK) { goto error; } /* cofactor & size */ key->dp.cofactor = srckey->dp.cofactor; key->dp.size = srckey->dp.size; @@ -93,7 +91,7 @@ for (i = 0; i < key->dp.oidlen; i++) key->dp.oid[i] = srckey->dp.oid[i]; } else { - _ecc_oid_lookup(key); /* try to find OID in ltc_ecc_sets */ + _ecc_oid_lookup(key); /* try to find OID in ltc_ecc_curves */ } /* success */ return CRYPT_OK; @@ -103,7 +101,7 @@ return err; } -int ecc_set_dp_bn(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key) +int ecc_set_dp_from_mpis(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key) { int err; @@ -133,7 +131,7 @@ /* cofactor & size */ key->dp.cofactor = cofactor; key->dp.size = mp_unsigned_bin_size(prime); - /* try to find OID in ltc_ecc_sets */ + /* try to find OID in ltc_ecc_curves */ _ecc_oid_lookup(key); /* success */ return CRYPT_OK; diff --git a/src/ltc/pk/ecc/ecc_sign_hash.c b/src/ltc/pk/ecc/ecc_sign_hash.c index 87e9506..f17e96c 100644 --- a/src/ltc/pk/ecc/ecc_sign_hash.c +++ b/src/ltc/pk/ecc/ecc_sign_hash.c @@ -67,7 +67,7 @@ /* make up a key and export the public copy */ do { - if ((err = ecc_set_dp_copy(key, &pubkey)) != CRYPT_OK) { goto errnokey; } + if ((err = ecc_copy_dp(key, &pubkey)) != CRYPT_OK) { goto errnokey; } if ((err = ecc_generate_key(prng, wprng, &pubkey)) != CRYPT_OK) { goto errnokey; } /* find r = x1 mod n */ diff --git a/src/ltc/pk/ecc/ecc_sizes.c b/src/ltc/pk/ecc/ecc_sizes.c index dcd310c..165c849 100644 --- a/src/ltc/pk/ecc/ecc_sizes.c +++ b/src/ltc/pk/ecc/ecc_sizes.c @@ -28,8 +28,8 @@ *high = 0; if (mp_init(&prime) == CRYPT_OK) { - for (i = 0; ltc_ecc_sets[i].name != NULL; i++) { - if (mp_read_radix(prime, ltc_ecc_sets[i].prime, 16) == CRYPT_OK) { + for (i = 0; ltc_ecc_curves[i].prime != NULL; i++) { + if (mp_read_radix(prime, ltc_ecc_curves[i].prime, 16) == CRYPT_OK) { size = mp_unsigned_bin_size(prime); if (size < *low) *low = size; if (size > *high) *high = size; diff --git a/src/ltc/pk/ecc/ecc_verify_hash.c b/src/ltc/pk/ecc/ecc_verify_hash.c index 34a4904..3dd2abb 100644 --- a/src/ltc/pk/ecc/ecc_verify_hash.c +++ b/src/ltc/pk/ecc/ecc_verify_hash.c @@ -109,12 +109,8 @@ if ((err = mp_mulmod(r, w, p, u2)) != CRYPT_OK) { goto error; } /* find mG and mQ */ - if ((err = mp_copy(key->dp.base.x, mG->x)) != CRYPT_OK) { goto error; } - if ((err = mp_copy(key->dp.base.y, mG->y)) != CRYPT_OK) { goto error; } - if ((err = mp_copy(key->dp.base.z, mG->z)) != CRYPT_OK) { goto error; } - if ((err = mp_copy(key->pubkey.x, mQ->x)) != CRYPT_OK) { goto error; } - if ((err = mp_copy(key->pubkey.y, mQ->y)) != CRYPT_OK) { goto error; } - if ((err = mp_copy(key->pubkey.z, mQ->z)) != CRYPT_OK) { goto error; } + if ((err = ltc_ecc_copy_point(&key->dp.base, mG)) != CRYPT_OK) { goto error; } + if ((err = ltc_ecc_copy_point(&key->pubkey, mQ)) != CRYPT_OK) { goto error; } /* find the montgomery mp */ if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK) { goto error; } diff --git a/src/ltc/pk/ecc/ltc_ecc_import_point.c b/src/ltc/pk/ecc/ltc_ecc_import_point.c index 6c8107c..7e103f4 100644 --- a/src/ltc/pk/ecc/ltc_ecc_import_point.c +++ b/src/ltc/pk/ecc/ltc_ecc_import_point.c @@ -31,8 +31,8 @@ /* load y */ if ((err = mp_read_unsigned_bin(y, (unsigned char *)in+1+size, size)) != CRYPT_OK) { goto cleanup; } } - else if ((in[0] == 0x02 || in[0] == 0x03) && (inlen-1) == size) { - /* read compressed point */ + else if ((in[0] == 0x02 || in[0] == 0x03) && (inlen-1) == size && ltc_mp.sqrtmod_prime != NULL) { + /* read compressed point - BEWARE: requires sqrtmod_prime */ /* load x */ if ((err = mp_read_unsigned_bin(x, (unsigned char *)in+1, size)) != CRYPT_OK) { goto cleanup; } /* compute x^3 */ diff --git a/src/ltc/pk/ecc/ltc_ecc_is_point_at_infinity.c b/src/ltc/pk/ecc/ltc_ecc_is_point_at_infinity.c index 87f3b0c..faf7631 100644 --- a/src/ltc/pk/ecc/ltc_ecc_is_point_at_infinity.c +++ b/src/ltc/pk/ecc/ltc_ecc_is_point_at_infinity.c @@ -15,16 +15,22 @@ * a point at infinity is any point (x,y,0) such that y^2 == x^3, except (0,0,0) */ -int ltc_ecc_is_point_at_infinity(const ecc_point *P, void *modulus) +int ltc_ecc_is_point_at_infinity(const ecc_point *P, void *modulus, int *retval) { - int err, retval = 0; + int err; void *x3, *y2; /* trivial case */ - if (!mp_iszero(P->z)) goto done; + if (!mp_iszero(P->z)) { + *retval = 0; + return CRYPT_OK; + } /* point (0,0,0) is not at infinity */ - if (mp_iszero(P->x) && mp_iszero(P->y)) goto done; + if (mp_iszero(P->x) && mp_iszero(P->y)) { + *retval = 0; + return CRYPT_OK; + } /* initialize */ if ((err = mp_init_multi(&x3, &y2, NULL)) != CRYPT_OK) goto done; @@ -37,12 +43,16 @@ if ((err = mp_mulmod(P->x, x3, modulus, x3)) != CRYPT_OK) goto cleanup; /* test y^2 == x^3 */ - if ((mp_cmp(x3, y2) == LTC_MP_EQ) && !mp_iszero(y2)) retval = 1; + err = CRYPT_OK; + if ((mp_cmp(x3, y2) == LTC_MP_EQ) && !mp_iszero(y2)) + *retval = 1; + else + *retval = 0; cleanup: mp_clear_multi(x3, y2, NULL); done: - return retval; + return err; } #endif diff --git a/src/ltc/pk/ecc/ltc_ecc_map.c b/src/ltc/pk/ecc/ltc_ecc_map.c index 92d059d..3c57019 100644 --- a/src/ltc/pk/ecc/ltc_ecc_map.c +++ b/src/ltc/pk/ecc/ltc_ecc_map.c @@ -33,10 +33,7 @@ LTC_ARGCHK(mp != NULL); if (mp_iszero(P->z)) { - if ((err = mp_set(P->x, 0)) != CRYPT_OK) { return err; } - if ((err = mp_set(P->y, 0)) != CRYPT_OK) { return err; } - if ((err = mp_set(P->z, 1)) != CRYPT_OK) { return err; } - return CRYPT_OK; + return ltc_ecc_set_point_xyz(0, 0, 1, P); } if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) { diff --git a/src/ltc/pk/ecc/ltc_ecc_mul2add.c b/src/ltc/pk/ecc/ltc_ecc_mul2add.c index 80ceb86..a2dcf5f 100644 --- a/src/ltc/pk/ecc/ltc_ecc_mul2add.c +++ b/src/ltc/pk/ecc/ltc_ecc_mul2add.c @@ -163,9 +163,7 @@ if (first == 1) { /* if first, copy from table */ first = 0; - if ((err = mp_copy(precomp[nA + (nB<<2)]->x, C->x)) != CRYPT_OK) { goto ERR_MU; } - if ((err = mp_copy(precomp[nA + (nB<<2)]->y, C->y)) != CRYPT_OK) { goto ERR_MU; } - if ((err = mp_copy(precomp[nA + (nB<<2)]->z, C->z)) != CRYPT_OK) { goto ERR_MU; } + if ((err = ltc_ecc_copy_point(precomp[nA + (nB<<2)], C)) != CRYPT_OK) { goto ERR_MU; } } else { /* if not first, add from table */ if ((err = ltc_mp.ecc_ptadd(C, precomp[nA + (nB<<2)], C, ma, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } diff --git a/src/ltc/pk/ecc/ltc_ecc_mulmod.c b/src/ltc/pk/ecc/ltc_ecc_mulmod.c index 50dedc1..ec8ba9c 100644 --- a/src/ltc/pk/ecc/ltc_ecc_mulmod.c +++ b/src/ltc/pk/ecc/ltc_ecc_mulmod.c @@ -32,7 +32,7 @@ int ltc_ecc_mulmod(void *k, const ecc_point *G, ecc_point *R, void *a, void *modulus, int map) { ecc_point *tG, *M[8]; - int i, j, err; + int i, j, err, inf; void *mp = NULL, *mu = NULL, *ma = NULL, *a_plus3 = NULL; ltc_mp_digit buf; int first, bitbuf, bitcpy, bitcnt, mode, digidx; @@ -42,12 +42,10 @@ LTC_ARGCHK(R != NULL); LTC_ARGCHK(modulus != NULL); - if (ltc_ecc_is_point_at_infinity(G, modulus)) { + if ((err = ltc_ecc_is_point_at_infinity(G, modulus, &inf)) != CRYPT_OK) return err; + if (inf) { /* return the point at infinity */ - if ((err = mp_set(R->x, 1)) != CRYPT_OK) { return err; } - if ((err = mp_set(R->y, 1)) != CRYPT_OK) { return err; } - if ((err = mp_set(R->z, 0)) != CRYPT_OK) { return err; } - return CRYPT_OK; + return ltc_ecc_set_point_xyz(1, 1, 0, R); } /* init montgomery reduction */ @@ -81,9 +79,7 @@ /* tG = G and convert to montgomery */ if (mp_cmp_d(mu, 1) == LTC_MP_EQ) { - if ((err = mp_copy(G->x, tG->x)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(G->y, tG->y)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(G->z, tG->z)) != CRYPT_OK) { goto done; } + if ((err = ltc_ecc_copy_point(G, tG)) != CRYPT_OK) { goto done; } } else { if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK) { goto done; } if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK) { goto done; } @@ -146,9 +142,7 @@ /* if this is the first window we do a simple copy */ if (first == 1) { /* R = kG [k = first window] */ - if ((err = mp_copy(M[bitbuf-8]->x, R->x)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(M[bitbuf-8]->y, R->y)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(M[bitbuf-8]->z, R->z)) != CRYPT_OK) { goto done; } + if ((err = ltc_ecc_copy_point(M[bitbuf-8], R)) != CRYPT_OK) { goto done; } first = 0; } else { /* normal window */ @@ -180,9 +174,7 @@ if ((bitbuf & (1 << WINSIZE)) != 0) { if (first == 1){ /* first add, so copy */ - if ((err = mp_copy(tG->x, R->x)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(tG->y, R->y)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(tG->z, R->z)) != CRYPT_OK) { goto done; } + if ((err = ltc_ecc_copy_point(tG, R)) != CRYPT_OK) { goto done; } first = 0; } else { /* then add */ diff --git a/src/ltc/pk/ecc/ltc_ecc_mulmod_timing.c b/src/ltc/pk/ecc/ltc_ecc_mulmod_timing.c index 068240a..9ff37d8 100644 --- a/src/ltc/pk/ecc/ltc_ecc_mulmod_timing.c +++ b/src/ltc/pk/ecc/ltc_ecc_mulmod_timing.c @@ -31,7 +31,7 @@ int ltc_ecc_mulmod(void *k, const ecc_point *G, ecc_point *R, void *a, void *modulus, int map) { ecc_point *tG, *M[3]; - int i, j, err; + int i, j, err, inf; void *mp = NULL, *mu = NULL, *ma = NULL, *a_plus3 = NULL; ltc_mp_digit buf; int bitcnt, mode, digidx; @@ -41,12 +41,10 @@ LTC_ARGCHK(R != NULL); LTC_ARGCHK(modulus != NULL); - if (ltc_ecc_is_point_at_infinity(G, modulus)) { + if ((err = ltc_ecc_is_point_at_infinity(G, modulus, &inf)) != CRYPT_OK) return err; + if (inf) { /* return the point at infinity */ - if ((err = mp_set(R->x, 1)) != CRYPT_OK) { return err; } - if ((err = mp_set(R->y, 1)) != CRYPT_OK) { return err; } - if ((err = mp_set(R->z, 0)) != CRYPT_OK) { return err; } - return CRYPT_OK; + return ltc_ecc_set_point_xyz(1, 1, 0, R); } /* init montgomery reduction */ @@ -88,9 +86,7 @@ /* calc the M tab */ /* M[0] == G */ - if ((err = mp_copy(tG->x, M[0]->x)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(tG->y, M[0]->y)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(tG->z, M[0]->z)) != CRYPT_OK) { goto done; } + if ((err = ltc_ecc_copy_point(tG, M[0])) != CRYPT_OK) { goto done; } /* M[1] == 2G */ if ((err = ltc_mp.ecc_ptdbl(tG, M[1], ma, modulus, mp)) != CRYPT_OK) { goto done; } @@ -136,9 +132,7 @@ } /* copy result out */ - if ((err = mp_copy(M[0]->x, R->x)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(M[0]->y, R->y)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(M[0]->z, R->z)) != CRYPT_OK) { goto done; } + if ((err = ltc_ecc_copy_point(M[0], R)) != CRYPT_OK) { goto done; } /* map R back from projective space */ if (map) { diff --git a/src/ltc/pk/ecc/ltc_ecc_points.c b/src/ltc/pk/ecc/ltc_ecc_points.c index 772e8ef..4a890fd 100644 --- a/src/ltc/pk/ecc/ltc_ecc_points.c +++ b/src/ltc/pk/ecc/ltc_ecc_points.c @@ -46,6 +46,24 @@ } } +int ltc_ecc_set_point_xyz(ltc_mp_digit x, ltc_mp_digit y, ltc_mp_digit z, ecc_point *p) +{ + int err; + if ((err = ltc_mp.set_int(p->x, x)) != CRYPT_OK) return err; + if ((err = ltc_mp.set_int(p->y, y)) != CRYPT_OK) return err; + if ((err = ltc_mp.set_int(p->z, z)) != CRYPT_OK) return err; + return CRYPT_OK; +} + +int ltc_ecc_copy_point(const ecc_point *src, ecc_point *dst) +{ + int err; + if ((err = ltc_mp.copy(src->x, dst->x)) != CRYPT_OK) return err; + if ((err = ltc_mp.copy(src->y, dst->y)) != CRYPT_OK) return err; + if ((err = ltc_mp.copy(src->z, dst->z)) != CRYPT_OK) return err; + return CRYPT_OK; +} + #endif /* ref: $Format:%D$ */ /* git commit: $Format:%H$ */ diff --git a/src/ltc/pk/ecc/ltc_ecc_projective_add_point.c b/src/ltc/pk/ecc/ltc_ecc_projective_add_point.c index 0182d0a..eff35c9 100644 --- a/src/ltc/pk/ecc/ltc_ecc_projective_add_point.c +++ b/src/ltc/pk/ecc/ltc_ecc_projective_add_point.c @@ -29,7 +29,7 @@ int ltc_ecc_projective_add_point(const ecc_point *P, const ecc_point *Q, ecc_point *R, void *ma, void *modulus, void *mp) { void *t1, *t2, *x, *y, *z; - int err; + int err, inf; LTC_ARGCHK(P != NULL); LTC_ARGCHK(Q != NULL); @@ -41,20 +41,18 @@ return err; } - if (ltc_ecc_is_point_at_infinity(P, modulus)) { + if ((err = ltc_ecc_is_point_at_infinity(P, modulus, &inf)) != CRYPT_OK) return err; + if (inf) { /* P is point at infinity >> Result = Q */ - if ((err = ltc_mp.copy(Q->x, R->x)) != CRYPT_OK) { goto done; } - if ((err = ltc_mp.copy(Q->y, R->y)) != CRYPT_OK) { goto done; } - if ((err = ltc_mp.copy(Q->z, R->z)) != CRYPT_OK) { goto done; } - goto done; /* CRYPT_OK */ - } - - if (ltc_ecc_is_point_at_infinity(Q, modulus)) { + err = ltc_ecc_copy_point(Q, R); + goto done; + } + + if ((err = ltc_ecc_is_point_at_infinity(Q, modulus, &inf)) != CRYPT_OK) return err; + if (inf) { /* Q is point at infinity >> Result = P */ - if ((err = ltc_mp.copy(P->x, R->x)) != CRYPT_OK) { goto done; } - if ((err = ltc_mp.copy(P->y, R->y)) != CRYPT_OK) { goto done; } - if ((err = ltc_mp.copy(P->z, R->z)) != CRYPT_OK) { goto done; } - goto done; /* CRYPT_OK */ + err = ltc_ecc_copy_point(P, R); + goto done; } if ((mp_cmp(P->x, Q->x) == LTC_MP_EQ) && (mp_cmp(P->z, Q->z) == LTC_MP_EQ)) { @@ -66,10 +64,8 @@ if ((err = mp_sub(modulus, Q->y, t1)) != CRYPT_OK) { goto done; } if (mp_cmp(P->y, t1) == LTC_MP_EQ) { /* here Q = -P >>> Result = the point at infinity */ - if ((err = ltc_mp.set_int(R->x, 1)) != CRYPT_OK) { goto done; } - if ((err = ltc_mp.set_int(R->y, 1)) != CRYPT_OK) { goto done; } - if ((err = ltc_mp.set_int(R->z, 0)) != CRYPT_OK) { goto done; } - goto done; /* CRYPT_OK */ + err = ltc_ecc_set_point_xyz(1, 1, 0, R); + goto done; } } diff --git a/src/ltc/pk/ecc/ltc_ecc_projective_dbl_point.c b/src/ltc/pk/ecc/ltc_ecc_projective_dbl_point.c index 57cfd6f..1b46457 100644 --- a/src/ltc/pk/ecc/ltc_ecc_projective_dbl_point.c +++ b/src/ltc/pk/ecc/ltc_ecc_projective_dbl_point.c @@ -46,7 +46,7 @@ int ltc_ecc_projective_dbl_point(const ecc_point *P, ecc_point *R, void *ma, void *modulus, void *mp) { void *t1, *t2; - int err; + int err, inf; LTC_ARGCHK(P != NULL); LTC_ARGCHK(R != NULL); @@ -58,17 +58,14 @@ } if (P != R) { - if ((err = mp_copy(P->x, R->x)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(P->y, R->y)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(P->z, R->z)) != CRYPT_OK) { goto done; } + if ((err = ltc_ecc_copy_point(P, R)) != CRYPT_OK) { goto done; } } - if (ltc_ecc_is_point_at_infinity(P, modulus)) { + if ((err = ltc_ecc_is_point_at_infinity(P, modulus, &inf)) != CRYPT_OK) return err; + if (inf) { /* if P is point at infinity >> Result = point at infinity */ - if ((err = ltc_mp.set_int(R->x, 1)) != CRYPT_OK) { goto done; } - if ((err = ltc_mp.set_int(R->y, 1)) != CRYPT_OK) { goto done; } - if ((err = ltc_mp.set_int(R->z, 0)) != CRYPT_OK) { goto done; } - goto done; /* CRYPT_OK */ + err = ltc_ecc_set_point_xyz(1, 1, 0, R); + goto done; } /* t1 = Z * Z */ diff --git a/src/ltc/pk/ecc/ltc_ecc_verify_key.c b/src/ltc/pk/ecc/ltc_ecc_verify_key.c index b417465..b04df5d 100644 --- a/src/ltc/pk/ecc/ltc_ecc_verify_key.c +++ b/src/ltc/pk/ecc/ltc_ecc_verify_key.c @@ -21,7 +21,7 @@ int ltc_ecc_verify_key(ecc_key *key) { - int err; + int err, inf; void *prime = NULL; void *order = NULL; void *a = NULL; @@ -52,7 +52,8 @@ point = ltc_ecc_new_point(); if ((err = ltc_ecc_mulmod(order, &(key->pubkey), point, a, prime, 1)) != CRYPT_OK) { goto done1; } - if (ltc_ecc_is_point_at_infinity(point, prime)) { + err = ltc_ecc_is_point_at_infinity(point, prime, &inf); + if (err != CRYPT_OK || inf) { err = CRYPT_ERROR; } else {