diff options
author | gregor herrmann <gregoa@debian.org> | 2018-04-09 21:21:20 +0200 |
---|---|---|
committer | gregor herrmann <gregoa@debian.org> | 2018-04-09 21:21:20 +0200 |
commit | fa5f52b7d5e821591e6c6a2f96f8abb644888b38 (patch) | |
tree | 8aa5611ba5ae98c26b4abb31d5928c82e4a194bf | |
parent | 5b7253046b660592f2e7db7afd2857c8ac517621 (diff) | |
parent | e8a8ed0e6467701e2e2737fa23c99724c8370036 (diff) |
New upstream version 0.059
329 files changed, 10722 insertions, 7182 deletions
@@ -1,5 +1,20 @@ Changes for CryptX +0.059 2018-03-25 + - new Crypt::Digest::Keccak(224|256|384|512) + - new methods sign_hash_rfc7518 + verify_hash_rfc7518 (Crypt::PK::ECC) + - improved import of pkcs#8 private keys (Crypt::PK::ECC) + - improved export allowing "compressed" variants (Crypt::PK::ECC) + - fix #28 Apple's APNS pkcs8 auth key import fails (Crypt::PK::ECC) + - fix cpantesters failure (5.8.1 related) + +0.058 2018-02-27 + - fix: decode_b58b + invalid input + +0.057 2018-01-31 + - significant speed-up (more stuff handled on XS level) + - Crypt::Checksum is deprecated in favour of Crypt::Checksum::Adler32|CRC32 + 0.056 2017-12-22 - new Crypt::Stream::Rabbit @@ -1,3 +1,4 @@ +#define PERL_NO_GET_CONTEXT /* we want efficiency */ #include "EXTERN.h" #include "perl.h" #include "XSUB.h" @@ -7,22 +8,53 @@ #define NEED_newRV_noinc_GLOBAL #include "ppport.h" +/* assert_not_ROK is broken in 5.8.1 */ +#if PERL_VERSION == 8 && PERL_SUBVERSION == 1 +# undef assert_not_ROK +# if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) +# define assert_not_ROK(sv) ({assert(!SvROK(sv) || !SvRV(sv));}), +# else +# define assert_not_ROK(sv) +# endif +#endif + #undef LTC_SOURCE #include "tomcrypt.h" #include "tommath.h" -typedef adler32_state *Crypt__Checksum__Adler32; -typedef crc32_state *Crypt__Checksum__CRC32; +typedef adler32_state *Crypt__Checksum__Adler32; +typedef crc32_state *Crypt__Checksum__CRC32; + +typedef ccm_state *Crypt__AuthEnc__CCM; +typedef eax_state *Crypt__AuthEnc__EAX; +typedef gcm_state *Crypt__AuthEnc__GCM; +typedef chacha20poly1305_state *Crypt__AuthEnc__ChaCha20Poly1305; +typedef ocb3_state *Crypt__AuthEnc__OCB; + +typedef chacha_state *Crypt__Stream__ChaCha; +typedef salsa20_state *Crypt__Stream__Salsa20; +typedef sosemanuk_state *Crypt__Stream__Sosemanuk; +typedef rabbit_state *Crypt__Stream__Rabbit; +typedef rc4_state *Crypt__Stream__RC4; +typedef sober128_state *Crypt__Stream__Sober128; + +typedef f9_state *Crypt__Mac__F9; +typedef hmac_state *Crypt__Mac__HMAC; +typedef omac_state *Crypt__Mac__OMAC; +typedef pelican_state *Crypt__Mac__Pelican; +typedef pmac_state *Crypt__Mac__PMAC; +typedef xcbc_state *Crypt__Mac__XCBC; +typedef poly1305_state *Crypt__Mac__Poly1305; +typedef blake2smac_state *Crypt__Mac__BLAKE2s; +typedef blake2bmac_state *Crypt__Mac__BLAKE2b; typedef struct cipher_struct { /* used by Crypt::Cipher */ symmetric_key skey; - int id; struct ltc_cipher_descriptor *desc; } *Crypt__Cipher; typedef struct digest_struct { /* used by Crypt::Digest */ hash_state state; - int id; struct ltc_hash_descriptor *desc; } *Crypt__Digest; @@ -31,109 +63,6 @@ typedef struct digest_shake_struct { /* used by Crypt::Digest::SHAKE */ int num; } *Crypt__Digest__SHAKE; -typedef struct ccm_struct { /* used by Crypt::AuthEnc::CCM */ - ccm_state state; - int direction; - int tag_len; - unsigned long pt_len; - int id; -} *Crypt__AuthEnc__CCM; - -typedef struct eax_struct { /* used by Crypt::AuthEnc::EAX */ - eax_state state; - int id; -} *Crypt__AuthEnc__EAX; - -typedef struct gcm_struct { /* used by Crypt::AuthEnc::GCM */ - gcm_state state; - int id; -} *Crypt__AuthEnc__GCM; - -typedef struct chacha20poly1305_struct {/* used by Crypt::AuthEnc::ChaCha20Poly1305 */ - chacha20poly1305_state state; - int id; -} *Crypt__AuthEnc__ChaCha20Poly1305; - -typedef struct ocb_struct { /* used by Crypt::AuthEnc::OCB */ - ocb3_state state; - int id; -} *Crypt__AuthEnc__OCB; - -typedef struct chacha_struct { /* used by Crypt::Stream::ChaCha */ - chacha_state state; - int id; -} *Crypt__Stream__ChaCha; - -typedef struct salsa20_struct { /* used by Crypt::Stream::Salsa20 */ - salsa20_state state; - int id; -} *Crypt__Stream__Salsa20; - -typedef struct sosemanuk_struct { /* used by Crypt::Stream::Sosemanuk */ - sosemanuk_state state; - int id; -} *Crypt__Stream__Sosemanuk; - -typedef struct rabbit_struct { /* used by Crypt::Stream::Rabbit */ - rabbit_state state; - int id; -} *Crypt__Stream__Rabbit; - -typedef struct rc4_struct { /* used by Crypt::Stream::RC4 */ - rc4_state state; - int id; -} *Crypt__Stream__RC4; - -typedef struct sober128_struct { /* used by Crypt::Stream::Sober128 */ - sober128_state state; - int id; -} *Crypt__Stream__Sober128; - -typedef struct f9_struct { /* used by Crypt::Mac::F9 */ - f9_state state; - int id; -} *Crypt__Mac__F9; - -typedef struct hmac_struct { /* used by Crypt::Mac::HMAC */ - hmac_state state; - int id; -} *Crypt__Mac__HMAC; - -typedef struct omac_struct { /* used by Crypt::Mac::OMAC */ - omac_state state; - int id; -} *Crypt__Mac__OMAC; - -typedef struct pelican_struct { /* used by Crypt::Mac::Pelican */ - pelican_state state; - int id; -} *Crypt__Mac__Pelican; - -typedef struct pmac_struct { /* used by Crypt::Mac::PMAC */ - pmac_state state; - int id; -} *Crypt__Mac__PMAC; - -typedef struct xcbc_struct { /* used by Crypt::Mac::XCBC */ - xcbc_state state; - int id; -} *Crypt__Mac__XCBC; - -typedef struct poly1305_struct { /* used by Crypt::Mac::Poly1305 */ - poly1305_state state; - int id; -} *Crypt__Mac__Poly1305; - -typedef struct blake2s_struct { /* used by Crypt::Mac::BLAKE2s */ - blake2smac_state state; - int id; -} *Crypt__Mac__BLAKE2s; - -typedef struct blake2b_struct { /* used by Crypt::Mac::BLAKE2b */ - blake2bmac_state state; - int id; -} *Crypt__Mac__BLAKE2b; - typedef struct cbc_struct { /* used by Crypt::Mode::CBC */ int cipher_id, cipher_rounds; symmetric_CBC state; @@ -141,7 +70,6 @@ typedef struct cbc_struct { /* used by Crypt::Mode::CBC */ int padlen; int padding_mode; int direction; - int id; } *Crypt__Mode__CBC; typedef struct ecb_struct { /* used by Crypt::Mode::ECB */ @@ -151,14 +79,12 @@ typedef struct ecb_struct { /* used by Crypt::Mode::ECB */ int padlen; int padding_mode; int direction; - int id; } *Crypt__Mode__ECB; typedef struct cfb_struct { /* used by Crypt::Mode::CFB */ int cipher_id, cipher_rounds; symmetric_CFB state; int direction; - int id; } *Crypt__Mode__CFB; typedef struct ctr_struct { /* used by Crypt::Mode::CTR */ @@ -166,174 +92,302 @@ typedef struct ctr_struct { /* used by Crypt::Mode::CTR */ int ctr_mode_param; symmetric_CTR state; int direction; - int id; } *Crypt__Mode__CTR; typedef struct f8_struct { /* used by Crypt::Mode::F8 */ int cipher_id, cipher_rounds; symmetric_F8 state; int direction; - int id; } *Crypt__Mode__F8; typedef struct lrw_struct { /* used by Crypt::Mode::LRW */ int cipher_id, cipher_rounds; symmetric_LRW state; int direction; - int id; } *Crypt__Mode__LRW; typedef struct ofb_struct { /* used by Crypt::Mode::OFB */ int cipher_id, cipher_rounds; symmetric_OFB state; int direction; - int id; } *Crypt__Mode__OFB; typedef struct xts_struct { /* used by Crypt::Mode::XTS */ int cipher_id, cipher_rounds; symmetric_xts state; int direction; - int id; } *Crypt__Mode__XTS; typedef struct prng_struct { /* used by Crypt::PRNG */ prng_state state; struct ltc_prng_descriptor *desc; IV last_pid; - int id; } *Crypt__PRNG; typedef struct rsa_struct { /* used by Crypt::PK::RSA */ prng_state pstate; int pindex; rsa_key key; - int id; } *Crypt__PK__RSA; typedef struct dsa_struct { /* used by Crypt::PK::DSA */ prng_state pstate; int pindex; dsa_key key; - int id; } *Crypt__PK__DSA; typedef struct dh_struct { /* used by Crypt::PK::DH */ prng_state pstate; int pindex; dh_key key; - int id; } *Crypt__PK__DH; typedef struct ecc_struct { /* used by Crypt::PK::ECC */ prng_state pstate; int pindex; ecc_key key; - ltc_ecc_set_type dp; - int id; } *Crypt__PK__ECC; -int str_add_leading_zero(char *str, int maxlen, int minlen) { - int len; +int mp_tohex_with_leading_zero(mp_int * a, char *str, int maxlen, int minlen) { + int len, rv; + + if (mp_isneg(a) == MP_YES) { + *str = '\0'; + return MP_VAL; + } + + rv = mp_toradix_n(a, str, 16, maxlen); + if (rv != MP_OKAY) { + *str = '\0'; + return rv; + } + len = (int)strlen(str); if (len > 0 && len % 2 && len < maxlen-2) { memmove(str+1, str, len+1); /* incl. NUL byte */ *str = '0'; /* add leading zero */ } + len = (int)strlen(str); if (len < minlen && minlen < maxlen-1) { memmove(str+(minlen-len), str, len+1); /* incl. NUL byte */ memset(str, '0', minlen-len); /* add leading zero */ } + return MP_OKAY; } -int mp_tohex_with_leading_zero(mp_int * a, char *str, int maxlen, int minlen) { - int rv; - if (mp_isneg(a) == MP_YES) { - *str = '\0'; - return MP_VAL; - } - rv = mp_toradix_n(a, str, 16, maxlen); - if (rv != MP_OKAY) { - *str = '\0'; - return rv; - } - return str_add_leading_zero(str, maxlen, minlen); +int _base16_encode(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) +{ + unsigned long i; + const char alphabet[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; + + if (*outlen < inlen * 2) { + *outlen = inlen * 2; + return CRYPT_BUFFER_OVERFLOW; + } + + for (i = 0; i < inlen; i++) { + out[i*2] = (unsigned char)alphabet[in[i] >> 4]; + out[i*2+1] = (unsigned char)alphabet[in[i] & 0xF]; + } + + *outlen = inlen * 2; + return CRYPT_OK; +} + +size_t _find_start(const char *name, char *ltcname, size_t ltclen) +{ + size_t i, start = 0; + if (name == NULL || strlen(name) + 1 > ltclen) croak("FATAL: invalid name") ; + /* normalize */ + for (i = 0; i < ltclen && name[i] > 0; i++) { + if (name[i] >= 'A' && name[i] <= 'Z') { + ltcname[i] = name[i] + 32; /* lowecase */ + } + else if (name[i] == '_') { + ltcname[i] = '-'; + } + else { + ltcname[i] = name[i]; + } + if (name[i] == ':') start = i + 1; + } + return start; +} + +int _find_hash(const char *name) +{ + char ltcname[100] = { 0 }; + size_t start = _find_start(name, ltcname, sizeof(ltcname) - 1); + /* special cases */ + if (strcmp(ltcname + start, "ripemd128") == 0) return find_hash("rmd128"); + if (strcmp(ltcname + start, "ripemd160") == 0) return find_hash("rmd160"); + if (strcmp(ltcname + start, "ripemd256") == 0) return find_hash("rmd256"); + if (strcmp(ltcname + start, "ripemd320") == 0) return find_hash("rmd320"); + if (strcmp(ltcname + start, "tiger192") == 0) return find_hash("tiger"); + if (strcmp(ltcname + start, "chaes") == 0) return find_hash("chc_hash"); + if (strcmp(ltcname + start, "chc-hash") == 0) return find_hash("chc_hash"); + return find_hash(ltcname + start); +} + +int _find_cipher(const char *name) +{ + char ltcname[100] = { 0 }; + size_t start = _find_start(name, ltcname, sizeof(ltcname) - 1); + /* special cases */ + if (strcmp(ltcname + start, "des-ede") == 0) return find_cipher("3des"); + if (strcmp(ltcname + start, "saferp") == 0) return find_cipher("safer+"); + return find_cipher(ltcname + start); +} + +int _find_prng(const char *name) +{ + char ltcname[100] = { 0 }; + size_t start = _find_start(name, ltcname, sizeof(ltcname) - 1); + return find_prng(ltcname + start); } /* Math::BigInt::LTM related */ typedef mp_int * Math__BigInt__LTM; STATIC SV * sv_from_mpi(mp_int *mpi) { + dTHX; /* fetch context */ SV *obj = newSV(0); sv_setref_pv(obj, "Math::BigInt::LTM", (void*)mpi); return obj; } -ltc_ecc_set_type* _ecc_set_dp_from_SV(ltc_ecc_set_type *dp, SV *curve) +void _ecc_oid_lookup(ecc_key *key) { - HV *h; - SV *param, **pref; - SV **sv_cofactor, **sv_prime, **sv_A, **sv_B, **sv_order, **sv_Gx, **sv_Gy; - int err; + int err; + unsigned i; + void *tmp; + const ltc_ecc_set_type *set; + + 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; + if ((mp_cmp(tmp, key->dp.prime) != LTC_MP_EQ)) continue; + if ((err = mp_read_radix(tmp, set->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 ((mp_cmp(tmp, key->dp.A) != LTC_MP_EQ)) continue; + if ((err = mp_read_radix(tmp, set->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 ((mp_cmp(tmp, key->dp.base.x) != LTC_MP_EQ)) continue; + if ((err = mp_read_radix(tmp, set->Gy, 16)) != CRYPT_OK) continue; + if ((mp_cmp(tmp, key->dp.base.y) != LTC_MP_EQ)) continue; + if (key->dp.cofactor != set->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]; + } +} + +int _ecc_set_dp_from_SV(ecc_key *key, SV *curve) +{ + dTHX; /* fetch context */ + HV *hc, *hl, *h; + SV *sv_crv, **pref; + SV **sv_cofactor, **sv_prime, **sv_A, **sv_B, **sv_order, **sv_Gx, **sv_Gy, **sv_oid; char *ch_name; - STRLEN l_name; + STRLEN l_name, i, j; + int err; + + if (!SvOK(curve)) croak("FATAL: undefined curve"); if (SvPOK(curve)) { + /* string */ ch_name = SvPV(curve, l_name); - if ((h = get_hv("Crypt::PK::ECC::curve", 0)) == NULL) croak("FATAL: generate_key_ex: no curve register"); - if ((pref = hv_fetch(h, ch_name, (U32)l_name, 0)) == NULL) croak("FATAL: generate_key_ex: unknown curve/1 '%s'", ch_name); - if (!SvOK(*pref)) croak("FATAL: generate_key_ex: unknown curve/2 '%s'", ch_name); - param = *pref; + if ((hl = get_hv("Crypt::PK::ECC::curve2ltc", 0)) == NULL) croak("FATAL: no curve2ltc register"); + pref = hv_fetch(hl, ch_name, (U32)l_name, 0); + if (pref && SvOK(*pref)) { + sv_crv = *pref; /* found in %cutve2ltc */ + } + else { + if ((hc = get_hv("Crypt::PK::ECC::curve", 0)) == NULL) croak("FATAL: no curve register"); + pref = hv_fetch(hc, ch_name, (U32)l_name, 0); + if (pref && SvOK(*pref)) { + sv_crv = *pref; /* found in %curve */ + } + else { + sv_crv = curve; + } + } } else if (SvROK(curve)) { - param = curve; + /* hashref */ + sv_crv = curve; } else { croak("FATAL: curve has to be a string or a hashref"); } - if ((h = (HV*)(SvRV(param))) == NULL) croak("FATAL: ecparams: param is not valid hashref"); - - if ((sv_prime = hv_fetchs(h, "prime", 0)) == NULL) croak("FATAL: ecparams: missing param prime"); - if ((sv_A = hv_fetchs(h, "A", 0)) == NULL) croak("FATAL: ecparams: missing param A"); - if ((sv_B = hv_fetchs(h, "B", 0)) == NULL) croak("FATAL: ecparams: missing param B"); - if ((sv_order = hv_fetchs(h, "order", 0)) == NULL) croak("FATAL: ecparams: missing param order"); - if ((sv_Gx = hv_fetchs(h, "Gx", 0)) == NULL) croak("FATAL: ecparams: missing param Gx"); - if ((sv_Gy = hv_fetchs(h, "Gy", 0)) == NULL) croak("FATAL: ecparams: missing param Gy"); - if ((sv_cofactor = hv_fetchs(h, "cofactor", 0)) == NULL) croak("FATAL: ecparams: missing param cofactor"); - - if (!SvOK(*sv_prime )) croak("FATAL: ecparams: undefined param prime"); - if (!SvOK(*sv_A )) croak("FATAL: ecparams: undefined param A"); - if (!SvOK(*sv_B )) croak("FATAL: ecparams: undefined param B"); - if (!SvOK(*sv_order )) croak("FATAL: ecparams: undefined param order"); - if (!SvOK(*sv_Gx )) croak("FATAL: ecparams: undefined param Gx"); - if (!SvOK(*sv_Gy )) croak("FATAL: ecparams: undefined param Gy"); - if (!SvOK(*sv_cofactor)) croak("FATAL: ecparams: undefined param cofactor"); - - err = ecc_dp_set( dp, - SvPV_nolen(*sv_prime), - SvPV_nolen(*sv_A), - SvPV_nolen(*sv_B), - SvPV_nolen(*sv_order), - SvPV_nolen(*sv_Gx), - SvPV_nolen(*sv_Gy), - (unsigned long)SvUV(*sv_cofactor), - NULL, /* we intentionally don't allow setting custom names */ - NULL /* we intentionally don't allow setting custom OIDs */ - ); - return err == CRYPT_OK ? dp : NULL; -} - -void _ecc_free_key(ecc_key *key, ltc_ecc_set_type *dp) -{ - if(dp) { - ecc_dp_clear(dp); + if (SvPOK(sv_crv)) { + /* string - curve name */ + const ltc_ecc_set_type *dp; + 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 (key->type != -1) { - ecc_free(key); - key->type = -1; - key->dp = NULL; + else { + /* hashref */ + ltc_ecc_set_type set = { 0 }; + + if ((h = (HV*)(SvRV(sv_crv))) == NULL) croak("FATAL: ecparams: param is not valid hashref"); + + if ((sv_prime = hv_fetchs(h, "prime", 0)) == NULL) croak("FATAL: ecparams: missing param prime"); + if ((sv_A = hv_fetchs(h, "A", 0)) == NULL) croak("FATAL: ecparams: missing param A"); + if ((sv_B = hv_fetchs(h, "B", 0)) == NULL) croak("FATAL: ecparams: missing param B"); + if ((sv_order = hv_fetchs(h, "order", 0)) == NULL) croak("FATAL: ecparams: missing param order"); + if ((sv_Gx = hv_fetchs(h, "Gx", 0)) == NULL) croak("FATAL: ecparams: missing param Gx"); + if ((sv_Gy = hv_fetchs(h, "Gy", 0)) == NULL) croak("FATAL: ecparams: missing param Gy"); + if ((sv_cofactor = hv_fetchs(h, "cofactor", 0)) == NULL) croak("FATAL: ecparams: missing param cofactor"); + + if (!SvOK(*sv_prime )) croak("FATAL: ecparams: undefined param prime"); + if (!SvOK(*sv_A )) croak("FATAL: ecparams: undefined param A"); + if (!SvOK(*sv_B )) croak("FATAL: ecparams: undefined param B"); + if (!SvOK(*sv_order )) croak("FATAL: ecparams: undefined param order"); + if (!SvOK(*sv_Gx )) croak("FATAL: ecparams: undefined param Gx"); + 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; + + sv_oid = hv_fetchs(h, "oid", 0); + if (sv_oid && SvPOK(*sv_oid)) { + ch_name = SvPV(*sv_oid, l_name); + for (i = 0, j = 0; i < l_name; i++) { + if (ch_name[i] == '.') { + 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'); + } + 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; + if (key->dp.oidlen == 0) _ecc_oid_lookup(key); + return CRYPT_OK; } } @@ -348,65 +402,115 @@ BOOT: if(crypt_mp_init("ltm") != CRYPT_OK) { croak("FATAL: crypt_mp_init failed"); } SV * -CryptX__encode_base64url(SV * in) +CryptX__ltc_build_settings() + CODE: + RETVAL = newSVpv(crypt_build_settings, 0); + OUTPUT: + RETVAL + +SV * +CryptX__ltc_mp_name() + CODE: + RETVAL = newSVpv(ltc_mp.name, 0); + OUTPUT: + RETVAL + +int +CryptX__ltc_mp_bits_per_digit() + CODE: + RETVAL = ltc_mp.bits_per_digit; + OUTPUT: + RETVAL + +MODULE = CryptX PACKAGE = Crypt::Misc + +PROTOTYPES: DISABLE + +SV * +_radix_to_bin(char *in, int radix) CODE: { - STRLEN in_len; - unsigned long out_len; - unsigned char *out_data, *in_data; + STRLEN len; + unsigned char *out_data; + mp_int mpi; - if (!SvPOK(in)) XSRETURN_UNDEF; - in_data = (unsigned char *) SvPVbyte(in, in_len); - if (in_len == 0) { + if (in == NULL) XSRETURN_UNDEF; + if (mp_init(&mpi) != CRYPT_OK) XSRETURN_UNDEF; + if (strlen(in) == 0) { RETVAL = newSVpvn("", 0); } - else { - out_len = (unsigned long)(4 * ((in_len + 2) / 3) + 1); - RETVAL = NEWSV(0, out_len); - SvPOK_only(RETVAL); - out_data = (unsigned char *)SvPVX(RETVAL); - if (base64url_encode(in_data, (unsigned long)in_len, out_data, &out_len) != CRYPT_OK) { - SvREFCNT_dec(RETVAL); - XSRETURN_UNDEF; + else if (mp_read_radix(&mpi, in, radix) == CRYPT_OK) { + len = mp_unsigned_bin_size(&mpi); + if (len == 0) { + RETVAL = newSVpvn("", 0); } - SvCUR_set(RETVAL, out_len); + else { + RETVAL = NEWSV(0, len); /* avoid zero! */ + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, len); + out_data = (unsigned char *)SvPVX(RETVAL); + mp_to_unsigned_bin(&mpi, out_data); + } + } + else { + RETVAL = newSVpvn(NULL, 0); /* undef */ } + mp_clear(&mpi); } OUTPUT: RETVAL SV * -CryptX__decode_base64url(SV * in) +_bin_to_radix(SV *in, int radix) CODE: { - STRLEN in_len; - unsigned long out_len; - unsigned char *out_data, *in_data; + STRLEN len; + unsigned char *in_data; + char *out_data; + mp_int mpi, tmp; + mp_digit d; + int digits = 0; - if (!SvPOK(in)) XSRETURN_UNDEF; - in_data = (unsigned char *) SvPVbyte(in, in_len); - if (in_len == 0) { + if (!SvPOK(in) || radix < 2 || radix > 64) XSRETURN_UNDEF; + in_data = (unsigned char *) SvPVbyte(in, len); + mp_init_multi(&mpi, &tmp, NULL); + if (len == 0) { RETVAL = newSVpvn("", 0); } else { - out_len = (unsigned long)in_len; - RETVAL = NEWSV(0, out_len); - SvPOK_only(RETVAL); - out_data = (unsigned char *)SvPVX(RETVAL); - if (base64url_decode(in_data, (unsigned long)in_len, out_data, &out_len) != CRYPT_OK) { - SvREFCNT_dec(RETVAL); - XSRETURN_UNDEF; + if (mp_read_unsigned_bin(&mpi, in_data, (unsigned long)len) == CRYPT_OK) { + mp_copy(&mpi, &tmp); + while (mp_iszero(&tmp) == MP_NO) { + mp_div_d(&tmp, (mp_digit)radix, &tmp, &d); + digits++; + } + if (digits == 0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, digits + 2); /* +2 for sign and NUL byte */ + SvPOK_only(RETVAL); + out_data = SvPVX(RETVAL); + mp_toradix(&mpi, out_data, radix); + SvCUR_set(RETVAL, strlen(out_data)); + } + } + else { + RETVAL = newSVpvn(NULL, 0); /* undef */ } - SvCUR_set(RETVAL, out_len); } + mp_clear_multi(&tmp, &mpi, NULL); } OUTPUT: RETVAL SV * -CryptX__encode_base64(SV * in) +encode_b64(SV * in) + ALIAS: + encode_b64u = 1 CODE: { + int rv; STRLEN in_len; unsigned long out_len; unsigned char *out_data, *in_data; @@ -418,10 +522,14 @@ CryptX__encode_base64(SV * in) } else { out_len = (unsigned long)(4 * ((in_len + 2) / 3) + 1); - RETVAL = NEWSV(0, out_len); + RETVAL = NEWSV(0, out_len); /* avoid zero! */ SvPOK_only(RETVAL); out_data = (unsigned char *)SvPVX(RETVAL); - if (base64_encode(in_data, (unsigned long)in_len, out_data, &out_len) != CRYPT_OK) { + if (ix == 1) + rv = base64url_encode(in_data, (unsigned long)in_len, out_data, &out_len); + else + rv = base64_encode(in_data, (unsigned long)in_len, out_data, &out_len); + if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); XSRETURN_UNDEF; } @@ -432,9 +540,12 @@ CryptX__encode_base64(SV * in) RETVAL SV * -CryptX__decode_base64(SV * in) +decode_b64(SV * in) + ALIAS: + decode_b64u = 1 CODE: { + int rv; STRLEN in_len; unsigned long out_len; unsigned char *out_data, *in_data; @@ -446,10 +557,14 @@ CryptX__decode_base64(SV * in) } else { out_len = (unsigned long)in_len; - RETVAL = NEWSV(0, out_len); + RETVAL = NEWSV(0, out_len); /* avoid zero! */ SvPOK_only(RETVAL); out_data = (unsigned char *)SvPVX(RETVAL); - if (base64_decode(in_data, (unsigned long)in_len, out_data, &out_len) != CRYPT_OK) { + if (ix == 1) + rv = base64url_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); + if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); XSRETURN_UNDEF; } @@ -460,7 +575,11 @@ CryptX__decode_base64(SV * in) RETVAL SV * -CryptX__encode_b32(SV *in, unsigned idx) +encode_b32r(SV *in) + ALIAS: + encode_b32b = 1 + encode_b32z = 2 + encode_b32c = 3 CODE: { STRLEN in_len; @@ -469,10 +588,10 @@ CryptX__encode_b32(SV *in, unsigned idx) int id = -1; if (!SvPOK(in)) XSRETURN_UNDEF; - if (idx == 0) id = BASE32_RFC4648; - if (idx == 1) id = BASE32_BASE32HEX; - if (idx == 2) id = BASE32_ZBASE32; - if (idx == 3) id = BASE32_CROCKFORD; + if (ix == 0) id = BASE32_RFC4648; + if (ix == 1) id = BASE32_BASE32HEX; + if (ix == 2) id = BASE32_ZBASE32; + if (ix == 3) id = BASE32_CROCKFORD; if (id == -1) XSRETURN_UNDEF; in_data = (unsigned char *) SvPVbyte(in, in_len); if (in_len == 0) { @@ -480,7 +599,7 @@ CryptX__encode_b32(SV *in, unsigned idx) } else { out_len = (unsigned long)((8 * in_len + 4) / 5); - RETVAL = NEWSV(0, out_len); + RETVAL = NEWSV(0, out_len); /* avoid zero! */ SvPOK_only(RETVAL); out_data = (unsigned char *)SvPVX(RETVAL); if (base32_encode(in_data, (unsigned long)in_len, out_data, &out_len, id) != CRYPT_OK) { @@ -494,7 +613,11 @@ CryptX__encode_b32(SV *in, unsigned idx) RETVAL SV * -CryptX__decode_b32(SV *in, unsigned idx) +decode_b32r(SV *in) + ALIAS: + decode_b32b = 1 + decode_b32z = 2 + decode_b32c = 3 CODE: { STRLEN in_len; @@ -503,10 +626,10 @@ CryptX__decode_b32(SV *in, unsigned idx) int id = -1; if (!SvPOK(in)) XSRETURN_UNDEF; - if (idx == 0) id = BASE32_RFC4648; - if (idx == 1) id = BASE32_BASE32HEX; - if (idx == 2) id = BASE32_ZBASE32; - if (idx == 3) id = BASE32_CROCKFORD; + if (ix == 0) id = BASE32_RFC4648; + if (ix == 1) id = BASE32_BASE32HEX; + if (ix == 2) id = BASE32_ZBASE32; + if (ix == 3) id = BASE32_CROCKFORD; if (id == -1) XSRETURN_UNDEF; in_data = (unsigned char *)SvPVbyte(in, in_len); if (in_len == 0) { @@ -514,7 +637,7 @@ CryptX__decode_b32(SV *in, unsigned idx) } else { out_len = (unsigned long)in_len; - RETVAL = NEWSV(0, out_len); + 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) { @@ -528,7 +651,7 @@ CryptX__decode_b32(SV *in, unsigned idx) RETVAL SV * -CryptX__increment_octets_le(SV * in) +increment_octets_le(SV * in) CODE: { STRLEN len, i = 0; @@ -536,28 +659,31 @@ CryptX__increment_octets_le(SV * in) if (!SvPOK(in)) XSRETURN_UNDEF; in_data = (unsigned char *)SvPVbyte(in, len); - if (len == 0) XSRETURN_UNDEF; - - RETVAL = NEWSV(0, len); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, len); - out_data = (unsigned char *)SvPVX(RETVAL); - Copy(in_data, out_data, len, unsigned char); - while (i < len) { - out_data[i]++; - if (0 != out_data[i]) break; - i++; + if (len == 0) { + RETVAL = newSVpvn("", 0); } - if (i == len) { - SvREFCNT_dec(RETVAL); - croak("FATAL: increment_octets_le overflow"); + else { + RETVAL = NEWSV(0, len); /* avoid zero! */ + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, len); + out_data = (unsigned char *)SvPVX(RETVAL); + Copy(in_data, out_data, len, unsigned char); + while (i < len) { + out_data[i]++; + if (0 != out_data[i]) break; + i++; + } + if (i == len) { + SvREFCNT_dec(RETVAL); + croak("FATAL: increment_octets_le overflow"); + } } } OUTPUT: RETVAL SV * -CryptX__increment_octets_be(SV * in) +increment_octets_be(SV * in) CODE: { STRLEN len, i = 0; @@ -565,119 +691,29 @@ CryptX__increment_octets_be(SV * in) if (!SvPOK(in)) XSRETURN_UNDEF; in_data = (unsigned char *)SvPVbyte(in, len); - if (len == 0) XSRETURN_UNDEF; - - RETVAL = NEWSV(0, len); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, len); - out_data = (unsigned char *)SvPVX(RETVAL); - Copy(in_data, out_data, len, unsigned char); - while (i < len) { - out_data[len - 1 - i]++; - if (0 != out_data[len - 1 - i]) break; - i++; - } - if (i == len) { - SvREFCNT_dec(RETVAL); - croak("FATAL: increment_octets_be overflow"); + if (len == 0) { + RETVAL = newSVpvn("", 0); } - } - OUTPUT: - RETVAL - -SV * -CryptX__radix_to_bin(char *in, int radix) - CODE: - { - STRLEN len; - unsigned char *out_data; - mp_int mpi; - - if (in == NULL || strlen(in) == 0) XSRETURN_UNDEF; - if (mp_init(&mpi) != CRYPT_OK) XSRETURN_UNDEF; - - if (mp_read_radix(&mpi, in, radix) == CRYPT_OK) { - len = mp_unsigned_bin_size(&mpi); - RETVAL = NEWSV(0, len); + else { + RETVAL = NEWSV(0, len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, len); out_data = (unsigned char *)SvPVX(RETVAL); - mp_to_unsigned_bin(&mpi, out_data); - mp_clear(&mpi); - } - else { - XSRETURN_UNDEF; - } - } - OUTPUT: - RETVAL - -SV * -CryptX__bin_to_radix(SV *in, int radix) - CODE: - { - STRLEN len; - unsigned char *in_data; - char *out_data; - mp_int mpi, tmp; - mp_digit d; - int digits = 0; - - if (!SvPOK(in) || radix < 2 || radix > 64) XSRETURN_UNDEF; - in_data = (unsigned char *) SvPVbyte(in, len); - if (len == 0) XSRETURN_UNDEF; - - mp_init(&mpi); - if (mp_read_unsigned_bin(&mpi, in_data, (unsigned long)len) == CRYPT_OK) { - mp_init_copy(&tmp, &mpi); - while (mp_iszero(&tmp) == MP_NO) { - mp_div_d(&tmp, (mp_digit)radix, &tmp, &d); - digits++; - } - mp_clear(&tmp); - - if (digits == 0) { - RETVAL = newSVpvn("", 0); - mp_clear(&mpi); + Copy(in_data, out_data, len, unsigned char); + while (i < len) { + out_data[len - 1 - i]++; + if (0 != out_data[len - 1 - i]) break; + i++; } - else { - RETVAL = NEWSV(0, digits + 2); /* +2 for sign and NUL byte */ - SvPOK_only(RETVAL); - out_data = SvPVX(RETVAL); - mp_toradix(&mpi, out_data, radix); - SvCUR_set(RETVAL, strlen(out_data)); - mp_clear(&mpi); + if (i == len) { + SvREFCNT_dec(RETVAL); + croak("FATAL: increment_octets_be overflow"); } } - else { - mp_clear(&mpi); - XSRETURN_UNDEF; - } } OUTPUT: RETVAL -SV * -CryptX__ltc_build_settings() - CODE: - RETVAL = newSVpv(crypt_build_settings, 0); - OUTPUT: - RETVAL - -SV * -CryptX__ltc_mp_name() - CODE: - RETVAL = newSVpv(ltc_mp.name, 0); - OUTPUT: - RETVAL - -int -CryptX__ltc_mp_bits_per_digit() - CODE: - RETVAL = ltc_mp.bits_per_digit; - OUTPUT: - RETVAL - ############################################################################### INCLUDE: inc/CryptX_Digest.xs.inc @@ -82,6 +82,10 @@ lib/Crypt/Digest/BLAKE2s_160.pm lib/Crypt/Digest/BLAKE2s_224.pm lib/Crypt/Digest/BLAKE2s_256.pm lib/Crypt/Digest/CHAES.pm +lib/Crypt/Digest/Keccak224.pm +lib/Crypt/Digest/Keccak256.pm +lib/Crypt/Digest/Keccak384.pm +lib/Crypt/Digest/Keccak512.pm lib/Crypt/Digest/MD2.pm lib/Crypt/Digest/MD4.pm lib/Crypt/Digest/MD5.pm @@ -389,6 +393,16 @@ src/ltc/pk/asn1/der/boolean/der_decode_boolean.c src/ltc/pk/asn1/der/boolean/der_encode_boolean.c src/ltc/pk/asn1/der/boolean/der_length_boolean.c src/ltc/pk/asn1/der/choice/der_decode_choice.c +src/ltc/pk/asn1/der/custom_type/der_decode_custom_type.c +src/ltc/pk/asn1/der/custom_type/der_encode_custom_type.c +src/ltc/pk/asn1/der/custom_type/der_length_custom_type.c +src/ltc/pk/asn1/der/general/der_asn1_maps.c +src/ltc/pk/asn1/der/general/der_decode_asn1_identifier.c +src/ltc/pk/asn1/der/general/der_decode_asn1_length.c +src/ltc/pk/asn1/der/general/der_encode_asn1_identifier.c +src/ltc/pk/asn1/der/general/der_encode_asn1_length.c +src/ltc/pk/asn1/der/general/der_length_asn1_identifier.c +src/ltc/pk/asn1/der/general/der_length_asn1_length.c src/ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c src/ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c src/ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.c @@ -410,10 +424,8 @@ src/ltc/pk/asn1/der/printable_string/der_length_printable_string.c src/ltc/pk/asn1/der/sequence/der_decode_sequence_ex.c src/ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.c src/ltc/pk/asn1/der/sequence/der_decode_sequence_multi.c -src/ltc/pk/asn1/der/sequence/der_decode_subject_public_key_info.c src/ltc/pk/asn1/der/sequence/der_encode_sequence_ex.c src/ltc/pk/asn1/der/sequence/der_encode_sequence_multi.c -src/ltc/pk/asn1/der/sequence/der_encode_subject_public_key_info.c src/ltc/pk/asn1/der/sequence/der_length_sequence.c src/ltc/pk/asn1/der/sequence/der_sequence_free.c src/ltc/pk/asn1/der/sequence/der_sequence_shrink.c @@ -430,6 +442,8 @@ src/ltc/pk/asn1/der/utctime/der_length_utctime.c src/ltc/pk/asn1/der/utf8/der_decode_utf8_string.c src/ltc/pk/asn1/der/utf8/der_encode_utf8_string.c src/ltc/pk/asn1/der/utf8/der_length_utf8_string.c +src/ltc/pk/asn1/x509/x509_decode_subject_public_key_info.c +src/ltc/pk/asn1/x509/x509_encode_subject_public_key_info.c src/ltc/pk/dh/dh.c src/ltc/pk/dh/dh_check_pubkey.c src/ltc/pk/dh/dh_export.c @@ -458,33 +472,29 @@ src/ltc/pk/ecc/ecc.c src/ltc/pk/ecc/ecc_ansi_x963_export.c src/ltc/pk/ecc/ecc_ansi_x963_import.c src/ltc/pk/ecc/ecc_decrypt_key.c -src/ltc/pk/ecc/ecc_dp_clear.c -src/ltc/pk/ecc/ecc_dp_fill_from_sets.c -src/ltc/pk/ecc/ecc_dp_from_oid.c -src/ltc/pk/ecc/ecc_dp_from_params.c -src/ltc/pk/ecc/ecc_dp_init.c -src/ltc/pk/ecc/ecc_dp_set.c src/ltc/pk/ecc/ecc_encrypt_key.c src/ltc/pk/ecc/ecc_export.c -src/ltc/pk/ecc/ecc_export_full.c -src/ltc/pk/ecc/ecc_export_raw.c +src/ltc/pk/ecc/ecc_export_openssl.c src/ltc/pk/ecc/ecc_free.c +src/ltc/pk/ecc/ecc_get_key.c +src/ltc/pk/ecc/ecc_get_set.c src/ltc/pk/ecc/ecc_get_size.c src/ltc/pk/ecc/ecc_import.c -src/ltc/pk/ecc/ecc_import_full.c +src/ltc/pk/ecc/ecc_import_openssl.c src/ltc/pk/ecc/ecc_import_pkcs8.c -src/ltc/pk/ecc/ecc_import_raw.c +src/ltc/pk/ecc/ecc_import_x509.c src/ltc/pk/ecc/ecc_make_key.c +src/ltc/pk/ecc/ecc_set_dp.c +src/ltc/pk/ecc/ecc_set_dp_internal.c +src/ltc/pk/ecc/ecc_set_key.c src/ltc/pk/ecc/ecc_shared_secret.c src/ltc/pk/ecc/ecc_sign_hash.c src/ltc/pk/ecc/ecc_sizes.c src/ltc/pk/ecc/ecc_verify_hash.c -src/ltc/pk/ecc/ecc_verify_key.c src/ltc/pk/ecc/ltc_ecc_export_point.c src/ltc/pk/ecc/ltc_ecc_import_point.c src/ltc/pk/ecc/ltc_ecc_is_point.c src/ltc/pk/ecc/ltc_ecc_is_point_at_infinity.c -src/ltc/pk/ecc/ltc_ecc_is_valid_idx.c src/ltc/pk/ecc/ltc_ecc_map.c src/ltc/pk/ecc/ltc_ecc_mul2add.c src/ltc/pk/ecc/ltc_ecc_mulmod.c @@ -492,6 +502,7 @@ src/ltc/pk/ecc/ltc_ecc_mulmod_timing.c src/ltc/pk/ecc/ltc_ecc_points.c src/ltc/pk/ecc/ltc_ecc_projective_add_point.c src/ltc/pk/ecc/ltc_ecc_projective_dbl_point.c +src/ltc/pk/ecc/ltc_ecc_verify_key.c src/ltc/pk/pkcs1/pkcs_1_i2osp.c src/ltc/pk/pkcs1/pkcs_1_mgf1.c src/ltc/pk/pkcs1/pkcs_1_oaep_decode.c @@ -904,6 +915,10 @@ t/digest_blake2s_160.t t/digest_blake2s_224.t t/digest_blake2s_256.t t/digest_chaes.t +t/digest_keccak224.t +t/digest_keccak256.t +t/digest_keccak384.t +t/digest_keccak512.t t/digest_md2.t t/digest_md4.t t/digest_md5.t @@ -45,6 +45,6 @@ "url" : "https://github.com/DCIT/perl-CryptX" } }, - "version" : "0.056", + "version" : "0.059", "x_serialization_backend" : "JSON::PP version 2.94" } @@ -22,5 +22,5 @@ requires: resources: bugtracker: https://github.com/DCIT/perl-CryptX/issues repository: https://github.com/DCIT/perl-CryptX -version: '0.056' +version: '0.059' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff --git a/Makefile.PL b/Makefile.PL index e23147fb..11f9956a 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -3,38 +3,58 @@ use warnings; use ExtUtils::MakeMaker; use Config; -my @myobjs = map { s|.c$|$Config{obj_ext}|; $_ } grep { $_ !~ m|^src/ltc/\.*tab\.c$| } ( - glob('src/ltm/*.c'), - glob('src/ltc/*/*.c'), - glob('src/ltc/*/*/*.c'), - glob('src/ltc/*/*/*/*.c'), - glob('src/ltc/*/*/*/*/*.c'), -); -my $myextlib = "src/liballinone$Config{lib_ext}"; -my $mycflags = "$Config{ccflags} $Config{cccdlflags} $Config{optimize}"; - -#FIX: this is particularly useful for Debian https://github.com/DCIT/perl-CryptX/pull/39 -$mycflags .= " $ENV{CFLAGS}" if $ENV{CFLAGS}; -$mycflags .= " $ENV{CPPFLAGS}" if $ENV{CPPFLAGS}; - -#FIX: gcc with -flto is a trouble maker see https://github.com/DCIT/perl-CryptX/issues/32 -$mycflags =~ s/-flto\b//g; - -#FIX: avoid -Wwrite-strings -Wcast-qual -pedantic -pedantic-errors -ansi -std=c89 -$mycflags =~ s/-pedantic\b//g; -$mycflags =~ s/-pedantic-errors\b//g; -$mycflags =~ s/-std=c89\b//g; -$mycflags =~ s/-ansi\b//g; -$mycflags =~ s/-Wwrite-strings\b//g; -$mycflags =~ s/-Wcast-qual\b//g; - -#FIX: avoid "ar: fatal: Numeric group ID too large" see https://github.com/DCIT/perl-CryptX/issues/33 -my $myarflags = '$(AR_STATIC_ARGS)'; -if ($^O ne 'MSWin32' && $Config{ar}) { - # for ar's "deterministic mode" we need GNU binutils 2.20+ (2009-10-16) - my $arver = `$Config{ar} --version 2>/dev/null`; - my ($maj, $min) = $arver =~ /^GNU ar [^\d]*(\d)\.(\d+)\.\d+/s; - $myarflags = 'rcD' if ($maj && $min && $maj >= 2 && $min >= 20) || $arver=~ /^BSD ar /; +my (@EUMM_INC_LIB, $myarflags, $mycflags); + +if ($ENV{CRYPTX_CFLAGS} || $ENV{CRYPTX_LDFLAGS}) { + # EXPERIMENTAL: use system libraries libtomcrypt + libtommath + # e.g. + # CRYPTX_LDFLAGS='-L/usr/local/lib -ltommath -ltomcrypt' CRYPTX_CFLAGS='-DLTM_DESC -I/usr/local/include' perl Makefile.PL + print "CRYPTX_CFLAGS = $ENV{CRYPTX_CFLAGS}\n" if $ENV{CRYPTX_CFLAGS}; + print "CRYPTX_LDFLAGS = $ENV{CRYPTX_LDFLAGS}\n" if $ENV{CRYPTX_LDFLAGS}; + @EUMM_INC_LIB = ( + INC => $ENV{CRYPTX_CFLAGS}, + LIBS => [ $ENV{CRYPTX_LDFLAGS} ], + ); +} +else { + # PREFERRED: use bundled libtomcrypt + libtommath (from ./src subdir) + my @myobjs = map { s|.c$|$Config{obj_ext}|; $_ } grep { $_ !~ m|^src/ltc/\.*tab\.c$| } ( + glob('src/ltm/*.c'), + glob('src/ltc/*/*.c'), + glob('src/ltc/*/*/*.c'), + glob('src/ltc/*/*/*/*.c'), + glob('src/ltc/*/*/*/*/*.c'), + ); + $mycflags = "$Config{ccflags} $Config{cccdlflags} $Config{optimize}"; + + #FIX: this is particularly useful for Debian https://github.com/DCIT/perl-CryptX/pull/39 + $mycflags .= " $ENV{CFLAGS}" if $ENV{CFLAGS}; + $mycflags .= " $ENV{CPPFLAGS}" if $ENV{CPPFLAGS}; + + #FIX: gcc with -flto is a trouble maker see https://github.com/DCIT/perl-CryptX/issues/32 + $mycflags =~ s/-flto\b//g; + + #FIX: avoid -Wwrite-strings -Wcast-qual -pedantic -pedantic-errors -ansi -std=c89 + $mycflags =~ s/-pedantic\b//g; + $mycflags =~ s/-pedantic-errors\b//g; + $mycflags =~ s/-std=c89\b//g; + $mycflags =~ s/-ansi\b//g; + $mycflags =~ s/-Wwrite-strings\b//g; + $mycflags =~ s/-Wcast-qual\b//g; + + #FIX: avoid "ar: fatal: Numeric group ID too large" see https://github.com/DCIT/perl-CryptX/issues/33 + $myarflags = '$(AR_STATIC_ARGS)'; + if ($^O ne 'MSWin32' && $Config{ar}) { + # for ar's "deterministic mode" we need GNU binutils 2.20+ (2009-10-16) + my $arver = `$Config{ar} --version 2>/dev/null`; + my ($maj, $min) = $arver =~ /^GNU ar [^\d]*(\d)\.(\d+)\.\d+/s; + $myarflags = 'rcD' if ($maj && $min && $maj >= 2 && $min >= 20) || $arver=~ /^BSD ar /; + } + @EUMM_INC_LIB = ( + INC => '-DLTM_DESC -Isrc/ltc/headers -Isrc/ltm', + MYEXTLIB => "src/liballinone$Config{lib_ext}", + clean => { 'FILES' => join(' ', @myobjs, "src/liballinone$Config{lib_ext}") }, + ); } my %eumm_args = ( @@ -46,23 +66,10 @@ my %eumm_args = ( LICENSE => 'perl_5', META_MERGE => { resources => { repository => 'https://github.com/DCIT/perl-CryptX', bugtracker => 'https://github.com/DCIT/perl-CryptX/issues' } }, dist => { 'PREOP' => 'perldoc -u lib/CryptX.pm | pod2markdown > README.md' }, - ($ENV{CRYPTX_CFLAGS} || $ENV{CRYPTX_LDFLAGS}) - ? - ( - # e.g. CRYPTX_LDFLAGS='-L/usr/local/lib -ltommath -ltomcrypt' CRYPTX_CFLAGS='-DLTM_DESC -I/usr/local/include' perl Makefile.PL - INC => $ENV{CRYPTX_CFLAGS}, - LIBS => [ $ENV{CRYPTX_LDFLAGS} ], - ) - : - ( - # bundled libtomcrypt + libtommath - INC => '-DLTM_DESC -Isrc/ltc/headers -Isrc/ltm', - MYEXTLIB => $myextlib, - clean => { 'FILES' => join(' ', @myobjs, $myextlib) }, - ) + @EUMM_INC_LIB ); -my $eumm_ver = eval $ExtUtils::MakeMaker::VERSION; +my $eumm_ver = eval $ExtUtils::MakeMaker::VERSION; delete $eumm_args{MIN_PERL_VERSION} if $eumm_ver < 6.48; delete $eumm_args{META_ADD} if $eumm_ver < 6.46; delete $eumm_args{META_MERGE} if $eumm_ver < 6.46; @@ -70,25 +77,25 @@ delete $eumm_args{LICENSE} if $eumm_ver < 6.31; WriteMakefile(%eumm_args); -# ARFLAGS=\$(AR_STATIC_ARGS) RANLIB=\$(RANLIB) AR=\$(AR) - sub MY::postamble { - my $myextlib = qq{ + return "" unless $mycflags && $myarflags; + + my $extra_targets = qq{ \$(MYEXTLIB): src/Makefile cd src && \$(MAKE) ARFLAGS="$myarflags" RANLIB="\$(RANLIB)" AR="\$(AR)" CC="\$(CC)" LIB_EXT=\$(LIB_EXT) OBJ_EXT=\$(OBJ_EXT) CFLAGS="$mycflags" }; - $myextlib = qq{ + $extra_targets = qq{ \$(MYEXTLIB): src/Makefile cd src && \$(MAKE) -f Makefile.nmake CFLAGS="$mycflags" } if $^O eq 'MSWin32' && $Config{make} =~ /nmake/ && $Config{cc} =~ /cl/; - $myextlib = qq{ + $extra_targets = qq{ \$(MYEXTLIB): src/Makefile cd src && \$(MAKE) CC="$Config{cc}" CFLAGS="$mycflags" } if $^O eq 'MSWin32' && $Config{cc} =~ /gcc/; - my $version_patch = q{ + $extra_targets .= q{ versionsync: $(NOECHO) perl _generators/version_patch.pl sync versioninc: @@ -107,7 +114,12 @@ openssltest: all $(NOECHO) perl -Mblib t/openssl/dsa-test.pl $(NOECHO) perl -Mblib t/openssl/ecc-test.pl $(NOECHO) perl -Mblib t/openssl/rsa-test.pl +rebuild-pre: + $(RM_F) src/liballinone.a + $(TOUCH) CryptX.xs +rebuild: rebuild-pre all + }; - return "$myextlib\n$version_patch"; + return $extra_targets; } @@ -6,7 +6,7 @@ CryptX - Cryptographic toolkit (self-contained, no external libraries needed) Cryptography in CryptX is based on [https://github.com/libtom/libtomcrypt](https://github.com/libtom/libtomcrypt) -Currently available modules: +Available modules: - Symmetric ciphers - see [Crypt::Cipher](https://metacpan.org/pod/Crypt::Cipher) and related modules @@ -36,11 +36,12 @@ Currently available modules: [Crypt::Digest::CHAES](https://metacpan.org/pod/Crypt::Digest::CHAES), [Crypt::Digest::MD2](https://metacpan.org/pod/Crypt::Digest::MD2), [Crypt::Digest::MD4](https://metacpan.org/pod/Crypt::Digest::MD4), [Crypt::Digest::MD5](https://metacpan.org/pod/Crypt::Digest::MD5), [Crypt::Digest::RIPEMD128](https://metacpan.org/pod/Crypt::Digest::RIPEMD128), [Crypt::Digest::RIPEMD160](https://metacpan.org/pod/Crypt::Digest::RIPEMD160), [Crypt::Digest::RIPEMD256](https://metacpan.org/pod/Crypt::Digest::RIPEMD256), [Crypt::Digest::RIPEMD320](https://metacpan.org/pod/Crypt::Digest::RIPEMD320), [Crypt::Digest::SHA1](https://metacpan.org/pod/Crypt::Digest::SHA1), [Crypt::Digest::SHA224](https://metacpan.org/pod/Crypt::Digest::SHA224), [Crypt::Digest::SHA256](https://metacpan.org/pod/Crypt::Digest::SHA256), [Crypt::Digest::SHA384](https://metacpan.org/pod/Crypt::Digest::SHA384), [Crypt::Digest::SHA512](https://metacpan.org/pod/Crypt::Digest::SHA512), [Crypt::Digest::SHA512\_224](https://metacpan.org/pod/Crypt::Digest::SHA512_224), [Crypt::Digest::SHA512\_256](https://metacpan.org/pod/Crypt::Digest::SHA512_256), [Crypt::Digest::Tiger192](https://metacpan.org/pod/Crypt::Digest::Tiger192), [Crypt::Digest::Whirlpool](https://metacpan.org/pod/Crypt::Digest::Whirlpool), + [Crypt::Digest::Keccak224](https://metacpan.org/pod/Crypt::Digest::Keccak224), [Crypt::Digest::Keccak256](https://metacpan.org/pod/Crypt::Digest::Keccak256), [Crypt::Digest::Keccak384](https://metacpan.org/pod/Crypt::Digest::Keccak384), [Crypt::Digest::Keccak512](https://metacpan.org/pod/Crypt::Digest::Keccak512), [Crypt::Digest::SHA3\_224](https://metacpan.org/pod/Crypt::Digest::SHA3_224), [Crypt::Digest::SHA3\_256](https://metacpan.org/pod/Crypt::Digest::SHA3_256), [Crypt::Digest::SHA3\_384](https://metacpan.org/pod/Crypt::Digest::SHA3_384), [Crypt::Digest::SHA3\_512](https://metacpan.org/pod/Crypt::Digest::SHA3_512), [Crypt::Digest::SHAKE](https://metacpan.org/pod/Crypt::Digest::SHAKE) - Checksums - [Crypt::Checksum](https://metacpan.org/pod/Crypt::Checksum), [Crypt::Checksum::Adler32](https://metacpan.org/pod/Crypt::Checksum::Adler32), [Crypt::Checksum::CRC32](https://metacpan.org/pod/Crypt::Checksum::CRC32) + [Crypt::Checksum::Adler32](https://metacpan.org/pod/Crypt::Checksum::Adler32), [Crypt::Checksum::CRC32](https://metacpan.org/pod/Crypt::Checksum::CRC32) - Message Authentication Codes @@ -51,9 +52,9 @@ Currently available modules: [Crypt::PK::RSA](https://metacpan.org/pod/Crypt::PK::RSA), [Crypt::PK::DSA](https://metacpan.org/pod/Crypt::PK::DSA), [Crypt::PK::ECC](https://metacpan.org/pod/Crypt::PK::ECC), [Crypt::PK::DH](https://metacpan.org/pod/Crypt::PK::DH) -- Cryptographically secure random number generators +- Cryptographically secure random number generators - see [Crypt::PRNG](https://metacpan.org/pod/Crypt::PRNG) and related modules - [Crypt::PRNG](https://metacpan.org/pod/Crypt::PRNG), [Crypt::PRNG::Fortuna](https://metacpan.org/pod/Crypt::PRNG::Fortuna), [Crypt::PRNG::Yarrow](https://metacpan.org/pod/Crypt::PRNG::Yarrow), [Crypt::PRNG::RC4](https://metacpan.org/pod/Crypt::PRNG::RC4), [Crypt::PRNG::Sober128](https://metacpan.org/pod/Crypt::PRNG::Sober128), [Crypt::PRNG::ChaCha20](https://metacpan.org/pod/Crypt::PRNG::ChaCha20) + [Crypt::PRNG::Fortuna](https://metacpan.org/pod/Crypt::PRNG::Fortuna), [Crypt::PRNG::Yarrow](https://metacpan.org/pod/Crypt::PRNG::Yarrow), [Crypt::PRNG::RC4](https://metacpan.org/pod/Crypt::PRNG::RC4), [Crypt::PRNG::Sober128](https://metacpan.org/pod/Crypt::PRNG::Sober128), [Crypt::PRNG::ChaCha20](https://metacpan.org/pod/Crypt::PRNG::ChaCha20) - Key derivation functions - PBKDF1, PBKDF2 and HKDF @@ -69,4 +70,4 @@ This program is free software; you can redistribute it and/or modify it under th # COPYRIGHT -Copyright (c) 2013+ DCIT, a.s. [http://www.dcit.cz](http://www.dcit.cz) / Karel Miko +Copyright (c) 2013+ DCIT, a.s. [https://www.dcit.cz](https://www.dcit.cz) / Karel Miko diff --git a/inc/CryptX_AuthEnc_CCM.xs.inc b/inc/CryptX_AuthEnc_CCM.xs.inc index f2be57a1..312feebb 100644 --- a/inc/CryptX_AuthEnc_CCM.xs.inc +++ b/inc/CryptX_AuthEnc_CCM.xs.inc @@ -1,7 +1,9 @@ MODULE = CryptX PACKAGE = Crypt::AuthEnc::CCM +PROTOTYPES: DISABLE + Crypt::AuthEnc::CCM -_new(char * cipher_name, SV * key, SV * nonce, SV * adata, int tag_len, int pt_len) +new(Class, char * cipher_name, SV * key, SV * nonce, SV * adata, int tag_len, int pt_len) CODE: { unsigned char *k=NULL; @@ -21,30 +23,27 @@ _new(char * cipher_name, SV * key, SV * nonce, SV * adata, int tag_len, int pt_l if (!SvPOK(adata)) croak("FATAL: adata must be string/buffer scalar"); h = (unsigned char *) SvPVbyte(adata, h_len); - id = find_cipher(cipher_name); + id = _find_cipher(cipher_name); if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); - Newz(0, RETVAL, 1, struct ccm_struct); + Newz(0, RETVAL, 1, ccm_state); if (!RETVAL) croak("FATAL: Newz failed"); - rv = ccm_init(&RETVAL->state, id, k, (int)k_len, (int)pt_len, (int)tag_len, (int)h_len); /* XXX-TODO why int? */ + rv = ccm_init(RETVAL, id, k, (int)k_len, (int)pt_len, (int)tag_len, (int)h_len); /* XXX-TODO why int? */ if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: ccm_init failed: %s", error_to_string(rv)); } - rv = ccm_add_nonce(&RETVAL->state, n, (unsigned long)n_len); + rv = ccm_add_nonce(RETVAL, n, (unsigned long)n_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: ccm_add_nonce failed: %s", error_to_string(rv)); } - rv = ccm_add_aad(&RETVAL->state, h, (unsigned long)h_len); + rv = ccm_add_aad(RETVAL, h, (unsigned long)h_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: ccm_add_aad failed: %s", error_to_string(rv)); } - RETVAL->direction = -1; - RETVAL->tag_len = tag_len; - RETVAL->pt_len = pt_len; } OUTPUT: RETVAL @@ -57,9 +56,9 @@ DESTROY(Crypt::AuthEnc::CCM self) Crypt::AuthEnc::CCM clone(Crypt::AuthEnc::CCM self) CODE: - Newz(0, RETVAL, 1, struct ccm_struct); + Newz(0, RETVAL, 1, ccm_state); if (!RETVAL) croak("FATAL: Newz failed"); - Copy(&self->state, &RETVAL->state, 1, struct ccm_struct); + Copy(self, RETVAL, 1, ccm_state); OUTPUT: RETVAL @@ -76,21 +75,15 @@ encrypt_add(Crypt::AuthEnc::CCM self, SV * data) RETVAL = newSVpvn("", 0); } else { - if (self->direction == -1) self->direction = CCM_ENCRYPT; - if (self->direction != CCM_ENCRYPT) { - croak("FATAL: encrypt_add failed: wrong direction"); - } - if (self->pt_len < in_data_len) croak("FATAL: encrypt_add failed: pt_len mismatch"); - RETVAL = NEWSV(0, in_data_len); + RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, in_data_len); out_data = (unsigned char *)SvPVX(RETVAL); - rv = ccm_process(&self->state, in_data, (unsigned long)in_data_len, out_data, self->direction); + rv = ccm_process(self, in_data, (unsigned long)in_data_len, out_data, CCM_ENCRYPT); if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); croak("FATAL: ccm_process failed: %s", error_to_string(rv)); } - self->pt_len -= (unsigned long)in_data_len; } } OUTPUT: @@ -109,21 +102,15 @@ decrypt_add(Crypt::AuthEnc::CCM self, SV * data) RETVAL = newSVpvn("", 0); } else { - if (self->direction == -1) self->direction = CCM_DECRYPT; - if (self->direction != CCM_DECRYPT) { - croak("FATAL: decrypt_add failed: wrong direction"); - } - if (self->pt_len < in_data_len) croak("FATAL: decrypt_add failed: pt_len mismatch"); - RETVAL = NEWSV(0, in_data_len); + RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, in_data_len); out_data = (unsigned char *)SvPVX(RETVAL); - rv = ccm_process(&self->state, out_data, (unsigned long)in_data_len, in_data, CCM_DECRYPT); + rv = ccm_process(self, out_data, (unsigned long)in_data_len, in_data, CCM_DECRYPT); if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); croak("FATAL: ccm_process failed: %s", error_to_string(rv)); } - self->pt_len -= (unsigned long)in_data_len; } } OUTPUT: @@ -135,13 +122,9 @@ encrypt_done(Crypt::AuthEnc::CCM self) { int rv; unsigned char tag[MAXBLOCKSIZE]; - unsigned long tag_len = self->tag_len; + unsigned long tag_len = MAXBLOCKSIZE; - if (self->direction != CCM_ENCRYPT) { - croak("FATAL: encrypt_done failed: wrong direction"); - } - if (self->pt_len != 0) croak("FATAL: encrypt_done failed: pt_len mismatch"); - rv = ccm_done(&self->state, tag, &tag_len); + rv = ccm_done(self, tag, &tag_len); if (rv != CRYPT_OK) croak("FATAL: ccm_done failed: %s", error_to_string(rv)); XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); } @@ -152,15 +135,11 @@ decrypt_done(Crypt::AuthEnc::CCM self, ...) { int rv; unsigned char tag[MAXBLOCKSIZE]; - unsigned long tag_len = self->tag_len; + unsigned long tag_len = MAXBLOCKSIZE; STRLEN expected_tag_len; unsigned char *expected_tag; - if (self->direction != CCM_DECRYPT) { - croak("FATAL: decrypt_done failed: wrong direction"); - } - if (self->pt_len != 0) croak("FATAL: decrypt_done failed: pt_len mismatch"); - rv = ccm_done(&self->state, tag, &tag_len); + rv = ccm_done(self, tag, &tag_len); if (rv != CRYPT_OK) croak("FATAL: ccm_done failed: %s", error_to_string(rv)); if (items == 1) { XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); @@ -179,3 +158,73 @@ decrypt_done(Crypt::AuthEnc::CCM self, ...) } } } + +void +ccm_encrypt_authenticate(char *cipher_name, SV *key, SV *nonce, SV *header, unsigned long tag_len, SV *plaintext) + PPCODE: + { + STRLEN k_len = 0, n_len = 0, h_len = 0, pt_len = 0; + unsigned char *k = NULL, *n = NULL, *h = NULL, *pt = NULL; + int rv, id; + unsigned char tag[MAXBLOCKSIZE]; + SV *output; + + if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len); + if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len); + if (SvPOK(plaintext)) pt = (unsigned char *) SvPVbyte(plaintext, pt_len); + if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len); + + id = _find_cipher(cipher_name); + if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + output = NEWSV(0, pt_len > 0 ? pt_len : 1); /* avoid zero! */ + SvPOK_only(output); + SvCUR_set(output, pt_len); + if(tag_len < 4 || tag_len > 16) tag_len = 16; + + rv = ccm_memory(id, k, (unsigned long)k_len, NULL, n, (unsigned long)n_len, h, (unsigned long)h_len, + pt, (unsigned long)pt_len, (unsigned char *)SvPVX(output), tag, &tag_len, CCM_ENCRYPT); + + if (rv != CRYPT_OK) { + SvREFCNT_dec(output); + croak("FATAL: ccm_memory failed: %s", error_to_string(rv)); + } + XPUSHs(sv_2mortal(output)); + XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); + } + +void +ccm_decrypt_verify(char *cipher_name, SV *key, SV *nonce, SV *header, SV *ciphertext, SV *tagsv) + PPCODE: + { + STRLEN k_len = 0, n_len = 0, h_len = 0, ct_len = 0, t_len = 0; + unsigned char *k = NULL, *n = NULL, *h = NULL, *ct = NULL, *t = NULL; + int rv, id; + unsigned char tag[MAXBLOCKSIZE]; + unsigned long tag_len; + SV *output; + + if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len); + if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len); + if (SvPOK(ciphertext)) ct = (unsigned char *) SvPVbyte(ciphertext, ct_len); + if (SvPOK(tagsv)) t = (unsigned char *) SvPVbyte(tagsv, t_len); + if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len); + + id = _find_cipher(cipher_name); + if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + output = NEWSV(0, ct_len > 0 ? ct_len : 1); /* avoid zero! */ + SvPOK_only(output); + SvCUR_set(output, ct_len); + tag_len = (unsigned long)t_len; + Copy(t, tag, t_len, unsigned char); + + rv = ccm_memory(id, k, (unsigned long)k_len, NULL, n, (unsigned long)n_len, h, (unsigned long)h_len, + (unsigned char *)SvPVX(output), (unsigned long)ct_len, ct, tag, &tag_len, CCM_DECRYPT); + + if (rv != CRYPT_OK) { + SvREFCNT_dec(output); + XPUSHs(sv_2mortal(newSVpvn(NULL,0))); /* undef */ + } + else { + XPUSHs(sv_2mortal(output)); + } + } diff --git a/inc/CryptX_AuthEnc_ChaCha20Poly1305.xs.inc b/inc/CryptX_AuthEnc_ChaCha20Poly1305.xs.inc index 7b8ff58d..8a32ef49 100644 --- a/inc/CryptX_AuthEnc_ChaCha20Poly1305.xs.inc +++ b/inc/CryptX_AuthEnc_ChaCha20Poly1305.xs.inc @@ -1,7 +1,9 @@ MODULE = CryptX PACKAGE = Crypt::AuthEnc::ChaCha20Poly1305 +PROTOTYPES: DISABLE + Crypt::AuthEnc::ChaCha20Poly1305 -_new(SV * key, SV * nonce = NULL) +new(Class, SV * key, SV * nonce = NULL) CODE: { int rv; @@ -15,17 +17,17 @@ _new(SV * key, SV * nonce = NULL) iv = (unsigned char *) SvPVbyte(nonce, iv_len); } - Newz(0, RETVAL, 1, struct chacha20poly1305_struct); + Newz(0, RETVAL, 1, chacha20poly1305_state); if (!RETVAL) croak("FATAL: Newz failed"); - rv = chacha20poly1305_init(&RETVAL->state, k, (unsigned long)k_len); + rv = chacha20poly1305_init(RETVAL, k, (unsigned long)k_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: chacha20poly1305_init failed: %s", error_to_string(rv)); } if (iv && iv_len > 0) { - rv = chacha20poly1305_setiv(&RETVAL->state, iv, (unsigned long)iv_len); + rv = chacha20poly1305_setiv(RETVAL, iv, (unsigned long)iv_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: chacha20poly1305_setiv failed: %s", error_to_string(rv)); @@ -43,9 +45,9 @@ DESTROY(Crypt::AuthEnc::ChaCha20Poly1305 self) Crypt::AuthEnc::ChaCha20Poly1305 clone(Crypt::AuthEnc::ChaCha20Poly1305 self) CODE: - Newz(0, RETVAL, 1, struct chacha20poly1305_struct); + Newz(0, RETVAL, 1, chacha20poly1305_state); if (!RETVAL) croak("FATAL: Newz failed"); - Copy(&self->state, &RETVAL->state, 1, struct chacha20poly1305_struct); + Copy(self, RETVAL, 1, chacha20poly1305_state); OUTPUT: RETVAL @@ -59,7 +61,7 @@ set_iv(Crypt::AuthEnc::ChaCha20Poly1305 self, SV * nonce) if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar"); iv = (unsigned char *) SvPVbyte(nonce, iv_len); - rv = chacha20poly1305_setiv(&self->state, iv, (unsigned long)iv_len); + rv = chacha20poly1305_setiv(self, iv, (unsigned long)iv_len); if (rv != CRYPT_OK) croak("FATAL: chacha20poly1305_setiv failed: %s", error_to_string(rv)); XPUSHs(ST(0)); /* return self */; } @@ -74,7 +76,7 @@ set_iv_rfc7905(Crypt::AuthEnc::ChaCha20Poly1305 self, SV * nonce, UV seqnum) if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar"); iv = (unsigned char *) SvPVbyte(nonce, iv_len); - rv = chacha20poly1305_setiv_rfc7905(&self->state, iv, (unsigned long)iv_len, (ulong64)seqnum); + rv = chacha20poly1305_setiv_rfc7905(self, iv, (unsigned long)iv_len, (ulong64)seqnum); if (rv != CRYPT_OK) croak("FATAL: chacha20poly1305_setiv_rfc7905 failed: %s", error_to_string(rv)); XPUSHs(ST(0)); /* return self */ } @@ -88,7 +90,7 @@ adata_add(Crypt::AuthEnc::ChaCha20Poly1305 self, SV * data) unsigned char *in_data; in_data = (unsigned char *)SvPVbyte(data, in_data_len); - rv = chacha20poly1305_add_aad(&self->state, in_data, (unsigned long)in_data_len); + rv = chacha20poly1305_add_aad(self, in_data, (unsigned long)in_data_len); if (rv != CRYPT_OK) croak("FATAL: chacha20poly1305_add_aad failed: %s", error_to_string(rv)); XPUSHs(ST(0)); /* return self */ } @@ -106,11 +108,11 @@ decrypt_add(Crypt::AuthEnc::ChaCha20Poly1305 self, SV * data) RETVAL = newSVpvn("", 0); } else { - RETVAL = NEWSV(0, in_data_len); + RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, in_data_len); out_data = (unsigned char *)SvPVX(RETVAL); - rv = chacha20poly1305_decrypt(&self->state, in_data, (unsigned long)in_data_len, out_data); + rv = chacha20poly1305_decrypt(self, in_data, (unsigned long)in_data_len, out_data); if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); croak("FATAL: chacha20poly1305_decrypt failed: %s", error_to_string(rv)); @@ -133,11 +135,11 @@ encrypt_add(Crypt::AuthEnc::ChaCha20Poly1305 self, SV * data) RETVAL = newSVpvn("", 0); } else { - RETVAL = NEWSV(0, in_data_len); + RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, in_data_len); out_data = (unsigned char *)SvPVX(RETVAL); - rv = chacha20poly1305_encrypt(&self->state, in_data, (unsigned long)in_data_len, out_data); + rv = chacha20poly1305_encrypt(self, in_data, (unsigned long)in_data_len, out_data); if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); croak("FATAL: chacha20poly1305_encrypt failed: %s", error_to_string(rv)); @@ -155,7 +157,7 @@ encrypt_done(Crypt::AuthEnc::ChaCha20Poly1305 self) unsigned char tag[MAXBLOCKSIZE]; unsigned long tag_len = sizeof(tag); - rv = chacha20poly1305_done(&self->state, tag, &tag_len); + rv = chacha20poly1305_done(self, tag, &tag_len); if (rv != CRYPT_OK) croak("FATAL: chacha20poly1305_done failed: %s", error_to_string(rv)); XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); } @@ -170,7 +172,7 @@ decrypt_done(Crypt::AuthEnc::ChaCha20Poly1305 self, ...) STRLEN expected_tag_len; unsigned char *expected_tag; - rv = chacha20poly1305_done(&self->state, tag, &tag_len); + rv = chacha20poly1305_done(self, tag, &tag_len); if (rv != CRYPT_OK) croak("FATAL: chacha20poly1305_done failed: %s", error_to_string(rv)); if (items == 1) { XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); @@ -189,3 +191,71 @@ decrypt_done(Crypt::AuthEnc::ChaCha20Poly1305 self, ...) } } } + +void +chacha20poly1305_encrypt_authenticate(SV *key, SV *nonce, SV *header, SV *plaintext) + PPCODE: + { + STRLEN k_len = 0, n_len = 0, h_len = 0, pt_len = 0; + unsigned char *k = NULL, *n = NULL, *h = NULL, *pt = NULL; + int rv; + unsigned char tag[MAXBLOCKSIZE]; + unsigned long tag_len = sizeof(tag); + SV *output; + + if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len); + if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len); + if (SvPOK(plaintext)) pt = (unsigned char *) SvPVbyte(plaintext, pt_len); + if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len); + + output = NEWSV(0, pt_len > 0 ? pt_len : 1); /* avoid zero! */ + SvPOK_only(output); + SvCUR_set(output, pt_len); + + rv = chacha20poly1305_memory(k, (unsigned long)k_len, n, (unsigned long)n_len, h, (unsigned long)h_len, + pt, (unsigned long)pt_len, (unsigned char *)SvPVX(output), tag, &tag_len, + CHACHA20POLY1305_ENCRYPT); + + if (rv != CRYPT_OK) { + SvREFCNT_dec(output); + croak("FATAL: ccm_memory failed: %s", error_to_string(rv)); + } + XPUSHs(sv_2mortal(output)); + XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); + } + +void +chacha20poly1305_decrypt_verify(SV *key, SV *nonce, SV *header, SV *ciphertext, SV *tagsv) + PPCODE: + { + STRLEN k_len = 0, n_len = 0, h_len = 0, ct_len = 0, t_len = 0; + unsigned char *k = NULL, *n = NULL, *h = NULL, *ct = NULL, *t = NULL; + int rv; + unsigned char tag[MAXBLOCKSIZE]; + unsigned long tag_len; + SV *output; + + if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len); + if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len); + if (SvPOK(ciphertext)) ct = (unsigned char *) SvPVbyte(ciphertext, ct_len); + if (SvPOK(tagsv)) t = (unsigned char *) SvPVbyte(tagsv, t_len); + if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len); + + output = NEWSV(0, ct_len > 0 ? ct_len : 1); /* avoid zero! */ + SvPOK_only(output); + SvCUR_set(output, ct_len); + tag_len = (unsigned long)t_len; + Copy(t, tag, t_len, unsigned char); + + rv = chacha20poly1305_memory(k, (unsigned long)k_len, n, (unsigned long)n_len, h, (unsigned long)h_len, + ct, (unsigned long)ct_len, (unsigned char *)SvPVX(output), tag, &tag_len, + CHACHA20POLY1305_DECRYPT); + + if (rv != CRYPT_OK) { + SvREFCNT_dec(output); + XPUSHs(sv_2mortal(newSVpvn(NULL,0))); /* undef */ + } + else { + XPUSHs(sv_2mortal(output)); + } + } diff --git a/inc/CryptX_AuthEnc_EAX.xs.inc b/inc/CryptX_AuthEnc_EAX.xs.inc index dc2d619c..54762e2d 100644 --- a/inc/CryptX_AuthEnc_EAX.xs.inc +++ b/inc/CryptX_AuthEnc_EAX.xs.inc @@ -1,7 +1,9 @@ MODULE = CryptX PACKAGE = Crypt::AuthEnc::EAX +PROTOTYPES: DISABLE + Crypt::AuthEnc::EAX -_new(char * cipher_name, SV * key, SV * nonce, SV * adata=&PL_sv_undef) +new(Class, char * cipher_name, SV * key, SV * nonce, SV * adata=&PL_sv_undef) CODE: { STRLEN k_len=0; @@ -21,13 +23,13 @@ _new(char * cipher_name, SV * key, SV * nonce, SV * adata=&PL_sv_undef) h = (unsigned char *) SvPVbyte(adata, h_len); } - id = find_cipher(cipher_name); + id = _find_cipher(cipher_name); if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); - Newz(0, RETVAL, 1, struct eax_struct); + Newz(0, RETVAL, 1, eax_state); if (!RETVAL) croak("FATAL: Newz failed"); - rv = eax_init(&RETVAL->state, id, k, (unsigned long)k_len, n, (unsigned long)n_len, h, (unsigned long)h_len); + rv = eax_init(RETVAL, id, k, (unsigned long)k_len, n, (unsigned long)n_len, h, (unsigned long)h_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: eax setup failed: %s", error_to_string(rv)); @@ -44,9 +46,9 @@ DESTROY(Crypt::AuthEnc::EAX self) Crypt::AuthEnc::EAX clone(Crypt::AuthEnc::EAX self) CODE: - Newz(0, RETVAL, 1, struct eax_struct); + Newz(0, RETVAL, 1, eax_state); if (!RETVAL) croak("FATAL: Newz failed"); - Copy(&self->state, &RETVAL->state, 1, struct eax_struct); + Copy(self, RETVAL, 1, eax_state); OUTPUT: RETVAL @@ -63,11 +65,11 @@ encrypt_add(Crypt::AuthEnc::EAX self, SV * data) RETVAL = newSVpvn("", 0); } else { - RETVAL = NEWSV(0, in_data_len); + RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, in_data_len); out_data = (unsigned char *)SvPVX(RETVAL); - rv = eax_encrypt(&self->state, in_data, out_data, (unsigned long)in_data_len); + rv = eax_encrypt(self, in_data, out_data, (unsigned long)in_data_len); if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); croak("FATAL: eax_encrypt failed: %s", error_to_string(rv)); @@ -90,11 +92,11 @@ decrypt_add(Crypt::AuthEnc::EAX self, SV * data) RETVAL = newSVpvn("", 0); } else { - RETVAL = NEWSV(0, in_data_len); + RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, in_data_len); out_data = (unsigned char *)SvPVX(RETVAL); - rv = eax_decrypt(&self->state, in_data, out_data, (unsigned long)in_data_len); + rv = eax_decrypt(self, in_data, out_data, (unsigned long)in_data_len); if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); croak("FATAL: eax_decrypt failed: %s", error_to_string(rv)); @@ -112,7 +114,7 @@ encrypt_done(Crypt::AuthEnc::EAX self) unsigned char tag[MAXBLOCKSIZE]; unsigned long tag_len = sizeof(tag); - rv = eax_done(&self->state, tag, &tag_len); + rv = eax_done(self, tag, &tag_len); if (rv != CRYPT_OK) croak("FATAL: eax_done failed: %s", error_to_string(rv)); XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); } @@ -127,7 +129,7 @@ decrypt_done(Crypt::AuthEnc::EAX self, ...) STRLEN expected_tag_len; unsigned char *expected_tag; - rv = eax_done(&self->state, tag, &tag_len); + rv = eax_done(self, tag, &tag_len); if (rv != CRYPT_OK) croak("FATAL: eax_done failed: %s", error_to_string(rv)); if (items == 1) { XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); @@ -155,7 +157,78 @@ adata_add(Crypt::AuthEnc::EAX self, SV * adata) int rv; unsigned char *h; h = (unsigned char *)SvPVbyte(adata, h_len); - rv = eax_addheader(&self->state, h, (unsigned long)h_len); + rv = eax_addheader(self, h, (unsigned long)h_len); if (rv != CRYPT_OK) croak("FATAL: eax_addheader failed: %s", error_to_string(rv)); XPUSHs(ST(0)); /* return self */ } + +void +eax_encrypt_authenticate(char *cipher_name, SV *key, SV *nonce, SV *header, SV *plaintext) + PPCODE: + { + STRLEN k_len = 0, n_len = 0, h_len = 0, pt_len = 0; + unsigned char *k = NULL, *n = NULL, *h = NULL, *pt = NULL; + int rv, id; + unsigned char tag[MAXBLOCKSIZE]; + unsigned long tag_len = sizeof(tag); + SV *output; + + if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len); + if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len); + if (SvPOK(plaintext)) pt = (unsigned char *) SvPVbyte(plaintext, pt_len); + if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len); + + id = _find_cipher(cipher_name); + if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + output = NEWSV(0, pt_len > 0 ? pt_len : 1); /* avoid zero! */ + SvPOK_only(output); + SvCUR_set(output, pt_len); + + rv = eax_encrypt_authenticate_memory(id, k, (unsigned long)k_len, n, (unsigned long)n_len, + h, (unsigned long)h_len, pt, (unsigned long)pt_len, + (unsigned char *)SvPVX(output), tag, &tag_len); + + if (rv != CRYPT_OK) { + SvREFCNT_dec(output); + croak("FATAL: ccm_memory failed: %s", error_to_string(rv)); + } + XPUSHs(sv_2mortal(output)); + XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); + } + +void +eax_decrypt_verify(char *cipher_name, SV *key, SV *nonce, SV *header, SV *ciphertext, SV *tagsv) + PPCODE: + { + STRLEN k_len = 0, n_len = 0, h_len = 0, ct_len = 0, t_len = 0; + unsigned char *k = NULL, *n = NULL, *h = NULL, *ct = NULL, *t = NULL; + int rv, id, stat = 0; + unsigned char tag[MAXBLOCKSIZE]; + unsigned long tag_len; + SV *output; + + if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len); + if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len); + if (SvPOK(ciphertext)) ct = (unsigned char *) SvPVbyte(ciphertext, ct_len); + if (SvPOK(tagsv)) t = (unsigned char *) SvPVbyte(tagsv, t_len); + if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len); + + id = _find_cipher(cipher_name); + if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + output = NEWSV(0, ct_len > 0 ? ct_len : 1); /* avoid zero! */ + SvPOK_only(output); + SvCUR_set(output, ct_len); + tag_len = (unsigned long)t_len; + Copy(t, tag, t_len, unsigned char); + + rv = eax_decrypt_verify_memory(id, k, (unsigned long)k_len, n, (unsigned long)n_len, h, (unsigned long)h_len, + ct, (unsigned long)ct_len, (unsigned char *)SvPVX(output), tag, tag_len, &stat); + + if (rv != CRYPT_OK || stat != 1) { + SvREFCNT_dec(output); + XPUSHs(sv_2mortal(newSVpvn(NULL,0))); /* undef */ + } + else { + XPUSHs(sv_2mortal(output)); + } + } diff --git a/inc/CryptX_AuthEnc_GCM.xs.inc b/inc/CryptX_AuthEnc_GCM.xs.inc index 5ea007b8..0618a2c9 100644 --- a/inc/CryptX_AuthEnc_GCM.xs.inc +++ b/inc/CryptX_AuthEnc_GCM.xs.inc @@ -1,7 +1,9 @@ MODULE = CryptX PACKAGE = Crypt::AuthEnc::GCM +PROTOTYPES: DISABLE + Crypt::AuthEnc::GCM -_new(char * cipher_name, SV * key, SV * nonce = NULL) +new(Class, char * cipher_name, SV * key, SV * nonce = NULL) CODE: { STRLEN k_len = 0, iv_len = 0; @@ -15,20 +17,20 @@ _new(char * cipher_name, SV * key, SV * nonce = NULL) iv = (unsigned char *)SvPVbyte(nonce, iv_len); } - id = find_cipher(cipher_name); + id = _find_cipher(cipher_name); if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); - Newz(0, RETVAL, 1, struct gcm_struct); + Newz(0, RETVAL, 1, gcm_state); if (!RETVAL) croak("FATAL: Newz failed"); - rv = gcm_init(&RETVAL->state, id, k, (unsigned long)k_len); + rv = gcm_init(RETVAL, id, k, (unsigned long)k_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: gcm_init failed: %s", error_to_string(rv)); } if (iv && iv_len > 0) { - rv = gcm_add_iv(&RETVAL->state, iv, (unsigned long)iv_len); + rv = gcm_add_iv(RETVAL, iv, (unsigned long)iv_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: gcm_add_iv failed: %s", error_to_string(rv)); @@ -46,9 +48,9 @@ DESTROY(Crypt::AuthEnc::GCM self) Crypt::AuthEnc::GCM clone(Crypt::AuthEnc::GCM self) CODE: - Newz(0, RETVAL, 1, struct gcm_struct); + Newz(0, RETVAL, 1, gcm_state); if (!RETVAL) croak("FATAL: Newz failed"); - Copy(&self->state, &RETVAL->state, 1, struct gcm_struct); + Copy(self, RETVAL, 1, gcm_state); OUTPUT: RETVAL @@ -57,7 +59,7 @@ reset(Crypt::AuthEnc::GCM self) PPCODE: { int rv; - rv = gcm_reset(&self->state); + rv = gcm_reset(self); if (rv != CRYPT_OK) croak("FATAL: gcm_reset failed: %s", error_to_string(rv)); XPUSHs(ST(0)); /* return self */ } @@ -76,11 +78,11 @@ encrypt_add(Crypt::AuthEnc::GCM self, SV * data) } else { - RETVAL = NEWSV(0, in_data_len); + RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, in_data_len); out_data = (unsigned char *)SvPVX(RETVAL); - rv = gcm_process(&self->state, in_data, (unsigned long)in_data_len, out_data, GCM_ENCRYPT); + rv = gcm_process(self, in_data, (unsigned long)in_data_len, out_data, GCM_ENCRYPT); if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); croak("FATAL: encrypt_add/gcm_process failed: %s", error_to_string(rv)); @@ -99,7 +101,7 @@ iv_add(Crypt::AuthEnc::GCM self, SV * data) unsigned char *in_data; in_data = (unsigned char *)SvPVbyte(data, in_data_len); - rv = gcm_add_iv(&self->state, in_data, (unsigned long)in_data_len); + rv = gcm_add_iv(self, in_data, (unsigned long)in_data_len); if (rv != CRYPT_OK) croak("FATAL: gcm_add_iv failed: %s", error_to_string(rv)); XPUSHs(ST(0)); /* return self */ } @@ -113,7 +115,7 @@ adata_add(Crypt::AuthEnc::GCM self, SV * data) unsigned char *in_data; in_data = (unsigned char *)SvPVbyte(data, in_data_len); - rv = gcm_add_aad(&self->state, in_data, (unsigned long)in_data_len); + rv = gcm_add_aad(self, in_data, (unsigned long)in_data_len); if (rv != CRYPT_OK) croak("FATAL: gcm_add_aad failed: %s", error_to_string(rv)); XPUSHs(ST(0)); /* return self */ } @@ -131,11 +133,11 @@ decrypt_add(Crypt::AuthEnc::GCM self, SV * data) RETVAL = newSVpvn("", 0); } else { - RETVAL = NEWSV(0, in_data_len); + RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, in_data_len); out_data = (unsigned char *)SvPVX(RETVAL); - rv = gcm_process(&self->state, out_data, (unsigned long)in_data_len, in_data, GCM_DECRYPT); + rv = gcm_process(self, out_data, (unsigned long)in_data_len, in_data, GCM_DECRYPT); if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); croak("FATAL: encrypt_add/gcm_process failed: %s", error_to_string(rv)); @@ -154,7 +156,7 @@ encrypt_done(Crypt::AuthEnc::GCM self) unsigned char tag[MAXBLOCKSIZE]; unsigned long tag_len = sizeof(tag); - rv = gcm_done(&self->state, tag, &tag_len); + rv = gcm_done(self, tag, &tag_len); if (rv != CRYPT_OK) croak("FATAL: gcm_done failed: %s", error_to_string(rv)); XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); } @@ -169,7 +171,7 @@ decrypt_done(Crypt::AuthEnc::GCM self, ...) STRLEN expected_tag_len; unsigned char *expected_tag; - rv = gcm_done(&self->state, tag, &tag_len); + rv = gcm_done(self, tag, &tag_len); if (rv != CRYPT_OK) croak("FATAL: gcm_done failed: %s", error_to_string(rv)); if (items == 1) { XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); @@ -188,3 +190,73 @@ decrypt_done(Crypt::AuthEnc::GCM self, ...) } } } + +void +gcm_encrypt_authenticate(char *cipher_name, SV *key, SV *nonce, SV *header = NULL, SV *plaintext) + PPCODE: + { + STRLEN k_len = 0, n_len = 0, h_len = 0, pt_len = 0; + unsigned char *k = NULL, *n = NULL, *h = NULL, *pt = NULL; + int rv, id; + unsigned char tag[MAXBLOCKSIZE]; + unsigned long tag_len = sizeof(tag); + SV *output; + + if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len); + if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len); + if (SvPOK(plaintext)) pt = (unsigned char *) SvPVbyte(plaintext, pt_len); + if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len); + + id = _find_cipher(cipher_name); + if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + output = NEWSV(0, pt_len > 0 ? pt_len : 1); /* avoid zero! */ + SvPOK_only(output); + SvCUR_set(output, pt_len); + + rv = gcm_memory(id, k, (unsigned long)k_len, n, (unsigned long)n_len, h, (unsigned long)h_len, + pt, (unsigned long)pt_len, (unsigned char *)SvPVX(output), tag, &tag_len, GCM_ENCRYPT); + + if (rv != CRYPT_OK) { + SvREFCNT_dec(output); + croak("FATAL: ccm_memory failed: %s", error_to_string(rv)); + } + XPUSHs(sv_2mortal(output)); + XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); + } + +void +gcm_decrypt_verify(char *cipher_name, SV *key, SV *nonce, SV *header, SV *ciphertext, SV *tagsv) + PPCODE: + { + STRLEN k_len = 0, n_len = 0, h_len = 0, ct_len = 0, t_len = 0; + unsigned char *k = NULL, *n = NULL, *h = NULL, *ct = NULL, *t = NULL; + int rv, id; + unsigned char tag[MAXBLOCKSIZE]; + unsigned long tag_len; + SV *output; + + if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len); + if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len); + if (SvPOK(ciphertext)) ct = (unsigned char *) SvPVbyte(ciphertext, ct_len); + if (SvPOK(tagsv)) t = (unsigned char *) SvPVbyte(tagsv, t_len); + if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len); + + id = _find_cipher(cipher_name); + if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + output = NEWSV(0, ct_len > 0 ? ct_len : 1); /* avoid zero! */ + SvPOK_only(output); + SvCUR_set(output, ct_len); + tag_len = (unsigned long)t_len; + Copy(t, tag, t_len, unsigned char); + + rv = gcm_memory(id, k, (unsigned long)k_len, n, (unsigned long)n_len, h, (unsigned long)h_len, + (unsigned char *)SvPVX(output), (unsigned long)ct_len, ct, tag, &tag_len, GCM_DECRYPT); + + if (rv != CRYPT_OK) { + SvREFCNT_dec(output); + XPUSHs(sv_2mortal(newSVpvn(NULL,0))); /* undef */ + } + else { + XPUSHs(sv_2mortal(output)); + } + } diff --git a/inc/CryptX_AuthEnc_OCB.xs.inc b/inc/CryptX_AuthEnc_OCB.xs.inc index e5a92cee..8d06e34c 100644 --- a/inc/CryptX_AuthEnc_OCB.xs.inc +++ b/inc/CryptX_AuthEnc_OCB.xs.inc @@ -1,7 +1,9 @@ MODULE = CryptX PACKAGE = Crypt::AuthEnc::OCB +PROTOTYPES: DISABLE + Crypt::AuthEnc::OCB -_new(char * cipher_name, SV * key, SV * nonce, unsigned long taglen) +new(Class, char * cipher_name, SV * key, SV * nonce, unsigned long taglen) CODE: { STRLEN k_len=0; @@ -15,13 +17,13 @@ _new(char * cipher_name, SV * key, SV * nonce, unsigned long taglen) if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar"); n = (unsigned char *) SvPVbyte(nonce, n_len); - id = find_cipher(cipher_name); + id = _find_cipher(cipher_name); if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); - Newz(0, RETVAL, 1, struct ocb_struct); + Newz(0, RETVAL, 1, ocb3_state); if (!RETVAL) croak("FATAL: Newz failed"); - rv = ocb3_init(&RETVAL->state, id, k, (unsigned long)k_len, n, (unsigned long)n_len, taglen); + rv = ocb3_init(RETVAL, id, k, (unsigned long)k_len, n, (unsigned long)n_len, taglen); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: ocb setup failed: %s", error_to_string(rv)); @@ -38,9 +40,9 @@ DESTROY(Crypt::AuthEnc::OCB self) Crypt::AuthEnc::OCB clone(Crypt::AuthEnc::OCB self) CODE: - Newz(0, RETVAL, 1, struct ocb_struct); + Newz(0, RETVAL, 1, ocb3_state); if (!RETVAL) croak("FATAL: Newz failed"); - Copy(&self->state, &RETVAL->state, 1, struct ocb_struct); + Copy(self, RETVAL, 1, ocb3_state); OUTPUT: RETVAL @@ -55,7 +57,7 @@ adata_add(Crypt::AuthEnc::OCB self, SV * data) in_data = (unsigned char *)SvPVbyte(data, in_data_len); if (in_data_len>0) { - rv = ocb3_add_aad(&self->state, in_data, (unsigned long)in_data_len); + rv = ocb3_add_aad(self, in_data, (unsigned long)in_data_len); if (rv != CRYPT_OK) croak("FATAL: ocb3_add_aad failed: %s", error_to_string(rv)); } XPUSHs(ST(0)); /* return self */ @@ -77,11 +79,11 @@ encrypt_add(Crypt::AuthEnc::OCB self, SV * data) if (in_data_len % 16) { croak ("FATAL: sizeof(data) should be multiple of 16"); } - RETVAL = NEWSV(0, in_data_len); + RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, in_data_len); out_data = (unsigned char *)SvPVX(RETVAL); - rv = ocb3_encrypt(&self->state, in_data, (unsigned long)in_data_len, out_data); + rv = ocb3_encrypt(self, in_data, (unsigned long)in_data_len, out_data); if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); croak("FATAL: ocb3_encrypt failed: %s", error_to_string(rv)); @@ -101,18 +103,18 @@ encrypt_last(Crypt::AuthEnc::OCB self, SV * data) in_data = (unsigned char *)SvPVbyte(data, in_data_len); if (in_data_len == 0) { - rv = ocb3_encrypt_last(&self->state, in_data, 0, NULL); + rv = ocb3_encrypt_last(self, in_data, 0, NULL); if (rv != CRYPT_OK) { croak("FATAL: ocb3_encrypt_last failed: %s", error_to_string(rv)); } RETVAL = newSVpvn("", 0); } else { - RETVAL = NEWSV(0, in_data_len); + RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, in_data_len); out_data = (unsigned char *)SvPVX(RETVAL); - rv = ocb3_encrypt_last(&self->state, in_data, (unsigned long)in_data_len, out_data); + rv = ocb3_encrypt_last(self, in_data, (unsigned long)in_data_len, out_data); if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); croak("FATAL: ocb3_encrypt_last failed: %s", error_to_string(rv)); @@ -138,11 +140,11 @@ decrypt_add(Crypt::AuthEnc::OCB self, SV * data) if (in_data_len % 16) { croak ("FATAL: sizeof(data) should be multiple of 16"); } - RETVAL = NEWSV(0, in_data_len); + RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, in_data_len); out_data = (unsigned char *)SvPVX(RETVAL); - rv = ocb3_decrypt(&self->state, in_data, (unsigned long)in_data_len, out_data); + rv = ocb3_decrypt(self, in_data, (unsigned long)in_data_len, out_data); if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); croak("FATAL: ocb3_decrypt failed: %s", error_to_string(rv)); @@ -162,18 +164,18 @@ decrypt_last(Crypt::AuthEnc::OCB self, SV * data) in_data = (unsigned char *)SvPVbyte(data, in_data_len); if (in_data_len == 0) { - rv = ocb3_decrypt_last(&self->state, in_data, 0, NULL); + rv = ocb3_decrypt_last(self, in_data, 0, NULL); if (rv != CRYPT_OK) { croak("FATAL: ocb3_encrypt_last failed: %s", error_to_string(rv)); } RETVAL = newSVpvn("", 0); } else { - RETVAL = NEWSV(0, in_data_len); + RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, in_data_len); out_data = (unsigned char *)SvPVX(RETVAL); - rv = ocb3_decrypt_last(&self->state, in_data, (unsigned long)in_data_len, out_data); + rv = ocb3_decrypt_last(self, in_data, (unsigned long)in_data_len, out_data); if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); croak("FATAL: ocb3_encrypt_last failed: %s", error_to_string(rv)); @@ -191,7 +193,7 @@ encrypt_done(Crypt::AuthEnc::OCB self) unsigned char tag[MAXBLOCKSIZE]; unsigned long tag_len = sizeof(tag); - rv = ocb3_done(&self->state, tag, &tag_len); + rv = ocb3_done(self, tag, &tag_len); if (rv != CRYPT_OK) croak("FATAL: ocb3_done_encrypt failed: %s", error_to_string(rv)); XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); @@ -207,7 +209,7 @@ decrypt_done(Crypt::AuthEnc::OCB self, ...) STRLEN expected_tag_len; unsigned char *expected_tag; - rv = ocb3_done(&self->state, tag, &tag_len); + rv = ocb3_done(self, tag, &tag_len); if (rv != CRYPT_OK) croak("FATAL: ocb3_done_decrypt failed: %s", error_to_string(rv)); if (items == 1) { XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); @@ -226,3 +228,71 @@ decrypt_done(Crypt::AuthEnc::OCB self, ...) } } } + +void +ocb_encrypt_authenticate(char *cipher_name, SV *key, SV *nonce, SV *header, unsigned long tag_len, SV *plaintext) + PPCODE: + { + STRLEN k_len = 0, n_len = 0, h_len = 0, pt_len = 0; + unsigned char *k = NULL, *n = NULL, *h = NULL, *pt = NULL; + int rv, id; + unsigned char tag[MAXBLOCKSIZE]; + SV *output; + + if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len); + if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len); + if (SvPOK(plaintext)) pt = (unsigned char *) SvPVbyte(plaintext, pt_len); + if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len); + + id = _find_cipher(cipher_name); + if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + output = NEWSV(0, pt_len > 0 ? pt_len : 1); /* avoid zero! */ + SvPOK_only(output); + SvCUR_set(output, pt_len); + if(tag_len < 4 || tag_len > 16) tag_len = 16; + + rv = ocb3_encrypt_authenticate_memory(id, k, (unsigned long)k_len, n, (unsigned long)n_len, + h, (unsigned long)h_len, pt, (unsigned long)pt_len, + (unsigned char *)SvPVX(output), tag, &tag_len); + + if (rv != CRYPT_OK) { + SvREFCNT_dec(output); + croak("FATAL: ccm_memory failed: %s", error_to_string(rv)); + } + XPUSHs(sv_2mortal(output)); + XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); + } + +void +ocb_decrypt_verify(char *cipher_name, SV *key, SV *nonce, SV *header, SV *ciphertext, SV *tagsv) + PPCODE: + { + STRLEN k_len = 0, n_len = 0, h_len = 0, ct_len = 0, t_len = 0; + unsigned char *k = NULL, *n = NULL, *h = NULL, *ct = NULL, *t = NULL; + int rv, id, stat = 0; + SV *output; + + if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len); + if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len); + if (SvPOK(ciphertext)) ct = (unsigned char *) SvPVbyte(ciphertext, ct_len); + if (SvPOK(tagsv)) t = (unsigned char *) SvPVbyte(tagsv, t_len); + if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len); + + id = _find_cipher(cipher_name); + if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); + output = NEWSV(0, ct_len > 0 ? ct_len : 1); /* avoid zero! */ + SvPOK_only(output); + SvCUR_set(output, ct_len); + + rv = ocb3_decrypt_verify_memory(id, k, (unsigned long)k_len, n, (unsigned long)n_len, + h, (unsigned long)h_len, ct, (unsigned long)ct_len, + (unsigned char *)SvPVX(output), t, (unsigned long)t_len, &stat); + + if (rv != CRYPT_OK || stat != 1) { + SvREFCNT_dec(output); + XPUSHs(sv_2mortal(newSVpvn(NULL,0))); /* undef */ + } + else { + XPUSHs(sv_2mortal(output)); + } + } diff --git a/inc/CryptX_BigInt_LTM.xs.inc b/inc/CryptX_BigInt_LTM.xs.inc index e321c385..db760109 100644 --- a/inc/CryptX_BigInt_LTM.xs.inc +++ b/inc/CryptX_BigInt_LTM.xs.inc @@ -1,5 +1,6 @@ MODULE = CryptX PACKAGE = Math::BigInt::LTM +PROTOTYPES: DISABLE ############################################################################## # _new() diff --git a/inc/CryptX_Checksum_Adler32.xs.inc b/inc/CryptX_Checksum_Adler32.xs.inc index f3b7692b..eb30b819 100644 --- a/inc/CryptX_Checksum_Adler32.xs.inc +++ b/inc/CryptX_Checksum_Adler32.xs.inc @@ -1,5 +1,7 @@ MODULE = CryptX PACKAGE = Crypt::Checksum::Adler32 +PROTOTYPES: DISABLE + Crypt::Checksum::Adler32 new(Class) CODE: @@ -51,27 +53,67 @@ add(Crypt::Checksum::Adler32 self, ...) SV * digest(Crypt::Checksum::Adler32 self) + ALIAS: + hexdigest = 1 + intdigest = 2 CODE: { - unsigned char hash[4]; + int rv; + unsigned char hash[4], out[8]; + unsigned long outlen = 8; + unsigned int ui32; + adler32_finish(self, hash, 4); /* returns void */ - RETVAL = newSVpvn((char *) hash, 4); + if (ix == 1) { + rv = _base16_encode(hash, 4, out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *)out, outlen); + } + else if (ix == 2) { + LOAD32H(ui32, hash); + RETVAL = newSVuv(ui32); + } + else { + RETVAL = newSVpvn((char *) hash, 4); + } } OUTPUT: RETVAL SV * -hexdigest(Crypt::Checksum::Adler32 self) +adler32_data(...) + ALIAS: + adler32_data_hex = 1 + adler32_data_int = 2 CODE: { - unsigned long i; - unsigned char hash[4]; - char hash_hex[4*2 + 1]; - adler32_finish(self, hash, 4); /* returns void */ - hash_hex[0] = '\0'; - for(i=0; i<4; i++) sprintf(&hash_hex[2*i], "%02x", hash[i]); - RETVAL = newSVpvn(hash_hex, strlen(hash_hex)); + adler32_state st; + int rv, j; + unsigned char hash[4], out[8], *in; + unsigned long outlen = 8; + unsigned int ui32; + STRLEN inlen; + + adler32_init(&st); + for(j = 0; j < items; j++) { + in = (unsigned char *)SvPVbyte(ST(j), inlen); + if (inlen > 0) { + adler32_update(&st, in, (unsigned long)inlen); /* returns void */ + } + } + adler32_finish(&st, hash, 4); /* returns void */ + if (ix == 1) { + rv = _base16_encode(hash, 4, out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *)out, outlen); + } + else if (ix == 2) { + LOAD32H(ui32, hash); + RETVAL = newSVuv(ui32); + } + else { + RETVAL = newSVpvn((char *) hash, 4); + } } OUTPUT: RETVAL - diff --git a/inc/CryptX_Checksum_CRC32.xs.inc b/inc/CryptX_Checksum_CRC32.xs.inc index b4d591a7..3c86e7ca 100644 --- a/inc/CryptX_Checksum_CRC32.xs.inc +++ b/inc/CryptX_Checksum_CRC32.xs.inc @@ -1,5 +1,7 @@ MODULE = CryptX PACKAGE = Crypt::Checksum::CRC32 +PROTOTYPES: DISABLE + Crypt::Checksum::CRC32 new(Class) CODE: @@ -51,27 +53,67 @@ add(Crypt::Checksum::CRC32 self, ...) SV * digest(Crypt::Checksum::CRC32 self) + ALIAS: + hexdigest = 1 + intdigest = 2 CODE: { - unsigned char hash[4]; + int rv; + unsigned char hash[4], out[8]; + unsigned long outlen = 8; + unsigned int ui32; + crc32_finish(self, hash, 4); /* returns void */ - RETVAL = newSVpvn((char *) hash, 4); + if (ix == 1) { + rv = _base16_encode(hash, 4, out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *)out, outlen); + } + else if (ix == 2) { + LOAD32H(ui32, hash); + RETVAL = newSVuv(ui32); + } + else { + RETVAL = newSVpvn((char *) hash, 4); + } } OUTPUT: RETVAL SV * -hexdigest(Crypt::Checksum::CRC32 self) +crc32_data(...) + ALIAS: + crc32_data_hex = 1 + crc32_data_int = 2 CODE: { - unsigned long i; - unsigned char hash[4]; - char hash_hex[4*2 + 1]; - crc32_finish(self, hash, 4); /* returns void */ - hash_hex[0] = '\0'; - for(i=0; i<4; i++) sprintf(&hash_hex[2*i], "%02x", hash[i]); - RETVAL = newSVpvn(hash_hex, strlen(hash_hex)); + crc32_state st; + int rv, j; + unsigned char hash[4], out[8], *in; + unsigned long outlen = 8; + unsigned int ui32; + STRLEN inlen; + + crc32_init(&st); + for(j = 0; j < items; j++) { + in = (unsigned char *)SvPVbyte(ST(j), inlen); + if (inlen > 0) { + crc32_update(&st, in, (unsigned long)inlen); /* returns void */ + } + } + crc32_finish(&st, hash, 4); /* returns void */ + if (ix == 1) { + rv = _base16_encode(hash, 4, out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *)out, outlen); + } + else if (ix == 2) { + LOAD32H(ui32, hash); + RETVAL = newSVuv(ui32); + } + else { + RETVAL = newSVpvn((char *) hash, 4); + } } OUTPUT: RETVAL - diff --git a/inc/CryptX_Cipher.xs.inc b/inc/CryptX_Cipher.xs.inc index b45c40a9..70d30d43 100644 --- a/inc/CryptX_Cipher.xs.inc +++ b/inc/CryptX_Cipher.xs.inc @@ -1,27 +1,36 @@ MODULE = CryptX PACKAGE = Crypt::Cipher +PROTOTYPES: DISABLE + Crypt::Cipher -_new(cipher_name, key, rounds=0) - char * cipher_name - SV * key - int rounds +new(char * class, ...) CODE: { STRLEN key_len; - unsigned char *key_data=NULL; - int rv; - int id; + unsigned char *key_data = NULL; + SV *key; + char *cipher_name; + int rv, id, rounds = 0, idx; + + /* we need to handle: + Crypt::Cipher->new('AES'); + Crypt::Cipher::AES->new(); + */ + idx = strcmp("Crypt::Cipher", class) == 0 ? 1 : 0; + if (idx + 1 > items) croak("FATAL: missing argument"); + cipher_name = SvPVX(ST(idx)); + key = ST(idx + 1); + if (idx + 3 <= items) rounds = (int)SvIV(ST(idx + 2)); if (!SvPOK (key)) croak("FATAL: key must be string scalar"); key_data = (unsigned char *)SvPVbyte(key, key_len); - id = find_cipher(cipher_name); + id = _find_cipher(cipher_name); if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); Newz(0, RETVAL, 1, struct cipher_struct); if (!RETVAL) croak("FATAL: Newz failed"); - RETVAL->id = id; RETVAL->desc = &cipher_descriptor[id]; rv = RETVAL->desc->setup(key_data, (int)key_len, rounds, &RETVAL->skey); if (rv != CRYPT_OK) { @@ -33,47 +42,12 @@ _new(cipher_name, key, rounds=0) RETVAL void -DESTROY(self) - Crypt::Cipher self +DESTROY(Crypt::Cipher self) CODE: Safefree(self); -int -_max_keysize(self, ...) - Crypt::Cipher self - CODE: - RETVAL = self->desc->max_key_length; - OUTPUT: - RETVAL - -int -_min_keysize(self, ...) - Crypt::Cipher self - CODE: - RETVAL = self->desc->min_key_length; - OUTPUT: - RETVAL - -int -_blocksize(self, ...) - Crypt::Cipher self - CODE: - RETVAL = self->desc->block_length; - OUTPUT: - RETVAL - -int -_default_rounds(self, ...) - Crypt::Cipher self - CODE: - RETVAL = self->desc->default_rounds; - OUTPUT: - RETVAL - SV * -encrypt(self, data) - Crypt::Cipher self - SV * data +encrypt(Crypt::Cipher self, SV * data) CODE: { int rv; @@ -84,7 +58,7 @@ encrypt(self, data) RETVAL = newSVpvn("", 0); } else if (len == (STRLEN)self->desc->block_length) { - RETVAL = NEWSV(0, len); + RETVAL = NEWSV(0, len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, len); rv = self->desc->ecb_encrypt((unsigned char *)plaintext, (unsigned char *)SvPVX(RETVAL), &self->skey); @@ -101,9 +75,7 @@ encrypt(self, data) RETVAL SV * -decrypt(self, data) - Crypt::Cipher self - SV * data +decrypt(Crypt::Cipher self, SV * data) CODE: { int rv; @@ -114,7 +86,7 @@ decrypt(self, data) RETVAL = newSVpvn("", 0); } else if (len == (STRLEN)self->desc->block_length) { - RETVAL = NEWSV(0, len); + RETVAL = NEWSV(0, len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, len); rv = self->desc->ecb_decrypt((unsigned char *)ciphertext, (unsigned char *)SvPVX(RETVAL), &self->skey); @@ -131,69 +103,85 @@ decrypt(self, data) RETVAL int -_block_length_by_name(cipher_name) - char * cipher_name +blocksize(SV * param, char * extra = NULL) CODE: { - int rv, id; - - id = find_cipher(cipher_name); - if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); - - rv = cipher_descriptor[id].block_length; - if (!rv) XSRETURN_UNDEF; - RETVAL = rv; + if (sv_isobject(param) && sv_derived_from(param, "Crypt::Cipher")) { + IV tmp = SvIV((SV*)SvRV(param)); + Crypt__Cipher obj = INT2PTR(Crypt__Cipher, tmp); + RETVAL = obj->desc->block_length; + } + else { + char *name = SvPOK(param) && strcmp(SvPVX(param), "Crypt::Cipher") ? SvPVX(param) : extra; + int rv, id = _find_cipher(name); + if (id == -1) croak("FATAL: find_cipher failed for '%s'", name); + rv = cipher_descriptor[id].block_length; + if (!rv) croak("FATAL: invalid block_length for '%s'", name); + RETVAL = rv; + } } OUTPUT: RETVAL int -_min_key_length_by_name(cipher_name) - char * cipher_name +max_keysize(SV * param, char * extra = NULL) CODE: { - int rv, id; - - id = find_cipher(cipher_name); - if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); - - rv = cipher_descriptor[id].min_key_length; - if (!rv) XSRETURN_UNDEF; - RETVAL = rv; + if (sv_isobject(param) && sv_derived_from(param, "Crypt::Cipher")) { + IV tmp = SvIV((SV*)SvRV(param)); + Crypt__Cipher obj = INT2PTR(Crypt__Cipher, tmp); + RETVAL = obj->desc->max_key_length; + } + else { + char *name = SvPOK(param) && strcmp(SvPVX(param), "Crypt::Cipher") ? SvPVX(param) : extra; + int rv, id = _find_cipher(name); + if (id == -1) croak("FATAL: find_cipher failed for '%s'", name); + rv = cipher_descriptor[id].max_key_length; + if (!rv) croak("FATAL: invalid max_key_length for '%s'", name); + RETVAL = rv; + } } OUTPUT: RETVAL int -_max_key_length_by_name(cipher_name) - char * cipher_name +min_keysize(SV * param, char * extra = NULL) CODE: { - int rv, id; - - id = find_cipher(cipher_name); - if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); - - rv = cipher_descriptor[id].max_key_length; - if (!rv) XSRETURN_UNDEF; - RETVAL = rv; + if (sv_isobject(param) && sv_derived_from(param, "Crypt::Cipher")) { + IV tmp = SvIV((SV*)SvRV(param)); + Crypt__Cipher obj = INT2PTR(Crypt__Cipher, tmp); + RETVAL = obj->desc->min_key_length; + } + else { + char *name = SvPOK(param) && strcmp(SvPVX(param), "Crypt::Cipher") ? SvPVX(param) : extra; + int rv, id = _find_cipher(name); + if (id == -1) croak("FATAL: find_cipher failed for '%s'", name); + rv = cipher_descriptor[id].min_key_length; + if (!rv) croak("FATAL: invalid min_key_length for '%s'", name); + RETVAL = rv; + } } OUTPUT: RETVAL int -_default_rounds_by_name(cipher_name) - char * cipher_name +default_rounds(SV * param, char * extra = NULL) CODE: { - int rv, id; - - id = find_cipher(cipher_name); - if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); - - rv = cipher_descriptor[id].default_rounds; - if (!rv) XSRETURN_UNDEF; - RETVAL = rv; + if (sv_isobject(param) && sv_derived_from(param, "Crypt::Cipher")) { + IV tmp = SvIV((SV*)SvRV(param)); + Crypt__Cipher obj = INT2PTR(Crypt__Cipher, tmp); + RETVAL = obj->desc->default_rounds; + } + else { + char *name = SvPOK(param) && strcmp(SvPVX(param), "Crypt::Cipher") ? SvPVX(param) : extra; + int rv, id = _find_cipher(name); + if (id == -1) croak("FATAL: find_cipher failed for '%s'", name); + rv = cipher_descriptor[id].default_rounds; + if (!rv) XSRETURN_UNDEF; + RETVAL = rv; + } } OUTPUT: RETVAL diff --git a/inc/CryptX_Digest.xs.inc b/inc/CryptX_Digest.xs.inc index 0a719a8f..8a97c1a9 100644 --- a/inc/CryptX_Digest.xs.inc +++ b/inc/CryptX_Digest.xs.inc @@ -1,20 +1,21 @@ MODULE = CryptX PACKAGE = Crypt::Digest +PROTOTYPES: DISABLE + Crypt::Digest -_new(digest_name) - char * digest_name +new(char * cname, char * pname = NULL) CODE: { int rv; int id; + char *digest_name = strcmp(cname, "Crypt::Digest") == 0 ? pname : cname; - id = find_hash(digest_name); + id = _find_hash(digest_name); if (id == -1) croak("FATAL: find_hash failed for '%s'", digest_name); Newz(0, RETVAL, 1, struct digest_struct); if (!RETVAL) croak("FATAL: Newz failed"); - RETVAL->id = id; RETVAL->desc = &hash_descriptor[id]; rv = RETVAL->desc->init(&RETVAL->state); if (rv != CRYPT_OK) { @@ -26,14 +27,12 @@ _new(digest_name) RETVAL void -DESTROY(self) - Crypt::Digest self +DESTROY(Crypt::Digest self) CODE: Safefree(self); void -reset(self) - Crypt::Digest self +reset(Crypt::Digest self) PPCODE: { int rv; @@ -43,8 +42,7 @@ reset(self) } Crypt::Digest -clone(self) - Crypt::Digest self +clone(Crypt::Digest self) CODE: Newz(0, RETVAL, 1, struct digest_struct); if (!RETVAL) croak("FATAL: Newz failed"); @@ -60,9 +58,9 @@ add(Crypt::Digest self, ...) int rv, i; unsigned char *in; - for(i=1; i<items; i++) { + for(i = 1; i < items; i++) { in = (unsigned char *)SvPVbyte(ST(i), inlen); - if (inlen>0) { + if (inlen > 0) { rv = self->desc->process(&self->state, in, (unsigned long)inlen); if (rv != CRYPT_OK) croak("FATAL: digest process failed: %s", error_to_string(rv)); } @@ -71,104 +69,118 @@ add(Crypt::Digest self, ...) } SV * -digest(self) - Crypt::Digest self - CODE: - { - unsigned char hash[MAXBLOCKSIZE]; - int rv; - - rv = self->desc->done(&self->state, hash); - if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv)); - RETVAL = newSVpvn((char *) hash, self->desc->hashsize); - } - OUTPUT: - RETVAL - -SV * -hexdigest(self) - Crypt::Digest self - CODE: - { - int rv; - unsigned long i; - unsigned char hash[MAXBLOCKSIZE]; - char hash_hex[MAXBLOCKSIZE*2 + 1]; - - rv = self->desc->done(&self->state, hash); - if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv)); - - hash_hex[0] = '\0'; - for(i=0; i<self->desc->hashsize; i++) - sprintf(&hash_hex[2*i], "%02x", hash[i]); - RETVAL = newSVpvn(hash_hex, strlen(hash_hex)); - } - OUTPUT: - RETVAL - -SV * -b64digest(self) - Crypt::Digest self +digest(Crypt::Digest self) + ALIAS: + hexdigest = 1 + b64digest = 2 + b64udigest = 3 CODE: { int rv; unsigned long outlen; unsigned char hash[MAXBLOCKSIZE]; - char hash_base64[MAXBLOCKSIZE*2 + 1]; + char out[MAXBLOCKSIZE*2]; rv = self->desc->done(&self->state, hash); if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv)); - outlen = sizeof(hash_base64); - rv = base64_encode(hash, self->desc->hashsize, (unsigned char *)hash_base64, &outlen); - if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(hash_base64, outlen); + outlen = sizeof(out); + if (ix == 3) { + rv = base64url_encode(hash, self->desc->hashsize, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + else if (ix == 2) { + rv = base64_encode(hash, self->desc->hashsize, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + else if (ix == 1) { + rv = _base16_encode(hash, self->desc->hashsize, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + else { + RETVAL = newSVpvn((char *) hash, self->desc->hashsize); + } } OUTPUT: RETVAL SV * -b64udigest(self) - Crypt::Digest self +digest_data(char * digest_name, ...) + ALIAS: + digest_data_hex = 1 + digest_data_b64 = 2 + digest_data_b64u = 3 CODE: { - int rv; - unsigned long outlen; - unsigned char hash[MAXBLOCKSIZE]; - char hash_base64[MAXBLOCKSIZE*2 + 1]; + STRLEN inlen; + int rv, id, i; + unsigned char *in, hash[MAXBLOCKSIZE]; + unsigned long len = sizeof(hash), outlen; + char out[MAXBLOCKSIZE*2]; + hash_state md; - rv = self->desc->done(&self->state, hash); + id = _find_hash(digest_name); + if (id == -1) croak("FATAL: find_digest failed for '%s'", digest_name); + + /* digest_data("SHA1", $data1, $data2, $data3); */ + len = hash_descriptor[id].hashsize; + rv = hash_descriptor[id].init(&md); + if (rv != CRYPT_OK) croak("FATAL: digest init failed: %s", error_to_string(rv)); + for (i = 1; i < items; i++) { + in = (unsigned char *)SvPVbyte(ST(i), inlen); + if (inlen > 0) { + rv = hash_descriptor[id].process(&md, in, (unsigned long)inlen); + if (rv != CRYPT_OK) croak("FATAL: digest process failed: %s", error_to_string(rv)); + } + } + rv = hash_descriptor[id].done(&md, hash); if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv)); - outlen = sizeof(hash_base64); - rv = base64url_encode(hash, self->desc->hashsize, (unsigned char *)hash_base64, &outlen); - if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(hash_base64, outlen); + outlen = sizeof(out); + if (ix == 3) { + rv = base64url_encode(hash, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else if (ix == 2) { + rv = base64_encode(hash, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else if (ix == 1) { + rv = _base16_encode(hash, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else { + RETVAL = newSVpvn((char *) hash, len); + } } OUTPUT: RETVAL int -_hashsize(self) - Crypt::Digest self - CODE: - RETVAL = self->desc->hashsize; - OUTPUT: - RETVAL - -int -_hashsize_by_name(digest_name) - char * digest_name +hashsize(SV * param, char * extra = NULL) CODE: { - int rv, id; - - id = find_hash(digest_name); - if (id == -1) croak("FATAL: find_digest failed for '%s'", digest_name); - - rv = hash_descriptor[id].hashsize; - if (!rv) croak("FATAL: invalid hashsize for '%s'", digest_name);; - RETVAL = rv; + if (sv_isobject(param) && sv_derived_from(param, "Crypt::Digest")) { + IV tmp = SvIV((SV*)SvRV(param)); + Crypt__Digest obj = INT2PTR(Crypt__Digest, tmp); + RETVAL = obj->desc->hashsize; + } + else { + char *digest_name; + int rv, id; + digest_name = SvPOK(param) && strcmp(SvPVX(param), "Crypt::Digest") ? SvPVX(param) : extra; + id = _find_hash(digest_name); + if (id == -1) croak("FATAL: find_hash failed for '%s'", digest_name); + rv = hash_descriptor[id].hashsize; + if (!rv) croak("FATAL: invalid hashsize for '%s'", digest_name);; + RETVAL = rv; + } } OUTPUT: RETVAL diff --git a/inc/CryptX_Digest_SHAKE.xs.inc b/inc/CryptX_Digest_SHAKE.xs.inc index 1ab196bc..07626668 100644 --- a/inc/CryptX_Digest_SHAKE.xs.inc +++ b/inc/CryptX_Digest_SHAKE.xs.inc @@ -1,7 +1,9 @@ MODULE = CryptX PACKAGE = Crypt::Digest::SHAKE +PROTOTYPES: DISABLE + Crypt::Digest::SHAKE -_new(int num) +new(Class, int num) CODE: { int rv; @@ -68,14 +70,19 @@ done(Crypt::Digest::SHAKE self, STRLEN out_len) int rv; unsigned char *out_data; - RETVAL = NEWSV(0, out_len); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, out_len); - out_data = (unsigned char *)SvPVX(RETVAL); - rv = sha3_shake_done(&self->state, out_data, (unsigned long)out_len); - if (rv != CRYPT_OK) { - SvREFCNT_dec(RETVAL); - croak("FATAL: sha3_shake_done failed: %s", error_to_string(rv)); + if (out_len == 0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, out_len); /* avoid zero! */ + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, out_len); + out_data = (unsigned char *)SvPVX(RETVAL); + rv = sha3_shake_done(&self->state, out_data, (unsigned long)out_len); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: sha3_shake_done failed: %s", error_to_string(rv)); + } } } OUTPUT: diff --git a/inc/CryptX_KeyDerivation.xs.inc b/inc/CryptX_KeyDerivation.xs.inc index 9e88d160..9ae79206 100644 --- a/inc/CryptX_KeyDerivation.xs.inc +++ b/inc/CryptX_KeyDerivation.xs.inc @@ -1,15 +1,11 @@ MODULE = CryptX PACKAGE = Crypt::KeyDerivation +PROTOTYPES: DISABLE + SV * -_pkcs_5_alg1(SV * password, SV * salt, int iteration_count, char * hash_name, unsigned long output_len) +pbkdf1(SV * password, SV * salt, int iteration_count = 5000, const char * hash_name = "SHA256", unsigned long output_len = 32) CODE: { - /* - int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, - const unsigned char *salt, - int iteration_count, int hash_idx, - unsigned char *out, unsigned long *outlen) - */ int rv, id; unsigned char *output; unsigned char *password_ptr=NULL; @@ -17,38 +13,37 @@ _pkcs_5_alg1(SV * password, SV * salt, int iteration_count, char * hash_name, un unsigned char *salt_ptr=NULL; STRLEN salt_len=0; - id = find_hash(hash_name); - if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); - - password_ptr = (unsigned char *)SvPVbyte(password, password_len); - salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); - if (salt_len < 8) croak("FATAL: salt_len has to be 8"); - - RETVAL = NEWSV(0, output_len); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, output_len); - output = (unsigned char *)SvPVX(RETVAL); - - rv = pkcs_5_alg1(password_ptr, (unsigned long)password_len, salt_ptr, iteration_count, id, output, &output_len); - if (rv != CRYPT_OK) { - SvREFCNT_dec(RETVAL); - croak("FATAL: pkcs_5_alg1 process failed: %s", error_to_string(rv)); + if (output_len == 0) { + RETVAL = newSVpvn("", 0); + } + else { + id = _find_hash(hash_name); + if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); + + password_ptr = (unsigned char *)SvPVbyte(password, password_len); + salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); + if (salt_len < 8) croak("FATAL: salt_len has to be 8"); + + RETVAL = NEWSV(0, output_len); /* avoid zero! */ + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, output_len); + output = (unsigned char *)SvPVX(RETVAL); + + rv = pkcs_5_alg1(password_ptr, (unsigned long)password_len, salt_ptr, iteration_count, id, output, &output_len); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: pkcs_5_alg1 process failed: %s", error_to_string(rv)); + } + SvCUR_set(RETVAL, output_len); } - SvCUR_set(RETVAL, output_len); } OUTPUT: RETVAL SV * -_pkcs_5_alg2(SV * password, SV * salt, int iteration_count, char * hash_name, unsigned long output_len) +pbkdf2(SV * password, SV * salt, int iteration_count = 5000, const char * hash_name = "SHA256", unsigned long output_len = 32) CODE: { - /* - int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, - const unsigned char *salt, unsigned long salt_len, - int iteration_count, int hash_idx, - unsigned char *out, unsigned long *outlen) - */ int rv, id; unsigned char *output; unsigned char *password_ptr=NULL; @@ -56,49 +51,47 @@ _pkcs_5_alg2(SV * password, SV * salt, int iteration_count, char * hash_name, un unsigned char *salt_ptr=NULL; STRLEN salt_len=0; - id = find_hash(hash_name); - if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); - - password_ptr = (unsigned char *)SvPVbyte(password, password_len); - salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); - - RETVAL = NEWSV(0, output_len); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, output_len); - output = (unsigned char *)SvPVX(RETVAL); - - rv = pkcs_5_alg2(password_ptr, (unsigned long)password_len, salt_ptr, (unsigned long)salt_len, iteration_count, id, output, &output_len); - if (rv != CRYPT_OK) { - SvREFCNT_dec(RETVAL); - croak("FATAL: pkcs_5_alg2 process failed: %s", error_to_string(rv)); + if (output_len == 0) { + RETVAL = newSVpvn("", 0); + } + else { + id = _find_hash(hash_name); + if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); + + password_ptr = (unsigned char *)SvPVbyte(password, password_len); + salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); + + RETVAL = NEWSV(0, output_len); /* avoid zero! */ + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, output_len); + output = (unsigned char *)SvPVX(RETVAL); + + rv = pkcs_5_alg2(password_ptr, (unsigned long)password_len, salt_ptr, (unsigned long)salt_len, iteration_count, id, output, &output_len); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: pkcs_5_alg2 process failed: %s", error_to_string(rv)); + } + SvCUR_set(RETVAL, output_len); } - SvCUR_set(RETVAL, output_len); } OUTPUT: RETVAL SV * -_hkdf_extract(char * hash_name, SV * salt, SV * in) +hkdf_extract(SV * in, SV * salt = &PL_sv_undef, const char * hash_name = "SHA256") CODE: { - /* - int hkdf_extract(int hash_idx, const unsigned char *salt, unsigned long saltlen, - const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen) - */ int rv, id; unsigned char output[MAXBLOCKSIZE]; unsigned long output_len; - unsigned char *in_ptr=NULL; - STRLEN in_len=0; - unsigned char *salt_ptr=NULL; - STRLEN salt_len=0; + unsigned char *in_ptr = NULL, *salt_ptr = NULL; + STRLEN in_len = 0, salt_len = 0; - id = find_hash(hash_name); + id = _find_hash(hash_name); if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); - in_ptr = (unsigned char *)SvPVbyte(in, in_len); - salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); + if (SvPOK(in)) in_ptr = (unsigned char *)SvPVbyte(in, in_len); + if (SvPOK(salt)) salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); output_len = sizeof(output); rv = hkdf_extract(id, salt_ptr, (unsigned long)salt_len, in_ptr, (unsigned long)in_len, output, &output_len); @@ -110,79 +103,72 @@ _hkdf_extract(char * hash_name, SV * salt, SV * in) RETVAL SV * -_hkdf_expand(char * hash_name, SV * info, SV * in, unsigned long output_len) +hkdf_expand(SV * in, const char * hash_name = "SHA256", unsigned long output_len = 32, SV * info = &PL_sv_undef) CODE: { - /* - int hkdf_expand(int hash_idx, const unsigned char *info, unsigned long infolen, - const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long outlen) - */ int rv, id; unsigned char *output; - unsigned char *in_ptr=NULL; - STRLEN in_len=0; - unsigned char *info_ptr=NULL; - STRLEN info_len=0; + unsigned char *in_ptr = NULL, *info_ptr = NULL; + STRLEN in_len = 0, info_len = 0; - id = find_hash(hash_name); - if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); - - in_ptr = (unsigned char *)SvPVbyte(in, in_len); - info_ptr = (unsigned char *)SvPVbyte(info, info_len); - - RETVAL = NEWSV(0, output_len); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, output_len); - output = (unsigned char *)SvPVX(RETVAL); - - rv = hkdf_expand(id, info_ptr, (unsigned long)info_len, in_ptr, (unsigned long)in_len, output, output_len); - if (rv != CRYPT_OK) { - SvREFCNT_dec(RETVAL); - croak("FATAL: hkdf_expand process failed: %s", error_to_string(rv)); + if (output_len == 0) { + RETVAL = newSVpvn("", 0); + } + else { + id = _find_hash(hash_name); + if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); + + if (SvPOK(in)) in_ptr = (unsigned char *)SvPVbyte(in, in_len); + if (SvPOK(info)) info_ptr = (unsigned char *)SvPVbyte(info, info_len); + + RETVAL = NEWSV(0, output_len); /* avoid zero! */ + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, output_len); + output = (unsigned char *)SvPVX(RETVAL); + + rv = hkdf_expand(id, info_ptr, (unsigned long)info_len, in_ptr, (unsigned long)in_len, output, output_len); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: hkdf_expand process failed: %s", error_to_string(rv)); + } + SvCUR_set(RETVAL, output_len); } - SvCUR_set(RETVAL, output_len); } OUTPUT: RETVAL SV * -_hkdf(char * hash_name, SV * salt, SV * info, SV * in, unsigned long output_len) +hkdf(SV * in, SV * salt, const char * hash_name = "SHA256", unsigned long output_len = 32, SV * info = &PL_sv_undef) CODE: { - /* - int hkdf(int hash_idx, const unsigned char *salt, unsigned long saltlen, - const unsigned char *info, unsigned long infolen, - const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long outlen) - */ int rv, id; unsigned char *output; - unsigned char *in_ptr=NULL; - STRLEN in_len=0; - unsigned char *info_ptr=NULL; - STRLEN info_len=0; - unsigned char *salt_ptr=NULL; - STRLEN salt_len=0; - - id = find_hash(hash_name); - if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); + unsigned char *in_ptr = NULL, *info_ptr = NULL, *salt_ptr = NULL; + STRLEN in_len = 0, info_len = 0, salt_len = 0; - in_ptr = (unsigned char *)SvPVbyte(in, in_len); - info_ptr = (unsigned char *)SvPVbyte(info, info_len); - salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); - - RETVAL = NEWSV(0, output_len); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, output_len); - output = (unsigned char *)SvPVX(RETVAL); - - rv = hkdf(id, salt_ptr, (unsigned long)salt_len, info_ptr, (unsigned long)info_len, in_ptr, (unsigned long)in_len, output, output_len); - if (rv != CRYPT_OK) { - SvREFCNT_dec(RETVAL); - croak("FATAL: hkdf_expand process failed: %s", error_to_string(rv)); + if (output_len == 0) { + RETVAL = newSVpvn("", 0); + } + else { + id = _find_hash(hash_name); + if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); + + if (SvPOK(in)) in_ptr = (unsigned char *)SvPVbyte(in, in_len); + if (SvPOK(info)) info_ptr = (unsigned char *)SvPVbyte(info, info_len); + if (SvPOK(salt)) salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); + + RETVAL = NEWSV(0, output_len); /* avoid zero! */ + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, output_len); + output = (unsigned char *)SvPVX(RETVAL); + + rv = hkdf(id, salt_ptr, (unsigned long)salt_len, info_ptr, (unsigned long)info_len, in_ptr, (unsigned long)in_len, output, output_len); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: hkdf_expand process failed: %s", error_to_string(rv)); + } + SvCUR_set(RETVAL, output_len); } - SvCUR_set(RETVAL, output_len); } OUTPUT: RETVAL diff --git a/inc/CryptX_Mac_BLAKE2b.xs.inc b/inc/CryptX_Mac_BLAKE2b.xs.inc index ae73990d..6d27e3e2 100644 --- a/inc/CryptX_Mac_BLAKE2b.xs.inc +++ b/inc/CryptX_Mac_BLAKE2b.xs.inc @@ -1,9 +1,11 @@ MODULE = CryptX PACKAGE = Crypt::Mac::BLAKE2b +PROTOTYPES: DISABLE + ### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! Crypt::Mac::BLAKE2b -_new(int size, SV * key) +new(Class, unsigned long size, SV * key) CODE: { STRLEN k_len=0; @@ -13,10 +15,10 @@ _new(int size, SV * key) if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); k = (unsigned char *) SvPVbyte(key, k_len); - Newz(0, RETVAL, 1, struct blake2b_struct); + Newz(0, RETVAL, 1, blake2bmac_state); if (!RETVAL) croak("FATAL: Newz failed"); - rv = blake2bmac_init(&RETVAL->state, size, k, (unsigned long)k_len); + rv = blake2bmac_init(RETVAL, size, k, (unsigned long)k_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: blake2b_init failed: %s", error_to_string(rv)); @@ -33,101 +35,118 @@ DESTROY(Crypt::Mac::BLAKE2b self) Crypt::Mac::BLAKE2b clone(Crypt::Mac::BLAKE2b self) CODE: - Newz(0, RETVAL, 1, struct blake2b_struct); + Newz(0, RETVAL, 1, blake2bmac_state); if (!RETVAL) croak("FATAL: Newz failed"); - Copy(&self->state, &RETVAL->state, 1, struct blake2b_struct); + Copy(self, RETVAL, 1, blake2bmac_state); OUTPUT: RETVAL void -_add_single(Crypt::Mac::BLAKE2b self, SV * data) - CODE: +add(Crypt::Mac::BLAKE2b self, ...) + PPCODE: { - int rv; + int rv, i; STRLEN in_data_len; unsigned char *in_data; - in_data = (unsigned char *)SvPVbyte(data, in_data_len); - if (in_data_len>0) { - rv = blake2bmac_process(&self->state, in_data, (unsigned long)in_data_len); - if (rv != CRYPT_OK) croak("FATAL: blake2b_process failed: %s", error_to_string(rv)); + for(i = 1; i < items; i++) { + in_data = (unsigned char *)SvPVbyte(ST(i), in_data_len); + if (in_data_len > 0) { + rv = blake2bmac_process(self, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: blake2b_process failed: %s", error_to_string(rv)); + } } + XPUSHs(ST(0)); /* return self */ } SV * mac(Crypt::Mac::BLAKE2b self) - CODE: - { - char mac[MAXBLOCKSIZE]; - unsigned long mac_len; - int rv; - - mac_len = sizeof(mac); - rv = blake2bmac_done(&self->state, (unsigned char*)mac, &mac_len); - if (rv != CRYPT_OK) croak("FATAL: blake2bmac_done failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac, mac_len); - } - OUTPUT: - RETVAL - -SV * -b64mac(Crypt::Mac::BLAKE2b self) + ALIAS: + hexmac = 1 + b64mac = 2 + b64umac = 3 CODE: { unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len; + unsigned long maclen, outlen; int rv; - unsigned long outlen; - char mac_base64[MAXBLOCKSIZE*2 + 1]; + char out[MAXBLOCKSIZE*2]; - mac_len = sizeof(mac); - rv = blake2bmac_done(&self->state, mac, &mac_len); + maclen = sizeof(mac); + rv = blake2bmac_done(self, mac, &maclen); if (rv != CRYPT_OK) croak("FATAL: blake2bmac_done failed: %s", error_to_string(rv)); - outlen = sizeof(mac_base64); - rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); - if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac_base64, outlen); + outlen = sizeof(out); + if (ix == 3) { + rv = base64url_encode(mac, maclen, (unsigned char*)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + if (ix == 2) { + rv = base64_encode(mac, maclen, (unsigned char*)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + if (ix == 1) { + rv = _base16_encode(mac, maclen, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + else { + RETVAL = newSVpvn((char * )mac, maclen); + } } OUTPUT: RETVAL SV * -b64umac(Crypt::Mac::BLAKE2b self) +blake2b(unsigned long size, SV * key, ...) + ALIAS: + blake2b_hex = 1 + blake2b_b64 = 2 + blake2b_b64u = 3 CODE: { + STRLEN inlen, klen; + unsigned char *in; + unsigned char *k = (unsigned char *)SvPVbyte(key, klen); + int rv, i; unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len; - int rv; - unsigned long outlen; - char mac_base64[MAXBLOCKSIZE*2 + 1]; - - mac_len = sizeof(mac); - rv = blake2bmac_done(&self->state, mac, &mac_len); + unsigned long len = sizeof(mac), outlen; + char out[MAXBLOCKSIZE*2]; + blake2bmac_state st; + + if (size < len) len = size; + rv = blake2bmac_init(&st, len, k, (unsigned long)klen); + if (rv != CRYPT_OK) croak("FATAL: blake2bmac_init failed: %s", error_to_string(rv)); + for (i = 2; i < items; i++) { + in = (unsigned char *)SvPVbyte(ST(i), inlen); + if (inlen > 0) { + rv = blake2bmac_process(&st, in, (unsigned long)inlen); + if (rv != CRYPT_OK) croak("FATAL: blake2bmac_process failed: %s", error_to_string(rv)); + } + } + rv = blake2bmac_done(&st, mac, &len); if (rv != CRYPT_OK) croak("FATAL: blake2bmac_done failed: %s", error_to_string(rv)); - outlen = sizeof(mac_base64); - rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); - if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac_base64, outlen); - } - OUTPUT: - RETVAL -SV * -hexmac(Crypt::Mac::BLAKE2b self) - CODE: - { - unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len, i; - int rv; - char mac_hex[MAXBLOCKSIZE*2 + 1]; - - mac_len = sizeof(mac); - rv = blake2bmac_done(&self->state, mac, &mac_len); - if (rv != CRYPT_OK) croak("FATAL: blake2bmac_done failed: %s", error_to_string(rv)); - mac_hex[0] = '\0'; - for(i=0; i<mac_len; i++) - sprintf(&mac_hex[2*i], "%02x", mac[i]); - RETVAL = newSVpvn(mac_hex, strlen(mac_hex)); + outlen = sizeof(out); + if (ix == 3) { + rv = base64url_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else if (ix == 2) { + rv = base64_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else if (ix == 1) { + rv = _base16_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else { + RETVAL = newSVpvn((char *) mac, len); + } } OUTPUT: RETVAL diff --git a/inc/CryptX_Mac_BLAKE2s.xs.inc b/inc/CryptX_Mac_BLAKE2s.xs.inc index 38e43cde..3ac34672 100644 --- a/inc/CryptX_Mac_BLAKE2s.xs.inc +++ b/inc/CryptX_Mac_BLAKE2s.xs.inc @@ -1,9 +1,11 @@ MODULE = CryptX PACKAGE = Crypt::Mac::BLAKE2s +PROTOTYPES: DISABLE + ### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! Crypt::Mac::BLAKE2s -_new(int size, SV * key) +new(Class, unsigned long size, SV * key) CODE: { STRLEN k_len=0; @@ -13,10 +15,10 @@ _new(int size, SV * key) if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); k = (unsigned char *) SvPVbyte(key, k_len); - Newz(0, RETVAL, 1, struct blake2s_struct); + Newz(0, RETVAL, 1, blake2smac_state); if (!RETVAL) croak("FATAL: Newz failed"); - rv = blake2smac_init(&RETVAL->state, size, k, (unsigned long)k_len); + rv = blake2smac_init(RETVAL, size, k, (unsigned long)k_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: blake2s_init failed: %s", error_to_string(rv)); @@ -33,101 +35,118 @@ DESTROY(Crypt::Mac::BLAKE2s self) Crypt::Mac::BLAKE2s clone(Crypt::Mac::BLAKE2s self) CODE: - Newz(0, RETVAL, 1, struct blake2s_struct); + Newz(0, RETVAL, 1, blake2smac_state); if (!RETVAL) croak("FATAL: Newz failed"); - Copy(&self->state, &RETVAL->state, 1, struct blake2s_struct); + Copy(self, RETVAL, 1, blake2smac_state); OUTPUT: RETVAL void -_add_single(Crypt::Mac::BLAKE2s self, SV * data) - CODE: +add(Crypt::Mac::BLAKE2s self, ...) + PPCODE: { - int rv; + int rv, i; STRLEN in_data_len; unsigned char *in_data; - in_data = (unsigned char *)SvPVbyte(data, in_data_len); - if (in_data_len>0) { - rv = blake2smac_process(&self->state, in_data, (unsigned long)in_data_len); - if (rv != CRYPT_OK) croak("FATAL: blake2s_process failed: %s", error_to_string(rv)); + for(i = 1; i < items; i++) { + in_data = (unsigned char *)SvPVbyte(ST(i), in_data_len); + if (in_data_len > 0) { + rv = blake2smac_process(self, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: blake2s_process failed: %s", error_to_string(rv)); + } } + XPUSHs(ST(0)); /* return self */ } SV * mac(Crypt::Mac::BLAKE2s self) - CODE: - { - char mac[MAXBLOCKSIZE]; - unsigned long mac_len; - int rv; - - mac_len = sizeof(mac); - rv = blake2smac_done(&self->state, (unsigned char*)mac, &mac_len); - if (rv != CRYPT_OK) croak("FATAL: blake2smac_done failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac, mac_len); - } - OUTPUT: - RETVAL - -SV * -b64mac(Crypt::Mac::BLAKE2s self) + ALIAS: + hexmac = 1 + b64mac = 2 + b64umac = 3 CODE: { unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len; + unsigned long maclen, outlen; int rv; - unsigned long outlen; - char mac_base64[MAXBLOCKSIZE*2 + 1]; + char out[MAXBLOCKSIZE*2]; - mac_len = sizeof(mac); - rv = blake2smac_done(&self->state, mac, &mac_len); + maclen = sizeof(mac); + rv = blake2smac_done(self, mac, &maclen); if (rv != CRYPT_OK) croak("FATAL: blake2smac_done failed: %s", error_to_string(rv)); - outlen = sizeof(mac_base64); - rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); - if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac_base64, outlen); + outlen = sizeof(out); + if (ix == 3) { + rv = base64url_encode(mac, maclen, (unsigned char*)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + if (ix == 2) { + rv = base64_encode(mac, maclen, (unsigned char*)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + if (ix == 1) { + rv = _base16_encode(mac, maclen, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + else { + RETVAL = newSVpvn((char * )mac, maclen); + } } OUTPUT: RETVAL SV * -b64umac(Crypt::Mac::BLAKE2s self) +blake2s(unsigned long size, SV * key, ...) + ALIAS: + blake2s_hex = 1 + blake2s_b64 = 2 + blake2s_b64u = 3 CODE: { + STRLEN inlen, klen; + unsigned char *in; + unsigned char *k = (unsigned char *)SvPVbyte(key, klen); + int rv, i; unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len; - int rv; - unsigned long outlen; - char mac_base64[MAXBLOCKSIZE*2 + 1]; - - mac_len = sizeof(mac); - rv = blake2smac_done(&self->state, mac, &mac_len); + unsigned long len = sizeof(mac), outlen; + char out[MAXBLOCKSIZE*2]; + blake2smac_state st; + + if (size < len) len = size; + rv = blake2smac_init(&st, len, k, (unsigned long)klen); + if (rv != CRYPT_OK) croak("FATAL: blake2smac_init failed: %s", error_to_string(rv)); + for (i = 2; i < items; i++) { + in = (unsigned char *)SvPVbyte(ST(i), inlen); + if (inlen > 0) { + rv = blake2smac_process(&st, in, (unsigned long)inlen); + if (rv != CRYPT_OK) croak("FATAL: blake2smac_process failed: %s", error_to_string(rv)); + } + } + rv = blake2smac_done(&st, mac, &len); if (rv != CRYPT_OK) croak("FATAL: blake2smac_done failed: %s", error_to_string(rv)); - outlen = sizeof(mac_base64); - rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); - if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac_base64, outlen); - } - OUTPUT: - RETVAL -SV * -hexmac(Crypt::Mac::BLAKE2s self) - CODE: - { - unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len, i; - int rv; - char mac_hex[MAXBLOCKSIZE*2 + 1]; - - mac_len = sizeof(mac); - rv = blake2smac_done(&self->state, mac, &mac_len); - if (rv != CRYPT_OK) croak("FATAL: blake2smac_done failed: %s", error_to_string(rv)); - mac_hex[0] = '\0'; - for(i=0; i<mac_len; i++) - sprintf(&mac_hex[2*i], "%02x", mac[i]); - RETVAL = newSVpvn(mac_hex, strlen(mac_hex)); + outlen = sizeof(out); + if (ix == 3) { + rv = base64url_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else if (ix == 2) { + rv = base64_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else if (ix == 1) { + rv = _base16_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else { + RETVAL = newSVpvn((char *) mac, len); + } } OUTPUT: RETVAL diff --git a/inc/CryptX_Mac_F9.xs.inc b/inc/CryptX_Mac_F9.xs.inc index 359cdb73..e1782c6c 100644 --- a/inc/CryptX_Mac_F9.xs.inc +++ b/inc/CryptX_Mac_F9.xs.inc @@ -1,9 +1,11 @@ MODULE = CryptX PACKAGE = Crypt::Mac::F9 +PROTOTYPES: DISABLE + ### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! Crypt::Mac::F9 -_new(char * cipher_name, SV * key) +new(Class, char * cipher_name, SV * key) CODE: { STRLEN k_len=0; @@ -11,16 +13,16 @@ _new(char * cipher_name, SV * key) int rv; int id; - id = find_cipher(cipher_name); + id = _find_cipher(cipher_name); if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); k = (unsigned char *) SvPVbyte(key, k_len); - Newz(0, RETVAL, 1, struct f9_struct); + Newz(0, RETVAL, 1, f9_state); if (!RETVAL) croak("FATAL: Newz failed"); - rv = f9_init(&RETVAL->state, id, k, (unsigned long)k_len); + rv = f9_init(RETVAL, id, k, (unsigned long)k_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: f9_init failed: %s", error_to_string(rv)); @@ -37,101 +39,119 @@ DESTROY(Crypt::Mac::F9 self) Crypt::Mac::F9 clone(Crypt::Mac::F9 self) CODE: - Newz(0, RETVAL, 1, struct f9_struct); + Newz(0, RETVAL, 1, f9_state); if (!RETVAL) croak("FATAL: Newz failed"); - Copy(&self->state, &RETVAL->state, 1, struct f9_struct); + Copy(self, RETVAL, 1, f9_state); OUTPUT: RETVAL void -_add_single(Crypt::Mac::F9 self, SV * data) - CODE: +add(Crypt::Mac::F9 self, ...) + PPCODE: { - int rv; + int rv, i; STRLEN in_data_len; unsigned char *in_data; - in_data = (unsigned char *)SvPVbyte(data, in_data_len); - if (in_data_len>0) { - rv = f9_process(&self->state, in_data, (unsigned long)in_data_len); - if (rv != CRYPT_OK) croak("FATAL: f9_process failed: %s", error_to_string(rv)); + for(i = 1; i < items; i++) { + in_data = (unsigned char *)SvPVbyte(ST(i), in_data_len); + if (in_data_len > 0) { + rv = f9_process(self, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: f9_process failed: %s", error_to_string(rv)); + } } + XPUSHs(ST(0)); /* return self */ } SV * mac(Crypt::Mac::F9 self) - CODE: - { - char mac[MAXBLOCKSIZE]; - unsigned long mac_len; - int rv; - - mac_len = sizeof(mac); - rv = f9_done(&self->state, (unsigned char*)mac, &mac_len); - if (rv != CRYPT_OK) croak("FATAL: f9_done failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac, mac_len); - } - OUTPUT: - RETVAL - -SV * -b64mac(Crypt::Mac::F9 self) + ALIAS: + hexmac = 1 + b64mac = 2 + b64umac = 3 CODE: { unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len; + unsigned long maclen, outlen; int rv; - unsigned long outlen; - char mac_base64[MAXBLOCKSIZE*2 + 1]; + char out[MAXBLOCKSIZE*2]; - mac_len = sizeof(mac); - rv = f9_done(&self->state, mac, &mac_len); + maclen = sizeof(mac); + rv = f9_done(self, mac, &maclen); if (rv != CRYPT_OK) croak("FATAL: f9_done failed: %s", error_to_string(rv)); - outlen = sizeof(mac_base64); - rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); - if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac_base64, outlen); + outlen = sizeof(out); + if (ix == 3) { + rv = base64url_encode(mac, maclen, (unsigned char*)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + if (ix == 2) { + rv = base64_encode(mac, maclen, (unsigned char*)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + if (ix == 1) { + rv = _base16_encode(mac, maclen, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + else { + RETVAL = newSVpvn((char * )mac, maclen); + } } OUTPUT: RETVAL SV * -b64umac(Crypt::Mac::F9 self) +f9(char * cipher_name, SV * key, ...) + ALIAS: + f9_hex = 1 + f9_b64 = 2 + f9_b64u = 3 CODE: { + STRLEN inlen, klen; + unsigned char *in; + unsigned char *k = (unsigned char *)SvPVbyte(key, klen); + int rv, i; unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len; - int rv; - unsigned long outlen; - char mac_base64[MAXBLOCKSIZE*2 + 1]; - - mac_len = sizeof(mac); - rv = f9_done(&self->state, mac, &mac_len); + unsigned long len = sizeof(mac), outlen; + char out[MAXBLOCKSIZE*2]; + f9_state st; + + int id = _find_cipher(cipher_name); + if (id == -1) croak("FATAL: find_cipher failed for '%s'", cipher_name); + rv = f9_init(&st, id, k, (unsigned long)klen); + if (rv != CRYPT_OK) croak("FATAL: f9_init failed: %s", error_to_string(rv)); + for (i = 2; i < items; i++) { + in = (unsigned char *)SvPVbyte(ST(i), inlen); + if (inlen > 0) { + rv = f9_process(&st, in, (unsigned long)inlen); + if (rv != CRYPT_OK) croak("FATAL: f9_process failed: %s", error_to_string(rv)); + } + } + rv = f9_done(&st, mac, &len); if (rv != CRYPT_OK) croak("FATAL: f9_done failed: %s", error_to_string(rv)); - outlen = sizeof(mac_base64); - rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); - if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac_base64, outlen); - } - OUTPUT: - RETVAL -SV * -hexmac(Crypt::Mac::F9 self) - CODE: - { - unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len, i; - int rv; - char mac_hex[MAXBLOCKSIZE*2 + 1]; - - mac_len = sizeof(mac); - rv = f9_done(&self->state, mac, &mac_len); - if (rv != CRYPT_OK) croak("FATAL: f9_done failed: %s", error_to_string(rv)); - mac_hex[0] = '\0'; - for(i=0; i<mac_len; i++) - sprintf(&mac_hex[2*i], "%02x", mac[i]); - RETVAL = newSVpvn(mac_hex, strlen(mac_hex)); + outlen = sizeof(out); + if (ix == 3) { + rv = base64url_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else if (ix == 2) { + rv = base64_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else if (ix == 1) { + rv = _base16_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else { + RETVAL = newSVpvn((char *) mac, len); + } } OUTPUT: RETVAL diff --git a/inc/CryptX_Mac_HMAC.xs.inc b/inc/CryptX_Mac_HMAC.xs.inc index 315aef41..8e4f73c9 100644 --- a/inc/CryptX_Mac_HMAC.xs.inc +++ b/inc/CryptX_Mac_HMAC.xs.inc @@ -1,9 +1,11 @@ MODULE = CryptX PACKAGE = Crypt::Mac::HMAC +PROTOTYPES: DISABLE + ### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! Crypt::Mac::HMAC -_new(char * hash_name, SV * key) +new(Class, char * hash_name, SV * key) CODE: { STRLEN k_len=0; @@ -11,16 +13,16 @@ _new(char * hash_name, SV * key) int rv; int id; - id = find_hash(hash_name); + id = _find_hash(hash_name); if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); k = (unsigned char *) SvPVbyte(key, k_len); - Newz(0, RETVAL, 1, struct hmac_struct); + Newz(0, RETVAL, 1, hmac_state); if (!RETVAL) croak("FATAL: Newz failed"); - rv = hmac_init(&RETVAL->state, id, k, (unsigned long)k_len); + rv = hmac_init(RETVAL, id, k, (unsigned long)k_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: hmac_init failed: %s", error_to_string(rv)); @@ -37,101 +39,119 @@ DESTROY(Crypt::Mac::HMAC self) Crypt::Mac::HMAC clone(Crypt::Mac::HMAC self) CODE: - Newz(0, RETVAL, 1, struct hmac_struct); + Newz(0, RETVAL, 1, hmac_state); if (!RETVAL) croak("FATAL: Newz failed"); - Copy(&self->state, &RETVAL->state, 1, struct hmac_struct); + Copy(self, RETVAL, 1, hmac_state); OUTPUT: RETVAL void -_add_single(Crypt::Mac::HMAC self, SV * data) - CODE: +add(Crypt::Mac::HMAC self, ...) + PPCODE: { - int rv; + int rv, i; STRLEN in_data_len; unsigned char *in_data; - in_data = (unsigned char *)SvPVbyte(data, in_data_len); - if (in_data_len>0) { - rv = hmac_process(&self->state, in_data, (unsigned long)in_data_len); - if (rv != CRYPT_OK) croak("FATAL: hmac_process failed: %s", error_to_string(rv)); + for(i = 1; i < items; i++) { + in_data = (unsigned char *)SvPVbyte(ST(i), in_data_len); + if (in_data_len > 0) { + rv = hmac_process(self, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: hmac_process failed: %s", error_to_string(rv)); + } } + XPUSHs(ST(0)); /* return self */ } SV * mac(Crypt::Mac::HMAC self) - CODE: - { - char mac[MAXBLOCKSIZE]; - unsigned long mac_len; - int rv; - - mac_len = sizeof(mac); - rv = hmac_done(&self->state, (unsigned char*)mac, &mac_len); - if (rv != CRYPT_OK) croak("FATAL: hmac_done failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac, mac_len); - } - OUTPUT: - RETVAL - -SV * -b64mac(Crypt::Mac::HMAC self) + ALIAS: + hexmac = 1 + b64mac = 2 + b64umac = 3 CODE: { unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len; + unsigned long maclen, outlen; int rv; - unsigned long outlen; - char mac_base64[MAXBLOCKSIZE*2 + 1]; + char out[MAXBLOCKSIZE*2]; - mac_len = sizeof(mac); - rv = hmac_done(&self->state, mac, &mac_len); + maclen = sizeof(mac); + rv = hmac_done(self, mac, &maclen); if (rv != CRYPT_OK) croak("FATAL: hmac_done failed: %s", error_to_string(rv)); - outlen = sizeof(mac_base64); - rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); - if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac_base64, outlen); + outlen = sizeof(out); + if (ix == 3) { + rv = base64url_encode(mac, maclen, (unsigned char*)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + if (ix == 2) { + rv = base64_encode(mac, maclen, (unsigned char*)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + if (ix == 1) { + rv = _base16_encode(mac, maclen, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + else { + RETVAL = newSVpvn((char * )mac, maclen); + } } OUTPUT: RETVAL SV * -b64umac(Crypt::Mac::HMAC self) +hmac(char * hash_name, SV * key, ...) + ALIAS: + hmac_hex = 1 + hmac_b64 = 2 + hmac_b64u = 3 CODE: { + STRLEN inlen, klen; + unsigned char *in; + unsigned char *k = (unsigned char *)SvPVbyte(key, klen); + int rv, i; unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len; - int rv; - unsigned long outlen; - char mac_base64[MAXBLOCKSIZE*2 + 1]; - - mac_len = sizeof(mac); - rv = hmac_done(&self->state, mac, &mac_len); + unsigned long len = sizeof(mac), outlen; + char out[MAXBLOCKSIZE*2]; + hmac_state st; + + int id = _find_hash(hash_name); + if (id == -1) croak("FATAL: find_digest failed for '%s'", hash_name); + rv = hmac_init(&st, id, k, (unsigned long)klen); + if (rv != CRYPT_OK) croak("FATAL: hmac_init failed: %s", error_to_string(rv)); + for (i = 2; i < items; i++) { + in = (unsigned char *)SvPVbyte(ST(i), inlen); + if (inlen > 0) { + rv = hmac_process(&st, in, (unsigned long)inlen); + if (rv != CRYPT_OK) croak("FATAL: hmac_process failed: %s", error_to_string(rv)); + } + } + rv = hmac_done(&st, mac, &len); if (rv != CRYPT_OK) croak("FATAL: hmac_done failed: %s", error_to_string(rv)); - outlen = sizeof(mac_base64); - rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); - if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac_base64, outlen); - } - OUTPUT: - RETVAL -SV * -hexmac(Crypt::Mac::HMAC self) - CODE: - { - unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len, i; - int rv; - char mac_hex[MAXBLOCKSIZE*2 + 1]; - - mac_len = sizeof(mac); - rv = hmac_done(&self->state, mac, &mac_len); - if (rv != CRYPT_OK) croak("FATAL: hmac_done failed: %s", error_to_string(rv)); - mac_hex[0] = '\0'; - for(i=0; i<mac_len; i++) - sprintf(&mac_hex[2*i], "%02x", mac[i]); - RETVAL = newSVpvn(mac_hex, strlen(mac_hex)); + outlen = sizeof(out); + if (ix == 3) { + rv = base64url_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else if (ix == 2) { + rv = base64_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else if (ix == 1) { + rv = _base16_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else { + RETVAL = newSVpvn((char *) mac, len); + } } OUTPUT: RETVAL diff --git a/inc/CryptX_Mac_OMAC.xs.inc b/inc/CryptX_Mac_OMAC.xs.inc index 5f4565e8..aa8699af 100644 --- a/inc/CryptX_Mac_OMAC.xs.inc +++ b/inc/CryptX_Mac_OMAC.xs.inc @@ -1,9 +1,11 @@ MODULE = CryptX PACKAGE = Crypt::Mac::OMAC +PROTOTYPES: DISABLE + ### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! Crypt::Mac::OMAC -_new(char * cipher_name, SV * key) +new(Class, char * cipher_name, SV * key) CODE: { STRLEN k_len=0; @@ -11,16 +13,16 @@ _new(char * cipher_name, SV * key) int rv; int id; - id = find_cipher(cipher_name); + id = _find_cipher(cipher_name); if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); k = (unsigned char *) SvPVbyte(key, k_len); - Newz(0, RETVAL, 1, struct omac_struct); + Newz(0, RETVAL, 1, omac_state); if (!RETVAL) croak("FATAL: Newz failed"); - rv = omac_init(&RETVAL->state, id, k, (unsigned long)k_len); + rv = omac_init(RETVAL, id, k, (unsigned long)k_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: omac_init failed: %s", error_to_string(rv)); @@ -37,101 +39,119 @@ DESTROY(Crypt::Mac::OMAC self) Crypt::Mac::OMAC clone(Crypt::Mac::OMAC self) CODE: - Newz(0, RETVAL, 1, struct omac_struct); + Newz(0, RETVAL, 1, omac_state); if (!RETVAL) croak("FATAL: Newz failed"); - Copy(&self->state, &RETVAL->state, 1, struct omac_struct); + Copy(self, RETVAL, 1, omac_state); OUTPUT: RETVAL void -_add_single(Crypt::Mac::OMAC self, SV * data) - CODE: +add(Crypt::Mac::OMAC self, ...) + PPCODE: { - int rv; + int rv, i; STRLEN in_data_len; unsigned char *in_data; - in_data = (unsigned char *)SvPVbyte(data, in_data_len); - if (in_data_len>0) { - rv = omac_process(&self->state, in_data, (unsigned long)in_data_len); - if (rv != CRYPT_OK) croak("FATAL: omac_process failed: %s", error_to_string(rv)); + for(i = 1; i < items; i++) { + in_data = (unsigned char *)SvPVbyte(ST(i), in_data_len); + if (in_data_len > 0) { + rv = omac_process(self, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: omac_process failed: %s", error_to_string(rv)); + } } + XPUSHs(ST(0)); /* return self */ } SV * mac(Crypt::Mac::OMAC self) - CODE: - { - char mac[MAXBLOCKSIZE]; - unsigned long mac_len; - int rv; - - mac_len = sizeof(mac); - rv = omac_done(&self->state, (unsigned char*)mac, &mac_len); - if (rv != CRYPT_OK) croak("FATAL: omac_done failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac, mac_len); - } - OUTPUT: - RETVAL - -SV * -b64mac(Crypt::Mac::OMAC self) + ALIAS: + hexmac = 1 + b64mac = 2 + b64umac = 3 CODE: { unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len; + unsigned long maclen, outlen; int rv; - unsigned long outlen; - char mac_base64[MAXBLOCKSIZE*2 + 1]; + char out[MAXBLOCKSIZE*2]; - mac_len = sizeof(mac); - rv = omac_done(&self->state, mac, &mac_len); + maclen = sizeof(mac); + rv = omac_done(self, mac, &maclen); if (rv != CRYPT_OK) croak("FATAL: omac_done failed: %s", error_to_string(rv)); - outlen = sizeof(mac_base64); - rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); - if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac_base64, outlen); + outlen = sizeof(out); + if (ix == 3) { + rv = base64url_encode(mac, maclen, (unsigned char*)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + if (ix == 2) { + rv = base64_encode(mac, maclen, (unsigned char*)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + if (ix == 1) { + rv = _base16_encode(mac, maclen, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + else { + RETVAL = newSVpvn((char * )mac, maclen); + } } OUTPUT: RETVAL SV * -b64umac(Crypt::Mac::OMAC self) +omac(char * cipher_name, SV * key, ...) + ALIAS: + omac_hex = 1 + omac_b64 = 2 + omac_b64u = 3 CODE: { + STRLEN inlen, klen; + unsigned char *in; + unsigned char *k = (unsigned char *)SvPVbyte(key, klen); + int rv, i; unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len; - int rv; - unsigned long outlen; - char mac_base64[MAXBLOCKSIZE*2 + 1]; - - mac_len = sizeof(mac); - rv = omac_done(&self->state, mac, &mac_len); + unsigned long len = sizeof(mac), outlen; + char out[MAXBLOCKSIZE*2]; + omac_state st; + + int id = _find_cipher(cipher_name); + if (id == -1) croak("FATAL: find_cipher failed for '%s'", cipher_name); + rv = omac_init(&st, id, k, (unsigned long)klen); + if (rv != CRYPT_OK) croak("FATAL: omac_init failed: %s", error_to_string(rv)); + for (i = 2; i < items; i++) { + in = (unsigned char *)SvPVbyte(ST(i), inlen); + if (inlen > 0) { + rv = omac_process(&st, in, (unsigned long)inlen); + if (rv != CRYPT_OK) croak("FATAL: omac_process failed: %s", error_to_string(rv)); + } + } + rv = omac_done(&st, mac, &len); if (rv != CRYPT_OK) croak("FATAL: omac_done failed: %s", error_to_string(rv)); - outlen = sizeof(mac_base64); - rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); - if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac_base64, outlen); - } - OUTPUT: - RETVAL -SV * -hexmac(Crypt::Mac::OMAC self) - CODE: - { - unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len, i; - int rv; - char mac_hex[MAXBLOCKSIZE*2 + 1]; - - mac_len = sizeof(mac); - rv = omac_done(&self->state, mac, &mac_len); - if (rv != CRYPT_OK) croak("FATAL: omac_done failed: %s", error_to_string(rv)); - mac_hex[0] = '\0'; - for(i=0; i<mac_len; i++) - sprintf(&mac_hex[2*i], "%02x", mac[i]); - RETVAL = newSVpvn(mac_hex, strlen(mac_hex)); + outlen = sizeof(out); + if (ix == 3) { + rv = base64url_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else if (ix == 2) { + rv = base64_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else if (ix == 1) { + rv = _base16_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else { + RETVAL = newSVpvn((char *) mac, len); + } } OUTPUT: RETVAL diff --git a/inc/CryptX_Mac_PMAC.xs.inc b/inc/CryptX_Mac_PMAC.xs.inc index 1308fb0d..9ee709df 100644 --- a/inc/CryptX_Mac_PMAC.xs.inc +++ b/inc/CryptX_Mac_PMAC.xs.inc @@ -1,9 +1,11 @@ MODULE = CryptX PACKAGE = Crypt::Mac::PMAC +PROTOTYPES: DISABLE + ### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! Crypt::Mac::PMAC -_new(char * cipher_name, SV * key) +new(Class, char * cipher_name, SV * key) CODE: { STRLEN k_len=0; @@ -11,16 +13,16 @@ _new(char * cipher_name, SV * key) int rv; int id; - id = find_cipher(cipher_name); + id = _find_cipher(cipher_name); if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); k = (unsigned char *) SvPVbyte(key, k_len); - Newz(0, RETVAL, 1, struct pmac_struct); + Newz(0, RETVAL, 1, pmac_state); if (!RETVAL) croak("FATAL: Newz failed"); - rv = pmac_init(&RETVAL->state, id, k, (unsigned long)k_len); + rv = pmac_init(RETVAL, id, k, (unsigned long)k_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: pmac_init failed: %s", error_to_string(rv)); @@ -37,101 +39,119 @@ DESTROY(Crypt::Mac::PMAC self) Crypt::Mac::PMAC clone(Crypt::Mac::PMAC self) CODE: - Newz(0, RETVAL, 1, struct pmac_struct); + Newz(0, RETVAL, 1, pmac_state); if (!RETVAL) croak("FATAL: Newz failed"); - Copy(&self->state, &RETVAL->state, 1, struct pmac_struct); + Copy(self, RETVAL, 1, pmac_state); OUTPUT: RETVAL void -_add_single(Crypt::Mac::PMAC self, SV * data) - CODE: +add(Crypt::Mac::PMAC self, ...) + PPCODE: { - int rv; + int rv, i; STRLEN in_data_len; unsigned char *in_data; - in_data = (unsigned char *)SvPVbyte(data, in_data_len); - if (in_data_len>0) { - rv = pmac_process(&self->state, in_data, (unsigned long)in_data_len); - if (rv != CRYPT_OK) croak("FATAL: pmac_process failed: %s", error_to_string(rv)); + for(i = 1; i < items; i++) { + in_data = (unsigned char *)SvPVbyte(ST(i), in_data_len); + if (in_data_len > 0) { + rv = pmac_process(self, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: pmac_process failed: %s", error_to_string(rv)); + } } + XPUSHs(ST(0)); /* return self */ } SV * mac(Crypt::Mac::PMAC self) - CODE: - { - char mac[MAXBLOCKSIZE]; - unsigned long mac_len; - int rv; - - mac_len = sizeof(mac); - rv = pmac_done(&self->state, (unsigned char*)mac, &mac_len); - if (rv != CRYPT_OK) croak("FATAL: pmac_done failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac, mac_len); - } - OUTPUT: - RETVAL - -SV * -b64mac(Crypt::Mac::PMAC self) + ALIAS: + hexmac = 1 + b64mac = 2 + b64umac = 3 CODE: { unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len; + unsigned long maclen, outlen; int rv; - unsigned long outlen; - char mac_base64[MAXBLOCKSIZE*2 + 1]; + char out[MAXBLOCKSIZE*2]; - mac_len = sizeof(mac); - rv = pmac_done(&self->state, mac, &mac_len); + maclen = sizeof(mac); + rv = pmac_done(self, mac, &maclen); if (rv != CRYPT_OK) croak("FATAL: pmac_done failed: %s", error_to_string(rv)); - outlen = sizeof(mac_base64); - rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); - if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac_base64, outlen); + outlen = sizeof(out); + if (ix == 3) { + rv = base64url_encode(mac, maclen, (unsigned char*)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + if (ix == 2) { + rv = base64_encode(mac, maclen, (unsigned char*)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + if (ix == 1) { + rv = _base16_encode(mac, maclen, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + else { + RETVAL = newSVpvn((char * )mac, maclen); + } } OUTPUT: RETVAL SV * -b64umac(Crypt::Mac::PMAC self) +pmac(char * cipher_name, SV * key, ...) + ALIAS: + pmac_hex = 1 + pmac_b64 = 2 + pmac_b64u = 3 CODE: { + STRLEN inlen, klen; + unsigned char *in; + unsigned char *k = (unsigned char *)SvPVbyte(key, klen); + int rv, i; unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len; - int rv; - unsigned long outlen; - char mac_base64[MAXBLOCKSIZE*2 + 1]; - - mac_len = sizeof(mac); - rv = pmac_done(&self->state, mac, &mac_len); + unsigned long len = sizeof(mac), outlen; + char out[MAXBLOCKSIZE*2]; + pmac_state st; + + int id = _find_cipher(cipher_name); + if (id == -1) croak("FATAL: find_cipher failed for '%s'", cipher_name); + rv = pmac_init(&st, id, k, (unsigned long)klen); + if (rv != CRYPT_OK) croak("FATAL: pmac_init failed: %s", error_to_string(rv)); + for (i = 2; i < items; i++) { + in = (unsigned char *)SvPVbyte(ST(i), inlen); + if (inlen > 0) { + rv = pmac_process(&st, in, (unsigned long)inlen); + if (rv != CRYPT_OK) croak("FATAL: pmac_process failed: %s", error_to_string(rv)); + } + } + rv = pmac_done(&st, mac, &len); if (rv != CRYPT_OK) croak("FATAL: pmac_done failed: %s", error_to_string(rv)); - outlen = sizeof(mac_base64); - rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); - if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac_base64, outlen); - } - OUTPUT: - RETVAL -SV * -hexmac(Crypt::Mac::PMAC self) - CODE: - { - unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len, i; - int rv; - char mac_hex[MAXBLOCKSIZE*2 + 1]; - - mac_len = sizeof(mac); - rv = pmac_done(&self->state, mac, &mac_len); - if (rv != CRYPT_OK) croak("FATAL: pmac_done failed: %s", error_to_string(rv)); - mac_hex[0] = '\0'; - for(i=0; i<mac_len; i++) - sprintf(&mac_hex[2*i], "%02x", mac[i]); - RETVAL = newSVpvn(mac_hex, strlen(mac_hex)); + outlen = sizeof(out); + if (ix == 3) { + rv = base64url_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else if (ix == 2) { + rv = base64_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else if (ix == 1) { + rv = _base16_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else { + RETVAL = newSVpvn((char *) mac, len); + } } OUTPUT: RETVAL diff --git a/inc/CryptX_Mac_Pelican.xs.inc b/inc/CryptX_Mac_Pelican.xs.inc index 6e92f867..34840192 100644 --- a/inc/CryptX_Mac_Pelican.xs.inc +++ b/inc/CryptX_Mac_Pelican.xs.inc @@ -1,9 +1,11 @@ MODULE = CryptX PACKAGE = Crypt::Mac::Pelican +PROTOTYPES: DISABLE + ### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! Crypt::Mac::Pelican -_new(SV * key) +new(Class, SV * key) CODE: { STRLEN k_len=0; @@ -13,10 +15,10 @@ _new(SV * key) if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); k = (unsigned char *) SvPVbyte(key, k_len); - Newz(0, RETVAL, 1, struct pelican_struct); + Newz(0, RETVAL, 1, pelican_state); if (!RETVAL) croak("FATAL: Newz failed"); - rv = pelican_init(&RETVAL->state, k, (unsigned long)k_len); + rv = pelican_init(RETVAL, k, (unsigned long)k_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: pelican_init failed: %s", error_to_string(rv)); @@ -33,101 +35,118 @@ DESTROY(Crypt::Mac::Pelican self) Crypt::Mac::Pelican clone(Crypt::Mac::Pelican self) CODE: - Newz(0, RETVAL, 1, struct pelican_struct); + Newz(0, RETVAL, 1, pelican_state); if (!RETVAL) croak("FATAL: Newz failed"); - Copy(&self->state, &RETVAL->state, 1, struct pelican_struct); + Copy(self, RETVAL, 1, pelican_state); OUTPUT: RETVAL void -_add_single(Crypt::Mac::Pelican self, SV * data) - CODE: +add(Crypt::Mac::Pelican self, ...) + PPCODE: { - int rv; + int rv, i; STRLEN in_data_len; unsigned char *in_data; - in_data = (unsigned char *)SvPVbyte(data, in_data_len); - if (in_data_len>0) { - rv = pelican_process(&self->state, in_data, (unsigned long)in_data_len); - if (rv != CRYPT_OK) croak("FATAL: pelican_process failed: %s", error_to_string(rv)); + for(i = 1; i < items; i++) { + in_data = (unsigned char *)SvPVbyte(ST(i), in_data_len); + if (in_data_len > 0) { + rv = pelican_process(self, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: pelican_process failed: %s", error_to_string(rv)); + } } + XPUSHs(ST(0)); /* return self */ } SV * mac(Crypt::Mac::Pelican self) - CODE: - { - char mac[MAXBLOCKSIZE]; - unsigned long mac_len; - int rv; - - mac_len = 16; - rv = pelican_done(&self->state, (unsigned char*)mac); - if (rv != CRYPT_OK) croak("FATAL: pelican_done failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac, mac_len); - } - OUTPUT: - RETVAL - -SV * -b64mac(Crypt::Mac::Pelican self) + ALIAS: + hexmac = 1 + b64mac = 2 + b64umac = 3 CODE: { unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len; + unsigned long maclen, outlen; int rv; - unsigned long outlen; - char mac_base64[MAXBLOCKSIZE*2 + 1]; + char out[MAXBLOCKSIZE*2]; - mac_len = 16; - rv = pelican_done(&self->state, mac); + maclen = 16; + rv = pelican_done(self, mac); if (rv != CRYPT_OK) croak("FATAL: pelican_done failed: %s", error_to_string(rv)); - outlen = sizeof(mac_base64); - rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); - if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac_base64, outlen); + outlen = sizeof(out); + if (ix == 3) { + rv = base64url_encode(mac, maclen, (unsigned char*)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + if (ix == 2) { + rv = base64_encode(mac, maclen, (unsigned char*)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + if (ix == 1) { + rv = _base16_encode(mac, maclen, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + else { + RETVAL = newSVpvn((char * )mac, maclen); + } } OUTPUT: RETVAL SV * -b64umac(Crypt::Mac::Pelican self) +pelican(SV * key, ...) + ALIAS: + pelican_hex = 1 + pelican_b64 = 2 + pelican_b64u = 3 CODE: { + STRLEN inlen, klen; + unsigned char *in; + unsigned char *k = (unsigned char *)SvPVbyte(key, klen); + int rv, i; unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len; - int rv; - unsigned long outlen; - char mac_base64[MAXBLOCKSIZE*2 + 1]; - - mac_len = 16; - rv = pelican_done(&self->state, mac); + unsigned long len = sizeof(mac), outlen; + char out[MAXBLOCKSIZE*2]; + pelican_state st; + + len = 16; + rv = pelican_init(&st, k, (unsigned long)klen); + if (rv != CRYPT_OK) croak("FATAL: pelican_init failed: %s", error_to_string(rv)); + for (i = 1; i < items; i++) { + in = (unsigned char *)SvPVbyte(ST(i), inlen); + if (inlen > 0) { + rv = pelican_process(&st, in, (unsigned long)inlen); + if (rv != CRYPT_OK) croak("FATAL: pelican_process failed: %s", error_to_string(rv)); + } + } + rv = pelican_done(&st, mac); if (rv != CRYPT_OK) croak("FATAL: pelican_done failed: %s", error_to_string(rv)); - outlen = sizeof(mac_base64); - rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); - if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac_base64, outlen); - } - OUTPUT: - RETVAL -SV * -hexmac(Crypt::Mac::Pelican self) - CODE: - { - unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len, i; - int rv; - char mac_hex[MAXBLOCKSIZE*2 + 1]; - - mac_len = 16; - rv = pelican_done(&self->state, mac); - if (rv != CRYPT_OK) croak("FATAL: pelican_done failed: %s", error_to_string(rv)); - mac_hex[0] = '\0'; - for(i=0; i<mac_len; i++) - sprintf(&mac_hex[2*i], "%02x", mac[i]); - RETVAL = newSVpvn(mac_hex, strlen(mac_hex)); + outlen = sizeof(out); + if (ix == 3) { + rv = base64url_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else if (ix == 2) { + rv = base64_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else if (ix == 1) { + rv = _base16_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else { + RETVAL = newSVpvn((char *) mac, len); + } } OUTPUT: RETVAL diff --git a/inc/CryptX_Mac_Poly1305.xs.inc b/inc/CryptX_Mac_Poly1305.xs.inc index a8128156..6e50821a 100644 --- a/inc/CryptX_Mac_Poly1305.xs.inc +++ b/inc/CryptX_Mac_Poly1305.xs.inc @@ -1,9 +1,11 @@ MODULE = CryptX PACKAGE = Crypt::Mac::Poly1305 +PROTOTYPES: DISABLE + ### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! Crypt::Mac::Poly1305 -_new(SV * key) +new(Class, SV * key) CODE: { STRLEN k_len=0; @@ -13,10 +15,10 @@ _new(SV * key) if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); k = (unsigned char *) SvPVbyte(key, k_len); - Newz(0, RETVAL, 1, struct poly1305_struct); + Newz(0, RETVAL, 1, poly1305_state); if (!RETVAL) croak("FATAL: Newz failed"); - rv = poly1305_init(&RETVAL->state, k, (unsigned long)k_len); + rv = poly1305_init(RETVAL, k, (unsigned long)k_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: poly1305_init failed: %s", error_to_string(rv)); @@ -33,101 +35,117 @@ DESTROY(Crypt::Mac::Poly1305 self) Crypt::Mac::Poly1305 clone(Crypt::Mac::Poly1305 self) CODE: - Newz(0, RETVAL, 1, struct poly1305_struct); + Newz(0, RETVAL, 1, poly1305_state); if (!RETVAL) croak("FATAL: Newz failed"); - Copy(&self->state, &RETVAL->state, 1, struct poly1305_struct); + Copy(self, RETVAL, 1, poly1305_state); OUTPUT: RETVAL void -_add_single(Crypt::Mac::Poly1305 self, SV * data) - CODE: +add(Crypt::Mac::Poly1305 self, ...) + PPCODE: { - int rv; + int rv, i; STRLEN in_data_len; unsigned char *in_data; - in_data = (unsigned char *)SvPVbyte(data, in_data_len); - if (in_data_len>0) { - rv = poly1305_process(&self->state, in_data, (unsigned long)in_data_len); - if (rv != CRYPT_OK) croak("FATAL: poly1305_process failed: %s", error_to_string(rv)); + for(i = 1; i < items; i++) { + in_data = (unsigned char *)SvPVbyte(ST(i), in_data_len); + if (in_data_len > 0) { + rv = poly1305_process(self, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: poly1305_process failed: %s", error_to_string(rv)); + } } + XPUSHs(ST(0)); /* return self */ } SV * mac(Crypt::Mac::Poly1305 self) - CODE: - { - char mac[MAXBLOCKSIZE]; - unsigned long mac_len; - int rv; - - mac_len = sizeof(mac); - rv = poly1305_done(&self->state, (unsigned char*)mac, &mac_len); - if (rv != CRYPT_OK) croak("FATAL: poly1305_done failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac, mac_len); - } - OUTPUT: - RETVAL - -SV * -b64mac(Crypt::Mac::Poly1305 self) + ALIAS: + hexmac = 1 + b64mac = 2 + b64umac = 3 CODE: { unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len; + unsigned long maclen, outlen; int rv; - unsigned long outlen; - char mac_base64[MAXBLOCKSIZE*2 + 1]; + char out[MAXBLOCKSIZE*2]; - mac_len = sizeof(mac); - rv = poly1305_done(&self->state, mac, &mac_len); + maclen = sizeof(mac); + rv = poly1305_done(self, mac, &maclen); if (rv != CRYPT_OK) croak("FATAL: poly1305_done failed: %s", error_to_string(rv)); - outlen = sizeof(mac_base64); - rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); - if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac_base64, outlen); + outlen = sizeof(out); + if (ix == 3) { + rv = base64url_encode(mac, maclen, (unsigned char*)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + if (ix == 2) { + rv = base64_encode(mac, maclen, (unsigned char*)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + if (ix == 1) { + rv = _base16_encode(mac, maclen, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + else { + RETVAL = newSVpvn((char * )mac, maclen); + } } OUTPUT: RETVAL SV * -b64umac(Crypt::Mac::Poly1305 self) +poly1305(SV * key, ...) + ALIAS: + poly1305_hex = 1 + poly1305_b64 = 2 + poly1305_b64u = 3 CODE: { + STRLEN inlen, klen; + unsigned char *in; + unsigned char *k = (unsigned char *)SvPVbyte(key, klen); + int rv, i; unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len; - int rv; - unsigned long outlen; - char mac_base64[MAXBLOCKSIZE*2 + 1]; - - mac_len = sizeof(mac); - rv = poly1305_done(&self->state, mac, &mac_len); + unsigned long len = sizeof(mac), outlen; + char out[MAXBLOCKSIZE*2]; + poly1305_state st; + + rv = poly1305_init(&st, k, (unsigned long)klen); + if (rv != CRYPT_OK) croak("FATAL: poly1305_init failed: %s", error_to_string(rv)); + for (i = 1; i < items; i++) { + in = (unsigned char *)SvPVbyte(ST(i), inlen); + if (inlen > 0) { + rv = poly1305_process(&st, in, (unsigned long)inlen); + if (rv != CRYPT_OK) croak("FATAL: poly1305_process failed: %s", error_to_string(rv)); + } + } + rv = poly1305_done(&st, mac, &len); if (rv != CRYPT_OK) croak("FATAL: poly1305_done failed: %s", error_to_string(rv)); - outlen = sizeof(mac_base64); - rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); - if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac_base64, outlen); - } - OUTPUT: - RETVAL -SV * -hexmac(Crypt::Mac::Poly1305 self) - CODE: - { - unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len, i; - int rv; - char mac_hex[MAXBLOCKSIZE*2 + 1]; - - mac_len = sizeof(mac); - rv = poly1305_done(&self->state, mac, &mac_len); - if (rv != CRYPT_OK) croak("FATAL: poly1305_done failed: %s", error_to_string(rv)); - mac_hex[0] = '\0'; - for(i=0; i<mac_len; i++) - sprintf(&mac_hex[2*i], "%02x", mac[i]); - RETVAL = newSVpvn(mac_hex, strlen(mac_hex)); + outlen = sizeof(out); + if (ix == 3) { + rv = base64url_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else if (ix == 2) { + rv = base64_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else if (ix == 1) { + rv = _base16_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else { + RETVAL = newSVpvn((char *) mac, len); + } } OUTPUT: RETVAL diff --git a/inc/CryptX_Mac_XCBC.xs.inc b/inc/CryptX_Mac_XCBC.xs.inc index 01f37172..6563b677 100644 --- a/inc/CryptX_Mac_XCBC.xs.inc +++ b/inc/CryptX_Mac_XCBC.xs.inc @@ -1,9 +1,11 @@ MODULE = CryptX PACKAGE = Crypt::Mac::XCBC +PROTOTYPES: DISABLE + ### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! Crypt::Mac::XCBC -_new(char * cipher_name, SV * key) +new(Class, char * cipher_name, SV * key) CODE: { STRLEN k_len=0; @@ -11,16 +13,16 @@ _new(char * cipher_name, SV * key) int rv; int id; - id = find_cipher(cipher_name); + id = _find_cipher(cipher_name); if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); k = (unsigned char *) SvPVbyte(key, k_len); - Newz(0, RETVAL, 1, struct xcbc_struct); + Newz(0, RETVAL, 1, xcbc_state); if (!RETVAL) croak("FATAL: Newz failed"); - rv = xcbc_init(&RETVAL->state, id, k, (unsigned long)k_len); + rv = xcbc_init(RETVAL, id, k, (unsigned long)k_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: xcbc_init failed: %s", error_to_string(rv)); @@ -37,101 +39,119 @@ DESTROY(Crypt::Mac::XCBC self) Crypt::Mac::XCBC clone(Crypt::Mac::XCBC self) CODE: - Newz(0, RETVAL, 1, struct xcbc_struct); + Newz(0, RETVAL, 1, xcbc_state); if (!RETVAL) croak("FATAL: Newz failed"); - Copy(&self->state, &RETVAL->state, 1, struct xcbc_struct); + Copy(self, RETVAL, 1, xcbc_state); OUTPUT: RETVAL void -_add_single(Crypt::Mac::XCBC self, SV * data) - CODE: +add(Crypt::Mac::XCBC self, ...) + PPCODE: { - int rv; + int rv, i; STRLEN in_data_len; unsigned char *in_data; - in_data = (unsigned char *)SvPVbyte(data, in_data_len); - if (in_data_len>0) { - rv = xcbc_process(&self->state, in_data, (unsigned long)in_data_len); - if (rv != CRYPT_OK) croak("FATAL: xcbc_process failed: %s", error_to_string(rv)); + for(i = 1; i < items; i++) { + in_data = (unsigned char *)SvPVbyte(ST(i), in_data_len); + if (in_data_len > 0) { + rv = xcbc_process(self, in_data, (unsigned long)in_data_len); + if (rv != CRYPT_OK) croak("FATAL: xcbc_process failed: %s", error_to_string(rv)); + } } + XPUSHs(ST(0)); /* return self */ } SV * mac(Crypt::Mac::XCBC self) - CODE: - { - char mac[MAXBLOCKSIZE]; - unsigned long mac_len; - int rv; - - mac_len = sizeof(mac); - rv = xcbc_done(&self->state, (unsigned char*)mac, &mac_len); - if (rv != CRYPT_OK) croak("FATAL: xcbc_done failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac, mac_len); - } - OUTPUT: - RETVAL - -SV * -b64mac(Crypt::Mac::XCBC self) + ALIAS: + hexmac = 1 + b64mac = 2 + b64umac = 3 CODE: { unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len; + unsigned long maclen, outlen; int rv; - unsigned long outlen; - char mac_base64[MAXBLOCKSIZE*2 + 1]; + char out[MAXBLOCKSIZE*2]; - mac_len = sizeof(mac); - rv = xcbc_done(&self->state, mac, &mac_len); + maclen = sizeof(mac); + rv = xcbc_done(self, mac, &maclen); if (rv != CRYPT_OK) croak("FATAL: xcbc_done failed: %s", error_to_string(rv)); - outlen = sizeof(mac_base64); - rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); - if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac_base64, outlen); + outlen = sizeof(out); + if (ix == 3) { + rv = base64url_encode(mac, maclen, (unsigned char*)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + if (ix == 2) { + rv = base64_encode(mac, maclen, (unsigned char*)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + if (ix == 1) { + rv = _base16_encode(mac, maclen, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn(out, outlen); + } + else { + RETVAL = newSVpvn((char * )mac, maclen); + } } OUTPUT: RETVAL SV * -b64umac(Crypt::Mac::XCBC self) +xcbc(char * cipher_name, SV * key, ...) + ALIAS: + xcbc_hex = 1 + xcbc_b64 = 2 + xcbc_b64u = 3 CODE: { + STRLEN inlen, klen; + unsigned char *in; + unsigned char *k = (unsigned char *)SvPVbyte(key, klen); + int rv, i; unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len; - int rv; - unsigned long outlen; - char mac_base64[MAXBLOCKSIZE*2 + 1]; - - mac_len = sizeof(mac); - rv = xcbc_done(&self->state, mac, &mac_len); + unsigned long len = sizeof(mac), outlen; + char out[MAXBLOCKSIZE*2]; + xcbc_state st; + + int id = _find_cipher(cipher_name); + if (id == -1) croak("FATAL: find_cipher failed for '%s'", cipher_name); + rv = xcbc_init(&st, id, k, (unsigned long)klen); + if (rv != CRYPT_OK) croak("FATAL: xcbc_init failed: %s", error_to_string(rv)); + for (i = 2; i < items; i++) { + in = (unsigned char *)SvPVbyte(ST(i), inlen); + if (inlen > 0) { + rv = xcbc_process(&st, in, (unsigned long)inlen); + if (rv != CRYPT_OK) croak("FATAL: xcbc_process failed: %s", error_to_string(rv)); + } + } + rv = xcbc_done(&st, mac, &len); if (rv != CRYPT_OK) croak("FATAL: xcbc_done failed: %s", error_to_string(rv)); - outlen = sizeof(mac_base64); - rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); - if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); - RETVAL = newSVpvn(mac_base64, outlen); - } - OUTPUT: - RETVAL -SV * -hexmac(Crypt::Mac::XCBC self) - CODE: - { - unsigned char mac[MAXBLOCKSIZE]; - unsigned long mac_len, i; - int rv; - char mac_hex[MAXBLOCKSIZE*2 + 1]; - - mac_len = sizeof(mac); - rv = xcbc_done(&self->state, mac, &mac_len); - if (rv != CRYPT_OK) croak("FATAL: xcbc_done failed: %s", error_to_string(rv)); - mac_hex[0] = '\0'; - for(i=0; i<mac_len; i++) - sprintf(&mac_hex[2*i], "%02x", mac[i]); - RETVAL = newSVpvn(mac_hex, strlen(mac_hex)); + outlen = sizeof(out); + if (ix == 3) { + rv = base64url_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else if (ix == 2) { + rv = base64_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else if (ix == 1) { + rv = _base16_encode(mac, len, (unsigned char *)out, &outlen); + if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char *) out, outlen); + } + else { + RETVAL = newSVpvn((char *) mac, len); + } } OUTPUT: RETVAL diff --git a/inc/CryptX_Mode_CBC.xs.inc b/inc/CryptX_Mode_CBC.xs.inc index 6a86b794..c7cbe0a8 100644 --- a/inc/CryptX_Mode_CBC.xs.inc +++ b/inc/CryptX_Mode_CBC.xs.inc @@ -1,9 +1,11 @@ MODULE = CryptX PACKAGE = Crypt::Mode::CBC +PROTOTYPES: DISABLE + ### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! Crypt::Mode::CBC -_new(char * cipher_name, int padding=1, int rounds=0) +new(Class, char * cipher_name, int padding=1, int rounds=0) CODE: { Newz(0, RETVAL, 1, struct cbc_struct); @@ -12,7 +14,7 @@ _new(char * cipher_name, int padding=1, int rounds=0) RETVAL->padlen = 0; RETVAL->direction = 0; RETVAL->cipher_rounds = rounds; - RETVAL->cipher_id = find_cipher(cipher_name); + RETVAL->cipher_id = _find_cipher(cipher_name); if (RETVAL->cipher_id == -1) { Safefree(RETVAL); croak("FATAL: find_cipfer failed for '%s'", cipher_name); @@ -26,16 +28,11 @@ DESTROY(Crypt::Mode::CBC self) CODE: Safefree(self); -int -_get_dir(Crypt::Mode::CBC self) - CODE: - RETVAL = self->direction; - OUTPUT: - RETVAL - void -_start(Crypt::Mode::CBC self, int dir, SV * key, SV * iv) - CODE: +start_decrypt(Crypt::Mode::CBC self, SV * key, SV * iv) + ALIAS: + start_encrypt = 1 + PPCODE: { int rv; STRLEN k_len=0; @@ -56,243 +53,215 @@ _start(Crypt::Mode::CBC self, int dir, SV * key, SV * iv) croak("FATAL: cbc_start failed: %s", error_to_string(rv)); } - self->direction = dir; + self->direction = ix == 1 ? 1 : -1; self->padlen = 0; + XPUSHs(ST(0)); /* return self */ } SV * -_encrypt(Crypt::Mode::CBC self, SV * data) +add(Crypt::Mode::CBC self, ...) CODE: { - int rv, has_tmp_block, blen; + int rv, has_tmp_block, blen, j; unsigned long i; - - STRLEN in_data_len, in_data_start; + STRLEN in_data_len, in_data_start, out_len = 0; unsigned char *in_data, *out_data, tmp_block[MAXBLOCKSIZE]; - if (self->direction != 1) croak("FATAL: encrypt error, call start_encrypt first (%d)", self->direction); + RETVAL = newSVpvn("", 0); + for (j = 1; j < items; j++) { + in_data = (unsigned char *)SvPVbyte(ST(j), in_data_len); + blen = (&self->state)->blocklen; + in_data_start = 0; + has_tmp_block = 0; + if (in_data_len > 0) { + if (self->direction == 1) { + /* handle non-empty self->pad buffer */ + if (self->padlen > 0) { + i = (blen - self->padlen); + if (in_data_len >= i) { /* enough data to fill pad */ + Copy(in_data, self->pad+self->padlen, i, unsigned char); + in_data_len -= i; + in_data_start = i; + rv = cbc_encrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: cbc_encrypt failed: %s", error_to_string(rv)); + } + self->padlen = 0; + has_tmp_block = 1; + } + else { /* not enough data to fill pad */ + Copy(in_data, self->pad+self->padlen, in_data_len, unsigned char); + self->padlen += (int)in_data_len; + in_data_len = 0; + } + } - blen = (&self->state)->blocklen; - in_data_start = 0; - has_tmp_block = 0; - in_data = (unsigned char *)SvPVbyte(data, in_data_len); - if (in_data_len == 0) { - RETVAL = newSVpvn("", 0); - } - else { - if (self->padlen > 0) { - i = (blen - self->padlen); - if (in_data_len >= i) { /* enough data to fill pad */ - Copy(in_data, self->pad+self->padlen, i, unsigned char); - in_data_len -= i; - in_data_start = i; - rv = cbc_encrypt(self->pad, tmp_block, blen, &self->state); - if (rv != CRYPT_OK) croak("FATAL: cbc_encrypt failed: %s", error_to_string(rv)); - self->padlen = 0; - has_tmp_block = 1; - } - else { /* not enough data to fill pad */ - Copy(in_data, self->pad+self->padlen, in_data_len, unsigned char); - self->padlen += (int)in_data_len; - in_data_len = 0; + i = (unsigned long)(in_data_len % blen); + if (in_data_len > 0 && i > 0) { /* save tail of data into pad */ + Copy(in_data + in_data_start + in_data_len - i, self->pad, i, unsigned char); + self->padlen = i; + in_data_len -= i; + } + + if (in_data_len > 0) { + i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); + out_data = (unsigned char*)SvGROW(RETVAL, out_len + i + 1) + out_len; + out_len += i; + if (has_tmp_block) { + Copy(tmp_block, out_data, blen, unsigned char); + out_data += blen; + } + rv = cbc_encrypt(in_data+in_data_start, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: cbc_encrypt failed: %s", error_to_string(rv)); + } + } /* in_data_len > 0 */ + else if (has_tmp_block) { + out_data = (unsigned char*)SvGROW(RETVAL, out_len + blen + 1) + out_len; + out_len += blen; + Copy(tmp_block, out_data, blen, unsigned char); + } } - } /* padlen > 0 */ + else if (self->direction == -1) { + if (self->padlen == blen) { + rv = cbc_decrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: cbc_decrypt failed: %s", error_to_string(rv)); + } + self->padlen = 0; + has_tmp_block = 1; + } /* padlen == blen */ + else if (self->padlen > 0) { + i = (blen - self->padlen); /* remaining bytes in padding buffer */ + if (in_data_len >= i) { /* enough data to fill pad */ + Copy(in_data, self->pad+self->padlen, i, unsigned char); + self->padlen += i; + in_data_len -= i; + in_data_start = i; + if (in_data_len>0 || self->padding_mode == 0) { + rv = cbc_decrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: cbc_decrypt failed: %s", error_to_string(rv)); + } + self->padlen = 0; + has_tmp_block = 1; + } + } + else { /* not enough data to fill pad */ + Copy(in_data, self->pad+self->padlen, in_data_len, unsigned char); + self->padlen += (int)in_data_len; + in_data_len = 0; + } + } /* padlen > 0 */ - i = (unsigned long)(in_data_len % blen); - if (in_data_len>0 && i>0) { /* save tail of data into pad */ - Copy(in_data+in_data_start+in_data_len-i, self->pad, i, unsigned char); - self->padlen = i; - in_data_len -= i; - } + /* here: a/ padlen == 1..16 && in_data_len == 0; b/ padlen == 0 && in_data_len > 0 */ + if (in_data_len>0) { + i = (unsigned long)(in_data_len % blen); + if (i>0) { /* save tail of data into pad */ + Copy(in_data+in_data_start+in_data_len-i, self->pad, i, unsigned char); + self->padlen = i; + in_data_len -= i; + } + } - if (in_data_len > 0) { - i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); - RETVAL = NEWSV(0, i); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, i); - out_data = (unsigned char *)SvPVX(RETVAL); - if (has_tmp_block) { - Copy(tmp_block, out_data, blen, unsigned char); - out_data += blen; + if (in_data_len>0) { + if (self->padlen == 0 && self->padding_mode !=0) { + /* in case of padding keep full pad if no more data */ + Copy(in_data+in_data_start+in_data_len-blen, self->pad, blen, unsigned char); + self->padlen = blen; + in_data_len -= blen; + } + i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); + if (i > 0) { + out_data = (unsigned char*)SvGROW(RETVAL, out_len + i + 1) + out_len; + out_len += i; + if (has_tmp_block) { + Copy(tmp_block, out_data, blen, unsigned char); + out_data += blen; + } + rv = cbc_decrypt(in_data+in_data_start, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: cbc_decrypt failed: %s", error_to_string(rv)); + } + } + } /* in_data_len>0 */ + else if (has_tmp_block) { + out_data = (unsigned char*)SvGROW(RETVAL, out_len + blen + 1) + out_len; + out_len += blen; + Copy(tmp_block, out_data, blen, unsigned char); + } } - rv = cbc_encrypt(in_data+in_data_start, out_data, (unsigned long)in_data_len, &self->state); - if (rv != CRYPT_OK) { + else { SvREFCNT_dec(RETVAL); - croak("FATAL: cbc_encrypt failed: %s", error_to_string(rv)); + croak("FATAL: call start_decryt or start_encrpyt first (%d)", self->direction); } - } /* in_data_len>0 */ - else if (has_tmp_block) { - RETVAL = newSVpvn((char*)tmp_block, blen); } - else { - RETVAL = newSVpvn("", 0); - } - } - } - OUTPUT: - RETVAL - -SV * -_finish_enc(Crypt::Mode::CBC self) - CODE: - { - unsigned char tmp_block[MAXBLOCKSIZE]; - int rv, blen, i, j; - - blen = (&self->state)->blocklen; - if (self->padlen<0 || self->padlen>=blen) croak("FATAL: invalid padlen"); - - if (self->padding_mode == 1) { /* pkcs5|7 padding */ - i = blen - self->padlen; - if (i == 0) i = blen; - for(j=self->padlen; j<blen; j++) self->pad[j] = (unsigned char)i; - rv = cbc_encrypt(self->pad, tmp_block, blen, &self->state); - if (rv != CRYPT_OK) croak("FATAL: cbc_encrypt failed: %s", error_to_string(rv)); - } - else if (self->padding_mode == 2) { /* oneandzeroes padding */ - self->pad[self->padlen] = 0x80; - for(j=self->padlen+1; j<blen; j++) self->pad[j] = 0; - rv = cbc_encrypt(self->pad, tmp_block, blen, &self->state); - if (rv != CRYPT_OK) croak("FATAL: cbc_encrypt failed: %s", error_to_string(rv)); - } - else { - if (self->padlen>0) croak("FATAL: cbc_encrypt, input data length not multiple of %d", blen); - blen = 0; } - - self->direction = 0; - RETVAL = newSVpvn((char*)tmp_block, blen); + if (out_len > 0) SvCUR_set(RETVAL, out_len); } OUTPUT: RETVAL SV * -_decrypt(Crypt::Mode::CBC self, SV * data) +finish(Crypt::Mode::CBC self) CODE: { - int rv, has_tmp_block, blen; - unsigned long i; - STRLEN in_data_len, in_data_start; - unsigned char *in_data, *out_data, tmp_block[MAXBLOCKSIZE]; - - if (self->direction != -1) croak("FATAL: decrypt error, call start_decryt first (%d)", self->direction); + unsigned char tmp_block[MAXBLOCKSIZE], ch; + int i, j, rv, blen = (&self->state)->blocklen; - blen = (&self->state)->blocklen; - in_data_start = 0; - has_tmp_block = 0; - in_data = (unsigned char *)SvPVbyte(data, in_data_len); - if (in_data_len == 0) { - RETVAL = newSVpvn("", 0); + if (self->direction == 1) { + if (self->padlen<0 || self->padlen>=blen) croak("FATAL: invalid padlen"); + if (self->padding_mode == 1) { /* pkcs5|7 padding */ + i = blen - self->padlen; + if (i == 0) i = blen; + for(j=self->padlen; j<blen; j++) self->pad[j] = (unsigned char)i; + rv = cbc_encrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) croak("FATAL: cbc_encrypt failed: %s", error_to_string(rv)); + } + else if (self->padding_mode == 2) { /* oneandzeroes padding */ + self->pad[self->padlen] = 0x80; + for(j=self->padlen+1; j<blen; j++) self->pad[j] = 0; + rv = cbc_encrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) croak("FATAL: cbc_encrypt failed: %s", error_to_string(rv)); + } + else { + if (self->padlen>0) croak("FATAL: cbc_encrypt, input data length not multiple of %d", blen); + blen = 0; + } } - else { - - if (self->padlen == blen) { + else if (self->direction == -1) { + if (self->padlen > 0) { + if (self->padlen != blen) croak("FATAL: cipher text length has to be multiple of %d (%d)", blen, self->padlen); rv = cbc_decrypt(self->pad, tmp_block, blen, &self->state); if (rv != CRYPT_OK) croak("FATAL: cbc_decrypt failed: %s", error_to_string(rv)); - self->padlen = 0; - has_tmp_block = 1; - } /* padlen == blen */ - else if (self->padlen > 0) { - i = (blen - self->padlen); /* remaining bytes in padding buffer */ - if (in_data_len >= i) { /* enough data to fill pad */ - Copy(in_data, self->pad+self->padlen, i, unsigned char); - self->padlen += i; - in_data_len -= i; - in_data_start = i; - if (in_data_len>0 || self->padding_mode == 0) { - rv = cbc_decrypt(self->pad, tmp_block, blen, &self->state); - if (rv != CRYPT_OK) croak("FATAL: cbc_decrypt failed: %s", error_to_string(rv)); - self->padlen = 0; - has_tmp_block = 1; - } - } - else { /* not enough data to fill pad */ - Copy(in_data, self->pad+self->padlen, in_data_len, unsigned char); - self->padlen += (int)in_data_len; - in_data_len = 0; - } - } /* padlen > 0 */ - - /* here: a/ padlen == 1..16 && in_data_len == 0; b/ padlen == 0 && in_data_len > 0 */ - if (in_data_len>0) { - i = (unsigned long)(in_data_len % blen); - if (i>0) { /* save tail of data into pad */ - Copy(in_data+in_data_start+in_data_len-i, self->pad, i, unsigned char); - self->padlen = i; - in_data_len -= i; - } - } - - if (in_data_len>0) { - if (self->padlen == 0 && self->padding_mode !=0) { - /* in case of padding keep full pad if no more data */ - Copy(in_data+in_data_start+in_data_len-blen, self->pad, blen, unsigned char); - self->padlen = blen; - in_data_len -= blen; + if (self->padding_mode == 0) { /* no padding */ + /* we already have blen */ } - i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); - if (i == 0) { - RETVAL = newSVpvn("", 0); + else if (self->padding_mode == 1) { /* pkcs5|7 padding */ + ch = tmp_block[blen-1]; + blen = blen - (ch > blen ? blen : ch); } - else { - RETVAL = NEWSV(0, i); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, i); - out_data = (unsigned char *)SvPVX(RETVAL); - if (has_tmp_block) { - Copy(tmp_block, out_data, blen, unsigned char); - out_data += blen; - } - rv = cbc_decrypt(in_data+in_data_start, out_data, (unsigned long)in_data_len, &self->state); - if (rv != CRYPT_OK) { - SvREFCNT_dec(RETVAL); - croak("FATAL: cbc_decrypt failed: %s", error_to_string(rv)); - } + else if (self->padding_mode == 2) { /* oneandzeroes padding */ + while ((unsigned char)tmp_block[blen - 1] == 0x00) blen--; + if ((unsigned char)tmp_block[blen - 1] == 0x80) blen--; + if (blen < 0) blen = 0; } - } /* in_data_len>0 */ - else if (has_tmp_block) { - RETVAL = newSVpvn((char*)tmp_block, blen); } else { - RETVAL = newSVpvn("", 0); + blen = 0; } } - - } - OUTPUT: - RETVAL - -SV * -_finish_dec(Crypt::Mode::CBC self) - CODE: - { - unsigned char tmp_block[MAXBLOCKSIZE]; - unsigned char i; - int rv, rv_len, blen; - - rv_len = 0; - if (self->padlen > 0) { - blen = (&self->state)->blocklen; - if (self->padlen != blen) croak("FATAL: cipher text length has to be multiple of %d (%d)", blen, self->padlen); - rv = cbc_decrypt(self->pad, tmp_block, blen, &self->state); - if (rv != CRYPT_OK) croak("FATAL: cbc_decrypt failed: %s", error_to_string(rv)); - if (self->padding_mode == 0) { /* no padding */ - rv_len = blen; - } - else if (self->padding_mode == 1) { /* pkcs5|7 padding */ - i = tmp_block[blen-1]; - rv_len = blen - (i>blen ? blen : i); - } - else if (self->padding_mode == 2) { /* oneandzeroes padding */ - rv_len = blen; - while ((unsigned char)tmp_block[rv_len-1] == 0x00) rv_len--; - if ((unsigned char)tmp_block[rv_len-1] == 0x80) rv_len--; - if (rv_len<0) rv_len = 0; - } + else { + XSRETURN_UNDEF; } self->direction = 0; - RETVAL = newSVpvn((char*)tmp_block, rv_len); + RETVAL = newSVpvn((char*)tmp_block, blen); } OUTPUT: RETVAL diff --git a/inc/CryptX_Mode_CFB.xs.inc b/inc/CryptX_Mode_CFB.xs.inc index 23f7bb72..283ebf9d 100644 --- a/inc/CryptX_Mode_CFB.xs.inc +++ b/inc/CryptX_Mode_CFB.xs.inc @@ -1,16 +1,18 @@ MODULE = CryptX PACKAGE = Crypt::Mode::CFB +PROTOTYPES: DISABLE + ### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! Crypt::Mode::CFB -_new(char * cipher_name, int rounds=0) +new(Class, char * cipher_name, int rounds=0) CODE: { Newz(0, RETVAL, 1, struct cfb_struct); if (!RETVAL) croak("FATAL: Newz failed"); RETVAL->direction = 0; RETVAL->cipher_rounds = rounds; - RETVAL->cipher_id = find_cipher(cipher_name); + RETVAL->cipher_id = _find_cipher(cipher_name); if (RETVAL->cipher_id == -1) { Safefree(RETVAL); croak("FATAL: find_cipfer failed for '%s'", cipher_name); @@ -24,16 +26,11 @@ DESTROY(Crypt::Mode::CFB self) CODE: Safefree(self); -int -_get_dir(Crypt::Mode::CFB self) - CODE: - RETVAL = self->direction; - OUTPUT: - RETVAL - void -_start(Crypt::Mode::CFB self, int dir, SV * key, SV * iv) - CODE: +start_decrypt(Crypt::Mode::CFB self, SV * key, SV * iv) + ALIAS: + start_encrypt = 1 + PPCODE: { STRLEN k_len=0; unsigned char *k=NULL; @@ -55,52 +52,51 @@ _start(Crypt::Mode::CFB self, int dir, SV * key, SV * iv) croak("FATAL: cfb_start failed: %s", error_to_string(rv)); } - self->direction = dir; + self->direction = ix == 1 ? 1 : -1; + XPUSHs(ST(0)); /* return self */ } SV * -_crypt(Crypt::Mode::CFB self, SV * data) +add(Crypt::Mode::CFB self, ...) CODE: { - int rv; - STRLEN in_data_len; + int rv, j; + STRLEN in_data_len, out_len = 0; unsigned char *in_data, *out_data; - in_data = (unsigned char *)SvPVbyte(data, in_data_len); - if (in_data_len == 0) { - RETVAL = newSVpvn("", 0); - } - else { - RETVAL = NEWSV(0, in_data_len); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, in_data_len); - out_data = (unsigned char *)SvPVX(RETVAL); - - if (self->direction == 1) { - rv = cfb_encrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); - if (rv != CRYPT_OK) { - SvREFCNT_dec(RETVAL); - croak("FATAL: cfb_encrypt failed: %s", error_to_string(rv)); + RETVAL = newSVpvn("", 0); + for (j = 1; j < items; j++) { + in_data = (unsigned char *)SvPVbyte(ST(j), in_data_len); + if (in_data_len > 0) { + out_data = (unsigned char*)SvGROW(RETVAL, out_len + in_data_len + 1) + out_len; + out_len += in_data_len; + if (self->direction == 1) { + rv = cfb_encrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: cfb_encrypt failed: %s", error_to_string(rv)); + } } - } - else if (self->direction == -1) { - rv = cfb_decrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); - if (rv != CRYPT_OK) { + else if (self->direction == -1) { + rv = cfb_decrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: cfb_decrypt failed: %s", error_to_string(rv)); + } + } + else { SvREFCNT_dec(RETVAL); - croak("FATAL: cfb_decrypt failed: %s", error_to_string(rv)); + croak("FATAL: cfb_crypt failed: call start_encrypt or start_decrypt first"); } } - else { - SvREFCNT_dec(RETVAL); - croak("FATAL: cfb_crypt failed: call start_encrypt or start_decrypt first"); - } } + if (out_len > 0) SvCUR_set(RETVAL, out_len); } OUTPUT: RETVAL SV * -_finish(Crypt::Mode::CFB self) +finish(Crypt::Mode::CFB self) CODE: self->direction = 0; RETVAL = newSVpvn("", 0); diff --git a/inc/CryptX_Mode_CTR.xs.inc b/inc/CryptX_Mode_CTR.xs.inc index 877186b2..baeb661a 100644 --- a/inc/CryptX_Mode_CTR.xs.inc +++ b/inc/CryptX_Mode_CTR.xs.inc @@ -1,16 +1,18 @@ MODULE = CryptX PACKAGE = Crypt::Mode::CTR +PROTOTYPES: DISABLE + ### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! Crypt::Mode::CTR -_new(char * cipher_name, int ctr_mode=0, int ctr_width=0, int rounds=0) +new(Class, char * cipher_name, int ctr_mode=0, int ctr_width=0, int rounds=0) CODE: { Newz(0, RETVAL, 1, struct ctr_struct); if (!RETVAL) croak("FATAL: Newz failed"); RETVAL->direction = 0; RETVAL->cipher_rounds = rounds; - RETVAL->cipher_id = find_cipher(cipher_name); + RETVAL->cipher_id = _find_cipher(cipher_name); if (RETVAL->cipher_id == -1) { Safefree(RETVAL); croak("FATAL: find_cipfer failed for '%s'", cipher_name); @@ -29,16 +31,11 @@ DESTROY(Crypt::Mode::CTR self) CODE: Safefree(self); -int -_get_dir(Crypt::Mode::CTR self) - CODE: - RETVAL = self->direction; - OUTPUT: - RETVAL - void -_start(Crypt::Mode::CTR self, int dir, SV * key, SV * iv) - CODE: +start_decrypt(Crypt::Mode::CTR self, SV * key, SV * iv) + ALIAS: + start_encrypt = 1 + PPCODE: { STRLEN k_len=0; unsigned char *k=NULL; @@ -60,52 +57,51 @@ _start(Crypt::Mode::CTR self, int dir, SV * key, SV * iv) croak("FATAL: ctr_start failed: %s", error_to_string(rv)); } - self->direction = dir; + self->direction = ix == 1 ? 1 : -1; + XPUSHs(ST(0)); /* return self */ } SV * -_crypt(Crypt::Mode::CTR self, SV * data) +add(Crypt::Mode::CTR self, ...) CODE: { - int rv; - STRLEN in_data_len; + int rv, j; + STRLEN in_data_len, out_len = 0; unsigned char *in_data, *out_data; - in_data = (unsigned char *)SvPVbyte(data, in_data_len); - if (in_data_len == 0) { - RETVAL = newSVpvn("", 0); - } - else { - RETVAL = NEWSV(0, in_data_len); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, in_data_len); - out_data = (unsigned char *)SvPVX(RETVAL); - - if (self->direction == 1) { - rv = ctr_encrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); - if (rv != CRYPT_OK) { - SvREFCNT_dec(RETVAL); - croak("FATAL: ctr_encrypt failed: %s", error_to_string(rv)); + RETVAL = newSVpvn("", 0); + for (j = 1; j < items; j++) { + in_data = (unsigned char *)SvPVbyte(ST(j), in_data_len); + if (in_data_len > 0) { + out_data = (unsigned char*)SvGROW(RETVAL, out_len + in_data_len + 1) + out_len; + out_len += in_data_len; + if (self->direction == 1) { + rv = ctr_encrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: ctr_encrypt failed: %s", error_to_string(rv)); + } } - } - else if (self->direction == -1) { - rv = ctr_decrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); - if (rv != CRYPT_OK) { + else if (self->direction == -1) { + rv = ctr_decrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: ctr_decrypt failed: %s", error_to_string(rv)); + } + } + else { SvREFCNT_dec(RETVAL); - croak("FATAL: ctr_decrypt failed: %s", error_to_string(rv)); + croak("FATAL: ctr_crypt failed: call start_encrypt or start_decrypt first"); } } - else { - SvREFCNT_dec(RETVAL); - croak("FATAL: ctr_crypt failed: call start_encrypt or start_decrypt first"); - } } + if (out_len > 0) SvCUR_set(RETVAL, out_len); } OUTPUT: RETVAL SV * -_finish(Crypt::Mode::CTR self) +finish(Crypt::Mode::CTR self) CODE: self->direction = 0; RETVAL = newSVpvn("", 0); diff --git a/inc/CryptX_Mode_ECB.xs.inc b/inc/CryptX_Mode_ECB.xs.inc index 1b2c4f2e..8d34adbe 100644 --- a/inc/CryptX_Mode_ECB.xs.inc +++ b/inc/CryptX_Mode_ECB.xs.inc @@ -1,9 +1,11 @@ MODULE = CryptX PACKAGE = Crypt::Mode::ECB +PROTOTYPES: DISABLE + ### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! Crypt::Mode::ECB -_new(char * cipher_name, int padding=1, int rounds=0) +new(Class, char * cipher_name, int padding=1, int rounds=0) CODE: { Newz(0, RETVAL, 1, struct ecb_struct); @@ -12,7 +14,7 @@ _new(char * cipher_name, int padding=1, int rounds=0) RETVAL->padlen = 0; RETVAL->direction = 0; RETVAL->cipher_rounds = rounds; - RETVAL->cipher_id = find_cipher(cipher_name); + RETVAL->cipher_id = _find_cipher(cipher_name); if (RETVAL->cipher_id == -1) { Safefree(RETVAL); croak("FATAL: find_cipfer failed for '%s'", cipher_name); @@ -26,16 +28,11 @@ DESTROY(Crypt::Mode::ECB self) CODE: Safefree(self); -int -_get_dir(Crypt::Mode::ECB self) - CODE: - RETVAL = self->direction; - OUTPUT: - RETVAL - void -_start(Crypt::Mode::ECB self, int dir, SV * key) - CODE: +start_decrypt(Crypt::Mode::ECB self, SV * key) + ALIAS: + start_encrypt = 1 + PPCODE: { int rv; STRLEN k_len=0; @@ -49,243 +46,215 @@ _start(Crypt::Mode::ECB self, int dir, SV * key) croak("FATAL: ecb_start failed: %s", error_to_string(rv)); } - self->direction = dir; + self->direction = ix == 1 ? 1 : -1; self->padlen = 0; + XPUSHs(ST(0)); /* return self */ } SV * -_encrypt(Crypt::Mode::ECB self, SV * data) +add(Crypt::Mode::ECB self, ...) CODE: { - int rv, has_tmp_block, blen; + int rv, has_tmp_block, blen, j; unsigned long i; - - STRLEN in_data_len, in_data_start; + STRLEN in_data_len, in_data_start, out_len = 0; unsigned char *in_data, *out_data, tmp_block[MAXBLOCKSIZE]; - if (self->direction != 1) croak("FATAL: encrypt error, call start_encrypt first (%d)", self->direction); + RETVAL = newSVpvn("", 0); + for (j = 1; j < items; j++) { + in_data = (unsigned char *)SvPVbyte(ST(j), in_data_len); + blen = (&self->state)->blocklen; + in_data_start = 0; + has_tmp_block = 0; + if (in_data_len > 0) { + if (self->direction == 1) { + /* handle non-empty self->pad buffer */ + if (self->padlen > 0) { + i = (blen - self->padlen); + if (in_data_len >= i) { /* enough data to fill pad */ + Copy(in_data, self->pad+self->padlen, i, unsigned char); + in_data_len -= i; + in_data_start = i; + rv = ecb_encrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: ecb_encrypt failed: %s", error_to_string(rv)); + } + self->padlen = 0; + has_tmp_block = 1; + } + else { /* not enough data to fill pad */ + Copy(in_data, self->pad+self->padlen, in_data_len, unsigned char); + self->padlen += (int)in_data_len; + in_data_len = 0; + } + } - blen = (&self->state)->blocklen; - in_data_start = 0; - has_tmp_block = 0; - in_data = (unsigned char *)SvPVbyte(data, in_data_len); - if (in_data_len == 0) { - RETVAL = newSVpvn("", 0); - } - else { - if (self->padlen > 0) { - i = (blen - self->padlen); - if (in_data_len >= i) { /* enough data to fill pad */ - Copy(in_data, self->pad+self->padlen, i, unsigned char); - in_data_len -= i; - in_data_start = i; - rv = ecb_encrypt(self->pad, tmp_block, blen, &self->state); - if (rv != CRYPT_OK) croak("FATAL: ecb_encrypt failed: %s", error_to_string(rv)); - self->padlen = 0; - has_tmp_block = 1; - } - else { /* not enough data to fill pad */ - Copy(in_data, self->pad+self->padlen, in_data_len, unsigned char); - self->padlen += (int)in_data_len; - in_data_len = 0; + i = (unsigned long)(in_data_len % blen); + if (in_data_len > 0 && i > 0) { /* save tail of data into pad */ + Copy(in_data + in_data_start + in_data_len - i, self->pad, i, unsigned char); + self->padlen = i; + in_data_len -= i; + } + + if (in_data_len > 0) { + i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); + out_data = (unsigned char*)SvGROW(RETVAL, out_len + i + 1) + out_len; + out_len += i; + if (has_tmp_block) { + Copy(tmp_block, out_data, blen, unsigned char); + out_data += blen; + } + rv = ecb_encrypt(in_data+in_data_start, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: ecb_encrypt failed: %s", error_to_string(rv)); + } + } /* in_data_len > 0 */ + else if (has_tmp_block) { + out_data = (unsigned char*)SvGROW(RETVAL, out_len + blen + 1) + out_len; + out_len += blen; + Copy(tmp_block, out_data, blen, unsigned char); + } } - } /* padlen > 0 */ + else if (self->direction == -1) { + if (self->padlen == blen) { + rv = ecb_decrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: ecb_decrypt failed: %s", error_to_string(rv)); + } + self->padlen = 0; + has_tmp_block = 1; + } /* padlen == blen */ + else if (self->padlen > 0) { + i = (blen - self->padlen); /* remaining bytes in padding buffer */ + if (in_data_len >= i) { /* enough data to fill pad */ + Copy(in_data, self->pad+self->padlen, i, unsigned char); + self->padlen += i; + in_data_len -= i; + in_data_start = i; + if (in_data_len>0 || self->padding_mode == 0) { + rv = ecb_decrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: ecb_decrypt failed: %s", error_to_string(rv)); + } + self->padlen = 0; + has_tmp_block = 1; + } + } + else { /* not enough data to fill pad */ + Copy(in_data, self->pad+self->padlen, in_data_len, unsigned char); + self->padlen += (int)in_data_len; + in_data_len = 0; + } + } /* padlen > 0 */ - i = (unsigned long)(in_data_len % blen); - if (in_data_len>0 && i>0) { /* save tail of data into pad */ - Copy(in_data+in_data_start+in_data_len-i, self->pad, i, unsigned char); - self->padlen = i; - in_data_len -= i; - } + /* here: a/ padlen == 1..16 && in_data_len == 0; b/ padlen == 0 && in_data_len > 0 */ + if (in_data_len>0) { + i = (unsigned long)(in_data_len % blen); + if (i>0) { /* save tail of data into pad */ + Copy(in_data+in_data_start+in_data_len-i, self->pad, i, unsigned char); + self->padlen = i; + in_data_len -= i; + } + } - if (in_data_len > 0) { - i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); - RETVAL = NEWSV(0, i); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, i); - out_data = (unsigned char *)SvPVX(RETVAL); - if (has_tmp_block) { - Copy(tmp_block, out_data, blen, unsigned char); - out_data += blen; + if (in_data_len>0) { + if (self->padlen == 0 && self->padding_mode !=0) { + /* in case of padding keep full pad if no more data */ + Copy(in_data+in_data_start+in_data_len-blen, self->pad, blen, unsigned char); + self->padlen = blen; + in_data_len -= blen; + } + i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); + if (i > 0) { + out_data = (unsigned char*)SvGROW(RETVAL, out_len + i + 1) + out_len; + out_len += i; + if (has_tmp_block) { + Copy(tmp_block, out_data, blen, unsigned char); + out_data += blen; + } + rv = ecb_decrypt(in_data+in_data_start, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: ecb_decrypt failed: %s", error_to_string(rv)); + } + } + } /* in_data_len>0 */ + else if (has_tmp_block) { + out_data = (unsigned char*)SvGROW(RETVAL, out_len + blen + 1) + out_len; + out_len += blen; + Copy(tmp_block, out_data, blen, unsigned char); + } } - rv = ecb_encrypt(in_data+in_data_start, out_data, (unsigned long)in_data_len, &self->state); - if (rv != CRYPT_OK) { + else { SvREFCNT_dec(RETVAL); - croak("FATAL: ecb_encrypt failed: %s", error_to_string(rv)); + croak("FATAL: call start_decryt or start_encrpyt first (%d)", self->direction); } - } /* in_data_len>0 */ - else if (has_tmp_block) { - RETVAL = newSVpvn((char*)tmp_block, blen); } - else { - RETVAL = newSVpvn("", 0); - } - } - } - OUTPUT: - RETVAL - -SV * -_finish_enc(Crypt::Mode::ECB self) - CODE: - { - unsigned char tmp_block[MAXBLOCKSIZE]; - int rv, blen, i, j; - - blen = (&self->state)->blocklen; - if (self->padlen<0 || self->padlen>=blen) croak("FATAL: invalid padlen"); - - if (self->padding_mode == 1) { /* pkcs5|7 padding */ - i = blen - self->padlen; - if (i == 0) i = blen; - for(j=self->padlen; j<blen; j++) self->pad[j] = (unsigned char)i; - rv = ecb_encrypt(self->pad, tmp_block, blen, &self->state); - if (rv != CRYPT_OK) croak("FATAL: ecb_encrypt failed: %s", error_to_string(rv)); - } - else if (self->padding_mode == 2) { /* oneandzeroes padding */ - self->pad[self->padlen] = 0x80; - for(j=self->padlen+1; j<blen; j++) self->pad[j] = 0; - rv = ecb_encrypt(self->pad, tmp_block, blen, &self->state); - if (rv != CRYPT_OK) croak("FATAL: ecb_encrypt failed: %s", error_to_string(rv)); - } - else { - if (self->padlen>0) croak("FATAL: ecb_encrypt, input data length not multiple of %d", blen); - blen = 0; } - - self->direction = 0; - RETVAL = newSVpvn((char*)tmp_block, blen); + if (out_len > 0) SvCUR_set(RETVAL, out_len); } OUTPUT: RETVAL SV * -_decrypt(Crypt::Mode::ECB self, SV * data) +finish(Crypt::Mode::ECB self) CODE: { - int rv, has_tmp_block, blen; - unsigned long i; - STRLEN in_data_len, in_data_start; - unsigned char *in_data, *out_data, tmp_block[MAXBLOCKSIZE]; - - if (self->direction != -1) croak("FATAL: decrypt error, call start_decryt first (%d)", self->direction); + unsigned char tmp_block[MAXBLOCKSIZE], ch; + int i, j, rv, blen = (&self->state)->blocklen; - blen = (&self->state)->blocklen; - in_data_start = 0; - has_tmp_block = 0; - in_data = (unsigned char *)SvPVbyte(data, in_data_len); - if (in_data_len == 0) { - RETVAL = newSVpvn("", 0); + if (self->direction == 1) { + if (self->padlen<0 || self->padlen>=blen) croak("FATAL: invalid padlen"); + if (self->padding_mode == 1) { /* pkcs5|7 padding */ + i = blen - self->padlen; + if (i == 0) i = blen; + for(j=self->padlen; j<blen; j++) self->pad[j] = (unsigned char)i; + rv = ecb_encrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) croak("FATAL: ecb_encrypt failed: %s", error_to_string(rv)); + } + else if (self->padding_mode == 2) { /* oneandzeroes padding */ + self->pad[self->padlen] = 0x80; + for(j=self->padlen+1; j<blen; j++) self->pad[j] = 0; + rv = ecb_encrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) croak("FATAL: ecb_encrypt failed: %s", error_to_string(rv)); + } + else { + if (self->padlen>0) croak("FATAL: ecb_encrypt, input data length not multiple of %d", blen); + blen = 0; + } } - else { - - if (self->padlen == blen) { + else if (self->direction == -1) { + if (self->padlen > 0) { + if (self->padlen != blen) croak("FATAL: cipher text length has to be multiple of %d (%d)", blen, self->padlen); rv = ecb_decrypt(self->pad, tmp_block, blen, &self->state); if (rv != CRYPT_OK) croak("FATAL: ecb_decrypt failed: %s", error_to_string(rv)); - self->padlen = 0; - has_tmp_block = 1; - } /* padlen == blen */ - else if (self->padlen > 0) { - i = (blen - self->padlen); /* remaining bytes in padding buffer */ - if (in_data_len >= i) { /* enough data to fill pad */ - Copy(in_data, self->pad+self->padlen, i, unsigned char); - self->padlen += i; - in_data_len -= i; - in_data_start = i; - if (in_data_len>0 || self->padding_mode == 0) { - rv = ecb_decrypt(self->pad, tmp_block, blen, &self->state); - if (rv != CRYPT_OK) croak("FATAL: ecb_decrypt failed: %s", error_to_string(rv)); - self->padlen = 0; - has_tmp_block = 1; - } - } - else { /* not enough data to fill pad */ - Copy(in_data, self->pad+self->padlen, in_data_len, unsigned char); - self->padlen += (int)in_data_len; - in_data_len = 0; - } - } /* padlen > 0 */ - - /* here: a/ padlen == 1..16 && in_data_len == 0; b/ padlen == 0 && in_data_len > 0 */ - if (in_data_len>0) { - i = (unsigned long)(in_data_len % blen); - if (i>0) { /* save tail of data into pad */ - Copy(in_data+in_data_start+in_data_len-i, self->pad, i, unsigned char); - self->padlen = i; - in_data_len -= i; - } - } - - if (in_data_len>0) { - if (self->padlen == 0 && self->padding_mode !=0) { - /* in case of padding keep full pad if no more data */ - Copy(in_data+in_data_start+in_data_len-blen, self->pad, blen, unsigned char); - self->padlen = blen; - in_data_len -= blen; + if (self->padding_mode == 0) { /* no padding */ + /* we already have blen */ } - i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); - if (i == 0) { - RETVAL = newSVpvn("", 0); + else if (self->padding_mode == 1) { /* pkcs5|7 padding */ + ch = tmp_block[blen-1]; + blen = blen - (ch > blen ? blen : ch); } - else { - RETVAL = NEWSV(0, i); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, i); - out_data = (unsigned char *)SvPVX(RETVAL); - if (has_tmp_block) { - Copy(tmp_block, out_data, blen, unsigned char); - out_data += blen; - } - rv = ecb_decrypt(in_data+in_data_start, out_data, (unsigned long)in_data_len, &self->state); - if (rv != CRYPT_OK) { - SvREFCNT_dec(RETVAL); - croak("FATAL: ecb_decrypt failed: %s", error_to_string(rv)); - } + else if (self->padding_mode == 2) { /* oneandzeroes padding */ + while ((unsigned char)tmp_block[blen - 1] == 0x00) blen--; + if ((unsigned char)tmp_block[blen - 1] == 0x80) blen--; + if (blen < 0) blen = 0; } - } /* in_data_len>0 */ - else if (has_tmp_block) { - RETVAL = newSVpvn((char*)tmp_block, blen); } else { - RETVAL = newSVpvn("", 0); + blen = 0; } } - - } - OUTPUT: - RETVAL - -SV * -_finish_dec(Crypt::Mode::ECB self) - CODE: - { - unsigned char tmp_block[MAXBLOCKSIZE]; - unsigned char i; - int rv, rv_len, blen; - - rv_len = 0; - if (self->padlen > 0) { - blen = (&self->state)->blocklen; - if (self->padlen != blen) croak("FATAL: cipher text length has to be multiple of %d (%d)", blen, self->padlen); - rv = ecb_decrypt(self->pad, tmp_block, blen, &self->state); - if (rv != CRYPT_OK) croak("FATAL: ecb_decrypt failed: %s", error_to_string(rv)); - if (self->padding_mode == 0) { /* no padding */ - rv_len = blen; - } - else if (self->padding_mode == 1) { /* pkcs5|7 padding */ - i = tmp_block[blen-1]; - rv_len = blen - (i>blen ? blen : i); - } - else if (self->padding_mode == 2) { /* oneandzeroes padding */ - rv_len = blen; - while ((unsigned char)tmp_block[rv_len-1] == 0x00) rv_len--; - if ((unsigned char)tmp_block[rv_len-1] == 0x80) rv_len--; - if (rv_len<0) rv_len = 0; - } + else { + XSRETURN_UNDEF; } self->direction = 0; - RETVAL = newSVpvn((char*)tmp_block, rv_len); + RETVAL = newSVpvn((char*)tmp_block, blen); } OUTPUT: RETVAL diff --git a/inc/CryptX_Mode_OFB.xs.inc b/inc/CryptX_Mode_OFB.xs.inc index 1acd3a94..1a3447b3 100644 --- a/inc/CryptX_Mode_OFB.xs.inc +++ b/inc/CryptX_Mode_OFB.xs.inc @@ -1,16 +1,18 @@ MODULE = CryptX PACKAGE = Crypt::Mode::OFB +PROTOTYPES: DISABLE + ### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! Crypt::Mode::OFB -_new(char * cipher_name, int rounds=0) +new(Class, char * cipher_name, int rounds=0) CODE: { Newz(0, RETVAL, 1, struct ofb_struct); if (!RETVAL) croak("FATAL: Newz failed"); RETVAL->direction = 0; RETVAL->cipher_rounds = rounds; - RETVAL->cipher_id = find_cipher(cipher_name); + RETVAL->cipher_id = _find_cipher(cipher_name); if (RETVAL->cipher_id == -1) { Safefree(RETVAL); croak("FATAL: find_cipfer failed for '%s'", cipher_name); @@ -24,16 +26,11 @@ DESTROY(Crypt::Mode::OFB self) CODE: Safefree(self); -int -_get_dir(Crypt::Mode::OFB self) - CODE: - RETVAL = self->direction; - OUTPUT: - RETVAL - void -_start(Crypt::Mode::OFB self, int dir, SV * key, SV * iv) - CODE: +start_decrypt(Crypt::Mode::OFB self, SV * key, SV * iv) + ALIAS: + start_encrypt = 1 + PPCODE: { STRLEN k_len=0; unsigned char *k=NULL; @@ -55,52 +52,51 @@ _start(Crypt::Mode::OFB self, int dir, SV * key, SV * iv) croak("FATAL: ofb_start failed: %s", error_to_string(rv)); } - self->direction = dir; + self->direction = ix == 1 ? 1 : -1; + XPUSHs(ST(0)); /* return self */ } SV * -_crypt(Crypt::Mode::OFB self, SV * data) +add(Crypt::Mode::OFB self, ...) CODE: { - int rv; - STRLEN in_data_len; + int rv, j; + STRLEN in_data_len, out_len = 0; unsigned char *in_data, *out_data; - in_data = (unsigned char *)SvPVbyte(data, in_data_len); - if (in_data_len == 0) { - RETVAL = newSVpvn("", 0); - } - else { - RETVAL = NEWSV(0, in_data_len); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, in_data_len); - out_data = (unsigned char *)SvPVX(RETVAL); - - if (self->direction == 1) { - rv = ofb_encrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); - if (rv != CRYPT_OK) { - SvREFCNT_dec(RETVAL); - croak("FATAL: ofb_encrypt failed: %s", error_to_string(rv)); + RETVAL = newSVpvn("", 0); + for (j = 1; j < items; j++) { + in_data = (unsigned char *)SvPVbyte(ST(j), in_data_len); + if (in_data_len > 0) { + out_data = (unsigned char*)SvGROW(RETVAL, out_len + in_data_len + 1) + out_len; + out_len += in_data_len; + if (self->direction == 1) { + rv = ofb_encrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: ofb_encrypt failed: %s", error_to_string(rv)); + } } - } - else if (self->direction == -1) { - rv = ofb_decrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); - if (rv != CRYPT_OK) { + else if (self->direction == -1) { + rv = ofb_decrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: ofb_decrypt failed: %s", error_to_string(rv)); + } + } + else { SvREFCNT_dec(RETVAL); - croak("FATAL: ofb_decrypt failed: %s", error_to_string(rv)); + croak("FATAL: ofb_crypt failed: call start_encrypt or start_decrypt first"); } } - else { - SvREFCNT_dec(RETVAL); - croak("FATAL: ofb_crypt failed: call start_encrypt or start_decrypt first"); - } } + if (out_len > 0) SvCUR_set(RETVAL, out_len); } OUTPUT: RETVAL SV * -_finish(Crypt::Mode::OFB self) +finish(Crypt::Mode::OFB self) CODE: self->direction = 0; RETVAL = newSVpvn("", 0); diff --git a/inc/CryptX_PK_DH.xs.inc b/inc/CryptX_PK_DH.xs.inc index 0898e805..4040800f 100644 --- a/inc/CryptX_PK_DH.xs.inc +++ b/inc/CryptX_PK_DH.xs.inc @@ -1,7 +1,9 @@ MODULE = CryptX PACKAGE = Crypt::PK::DH +PROTOTYPES: DISABLE + Crypt::PK::DH -_new() +_new(Class) CODE: { int rv; @@ -208,7 +210,7 @@ key2hash(Crypt::PK::DH self) not_used = hv_store(rv_hash, "size", 4, newSViv(dh_get_groupsize(&self->key)), 0); /* type */ not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0); - if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */ + LTC_UNUSED_PARAM(not_used); RETVAL = newRV_noinc((SV*)rv_hash); OUTPUT: RETVAL diff --git a/inc/CryptX_PK_DSA.xs.inc b/inc/CryptX_PK_DSA.xs.inc index aebb53a3..d1673f4e 100644 --- a/inc/CryptX_PK_DSA.xs.inc +++ b/inc/CryptX_PK_DSA.xs.inc @@ -1,7 +1,9 @@ MODULE = CryptX PACKAGE = Crypt::PK::DSA +PROTOTYPES: DISABLE + Crypt::PK::DSA -_new() +_new(Class) CODE: { int rv; @@ -229,7 +231,7 @@ key2hash(Crypt::PK::DSA self) not_used = hv_store(rv_hash, "size", 4, newSViv(qsize), 0); /* type */ not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0); - if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */ + LTC_UNUSED_PARAM(not_used); RETVAL = newRV_noinc((SV*)rv_hash); OUTPUT: RETVAL @@ -261,7 +263,7 @@ export_key_der(Crypt::PK::DSA self, char * type) RETVAL SV * -_encrypt(Crypt::PK::DSA self, SV * data, char * hash_name) +encrypt(Crypt::PK::DSA self, SV * data, const char * hash_name = "SHA1") CODE: { int rv, hash_id; @@ -272,7 +274,7 @@ _encrypt(Crypt::PK::DSA self, SV * data, char * hash_name) data_ptr = (unsigned char *)SvPVbyte(data, data_len); - hash_id = find_hash(hash_name); + hash_id = _find_hash(hash_name); if (hash_id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); rv = dsa_encrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->pstate, self->pindex, @@ -284,7 +286,7 @@ _encrypt(Crypt::PK::DSA self, SV * data, char * hash_name) RETVAL SV * -_decrypt(Crypt::PK::DSA self, SV * data) +decrypt(Crypt::PK::DSA self, SV * data) CODE: { int rv; @@ -303,17 +305,25 @@ _decrypt(Crypt::PK::DSA self, SV * data) RETVAL SV * -_sign(Crypt::PK::DSA self, SV * data) +sign_hash(Crypt::PK::DSA self, SV * data, const char * hash_name = "SHA1") + ALIAS: + sign_message = 1 CODE: { - int rv; - unsigned char *data_ptr=NULL; - STRLEN data_len=0; - unsigned char buffer[1024]; - unsigned long buffer_len = 1024; + int rv, id; + unsigned char buffer[1024], tmp[MAXBLOCKSIZE], *data_ptr = NULL; + unsigned long tmp_len = MAXBLOCKSIZE, buffer_len = 1024; + STRLEN data_len = 0; data_ptr = (unsigned char *)SvPVbyte(data, data_len); - + if (ix == 1) { + id = _find_hash(hash_name); + if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); + rv = hash_memory(id, data_ptr, (unsigned long)data_len, tmp, &tmp_len); + if (rv != CRYPT_OK) croak("FATAL: hash_memory failed: %s", error_to_string(rv)); + data_ptr = tmp; + data_len = tmp_len; + } rv = dsa_sign_hash(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->pstate, self->pindex, &self->key); @@ -324,18 +334,26 @@ _sign(Crypt::PK::DSA self, SV * data) RETVAL int -_verify(Crypt::PK::DSA self, SV * sig, SV * data) +verify_hash(Crypt::PK::DSA self, SV * sig, SV * data, const char * hash_name = "SHA1") + ALIAS: + verify_message = 1 CODE: { - int rv, stat; - unsigned char *data_ptr=NULL; - STRLEN data_len=0; - unsigned char *sig_ptr=NULL; - STRLEN sig_len=0; + int rv, stat, id; + unsigned char tmp[MAXBLOCKSIZE], *data_ptr = NULL, *sig_ptr = NULL; + unsigned long tmp_len = MAXBLOCKSIZE; + STRLEN data_len = 0, sig_len = 0; data_ptr = (unsigned char *)SvPVbyte(data, data_len); sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len); - + if (ix == 1) { + id = _find_hash(hash_name); + if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); + rv = hash_memory(id, data_ptr, (unsigned long)data_len, tmp, &tmp_len); + if (rv != CRYPT_OK) croak("FATAL: hash_memory failed: %s", error_to_string(rv)); + data_ptr = tmp; + data_len = tmp_len; + } RETVAL = 1; stat = 0; rv = dsa_verify_hash(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key); diff --git a/inc/CryptX_PK_ECC.xs.inc b/inc/CryptX_PK_ECC.xs.inc index 239376f2..751b7d83 100644 --- a/inc/CryptX_PK_ECC.xs.inc +++ b/inc/CryptX_PK_ECC.xs.inc @@ -1,7 +1,9 @@ MODULE = CryptX PACKAGE = Crypt::PK::ECC +PROTOTYPES: DISABLE + Crypt::PK::ECC -_new() +_new(Class) CODE: { int rv; @@ -9,7 +11,6 @@ _new() if (!RETVAL) croak("FATAL: Newz failed"); RETVAL->pindex = find_prng("chacha20"); RETVAL->key.type = -1; - ecc_dp_init(&RETVAL->dp); if (RETVAL->pindex == -1) { Safefree(RETVAL); croak("FATAL: find_prng('chacha20') failed"); @@ -29,10 +30,11 @@ generate_key(Crypt::PK::ECC self, SV *curve) { int rv; /* setup dp structure */ - _ecc_set_dp_from_SV(&self->dp, curve); /* croaks on error */ + rv = _ecc_set_dp_from_SV(&self->key, curve); /* croaks on error */ + if (rv != CRYPT_OK) croak("FATAL: ecc_set_dp failed: %s", error_to_string(rv)); /* gen the key */ - rv = ecc_make_key_ex(&self->pstate, self->pindex, &self->key, &self->dp); - if (rv != CRYPT_OK) croak("FATAL: ecc_make_key_ex failed: %s", error_to_string(rv)); + rv = ecc_generate_key(&self->pstate, self->pindex, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_generate_key failed: %s", error_to_string(rv)); XPUSHs(ST(0)); /* return self */ } @@ -45,9 +47,9 @@ _import(Crypt::PK::ECC self, SV * key_data) STRLEN data_len=0; data = (unsigned char *)SvPVbyte(key_data, data_len); - _ecc_free_key(&self->key, &self->dp); - rv = ecc_import_full(data, (unsigned long)data_len, &self->key, &self->dp); - if (rv != CRYPT_OK) croak("FATAL: ecc_import_full failed: %s", error_to_string(rv)); + if (self->key.type != -1) { ecc_free(&self->key); self->key.type = -1; } + rv = ecc_import_openssl(data, (unsigned long)data_len, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_import_openssl failed: %s", error_to_string(rv)); XPUSHs(ST(0)); /* return self */ } @@ -63,14 +65,14 @@ _import_pkcs8(Crypt::PK::ECC self, SV * key_data, SV * passwd) if (SvOK(passwd)) { pwd = (unsigned char *)SvPVbyte(passwd, pwd_len); } - _ecc_free_key(&self->key, &self->dp); - rv = ecc_import_pkcs8(data, (unsigned long)data_len, pwd, (unsigned long)pwd_len, &self->key, &self->dp); + if (self->key.type != -1) { ecc_free(&self->key); self->key.type = -1; } + rv = ecc_import_pkcs8(data, (unsigned long)data_len, pwd, (unsigned long)pwd_len, &self->key); if (rv != CRYPT_OK) croak("FATAL: ecc_import_pkcs8 failed: %s", error_to_string(rv)); XPUSHs(ST(0)); /* return self */ } void -import_key_raw(Crypt::PK::ECC self, SV * key_data, SV * curve) +_import_x509(Crypt::PK::ECC self, SV * key_data) PPCODE: { int rv; @@ -78,12 +80,29 @@ import_key_raw(Crypt::PK::ECC self, SV * key_data, SV * curve) STRLEN data_len=0; data = (unsigned char *)SvPVbyte(key_data, data_len); - _ecc_free_key(&self->key, &self->dp); + if (self->key.type != -1) { ecc_free(&self->key); self->key.type = -1; } + rv = ecc_import_x509(data, (unsigned long)data_len, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_import_x509 failed: %s", error_to_string(rv)); + XPUSHs(ST(0)); /* return self */ + } - _ecc_set_dp_from_SV(&self->dp, curve); /* croaks on error */ +void +import_key_raw(Crypt::PK::ECC self, SV * key_data, SV * curve) + PPCODE: + { + int rv, type; + unsigned char *data=NULL; + STRLEN data_len=0; - rv = ecc_import_raw(data, (unsigned long)data_len, &self->key, &self->dp); - if (rv != CRYPT_OK) croak("FATAL: ecc_import_raw failed: %s", error_to_string(rv)); + data = (unsigned char *)SvPVbyte(key_data, data_len); + if (self->key.type != -1) { ecc_free(&self->key); self->key.type = -1; } + /* setup dp structure */ + rv = _ecc_set_dp_from_SV(&self->key, curve); /* croaks on error */ + if (rv != CRYPT_OK) croak("FATAL: ecc_set_dp failed: %s", error_to_string(rv)); + /* import key */ + type = (data_len == (STRLEN)ecc_get_size(&self->key)) ? PK_PRIVATE : PK_PUBLIC; + rv = ecc_set_key(data, (unsigned long)data_len, type, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_set_key failed: %s", error_to_string(rv)); XPUSHs(ST(0)); /* return self */ } @@ -151,61 +170,55 @@ key2hash(Crypt::PK::ECC self) not_used = hv_store(rv_hash, "pub_y", 5, newSVpv("", 0), 0); } /* curve_... */ - if (self->key.dp) { - not_used = hv_store(rv_hash, "curve_cofactor", 14, newSViv(self->key.dp->cofactor), 0); - /* prepend leading zero if we have odd number of hexadecimal digits */ - strncpy(buf, self->key.dp->prime, 20000); str_add_leading_zero(buf, 20000, 0); - not_used = hv_store(rv_hash, "curve_prime", 11, newSVpv(buf, strlen(buf)), 0); - strncpy(buf, self->key.dp->A, 20000); str_add_leading_zero(buf, 20000, 0); - not_used = hv_store(rv_hash, "curve_A", 7, newSVpv(buf, strlen(buf)), 0); - strncpy(buf, self->key.dp->B, 20000); str_add_leading_zero(buf, 20000, 0); - not_used = hv_store(rv_hash, "curve_B", 7, newSVpv(buf, strlen(buf)), 0); - strncpy(buf, self->key.dp->order, 20000); str_add_leading_zero(buf, 20000, 0); - not_used = hv_store(rv_hash, "curve_order", 11, newSVpv(buf, strlen(buf)), 0); - strncpy(buf, self->key.dp->Gx, 20000); str_add_leading_zero(buf, 20000, 0); - not_used = hv_store(rv_hash, "curve_Gx", 8, newSVpv(buf, strlen(buf)), 0); - strncpy(buf, self->key.dp->Gy, 20000); str_add_leading_zero(buf, 20000, 0); - not_used = hv_store(rv_hash, "curve_Gy", 8, newSVpv(buf, strlen(buf)), 0); - /* OLD approach - not_used = hv_store(rv_hash, "curve_prime", 11, newSVpv(self->key.dp->prime, strlen(self->key.dp->prime)), 0); - not_used = hv_store(rv_hash, "curve_A", 7, newSVpv(self->key.dp->A, strlen(self->key.dp->A)), 0); - not_used = hv_store(rv_hash, "curve_B", 7, newSVpv(self->key.dp->B, strlen(self->key.dp->B)), 0); - not_used = hv_store(rv_hash, "curve_order", 11, newSVpv(self->key.dp->order, strlen(self->key.dp->order)), 0); - not_used = hv_store(rv_hash, "curve_Gx", 8, newSVpv(self->key.dp->Gx, strlen(self->key.dp->Gx)), 0); - not_used = hv_store(rv_hash, "curve_Gy", 8, newSVpv(self->key.dp->Gy, strlen(self->key.dp->Gy)), 0); - */ - { - mp_int p_num; - mp_init(&p_num); - mp_read_radix(&p_num, self->key.dp->prime, 16); - not_used = hv_store(rv_hash, "curve_bytes", 11, newSViv(mp_unsigned_bin_size(&p_num)), 0); - not_used = hv_store(rv_hash, "curve_bits", 10, newSViv(mp_count_bits(&p_num)), 0); - mp_clear(&p_num); - } - { - unsigned long i; - SV *name; - char *name_ptr; - STRLEN name_len; - - name = newSVpv(self->key.dp->name, strlen(self->key.dp->name)); - name_ptr = SvPV(name, name_len); - for (i=0; i<name_len && name_ptr[i]>0; i++) name_ptr[i] = toLOWER(name_ptr[i]); - not_used = hv_store(rv_hash, "curve_name", 10, name, 0); - } - if (self->key.dp->oid.OIDlen > 0) { + { + not_used = hv_store(rv_hash, "curve_cofactor", 14, newSViv(self->key.dp.cofactor), 0); + mp_tohex_with_leading_zero(self->key.dp.prime, buf, 20000, 0); + not_used = hv_store(rv_hash, "curve_prime", 11, newSVpv(buf, strlen(buf)), 0); + mp_tohex_with_leading_zero(self->key.dp.A, buf, 20000, 0); + not_used = hv_store(rv_hash, "curve_A", 7, newSVpv(buf, strlen(buf)), 0); + mp_tohex_with_leading_zero(self->key.dp.B, buf, 20000, 0); + not_used = hv_store(rv_hash, "curve_B", 7, newSVpv(buf, strlen(buf)), 0); + mp_tohex_with_leading_zero(self->key.dp.order, buf, 20000, 0); + not_used = hv_store(rv_hash, "curve_order", 11, newSVpv(buf, strlen(buf)), 0); + mp_tohex_with_leading_zero(self->key.dp.base.x, buf, 20000, 0); + not_used = hv_store(rv_hash, "curve_Gx", 8, newSVpv(buf, strlen(buf)), 0); + mp_tohex_with_leading_zero(self->key.dp.base.y, buf, 20000, 0); + not_used = hv_store(rv_hash, "curve_Gy", 8, newSVpv(buf, strlen(buf)), 0); + not_used = hv_store(rv_hash, "curve_bytes", 11, newSViv(mp_unsigned_bin_size(self->key.dp.prime)), 0); + not_used = hv_store(rv_hash, "curve_bits", 10, newSViv(mp_count_bits(self->key.dp.prime)), 0); + + if (self->key.dp.oidlen > 0) { unsigned long i; + HV *h; + SV **pref, *cname; + char *cname_ptr, *oid_ptr; + STRLEN cname_len; + + /* OID -> "curve_oid" */ SV *oid = newSVpv("", 0); - for(i = 0; i < self->key.dp->oid.OIDlen - 1; i++) sv_catpvf(oid, "%lu.", self->key.dp->oid.OID[i]); - sv_catpvf(oid, "%lu", self->key.dp->oid.OID[i]); + for(i = 0; i < self->key.dp.oidlen - 1; i++) sv_catpvf(oid, "%lu.", self->key.dp.oid[i]); + sv_catpvf(oid, "%lu", self->key.dp.oid[i]); + oid_ptr = SvPVX(oid); 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) { + 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); + } + } } } /* size */ not_used = hv_store(rv_hash, "size", 4, newSViv(esize), 0); /* type */ not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0); - if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */ + LTC_UNUSED_PARAM(not_used); RETVAL = newRV_noinc((SV*)rv_hash); OUTPUT: RETVAL @@ -218,25 +231,35 @@ export_key_der(Crypt::PK::ECC self, char * type) unsigned char out[4096]; unsigned long int out_len = 4096; - RETVAL = newSVpvn(NULL, 0); /* undef */ + if (self->key.type == -1) croak("FATAL: export_key_der no key"); if (strnEQ(type, "private_short", 16)) { - rv = ecc_export_full(out, &out_len, PK_PRIVATE|PK_CURVEOID, &self->key); - if (rv != CRYPT_OK) croak("FATAL: ecc_export(PK_PRIVATE|PK_CURVEOID) failed: %s", error_to_string(rv)); + rv = ecc_export_openssl(out, &out_len, PK_PRIVATE|PK_CURVEOID, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_export_openssl(PK_PRIVATE|PK_CURVEOID) failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)out, out_len); + } + else if (strnEQ(type, "private_compressed", 16)) { + rv = ecc_export_openssl(out, &out_len, PK_PRIVATE|PK_CURVEOID|PK_COMPRESSED, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_export_openssl(PK_PRIVATE|PK_CURVEOID|PK_COMPRESSED) failed: %s", error_to_string(rv)); RETVAL = newSVpvn((char*)out, out_len); } else if (strnEQ(type, "private", 7)) { - rv = ecc_export_full(out, &out_len, PK_PRIVATE, &self->key); - if (rv != CRYPT_OK) croak("FATAL: ecc_export(PK_PRIVATE) failed: %s", error_to_string(rv)); + rv = ecc_export_openssl(out, &out_len, PK_PRIVATE, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_export_openssl(PK_PRIVATE) failed: %s", error_to_string(rv)); + RETVAL = newSVpvn((char*)out, out_len); + } + else if (strnEQ(type, "public_compressed", 15)) { + rv = ecc_export_openssl(out, &out_len, PK_PUBLIC|PK_CURVEOID|PK_COMPRESSED, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_export_openssl(PK_PUBLIC|PK_CURVEOID|PK_COMPRESSED) failed: %s", error_to_string(rv)); RETVAL = newSVpvn((char*)out, out_len); } else if (strnEQ(type, "public_short", 15)) { - rv = ecc_export_full(out, &out_len, PK_PUBLIC|PK_CURVEOID, &self->key); - if (rv != CRYPT_OK) croak("FATAL: ecc_export(PK_PUBLIC|PK_CURVEOID) failed: %s", error_to_string(rv)); + rv = ecc_export_openssl(out, &out_len, PK_PUBLIC|PK_CURVEOID, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_export_openssl(PK_PUBLIC|PK_CURVEOID) failed: %s", error_to_string(rv)); RETVAL = newSVpvn((char*)out, out_len); } else if (strnEQ(type, "public", 6)) { - rv = ecc_export_full(out, &out_len, PK_PUBLIC, &self->key); - if (rv != CRYPT_OK) croak("FATAL: ecc_export(PK_PUBLIC) failed: %s", error_to_string(rv)); + rv = ecc_export_openssl(out, &out_len, PK_PUBLIC, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_export_openssl(PK_PUBLIC) failed: %s", error_to_string(rv)); RETVAL = newSVpvn((char*)out, out_len); } else { @@ -254,20 +277,20 @@ export_key_raw(Crypt::PK::ECC self, char * type) unsigned char out[4096]; unsigned long int out_len = sizeof(out); - RETVAL = newSVpvn(NULL, 0); /* undef */ + if (self->key.type == -1) croak("FATAL: export_key_der no key"); if (strnEQ(type, "private", 7)) { - rv = ecc_export_raw(out, &out_len, PK_PRIVATE, &self->key); - if (rv != CRYPT_OK) croak("FATAL: ecc_export_raw(private) failed: %s", error_to_string(rv)); + rv = ecc_get_key(out, &out_len, PK_PRIVATE, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_get_key(private) failed: %s", error_to_string(rv)); RETVAL = newSVpvn((char*)out, out_len); } else if (strnEQ(type, "public_compressed", 17)) { - rv = ecc_export_raw(out, &out_len, PK_PUBLIC|PK_COMPRESSED, &self->key); - if (rv != CRYPT_OK) croak("FATAL: ecc_export_raw(public_compressed) failed: %s", error_to_string(rv)); + rv = ecc_get_key(out, &out_len, PK_PUBLIC|PK_COMPRESSED, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_get_key(public_compressed) failed: %s", error_to_string(rv)); RETVAL = newSVpvn((char*)out, out_len); } else if (strnEQ(type, "public", 6)) { - rv = ecc_export_raw(out, &out_len, PK_PUBLIC, &self->key); - if (rv != CRYPT_OK) croak("FATAL: ecc_export_raw(public) failed: %s", error_to_string(rv)); + rv = ecc_get_key(out, &out_len, PK_PUBLIC, &self->key); + if (rv != CRYPT_OK) croak("FATAL: ecc_get_key(public) failed: %s", error_to_string(rv)); RETVAL = newSVpvn((char*)out, out_len); } else { @@ -278,7 +301,7 @@ export_key_raw(Crypt::PK::ECC self, char * type) RETVAL SV * -_encrypt(Crypt::PK::ECC self, SV * data, char * hash_name) +encrypt(Crypt::PK::ECC self, SV * data, const char * hash_name = "SHA1") CODE: { int rv, hash_id; @@ -289,7 +312,7 @@ _encrypt(Crypt::PK::ECC self, SV * data, char * hash_name) data_ptr = (unsigned char *)SvPVbyte(data, data_len); - hash_id = find_hash(hash_name); + hash_id = _find_hash(hash_name); if (hash_id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); rv = ecc_encrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->pstate, self->pindex, @@ -301,7 +324,7 @@ _encrypt(Crypt::PK::ECC self, SV * data, char * hash_name) RETVAL SV * -_decrypt(Crypt::PK::ECC self, SV * data) +decrypt(Crypt::PK::ECC self, SV * data) CODE: { int rv; @@ -320,20 +343,28 @@ _decrypt(Crypt::PK::ECC self, SV * data) RETVAL SV * -_sign(Crypt::PK::ECC self, SV * data) +sign_hash(Crypt::PK::ECC self, SV * data, const char * hash_name = "SHA1") ALIAS: - _sign_rfc7518 = 1 + sign_hash_rfc7518 = 3 + sign_message = 1 + sign_message_rfc7518 = 2 CODE: { - int rv; - unsigned char *data_ptr=NULL; - STRLEN data_len=0; - unsigned char buffer[1024]; - unsigned long buffer_len = 1024; + int rv, id; + unsigned char buffer[1024], tmp[MAXBLOCKSIZE], *data_ptr = NULL; + unsigned long tmp_len = MAXBLOCKSIZE, buffer_len = 1024; + STRLEN data_len = 0; data_ptr = (unsigned char *)SvPVbyte(data, data_len); - - if (ix == 1) { + if (ix == 1 || ix == 2) { + id = _find_hash(hash_name); + if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); + rv = hash_memory(id, data_ptr, (unsigned long)data_len, tmp, &tmp_len); + if (rv != CRYPT_OK) croak("FATAL: hash_memory failed: %s", error_to_string(rv)); + data_ptr = tmp; + data_len = tmp_len; + } + if (ix == 2 || ix == 3) { rv = ecc_sign_hash_rfc7518(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->pstate, self->pindex, &self->key); @@ -350,23 +381,31 @@ _sign(Crypt::PK::ECC self, SV * data) RETVAL int -_verify(Crypt::PK::ECC self, SV * sig, SV * data) +verify_hash(Crypt::PK::ECC self, SV * sig, SV * data, const char * hash_name = "SHA1") ALIAS: - _verify_rfc7518 = 1 + verify_hash_rfc7518 = 3 + verify_message = 1 + verify_message_rfc7518 = 2 CODE: { - int rv, stat; - unsigned char *data_ptr=NULL; - STRLEN data_len=0; - unsigned char *sig_ptr=NULL; - STRLEN sig_len=0; + int rv, stat, id; + unsigned char tmp[MAXBLOCKSIZE], *data_ptr = NULL, *sig_ptr = NULL; + unsigned long tmp_len = MAXBLOCKSIZE; + STRLEN data_len = 0, sig_len = 0; data_ptr = (unsigned char *)SvPVbyte(data, data_len); sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len); - + if (ix == 1 || ix == 2) { + id = _find_hash(hash_name); + if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); + rv = hash_memory(id, data_ptr, (unsigned long)data_len, tmp, &tmp_len); + if (rv != CRYPT_OK) croak("FATAL: hash_memory failed: %s", error_to_string(rv)); + data_ptr = tmp; + data_len = tmp_len; + } RETVAL = 1; stat = 0; - if (ix == 1) { + if (ix == 2 || ix == 3) { rv = ecc_verify_hash_rfc7518(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key); } else { @@ -395,6 +434,6 @@ shared_secret(Crypt::PK::ECC self, Crypt::PK::ECC pubkey) void DESTROY(Crypt::PK::ECC self) CODE: - _ecc_free_key(&self->key, &self->dp); + if (self->key.type != -1) { ecc_free(&self->key); self->key.type = -1; } Safefree(self); diff --git a/inc/CryptX_PK_RSA.xs.inc b/inc/CryptX_PK_RSA.xs.inc index 0c0cf852..ef33f109 100644 --- a/inc/CryptX_PK_RSA.xs.inc +++ b/inc/CryptX_PK_RSA.xs.inc @@ -1,7 +1,9 @@ MODULE = CryptX PACKAGE = Crypt::PK::RSA +PROTOTYPES: DISABLE + Crypt::PK::RSA -_new() +_new(Class) CODE: { int rv; @@ -261,7 +263,7 @@ key2hash(Crypt::PK::RSA self) not_used = hv_store(rv_hash, "size", 4, newSViv(nsize), 0); /* type */ not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0); - if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */ + LTC_UNUSED_PARAM(not_used); RETVAL = newRV_noinc((SV*)rv_hash); OUTPUT: RETVAL @@ -293,7 +295,7 @@ export_key_der(Crypt::PK::RSA self, char * type) RETVAL SV * -_encrypt(Crypt::PK::RSA self, SV * data, char * padding, char * oaep_hash, SV * oaep_lparam) +encrypt(Crypt::PK::RSA self, SV * data, const char * padding = "oaep", const char * oaep_hash = "SHA1", SV * oaep_lparam = NULL) CODE: { int rv, hash_id; @@ -308,9 +310,9 @@ _encrypt(Crypt::PK::RSA self, SV * data, char * padding, char * oaep_hash, SV * RETVAL = newSVpvn(NULL, 0); /* undef */ if (strnEQ(padding, "oaep", 4)) { - hash_id = find_hash(oaep_hash); + hash_id = _find_hash(oaep_hash); if (hash_id == -1) croak("FATAL: find_hash failed for '%s'", oaep_hash); - lparam_ptr = (unsigned char *)SvPVbyte(oaep_lparam, lparam_len); + if (oaep_lparam) lparam_ptr = (unsigned char *)SvPVbyte(oaep_lparam, lparam_len); rv = rsa_encrypt_key_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, lparam_ptr, (unsigned long)lparam_len, &self->pstate, self->pindex, hash_id, LTC_PKCS_1_OAEP, &self->key); @@ -338,7 +340,7 @@ _encrypt(Crypt::PK::RSA self, SV * data, char * padding, char * oaep_hash, SV * RETVAL SV * -_decrypt(Crypt::PK::RSA self, SV * data, char * padding, char * oaep_hash, SV * oaep_lparam) +decrypt(Crypt::PK::RSA self, SV * data, const char * padding = "oaep", const char * oaep_hash = "SHA1", SV * oaep_lparam = NULL) CODE: { int rv, hash_id, stat; @@ -353,9 +355,9 @@ _decrypt(Crypt::PK::RSA self, SV * data, char * padding, char * oaep_hash, SV * RETVAL = newSVpvn(NULL, 0); /* undef */ if (strnEQ(padding, "oaep", 4)) { - hash_id = find_hash(oaep_hash); + hash_id = _find_hash(oaep_hash); if (hash_id == -1) croak("FATAL: find_hash failed for '%s'", oaep_hash); - lparam_ptr = (unsigned char *)SvPVbyte(oaep_lparam, lparam_len); + if (oaep_lparam) lparam_ptr = (unsigned char *)SvPVbyte(oaep_lparam, lparam_len); rv = rsa_decrypt_key_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, lparam_ptr, (unsigned long)lparam_len, hash_id, LTC_PKCS_1_OAEP, &stat, &self->key); if (rv != CRYPT_OK) croak("FATAL: rsa_decrypt_key_ex failed: %s", error_to_string(rv)); @@ -383,20 +385,27 @@ _decrypt(Crypt::PK::RSA self, SV * data, char * padding, char * oaep_hash, SV * RETVAL SV * -_sign(Crypt::PK::RSA self, SV * data, char * padding, char * hash_name=NULL, unsigned long saltlen=12) +sign_hash(Crypt::PK::RSA self, SV * data, const char * hash_name = "SHA1", const char * padding = "pss", unsigned long saltlen=12) + ALIAS: + sign_message = 1 CODE: { int rv, hash_id; - unsigned char *data_ptr=NULL; - STRLEN data_len=0; - unsigned char buffer[1024]; - unsigned long buffer_len = 1024; + unsigned char buffer[1024], tmp[MAXBLOCKSIZE], *data_ptr = NULL; + unsigned long tmp_len = MAXBLOCKSIZE, buffer_len = 1024; + STRLEN data_len = 0; data_ptr = (unsigned char *)SvPVbyte(data, data_len); - - RETVAL = newSVpvn(NULL, 0); /* undef */ + if (ix == 1) { + hash_id = _find_hash(hash_name); + if (hash_id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); + rv = hash_memory(hash_id, data_ptr, (unsigned long)data_len, tmp, &tmp_len); + if (rv != CRYPT_OK) croak("FATAL: hash_memory failed: %s", error_to_string(rv)); + data_ptr = tmp; + data_len = tmp_len; + } if (strnEQ(padding, "pss", 3)) { - hash_id = find_hash(hash_name); + hash_id = _find_hash(hash_name); if (hash_id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); rv = rsa_sign_hash_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, LTC_PKCS_1_PSS, &self->pstate, self->pindex, @@ -405,7 +414,7 @@ _sign(Crypt::PK::RSA self, SV * data, char * padding, char * hash_name=NULL, uns RETVAL = newSVpvn((char*)buffer, buffer_len); } else if (strnEQ(padding, "v1.5", 4)) { - hash_id = find_hash(hash_name); + hash_id = _find_hash(hash_name); if (hash_id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); rv = rsa_sign_hash_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, LTC_PKCS_1_V1_5, &self->pstate, self->pindex, @@ -427,31 +436,37 @@ _sign(Crypt::PK::RSA self, SV * data, char * padding, char * hash_name=NULL, uns RETVAL int -_verify(Crypt::PK::RSA self, SV * sig, SV * data, char * padding, char * hash_name=NULL, unsigned long saltlen=12) +verify_hash(Crypt::PK::RSA self, SV * sig, SV * data, const char * hash_name = "SHA1", const char * padding = "pss", unsigned long saltlen = 12) + ALIAS: + verify_message = 1 CODE: { int rv, hash_id, stat; - unsigned char *data_ptr=NULL; - STRLEN data_len=0; - unsigned char *sig_ptr=NULL; - STRLEN sig_len=0; - unsigned char buffer[1024]; - unsigned long i, buffer_len = 1024; + unsigned char tmp[MAXBLOCKSIZE], buffer[1024], *data_ptr = NULL, *sig_ptr = NULL; + unsigned long i, tmp_len = MAXBLOCKSIZE, buffer_len = 1024; + STRLEN data_len = 0, sig_len = 0; data_ptr = (unsigned char *)SvPVbyte(data, data_len); sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len); - + if (ix == 1) { + hash_id = _find_hash(hash_name); + if (hash_id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); + rv = hash_memory(hash_id, data_ptr, (unsigned long)data_len, tmp, &tmp_len); + if (rv != CRYPT_OK) croak("FATAL: hash_memory failed: %s", error_to_string(rv)); + data_ptr = tmp; + data_len = tmp_len; + } RETVAL = 1; stat = 0; if (strnEQ(padding, "pss", 3)) { - hash_id = find_hash(hash_name); + hash_id = _find_hash(hash_name); if (hash_id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); rv = rsa_verify_hash_ex(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, LTC_PKCS_1_PSS, hash_id, saltlen, &stat, &self->key); if (rv != CRYPT_OK || stat != 1) RETVAL = 0; } else if (strnEQ(padding, "v1.5", 4)) { - hash_id = find_hash(hash_name); + hash_id = _find_hash(hash_name); if (hash_id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); rv = rsa_verify_hash_ex(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, LTC_PKCS_1_V1_5, hash_id, 0, &stat, &self->key); diff --git a/inc/CryptX_PRNG.xs.inc b/inc/CryptX_PRNG.xs.inc index 192f1f6e..93453119 100644 --- a/inc/CryptX_PRNG.xs.inc +++ b/inc/CryptX_PRNG.xs.inc @@ -1,23 +1,35 @@ MODULE = CryptX PACKAGE = Crypt::PRNG +PROTOTYPES: DISABLE + Crypt::PRNG -_new(IV curpid, char * prng_name, SV * entropy=&PL_sv_undef) +new(char * class, ...) CODE: { - int rv, id; + IV curpid = (IV)PerlProc_getpid(); + int rv, id, idx; unsigned char *ent=NULL; STRLEN ent_len=0; unsigned char entropy_buf[40]; + char *prng_name = (char *)"ChaCha20"; + SV *entropy = &PL_sv_undef; + + /* we need to handle: + Crypt::PRNG->new('RC4'); + Crypt::Cipher::RC4->new(); + */ + idx = strcmp("Crypt::PRNG", class) == 0 ? 1 : 0; + if (idx + 1 <= items) prng_name = SvPVX(ST(idx)); + if (idx + 2 <= items) entropy = ST(idx + 1); Newz(0, RETVAL, 1, struct prng_struct); if (!RETVAL) croak("FATAL: Newz failed"); - id = find_prng(prng_name); + id = _find_prng(prng_name); if (id == -1) { Safefree(RETVAL); croak("FATAL: find_prng failed for '%s'", prng_name); } - RETVAL->id = id; RETVAL->last_pid = curpid; RETVAL->desc = &prng_descriptor[id]; @@ -58,9 +70,7 @@ _new(IV curpid, char * prng_name, SV * entropy=&PL_sv_undef) void DESTROY(Crypt::PRNG self) CODE: - { Safefree(self); - } void add_entropy(Crypt::PRNG self, SV * entropy=&PL_sv_undef) @@ -85,37 +95,89 @@ add_entropy(Crypt::PRNG self, SV * entropy=&PL_sv_undef) } SV * -_bytes(Crypt::PRNG self, IV curpid, STRLEN output_len) +bytes(Crypt::PRNG self, unsigned long output_len) + ALIAS: + bytes_hex = 1 + bytes_b64 = 2 + bytes_b64u = 3 CODE: { - int rv_len; - unsigned char *rdata; + IV curpid = (IV)PerlProc_getpid(); + int rv_len, rv; + unsigned long len; + unsigned char *rdata, *tmp; unsigned char entropy_buf[40]; - if (self->last_pid != curpid) { - if (rng_get_bytes(entropy_buf, 40, NULL) != 40) croak("FATAL: rng_get_bytes failed"); - self->desc->add_entropy(entropy_buf, 40, &self->state); - self->desc->ready(&self->state); - self->last_pid = curpid; + if (output_len == 0) { + RETVAL = newSVpvn("", 0); } - - RETVAL = NEWSV(0, output_len); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, output_len); - rdata = (unsigned char *)SvPVX(RETVAL); - rv_len = (self->desc->read)(rdata, (unsigned long)output_len, &self->state); - if ((UV)rv_len != output_len) { - SvREFCNT_dec(RETVAL); - croak("FATAL: PRNG_read failed"); + else { + if (self->last_pid != curpid) { + if (rng_get_bytes(entropy_buf, 40, NULL) != 40) croak("FATAL: rng_get_bytes failed"); + self->desc->add_entropy(entropy_buf, 40, &self->state); + self->desc->ready(&self->state); + self->last_pid = curpid; + } + if (ix == 1) { + /* HEX */ + Newz(0, tmp, output_len, unsigned char); + if (tmp == NULL) croak("FATAL: Newz failed"); + rv_len = (self->desc->read)(tmp, (unsigned long)output_len, &self->state); + if ((UV)rv_len != output_len) croak("FATAL: PRNG_read failed"); + RETVAL = NEWSV(0, output_len * 2); /* avoid zero! */ + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, output_len * 2); + rdata = (unsigned char *)SvPVX(RETVAL); + len = output_len * 2; + rv = _base16_encode(tmp, output_len, rdata, &len); + Safefree(tmp); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: base16_encode failed"); + } + } + else if (ix == 2 || ix == 3) { + /* BASE64 or BASE64URL */ + Newz(0, tmp, output_len, unsigned char); + if (tmp == NULL) croak("FATAL: Newz failed"); + rv_len = (self->desc->read)(tmp, (unsigned long)output_len, &self->state); + if ((UV)rv_len != output_len) croak("FATAL: PRNG_read failed"); + RETVAL = NEWSV(0, output_len * 2); /* avoid zero! */ + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, output_len * 2); + rdata = (unsigned char *)SvPVX(RETVAL); + len = output_len * 2; + rv = ix == 3 ? base64url_encode(tmp, output_len, rdata, &len) : + base64_encode(tmp, output_len, rdata, &len); + SvCUR_set(RETVAL, len); + Safefree(tmp); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak(ix == 3 ? "FATAL: base64url_encode failed" : "FATAL: base64_encode failed"); + } + } + else { + /* RAW BYTES */ + RETVAL = NEWSV(0, output_len); /* avoid zero! */ + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, output_len); + rdata = (unsigned char *)SvPVX(RETVAL); + rv_len = (self->desc->read)(rdata, (unsigned long)output_len, &self->state); + if ((UV)rv_len != output_len) { + SvREFCNT_dec(RETVAL); + croak("FATAL: PRNG_read failed"); + } + } } } OUTPUT: RETVAL UV -_int32(Crypt::PRNG self, IV curpid) +int32(Crypt::PRNG self) CODE: { + IV curpid = (IV)PerlProc_getpid(); int i; unsigned char rdata[4]; unsigned char entropy_buf[40]; @@ -135,14 +197,14 @@ _int32(Crypt::PRNG self, IV curpid) RETVAL NV -_double(Crypt::PRNG self, IV curpid, ...) +double(Crypt::PRNG self, SV * limit_sv = NULL) CODE: { + IV curpid = (IV)PerlProc_getpid(); int i; unsigned long a, b; /* 32bit is enough */ unsigned char rdata[7]; /* for double we need 53 bits */ unsigned char entropy_buf[40]; - NV limit; if (self->last_pid != curpid) { if (rng_get_bytes(entropy_buf, 40, NULL) != 40) croak("FATAL: rng_get_bytes failed"); @@ -156,8 +218,8 @@ _double(Crypt::PRNG self, IV curpid, ...) a = (((unsigned long)(rdata[0])<<16) + ((unsigned long)(rdata[1])<<8) + ((unsigned long)(rdata[2]))) & 0x1FFFFF; /* 21 bits */ b = ((unsigned long)(rdata[3])<<24) + ((unsigned long)(rdata[4])<<16) + ((unsigned long)(rdata[5])<<8) + ((unsigned long)(rdata[6])); /* 32 bits */ RETVAL = ( (NV)a * 4294967296.0 + (NV)b ) / 9007199254740992.0; /* (a * 2^32 + b) / 2^53 */ - if (items>2 && SvOK(ST(2))) { - limit = SvNV(ST(2)); + if (limit_sv && SvOK(limit_sv)) { + NV limit = SvNV(limit_sv); if (limit > 0 || limit < 0) RETVAL = RETVAL * limit; } } diff --git a/inc/CryptX_Stream_ChaCha.xs.inc b/inc/CryptX_Stream_ChaCha.xs.inc index 4b71a090..e1287b64 100644 --- a/inc/CryptX_Stream_ChaCha.xs.inc +++ b/inc/CryptX_Stream_ChaCha.xs.inc @@ -1,5 +1,7 @@ MODULE = CryptX PACKAGE = Crypt::Stream::ChaCha +PROTOTYPES: DISABLE + Crypt::Stream::ChaCha new(Class, SV * key, SV * nonce, UV counter = 0, int rounds = 20) CODE: @@ -13,24 +15,24 @@ new(Class, SV * key, SV * nonce, UV counter = 0, int rounds = 20) k = (unsigned char *) SvPVbyte(key, k_len); iv = (unsigned char *) SvPVbyte(nonce, iv_len); - Newz(0, RETVAL, 1, struct chacha_struct); + Newz(0, RETVAL, 1, chacha_state); if (!RETVAL) croak("FATAL: Newz failed"); - rv = chacha_setup(&RETVAL->state, k, (unsigned long)k_len, rounds); + rv = chacha_setup(RETVAL, k, (unsigned long)k_len, rounds); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: chacha_setup failed: %s", error_to_string(rv)); } if (iv_len == 12) { - rv = chacha_ivctr32(&RETVAL->state, iv, (unsigned long)iv_len, (ulong32)counter); + rv = chacha_ivctr32(RETVAL, iv, (unsigned long)iv_len, (ulong32)counter); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: chacha_ivctr32 failed: %s", error_to_string(rv)); } } else if (iv_len == 8) { - rv = chacha_ivctr64(&RETVAL->state, iv, (unsigned long)iv_len, (ulong64)counter); + rv = chacha_ivctr64(RETVAL, iv, (unsigned long)iv_len, (ulong64)counter); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: chacha_ivctr64 failed: %s", error_to_string(rv)); @@ -47,15 +49,15 @@ new(Class, SV * key, SV * nonce, UV counter = 0, int rounds = 20) void DESTROY(Crypt::Stream::ChaCha self) CODE: - chacha_done(&self->state); + chacha_done(self); Safefree(self); Crypt::Stream::ChaCha clone(Crypt::Stream::ChaCha self) CODE: - Newz(0, RETVAL, 1, struct chacha_struct); + Newz(0, RETVAL, 1, chacha_state); if (!RETVAL) croak("FATAL: Newz failed"); - Copy(&self->state, &RETVAL->state, 1, struct chacha_struct); + Copy(self, RETVAL, 1, chacha_state); OUTPUT: RETVAL @@ -66,14 +68,19 @@ keystream(Crypt::Stream::ChaCha self, STRLEN out_len) int rv; unsigned char *out_data; - RETVAL = NEWSV(0, out_len); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, out_len); - out_data = (unsigned char *)SvPVX(RETVAL); - rv = chacha_keystream(&self->state, out_data, (unsigned long)out_len); - if (rv != CRYPT_OK) { - SvREFCNT_dec(RETVAL); - croak("FATAL: chacha_keystream failed: %s", error_to_string(rv)); + if (out_len == 0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, out_len); /* avoid zero! */ + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, out_len); + out_data = (unsigned char *)SvPVX(RETVAL); + rv = chacha_keystream(self, out_data, (unsigned long)out_len); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: chacha_keystream failed: %s", error_to_string(rv)); + } } } OUTPUT: @@ -92,11 +99,11 @@ crypt(Crypt::Stream::ChaCha self, SV * data) RETVAL = newSVpvn("", 0); } else { - RETVAL = NEWSV(0, in_data_len); + RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, in_data_len); out_data = (unsigned char *)SvPVX(RETVAL); - rv = chacha_crypt(&self->state, in_data, (unsigned long)in_data_len, out_data); + rv = chacha_crypt(self, in_data, (unsigned long)in_data_len, out_data); if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); croak("FATAL: chacha_crypt failed: %s", error_to_string(rv)); diff --git a/inc/CryptX_Stream_RC4.xs.inc b/inc/CryptX_Stream_RC4.xs.inc index 09a56147..eb48b90e 100644 --- a/inc/CryptX_Stream_RC4.xs.inc +++ b/inc/CryptX_Stream_RC4.xs.inc @@ -1,5 +1,7 @@ MODULE = CryptX PACKAGE = Crypt::Stream::RC4 +PROTOTYPES: DISABLE + Crypt::Stream::RC4 new(Class, SV * key) CODE: @@ -11,10 +13,10 @@ new(Class, SV * key) if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); k = (unsigned char *) SvPVbyte(key, k_len); - Newz(0, RETVAL, 1, struct rc4_struct); + Newz(0, RETVAL, 1, rc4_state); if (!RETVAL) croak("FATAL: Newz failed"); - rv = rc4_stream_setup(&RETVAL->state, k, (unsigned long)k_len); + rv = rc4_stream_setup(RETVAL, k, (unsigned long)k_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: rc4_stream_setup failed: %s", error_to_string(rv)); @@ -26,15 +28,15 @@ new(Class, SV * key) void DESTROY(Crypt::Stream::RC4 self) CODE: - rc4_stream_done(&self->state); + rc4_stream_done(self); Safefree(self); Crypt::Stream::RC4 clone(Crypt::Stream::RC4 self) CODE: - Newz(0, RETVAL, 1, struct rc4_struct); + Newz(0, RETVAL, 1, rc4_state); if (!RETVAL) croak("FATAL: Newz failed"); - Copy(&self->state, &RETVAL->state, 1, struct rc4_struct); + Copy(self, RETVAL, 1, rc4_state); OUTPUT: RETVAL @@ -45,14 +47,19 @@ keystream(Crypt::Stream::RC4 self, STRLEN out_len) int rv; unsigned char *out_data; - RETVAL = NEWSV(0, out_len); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, out_len); - out_data = (unsigned char *)SvPVX(RETVAL); - rv = rc4_stream_keystream(&self->state, out_data, (unsigned long)out_len); - if (rv != CRYPT_OK) { - SvREFCNT_dec(RETVAL); - croak("FATAL: rc4_stream_keystream failed: %s", error_to_string(rv)); + if (out_len == 0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, out_len); /* avoid zero! */ + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, out_len); + out_data = (unsigned char *)SvPVX(RETVAL); + rv = rc4_stream_keystream(self, out_data, (unsigned long)out_len); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: rc4_stream_keystream failed: %s", error_to_string(rv)); + } } } OUTPUT: @@ -71,11 +78,11 @@ crypt(Crypt::Stream::RC4 self, SV * data) RETVAL = newSVpvn("", 0); } else { - RETVAL = NEWSV(0, in_data_len); + RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, in_data_len); out_data = (unsigned char *)SvPVX(RETVAL); - rv = rc4_stream_crypt(&self->state, in_data, (unsigned long)in_data_len, out_data); + rv = rc4_stream_crypt(self, in_data, (unsigned long)in_data_len, out_data); if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); croak("FATAL: rc4_stream_crypt failed: %s", error_to_string(rv)); diff --git a/inc/CryptX_Stream_Rabbit.xs.inc b/inc/CryptX_Stream_Rabbit.xs.inc index 6ef18249..fe083bc4 100644 --- a/inc/CryptX_Stream_Rabbit.xs.inc +++ b/inc/CryptX_Stream_Rabbit.xs.inc @@ -1,5 +1,7 @@ MODULE = CryptX PACKAGE = Crypt::Stream::Rabbit +PROTOTYPES: DISABLE + Crypt::Stream::Rabbit new(Class, SV * key, SV * nonce=&PL_sv_undef) CODE: @@ -11,10 +13,10 @@ new(Class, SV * key, SV * nonce=&PL_sv_undef) if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); k = (unsigned char *)SvPVbyte(key, k_len); - Newz(0, RETVAL, 1, struct rabbit_struct); + Newz(0, RETVAL, 1, rabbit_state); if (!RETVAL) croak("FATAL: Newz failed"); - rv = rabbit_setup(&RETVAL->state, k, (unsigned long)k_len); + rv = rabbit_setup(RETVAL, k, (unsigned long)k_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: rabbit_setup failed: %s", error_to_string(rv)); @@ -23,7 +25,7 @@ new(Class, SV * key, SV * nonce=&PL_sv_undef) if (SvOK(nonce)) { if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar"); iv = (unsigned char *)SvPVbyte(nonce, iv_len); - rv = rabbit_setiv(&RETVAL->state, iv, (unsigned long)iv_len); + rv = rabbit_setiv(RETVAL, iv, (unsigned long)iv_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: rabbit_setiv failed: %s", error_to_string(rv)); @@ -37,15 +39,15 @@ new(Class, SV * key, SV * nonce=&PL_sv_undef) void DESTROY(Crypt::Stream::Rabbit self) CODE: - rabbit_done(&self->state); + rabbit_done(self); Safefree(self); Crypt::Stream::Rabbit clone(Crypt::Stream::Rabbit self) CODE: - Newz(0, RETVAL, 1, struct rabbit_struct); + Newz(0, RETVAL, 1, rabbit_state); if (!RETVAL) croak("FATAL: Newz failed"); - Copy(&self->state, &RETVAL->state, 1, struct rabbit_struct); + Copy(self, RETVAL, 1, rabbit_state); OUTPUT: RETVAL @@ -56,14 +58,19 @@ keystream(Crypt::Stream::Rabbit self, STRLEN out_len) int rv; unsigned char *out_data; - RETVAL = NEWSV(0, out_len); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, out_len); - out_data = (unsigned char *)SvPVX(RETVAL); - rv = rabbit_keystream(&self->state, out_data, (unsigned long)out_len); - if (rv != CRYPT_OK) { - SvREFCNT_dec(RETVAL); - croak("FATAL: rabbit_keystream failed: %s", error_to_string(rv)); + if (out_len == 0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, out_len); /* avoid zero! */ + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, out_len); + out_data = (unsigned char *)SvPVX(RETVAL); + rv = rabbit_keystream(self, out_data, (unsigned long)out_len); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: rabbit_keystream failed: %s", error_to_string(rv)); + } } } OUTPUT: @@ -82,11 +89,11 @@ crypt(Crypt::Stream::Rabbit self, SV * data) RETVAL = newSVpvn("", 0); } else { - RETVAL = NEWSV(0, in_data_len); + RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, in_data_len); out_data = (unsigned char *)SvPVX(RETVAL); - rv = rabbit_crypt(&self->state, in_data, (unsigned long)in_data_len, out_data); + rv = rabbit_crypt(self, in_data, (unsigned long)in_data_len, out_data); if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); croak("FATAL: rabbit_crypt failed: %s", error_to_string(rv)); diff --git a/inc/CryptX_Stream_Salsa20.xs.inc b/inc/CryptX_Stream_Salsa20.xs.inc index 7430c3dc..65c0d580 100644 --- a/inc/CryptX_Stream_Salsa20.xs.inc +++ b/inc/CryptX_Stream_Salsa20.xs.inc @@ -1,5 +1,7 @@ MODULE = CryptX PACKAGE = Crypt::Stream::Salsa20 +PROTOTYPES: DISABLE + Crypt::Stream::Salsa20 new(Class, SV * key, SV * nonce, UV counter = 0, int rounds = 20) CODE: @@ -13,16 +15,16 @@ new(Class, SV * key, SV * nonce, UV counter = 0, int rounds = 20) k = (unsigned char *)SvPVbyte(key, k_len); iv = (unsigned char *)SvPVbyte(nonce, iv_len); - Newz(0, RETVAL, 1, struct salsa20_struct); + Newz(0, RETVAL, 1, salsa20_state); if (!RETVAL) croak("FATAL: Newz failed"); - rv = salsa20_setup(&RETVAL->state, k, (unsigned long)k_len, rounds); + rv = salsa20_setup(RETVAL, k, (unsigned long)k_len, rounds); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: salsa20_setup failed: %s", error_to_string(rv)); } - rv = salsa20_ivctr64(&RETVAL->state, iv, (unsigned long)iv_len, (ulong64)counter); + rv = salsa20_ivctr64(RETVAL, iv, (unsigned long)iv_len, (ulong64)counter); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: salsa20_ivctr64 failed: %s", error_to_string(rv)); @@ -34,15 +36,15 @@ new(Class, SV * key, SV * nonce, UV counter = 0, int rounds = 20) void DESTROY(Crypt::Stream::Salsa20 self) CODE: - salsa20_done(&self->state); + salsa20_done(self); Safefree(self); Crypt::Stream::Salsa20 clone(Crypt::Stream::Salsa20 self) CODE: - Newz(0, RETVAL, 1, struct salsa20_struct); + Newz(0, RETVAL, 1, salsa20_state); if (!RETVAL) croak("FATAL: Newz failed"); - Copy(&self->state, &RETVAL->state, 1, struct salsa20_struct); + Copy(self, RETVAL, 1, salsa20_state); OUTPUT: RETVAL @@ -53,14 +55,19 @@ keystream(Crypt::Stream::Salsa20 self, STRLEN out_len) int rv; unsigned char *out_data; - RETVAL = NEWSV(0, out_len); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, out_len); - out_data = (unsigned char *)SvPVX(RETVAL); - rv = salsa20_keystream(&self->state, out_data, (unsigned long)out_len); - if (rv != CRYPT_OK) { - SvREFCNT_dec(RETVAL); - croak("FATAL: salsa20_keystream failed: %s", error_to_string(rv)); + if (out_len == 0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, out_len); /* avoid zero! */ + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, out_len); + out_data = (unsigned char *)SvPVX(RETVAL); + rv = salsa20_keystream(self, out_data, (unsigned long)out_len); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: salsa20_keystream failed: %s", error_to_string(rv)); + } } } OUTPUT: @@ -79,11 +86,11 @@ crypt(Crypt::Stream::Salsa20 self, SV * data) RETVAL = newSVpvn("", 0); } else { - RETVAL = NEWSV(0, in_data_len); + RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, in_data_len); out_data = (unsigned char *)SvPVX(RETVAL); - rv = salsa20_crypt(&self->state, in_data, (unsigned long)in_data_len, out_data); + rv = salsa20_crypt(self, in_data, (unsigned long)in_data_len, out_data); if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); croak("FATAL: salsa20_crypt failed: %s", error_to_string(rv)); diff --git a/inc/CryptX_Stream_Sober128.xs.inc b/inc/CryptX_Stream_Sober128.xs.inc index 7802bb16..5e03ba4f 100644 --- a/inc/CryptX_Stream_Sober128.xs.inc +++ b/inc/CryptX_Stream_Sober128.xs.inc @@ -1,5 +1,7 @@ MODULE = CryptX PACKAGE = Crypt::Stream::Sober128 +PROTOTYPES: DISABLE + Crypt::Stream::Sober128 new(Class, SV * key, SV * nonce) CODE: @@ -13,16 +15,16 @@ new(Class, SV * key, SV * nonce) k = (unsigned char *) SvPVbyte(key, k_len); iv = (unsigned char *) SvPVbyte(nonce, iv_len); - Newz(0, RETVAL, 1, struct sober128_struct); + Newz(0, RETVAL, 1, sober128_state); if (!RETVAL) croak("FATAL: Newz failed"); - rv = sober128_stream_setup(&RETVAL->state, k, (unsigned long)k_len); + rv = sober128_stream_setup(RETVAL, k, (unsigned long)k_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: sober128_stream_setup failed: %s", error_to_string(rv)); } - rv = sober128_stream_setiv(&RETVAL->state, iv, (unsigned long)iv_len); + rv = sober128_stream_setiv(RETVAL, iv, (unsigned long)iv_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: sober128_stream_setiv failed: %s", error_to_string(rv)); @@ -34,15 +36,15 @@ new(Class, SV * key, SV * nonce) void DESTROY(Crypt::Stream::Sober128 self) CODE: - sober128_stream_done(&self->state); + sober128_stream_done(self); Safefree(self); Crypt::Stream::Sober128 clone(Crypt::Stream::Sober128 self) CODE: - Newz(0, RETVAL, 1, struct sober128_struct); + Newz(0, RETVAL, 1, sober128_state); if (!RETVAL) croak("FATAL: Newz failed"); - Copy(&self->state, &RETVAL->state, 1, struct sober128_struct); + Copy(self, RETVAL, 1, sober128_state); OUTPUT: RETVAL @@ -53,14 +55,19 @@ keystream(Crypt::Stream::Sober128 self, STRLEN out_len) int rv; unsigned char *out_data; - RETVAL = NEWSV(0, out_len); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, out_len); - out_data = (unsigned char *)SvPVX(RETVAL); - rv = sober128_stream_keystream(&self->state, out_data, (unsigned long)out_len); - if (rv != CRYPT_OK) { - SvREFCNT_dec(RETVAL); - croak("FATAL: sober128_stream_keystream failed: %s", error_to_string(rv)); + if (out_len == 0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, out_len); /* avoid zero! */ + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, out_len); + out_data = (unsigned char *)SvPVX(RETVAL); + rv = sober128_stream_keystream(self, out_data, (unsigned long)out_len); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: sober128_stream_keystream failed: %s", error_to_string(rv)); + } } } OUTPUT: @@ -79,11 +86,11 @@ crypt(Crypt::Stream::Sober128 self, SV * data) RETVAL = newSVpvn("", 0); } else { - RETVAL = NEWSV(0, in_data_len); + RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, in_data_len); out_data = (unsigned char *)SvPVX(RETVAL); - rv = sober128_stream_crypt(&self->state, in_data, (unsigned long)in_data_len, out_data); + rv = sober128_stream_crypt(self, in_data, (unsigned long)in_data_len, out_data); if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); croak("FATAL: sober128_stream_crypt failed: %s", error_to_string(rv)); diff --git a/inc/CryptX_Stream_Sosemanuk.xs.inc b/inc/CryptX_Stream_Sosemanuk.xs.inc index 2f46859d..da5fcfb5 100644 --- a/inc/CryptX_Stream_Sosemanuk.xs.inc +++ b/inc/CryptX_Stream_Sosemanuk.xs.inc @@ -1,5 +1,7 @@ MODULE = CryptX PACKAGE = Crypt::Stream::Sosemanuk +PROTOTYPES: DISABLE + Crypt::Stream::Sosemanuk new(Class, SV * key, SV * nonce=&PL_sv_undef) CODE: @@ -11,10 +13,10 @@ new(Class, SV * key, SV * nonce=&PL_sv_undef) if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); k = (unsigned char *)SvPVbyte(key, k_len); - Newz(0, RETVAL, 1, struct sosemanuk_struct); + Newz(0, RETVAL, 1, sosemanuk_state); if (!RETVAL) croak("FATAL: Newz failed"); - rv = sosemanuk_setup(&RETVAL->state, k, (unsigned long)k_len); + rv = sosemanuk_setup(RETVAL, k, (unsigned long)k_len); if (rv != CRYPT_OK) { Safefree(RETVAL); croak("FATAL: sosemanuk_setup failed: %s", error_to_string(rv)); @@ -23,10 +25,10 @@ new(Class, SV * key, SV * nonce=&PL_sv_undef) if (SvOK(nonce)) { if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar"); iv = (unsigned char *)SvPVbyte(nonce, iv_len); - rv = sosemanuk_setiv(&RETVAL->state, iv, (unsigned long)iv_len); + rv = sosemanuk_setiv(RETVAL, iv, (unsigned long)iv_len); } else { - rv = sosemanuk_setiv(&RETVAL->state, NULL, 0); + rv = sosemanuk_setiv(RETVAL, NULL, 0); } if (rv != CRYPT_OK) { Safefree(RETVAL); @@ -40,15 +42,15 @@ new(Class, SV * key, SV * nonce=&PL_sv_undef) void DESTROY(Crypt::Stream::Sosemanuk self) CODE: - sosemanuk_done(&self->state); + sosemanuk_done(self); Safefree(self); Crypt::Stream::Sosemanuk clone(Crypt::Stream::Sosemanuk self) CODE: - Newz(0, RETVAL, 1, struct sosemanuk_struct); + Newz(0, RETVAL, 1, sosemanuk_state); if (!RETVAL) croak("FATAL: Newz failed"); - Copy(&self->state, &RETVAL->state, 1, struct sosemanuk_struct); + Copy(self, RETVAL, 1, sosemanuk_state); OUTPUT: RETVAL @@ -59,14 +61,19 @@ keystream(Crypt::Stream::Sosemanuk self, STRLEN out_len) int rv; unsigned char *out_data; - RETVAL = NEWSV(0, out_len); - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, out_len); - out_data = (unsigned char *)SvPVX(RETVAL); - rv = sosemanuk_keystream(&self->state, out_data, (unsigned long)out_len); - if (rv != CRYPT_OK) { - SvREFCNT_dec(RETVAL); - croak("FATAL: sosemanuk_keystream failed: %s", error_to_string(rv)); + if (out_len == 0) { + RETVAL = newSVpvn("", 0); + } + else { + RETVAL = NEWSV(0, out_len); /* avoid zero! */ + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, out_len); + out_data = (unsigned char *)SvPVX(RETVAL); + rv = sosemanuk_keystream(self, out_data, (unsigned long)out_len); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: sosemanuk_keystream failed: %s", error_to_string(rv)); + } } } OUTPUT: @@ -85,11 +92,11 @@ crypt(Crypt::Stream::Sosemanuk self, SV * data) RETVAL = newSVpvn("", 0); } else { - RETVAL = NEWSV(0, in_data_len); + RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ SvPOK_only(RETVAL); SvCUR_set(RETVAL, in_data_len); out_data = (unsigned char *)SvPVX(RETVAL); - rv = sosemanuk_crypt(&self->state, in_data, (unsigned long)in_data_len, out_data); + rv = sosemanuk_crypt(self, in_data, (unsigned long)in_data_len, out_data); if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); croak("FATAL: sosemanuk_crypt failed: %s", error_to_string(rv)); diff --git a/lib/Crypt/AuthEnc.pm b/lib/Crypt/AuthEnc.pm index 78ce6cb1..359f3244 100644 --- a/lib/Crypt/AuthEnc.pm +++ b/lib/Crypt/AuthEnc.pm @@ -2,9 +2,9 @@ package Crypt::AuthEnc; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -sub CLONE_SKIP { 1 } # prevent cloning +### not used 1; diff --git a/lib/Crypt/AuthEnc/CCM.pm b/lib/Crypt/AuthEnc/CCM.pm index 57b60d02..15673c5d 100644 --- a/lib/Crypt/AuthEnc/CCM.pm +++ b/lib/Crypt/AuthEnc/CCM.pm @@ -2,9 +2,9 @@ package Crypt::AuthEnc::CCM; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use base qw(Crypt::AuthEnc Exporter); +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; our %EXPORT_TAGS = ( all => [qw( ccm_encrypt_authenticate ccm_decrypt_verify )] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); @@ -12,50 +12,8 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; use CryptX; -use Crypt::Cipher; - -sub new { - my $class = shift; - local $SIG{__DIE__} = \&CryptX::_croak; - return _new(Crypt::Cipher::_trans_cipher_name(shift), @_); -} - -sub ccm_encrypt_authenticate { - my $cipher_name = shift; - my $key = shift; - my $iv = shift; - my $adata = shift; - my $tag_len = shift; - my $plaintext = shift; - - $iv = "" if !defined $iv; - $adata = "" if !defined $adata; - $plaintext = "" if !defined $plaintext; - - local $SIG{__DIE__} = \&CryptX::_croak; - my $m = Crypt::AuthEnc::CCM->new($cipher_name, $key, $iv, $adata, $tag_len, length($plaintext)); - my $ct = $m->encrypt_add($plaintext); - my $tag = $m->encrypt_done(); - return ($ct, $tag); -} - -sub ccm_decrypt_verify { - my $cipher_name = shift; - my $key = shift; - my $iv = shift; - my $adata = shift; - my $ciphertext = shift; - my $tag = shift; - - $iv = "" if !defined $iv; - $adata = "" if !defined $adata; - $ciphertext = "" if !defined $ciphertext; - - local $SIG{__DIE__} = \&CryptX::_croak; - my $m = Crypt::AuthEnc::CCM->new($cipher_name, $key, $iv, $adata, length($tag), length($ciphertext)); - my $pt = $m->decrypt_add($ciphertext); - return $m->decrypt_done($tag) ? $pt : undef; -} + +sub CLONE_SKIP { 1 } # prevent cloning 1; diff --git a/lib/Crypt/AuthEnc/ChaCha20Poly1305.pm b/lib/Crypt/AuthEnc/ChaCha20Poly1305.pm index fe351023..104e2422 100644 --- a/lib/Crypt/AuthEnc/ChaCha20Poly1305.pm +++ b/lib/Crypt/AuthEnc/ChaCha20Poly1305.pm @@ -2,9 +2,9 @@ package Crypt::AuthEnc::ChaCha20Poly1305; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use base qw(Crypt::AuthEnc Exporter); +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; our %EXPORT_TAGS = ( all => [qw( chacha20poly1305_encrypt_authenticate chacha20poly1305_decrypt_verify )] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); @@ -13,39 +13,7 @@ use Carp; $Carp::Internal{(__PACKAGE__)}++; use CryptX; -sub new { - my $class = shift; - local $SIG{__DIE__} = \&CryptX::_croak; - return _new(@_); -} - -sub chacha20poly1305_encrypt_authenticate { - my $key = shift; - my $iv = shift; - my $adata = shift; - my $plaintext = shift; - - local $SIG{__DIE__} = \&CryptX::_croak; - my $m = Crypt::AuthEnc::ChaCha20Poly1305->new($key, $iv); - $m->adata_add(defined $adata ? $adata : ''); #XXX-TODO if no aad we have to pass empty string - my $ct = $m->encrypt_add($plaintext); - my $tag = $m->encrypt_done; - return ($ct, $tag); -} - -sub chacha20poly1305_decrypt_verify { - my $key = shift; - my $iv = shift; - my $adata = shift; - my $ciphertext = shift; - my $tag = shift; - - local $SIG{__DIE__} = \&CryptX::_croak; - my $m = Crypt::AuthEnc::ChaCha20Poly1305->new($key, $iv); - $m->adata_add(defined $adata ? $adata : ''); #XXX-TODO if no aad we have to pass empty string - my $ct = $m->decrypt_add($ciphertext); - return $m->decrypt_done($tag) ? $ct : undef; -} +sub CLONE_SKIP { 1 } # prevent cloning 1; diff --git a/lib/Crypt/AuthEnc/EAX.pm b/lib/Crypt/AuthEnc/EAX.pm index 88552be3..6aad5b6d 100644 --- a/lib/Crypt/AuthEnc/EAX.pm +++ b/lib/Crypt/AuthEnc/EAX.pm @@ -2,9 +2,9 @@ package Crypt::AuthEnc::EAX; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use base qw(Crypt::AuthEnc Exporter); +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; our %EXPORT_TAGS = ( all => [qw( eax_encrypt_authenticate eax_decrypt_verify )] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); @@ -12,58 +12,13 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; use CryptX; -use Crypt::Cipher; - -### the following methods/functions are implemented in XS: -# - _new -# - DESTROY -# - clone -# - encrypt_add -# - encrypt_done -# - decrypt_add -# - decrypt_done -# - adata_add - -sub new { - my $class = shift; - local $SIG{__DIE__} = \&CryptX::_croak; - return _new(Crypt::Cipher::_trans_cipher_name(shift), @_); -} - -sub eax_encrypt_authenticate { - my $cipher_name = shift; - my $key = shift; - my $iv = shift; - my $adata = shift; - my $plaintext = shift; - - local $SIG{__DIE__} = \&CryptX::_croak; - my $m = Crypt::AuthEnc::EAX->new($cipher_name, $key, $iv); - $m->adata_add($adata) if defined $adata; - my $ct = $m->encrypt_add($plaintext); - my $tag = $m->encrypt_done; - return ($ct, $tag); -} - -sub eax_decrypt_verify { - my $cipher_name = shift; - my $key = shift; - my $iv = shift; - my $adata = shift; - my $ciphertext = shift; - my $tag = shift; - - local $SIG{__DIE__} = \&CryptX::_croak; - my $m = Crypt::AuthEnc::EAX->new($cipher_name, $key, $iv); - $m->adata_add($adata) if defined $adata; - my $ct = $m->decrypt_add($ciphertext); - return $m->decrypt_done($tag) ? $ct : undef; -} # obsolete, only for backwards compatibility sub header_add { goto &adata_add } sub aad_add { goto &adata_add } +sub CLONE_SKIP { 1 } # prevent cloning + 1; =pod diff --git a/lib/Crypt/AuthEnc/GCM.pm b/lib/Crypt/AuthEnc/GCM.pm index aa7ffba6..ba8ae8ba 100644 --- a/lib/Crypt/AuthEnc/GCM.pm +++ b/lib/Crypt/AuthEnc/GCM.pm @@ -2,9 +2,9 @@ package Crypt::AuthEnc::GCM; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use base qw(Crypt::AuthEnc Exporter); +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; our %EXPORT_TAGS = ( all => [qw( gcm_encrypt_authenticate gcm_decrypt_verify )] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); @@ -12,48 +12,8 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; use CryptX; -use Crypt::Cipher; - -sub new { - my ($class, $cipher, $key, $iv) = @_; - local $SIG{__DIE__} = \&CryptX::_croak; - my $self = _new(Crypt::Cipher::_trans_cipher_name($cipher), $key); - # for backwards compatibility the $iv is optional - $self->iv_add($iv) if defined $iv; - return $self; -} - -sub gcm_encrypt_authenticate { - my $cipher_name = shift; - my $key = shift; - my $iv = shift; - my $adata = shift; - my $plaintext = shift; - - local $SIG{__DIE__} = \&CryptX::_croak; - my $m = Crypt::AuthEnc::GCM->new($cipher_name, $key); - $m->iv_add($iv); - $m->adata_add(defined $adata ? $adata : ''); #XXX-TODO if no aad we have to pass empty string - my $ct = $m->encrypt_add($plaintext); - my $tag = $m->encrypt_done; - return ($ct, $tag); -} - -sub gcm_decrypt_verify { - my $cipher_name = shift; - my $key = shift; - my $iv = shift; - my $adata = shift; - my $ciphertext = shift; - my $tag = shift; - - local $SIG{__DIE__} = \&CryptX::_croak; - my $m = Crypt::AuthEnc::GCM->new($cipher_name, $key); - $m->iv_add($iv); - $m->adata_add(defined $adata ? $adata : ''); #XXX-TODO if no aad we have to pass empty string - my $ct = $m->decrypt_add($ciphertext); - return $m->decrypt_done($tag) ? $ct : undef; -} + +sub CLONE_SKIP { 1 } # prevent cloning 1; diff --git a/lib/Crypt/AuthEnc/OCB.pm b/lib/Crypt/AuthEnc/OCB.pm index 83f3076f..7f515c9b 100644 --- a/lib/Crypt/AuthEnc/OCB.pm +++ b/lib/Crypt/AuthEnc/OCB.pm @@ -2,9 +2,9 @@ package Crypt::AuthEnc::OCB; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use base qw(Crypt::AuthEnc Exporter); +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; our %EXPORT_TAGS = ( all => [qw( ocb_encrypt_authenticate ocb_decrypt_verify )] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); @@ -12,49 +12,13 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; use CryptX; -use Crypt::Cipher; - -sub new { - my $class = shift; - local $SIG{__DIE__} = \&CryptX::_croak; - return _new(Crypt::Cipher::_trans_cipher_name(shift), @_); -} - -sub ocb_encrypt_authenticate { - my $cipher_name = shift; - my $key = shift; - my $nonce = shift; - my $adata = shift; - my $tag_len = shift; - my $plaintext = shift; - - local $SIG{__DIE__} = \&CryptX::_croak; - my $m = Crypt::AuthEnc::OCB->new($cipher_name, $key, $nonce, $tag_len); - $m->adata_add($adata) if defined $adata; - my $ct = $m->encrypt_last($plaintext); - my $tag = $m->encrypt_done; - return ($ct, $tag); -} - -sub ocb_decrypt_verify { - my $cipher_name = shift; - my $key = shift; - my $nonce = shift; - my $adata = shift; - my $ciphertext = shift; - my $tag = shift; - - local $SIG{__DIE__} = \&CryptX::_croak; - my $m = Crypt::AuthEnc::OCB->new($cipher_name, $key, $nonce, length($tag)); - $m->adata_add($adata) if defined $adata; - my $ct = $m->decrypt_last($ciphertext); - return $m->decrypt_done($tag) ? $ct : undef; -} # obsolete, only for backwards compatibility sub aad_add { goto &adata_add } sub blocksize { return 16 } +sub CLONE_SKIP { 1 } # prevent cloning + 1; =pod diff --git a/lib/Crypt/Checksum.pm b/lib/Crypt/Checksum.pm index 2273afed..8d4d8c9c 100644 --- a/lib/Crypt/Checksum.pm +++ b/lib/Crypt/Checksum.pm @@ -2,34 +2,57 @@ package Crypt::Checksum; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; -our %EXPORT_TAGS = ( all => [qw/ - adler32_data adler32_data_hex adler32_data_int adler32_file adler32_file_hex adler32_file_int - crc32_data crc32_data_hex crc32_data_int crc32_file crc32_file_hex crc32_file_int - /] ); +our %EXPORT_TAGS = ( all => [qw/ adler32_data adler32_data_hex adler32_data_int adler32_file adler32_file_hex adler32_file_int + crc32_data crc32_data_hex crc32_data_int crc32_file crc32_file_hex crc32_file_int /] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; -use Crypt::Checksum::Adler32; -use Crypt::Checksum::CRC32; -sub adler32_data { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Checksum::Adler32->new->add(@_)->digest } -sub adler32_data_hex { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Checksum::Adler32->new->add(@_)->hexdigest } -sub adler32_data_int { local $SIG{__DIE__} = \&CryptX::_croak; unpack("N", Crypt::Checksum::Adler32->new->add(@_)->digest) } -sub adler32_file { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Checksum::Adler32->new->addfile(@_)->digest } -sub adler32_file_hex { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Checksum::Adler32->new->addfile(@_)->hexdigest } -sub adler32_file_int { local $SIG{__DIE__} = \&CryptX::_croak; unpack("N", Crypt::Checksum::Adler32->new->addfile(@_)->digest) } -sub crc32_data { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Checksum::CRC32->new->add(@_)->digest } -sub crc32_data_hex { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Checksum::CRC32->new->add(@_)->hexdigest } -sub crc32_data_int { local $SIG{__DIE__} = \&CryptX::_croak; unpack("N", Crypt::Checksum::CRC32->new->add(@_)->digest) } -sub crc32_file { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Checksum::CRC32->new->addfile(@_)->digest } -sub crc32_file_hex { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Checksum::CRC32->new->addfile(@_)->hexdigest } -sub crc32_file_int { local $SIG{__DIE__} = \&CryptX::_croak; unpack("N", Crypt::Checksum::CRC32->new->addfile(@_)->digest) } +# obsolete since v0.057, only for backwards compatibility +use Crypt::Checksum::CRC32; +use Crypt::Checksum::Adler32; +sub adler32_data { goto \&Crypt::Checksum::Adler32::adler32_data } +sub adler32_data_hex { goto \&Crypt::Checksum::Adler32::adler32_data_hex } +sub adler32_data_int { goto \&Crypt::Checksum::Adler32::adler32_data_int } +sub adler32_file { goto \&Crypt::Checksum::Adler32::adler32_file } +sub adler32_file_hex { goto \&Crypt::Checksum::Adler32::adler32_file_hex } +sub adler32_file_int { goto \&Crypt::Checksum::Adler32::adler32_file_int } +sub crc32_data { goto \&Crypt::Checksum::CRC32::crc32_data } +sub crc32_data_hex { goto \&Crypt::Checksum::CRC32::crc32_data_hex } +sub crc32_data_int { goto \&Crypt::Checksum::CRC32::crc32_data_int } +sub crc32_file { goto \&Crypt::Checksum::CRC32::crc32_file } +sub crc32_file_hex { goto \&Crypt::Checksum::CRC32::crc32_file_hex } +sub crc32_file_int { goto \&Crypt::Checksum::CRC32::crc32_file_int } + +sub addfile { + my ($self, $file) = @_; + + my $handle; + if (ref(\$file) eq 'SCALAR') { #filename + open($handle, "<", $file) || croak "FATAL: cannot open '$file': $!"; + binmode($handle); + } + else { #handle + $handle = $file + } + croak "FATAL: invalid handle" unless defined $handle; + + my $n; + my $buf = ""; + while (($n = read($handle, $buf, 32*1024))) { + $self->add($buf) + } + croak "FATAL: read failed: $!" unless defined $n; + + return $self; +} + +sub CLONE_SKIP { 1 } # prevent cloning 1; @@ -37,163 +60,10 @@ sub crc32_file_int { local $SIG{__DIE__} = \&CryptX::_croak; unpack("N", Cr =head1 NAME -Crypt::Checksum - functional interface to CRC32 and Adler32 checksums - -=head1 SYNOPSIS - - use Crypt::Checksum ':all'; - - # calculate Adler32 checksum from string/buffer - $checksum_raw = adler32_data($data); - $checksum_hex = adler32_data_hex($data); - - # calculate Adler32 checksum from file - $checksum_raw = adler32_file('filename.dat'); - $checksum_hex = adler32_file_hex('filename.dat'); - - # calculate Adler32 checksum from filehandle - $checksum_raw = adler32_file(*FILEHANDLE); - $checksum_hex = adler32_file_hex(*FILEHANDLE); - - # calculate CRC32 checksum from string/buffer - $checksum_raw = crc32_data($data); - $checksum_hex = crc32_data_hex($data); - - # calculate CRC32 checksum from file - $checksum_raw = crc32_file('filename.dat'); - $checksum_hex = crc32_file_hex('filename.dat'); - - # calculate CRC32 checksum from filehandle - $checksum_raw = crc32_file(*FILEHANDLE); - $checksum_hex = crc32_file_hex(*FILEHANDLE); +Crypt::Checksum - [internal only] =head1 DESCRIPTION -Calculating CRC32 and Adler32 checksums (functional interface); - -I<Since: CryptX-0.032> - -=head1 EXPORT - -Nothing is exported by default. - -You can export selected functions: - - use Crypt::Checksum qw( adler32_data adler32_data_hex adler32_file adler32_file_hex - crc32_data crc32_data_hex crc32_file crc32_file_hex ); - -Or all of them at once: - - use Crypt::Checksum ':all'; - -=head1 FUNCTIONS - -=head2 adler32_data - -Returns checksum as raw octects. - - $checksum_raw = adler32_data('data string'); - #or - $checksum_raw = adler32_data('any data', 'more data', 'even more data'); - -=head2 adler32_data_hex - -Returns checksum as a hexadecimal string. - - $checksum_hex = adler32_data_hex('data string'); - #or - $checksum_hex = adler32_data_hex('any data', 'more data', 'even more data'); - -=head2 adler32_data_int - -Returns checksum as unsigned 32bit integer. - - $checksum_hex = adler32_data_int('data string'); - #or - $checksum_hex = adler32_data_int('any data', 'more data', 'even more data'); - -=head2 adler32_file - -Returns checksum as raw octects. - - $checksum_raw = adler32_file('filename.dat'); - #or - $checksum_raw = adler32_file(*FILEHANDLE); - -=head2 adler32_file_hex - -Returns checksum as a hexadecimal string. - - $checksum_hex = adler32_file_hex('filename.dat'); - #or - $checksum_hex = adler32_file_hex(*FILEHANDLE); - -=head2 adler32_file_int - -Returns checksum as unsigned 32bit integer. - - $checksum_hex = adler32_file_int('filename.dat'); - #or - $checksum_hex = adler32_file_int(*FILEHANDLE); - -=head2 crc32_data - -Returns checksum as raw octects. - - $checksum_raw = crc32_data('data string'); - #or - $checksum_raw = crc32_data('any data', 'more data', 'even more data'); - -=head2 crc32_data_hex - -Returns checksum as a hexadecimal string. - - $checksum_hex = crc32_data_hex('data string'); - #or - $checksum_hex = crc32_data_hex('any data', 'more data', 'even more data'); - -=head2 crc32_data_int - -Returns checksum as unsigned 32bit integer. - - $checksum_hex = crc32_data_int('data string'); - #or - $checksum_hex = crc32_data_int('any data', 'more data', 'even more data'); - -=head2 crc32_file - -Returns checksum as raw octects. - - $checksum_raw = crc32_file('filename.dat'); - #or - $checksum_raw = crc32_file(*FILEHANDLE); - -=head2 crc32_file_hex - -Returns checksum as a hexadecimal string. - - $checksum_hex = crc32_file_hex('filename.dat'); - #or - $checksum_hex = crc32_file_hex(*FILEHANDLE); - -=head2 crc32_file_int - -Returns checksum as unsigned 32bit integer. - - $checksum_hex = crc32_file_int('filename.dat'); - #or - $checksum_hex = crc32_file_int(*FILEHANDLE); - -=head1 SEE ALSO - -=over - -=item * L<CryptX|CryptX>, L<Crypt::Checksum::Adler32>, L<Crypt::Checksum::CRC32> - -=item * L<https://en.wikipedia.org/wiki/Adler-32> - -=item * L<https://en.wikipedia.org/wiki/Cyclic_redundancy_check> - -=back +You are probably looking for L<Crypt::Checksum::CRC32> or L<Crypt::Checksum::Adler32>. =cut diff --git a/lib/Crypt/Checksum/Adler32.pm b/lib/Crypt/Checksum/Adler32.pm index dd2a4952..767d3e30 100644 --- a/lib/Crypt/Checksum/Adler32.pm +++ b/lib/Crypt/Checksum/Adler32.pm @@ -2,36 +2,20 @@ package Crypt::Checksum::Adler32; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; + +use base qw(Crypt::Checksum Exporter); +our %EXPORT_TAGS = ( all => [qw( adler32_data adler32_data_hex adler32_data_int adler32_file adler32_file_hex adler32_file_int )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; use CryptX; -sub addfile { - my ($self, $file) = @_; - - my $handle; - if (ref(\$file) eq 'SCALAR') { #filename - open($handle, "<", $file) || croak "FATAL: cannot open '$file': $!"; - binmode($handle); - } - else { #handle - $handle = $file - } - croak "FATAL: invalid handle" unless defined $handle; - - my $n; - my $buf = ""; - while (($n = read($handle, $buf, 32*1024))) { - $self->add($buf) - } - croak "FATAL: read failed: $!" unless defined $n; - - return $self; -} - -sub CLONE_SKIP { 1 } # prevent cloning +sub adler32_file { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Checksum::Adler32->new->addfile(@_)->digest } +sub adler32_file_hex { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Checksum::Adler32->new->addfile(@_)->hexdigest } +sub adler32_file_int { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Checksum::Adler32->new->addfile(@_)->intdigest } 1; @@ -43,20 +27,101 @@ Crypt::Checksum::Adler32 - Compute Adler32 checksum =head1 SYNOPSIS + ### Functional interface: + use Crypt::Checksum::Adler32 ':all'; + + # calculate Adler32 checksum from string/buffer + $checksum_raw = adler32_data($data); + $checksum_hex = adler32_data_hex($data); + $checksum_int = adler32_data_int($data); + # calculate Adler32 checksum from file + $checksum_raw = adler32_file('filename.dat'); + $checksum_hex = adler32_file_hex('filename.dat'); + $checksum_int = adler32_file_int('filename.dat'); + # calculate Adler32 checksum from filehandle + $checksum_raw = adler32_file(*FILEHANDLE); + $checksum_hex = adler32_file_hex(*FILEHANDLE); + $checksum_int = adler32_file_int(*FILEHANDLE); + + ### OO interface: use Crypt::Checksum::Adler32; $d = Crypt::Checksum::Adler32->new; $d->add('any data'); + $d->add('another data'); $d->addfile('filename.dat'); $d->addfile(*FILEHANDLE); - $checksum_raw = $d->digest; # raw bytes + $checksum_raw = $d->digest; # raw 4 bytes $checksum_hex = $d->hexdigest; # hexadecimal form + $checksum_int = $d->intdigest; # 32bit unsigned integer =head1 DESCRIPTION -Calculating Adler32 checksums (OO interface); +Calculating Adler32 checksums. + +I<Updated: v0.057> + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Checksum::Adler32 qw(adler32_data adler32_data_hex adler32_data_int adler32_file adler32_file_hex adler32_file_int); -I<Since: CryptX-0.032> +Or all of them at once: + + use Crypt::Checksum::Adler32 ':all'; + +=head1 FUNCTIONS + +=head2 adler32_data + +Returns checksum as raw octects. + + $checksum_raw = adler32_data('data string'); + #or + $checksum_raw = adler32_data('any data', 'more data', 'even more data'); + +=head2 adler32_data_hex + +Returns checksum as a hexadecimal string. + + $checksum_hex = adler32_data_hex('data string'); + #or + $checksum_hex = adler32_data_hex('any data', 'more data', 'even more data'); + +=head2 adler32_data_int + +Returns checksum as unsigned 32bit integer. + + $checksum_int = adler32_data_int('data string'); + #or + $checksum_int = adler32_data_int('any data', 'more data', 'even more data'); + +=head2 adler32_file + +Returns checksum as raw octects. + + $checksum_raw = adler32_file('filename.dat'); + #or + $checksum_raw = adler32_file(*FILEHANDLE); + +=head2 adler32_file_hex + +Returns checksum as a hexadecimal string. + + $checksum_hex = adler32_file_hex('filename.dat'); + #or + $checksum_hex = adler32_file_hex(*FILEHANDLE); + +=head2 adler32_file_int + +Returns checksum as unsigned 32bit integer. + + $checksum_int = adler32_file_int('filename.dat'); + #or + $checksum_int = adler32_file_int(*FILEHANDLE); =head1 METHODS @@ -110,11 +175,17 @@ Returns the checksum encoded as a hexadecimal string. $result_hex = $d->hexdigest(); +=head2 intdigest + +Returns the checksum encoded as unsigned 32bit integer. + + $result_int = $d->intdigest(); + =head1 SEE ALSO =over -=item * L<CryptX|CryptX>, L<Crypt::Checksum> +=item * L<CryptX|CryptX> =item * L<https://en.wikipedia.org/wiki/Adler-32> diff --git a/lib/Crypt/Checksum/CRC32.pm b/lib/Crypt/Checksum/CRC32.pm index fc7f56a3..690ba6a7 100644 --- a/lib/Crypt/Checksum/CRC32.pm +++ b/lib/Crypt/Checksum/CRC32.pm @@ -2,36 +2,20 @@ package Crypt::Checksum::CRC32; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; + +use base qw(Crypt::Checksum Exporter); +our %EXPORT_TAGS = ( all => [qw( crc32_data crc32_data_hex crc32_data_int crc32_file crc32_file_hex crc32_file_int )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; use CryptX; -sub addfile { - my ($self, $file) = @_; - - my $handle; - if (ref(\$file) eq 'SCALAR') { #filename - open($handle, "<", $file) || croak "FATAL: cannot open '$file': $!"; - binmode($handle); - } - else { #handle - $handle = $file - } - croak "FATAL: invalid handle" unless defined $handle; - - my $n; - my $buf = ""; - while (($n = read($handle, $buf, 32*1024))) { - $self->add($buf) - } - croak "FATAL: read failed: $!" unless defined $n; - - return $self; -} - -sub CLONE_SKIP { 1 } # prevent cloning +sub crc32_file { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Checksum::CRC32->new->addfile(@_)->digest } +sub crc32_file_hex { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Checksum::CRC32->new->addfile(@_)->hexdigest } +sub crc32_file_int { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Checksum::CRC32->new->addfile(@_)->intdigest } 1; @@ -43,20 +27,101 @@ Crypt::Checksum::CRC32 - Compute CRC32 checksum =head1 SYNOPSIS + ### Functional interface: + use Crypt::Checksum::CRC32 ':all'; + + # calculate CRC32 checksum from string/buffer + $checksum_raw = crc32_data($data); + $checksum_hex = crc32_data_hex($data); + $checksum_int = crc32_data_int($data); + # calculate CRC32 checksum from file + $checksum_raw = crc32_file('filename.dat'); + $checksum_hex = crc32_file_hex('filename.dat'); + $checksum_int = crc32_file_int('filename.dat'); + # calculate CRC32 checksum from filehandle + $checksum_raw = crc32_file(*FILEHANDLE); + $checksum_hex = crc32_file_hex(*FILEHANDLE); + $checksum_int = crc32_file_int(*FILEHANDLE); + + ### OO interface: use Crypt::Checksum::CRC32; $d = Crypt::Checksum::CRC32->new; $d->add('any data'); + $d->add('another data'); $d->addfile('filename.dat'); $d->addfile(*FILEHANDLE); - $checksum_raw = $d->digest; # raw bytes + $checksum_raw = $d->digest; # raw 4 bytes $checksum_hex = $d->hexdigest; # hexadecimal form + $checksum_int = $d->intdigest; # 32bit unsigned integer =head1 DESCRIPTION -Calculating CRC32 checksums (OO interface); +Calculating CRC32 checksums. + +I<Updated: v0.057> + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Checksum::CRC32 qw(crc32_data crc32_data_hex crc32_data_int crc32_file crc32_file_hex crc32_file_int); -I<Since: CryptX-0.032> +Or all of them at once: + + use Crypt::Checksum::CRC32 ':all'; + +=head1 FUNCTIONS + +=head2 crc32_data + +Returns checksum as raw octects. + + $checksum_raw = crc32_data('data string'); + #or + $checksum_raw = crc32_data('any data', 'more data', 'even more data'); + +=head2 crc32_data_hex + +Returns checksum as a hexadecimal string. + + $checksum_hex = crc32_data_hex('data string'); + #or + $checksum_hex = crc32_data_hex('any data', 'more data', 'even more data'); + +=head2 crc32_data_int + +Returns checksum as unsigned 32bit integer. + + $checksum_int = crc32_data_int('data string'); + #or + $checksum_int = crc32_data_int('any data', 'more data', 'even more data'); + +=head2 crc32_file + +Returns checksum as raw octects. + + $checksum_raw = crc32_file('filename.dat'); + #or + $checksum_raw = crc32_file(*FILEHANDLE); + +=head2 crc32_file_hex + +Returns checksum as a hexadecimal string. + + $checksum_hex = crc32_file_hex('filename.dat'); + #or + $checksum_hex = crc32_file_hex(*FILEHANDLE); + +=head2 crc32_file_int + +Returns checksum as unsigned 32bit integer. + + $checksum_int = crc32_file_int('filename.dat'); + #or + $checksum_int = crc32_file_int(*FILEHANDLE); =head1 METHODS @@ -110,11 +175,17 @@ Returns the checksum encoded as a hexadecimal string. $result_hex = $d->hexdigest(); +=head2 intdigest + +Returns the checksum encoded as unsigned 32bit integer. + + $result_int = $d->intdigest(); + =head1 SEE ALSO =over -=item * L<CryptX|CryptX>, L<Crypt::Checksum> +=item * L<CryptX|CryptX> =item * L<https://en.wikipedia.org/wiki/Cyclic_redundancy_check> diff --git a/lib/Crypt/Cipher.pm b/lib/Crypt/Cipher.pm index 609c32a6..a2179364 100644 --- a/lib/Crypt/Cipher.pm +++ b/lib/Crypt/Cipher.pm @@ -2,91 +2,23 @@ package Crypt::Cipher; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use Carp; $Carp::Internal{(__PACKAGE__)}++; use CryptX; ### the following methods/functions are implemented in XS: -# - _new +# - new # - DESTROY -# - _keysize -# - _max_keysize -# - _min_keysize -# - _blocksize -# - _default_rounds -# - encrypt +# - blocksize # - decrypt -#functions, not methods: -# - _block_length_by_name -# - _min_key_length_by_name -# - _max_key_length_by_name -# - _default_rounds_by_name - -sub _trans_cipher_name { - my $name = shift || ""; - my %trans = ( - DES_EDE => '3des', - SAFERP => 'safer+', - SAFER_K128 => 'safer-k128', - SAFER_K64 => 'safer-k64', - SAFER_SK128 => 'safer-sk128', - SAFER_SK64 => 'safer-sk64', - ); - $name =~ s/^Crypt::Cipher:://; - return $trans{uc($name)} if defined $trans{uc($name)}; - return lc($name); -} - -### METHODS - -sub new { - my $pkg = shift; - my $cipher_name = $pkg eq __PACKAGE__ ? _trans_cipher_name(shift) : _trans_cipher_name($pkg); - local $SIG{__DIE__} = \&CryptX::_croak; - return _new($cipher_name, @_); -} - -sub blocksize { - my $self = shift; - return $self->_blocksize if ref($self); - $self = _trans_cipher_name(shift) if $self eq __PACKAGE__; - local $SIG{__DIE__} = \&CryptX::_croak; - return _block_length_by_name(_trans_cipher_name($self)); -} - -sub max_keysize -{ - my $self = shift; - return unless defined $self; - return $self->_max_keysize if ref($self); - $self = _trans_cipher_name(shift) if $self eq __PACKAGE__; - local $SIG{__DIE__} = \&CryptX::_croak; - return _max_key_length_by_name(_trans_cipher_name($self)); -} - -sub min_keysize { - my $self = shift; - return unless defined $self; - return $self->_min_keysize if ref($self); - $self = _trans_cipher_name(shift) if $self eq __PACKAGE__; - local $SIG{__DIE__} = \&CryptX::_croak; - return _min_key_length_by_name(_trans_cipher_name($self)); -} - -sub keysize { - goto &max_keysize; -} - -sub default_rounds { - my $self = shift; - return unless defined $self; - return $self->_default_rounds if ref($self); - $self = _trans_cipher_name(shift) if $self eq __PACKAGE__; - local $SIG{__DIE__} = \&CryptX::_croak; - return _default_rounds_by_name(_trans_cipher_name($self)); -} +# - default_rounds +# - encrypt +# - max_keysize +# - min_keysize + +sub keysize { goto \&max_keysize; } # for Crypt::CBC compatibility sub CLONE_SKIP { 1 } # prevent cloning diff --git a/lib/Crypt/Cipher/AES.pm b/lib/Crypt/Cipher/AES.pm index 870c5c15..d5c894fc 100644 --- a/lib/Crypt/Cipher/AES.pm +++ b/lib/Crypt/Cipher/AES.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::AES; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('AES') } +sub keysize { Crypt::Cipher::keysize('AES') } +sub max_keysize { Crypt::Cipher::max_keysize('AES') } +sub min_keysize { Crypt::Cipher::min_keysize('AES') } +sub default_rounds { Crypt::Cipher::default_rounds('AES') } 1; diff --git a/lib/Crypt/Cipher/Anubis.pm b/lib/Crypt/Cipher/Anubis.pm index 61ca00f3..8156c69a 100644 --- a/lib/Crypt/Cipher/Anubis.pm +++ b/lib/Crypt/Cipher/Anubis.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::Anubis; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('Anubis') } +sub keysize { Crypt::Cipher::keysize('Anubis') } +sub max_keysize { Crypt::Cipher::max_keysize('Anubis') } +sub min_keysize { Crypt::Cipher::min_keysize('Anubis') } +sub default_rounds { Crypt::Cipher::default_rounds('Anubis') } 1; diff --git a/lib/Crypt/Cipher/Blowfish.pm b/lib/Crypt/Cipher/Blowfish.pm index 279cc6cb..a17dee47 100644 --- a/lib/Crypt/Cipher/Blowfish.pm +++ b/lib/Crypt/Cipher/Blowfish.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::Blowfish; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('Blowfish') } +sub keysize { Crypt::Cipher::keysize('Blowfish') } +sub max_keysize { Crypt::Cipher::max_keysize('Blowfish') } +sub min_keysize { Crypt::Cipher::min_keysize('Blowfish') } +sub default_rounds { Crypt::Cipher::default_rounds('Blowfish') } 1; diff --git a/lib/Crypt/Cipher/CAST5.pm b/lib/Crypt/Cipher/CAST5.pm index edc17834..b7f14fe9 100644 --- a/lib/Crypt/Cipher/CAST5.pm +++ b/lib/Crypt/Cipher/CAST5.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::CAST5; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('CAST5') } +sub keysize { Crypt::Cipher::keysize('CAST5') } +sub max_keysize { Crypt::Cipher::max_keysize('CAST5') } +sub min_keysize { Crypt::Cipher::min_keysize('CAST5') } +sub default_rounds { Crypt::Cipher::default_rounds('CAST5') } 1; diff --git a/lib/Crypt/Cipher/Camellia.pm b/lib/Crypt/Cipher/Camellia.pm index c83daa47..1dde5412 100644 --- a/lib/Crypt/Cipher/Camellia.pm +++ b/lib/Crypt/Cipher/Camellia.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::Camellia; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('Camellia') } +sub keysize { Crypt::Cipher::keysize('Camellia') } +sub max_keysize { Crypt::Cipher::max_keysize('Camellia') } +sub min_keysize { Crypt::Cipher::min_keysize('Camellia') } +sub default_rounds { Crypt::Cipher::default_rounds('Camellia') } 1; diff --git a/lib/Crypt/Cipher/DES.pm b/lib/Crypt/Cipher/DES.pm index 389fb5c3..1e28dfbe 100644 --- a/lib/Crypt/Cipher/DES.pm +++ b/lib/Crypt/Cipher/DES.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::DES; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('DES') } +sub keysize { Crypt::Cipher::keysize('DES') } +sub max_keysize { Crypt::Cipher::max_keysize('DES') } +sub min_keysize { Crypt::Cipher::min_keysize('DES') } +sub default_rounds { Crypt::Cipher::default_rounds('DES') } 1; diff --git a/lib/Crypt/Cipher/DES_EDE.pm b/lib/Crypt/Cipher/DES_EDE.pm index 83501c70..d100e44c 100644 --- a/lib/Crypt/Cipher/DES_EDE.pm +++ b/lib/Crypt/Cipher/DES_EDE.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::DES_EDE; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('DES_EDE') } +sub keysize { Crypt::Cipher::keysize('DES_EDE') } +sub max_keysize { Crypt::Cipher::max_keysize('DES_EDE') } +sub min_keysize { Crypt::Cipher::min_keysize('DES_EDE') } +sub default_rounds { Crypt::Cipher::default_rounds('DES_EDE') } 1; diff --git a/lib/Crypt/Cipher/IDEA.pm b/lib/Crypt/Cipher/IDEA.pm index 9d78e930..2c1226f3 100644 --- a/lib/Crypt/Cipher/IDEA.pm +++ b/lib/Crypt/Cipher/IDEA.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::IDEA; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('IDEA') } +sub keysize { Crypt::Cipher::keysize('IDEA') } +sub max_keysize { Crypt::Cipher::max_keysize('IDEA') } +sub min_keysize { Crypt::Cipher::min_keysize('IDEA') } +sub default_rounds { Crypt::Cipher::default_rounds('IDEA') } 1; diff --git a/lib/Crypt/Cipher/KASUMI.pm b/lib/Crypt/Cipher/KASUMI.pm index c8e0f9d8..dd4c6dba 100644 --- a/lib/Crypt/Cipher/KASUMI.pm +++ b/lib/Crypt/Cipher/KASUMI.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::KASUMI; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('KASUMI') } +sub keysize { Crypt::Cipher::keysize('KASUMI') } +sub max_keysize { Crypt::Cipher::max_keysize('KASUMI') } +sub min_keysize { Crypt::Cipher::min_keysize('KASUMI') } +sub default_rounds { Crypt::Cipher::default_rounds('KASUMI') } 1; diff --git a/lib/Crypt/Cipher/Khazad.pm b/lib/Crypt/Cipher/Khazad.pm index 1b5626b1..501235b0 100644 --- a/lib/Crypt/Cipher/Khazad.pm +++ b/lib/Crypt/Cipher/Khazad.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::Khazad; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('Khazad') } +sub keysize { Crypt::Cipher::keysize('Khazad') } +sub max_keysize { Crypt::Cipher::max_keysize('Khazad') } +sub min_keysize { Crypt::Cipher::min_keysize('Khazad') } +sub default_rounds { Crypt::Cipher::default_rounds('Khazad') } 1; diff --git a/lib/Crypt/Cipher/MULTI2.pm b/lib/Crypt/Cipher/MULTI2.pm index ebb66f8f..7b588aae 100644 --- a/lib/Crypt/Cipher/MULTI2.pm +++ b/lib/Crypt/Cipher/MULTI2.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::MULTI2; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('MULTI2') } +sub keysize { Crypt::Cipher::keysize('MULTI2') } +sub max_keysize { Crypt::Cipher::max_keysize('MULTI2') } +sub min_keysize { Crypt::Cipher::min_keysize('MULTI2') } +sub default_rounds { Crypt::Cipher::default_rounds('MULTI2') } 1; diff --git a/lib/Crypt/Cipher/Noekeon.pm b/lib/Crypt/Cipher/Noekeon.pm index 58cedc0d..d1efa638 100644 --- a/lib/Crypt/Cipher/Noekeon.pm +++ b/lib/Crypt/Cipher/Noekeon.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::Noekeon; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('Noekeon') } +sub keysize { Crypt::Cipher::keysize('Noekeon') } +sub max_keysize { Crypt::Cipher::max_keysize('Noekeon') } +sub min_keysize { Crypt::Cipher::min_keysize('Noekeon') } +sub default_rounds { Crypt::Cipher::default_rounds('Noekeon') } 1; diff --git a/lib/Crypt/Cipher/RC2.pm b/lib/Crypt/Cipher/RC2.pm index 3727085d..da63d348 100644 --- a/lib/Crypt/Cipher/RC2.pm +++ b/lib/Crypt/Cipher/RC2.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::RC2; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('RC2') } +sub keysize { Crypt::Cipher::keysize('RC2') } +sub max_keysize { Crypt::Cipher::max_keysize('RC2') } +sub min_keysize { Crypt::Cipher::min_keysize('RC2') } +sub default_rounds { Crypt::Cipher::default_rounds('RC2') } 1; diff --git a/lib/Crypt/Cipher/RC5.pm b/lib/Crypt/Cipher/RC5.pm index 5e29a8e0..06f81862 100644 --- a/lib/Crypt/Cipher/RC5.pm +++ b/lib/Crypt/Cipher/RC5.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::RC5; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('RC5') } +sub keysize { Crypt::Cipher::keysize('RC5') } +sub max_keysize { Crypt::Cipher::max_keysize('RC5') } +sub min_keysize { Crypt::Cipher::min_keysize('RC5') } +sub default_rounds { Crypt::Cipher::default_rounds('RC5') } 1; diff --git a/lib/Crypt/Cipher/RC6.pm b/lib/Crypt/Cipher/RC6.pm index 05da0dc0..e662a67a 100644 --- a/lib/Crypt/Cipher/RC6.pm +++ b/lib/Crypt/Cipher/RC6.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::RC6; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('RC6') } +sub keysize { Crypt::Cipher::keysize('RC6') } +sub max_keysize { Crypt::Cipher::max_keysize('RC6') } +sub min_keysize { Crypt::Cipher::min_keysize('RC6') } +sub default_rounds { Crypt::Cipher::default_rounds('RC6') } 1; diff --git a/lib/Crypt/Cipher/SAFERP.pm b/lib/Crypt/Cipher/SAFERP.pm index 878ff0c2..8c5b3f51 100644 --- a/lib/Crypt/Cipher/SAFERP.pm +++ b/lib/Crypt/Cipher/SAFERP.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::SAFERP; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('SAFERP') } +sub keysize { Crypt::Cipher::keysize('SAFERP') } +sub max_keysize { Crypt::Cipher::max_keysize('SAFERP') } +sub min_keysize { Crypt::Cipher::min_keysize('SAFERP') } +sub default_rounds { Crypt::Cipher::default_rounds('SAFERP') } 1; diff --git a/lib/Crypt/Cipher/SAFER_K128.pm b/lib/Crypt/Cipher/SAFER_K128.pm index 8eaf4af5..c1be436a 100644 --- a/lib/Crypt/Cipher/SAFER_K128.pm +++ b/lib/Crypt/Cipher/SAFER_K128.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::SAFER_K128; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('SAFER_K128') } +sub keysize { Crypt::Cipher::keysize('SAFER_K128') } +sub max_keysize { Crypt::Cipher::max_keysize('SAFER_K128') } +sub min_keysize { Crypt::Cipher::min_keysize('SAFER_K128') } +sub default_rounds { Crypt::Cipher::default_rounds('SAFER_K128') } 1; diff --git a/lib/Crypt/Cipher/SAFER_K64.pm b/lib/Crypt/Cipher/SAFER_K64.pm index d8862b28..cda042e9 100644 --- a/lib/Crypt/Cipher/SAFER_K64.pm +++ b/lib/Crypt/Cipher/SAFER_K64.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::SAFER_K64; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('SAFER_K64') } +sub keysize { Crypt::Cipher::keysize('SAFER_K64') } +sub max_keysize { Crypt::Cipher::max_keysize('SAFER_K64') } +sub min_keysize { Crypt::Cipher::min_keysize('SAFER_K64') } +sub default_rounds { Crypt::Cipher::default_rounds('SAFER_K64') } 1; diff --git a/lib/Crypt/Cipher/SAFER_SK128.pm b/lib/Crypt/Cipher/SAFER_SK128.pm index a150fe0f..76bd22f6 100644 --- a/lib/Crypt/Cipher/SAFER_SK128.pm +++ b/lib/Crypt/Cipher/SAFER_SK128.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::SAFER_SK128; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('SAFER_SK128') } +sub keysize { Crypt::Cipher::keysize('SAFER_SK128') } +sub max_keysize { Crypt::Cipher::max_keysize('SAFER_SK128') } +sub min_keysize { Crypt::Cipher::min_keysize('SAFER_SK128') } +sub default_rounds { Crypt::Cipher::default_rounds('SAFER_SK128') } 1; diff --git a/lib/Crypt/Cipher/SAFER_SK64.pm b/lib/Crypt/Cipher/SAFER_SK64.pm index 22ddd05d..582eb0fc 100644 --- a/lib/Crypt/Cipher/SAFER_SK64.pm +++ b/lib/Crypt/Cipher/SAFER_SK64.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::SAFER_SK64; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('SAFER_SK64') } +sub keysize { Crypt::Cipher::keysize('SAFER_SK64') } +sub max_keysize { Crypt::Cipher::max_keysize('SAFER_SK64') } +sub min_keysize { Crypt::Cipher::min_keysize('SAFER_SK64') } +sub default_rounds { Crypt::Cipher::default_rounds('SAFER_SK64') } 1; diff --git a/lib/Crypt/Cipher/SEED.pm b/lib/Crypt/Cipher/SEED.pm index 4fc6338a..bea2c9bb 100644 --- a/lib/Crypt/Cipher/SEED.pm +++ b/lib/Crypt/Cipher/SEED.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::SEED; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('SEED') } +sub keysize { Crypt::Cipher::keysize('SEED') } +sub max_keysize { Crypt::Cipher::max_keysize('SEED') } +sub min_keysize { Crypt::Cipher::min_keysize('SEED') } +sub default_rounds { Crypt::Cipher::default_rounds('SEED') } 1; diff --git a/lib/Crypt/Cipher/Serpent.pm b/lib/Crypt/Cipher/Serpent.pm index 21e31094..69e8e8b0 100644 --- a/lib/Crypt/Cipher/Serpent.pm +++ b/lib/Crypt/Cipher/Serpent.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::Serpent; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('Serpent') } +sub keysize { Crypt::Cipher::keysize('Serpent') } +sub max_keysize { Crypt::Cipher::max_keysize('Serpent') } +sub min_keysize { Crypt::Cipher::min_keysize('Serpent') } +sub default_rounds { Crypt::Cipher::default_rounds('Serpent') } 1; diff --git a/lib/Crypt/Cipher/Skipjack.pm b/lib/Crypt/Cipher/Skipjack.pm index bcf6dd4f..3e0db08e 100644 --- a/lib/Crypt/Cipher/Skipjack.pm +++ b/lib/Crypt/Cipher/Skipjack.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::Skipjack; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('Skipjack') } +sub keysize { Crypt::Cipher::keysize('Skipjack') } +sub max_keysize { Crypt::Cipher::max_keysize('Skipjack') } +sub min_keysize { Crypt::Cipher::min_keysize('Skipjack') } +sub default_rounds { Crypt::Cipher::default_rounds('Skipjack') } 1; diff --git a/lib/Crypt/Cipher/Twofish.pm b/lib/Crypt/Cipher/Twofish.pm index fef9f266..4da40110 100644 --- a/lib/Crypt/Cipher/Twofish.pm +++ b/lib/Crypt/Cipher/Twofish.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::Twofish; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('Twofish') } +sub keysize { Crypt::Cipher::keysize('Twofish') } +sub max_keysize { Crypt::Cipher::max_keysize('Twofish') } +sub min_keysize { Crypt::Cipher::min_keysize('Twofish') } +sub default_rounds { Crypt::Cipher::default_rounds('Twofish') } 1; diff --git a/lib/Crypt/Cipher/XTEA.pm b/lib/Crypt/Cipher/XTEA.pm index 1a7fb821..1a630bc6 100644 --- a/lib/Crypt/Cipher/XTEA.pm +++ b/lib/Crypt/Cipher/XTEA.pm @@ -4,16 +4,15 @@ package Crypt::Cipher::XTEA; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use CryptX; -use base 'Crypt::Cipher'; +use base qw(Crypt::Cipher); -sub blocksize { Crypt::Cipher::blocksize(__PACKAGE__) } -sub keysize { Crypt::Cipher::keysize(__PACKAGE__) } -sub max_keysize { Crypt::Cipher::max_keysize(__PACKAGE__) } -sub min_keysize { Crypt::Cipher::min_keysize(__PACKAGE__) } -sub default_rounds { Crypt::Cipher::default_rounds(__PACKAGE__) } +sub blocksize { Crypt::Cipher::blocksize('XTEA') } +sub keysize { Crypt::Cipher::keysize('XTEA') } +sub max_keysize { Crypt::Cipher::max_keysize('XTEA') } +sub min_keysize { Crypt::Cipher::min_keysize('XTEA') } +sub default_rounds { Crypt::Cipher::default_rounds('XTEA') } 1; diff --git a/lib/Crypt/Digest.pm b/lib/Crypt/Digest.pm index 3fa01e6d..cb3a32ab 100644 --- a/lib/Crypt/Digest.pm +++ b/lib/Crypt/Digest.pm @@ -2,7 +2,7 @@ package Crypt::Digest; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; our %EXPORT_TAGS = ( all => [qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u )] ); @@ -14,70 +14,22 @@ $Carp::Internal{(__PACKAGE__)}++; use CryptX; ### the following methods/functions are implemented in XS: -# - _new -# - _hashsize -# - _hashsize_by_name (function, not method) +# - new +# - hashsize # - clone # - reset # - digest # - hexdigest # - b64digest # - add +# - digest_data +# - digest_data_hex +# - digest_data_b64 +# - digest_data_b64u # - DESTROY -sub _trans_digest_name { - my $name = shift || ""; - my %trans = ( - CHAES => 'chc_hash', - RIPEMD128 => 'rmd128', - RIPEMD160 => 'rmd160', - RIPEMD256 => 'rmd256', - RIPEMD320 => 'rmd320', - TIGER192 => 'tiger', - SHA512_224 => 'sha512-224', - SHA512_256 => 'sha512-256', - SHA3_224 => 'sha3-224', - SHA3_256 => 'sha3-256', - SHA3_384 => 'sha3-384', - SHA3_512 => 'sha3-512', - BLAKE2B_160 => 'blake2b-160', - BLAKE2B_256 => 'blake2b-256', - BLAKE2B_384 => 'blake2b-384', - BLAKE2B_512 => 'blake2b-512', - BLAKE2S_128 => 'blake2s-128', - BLAKE2S_160 => 'blake2s-160', - BLAKE2S_224 => 'blake2s-224', - BLAKE2S_256 => 'blake2s-256', - ); - $name =~ s/^Crypt::Digest:://i; - return $trans{uc($name)} if defined $trans{uc($name)}; - return lc($name); -} - ### METHODS -sub new { - my $pkg = shift; - unshift @_, ($pkg eq 'Crypt::Digest' ? _trans_digest_name(shift) : _trans_digest_name($pkg)); - local $SIG{__DIE__} = \&CryptX::_croak; - return _new(@_); -} - -sub hashsize { - return unless defined $_[0]; - - if (ref $_[0]) { - local $SIG{__DIE__} = \&CryptX::_croak; - return _hashsize(@_); - } - else { - my $pkg = shift; - unshift @_, ($pkg eq 'Crypt::Digest' ? _trans_digest_name(shift) : _trans_digest_name($pkg)); - local $SIG{__DIE__} = \&CryptX::_croak; - return _hashsize_by_name(@_); - } -} - sub addfile { my ($self, $file) = @_; @@ -105,11 +57,6 @@ sub CLONE_SKIP { 1 } # prevent cloning ### FUNCTIONS -sub digest_data { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Digest->new(shift)->add(@_)->digest } -sub digest_data_hex { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Digest->new(shift)->add(@_)->hexdigest } -sub digest_data_b64 { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Digest->new(shift)->add(@_)->b64digest } -sub digest_data_b64u { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Digest->new(shift)->add(@_)->b64udigest } - sub digest_file { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Digest->new(shift)->addfile(@_)->digest } sub digest_file_hex { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Digest->new(shift)->addfile(@_)->hexdigest } sub digest_file_b64 { local $SIG{__DIE__} = \&CryptX::_croak; Crypt::Digest->new(shift)->addfile(@_)->b64digest } diff --git a/lib/Crypt/Digest/BLAKE2b_160.pm b/lib/Crypt/Digest/BLAKE2b_160.pm index 3dab678d..8c6730aa 100644 --- a/lib/Crypt/Digest/BLAKE2b_160.pm +++ b/lib/Crypt/Digest/BLAKE2b_160.pm @@ -4,7 +4,7 @@ package Crypt::Digest::BLAKE2b_160; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( blake2b_160 blake2b_160_hex blake2b_160_b64 blake2b_160_b64u blake2b_160_file blake2b_160_file_hex blake2b_160_file_b64 blake2b_160_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub blake2b_160 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub blake2b_160_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub blake2b_160_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub blake2b_160_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub blake2b_160_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub blake2b_160_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub blake2b_160_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub blake2b_160_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('BLAKE2b_160') } +sub blake2b_160 { Crypt::Digest::digest_data('BLAKE2b_160', @_) } +sub blake2b_160_hex { Crypt::Digest::digest_data_hex('BLAKE2b_160', @_) } +sub blake2b_160_b64 { Crypt::Digest::digest_data_b64('BLAKE2b_160', @_) } +sub blake2b_160_b64u { Crypt::Digest::digest_data_b64u('BLAKE2b_160', @_) } +sub blake2b_160_file { Crypt::Digest::digest_file('BLAKE2b_160', @_) } +sub blake2b_160_file_hex { Crypt::Digest::digest_file_hex('BLAKE2b_160', @_) } +sub blake2b_160_file_b64 { Crypt::Digest::digest_file_b64('BLAKE2b_160', @_) } +sub blake2b_160_file_b64u { Crypt::Digest::digest_file_b64u('BLAKE2b_160', @_) } 1; diff --git a/lib/Crypt/Digest/BLAKE2b_256.pm b/lib/Crypt/Digest/BLAKE2b_256.pm index 564ef874..fd9bc59b 100644 --- a/lib/Crypt/Digest/BLAKE2b_256.pm +++ b/lib/Crypt/Digest/BLAKE2b_256.pm @@ -4,7 +4,7 @@ package Crypt::Digest::BLAKE2b_256; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( blake2b_256 blake2b_256_hex blake2b_256_b64 blake2b_256_b64u blake2b_256_file blake2b_256_file_hex blake2b_256_file_b64 blake2b_256_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub blake2b_256 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub blake2b_256_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub blake2b_256_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub blake2b_256_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub blake2b_256_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub blake2b_256_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub blake2b_256_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub blake2b_256_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('BLAKE2b_256') } +sub blake2b_256 { Crypt::Digest::digest_data('BLAKE2b_256', @_) } +sub blake2b_256_hex { Crypt::Digest::digest_data_hex('BLAKE2b_256', @_) } +sub blake2b_256_b64 { Crypt::Digest::digest_data_b64('BLAKE2b_256', @_) } +sub blake2b_256_b64u { Crypt::Digest::digest_data_b64u('BLAKE2b_256', @_) } +sub blake2b_256_file { Crypt::Digest::digest_file('BLAKE2b_256', @_) } +sub blake2b_256_file_hex { Crypt::Digest::digest_file_hex('BLAKE2b_256', @_) } +sub blake2b_256_file_b64 { Crypt::Digest::digest_file_b64('BLAKE2b_256', @_) } +sub blake2b_256_file_b64u { Crypt::Digest::digest_file_b64u('BLAKE2b_256', @_) } 1; diff --git a/lib/Crypt/Digest/BLAKE2b_384.pm b/lib/Crypt/Digest/BLAKE2b_384.pm index e321763d..03d33b1e 100644 --- a/lib/Crypt/Digest/BLAKE2b_384.pm +++ b/lib/Crypt/Digest/BLAKE2b_384.pm @@ -4,7 +4,7 @@ package Crypt::Digest::BLAKE2b_384; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( blake2b_384 blake2b_384_hex blake2b_384_b64 blake2b_384_b64u blake2b_384_file blake2b_384_file_hex blake2b_384_file_b64 blake2b_384_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub blake2b_384 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub blake2b_384_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub blake2b_384_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub blake2b_384_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub blake2b_384_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub blake2b_384_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub blake2b_384_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub blake2b_384_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('BLAKE2b_384') } +sub blake2b_384 { Crypt::Digest::digest_data('BLAKE2b_384', @_) } +sub blake2b_384_hex { Crypt::Digest::digest_data_hex('BLAKE2b_384', @_) } +sub blake2b_384_b64 { Crypt::Digest::digest_data_b64('BLAKE2b_384', @_) } +sub blake2b_384_b64u { Crypt::Digest::digest_data_b64u('BLAKE2b_384', @_) } +sub blake2b_384_file { Crypt::Digest::digest_file('BLAKE2b_384', @_) } +sub blake2b_384_file_hex { Crypt::Digest::digest_file_hex('BLAKE2b_384', @_) } +sub blake2b_384_file_b64 { Crypt::Digest::digest_file_b64('BLAKE2b_384', @_) } +sub blake2b_384_file_b64u { Crypt::Digest::digest_file_b64u('BLAKE2b_384', @_) } 1; diff --git a/lib/Crypt/Digest/BLAKE2b_512.pm b/lib/Crypt/Digest/BLAKE2b_512.pm index a59cdd2b..e3b08e4b 100644 --- a/lib/Crypt/Digest/BLAKE2b_512.pm +++ b/lib/Crypt/Digest/BLAKE2b_512.pm @@ -4,7 +4,7 @@ package Crypt::Digest::BLAKE2b_512; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( blake2b_512 blake2b_512_hex blake2b_512_b64 blake2b_512_b64u blake2b_512_file blake2b_512_file_hex blake2b_512_file_b64 blake2b_512_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub blake2b_512 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub blake2b_512_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub blake2b_512_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub blake2b_512_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub blake2b_512_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub blake2b_512_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub blake2b_512_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub blake2b_512_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('BLAKE2b_512') } +sub blake2b_512 { Crypt::Digest::digest_data('BLAKE2b_512', @_) } +sub blake2b_512_hex { Crypt::Digest::digest_data_hex('BLAKE2b_512', @_) } +sub blake2b_512_b64 { Crypt::Digest::digest_data_b64('BLAKE2b_512', @_) } +sub blake2b_512_b64u { Crypt::Digest::digest_data_b64u('BLAKE2b_512', @_) } +sub blake2b_512_file { Crypt::Digest::digest_file('BLAKE2b_512', @_) } +sub blake2b_512_file_hex { Crypt::Digest::digest_file_hex('BLAKE2b_512', @_) } +sub blake2b_512_file_b64 { Crypt::Digest::digest_file_b64('BLAKE2b_512', @_) } +sub blake2b_512_file_b64u { Crypt::Digest::digest_file_b64u('BLAKE2b_512', @_) } 1; diff --git a/lib/Crypt/Digest/BLAKE2s_128.pm b/lib/Crypt/Digest/BLAKE2s_128.pm index 15c6c04e..5d8dbc9e 100644 --- a/lib/Crypt/Digest/BLAKE2s_128.pm +++ b/lib/Crypt/Digest/BLAKE2s_128.pm @@ -4,7 +4,7 @@ package Crypt::Digest::BLAKE2s_128; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( blake2s_128 blake2s_128_hex blake2s_128_b64 blake2s_128_b64u blake2s_128_file blake2s_128_file_hex blake2s_128_file_b64 blake2s_128_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub blake2s_128 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub blake2s_128_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub blake2s_128_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub blake2s_128_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub blake2s_128_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub blake2s_128_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub blake2s_128_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub blake2s_128_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('BLAKE2s_128') } +sub blake2s_128 { Crypt::Digest::digest_data('BLAKE2s_128', @_) } +sub blake2s_128_hex { Crypt::Digest::digest_data_hex('BLAKE2s_128', @_) } +sub blake2s_128_b64 { Crypt::Digest::digest_data_b64('BLAKE2s_128', @_) } +sub blake2s_128_b64u { Crypt::Digest::digest_data_b64u('BLAKE2s_128', @_) } +sub blake2s_128_file { Crypt::Digest::digest_file('BLAKE2s_128', @_) } +sub blake2s_128_file_hex { Crypt::Digest::digest_file_hex('BLAKE2s_128', @_) } +sub blake2s_128_file_b64 { Crypt::Digest::digest_file_b64('BLAKE2s_128', @_) } +sub blake2s_128_file_b64u { Crypt::Digest::digest_file_b64u('BLAKE2s_128', @_) } 1; diff --git a/lib/Crypt/Digest/BLAKE2s_160.pm b/lib/Crypt/Digest/BLAKE2s_160.pm index c3e8af12..9c17f783 100644 --- a/lib/Crypt/Digest/BLAKE2s_160.pm +++ b/lib/Crypt/Digest/BLAKE2s_160.pm @@ -4,7 +4,7 @@ package Crypt::Digest::BLAKE2s_160; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( blake2s_160 blake2s_160_hex blake2s_160_b64 blake2s_160_b64u blake2s_160_file blake2s_160_file_hex blake2s_160_file_b64 blake2s_160_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub blake2s_160 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub blake2s_160_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub blake2s_160_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub blake2s_160_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub blake2s_160_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub blake2s_160_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub blake2s_160_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub blake2s_160_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('BLAKE2s_160') } +sub blake2s_160 { Crypt::Digest::digest_data('BLAKE2s_160', @_) } +sub blake2s_160_hex { Crypt::Digest::digest_data_hex('BLAKE2s_160', @_) } +sub blake2s_160_b64 { Crypt::Digest::digest_data_b64('BLAKE2s_160', @_) } +sub blake2s_160_b64u { Crypt::Digest::digest_data_b64u('BLAKE2s_160', @_) } +sub blake2s_160_file { Crypt::Digest::digest_file('BLAKE2s_160', @_) } +sub blake2s_160_file_hex { Crypt::Digest::digest_file_hex('BLAKE2s_160', @_) } +sub blake2s_160_file_b64 { Crypt::Digest::digest_file_b64('BLAKE2s_160', @_) } +sub blake2s_160_file_b64u { Crypt::Digest::digest_file_b64u('BLAKE2s_160', @_) } 1; diff --git a/lib/Crypt/Digest/BLAKE2s_224.pm b/lib/Crypt/Digest/BLAKE2s_224.pm index c8534cf0..c8abbf22 100644 --- a/lib/Crypt/Digest/BLAKE2s_224.pm +++ b/lib/Crypt/Digest/BLAKE2s_224.pm @@ -4,7 +4,7 @@ package Crypt::Digest::BLAKE2s_224; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( blake2s_224 blake2s_224_hex blake2s_224_b64 blake2s_224_b64u blake2s_224_file blake2s_224_file_hex blake2s_224_file_b64 blake2s_224_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub blake2s_224 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub blake2s_224_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub blake2s_224_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub blake2s_224_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub blake2s_224_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub blake2s_224_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub blake2s_224_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub blake2s_224_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('BLAKE2s_224') } +sub blake2s_224 { Crypt::Digest::digest_data('BLAKE2s_224', @_) } +sub blake2s_224_hex { Crypt::Digest::digest_data_hex('BLAKE2s_224', @_) } +sub blake2s_224_b64 { Crypt::Digest::digest_data_b64('BLAKE2s_224', @_) } +sub blake2s_224_b64u { Crypt::Digest::digest_data_b64u('BLAKE2s_224', @_) } +sub blake2s_224_file { Crypt::Digest::digest_file('BLAKE2s_224', @_) } +sub blake2s_224_file_hex { Crypt::Digest::digest_file_hex('BLAKE2s_224', @_) } +sub blake2s_224_file_b64 { Crypt::Digest::digest_file_b64('BLAKE2s_224', @_) } +sub blake2s_224_file_b64u { Crypt::Digest::digest_file_b64u('BLAKE2s_224', @_) } 1; diff --git a/lib/Crypt/Digest/BLAKE2s_256.pm b/lib/Crypt/Digest/BLAKE2s_256.pm index 8d4a1ad1..de55e6de 100644 --- a/lib/Crypt/Digest/BLAKE2s_256.pm +++ b/lib/Crypt/Digest/BLAKE2s_256.pm @@ -4,7 +4,7 @@ package Crypt::Digest::BLAKE2s_256; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( blake2s_256 blake2s_256_hex blake2s_256_b64 blake2s_256_b64u blake2s_256_file blake2s_256_file_hex blake2s_256_file_b64 blake2s_256_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub blake2s_256 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub blake2s_256_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub blake2s_256_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub blake2s_256_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub blake2s_256_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub blake2s_256_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub blake2s_256_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub blake2s_256_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('BLAKE2s_256') } +sub blake2s_256 { Crypt::Digest::digest_data('BLAKE2s_256', @_) } +sub blake2s_256_hex { Crypt::Digest::digest_data_hex('BLAKE2s_256', @_) } +sub blake2s_256_b64 { Crypt::Digest::digest_data_b64('BLAKE2s_256', @_) } +sub blake2s_256_b64u { Crypt::Digest::digest_data_b64u('BLAKE2s_256', @_) } +sub blake2s_256_file { Crypt::Digest::digest_file('BLAKE2s_256', @_) } +sub blake2s_256_file_hex { Crypt::Digest::digest_file_hex('BLAKE2s_256', @_) } +sub blake2s_256_file_b64 { Crypt::Digest::digest_file_b64('BLAKE2s_256', @_) } +sub blake2s_256_file_b64u { Crypt::Digest::digest_file_b64u('BLAKE2s_256', @_) } 1; diff --git a/lib/Crypt/Digest/CHAES.pm b/lib/Crypt/Digest/CHAES.pm index c4ffb33c..d4456447 100644 --- a/lib/Crypt/Digest/CHAES.pm +++ b/lib/Crypt/Digest/CHAES.pm @@ -4,7 +4,7 @@ package Crypt::Digest::CHAES; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( chaes chaes_hex chaes_b64 chaes_b64u chaes_file chaes_file_hex chaes_file_b64 chaes_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub chaes { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub chaes_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub chaes_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub chaes_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub chaes_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub chaes_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub chaes_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub chaes_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('CHAES') } +sub chaes { Crypt::Digest::digest_data('CHAES', @_) } +sub chaes_hex { Crypt::Digest::digest_data_hex('CHAES', @_) } +sub chaes_b64 { Crypt::Digest::digest_data_b64('CHAES', @_) } +sub chaes_b64u { Crypt::Digest::digest_data_b64u('CHAES', @_) } +sub chaes_file { Crypt::Digest::digest_file('CHAES', @_) } +sub chaes_file_hex { Crypt::Digest::digest_file_hex('CHAES', @_) } +sub chaes_file_b64 { Crypt::Digest::digest_file_b64('CHAES', @_) } +sub chaes_file_b64u { Crypt::Digest::digest_file_b64u('CHAES', @_) } 1; diff --git a/lib/Crypt/Digest/Keccak224.pm b/lib/Crypt/Digest/Keccak224.pm new file mode 100644 index 00000000..2b163297 --- /dev/null +++ b/lib/Crypt/Digest/Keccak224.pm @@ -0,0 +1,223 @@ +package Crypt::Digest::Keccak224; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.059'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( keccak224 keccak224_hex keccak224_b64 keccak224_b64u keccak224_file keccak224_file_hex keccak224_file_b64 keccak224_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('Keccak224') } +sub keccak224 { Crypt::Digest::digest_data('Keccak224', @_) } +sub keccak224_hex { Crypt::Digest::digest_data_hex('Keccak224', @_) } +sub keccak224_b64 { Crypt::Digest::digest_data_b64('Keccak224', @_) } +sub keccak224_b64u { Crypt::Digest::digest_data_b64u('Keccak224', @_) } +sub keccak224_file { Crypt::Digest::digest_file('Keccak224', @_) } +sub keccak224_file_hex { Crypt::Digest::digest_file_hex('Keccak224', @_) } +sub keccak224_file_b64 { Crypt::Digest::digest_file_b64('Keccak224', @_) } +sub keccak224_file_b64u { Crypt::Digest::digest_file_b64u('Keccak224', @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::Keccak224 - Hash function Keccak-224 [size: 224 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::Keccak224 qw( keccak224 keccak224_hex keccak224_b64 keccak224_b64u + keccak224_file keccak224_file_hex keccak224_file_b64 keccak224_file_b64u ); + + # calculate digest from string/buffer + $keccak224_raw = keccak224('data string'); + $keccak224_hex = keccak224_hex('data string'); + $keccak224_b64 = keccak224_b64('data string'); + $keccak224_b64u = keccak224_b64u('data string'); + # calculate digest from file + $keccak224_raw = keccak224_file('filename.dat'); + $keccak224_hex = keccak224_file_hex('filename.dat'); + $keccak224_b64 = keccak224_file_b64('filename.dat'); + $keccak224_b64u = keccak224_file_b64u('filename.dat'); + # calculate digest from filehandle + $keccak224_raw = keccak224_file(*FILEHANDLE); + $keccak224_hex = keccak224_file_hex(*FILEHANDLE); + $keccak224_b64 = keccak224_file_b64(*FILEHANDLE); + $keccak224_b64u = keccak224_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::Keccak224; + + $d = Crypt::Digest::Keccak224->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the Keccak224 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::Keccak224 qw(keccak224 keccak224_hex keccak224_b64 keccak224_b64u + keccak224_file keccak224_file_hex keccak224_file_b64 keccak224_file_b64u); + +Or all of them at once: + + use Crypt::Digest::Keccak224 ':all'; + +=head1 FUNCTIONS + +=head2 keccak224 + +Logically joins all arguments into a single string, and returns its Keccak224 digest encoded as a binary string. + + $keccak224_raw = keccak224('data string'); + #or + $keccak224_raw = keccak224('any data', 'more data', 'even more data'); + +=head2 keccak224_hex + +Logically joins all arguments into a single string, and returns its Keccak224 digest encoded as a hexadecimal string. + + $keccak224_hex = keccak224_hex('data string'); + #or + $keccak224_hex = keccak224_hex('any data', 'more data', 'even more data'); + +=head2 keccak224_b64 + +Logically joins all arguments into a single string, and returns its Keccak224 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $keccak224_b64 = keccak224_b64('data string'); + #or + $keccak224_b64 = keccak224_b64('any data', 'more data', 'even more data'); + +=head2 keccak224_b64u + +Logically joins all arguments into a single string, and returns its Keccak224 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $keccak224_b64url = keccak224_b64u('data string'); + #or + $keccak224_b64url = keccak224_b64u('any data', 'more data', 'even more data'); + +=head2 keccak224_file + +Reads file (defined by filename or filehandle) content, and returns its Keccak224 digest encoded as a binary string. + + $keccak224_raw = keccak224_file('filename.dat'); + #or + $keccak224_raw = keccak224_file(*FILEHANDLE); + +=head2 keccak224_file_hex + +Reads file (defined by filename or filehandle) content, and returns its Keccak224 digest encoded as a hexadecimal string. + + $keccak224_hex = keccak224_file_hex('filename.dat'); + #or + $keccak224_hex = keccak224_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 keccak224_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its Keccak224 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $keccak224_b64 = keccak224_file_b64('filename.dat'); + #or + $keccak224_b64 = keccak224_file_b64(*FILEHANDLE); + +=head2 keccak224_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its Keccak224 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $keccak224_b64url = keccak224_file_b64u('filename.dat'); + #or + $keccak224_b64url = keccak224_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::Keccak224->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::Keccak224->hashsize(); + #or + Crypt::Digest::Keccak224::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest> + +=item * L<https://keccak.team/index.html> + +=back + +=cut diff --git a/lib/Crypt/Digest/Keccak256.pm b/lib/Crypt/Digest/Keccak256.pm new file mode 100644 index 00000000..dfc7badc --- /dev/null +++ b/lib/Crypt/Digest/Keccak256.pm @@ -0,0 +1,223 @@ +package Crypt::Digest::Keccak256; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.059'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( keccak256 keccak256_hex keccak256_b64 keccak256_b64u keccak256_file keccak256_file_hex keccak256_file_b64 keccak256_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('Keccak256') } +sub keccak256 { Crypt::Digest::digest_data('Keccak256', @_) } +sub keccak256_hex { Crypt::Digest::digest_data_hex('Keccak256', @_) } +sub keccak256_b64 { Crypt::Digest::digest_data_b64('Keccak256', @_) } +sub keccak256_b64u { Crypt::Digest::digest_data_b64u('Keccak256', @_) } +sub keccak256_file { Crypt::Digest::digest_file('Keccak256', @_) } +sub keccak256_file_hex { Crypt::Digest::digest_file_hex('Keccak256', @_) } +sub keccak256_file_b64 { Crypt::Digest::digest_file_b64('Keccak256', @_) } +sub keccak256_file_b64u { Crypt::Digest::digest_file_b64u('Keccak256', @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::Keccak256 - Hash function Keccak-256 [size: 256 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::Keccak256 qw( keccak256 keccak256_hex keccak256_b64 keccak256_b64u + keccak256_file keccak256_file_hex keccak256_file_b64 keccak256_file_b64u ); + + # calculate digest from string/buffer + $keccak256_raw = keccak256('data string'); + $keccak256_hex = keccak256_hex('data string'); + $keccak256_b64 = keccak256_b64('data string'); + $keccak256_b64u = keccak256_b64u('data string'); + # calculate digest from file + $keccak256_raw = keccak256_file('filename.dat'); + $keccak256_hex = keccak256_file_hex('filename.dat'); + $keccak256_b64 = keccak256_file_b64('filename.dat'); + $keccak256_b64u = keccak256_file_b64u('filename.dat'); + # calculate digest from filehandle + $keccak256_raw = keccak256_file(*FILEHANDLE); + $keccak256_hex = keccak256_file_hex(*FILEHANDLE); + $keccak256_b64 = keccak256_file_b64(*FILEHANDLE); + $keccak256_b64u = keccak256_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::Keccak256; + + $d = Crypt::Digest::Keccak256->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the Keccak256 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::Keccak256 qw(keccak256 keccak256_hex keccak256_b64 keccak256_b64u + keccak256_file keccak256_file_hex keccak256_file_b64 keccak256_file_b64u); + +Or all of them at once: + + use Crypt::Digest::Keccak256 ':all'; + +=head1 FUNCTIONS + +=head2 keccak256 + +Logically joins all arguments into a single string, and returns its Keccak256 digest encoded as a binary string. + + $keccak256_raw = keccak256('data string'); + #or + $keccak256_raw = keccak256('any data', 'more data', 'even more data'); + +=head2 keccak256_hex + +Logically joins all arguments into a single string, and returns its Keccak256 digest encoded as a hexadecimal string. + + $keccak256_hex = keccak256_hex('data string'); + #or + $keccak256_hex = keccak256_hex('any data', 'more data', 'even more data'); + +=head2 keccak256_b64 + +Logically joins all arguments into a single string, and returns its Keccak256 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $keccak256_b64 = keccak256_b64('data string'); + #or + $keccak256_b64 = keccak256_b64('any data', 'more data', 'even more data'); + +=head2 keccak256_b64u + +Logically joins all arguments into a single string, and returns its Keccak256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $keccak256_b64url = keccak256_b64u('data string'); + #or + $keccak256_b64url = keccak256_b64u('any data', 'more data', 'even more data'); + +=head2 keccak256_file + +Reads file (defined by filename or filehandle) content, and returns its Keccak256 digest encoded as a binary string. + + $keccak256_raw = keccak256_file('filename.dat'); + #or + $keccak256_raw = keccak256_file(*FILEHANDLE); + +=head2 keccak256_file_hex + +Reads file (defined by filename or filehandle) content, and returns its Keccak256 digest encoded as a hexadecimal string. + + $keccak256_hex = keccak256_file_hex('filename.dat'); + #or + $keccak256_hex = keccak256_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 keccak256_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its Keccak256 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $keccak256_b64 = keccak256_file_b64('filename.dat'); + #or + $keccak256_b64 = keccak256_file_b64(*FILEHANDLE); + +=head2 keccak256_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its Keccak256 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $keccak256_b64url = keccak256_file_b64u('filename.dat'); + #or + $keccak256_b64url = keccak256_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::Keccak256->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::Keccak256->hashsize(); + #or + Crypt::Digest::Keccak256::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest> + +=item * L<https://keccak.team/index.html> + +=back + +=cut diff --git a/lib/Crypt/Digest/Keccak384.pm b/lib/Crypt/Digest/Keccak384.pm new file mode 100644 index 00000000..017c92d1 --- /dev/null +++ b/lib/Crypt/Digest/Keccak384.pm @@ -0,0 +1,223 @@ +package Crypt::Digest::Keccak384; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.059'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( keccak384 keccak384_hex keccak384_b64 keccak384_b64u keccak384_file keccak384_file_hex keccak384_file_b64 keccak384_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('Keccak384') } +sub keccak384 { Crypt::Digest::digest_data('Keccak384', @_) } +sub keccak384_hex { Crypt::Digest::digest_data_hex('Keccak384', @_) } +sub keccak384_b64 { Crypt::Digest::digest_data_b64('Keccak384', @_) } +sub keccak384_b64u { Crypt::Digest::digest_data_b64u('Keccak384', @_) } +sub keccak384_file { Crypt::Digest::digest_file('Keccak384', @_) } +sub keccak384_file_hex { Crypt::Digest::digest_file_hex('Keccak384', @_) } +sub keccak384_file_b64 { Crypt::Digest::digest_file_b64('Keccak384', @_) } +sub keccak384_file_b64u { Crypt::Digest::digest_file_b64u('Keccak384', @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::Keccak384 - Hash function Keccak-384 [size: 384 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::Keccak384 qw( keccak384 keccak384_hex keccak384_b64 keccak384_b64u + keccak384_file keccak384_file_hex keccak384_file_b64 keccak384_file_b64u ); + + # calculate digest from string/buffer + $keccak384_raw = keccak384('data string'); + $keccak384_hex = keccak384_hex('data string'); + $keccak384_b64 = keccak384_b64('data string'); + $keccak384_b64u = keccak384_b64u('data string'); + # calculate digest from file + $keccak384_raw = keccak384_file('filename.dat'); + $keccak384_hex = keccak384_file_hex('filename.dat'); + $keccak384_b64 = keccak384_file_b64('filename.dat'); + $keccak384_b64u = keccak384_file_b64u('filename.dat'); + # calculate digest from filehandle + $keccak384_raw = keccak384_file(*FILEHANDLE); + $keccak384_hex = keccak384_file_hex(*FILEHANDLE); + $keccak384_b64 = keccak384_file_b64(*FILEHANDLE); + $keccak384_b64u = keccak384_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::Keccak384; + + $d = Crypt::Digest::Keccak384->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the Keccak384 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::Keccak384 qw(keccak384 keccak384_hex keccak384_b64 keccak384_b64u + keccak384_file keccak384_file_hex keccak384_file_b64 keccak384_file_b64u); + +Or all of them at once: + + use Crypt::Digest::Keccak384 ':all'; + +=head1 FUNCTIONS + +=head2 keccak384 + +Logically joins all arguments into a single string, and returns its Keccak384 digest encoded as a binary string. + + $keccak384_raw = keccak384('data string'); + #or + $keccak384_raw = keccak384('any data', 'more data', 'even more data'); + +=head2 keccak384_hex + +Logically joins all arguments into a single string, and returns its Keccak384 digest encoded as a hexadecimal string. + + $keccak384_hex = keccak384_hex('data string'); + #or + $keccak384_hex = keccak384_hex('any data', 'more data', 'even more data'); + +=head2 keccak384_b64 + +Logically joins all arguments into a single string, and returns its Keccak384 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $keccak384_b64 = keccak384_b64('data string'); + #or + $keccak384_b64 = keccak384_b64('any data', 'more data', 'even more data'); + +=head2 keccak384_b64u + +Logically joins all arguments into a single string, and returns its Keccak384 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $keccak384_b64url = keccak384_b64u('data string'); + #or + $keccak384_b64url = keccak384_b64u('any data', 'more data', 'even more data'); + +=head2 keccak384_file + +Reads file (defined by filename or filehandle) content, and returns its Keccak384 digest encoded as a binary string. + + $keccak384_raw = keccak384_file('filename.dat'); + #or + $keccak384_raw = keccak384_file(*FILEHANDLE); + +=head2 keccak384_file_hex + +Reads file (defined by filename or filehandle) content, and returns its Keccak384 digest encoded as a hexadecimal string. + + $keccak384_hex = keccak384_file_hex('filename.dat'); + #or + $keccak384_hex = keccak384_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 keccak384_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its Keccak384 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $keccak384_b64 = keccak384_file_b64('filename.dat'); + #or + $keccak384_b64 = keccak384_file_b64(*FILEHANDLE); + +=head2 keccak384_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its Keccak384 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $keccak384_b64url = keccak384_file_b64u('filename.dat'); + #or + $keccak384_b64url = keccak384_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::Keccak384->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::Keccak384->hashsize(); + #or + Crypt::Digest::Keccak384::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest> + +=item * L<https://keccak.team/index.html> + +=back + +=cut diff --git a/lib/Crypt/Digest/Keccak512.pm b/lib/Crypt/Digest/Keccak512.pm new file mode 100644 index 00000000..9a54bc15 --- /dev/null +++ b/lib/Crypt/Digest/Keccak512.pm @@ -0,0 +1,223 @@ +package Crypt::Digest::Keccak512; + +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; +our $VERSION = '0.059'; + +use base qw(Crypt::Digest Exporter); +our %EXPORT_TAGS = ( all => [qw( keccak512 keccak512_hex keccak512_b64 keccak512_b64u keccak512_file keccak512_file_hex keccak512_file_b64 keccak512_file_b64u )] ); +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +our @EXPORT = qw(); + +use Carp; +$Carp::Internal{(__PACKAGE__)}++; +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('Keccak512') } +sub keccak512 { Crypt::Digest::digest_data('Keccak512', @_) } +sub keccak512_hex { Crypt::Digest::digest_data_hex('Keccak512', @_) } +sub keccak512_b64 { Crypt::Digest::digest_data_b64('Keccak512', @_) } +sub keccak512_b64u { Crypt::Digest::digest_data_b64u('Keccak512', @_) } +sub keccak512_file { Crypt::Digest::digest_file('Keccak512', @_) } +sub keccak512_file_hex { Crypt::Digest::digest_file_hex('Keccak512', @_) } +sub keccak512_file_b64 { Crypt::Digest::digest_file_b64('Keccak512', @_) } +sub keccak512_file_b64u { Crypt::Digest::digest_file_b64u('Keccak512', @_) } + +1; + +=pod + +=head1 NAME + +Crypt::Digest::Keccak512 - Hash function Keccak-512 [size: 512 bits] + +=head1 SYNOPSIS + + ### Functional interface: + use Crypt::Digest::Keccak512 qw( keccak512 keccak512_hex keccak512_b64 keccak512_b64u + keccak512_file keccak512_file_hex keccak512_file_b64 keccak512_file_b64u ); + + # calculate digest from string/buffer + $keccak512_raw = keccak512('data string'); + $keccak512_hex = keccak512_hex('data string'); + $keccak512_b64 = keccak512_b64('data string'); + $keccak512_b64u = keccak512_b64u('data string'); + # calculate digest from file + $keccak512_raw = keccak512_file('filename.dat'); + $keccak512_hex = keccak512_file_hex('filename.dat'); + $keccak512_b64 = keccak512_file_b64('filename.dat'); + $keccak512_b64u = keccak512_file_b64u('filename.dat'); + # calculate digest from filehandle + $keccak512_raw = keccak512_file(*FILEHANDLE); + $keccak512_hex = keccak512_file_hex(*FILEHANDLE); + $keccak512_b64 = keccak512_file_b64(*FILEHANDLE); + $keccak512_b64u = keccak512_file_b64u(*FILEHANDLE); + + ### OO interface: + use Crypt::Digest::Keccak512; + + $d = Crypt::Digest::Keccak512->new; + $d->add('any data'); + $d->addfile('filename.dat'); + $d->addfile(*FILEHANDLE); + $result_raw = $d->digest; # raw bytes + $result_hex = $d->hexdigest; # hexadecimal form + $result_b64 = $d->b64digest; # Base64 form + $result_b64u = $d->b64udigest; # Base64 URL Safe form + +=head1 DESCRIPTION + +Provides an interface to the Keccak512 digest algorithm. + +=head1 EXPORT + +Nothing is exported by default. + +You can export selected functions: + + use Crypt::Digest::Keccak512 qw(keccak512 keccak512_hex keccak512_b64 keccak512_b64u + keccak512_file keccak512_file_hex keccak512_file_b64 keccak512_file_b64u); + +Or all of them at once: + + use Crypt::Digest::Keccak512 ':all'; + +=head1 FUNCTIONS + +=head2 keccak512 + +Logically joins all arguments into a single string, and returns its Keccak512 digest encoded as a binary string. + + $keccak512_raw = keccak512('data string'); + #or + $keccak512_raw = keccak512('any data', 'more data', 'even more data'); + +=head2 keccak512_hex + +Logically joins all arguments into a single string, and returns its Keccak512 digest encoded as a hexadecimal string. + + $keccak512_hex = keccak512_hex('data string'); + #or + $keccak512_hex = keccak512_hex('any data', 'more data', 'even more data'); + +=head2 keccak512_b64 + +Logically joins all arguments into a single string, and returns its Keccak512 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $keccak512_b64 = keccak512_b64('data string'); + #or + $keccak512_b64 = keccak512_b64('any data', 'more data', 'even more data'); + +=head2 keccak512_b64u + +Logically joins all arguments into a single string, and returns its Keccak512 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $keccak512_b64url = keccak512_b64u('data string'); + #or + $keccak512_b64url = keccak512_b64u('any data', 'more data', 'even more data'); + +=head2 keccak512_file + +Reads file (defined by filename or filehandle) content, and returns its Keccak512 digest encoded as a binary string. + + $keccak512_raw = keccak512_file('filename.dat'); + #or + $keccak512_raw = keccak512_file(*FILEHANDLE); + +=head2 keccak512_file_hex + +Reads file (defined by filename or filehandle) content, and returns its Keccak512 digest encoded as a hexadecimal string. + + $keccak512_hex = keccak512_file_hex('filename.dat'); + #or + $keccak512_hex = keccak512_file_hex(*FILEHANDLE); + +B<BEWARE:> You have to make sure that the filehandle is in binary mode before you pass it as argument to the addfile() method. + +=head2 keccak512_file_b64 + +Reads file (defined by filename or filehandle) content, and returns its Keccak512 digest encoded as a Base64 string, B<with> trailing '=' padding. + + $keccak512_b64 = keccak512_file_b64('filename.dat'); + #or + $keccak512_b64 = keccak512_file_b64(*FILEHANDLE); + +=head2 keccak512_file_b64u + +Reads file (defined by filename or filehandle) content, and returns its Keccak512 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). + + $keccak512_b64url = keccak512_file_b64u('filename.dat'); + #or + $keccak512_b64url = keccak512_file_b64u(*FILEHANDLE); + +=head1 METHODS + +The OO interface provides the same set of functions as L<Crypt::Digest>. + +=head2 new + + $d = Crypt::Digest::Keccak512->new(); + +=head2 clone + + $d->clone(); + +=head2 reset + + $d->reset(); + +=head2 add + + $d->add('any data'); + #or + $d->add('any data', 'more data', 'even more data'); + +=head2 addfile + + $d->addfile('filename.dat'); + #or + $d->addfile(*FILEHANDLE); + +=head2 add_bits + + $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010"); + #or + $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16); + +=head2 hashsize + + $d->hashsize; + #or + Crypt::Digest::Keccak512->hashsize(); + #or + Crypt::Digest::Keccak512::hashsize(); + +=head2 digest + + $result_raw = $d->digest(); + +=head2 hexdigest + + $result_hex = $d->hexdigest(); + +=head2 b64digest + + $result_b64 = $d->b64digest(); + +=head2 b64udigest + + $result_b64url = $d->b64udigest(); + +=head1 SEE ALSO + +=over + +=item * L<CryptX|CryptX>, L<Crypt::Digest> + +=item * L<https://keccak.team/index.html> + +=back + +=cut diff --git a/lib/Crypt/Digest/MD2.pm b/lib/Crypt/Digest/MD2.pm index 9d1d5d16..4097df1b 100644 --- a/lib/Crypt/Digest/MD2.pm +++ b/lib/Crypt/Digest/MD2.pm @@ -4,7 +4,7 @@ package Crypt::Digest::MD2; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( md2 md2_hex md2_b64 md2_b64u md2_file md2_file_hex md2_file_b64 md2_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub md2 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub md2_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub md2_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub md2_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub md2_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub md2_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub md2_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub md2_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('MD2') } +sub md2 { Crypt::Digest::digest_data('MD2', @_) } +sub md2_hex { Crypt::Digest::digest_data_hex('MD2', @_) } +sub md2_b64 { Crypt::Digest::digest_data_b64('MD2', @_) } +sub md2_b64u { Crypt::Digest::digest_data_b64u('MD2', @_) } +sub md2_file { Crypt::Digest::digest_file('MD2', @_) } +sub md2_file_hex { Crypt::Digest::digest_file_hex('MD2', @_) } +sub md2_file_b64 { Crypt::Digest::digest_file_b64('MD2', @_) } +sub md2_file_b64u { Crypt::Digest::digest_file_b64u('MD2', @_) } 1; diff --git a/lib/Crypt/Digest/MD4.pm b/lib/Crypt/Digest/MD4.pm index 2e1171ab..d8e6d447 100644 --- a/lib/Crypt/Digest/MD4.pm +++ b/lib/Crypt/Digest/MD4.pm @@ -4,7 +4,7 @@ package Crypt::Digest::MD4; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( md4 md4_hex md4_b64 md4_b64u md4_file md4_file_hex md4_file_b64 md4_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub md4 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub md4_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub md4_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub md4_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub md4_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub md4_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub md4_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub md4_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('MD4') } +sub md4 { Crypt::Digest::digest_data('MD4', @_) } +sub md4_hex { Crypt::Digest::digest_data_hex('MD4', @_) } +sub md4_b64 { Crypt::Digest::digest_data_b64('MD4', @_) } +sub md4_b64u { Crypt::Digest::digest_data_b64u('MD4', @_) } +sub md4_file { Crypt::Digest::digest_file('MD4', @_) } +sub md4_file_hex { Crypt::Digest::digest_file_hex('MD4', @_) } +sub md4_file_b64 { Crypt::Digest::digest_file_b64('MD4', @_) } +sub md4_file_b64u { Crypt::Digest::digest_file_b64u('MD4', @_) } 1; diff --git a/lib/Crypt/Digest/MD5.pm b/lib/Crypt/Digest/MD5.pm index 27842228..65d99ee9 100644 --- a/lib/Crypt/Digest/MD5.pm +++ b/lib/Crypt/Digest/MD5.pm @@ -4,7 +4,7 @@ package Crypt::Digest::MD5; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( md5 md5_hex md5_b64 md5_b64u md5_file md5_file_hex md5_file_b64 md5_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub md5 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub md5_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub md5_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub md5_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub md5_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub md5_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub md5_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub md5_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('MD5') } +sub md5 { Crypt::Digest::digest_data('MD5', @_) } +sub md5_hex { Crypt::Digest::digest_data_hex('MD5', @_) } +sub md5_b64 { Crypt::Digest::digest_data_b64('MD5', @_) } +sub md5_b64u { Crypt::Digest::digest_data_b64u('MD5', @_) } +sub md5_file { Crypt::Digest::digest_file('MD5', @_) } +sub md5_file_hex { Crypt::Digest::digest_file_hex('MD5', @_) } +sub md5_file_b64 { Crypt::Digest::digest_file_b64('MD5', @_) } +sub md5_file_b64u { Crypt::Digest::digest_file_b64u('MD5', @_) } 1; diff --git a/lib/Crypt/Digest/RIPEMD128.pm b/lib/Crypt/Digest/RIPEMD128.pm index 60a41c11..1683b212 100644 --- a/lib/Crypt/Digest/RIPEMD128.pm +++ b/lib/Crypt/Digest/RIPEMD128.pm @@ -4,7 +4,7 @@ package Crypt::Digest::RIPEMD128; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( ripemd128 ripemd128_hex ripemd128_b64 ripemd128_b64u ripemd128_file ripemd128_file_hex ripemd128_file_b64 ripemd128_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub ripemd128 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub ripemd128_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub ripemd128_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub ripemd128_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub ripemd128_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub ripemd128_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub ripemd128_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub ripemd128_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('RIPEMD128') } +sub ripemd128 { Crypt::Digest::digest_data('RIPEMD128', @_) } +sub ripemd128_hex { Crypt::Digest::digest_data_hex('RIPEMD128', @_) } +sub ripemd128_b64 { Crypt::Digest::digest_data_b64('RIPEMD128', @_) } +sub ripemd128_b64u { Crypt::Digest::digest_data_b64u('RIPEMD128', @_) } +sub ripemd128_file { Crypt::Digest::digest_file('RIPEMD128', @_) } +sub ripemd128_file_hex { Crypt::Digest::digest_file_hex('RIPEMD128', @_) } +sub ripemd128_file_b64 { Crypt::Digest::digest_file_b64('RIPEMD128', @_) } +sub ripemd128_file_b64u { Crypt::Digest::digest_file_b64u('RIPEMD128', @_) } 1; diff --git a/lib/Crypt/Digest/RIPEMD160.pm b/lib/Crypt/Digest/RIPEMD160.pm index 574b2570..7dcc7851 100644 --- a/lib/Crypt/Digest/RIPEMD160.pm +++ b/lib/Crypt/Digest/RIPEMD160.pm @@ -4,7 +4,7 @@ package Crypt::Digest::RIPEMD160; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( ripemd160 ripemd160_hex ripemd160_b64 ripemd160_b64u ripemd160_file ripemd160_file_hex ripemd160_file_b64 ripemd160_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub ripemd160 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub ripemd160_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub ripemd160_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub ripemd160_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub ripemd160_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub ripemd160_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub ripemd160_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub ripemd160_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('RIPEMD160') } +sub ripemd160 { Crypt::Digest::digest_data('RIPEMD160', @_) } +sub ripemd160_hex { Crypt::Digest::digest_data_hex('RIPEMD160', @_) } +sub ripemd160_b64 { Crypt::Digest::digest_data_b64('RIPEMD160', @_) } +sub ripemd160_b64u { Crypt::Digest::digest_data_b64u('RIPEMD160', @_) } +sub ripemd160_file { Crypt::Digest::digest_file('RIPEMD160', @_) } +sub ripemd160_file_hex { Crypt::Digest::digest_file_hex('RIPEMD160', @_) } +sub ripemd160_file_b64 { Crypt::Digest::digest_file_b64('RIPEMD160', @_) } +sub ripemd160_file_b64u { Crypt::Digest::digest_file_b64u('RIPEMD160', @_) } 1; diff --git a/lib/Crypt/Digest/RIPEMD256.pm b/lib/Crypt/Digest/RIPEMD256.pm index 7909090f..f7ff62ae 100644 --- a/lib/Crypt/Digest/RIPEMD256.pm +++ b/lib/Crypt/Digest/RIPEMD256.pm @@ -4,7 +4,7 @@ package Crypt::Digest::RIPEMD256; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( ripemd256 ripemd256_hex ripemd256_b64 ripemd256_b64u ripemd256_file ripemd256_file_hex ripemd256_file_b64 ripemd256_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub ripemd256 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub ripemd256_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub ripemd256_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub ripemd256_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub ripemd256_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub ripemd256_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub ripemd256_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub ripemd256_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('RIPEMD256') } +sub ripemd256 { Crypt::Digest::digest_data('RIPEMD256', @_) } +sub ripemd256_hex { Crypt::Digest::digest_data_hex('RIPEMD256', @_) } +sub ripemd256_b64 { Crypt::Digest::digest_data_b64('RIPEMD256', @_) } +sub ripemd256_b64u { Crypt::Digest::digest_data_b64u('RIPEMD256', @_) } +sub ripemd256_file { Crypt::Digest::digest_file('RIPEMD256', @_) } +sub ripemd256_file_hex { Crypt::Digest::digest_file_hex('RIPEMD256', @_) } +sub ripemd256_file_b64 { Crypt::Digest::digest_file_b64('RIPEMD256', @_) } +sub ripemd256_file_b64u { Crypt::Digest::digest_file_b64u('RIPEMD256', @_) } 1; diff --git a/lib/Crypt/Digest/RIPEMD320.pm b/lib/Crypt/Digest/RIPEMD320.pm index 4868aeda..c2e8e0d0 100644 --- a/lib/Crypt/Digest/RIPEMD320.pm +++ b/lib/Crypt/Digest/RIPEMD320.pm @@ -4,7 +4,7 @@ package Crypt::Digest::RIPEMD320; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( ripemd320 ripemd320_hex ripemd320_b64 ripemd320_b64u ripemd320_file ripemd320_file_hex ripemd320_file_b64 ripemd320_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub ripemd320 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub ripemd320_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub ripemd320_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub ripemd320_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub ripemd320_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub ripemd320_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub ripemd320_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub ripemd320_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('RIPEMD320') } +sub ripemd320 { Crypt::Digest::digest_data('RIPEMD320', @_) } +sub ripemd320_hex { Crypt::Digest::digest_data_hex('RIPEMD320', @_) } +sub ripemd320_b64 { Crypt::Digest::digest_data_b64('RIPEMD320', @_) } +sub ripemd320_b64u { Crypt::Digest::digest_data_b64u('RIPEMD320', @_) } +sub ripemd320_file { Crypt::Digest::digest_file('RIPEMD320', @_) } +sub ripemd320_file_hex { Crypt::Digest::digest_file_hex('RIPEMD320', @_) } +sub ripemd320_file_b64 { Crypt::Digest::digest_file_b64('RIPEMD320', @_) } +sub ripemd320_file_b64u { Crypt::Digest::digest_file_b64u('RIPEMD320', @_) } 1; diff --git a/lib/Crypt/Digest/SHA1.pm b/lib/Crypt/Digest/SHA1.pm index fcabebdc..9e994d0c 100644 --- a/lib/Crypt/Digest/SHA1.pm +++ b/lib/Crypt/Digest/SHA1.pm @@ -4,7 +4,7 @@ package Crypt::Digest::SHA1; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( sha1 sha1_hex sha1_b64 sha1_b64u sha1_file sha1_file_hex sha1_file_b64 sha1_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub sha1 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub sha1_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub sha1_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub sha1_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub sha1_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub sha1_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub sha1_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub sha1_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('SHA1') } +sub sha1 { Crypt::Digest::digest_data('SHA1', @_) } +sub sha1_hex { Crypt::Digest::digest_data_hex('SHA1', @_) } +sub sha1_b64 { Crypt::Digest::digest_data_b64('SHA1', @_) } +sub sha1_b64u { Crypt::Digest::digest_data_b64u('SHA1', @_) } +sub sha1_file { Crypt::Digest::digest_file('SHA1', @_) } +sub sha1_file_hex { Crypt::Digest::digest_file_hex('SHA1', @_) } +sub sha1_file_b64 { Crypt::Digest::digest_file_b64('SHA1', @_) } +sub sha1_file_b64u { Crypt::Digest::digest_file_b64u('SHA1', @_) } 1; diff --git a/lib/Crypt/Digest/SHA224.pm b/lib/Crypt/Digest/SHA224.pm index da34dd31..5afdac75 100644 --- a/lib/Crypt/Digest/SHA224.pm +++ b/lib/Crypt/Digest/SHA224.pm @@ -4,7 +4,7 @@ package Crypt::Digest::SHA224; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( sha224 sha224_hex sha224_b64 sha224_b64u sha224_file sha224_file_hex sha224_file_b64 sha224_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub sha224 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub sha224_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub sha224_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub sha224_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub sha224_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub sha224_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub sha224_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub sha224_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('SHA224') } +sub sha224 { Crypt::Digest::digest_data('SHA224', @_) } +sub sha224_hex { Crypt::Digest::digest_data_hex('SHA224', @_) } +sub sha224_b64 { Crypt::Digest::digest_data_b64('SHA224', @_) } +sub sha224_b64u { Crypt::Digest::digest_data_b64u('SHA224', @_) } +sub sha224_file { Crypt::Digest::digest_file('SHA224', @_) } +sub sha224_file_hex { Crypt::Digest::digest_file_hex('SHA224', @_) } +sub sha224_file_b64 { Crypt::Digest::digest_file_b64('SHA224', @_) } +sub sha224_file_b64u { Crypt::Digest::digest_file_b64u('SHA224', @_) } 1; diff --git a/lib/Crypt/Digest/SHA256.pm b/lib/Crypt/Digest/SHA256.pm index e5259130..d81ce7e8 100644 --- a/lib/Crypt/Digest/SHA256.pm +++ b/lib/Crypt/Digest/SHA256.pm @@ -4,7 +4,7 @@ package Crypt::Digest::SHA256; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( sha256 sha256_hex sha256_b64 sha256_b64u sha256_file sha256_file_hex sha256_file_b64 sha256_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub sha256 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub sha256_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub sha256_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub sha256_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub sha256_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub sha256_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub sha256_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub sha256_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('SHA256') } +sub sha256 { Crypt::Digest::digest_data('SHA256', @_) } +sub sha256_hex { Crypt::Digest::digest_data_hex('SHA256', @_) } +sub sha256_b64 { Crypt::Digest::digest_data_b64('SHA256', @_) } +sub sha256_b64u { Crypt::Digest::digest_data_b64u('SHA256', @_) } +sub sha256_file { Crypt::Digest::digest_file('SHA256', @_) } +sub sha256_file_hex { Crypt::Digest::digest_file_hex('SHA256', @_) } +sub sha256_file_b64 { Crypt::Digest::digest_file_b64('SHA256', @_) } +sub sha256_file_b64u { Crypt::Digest::digest_file_b64u('SHA256', @_) } 1; diff --git a/lib/Crypt/Digest/SHA384.pm b/lib/Crypt/Digest/SHA384.pm index 4cf820e7..79fdd8c3 100644 --- a/lib/Crypt/Digest/SHA384.pm +++ b/lib/Crypt/Digest/SHA384.pm @@ -4,7 +4,7 @@ package Crypt::Digest::SHA384; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( sha384 sha384_hex sha384_b64 sha384_b64u sha384_file sha384_file_hex sha384_file_b64 sha384_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub sha384 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub sha384_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub sha384_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub sha384_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub sha384_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub sha384_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub sha384_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub sha384_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('SHA384') } +sub sha384 { Crypt::Digest::digest_data('SHA384', @_) } +sub sha384_hex { Crypt::Digest::digest_data_hex('SHA384', @_) } +sub sha384_b64 { Crypt::Digest::digest_data_b64('SHA384', @_) } +sub sha384_b64u { Crypt::Digest::digest_data_b64u('SHA384', @_) } +sub sha384_file { Crypt::Digest::digest_file('SHA384', @_) } +sub sha384_file_hex { Crypt::Digest::digest_file_hex('SHA384', @_) } +sub sha384_file_b64 { Crypt::Digest::digest_file_b64('SHA384', @_) } +sub sha384_file_b64u { Crypt::Digest::digest_file_b64u('SHA384', @_) } 1; diff --git a/lib/Crypt/Digest/SHA3_224.pm b/lib/Crypt/Digest/SHA3_224.pm index 5f2d334d..8eb3a82b 100644 --- a/lib/Crypt/Digest/SHA3_224.pm +++ b/lib/Crypt/Digest/SHA3_224.pm @@ -4,7 +4,7 @@ package Crypt::Digest::SHA3_224; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( sha3_224 sha3_224_hex sha3_224_b64 sha3_224_b64u sha3_224_file sha3_224_file_hex sha3_224_file_b64 sha3_224_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub sha3_224 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub sha3_224_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub sha3_224_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub sha3_224_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub sha3_224_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub sha3_224_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub sha3_224_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub sha3_224_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('SHA3_224') } +sub sha3_224 { Crypt::Digest::digest_data('SHA3_224', @_) } +sub sha3_224_hex { Crypt::Digest::digest_data_hex('SHA3_224', @_) } +sub sha3_224_b64 { Crypt::Digest::digest_data_b64('SHA3_224', @_) } +sub sha3_224_b64u { Crypt::Digest::digest_data_b64u('SHA3_224', @_) } +sub sha3_224_file { Crypt::Digest::digest_file('SHA3_224', @_) } +sub sha3_224_file_hex { Crypt::Digest::digest_file_hex('SHA3_224', @_) } +sub sha3_224_file_b64 { Crypt::Digest::digest_file_b64('SHA3_224', @_) } +sub sha3_224_file_b64u { Crypt::Digest::digest_file_b64u('SHA3_224', @_) } 1; diff --git a/lib/Crypt/Digest/SHA3_256.pm b/lib/Crypt/Digest/SHA3_256.pm index dffda719..75828ad2 100644 --- a/lib/Crypt/Digest/SHA3_256.pm +++ b/lib/Crypt/Digest/SHA3_256.pm @@ -4,7 +4,7 @@ package Crypt::Digest::SHA3_256; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( sha3_256 sha3_256_hex sha3_256_b64 sha3_256_b64u sha3_256_file sha3_256_file_hex sha3_256_file_b64 sha3_256_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub sha3_256 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub sha3_256_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub sha3_256_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub sha3_256_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub sha3_256_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub sha3_256_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub sha3_256_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub sha3_256_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('SHA3_256') } +sub sha3_256 { Crypt::Digest::digest_data('SHA3_256', @_) } +sub sha3_256_hex { Crypt::Digest::digest_data_hex('SHA3_256', @_) } +sub sha3_256_b64 { Crypt::Digest::digest_data_b64('SHA3_256', @_) } +sub sha3_256_b64u { Crypt::Digest::digest_data_b64u('SHA3_256', @_) } +sub sha3_256_file { Crypt::Digest::digest_file('SHA3_256', @_) } +sub sha3_256_file_hex { Crypt::Digest::digest_file_hex('SHA3_256', @_) } +sub sha3_256_file_b64 { Crypt::Digest::digest_file_b64('SHA3_256', @_) } +sub sha3_256_file_b64u { Crypt::Digest::digest_file_b64u('SHA3_256', @_) } 1; diff --git a/lib/Crypt/Digest/SHA3_384.pm b/lib/Crypt/Digest/SHA3_384.pm index cfcb8c8e..3d15489f 100644 --- a/lib/Crypt/Digest/SHA3_384.pm +++ b/lib/Crypt/Digest/SHA3_384.pm @@ -4,7 +4,7 @@ package Crypt::Digest::SHA3_384; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( sha3_384 sha3_384_hex sha3_384_b64 sha3_384_b64u sha3_384_file sha3_384_file_hex sha3_384_file_b64 sha3_384_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub sha3_384 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub sha3_384_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub sha3_384_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub sha3_384_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub sha3_384_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub sha3_384_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub sha3_384_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub sha3_384_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('SHA3_384') } +sub sha3_384 { Crypt::Digest::digest_data('SHA3_384', @_) } +sub sha3_384_hex { Crypt::Digest::digest_data_hex('SHA3_384', @_) } +sub sha3_384_b64 { Crypt::Digest::digest_data_b64('SHA3_384', @_) } +sub sha3_384_b64u { Crypt::Digest::digest_data_b64u('SHA3_384', @_) } +sub sha3_384_file { Crypt::Digest::digest_file('SHA3_384', @_) } +sub sha3_384_file_hex { Crypt::Digest::digest_file_hex('SHA3_384', @_) } +sub sha3_384_file_b64 { Crypt::Digest::digest_file_b64('SHA3_384', @_) } +sub sha3_384_file_b64u { Crypt::Digest::digest_file_b64u('SHA3_384', @_) } 1; diff --git a/lib/Crypt/Digest/SHA3_512.pm b/lib/Crypt/Digest/SHA3_512.pm index d2c8aa17..27afec41 100644 --- a/lib/Crypt/Digest/SHA3_512.pm +++ b/lib/Crypt/Digest/SHA3_512.pm @@ -4,7 +4,7 @@ package Crypt::Digest::SHA3_512; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( sha3_512 sha3_512_hex sha3_512_b64 sha3_512_b64u sha3_512_file sha3_512_file_hex sha3_512_file_b64 sha3_512_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub sha3_512 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub sha3_512_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub sha3_512_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub sha3_512_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub sha3_512_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub sha3_512_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub sha3_512_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub sha3_512_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('SHA3_512') } +sub sha3_512 { Crypt::Digest::digest_data('SHA3_512', @_) } +sub sha3_512_hex { Crypt::Digest::digest_data_hex('SHA3_512', @_) } +sub sha3_512_b64 { Crypt::Digest::digest_data_b64('SHA3_512', @_) } +sub sha3_512_b64u { Crypt::Digest::digest_data_b64u('SHA3_512', @_) } +sub sha3_512_file { Crypt::Digest::digest_file('SHA3_512', @_) } +sub sha3_512_file_hex { Crypt::Digest::digest_file_hex('SHA3_512', @_) } +sub sha3_512_file_b64 { Crypt::Digest::digest_file_b64('SHA3_512', @_) } +sub sha3_512_file_b64u { Crypt::Digest::digest_file_b64u('SHA3_512', @_) } 1; diff --git a/lib/Crypt/Digest/SHA512.pm b/lib/Crypt/Digest/SHA512.pm index c12ed5a5..7ba414a2 100644 --- a/lib/Crypt/Digest/SHA512.pm +++ b/lib/Crypt/Digest/SHA512.pm @@ -4,7 +4,7 @@ package Crypt::Digest::SHA512; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( sha512 sha512_hex sha512_b64 sha512_b64u sha512_file sha512_file_hex sha512_file_b64 sha512_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub sha512 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub sha512_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub sha512_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub sha512_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub sha512_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub sha512_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub sha512_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub sha512_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('SHA512') } +sub sha512 { Crypt::Digest::digest_data('SHA512', @_) } +sub sha512_hex { Crypt::Digest::digest_data_hex('SHA512', @_) } +sub sha512_b64 { Crypt::Digest::digest_data_b64('SHA512', @_) } +sub sha512_b64u { Crypt::Digest::digest_data_b64u('SHA512', @_) } +sub sha512_file { Crypt::Digest::digest_file('SHA512', @_) } +sub sha512_file_hex { Crypt::Digest::digest_file_hex('SHA512', @_) } +sub sha512_file_b64 { Crypt::Digest::digest_file_b64('SHA512', @_) } +sub sha512_file_b64u { Crypt::Digest::digest_file_b64u('SHA512', @_) } 1; diff --git a/lib/Crypt/Digest/SHA512_224.pm b/lib/Crypt/Digest/SHA512_224.pm index 7d719ba6..1f83b53f 100644 --- a/lib/Crypt/Digest/SHA512_224.pm +++ b/lib/Crypt/Digest/SHA512_224.pm @@ -4,7 +4,7 @@ package Crypt::Digest::SHA512_224; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( sha512_224 sha512_224_hex sha512_224_b64 sha512_224_b64u sha512_224_file sha512_224_file_hex sha512_224_file_b64 sha512_224_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub sha512_224 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub sha512_224_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub sha512_224_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub sha512_224_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub sha512_224_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub sha512_224_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub sha512_224_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub sha512_224_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('SHA512_224') } +sub sha512_224 { Crypt::Digest::digest_data('SHA512_224', @_) } +sub sha512_224_hex { Crypt::Digest::digest_data_hex('SHA512_224', @_) } +sub sha512_224_b64 { Crypt::Digest::digest_data_b64('SHA512_224', @_) } +sub sha512_224_b64u { Crypt::Digest::digest_data_b64u('SHA512_224', @_) } +sub sha512_224_file { Crypt::Digest::digest_file('SHA512_224', @_) } +sub sha512_224_file_hex { Crypt::Digest::digest_file_hex('SHA512_224', @_) } +sub sha512_224_file_b64 { Crypt::Digest::digest_file_b64('SHA512_224', @_) } +sub sha512_224_file_b64u { Crypt::Digest::digest_file_b64u('SHA512_224', @_) } 1; diff --git a/lib/Crypt/Digest/SHA512_256.pm b/lib/Crypt/Digest/SHA512_256.pm index 625855ce..fb8d92d2 100644 --- a/lib/Crypt/Digest/SHA512_256.pm +++ b/lib/Crypt/Digest/SHA512_256.pm @@ -4,7 +4,7 @@ package Crypt::Digest::SHA512_256; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( sha512_256 sha512_256_hex sha512_256_b64 sha512_256_b64u sha512_256_file sha512_256_file_hex sha512_256_file_b64 sha512_256_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub sha512_256 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub sha512_256_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub sha512_256_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub sha512_256_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub sha512_256_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub sha512_256_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub sha512_256_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub sha512_256_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('SHA512_256') } +sub sha512_256 { Crypt::Digest::digest_data('SHA512_256', @_) } +sub sha512_256_hex { Crypt::Digest::digest_data_hex('SHA512_256', @_) } +sub sha512_256_b64 { Crypt::Digest::digest_data_b64('SHA512_256', @_) } +sub sha512_256_b64u { Crypt::Digest::digest_data_b64u('SHA512_256', @_) } +sub sha512_256_file { Crypt::Digest::digest_file('SHA512_256', @_) } +sub sha512_256_file_hex { Crypt::Digest::digest_file_hex('SHA512_256', @_) } +sub sha512_256_file_b64 { Crypt::Digest::digest_file_b64('SHA512_256', @_) } +sub sha512_256_file_b64u { Crypt::Digest::digest_file_b64u('SHA512_256', @_) } 1; diff --git a/lib/Crypt/Digest/SHAKE.pm b/lib/Crypt/Digest/SHAKE.pm index c5bbabfc..90dd48f4 100644 --- a/lib/Crypt/Digest/SHAKE.pm +++ b/lib/Crypt/Digest/SHAKE.pm @@ -2,14 +2,12 @@ package Crypt::Digest::SHAKE; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use Carp; $Carp::Internal{(__PACKAGE__)}++; use CryptX; -sub new { my $class = shift; _new(@_) } - sub addfile { my ($self, $file) = @_; diff --git a/lib/Crypt/Digest/Tiger192.pm b/lib/Crypt/Digest/Tiger192.pm index 97ba660f..8b248ac6 100644 --- a/lib/Crypt/Digest/Tiger192.pm +++ b/lib/Crypt/Digest/Tiger192.pm @@ -4,7 +4,7 @@ package Crypt::Digest::Tiger192; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( tiger192 tiger192_hex tiger192_b64 tiger192_b64u tiger192_file tiger192_file_hex tiger192_file_b64 tiger192_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub tiger192 { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub tiger192_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub tiger192_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub tiger192_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub tiger192_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub tiger192_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub tiger192_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub tiger192_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('Tiger192') } +sub tiger192 { Crypt::Digest::digest_data('Tiger192', @_) } +sub tiger192_hex { Crypt::Digest::digest_data_hex('Tiger192', @_) } +sub tiger192_b64 { Crypt::Digest::digest_data_b64('Tiger192', @_) } +sub tiger192_b64u { Crypt::Digest::digest_data_b64u('Tiger192', @_) } +sub tiger192_file { Crypt::Digest::digest_file('Tiger192', @_) } +sub tiger192_file_hex { Crypt::Digest::digest_file_hex('Tiger192', @_) } +sub tiger192_file_b64 { Crypt::Digest::digest_file_b64('Tiger192', @_) } +sub tiger192_file_b64u { Crypt::Digest::digest_file_b64u('Tiger192', @_) } 1; diff --git a/lib/Crypt/Digest/Whirlpool.pm b/lib/Crypt/Digest/Whirlpool.pm index 37b4b549..d86bbc4d 100644 --- a/lib/Crypt/Digest/Whirlpool.pm +++ b/lib/Crypt/Digest/Whirlpool.pm @@ -4,7 +4,7 @@ package Crypt::Digest::Whirlpool; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Digest Exporter); our %EXPORT_TAGS = ( all => [qw( whirlpool whirlpool_hex whirlpool_b64 whirlpool_b64u whirlpool_file whirlpool_file_hex whirlpool_file_b64 whirlpool_file_b64u )] ); @@ -13,19 +13,17 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; -use CryptX; - -sub hashsize { Crypt::Digest::hashsize(__PACKAGE__) } - -sub whirlpool { Crypt::Digest::digest_data(__PACKAGE__, @_) } -sub whirlpool_hex { Crypt::Digest::digest_data_hex(__PACKAGE__, @_) } -sub whirlpool_b64 { Crypt::Digest::digest_data_b64(__PACKAGE__, @_) } -sub whirlpool_b64u { Crypt::Digest::digest_data_b64u(__PACKAGE__, @_) } - -sub whirlpool_file { Crypt::Digest::digest_file(__PACKAGE__, @_) } -sub whirlpool_file_hex { Crypt::Digest::digest_file_hex(__PACKAGE__, @_) } -sub whirlpool_file_b64 { Crypt::Digest::digest_file_b64(__PACKAGE__, @_) } -sub whirlpool_file_b64u { Crypt::Digest::digest_file_b64u(__PACKAGE__, @_) } +use Crypt::Digest; + +sub hashsize { Crypt::Digest::hashsize('Whirlpool') } +sub whirlpool { Crypt::Digest::digest_data('Whirlpool', @_) } +sub whirlpool_hex { Crypt::Digest::digest_data_hex('Whirlpool', @_) } +sub whirlpool_b64 { Crypt::Digest::digest_data_b64('Whirlpool', @_) } +sub whirlpool_b64u { Crypt::Digest::digest_data_b64u('Whirlpool', @_) } +sub whirlpool_file { Crypt::Digest::digest_file('Whirlpool', @_) } +sub whirlpool_file_hex { Crypt::Digest::digest_file_hex('Whirlpool', @_) } +sub whirlpool_file_b64 { Crypt::Digest::digest_file_b64('Whirlpool', @_) } +sub whirlpool_file_b64u { Crypt::Digest::digest_file_b64u('Whirlpool', @_) } 1; diff --git a/lib/Crypt/KeyDerivation.pm b/lib/Crypt/KeyDerivation.pm index fa33215a..ea0b2d27 100644 --- a/lib/Crypt/KeyDerivation.pm +++ b/lib/Crypt/KeyDerivation.pm @@ -2,7 +2,7 @@ package Crypt::KeyDerivation; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; our %EXPORT_TAGS = ( all => [qw(pbkdf1 pbkdf2 hkdf hkdf_expand hkdf_extract)] ); @@ -12,57 +12,6 @@ our @EXPORT = qw(); use Carp; $Carp::Internal{(__PACKAGE__)}++; use CryptX; -use Crypt::Digest; - -sub pbkdf1 { - my ($password, $salt, $iteration_count, $hash_name, $len) = @_; - $iteration_count ||= 5000; - $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA256'); - $len ||= 32; - local $SIG{__DIE__} = \&CryptX::_croak; - return _pkcs_5_alg1($password, $salt, $iteration_count, $hash_name, $len); -} - -sub pbkdf2 { - my ($password, $salt, $iteration_count, $hash_name, $len) = @_; - $iteration_count ||= 5000; - $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA256'); - $len ||= 32; - local $SIG{__DIE__} = \&CryptX::_croak; - return _pkcs_5_alg2($password, $salt, $iteration_count, $hash_name, $len); -} - -sub hkdf_extract { - # RFC: HKDF-Extract(salt, IKM, [Hash]) -> PRK - #my ($hash_name, $salt, $keying_material) = @_; - my ($keying_material, $salt, $hash_name) = @_; - $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA256'); - $salt = pack("H*", "00" x Crypt::Digest->hashsize($hash_name)) unless defined $salt; # according to rfc5869 defaults to HashLen zero octets - local $SIG{__DIE__} = \&CryptX::_croak; - return _hkdf_extract($hash_name, $salt, $keying_material); -} - -sub hkdf_expand { - # RFC: HKDF-Expand(PRK, info, L, [Hash]) -> OKM - #my ($hash_name, $info, $keying_material, $len) = @_; - my ($keying_material, $hash_name, $len, $info) = @_; - $len ||= 32; - $info ||= ''; - $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA256'); - local $SIG{__DIE__} = \&CryptX::_croak; - return _hkdf_expand($hash_name, $info, $keying_material, $len); -} - -sub hkdf { - #my ($hash_name, $salt, $info, $keying_material, $len) = @_; - my ($keying_material, $salt, $hash_name, $len, $info) = @_; - $len ||= 32; - $info ||= ''; - $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA256'); - $salt = pack("H*", "00" x Crypt::Digest->hashsize($hash_name)) unless defined $salt; # according to rfc5869 defaults to HashLen zero octets - local $SIG{__DIE__} = \&CryptX::_croak; - return _hkdf($hash_name, $salt, $info, $keying_material, $len); -} 1; diff --git a/lib/Crypt/Mac.pm b/lib/Crypt/Mac.pm index adf35217..8d6f696b 100644 --- a/lib/Crypt/Mac.pm +++ b/lib/Crypt/Mac.pm @@ -2,35 +2,21 @@ package Crypt::Mac; use strict; use warnings; -our $VERSION = '0.056'; - -require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; -our %EXPORT_TAGS = ( all => [qw( mac mac_hex )] ); -our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); -our @EXPORT = qw(); +our $VERSION = '0.059'; use Carp; $Carp::Internal{(__PACKAGE__)}++; use CryptX; -sub add { - my $self = shift; - local $SIG{__DIE__} = \&CryptX::_croak; - $self->_add_single($_) for (@_); - return $self; -} - sub addfile { my ($self, $file) = @_; my $handle; if (ref(\$file) eq 'SCALAR') { - #filename open($handle, "<", $file) || die "FATAL: cannot open '$file': $!"; binmode($handle); } else { - #handle $handle = $file } die "FATAL: invalid handle" unless defined $handle; @@ -39,7 +25,7 @@ sub addfile { my $buf = ""; local $SIG{__DIE__} = \&CryptX::_croak; while (($n = read($handle, $buf, 32*1024))) { - $self->_add_single($buf) + $self->add($buf); } die "FATAL: read failed: $!" unless defined $n; diff --git a/lib/Crypt/Mac/BLAKE2b.pm b/lib/Crypt/Mac/BLAKE2b.pm index 95905290..26b12d02 100644 --- a/lib/Crypt/Mac/BLAKE2b.pm +++ b/lib/Crypt/Mac/BLAKE2b.pm @@ -4,20 +4,13 @@ package Crypt::Mac::BLAKE2b; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Mac Exporter); our %EXPORT_TAGS = ( all => [qw( blake2b blake2b_hex blake2b_b64 blake2b_b64u )] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); -use CryptX; -sub new { my $class = shift; _new(@_) } -sub blake2b { Crypt::Mac::BLAKE2b->new(shift, shift)->add(@_)->mac } -sub blake2b_hex { Crypt::Mac::BLAKE2b->new(shift, shift)->add(@_)->hexmac } -sub blake2b_b64 { Crypt::Mac::BLAKE2b->new(shift, shift)->add(@_)->b64mac } -sub blake2b_b64u { Crypt::Mac::BLAKE2b->new(shift, shift)->add(@_)->b64umac } - 1; =pod diff --git a/lib/Crypt/Mac/BLAKE2s.pm b/lib/Crypt/Mac/BLAKE2s.pm index 02951e4a..2faab14e 100644 --- a/lib/Crypt/Mac/BLAKE2s.pm +++ b/lib/Crypt/Mac/BLAKE2s.pm @@ -4,20 +4,13 @@ package Crypt::Mac::BLAKE2s; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Mac Exporter); our %EXPORT_TAGS = ( all => [qw( blake2s blake2s_hex blake2s_b64 blake2s_b64u )] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); -use CryptX; -sub new { my $class = shift; _new(@_) } -sub blake2s { Crypt::Mac::BLAKE2s->new(shift, shift)->add(@_)->mac } -sub blake2s_hex { Crypt::Mac::BLAKE2s->new(shift, shift)->add(@_)->hexmac } -sub blake2s_b64 { Crypt::Mac::BLAKE2s->new(shift, shift)->add(@_)->b64mac } -sub blake2s_b64u { Crypt::Mac::BLAKE2s->new(shift, shift)->add(@_)->b64umac } - 1; =pod diff --git a/lib/Crypt/Mac/F9.pm b/lib/Crypt/Mac/F9.pm index 311d0624..9310ab5c 100644 --- a/lib/Crypt/Mac/F9.pm +++ b/lib/Crypt/Mac/F9.pm @@ -4,22 +4,13 @@ package Crypt::Mac::F9; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Mac Exporter); our %EXPORT_TAGS = ( all => [qw( f9 f9_hex f9_b64 f9_b64u )] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); -use CryptX; -use Crypt::Cipher; - -sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } -sub f9 { Crypt::Mac::F9->new(shift, shift)->add(@_)->mac } -sub f9_hex { Crypt::Mac::F9->new(shift, shift)->add(@_)->hexmac } -sub f9_b64 { Crypt::Mac::F9->new(shift, shift)->add(@_)->b64mac } -sub f9_b64u { Crypt::Mac::F9->new(shift, shift)->add(@_)->b64umac } - 1; =pod diff --git a/lib/Crypt/Mac/HMAC.pm b/lib/Crypt/Mac/HMAC.pm index 618e41bd..f381f74a 100644 --- a/lib/Crypt/Mac/HMAC.pm +++ b/lib/Crypt/Mac/HMAC.pm @@ -4,22 +4,13 @@ package Crypt::Mac::HMAC; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Mac Exporter); our %EXPORT_TAGS = ( all => [qw( hmac hmac_hex hmac_b64 hmac_b64u )] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); -use CryptX; -use Crypt::Digest; - -sub new { my $class = shift; _new(Crypt::Digest::_trans_digest_name(shift), @_) } -sub hmac { Crypt::Mac::HMAC->new(shift, shift)->add(@_)->mac } -sub hmac_hex { Crypt::Mac::HMAC->new(shift, shift)->add(@_)->hexmac } -sub hmac_b64 { Crypt::Mac::HMAC->new(shift, shift)->add(@_)->b64mac } -sub hmac_b64u { Crypt::Mac::HMAC->new(shift, shift)->add(@_)->b64umac } - 1; =pod diff --git a/lib/Crypt/Mac/OMAC.pm b/lib/Crypt/Mac/OMAC.pm index d1ad335a..d3ee44b5 100644 --- a/lib/Crypt/Mac/OMAC.pm +++ b/lib/Crypt/Mac/OMAC.pm @@ -4,22 +4,13 @@ package Crypt::Mac::OMAC; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Mac Exporter); our %EXPORT_TAGS = ( all => [qw( omac omac_hex omac_b64 omac_b64u )] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); -use CryptX; -use Crypt::Cipher; - -sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } -sub omac { Crypt::Mac::OMAC->new(shift, shift)->add(@_)->mac } -sub omac_hex { Crypt::Mac::OMAC->new(shift, shift)->add(@_)->hexmac } -sub omac_b64 { Crypt::Mac::OMAC->new(shift, shift)->add(@_)->b64mac } -sub omac_b64u { Crypt::Mac::OMAC->new(shift, shift)->add(@_)->b64umac } - 1; =pod diff --git a/lib/Crypt/Mac/PMAC.pm b/lib/Crypt/Mac/PMAC.pm index f66ba827..f9c952fe 100644 --- a/lib/Crypt/Mac/PMAC.pm +++ b/lib/Crypt/Mac/PMAC.pm @@ -4,22 +4,13 @@ package Crypt::Mac::PMAC; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Mac Exporter); our %EXPORT_TAGS = ( all => [qw( pmac pmac_hex pmac_b64 pmac_b64u )] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); -use CryptX; -use Crypt::Cipher; - -sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } -sub pmac { Crypt::Mac::PMAC->new(shift, shift)->add(@_)->mac } -sub pmac_hex { Crypt::Mac::PMAC->new(shift, shift)->add(@_)->hexmac } -sub pmac_b64 { Crypt::Mac::PMAC->new(shift, shift)->add(@_)->b64mac } -sub pmac_b64u { Crypt::Mac::PMAC->new(shift, shift)->add(@_)->b64umac } - 1; =pod diff --git a/lib/Crypt/Mac/Pelican.pm b/lib/Crypt/Mac/Pelican.pm index 3a8ab2f0..104c5835 100644 --- a/lib/Crypt/Mac/Pelican.pm +++ b/lib/Crypt/Mac/Pelican.pm @@ -4,20 +4,13 @@ package Crypt::Mac::Pelican; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Mac Exporter); our %EXPORT_TAGS = ( all => [qw( pelican pelican_hex pelican_b64 pelican_b64u )] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); -use CryptX; -sub new { my $class = shift; _new(@_) } -sub pelican { Crypt::Mac::Pelican->new(shift)->add(@_)->mac } -sub pelican_hex { Crypt::Mac::Pelican->new(shift)->add(@_)->hexmac } -sub pelican_b64 { Crypt::Mac::Pelican->new(shift)->add(@_)->b64mac } -sub pelican_b64u { Crypt::Mac::Pelican->new(shift)->add(@_)->b64umac } - 1; =pod diff --git a/lib/Crypt/Mac/Poly1305.pm b/lib/Crypt/Mac/Poly1305.pm index a7115535..73e58b4d 100644 --- a/lib/Crypt/Mac/Poly1305.pm +++ b/lib/Crypt/Mac/Poly1305.pm @@ -4,20 +4,13 @@ package Crypt::Mac::Poly1305; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Mac Exporter); our %EXPORT_TAGS = ( all => [qw( poly1305 poly1305_hex poly1305_b64 poly1305_b64u )] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); -use CryptX; -sub new { my $class = shift; _new(@_) } -sub poly1305 { Crypt::Mac::Poly1305->new(shift)->add(@_)->mac } -sub poly1305_hex { Crypt::Mac::Poly1305->new(shift)->add(@_)->hexmac } -sub poly1305_b64 { Crypt::Mac::Poly1305->new(shift)->add(@_)->b64mac } -sub poly1305_b64u { Crypt::Mac::Poly1305->new(shift)->add(@_)->b64umac } - 1; =pod diff --git a/lib/Crypt/Mac/XCBC.pm b/lib/Crypt/Mac/XCBC.pm index 3bd9646c..d17634d2 100644 --- a/lib/Crypt/Mac/XCBC.pm +++ b/lib/Crypt/Mac/XCBC.pm @@ -4,22 +4,13 @@ package Crypt::Mac::XCBC; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::Mac Exporter); our %EXPORT_TAGS = ( all => [qw( xcbc xcbc_hex xcbc_b64 xcbc_b64u )] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); -use CryptX; -use Crypt::Cipher; - -sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } -sub xcbc { Crypt::Mac::XCBC->new(shift, shift)->add(@_)->mac } -sub xcbc_hex { Crypt::Mac::XCBC->new(shift, shift)->add(@_)->hexmac } -sub xcbc_b64 { Crypt::Mac::XCBC->new(shift, shift)->add(@_)->b64mac } -sub xcbc_b64u { Crypt::Mac::XCBC->new(shift, shift)->add(@_)->b64umac } - 1; =pod diff --git a/lib/Crypt/Misc.pm b/lib/Crypt/Misc.pm index 4ab80c93..72489ea5 100644 --- a/lib/Crypt/Misc.pm +++ b/lib/Crypt/Misc.pm @@ -2,7 +2,7 @@ package Crypt::Misc; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; require Exporter; our @ISA = qw(Exporter); ### use Exporter 5.57 'import'; use Carp 'croak'; @@ -35,22 +35,6 @@ use Crypt::Mode::OFB; use Crypt::Cipher; use Crypt::PRNG 'random_bytes'; -sub encode_b64 { - CryptX::_encode_base64(@_); -} - -sub decode_b64 { - CryptX::_decode_base64(@_); -} - -sub encode_b64u { - CryptX::_encode_base64url(@_); -} - -sub decode_b64u { - CryptX::_decode_base64url(@_); -} - sub _encode_b58 { my ($bytes, $alphabet) = @_; @@ -61,7 +45,7 @@ sub _encode_b58 { if ($bytes =~ /^(\x00+)/) { $base58 = ('0' x length($1)); } - $base58 .= CryptX::_bin_to_radix($bytes, 58); + $base58 .= _bin_to_radix($bytes, 58); if (defined $alphabet) { my $default = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv"; @@ -80,7 +64,7 @@ sub _decode_b58 { my $default = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv"; if (defined $alphabet) { - return undef if $alphabet !~ /^[a-zA-Z0-9]{58}$/; + return undef if $alphabet !~ /^[a-zA-Z0-9]{58}$/ || $base58 !~ /^[$alphabet]+$/; eval "\$base58 =~ tr/$alphabet/$default/"; # HACK: https://stackoverflow.com/questions/11415045/using-a-char-variable-in-tr return undef if $@; } @@ -92,7 +76,7 @@ sub _decode_b58 { $base58 = $2; $bytes = ("\x00" x length($1)); } - $bytes .= CryptX::_radix_to_bin($base58, 58) if defined $base58 && length($base58) > 0; + $bytes .= _radix_to_bin($base58, 58) if defined $base58 && length($base58) > 0; return $bytes; } @@ -109,27 +93,6 @@ sub encode_b58r { _encode_b58(shift, "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65 sub encode_b58t { _encode_b58(shift, "RPShNAF39wBUDnEGHJKLM4pQrsT7VWXYZ2bcdeCg65jkm8ofqi1tuvaxyz") } # Tipple sub encode_b58s { _encode_b58(shift, "gsphnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCr65jkm8oFqi1tuvAxyz") } # Stellar -sub encode_b32r { CryptX::_encode_b32(shift, 0) } # rfc4648 -sub encode_b32b { CryptX::_encode_b32(shift, 1) } # base32hex -sub encode_b32z { CryptX::_encode_b32(shift, 2) } # zbase32 -sub encode_b32c { CryptX::_encode_b32(shift, 3) } # crockford - -sub decode_b32r { CryptX::_decode_b32(shift, 0) } # rfc4648 -sub decode_b32b { CryptX::_decode_b32(shift, 1) } # base32hex -sub decode_b32z { CryptX::_decode_b32(shift, 2) } # zbase32 -sub decode_b32c { CryptX::_decode_b32(shift, 3) } # crockford - - -sub increment_octets_be { - CryptX::_increment_octets_be(@_); - #$_[0] = CryptX::_increment_octets_be($_[0]); -} - -sub increment_octets_le { - CryptX::_increment_octets_le(@_); - #$_[0] = CryptX::_increment_octets_le($_[0]); -} - sub pem_to_der { my ($data, $password) = @_; @@ -194,6 +157,7 @@ sub der_to_pem { } sub read_rawfile { + # $data = read_rawfile($filename); my $f = shift; croak "FATAL: read_rawfile() non-existing file '$f'" unless -f $f; open my $fh, "<", $f or croak "FATAL: read_rawfile() cannot open file '$f': $!"; diff --git a/lib/Crypt/Mode.pm b/lib/Crypt/Mode.pm index eb00dad5..a8474588 100644 --- a/lib/Crypt/Mode.pm +++ b/lib/Crypt/Mode.pm @@ -2,64 +2,9 @@ package Crypt::Mode; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -### METHODS - -sub new { die } # overriden in subclass - -sub encrypt { - my ($self, $pt) = (shift, shift); - $self->_start(1, @_); - return $self->add($pt) . $self->finish; -} - -sub decrypt { - my ($self, $ct) = (shift, shift); - $self->_start(-1, @_); - return $self->add($ct) . $self->finish; -} - -sub start_encrypt { - my $self = shift; - $self->_start(1, @_); - return $self; -} - -sub start_decrypt { - my $self = shift; - $self->_start(-1, @_); - return $self; -} - -sub finish { - shift->_finish(@_); -} - -sub add { - my $self = shift; - my $rv = ''; - $rv .= $self->_crypt($_) for (@_); - return $rv; -} - -sub _crypt { - my $self = shift; - my $dir = $self->_get_dir; - return $self->_encrypt(@_) if $dir == 1; - return $self->_decrypt(@_) if $dir == -1; - return; -} - -sub _finish { - my $self = shift; - my $dir = $self->_get_dir; - return $self->_finish_enc(@_) if $dir == 1; - return $self->_finish_dec(@_) if $dir == -1; - return; -} - -sub CLONE_SKIP { 1 } # prevent cloning +### not used 1; diff --git a/lib/Crypt/Mode/CBC.pm b/lib/Crypt/Mode/CBC.pm index 2993770b..be0a98cd 100644 --- a/lib/Crypt/Mode/CBC.pm +++ b/lib/Crypt/Mode/CBC.pm @@ -4,12 +4,23 @@ package Crypt::Mode::CBC; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use Crypt::Cipher; -use base 'Crypt::Mode'; -sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } +sub encrypt { + my ($self, $pt) = (shift, shift); + local $SIG{__DIE__} = \&CryptX::_croak; + $self->start_encrypt(@_)->add($pt) . $self->finish; +} + +sub decrypt { + my ($self, $ct) = (shift, shift); + local $SIG{__DIE__} = \&CryptX::_croak; + $self->start_decrypt(@_)->add($ct) . $self->finish; +} + +sub CLONE_SKIP { 1 } # prevent cloning 1; diff --git a/lib/Crypt/Mode/CFB.pm b/lib/Crypt/Mode/CFB.pm index 00528f3b..effa2404 100644 --- a/lib/Crypt/Mode/CFB.pm +++ b/lib/Crypt/Mode/CFB.pm @@ -4,12 +4,23 @@ package Crypt::Mode::CFB; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use Crypt::Cipher; -use base 'Crypt::Mode'; -sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } +sub encrypt { + my ($self, $pt) = (shift, shift); + local $SIG{__DIE__} = \&CryptX::_croak; + $self->start_encrypt(@_)->add($pt); +} + +sub decrypt { + my ($self, $ct) = (shift, shift); + local $SIG{__DIE__} = \&CryptX::_croak; + $self->start_decrypt(@_)->add($ct); +} + +sub CLONE_SKIP { 1 } # prevent cloning 1; diff --git a/lib/Crypt/Mode/CTR.pm b/lib/Crypt/Mode/CTR.pm index 7bfcef21..b8a6e647 100644 --- a/lib/Crypt/Mode/CTR.pm +++ b/lib/Crypt/Mode/CTR.pm @@ -4,12 +4,23 @@ package Crypt::Mode::CTR; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use Crypt::Cipher; -use base 'Crypt::Mode'; -sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } +sub encrypt { + my ($self, $pt) = (shift, shift); + local $SIG{__DIE__} = \&CryptX::_croak; + $self->start_encrypt(@_)->add($pt); +} + +sub decrypt { + my ($self, $ct) = (shift, shift); + local $SIG{__DIE__} = \&CryptX::_croak; + $self->start_decrypt(@_)->add($ct); +} + +sub CLONE_SKIP { 1 } # prevent cloning 1; diff --git a/lib/Crypt/Mode/ECB.pm b/lib/Crypt/Mode/ECB.pm index 3826d1b5..73711ffe 100644 --- a/lib/Crypt/Mode/ECB.pm +++ b/lib/Crypt/Mode/ECB.pm @@ -4,12 +4,23 @@ package Crypt::Mode::ECB; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use Crypt::Cipher; -use base 'Crypt::Mode'; -sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } +sub encrypt { + my ($self, $pt) = (shift, shift); + local $SIG{__DIE__} = \&CryptX::_croak; + $self->start_encrypt(@_)->add($pt) . $self->finish; +} + +sub decrypt { + my ($self, $ct) = (shift, shift); + local $SIG{__DIE__} = \&CryptX::_croak; + $self->start_decrypt(@_)->add($ct) . $self->finish; +} + +sub CLONE_SKIP { 1 } # prevent cloning 1; diff --git a/lib/Crypt/Mode/OFB.pm b/lib/Crypt/Mode/OFB.pm index 25bb3e9d..7ef45437 100644 --- a/lib/Crypt/Mode/OFB.pm +++ b/lib/Crypt/Mode/OFB.pm @@ -4,12 +4,23 @@ package Crypt::Mode::OFB; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use Crypt::Cipher; -use base 'Crypt::Mode'; -sub new { my $class = shift; _new(Crypt::Cipher::_trans_cipher_name(shift), @_) } +sub encrypt { + my ($self, $pt) = (shift, shift); + local $SIG{__DIE__} = \&CryptX::_croak; + $self->start_encrypt(@_)->add($pt); +} + +sub decrypt { + my ($self, $ct) = (shift, shift); + local $SIG{__DIE__} = \&CryptX::_croak; + $self->start_decrypt(@_)->add($ct); +} + +sub CLONE_SKIP { 1 } # prevent cloning 1; diff --git a/lib/Crypt/PK.pm b/lib/Crypt/PK.pm index c8285563..28d7bb6e 100644 --- a/lib/Crypt/PK.pm +++ b/lib/Crypt/PK.pm @@ -2,7 +2,7 @@ package Crypt::PK; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use Carp; diff --git a/lib/Crypt/PK/DH.pm b/lib/Crypt/PK/DH.pm index aa3786c5..1f9971d9 100644 --- a/lib/Crypt/PK/DH.pm +++ b/lib/Crypt/PK/DH.pm @@ -2,7 +2,7 @@ package Crypt::PK::DH; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; our %EXPORT_TAGS = ( all => [qw( dh_shared_secret )] ); @@ -168,10 +168,8 @@ my %DH_PARAMS = ( ); sub new { - my ($class, $f) = @_; - my $self = _new(); - $self->import_key($f) if $f; - return $self; + my $self = shift->_new(); + return @_ > 0 ? $self->import_key(@_) : $self; } sub import_key { diff --git a/lib/Crypt/PK/DSA.pm b/lib/Crypt/PK/DSA.pm index afd64850..3ce42994 100644 --- a/lib/Crypt/PK/DSA.pm +++ b/lib/Crypt/PK/DSA.pm @@ -2,7 +2,7 @@ package Crypt::PK::DSA; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; our %EXPORT_TAGS = ( all => [qw( dsa_encrypt dsa_decrypt dsa_sign_message dsa_verify_message dsa_sign_hash dsa_verify_hash )] ); @@ -10,16 +10,15 @@ our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); use Carp; +$Carp::Internal{(__PACKAGE__)}++; use CryptX; use Crypt::Digest 'digest_data'; use Crypt::Misc qw(read_rawfile encode_b64u decode_b64u encode_b64 decode_b64 pem_to_der der_to_pem); use Crypt::PK; sub new { - my ($class, $f, $p) = @_; - my $self = _new(); - $self->import_key($f, $p) if $f; - return $self; + my $self = shift->_new(); + return @_ > 0 ? $self->import_key(@_) : $self; } sub generate_key { @@ -96,55 +95,11 @@ sub import_key { croak "FATAL: invalid or unsupported DSA key format"; } -sub encrypt { - my ($self, $data, $hash_name) = @_; - $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); - return $self->_encrypt($data, $hash_name); -} - -sub decrypt { - my ($self, $data) = @_; - return $self->_decrypt($data); -} - -sub _truncate { - my ($self, $hash) = @_; - ### section 4.6 of FIPS 186-4 - # let N be the bit length of q - # z = the leftmost min(N, outlen) bits of Hash(M). - my $q = $self->size_q; # = size in bytes - return $hash if $q >= length($hash); - return substr($hash, 0, $q); -} - -sub sign_message { - my ($self, $data, $hash_name) = @_; - $hash_name ||= 'SHA1'; - my $data_hash = digest_data($hash_name, $data); - return $self->_sign($self->_truncate($data_hash)); -} - -sub verify_message { - my ($self, $sig, $data, $hash_name) = @_; - $hash_name ||= 'SHA1'; - my $data_hash = digest_data($hash_name, $data); - return $self->_verify($sig, $self->_truncate($data_hash)); -} - -sub sign_hash { - my ($self, $data_hash) = @_; - return $self->_sign($self->_truncate($data_hash)); -} - -sub verify_hash { - my ($self, $sig, $data_hash) = @_; - return $self->_verify($sig, $self->_truncate($data_hash)); -} - ### FUNCTIONS sub dsa_encrypt { my $key = shift; + local $SIG{__DIE__} = \&CryptX::_croak; $key = __PACKAGE__->new($key) unless ref $key; carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; return $key->encrypt(@_); @@ -152,6 +107,7 @@ sub dsa_encrypt { sub dsa_decrypt { my $key = shift; + local $SIG{__DIE__} = \&CryptX::_croak; $key = __PACKAGE__->new($key) unless ref $key; carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; return $key->decrypt(@_); @@ -159,6 +115,7 @@ sub dsa_decrypt { sub dsa_sign_message { my $key = shift; + local $SIG{__DIE__} = \&CryptX::_croak; $key = __PACKAGE__->new($key) unless ref $key; carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; return $key->sign_message(@_); @@ -166,6 +123,7 @@ sub dsa_sign_message { sub dsa_verify_message { my $key = shift; + local $SIG{__DIE__} = \&CryptX::_croak; $key = __PACKAGE__->new($key) unless ref $key; carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; return $key->verify_message(@_); @@ -173,6 +131,7 @@ sub dsa_verify_message { sub dsa_sign_hash { my $key = shift; + local $SIG{__DIE__} = \&CryptX::_croak; $key = __PACKAGE__->new($key) unless ref $key; carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; return $key->sign_hash(@_); @@ -180,6 +139,7 @@ sub dsa_sign_hash { sub dsa_verify_hash { my $key = shift; + local $SIG{__DIE__} = \&CryptX::_croak; $key = __PACKAGE__->new($key) unless ref $key; carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; return $key->verify_hash(@_); diff --git a/lib/Crypt/PK/ECC.pm b/lib/Crypt/PK/ECC.pm index 28d83589..9e2d06ab 100644 --- a/lib/Crypt/PK/ECC.pm +++ b/lib/Crypt/PK/ECC.pm @@ -2,7 +2,7 @@ package Crypt::PK::ECC; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; our %EXPORT_TAGS = ( all => [qw( ecc_encrypt ecc_decrypt ecc_sign_message ecc_verify_message ecc_sign_hash ecc_verify_hash ecc_shared_secret )] ); @@ -10,429 +10,177 @@ our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); use Carp; +$Carp::Internal{(__PACKAGE__)}++; use CryptX; 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 = ( - ### http://www.ecc-brainpool.org/download/Domain-parameters.pdf (v1.0 19.10.2005) - brainpoolp160r1 => { - oid => '1.3.36.3.3.2.8.1.1.1', - prime => "E95E4A5F737059DC60DFC7AD95B3D8139515620F", - A => "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", - B => "1E589A8595423412134FAA2DBDEC95C8D8675E58", - Gx => "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", - Gy => "1667CB477A1A8EC338F94741669C976316DA6321", - order => "E95E4A5F737059DC60DF5991D45029409E60FC09", - cofactor => 1, + # 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', }, - brainpoolp192r1 => { - oid => '1.3.36.3.3.2.8.1.1.3', - prime => "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", - A => "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", - B => "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", - Gx => "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", - Gy => "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", - order => "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", - cofactor => 1, - }, - brainpoolp224r1 => { - oid => '1.3.36.3.3.2.8.1.1.5', - prime => "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", - A => "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", - B => "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", - Gx => "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", - Gy => "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", - order => "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", - cofactor => 1, - }, - brainpoolp256r1 => { - oid => '1.3.36.3.3.2.8.1.1.7', - prime => "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", - A => "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", - B => "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", - Gx => "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", - Gy => "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", - order => "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", - cofactor => 1, - }, - brainpoolp320r1 => { - oid => '1.3.36.3.3.2.8.1.1.9', - prime => "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", - A => "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", - B => "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", - Gx => "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", - Gy => "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", - order => "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", - cofactor => 1, - }, - brainpoolp384r1 => { - oid => '1.3.36.3.3.2.8.1.1.11', - prime => "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", - A => "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", - B => "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", - Gx => "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", - Gy => "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", - order => "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", - cofactor => 1, - }, - brainpoolp512r1 => { - oid => '1.3.36.3.3.2.8.1.1.13', - prime => "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", - A => "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", - B => "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", - Gx => "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", - Gy => "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", - order => "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", - cofactor => 1, - }, - ### http://www.secg.org/collateral/sec2_final.pdf (September 20, 2000 - Version 1.0) - secp112r1 => { - oid => '1.3.132.0.6', - prime => "DB7C2ABF62E35E668076BEAD208B", - A => "DB7C2ABF62E35E668076BEAD2088", - B => "659EF8BA043916EEDE8911702B22", - Gx => "09487239995A5EE76B55F9C2F098", - Gy => "A89CE5AF8724C0A23E0E0FF77500", - order => "DB7C2ABF62E35E7628DFAC6561C5", - cofactor => 1, - }, - secp112r2 => { - oid => '1.3.132.0.7', - prime => "DB7C2ABF62E35E668076BEAD208B", - A => "6127C24C05F38A0AAAF65C0EF02C", - B => "51DEF1815DB5ED74FCC34C85D709", - Gx => "4BA30AB5E892B4E1649DD0928643", - Gy => "ADCD46F5882E3747DEF36E956E97", - order => "36DF0AAFD8B8D7597CA10520D04B", - cofactor => 4, - }, - secp128r1 => { - oid => '1.3.132.0.28', - prime => "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", - A => "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", - B => "E87579C11079F43DD824993C2CEE5ED3", - Gx => "161FF7528B899B2D0C28607CA52C5B86", - Gy => "CF5AC8395BAFEB13C02DA292DDED7A83", - order => "FFFFFFFE0000000075A30D1B9038A115", - cofactor => 1, - }, - secp128r2 => { - oid => '1.3.132.0.29', - prime => "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", - A => "D6031998D1B3BBFEBF59CC9BBFF9AEE1", - B => "5EEEFCA380D02919DC2C6558BB6D8A5D", - Gx => "7B6AA5D85E572983E6FB32A7CDEBC140", - Gy => "27B6916A894D3AEE7106FE805FC34B44", - order => "3FFFFFFF7FFFFFFFBE0024720613B5A3", - cofactor => 4, - }, - secp160k1 => { - oid => '1.3.132.0.9', - prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", - A => "0000000000000000000000000000000000000000", - B => "0000000000000000000000000000000000000007", - Gx => "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", - Gy => "938CF935318FDCED6BC28286531733C3F03C4FEE", - order => "0100000000000000000001B8FA16DFAB9ACA16B6B3", - cofactor => 1, - }, - secp160r1 => { - oid => '1.3.132.0.8', - prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", - A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", - B => "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", - Gx => "4A96B5688EF573284664698968C38BB913CBFC82", - Gy => "23A628553168947D59DCC912042351377AC5FB32", - order => "0100000000000000000001F4C8F927AED3CA752257", - cofactor => 1, - }, - secp160r2 => { - oid => '1.3.132.0.30', - prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", - A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", - B => "B4E134D3FB59EB8BAB57274904664D5AF50388BA", - Gx => "52DCB034293A117E1F4FF11B30F7199D3144CE6D", - Gy => "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", - order => "0100000000000000000000351EE786A818F3A1A16B", - cofactor => 1, - }, - secp192k1 => { - oid => '1.3.132.0.31', - prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", - A => "000000000000000000000000000000000000000000000000", - B => "000000000000000000000000000000000000000000000003", - Gx => "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", - Gy => "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", - order => "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", - cofactor => 1, - }, - secp192r1 => { # == NIST P-192, X9.62 prime192v1 - oid => '1.2.840.10045.3.1.1', - prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", - A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", - B => "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", - Gx => "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", - Gy => "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811", - order => "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", - cofactor => 1, - }, - secp224k1 => { - oid => '1.3.132.0.32', - prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", - A => "00000000000000000000000000000000000000000000000000000000", - B => "00000000000000000000000000000000000000000000000000000005", - Gx => "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", - Gy => "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", - order => "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", - cofactor => 1, - }, - secp224r1 => { # == NIST P-224 - oid => '1.3.132.0.33', - prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", - A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", - B => "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", - Gx => "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", - Gy => "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", - order => "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", - cofactor => 1, - }, - secp256k1 => { - oid => '1.3.132.0.10', - prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", - A => "0000000000000000000000000000000000000000000000000000000000000000", - B => "0000000000000000000000000000000000000000000000000000000000000007", - Gx => "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", - Gy => "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", - order => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", - cofactor => 1, - }, - secp256r1 => { # == NIST P-256, X9.62 prime256v1 - oid => '1.2.840.10045.3.1.7', - prime => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", - A => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", - B => "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", - Gx => "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", - Gy => "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", - order => "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", - cofactor => 1, - }, - secp384r1 => { # == NIST P-384 - oid => '1.3.132.0.34', - prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", - A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", - B => "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", - Gx => "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", - Gy => "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", - order => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", - cofactor => 1, - }, - secp521r1 => { # == NIST P-521 - oid => '1.3.132.0.35', - prime => "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", - A => "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", - B => "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", - Gx => "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", - Gy => "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", - order => "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", - cofactor => 1 - }, - ### http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf (July 2013) - nistp192 => { # == secp192r1, X9.62 prime192v1 - oid => '1.2.840.10045.3.1.1', - prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', - A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', - B => '64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1', - Gx => '188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012', - Gy => '07192B95FFC8DA78631011ED6B24CDD573F977A11E794811', - order => 'FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831', - cofactor => 1, - }, - nistp224 => { # == secp224r1 - oid => '1.3.132.0.33', - prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001', - A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE', - B => 'B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4', - Gx => 'B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21', - Gy => 'BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34', - order => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D', - cofactor => 1, - }, - nistp256 => { # == secp256r1, X9.62 prime256v1 - oid => '1.2.840.10045.3.1.7', - prime => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF', - A => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC', - B => '5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B', - Gx => '6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296', - Gy => '4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5', - order => 'FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551', - cofactor => 1, - }, - nistp384 => { # == secp384r1 - oid => '1.3.132.0.34', - prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF', - A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC', - B => 'B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF', - Gx => 'AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7', - Gy => '3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F', - order => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973', - cofactor => 1, - }, - nistp521 => { # == secp521r1 - oid => '1.3.132.0.35', - prime => '1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', - A => '1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC', - B => '051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00', - Gx => '0C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66', - Gy => '11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650', - order => '1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409', - cofactor => 1, - }, - ### ANS X9.62 elliptic curves - http://www.flexiprovider.de/CurvesGfpX962.html - prime192v1 => { # == secp192r1, NIST P-192 - oid => '1.2.840.10045.3.1.1', - prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', - A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', - B => '64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1', - Gx => '188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012', - Gy => '07192B95FFC8DA78631011ED6B24CDD573F977A11E794811', - order => 'FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831', - cofactor => 1, - }, - prime192v2 => { - oid => '1.2.840.10045.3.1.2', - prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', - A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', - B => 'CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953', - Gx => 'EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A', - Gy => '6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15', - order => 'FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31', - cofactor => 1 - }, - prime192v3 => { - oid => '1.2.840.10045.3.1.3', - prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', - A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', - B => '22123DC2395A05CAA7423DAECCC94760A7D462256BD56916', - Gx => '7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896', - Gy => '38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0', - order => 'FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13', - cofactor => 1, - }, - prime239v1 => { - oid => '1.2.840.10045.3.1.4', - prime => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', - A => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', - B => '6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A', - Gx => '0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF', - Gy => '7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE', - order => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B', - cofactor => 1, - }, - prime239v2 => { - oid => '1.2.840.10045.3.1.5', - prime => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', - A => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', - B => '617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C', - Gx => '38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7', - Gy => '5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA', - order => '7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063', - cofactor => 1, - }, - prime239v3 => { - oid => '1.2.840.10045.3.1.6', - prime => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', - A => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', - B => '255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E', - Gx => '6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A', - Gy => '1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3', - order => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551', - cofactor => 1, - }, - prime256v1 => { # == secp256r1, NIST P-256 - oid => '1.2.840.10045.3.1.7', - prime => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF', - A => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC', - B => '5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B', - Gx => '6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296', - Gy => '4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5', - order => 'FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551', - cofactor => 1, + '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', }, ); -my %jwkcrv = ( - 'P-192' => 'secp192r1', - 'P-224' => 'secp224r1', - 'P-256' => 'secp256r1', - 'P-384' => 'secp384r1', - 'P-521' => 'secp521r1', +my %jwk2curve = ( + 'P-192' => 'secp192r1', + 'P-224' => 'secp224r1', + 'P-256' => 'secp256r1', + 'P-384' => 'secp384r1', + 'P-521' => 'secp521r1', +); + +my %curve2jwk = ( + '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 + '1.3.132.0.34' => 'P-384', # secp384r1 + '1.3.132.0.35' => 'P-521', # secp521r1 + 'nistp192' => 'P-192', + 'nistp224' => 'P-224', + 'nistp256' => 'P-256', + 'nistp384' => 'P-384', + 'nistp521' => 'P-521', + 'prime192v1' => 'P-192', + 'prime256v1' => 'P-256', + 'secp192r1' => 'P-192', + 'secp224r1' => 'P-224', + 'secp256r1' => 'P-256', + 'secp384r1' => 'P-384', + '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) = @_; - my $p = $curve{$crv}{prime}; - croak "FATAL: invalid or unknown curve" if !$p; - $p =~ s/^0+//; - my $hex_size = length($p) % 2 ? length($p) + 1 : length($p); - if ($k) { - $k =~ /^0+/; - croak "FATAL: too long private key (k)" if length($k) > $hex_size; - my $priv_hex = "0" x ($hex_size - length($k)) . $k; - return $self->import_key_raw(pack("H*", $priv_hex), $crv); + croak "FATAL: no curve" if !$crv; + if (defined $k && length($k) > 0) { + croak "FATAL: invalid length (k)" if length($k) % 2; + return $self->import_key_raw(pack("H*", $k), $crv); } - elsif ($x && $y) { - $x =~ /^0+/; - $y =~ /^0+/; - croak "FATAL: too long public key (x)" if length($x) > $hex_size; - croak "FATAL: too long public key (y)" if length($y) > $hex_size; - my $pub_hex = "04" . ("0" x ($hex_size - length($x))) . $x . ("0" x ($hex_size - length($y))) . $y; + elsif (defined $x && defined $y) { + croak "FATAL: invalid length (x)" if length($x) % 2; + croak "FATAL: invalid length (y)" if length($y) % 2; + croak "FATAL: invalid length (x,y)" if length($y) != length($x); + my $pub_hex = "04" . $x . $y; return $self->import_key_raw(pack("H*", $pub_hex), $crv); } } -sub _curve_name_lookup { - my ($self, $key) = @_; - - return $key->{curve_name} if $key->{curve_name} && exists $curve{$key->{curve_name}}; - - defined(my $A = $key->{curve_A}) or return; - defined(my $B = $key->{curve_B}) or return; - defined(my $Gx = $key->{curve_Gx}) or return; - defined(my $Gy = $key->{curve_Gy}) or return; - defined(my $order = $key->{curve_order}) or return; - defined(my $prime = $key->{curve_prime}) or return; - defined(my $cofactor = $key->{curve_cofactor}) or return; - $A =~ s/^0+//; - $B =~ s/^0+//; - $Gx =~ s/^0+//; - $Gy =~ s/^0+//; - $order =~ s/^0+//; - $prime =~ s/^0+//; - - for my $k (sort keys %curve) { - (my $c_A = $curve{$k}{A} ) =~ s/^0+//; - (my $c_B = $curve{$k}{B} ) =~ s/^0+//; - (my $c_Gx = $curve{$k}{Gx} ) =~ s/^0+//; - (my $c_Gy = $curve{$k}{Gy} ) =~ s/^0+//; - (my $c_order = $curve{$k}{order} ) =~ s/^0+//; - (my $c_prime = $curve{$k}{prime} ) =~ s/^0+//; - my $c_cofactor = $curve{$k}{cofactor}; - return $k if $A eq $c_A && $B eq $c_B && $Gx eq $c_Gx && $Gy eq $c_Gy && - $order eq $c_order && $prime eq $c_prime && $cofactor == $c_cofactor; - } -} - sub new { - my ($class, $f, $p) = @_; - my $self = _new(); - $self->import_key($f, $p) if $f; - return $self; + my $self = shift->_new(); + return @_ > 0 ? $self->import_key(@_) : $self; } sub export_key_pem { my ($self, $type, $password, $cipher) = @_; + local $SIG{__DIE__} = \&CryptX::_croak; my $key = $self->export_key_der($type||''); return unless $key; return der_to_pem($key, "EC PRIVATE KEY", $password, $cipher) if substr($type, 0, 7) eq 'private'; @@ -441,13 +189,11 @@ sub export_key_pem { sub export_key_jwk { my ($self, $type, $wanthash) = @_; + local $SIG{__DIE__} = \&CryptX::_croak; my $kh = $self->key2hash; - my $curve = $self->_curve_name_lookup($kh); - $curve = 'P-192' if $curve =~ /(secp192r1|nistp192|prime192v1)/; - $curve = 'P-224' if $curve =~ /(secp224r1|nistp224)/; - $curve = 'P-256' if $curve =~ /(secp256r1|nistp256|prime256v1)/; - $curve = 'P-384' if $curve =~ /(secp384r1|nistp384)/; - $curve = 'P-521' if $curve =~ /(secp521r1|nistp521)/; + $kh->{curve_oid} = '' if !defined $kh->{curve_oid}; + $kh->{curve_name} = '' if !defined $kh->{curve_name}; + my $curve_jwt = $curve2jwk{$kh->{curve_oid}} || $curve2jwk{lc $kh->{curve_name}} || $kh->{curve_name}; if ($type && $type eq 'private') { return unless $kh->{pub_x} && $kh->{pub_y} && $kh->{k}; for (qw/pub_x pub_y k/) { @@ -456,7 +202,7 @@ sub export_key_jwk { # NOTE: x + y are not necessary in privkey # but they are used in https://tools.ietf.org/html/rfc7517#appendix-A.2 my $hash = { - kty => "EC", crv=>$curve, + kty => "EC", crv => $curve_jwt, x => encode_b64u(pack("H*", $kh->{pub_x})), y => encode_b64u(pack("H*", $kh->{pub_y})), d => encode_b64u(pack("H*", $kh->{k})), @@ -469,7 +215,7 @@ sub export_key_jwk { $kh->{$_} = "0$kh->{$_}" if length($kh->{$_}) % 2; } my $hash = { - kty => "EC", crv=>$curve, + kty => "EC", crv => $curve_jwt, x => encode_b64u(pack("H*", $kh->{pub_x})), y => encode_b64u(pack("H*", $kh->{pub_y})), }; @@ -479,6 +225,7 @@ sub export_key_jwk { sub export_key_jwk_thumbprint { my ($self, $hash_name) = @_; + local $SIG{__DIE__} = \&CryptX::_croak; $hash_name ||= 'SHA256'; my $h = $self->export_key_jwk('public', 1); my $json = CryptX::_encode_json({crv=>$h->{crv}, kty=>$h->{kty}, x=>$h->{x}, y=>$h->{y}}); @@ -487,15 +234,15 @@ sub export_key_jwk_thumbprint { sub import_key { my ($self, $key, $password) = @_; + local $SIG{__DIE__} = \&CryptX::_croak; croak "FATAL: undefined key" unless $key; # special case if (ref($key) eq 'HASH') { if (($key->{pub_x} && $key->{pub_y}) || $key->{k}) { # hash exported via key2hash - my $curve = $self->_curve_name_lookup($key); - croak "FATAL: invalid or unknown curve" if !$curve; - return $self->_import_hex($key->{pub_x}, $key->{pub_y}, $key->{k}, $curve); + my $curve_name = $key->{curve_name} || $key->{curve_oid}; + return $self->_import_hex($key->{pub_x}, $key->{pub_y}, $key->{k}, $curve_name); } if ($key->{crv} && $key->{kty} && $key->{kty} eq "EC" && ($key->{d} || ($key->{x} && $key->{y}))) { # hash with items corresponding to JSON Web Key (JWK) @@ -503,11 +250,11 @@ sub import_key { for (qw/x y d/) { $key->{$_} = eval { unpack("H*", decode_b64u($key->{$_})) } if exists $key->{$_}; } - if (my $curve = $jwkcrv{$key->{crv}}) { - return $self->_import_hex($key->{x}, $key->{y}, $key->{d}, $curve); + 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) - return $self->_import_hex($key->{x}, $key->{y}, $key->{d}, lc($key->{crv})); + return $self->_import_hex($key->{x}, $key->{y}, $key->{d}, $key->{crv}); } croak "FATAL: unexpected ECC key hash"; } @@ -533,8 +280,8 @@ sub import_key { return $self->_import_pkcs8($data, $password); } elsif ($data =~ /-----BEGIN ENCRYPTED PRIVATE KEY-----(.*?)-----END/sg) { - # XXX-TODO: pkcs#8 encrypted private key - croak "FATAL: encrypted pkcs8 EC private keys are not supported"; + $data = pem_to_der($data, $password); + return $self->_import_pkcs8($data, $password); } elsif ($data =~ /^\s*(\{.*?\})\s*$/s) { # JSON Web Key (JWK) - http://tools.ietf.org/html/draft-ietf-jose-json-web-key @@ -544,13 +291,17 @@ sub import_key { for (qw/x y d/) { $h->{$_} = eval { unpack("H*", decode_b64u($h->{$_})) } if exists $h->{$_}; } - if (my $curve = $jwkcrv{$h->{crv}}) { - return $self->_import_hex($h->{x}, $h->{y}, $h->{d}, $curve); + 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) - return $self->_import_hex($h->{x}, $h->{y}, $h->{d}, lc($h->{crv})); + return $self->_import_hex($h->{x}, $h->{y}, $h->{d}, $h->{crv}); } } + elsif ($data =~ /-----BEGIN CERTIFICATE-----(.*?)-----END CERTIFICATE-----/sg) { + $data = pem_to_der($data); + return $self->_import_x509($data); + } elsif ($data =~ /---- BEGIN SSH2 PUBLIC KEY ----(.*?)---- END SSH2 PUBLIC KEY ----/sg) { $data = pem_to_der($data); my ($typ, $skip, $pubkey) = Crypt::PK::_ssh_parse($data); @@ -562,61 +313,12 @@ sub import_key { return $self->import_key_raw($pubkey, "$2") if $pubkey && $typ =~ /^ecdsa-(.+?)-(.*)$/; } else { - my $rv = eval { $self->_import($data) } || eval { $self->_import_pkcs8($data, $password) }; + my $rv = eval { $self->_import($data) } || eval { $self->_import_pkcs8($data, $password) } || eval { $self->_import_x509($data) }; return $rv if $rv; } croak "FATAL: invalid or unsupported EC key format"; } -sub encrypt { - my ($self, $data, $hash_name) = @_; - $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); - return $self->_encrypt($data, $hash_name); -} - -sub decrypt { - my ($self, $data) = @_; - return $self->_decrypt($data); -} - -sub sign_message { - my ($self, $data, $hash_name) = @_; - $hash_name ||= 'SHA1'; - my $data_hash = digest_data($hash_name, $data); - return $self->_sign($data_hash); -} - -sub sign_message_rfc7518 { - my ($self, $data, $hash_name) = @_; - $hash_name ||= 'SHA1'; - my $data_hash = digest_data($hash_name, $data); - return $self->_sign_rfc7518($data_hash); -} - -sub verify_message { - my ($self, $sig, $data, $hash_name) = @_; - $hash_name ||= 'SHA1'; - my $data_hash = digest_data($hash_name, $data); - return $self->_verify($sig, $data_hash); -} - -sub verify_message_rfc7518 { - my ($self, $sig, $data, $hash_name) = @_; - $hash_name ||= 'SHA1'; - my $data_hash = digest_data($hash_name, $data); - return $self->_verify_rfc7518($sig, $data_hash); -} - -sub sign_hash { - my ($self, $data_hash) = @_; - return $self->_sign($data_hash); -} - -sub verify_hash { - my ($self, $sig, $data_hash) = @_; - return $self->_verify($sig, $data_hash); -} - sub curve2hash { my $self = shift; my $kh = $self->key2hash; @@ -627,7 +329,8 @@ sub curve2hash { Gx => $kh->{curve_Gx}, Gy => $kh->{curve_Gy}, cofactor => $kh->{curve_cofactor}, - order => $kh->{curve_order} + order => $kh->{curve_order}, + oid => $kh->{curve_oid}, }; } @@ -635,6 +338,7 @@ sub curve2hash { sub ecc_encrypt { my $key = shift; + local $SIG{__DIE__} = \&CryptX::_croak; $key = __PACKAGE__->new($key) unless ref $key; carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; return $key->encrypt(@_); @@ -642,6 +346,7 @@ sub ecc_encrypt { sub ecc_decrypt { my $key = shift; + local $SIG{__DIE__} = \&CryptX::_croak; $key = __PACKAGE__->new($key) unless ref $key; carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; return $key->decrypt(@_); @@ -649,6 +354,7 @@ sub ecc_decrypt { sub ecc_sign_message { my $key = shift; + local $SIG{__DIE__} = \&CryptX::_croak; $key = __PACKAGE__->new($key) unless ref $key; carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; return $key->sign_message(@_); @@ -656,6 +362,7 @@ sub ecc_sign_message { sub ecc_verify_message { my $key = shift; + local $SIG{__DIE__} = \&CryptX::_croak; $key = __PACKAGE__->new($key) unless ref $key; carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; return $key->verify_message(@_); @@ -663,6 +370,7 @@ sub ecc_verify_message { sub ecc_sign_hash { my $key = shift; + local $SIG{__DIE__} = \&CryptX::_croak; $key = __PACKAGE__->new($key) unless ref $key; carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; return $key->sign_hash(@_); @@ -670,6 +378,7 @@ sub ecc_sign_hash { sub ecc_verify_hash { my $key = shift; + local $SIG{__DIE__} = \&CryptX::_croak; $key = __PACKAGE__->new($key) unless ref $key; carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; return $key->verify_hash(@_); @@ -677,6 +386,7 @@ sub ecc_verify_hash { sub ecc_shared_secret { my ($privkey, $pubkey) = @_; + local $SIG{__DIE__} = \&CryptX::_croak; $privkey = __PACKAGE__->new($privkey) unless ref $privkey; $pubkey = __PACKAGE__->new($pubkey) unless ref $pubkey; carp "FATAL: invalid 'privkey' param" unless ref($privkey) eq __PACKAGE__ && $privkey->is_private; @@ -912,6 +622,13 @@ Supported key formats: lBQ9T/RsLLc+PmpB1+7yPAR+oR5gZn3kJQ== -----END EC PRIVATE KEY----- +=item * EC private keys with curve defined by OID + compressed form (supported since: CryptX-0.059) + + -----BEGIN EC PRIVATE KEY----- + MFcCAQEEIBG1c3z52T8XwMsahGVdOZWgKCQJfv+l7djuJjgetdbDoAoGCCqGSM49 + AwEHoSQDIgADoBUyo8CQAFPeYPvv78ylh5MwFZjTCLQeb042TjiMJxE= + -----END EC PRIVATE KEY----- + =item * EC private keys in password protected PEM format -----BEGIN EC PRIVATE KEY----- @@ -944,6 +661,13 @@ Supported key formats: CLQeb042TjiMJxG+9DLFmRSMlBQ9T/RsLLc+PmpB1+7yPAR+oR5gZn3kJQ== -----END PUBLIC KEY----- +=item * EC public keys with curve defined by OID + public point in compressed form (supported since: CryptX-0.059) + + -----BEGIN PUBLIC KEY----- + MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADoBUyo8CQAFPeYPvv78ylh5MwFZjT + CLQeb042TjiMJxE= + -----END PUBLIC KEY----- + =item * PKCS#8 private keys with all curve parameters -----BEGIN PRIVATE KEY----- @@ -964,7 +688,7 @@ Supported key formats: lEHQYjWya2YnHaPq/iMFa7A= -----END PRIVATE KEY----- -=item * PKCS#8 encrypted private keys ARE NOT SUPPORTED YET! +=item * PKCS#8 encrypted private keys - password protected keys (supported since: CryptX-0.059) -----BEGIN ENCRYPTED PRIVATE KEY----- MIGYMBwGCiqGSIb3DQEMAQMwDgQINApjTa6oFl0CAggABHi+59l4d4e6KtG9yci2 @@ -973,6 +697,19 @@ Supported key formats: 4INKZyMv/G7VpZ0= -----END ENCRYPTED PRIVATE KEY----- +=item * EC public key from X509 certificate + + -----BEGIN CERTIFICATE----- + MIIBdDCCARqgAwIBAgIJAL2BBClDEnnOMAoGCCqGSM49BAMEMBcxFTATBgNVBAMM + DFRlc3QgQ2VydCBFQzAgFw0xNzEyMzAyMDMzNDFaGA8zMDE3MDUwMjIwMzM0MVow + FzEVMBMGA1UEAwwMVGVzdCBDZXJ0IEVDMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE + KvkL2r5xZp7RzxLQJK+6tn/7lic+L70e1fmNbHOdxRaRvbK5G0AQWrdsbjJb92Ni + lCQk2+w/i+VuS2Q3MSR5TaNQME4wHQYDVR0OBBYEFGbJkDyKgaMcIGHS8/WuqIVw + +R8sMB8GA1UdIwQYMBaAFGbJkDyKgaMcIGHS8/WuqIVw+R8sMAwGA1UdEwQFMAMB + Af8wCgYIKoZIzj0EAwQDSAAwRQIhAJtOsmrM+gJpImoynAyqTN+7myL71uxd+YeC + 6ze4MnzWAiBQi5/BqEr/SQ1+BC2TPtswvJPRFh2ZvT/6Km3gKoNVXQ== + -----END CERTIFICATE----- + =item * SSH public EC keys ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNT...T3xYfJIs= @@ -1035,6 +772,13 @@ that does not explicitly contain curve parameters but only curve OID. #or my $public_der = $pk->export_key_der('public_short'); +Since CryptX-0.59 C<export_key_der> can also export keys in "compressed" format +that defines curve by OID + stores public point in compressed form. + + my $private_pem = $pk->export_key_der('private_compressed'); + #or + my $public_pem = $pk->export_key_der('public_compressed'); + =head2 export_key_pem my $private_pem = $pk->export_key_pem('private'); @@ -1048,6 +792,13 @@ that does not explicitly contain curve parameters but only curve OID. #or my $public_pem = $pk->export_key_pem('public_short'); +Since CryptX-0.59 C<export_key_pem> can also export keys in "compressed" format +that defines curve by OID + stores public point in compressed form. + + my $private_pem = $pk->export_key_pem('private_compressed'); + #or + my $public_pem = $pk->export_key_pem('public_compressed'); + Support for password protected PEM keys my $private_pem = $pk->export_key_pem('private', $password); @@ -1154,11 +905,25 @@ Same as L<verify_message|/verify_message> only the signature format is as define my $pk = Crypt::PK::ECC->new($priv_key_filename); my $signature = $priv->sign_hash($message_hash); +=head2 sign_hash_rfc7518 + +I<Since: CryptX-0.059> + +Same as L<sign_hash|/sign_hash> only the signature format is as defined by L<https://tools.ietf.org/html/rfc7518> +(JWA - JSON Web Algorithms). + =head2 verify_hash my $pk = Crypt::PK::ECC->new($pub_key_filename); my $valid = $pub->verify_hash($signature, $message_hash); +=head2 verify_hash_rfc7518 + +I<Since: CryptX-0.059> + +Same as L<verify_hash|/verify_hash> only the signature format is as defined by L<https://tools.ietf.org/html/rfc7518> +(JWA - JSON Web Algorithms). + =head2 shared_secret # Alice having her priv key $pk and Bob's public key $pkb diff --git a/lib/Crypt/PK/RSA.pm b/lib/Crypt/PK/RSA.pm index 0344a80c..722b4ed9 100644 --- a/lib/Crypt/PK/RSA.pm +++ b/lib/Crypt/PK/RSA.pm @@ -2,7 +2,7 @@ package Crypt::PK::RSA; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; our %EXPORT_TAGS = ( all => [qw(rsa_encrypt rsa_decrypt rsa_sign_message rsa_verify_message rsa_sign_hash rsa_verify_hash)] ); @@ -16,10 +16,8 @@ use Crypt::Misc qw(read_rawfile encode_b64u decode_b64u encode_b64 decode_b64 pe use Crypt::PK; sub new { - my ($class, $f, $p) = @_; - my $self = _new(); - $self->import_key($f, $p) if $f; - return $self; + my $self = shift->_new(); + return @_ > 0 ? $self->import_key(@_) : $self; } sub export_key_pem { @@ -165,64 +163,11 @@ sub import_key { croak "FATAL: invalid or unsupported RSA key format"; } -sub encrypt { - my ($self, $data, $padding, $hash_name, $lparam) = @_; - $lparam ||= ''; - $padding ||= 'oaep'; - $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); - - return $self->_encrypt($data, $padding, $hash_name, $lparam); -} - -sub decrypt { - my ($self, $data, $padding, $hash_name, $lparam) = @_; - $lparam ||= ''; - $padding ||= 'oaep'; - $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); - - return $self->_decrypt($data, $padding, $hash_name, $lparam); -} - -sub sign_hash { - my ($self, $data, $hash_name, $padding, $saltlen) = @_; - $saltlen ||= 12; - $padding ||= 'pss'; - $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); - - return $self->_sign($data, $padding, $hash_name, $saltlen); -} - -sub sign_message { - my ($self, $data, $hash_name, $padding, $saltlen) = @_; - $saltlen ||= 12; - $padding ||= 'pss'; - $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); - - return $self->_sign(digest_data($hash_name, $data), $padding, $hash_name, $saltlen); -} - -sub verify_hash { - my ($self, $sig, $data, $hash_name, $padding, $saltlen) = @_; - $saltlen ||= 12; - $padding ||= 'pss'; - $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); - - return $self->_verify($sig, $data, $padding, $hash_name, $saltlen); -} - -sub verify_message { - my ($self, $sig, $data, $hash_name, $padding, $saltlen) = @_; - $saltlen ||= 12; - $padding ||= 'pss'; - $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); - - return $self->_verify($sig, digest_data($hash_name, $data), $padding, $hash_name, $saltlen); -} - ### FUNCTIONS sub rsa_encrypt { my $key = shift; + local $SIG{__DIE__} = \&CryptX::_croak; $key = __PACKAGE__->new($key) unless ref $key; carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; return $key->encrypt(@_); @@ -230,6 +175,7 @@ sub rsa_encrypt { sub rsa_decrypt { my $key = shift; + local $SIG{__DIE__} = \&CryptX::_croak; $key = __PACKAGE__->new($key) unless ref $key; carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; return $key->decrypt(@_); @@ -237,6 +183,7 @@ sub rsa_decrypt { sub rsa_sign_hash { my $key = shift; + local $SIG{__DIE__} = \&CryptX::_croak; $key = __PACKAGE__->new($key) unless ref $key; carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; return $key->sign_hash(@_); @@ -244,6 +191,7 @@ sub rsa_sign_hash { sub rsa_verify_hash { my $key = shift; + local $SIG{__DIE__} = \&CryptX::_croak; $key = __PACKAGE__->new($key) unless ref $key; carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; return $key->verify_hash(@_); @@ -251,6 +199,7 @@ sub rsa_verify_hash { sub rsa_sign_message { my $key = shift; + local $SIG{__DIE__} = \&CryptX::_croak; $key = __PACKAGE__->new($key) unless ref $key; carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; return $key->sign_message(@_); @@ -258,6 +207,7 @@ sub rsa_sign_message { sub rsa_verify_message { my $key = shift; + local $SIG{__DIE__} = \&CryptX::_croak; $key = __PACKAGE__->new($key) unless ref $key; carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; return $key->verify_message(@_); diff --git a/lib/Crypt/PRNG.pm b/lib/Crypt/PRNG.pm index 41cfc155..12858393 100644 --- a/lib/Crypt/PRNG.pm +++ b/lib/Crypt/PRNG.pm @@ -2,42 +2,17 @@ package Crypt::PRNG; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; -use base qw(Exporter); +require Exporter; our @ISA = qw(Exporter); ### use Exporter 'import'; our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); -#BEWARE: cannot use Crypt::Misc qw(encode_b64 encode_b64u); +use Carp; +$Carp::Internal{(__PACKAGE__)}++; use CryptX; -sub _trans_prng_name { - my $name = shift; - $name =~ s/^Crypt::PRNG:://; - return lc($name); -} - -### METHODS - -sub new { - my $pkg = shift; - my $prng_name = $pkg eq __PACKAGE__ ? _trans_prng_name(shift||'ChaCha20') : _trans_prng_name($pkg); - return _new($$, $prng_name, @_); -} - -sub bytes { return shift->_bytes($$, shift) } - -sub int32 { return shift->_int32($$) } - -sub double { return shift->_double($$, shift) } - -sub bytes_hex { return unpack("H*", shift->bytes(shift)) } - -sub bytes_b64 { return CryptX::_encode_base64(shift->bytes(shift)) } - -sub bytes_b64u { return CryptX::_encode_base64url(shift->bytes(shift)) } - sub string { my ($self, $len) = @_; return $self->string_from("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", $len); diff --git a/lib/Crypt/PRNG/ChaCha20.pm b/lib/Crypt/PRNG/ChaCha20.pm index c0e3dc21..b44441cb 100644 --- a/lib/Crypt/PRNG/ChaCha20.pm +++ b/lib/Crypt/PRNG/ChaCha20.pm @@ -2,7 +2,7 @@ package Crypt::PRNG::ChaCha20; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::PRNG Exporter); our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] ); @@ -10,7 +10,6 @@ our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); use CryptX; -use base 'Crypt::PRNG'; { ### stolen from Bytes::Random::Secure diff --git a/lib/Crypt/PRNG/Fortuna.pm b/lib/Crypt/PRNG/Fortuna.pm index 0b4b9e17..19a57096 100644 --- a/lib/Crypt/PRNG/Fortuna.pm +++ b/lib/Crypt/PRNG/Fortuna.pm @@ -2,7 +2,7 @@ package Crypt::PRNG::Fortuna; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::PRNG Exporter); our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] ); @@ -10,7 +10,6 @@ our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); use CryptX; -use base 'Crypt::PRNG'; { ### stolen from Bytes::Random::Secure diff --git a/lib/Crypt/PRNG/RC4.pm b/lib/Crypt/PRNG/RC4.pm index e250b7c6..63af12f0 100644 --- a/lib/Crypt/PRNG/RC4.pm +++ b/lib/Crypt/PRNG/RC4.pm @@ -2,7 +2,7 @@ package Crypt::PRNG::RC4; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::PRNG Exporter); our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] ); @@ -10,7 +10,6 @@ our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); use CryptX; -use base 'Crypt::PRNG'; { ### stolen from Bytes::Random::Secure diff --git a/lib/Crypt/PRNG/Sober128.pm b/lib/Crypt/PRNG/Sober128.pm index 3fc29253..1249ec89 100644 --- a/lib/Crypt/PRNG/Sober128.pm +++ b/lib/Crypt/PRNG/Sober128.pm @@ -2,7 +2,7 @@ package Crypt::PRNG::Sober128; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::PRNG Exporter); our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] ); @@ -10,7 +10,6 @@ our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw(); use CryptX; -use base 'Crypt::PRNG'; { ### stolen from Bytes::Random::Secure diff --git a/lib/Crypt/PRNG/Yarrow.pm b/lib/Crypt/PRNG/Yarrow.pm index f85450c8..70052a17 100644 --- a/lib/Crypt/PRNG/Yarrow.pm +++ b/lib/Crypt/PRNG/Yarrow.pm @@ -2,7 +2,7 @@ package Crypt::PRNG::Yarrow; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use base qw(Crypt::PRNG Exporter); our %EXPORT_TAGS = ( all => [qw(random_bytes random_bytes_hex random_bytes_b64 random_bytes_b64u random_string random_string_from rand irand)] ); diff --git a/lib/Crypt/Stream/ChaCha.pm b/lib/Crypt/Stream/ChaCha.pm index 80555aff..2c9eb1ac 100644 --- a/lib/Crypt/Stream/ChaCha.pm +++ b/lib/Crypt/Stream/ChaCha.pm @@ -2,7 +2,7 @@ package Crypt::Stream::ChaCha; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use CryptX; diff --git a/lib/Crypt/Stream/RC4.pm b/lib/Crypt/Stream/RC4.pm index 2d21f9ff..d1e6ed4f 100644 --- a/lib/Crypt/Stream/RC4.pm +++ b/lib/Crypt/Stream/RC4.pm @@ -2,7 +2,7 @@ package Crypt::Stream::RC4; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use CryptX; diff --git a/lib/Crypt/Stream/Rabbit.pm b/lib/Crypt/Stream/Rabbit.pm index 2facea9c..649e63db 100644 --- a/lib/Crypt/Stream/Rabbit.pm +++ b/lib/Crypt/Stream/Rabbit.pm @@ -2,7 +2,7 @@ package Crypt::Stream::Rabbit; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use CryptX; diff --git a/lib/Crypt/Stream/Salsa20.pm b/lib/Crypt/Stream/Salsa20.pm index 005ca167..26478b21 100644 --- a/lib/Crypt/Stream/Salsa20.pm +++ b/lib/Crypt/Stream/Salsa20.pm @@ -2,7 +2,7 @@ package Crypt::Stream::Salsa20; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use CryptX; diff --git a/lib/Crypt/Stream/Sober128.pm b/lib/Crypt/Stream/Sober128.pm index 1b407957..cc2db1b5 100644 --- a/lib/Crypt/Stream/Sober128.pm +++ b/lib/Crypt/Stream/Sober128.pm @@ -2,7 +2,7 @@ package Crypt::Stream::Sober128; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use CryptX; diff --git a/lib/Crypt/Stream/Sosemanuk.pm b/lib/Crypt/Stream/Sosemanuk.pm index 6e44f706..790447d9 100644 --- a/lib/Crypt/Stream/Sosemanuk.pm +++ b/lib/Crypt/Stream/Sosemanuk.pm @@ -2,7 +2,7 @@ package Crypt::Stream::Sosemanuk; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use CryptX; diff --git a/lib/CryptX.pm b/lib/CryptX.pm index 3b60a19a..ead2f929 100644 --- a/lib/CryptX.pm +++ b/lib/CryptX.pm @@ -2,10 +2,7 @@ package CryptX; use strict; use warnings ; -our $VERSION = '0.056'; - -use base qw(Exporter); -our @EXPORT_OK = qw(); +our $VERSION = '0.059'; require XSLoader; XSLoader::load('CryptX', $VERSION); @@ -67,7 +64,7 @@ CryptX - Cryptographic toolkit (self-contained, no external libraries needed) Cryptography in CryptX is based on L<https://github.com/libtom/libtomcrypt> -Currently available modules: +Available modules: =over @@ -99,11 +96,12 @@ L<Crypt::Digest::BLAKE2s_128>, L<Crypt::Digest::BLAKE2s_160>, L<Crypt::Digest::B L<Crypt::Digest::CHAES>, L<Crypt::Digest::MD2>, L<Crypt::Digest::MD4>, L<Crypt::Digest::MD5>, L<Crypt::Digest::RIPEMD128>, L<Crypt::Digest::RIPEMD160>, L<Crypt::Digest::RIPEMD256>, L<Crypt::Digest::RIPEMD320>, L<Crypt::Digest::SHA1>, L<Crypt::Digest::SHA224>, L<Crypt::Digest::SHA256>, L<Crypt::Digest::SHA384>, L<Crypt::Digest::SHA512>, L<Crypt::Digest::SHA512_224>, L<Crypt::Digest::SHA512_256>, L<Crypt::Digest::Tiger192>, L<Crypt::Digest::Whirlpool>, +L<Crypt::Digest::Keccak224>, L<Crypt::Digest::Keccak256>, L<Crypt::Digest::Keccak384>, L<Crypt::Digest::Keccak512>, L<Crypt::Digest::SHA3_224>, L<Crypt::Digest::SHA3_256>, L<Crypt::Digest::SHA3_384>, L<Crypt::Digest::SHA3_512>, L<Crypt::Digest::SHAKE> =item * Checksums -L<Crypt::Checksum>, L<Crypt::Checksum::Adler32>, L<Crypt::Checksum::CRC32> +L<Crypt::Checksum::Adler32>, L<Crypt::Checksum::CRC32> =item * Message Authentication Codes @@ -114,9 +112,9 @@ L<Crypt::Mac::Pelican>, L<Crypt::Mac::PMAC>, L<Crypt::Mac::XCBC>, L<Crypt::Mac:: L<Crypt::PK::RSA>, L<Crypt::PK::DSA>, L<Crypt::PK::ECC>, L<Crypt::PK::DH> -=item * Cryptographically secure random number generators +=item * Cryptographically secure random number generators - see L<Crypt::PRNG> and related modules -L<Crypt::PRNG>, L<Crypt::PRNG::Fortuna>, L<Crypt::PRNG::Yarrow>, L<Crypt::PRNG::RC4>, L<Crypt::PRNG::Sober128>, L<Crypt::PRNG::ChaCha20> +L<Crypt::PRNG::Fortuna>, L<Crypt::PRNG::Yarrow>, L<Crypt::PRNG::RC4>, L<Crypt::PRNG::Sober128>, L<Crypt::PRNG::ChaCha20> =item * Key derivation functions - PBKDF1, PBKDF2 and HKDF @@ -134,6 +132,6 @@ This program is free software; you can redistribute it and/or modify it under th =head1 COPYRIGHT -Copyright (c) 2013+ DCIT, a.s. L<http://www.dcit.cz> / Karel Miko +Copyright (c) 2013+ DCIT, a.s. L<https://www.dcit.cz> / Karel Miko =cut diff --git a/lib/Math/BigInt/LTM.pm b/lib/Math/BigInt/LTM.pm index 3acc41f9..9d09b43f 100644 --- a/lib/Math/BigInt/LTM.pm +++ b/lib/Math/BigInt/LTM.pm @@ -2,7 +2,7 @@ package Math::BigInt::LTM; use strict; use warnings; -our $VERSION = '0.056'; +our $VERSION = '0.059'; use CryptX; diff --git a/src/Makefile b/src/Makefile index e75ff89d..6775fa91 100644 --- a/src/Makefile +++ b/src/Makefile @@ -66,7 +66,12 @@ ltc/modes/ofb/ofb_start.o ltc/pk/asn1/der/bit/der_decode_bit_string.o ltc/pk/asn ltc/pk/asn1/der/bit/der_encode_bit_string.o ltc/pk/asn1/der/bit/der_encode_raw_bit_string.o \ ltc/pk/asn1/der/bit/der_length_bit_string.o ltc/pk/asn1/der/boolean/der_decode_boolean.o \ ltc/pk/asn1/der/boolean/der_encode_boolean.o ltc/pk/asn1/der/boolean/der_length_boolean.o \ -ltc/pk/asn1/der/choice/der_decode_choice.o ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.o \ +ltc/pk/asn1/der/choice/der_decode_choice.o ltc/pk/asn1/der/custom_type/der_decode_custom_type.o \ +ltc/pk/asn1/der/custom_type/der_encode_custom_type.o ltc/pk/asn1/der/custom_type/der_length_custom_type.o \ +ltc/pk/asn1/der/general/der_asn1_maps.o ltc/pk/asn1/der/general/der_decode_asn1_identifier.o \ +ltc/pk/asn1/der/general/der_decode_asn1_length.o ltc/pk/asn1/der/general/der_encode_asn1_identifier.o \ +ltc/pk/asn1/der/general/der_encode_asn1_length.o ltc/pk/asn1/der/general/der_length_asn1_identifier.o \ +ltc/pk/asn1/der/general/der_length_asn1_length.o ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.o \ ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.o ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.o \ ltc/pk/asn1/der/ia5/der_decode_ia5_string.o ltc/pk/asn1/der/ia5/der_encode_ia5_string.o \ ltc/pk/asn1/der/ia5/der_length_ia5_string.o ltc/pk/asn1/der/integer/der_decode_integer.o \ @@ -77,8 +82,7 @@ ltc/pk/asn1/der/octet/der_encode_octet_string.o ltc/pk/asn1/der/octet/der_length ltc/pk/asn1/der/printable_string/der_decode_printable_string.o ltc/pk/asn1/der/printable_string/der_encode_printable_string.o \ ltc/pk/asn1/der/printable_string/der_length_printable_string.o ltc/pk/asn1/der/sequence/der_decode_sequence_ex.o \ ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.o ltc/pk/asn1/der/sequence/der_decode_sequence_multi.o \ -ltc/pk/asn1/der/sequence/der_decode_subject_public_key_info.o ltc/pk/asn1/der/sequence/der_encode_sequence_ex.o \ -ltc/pk/asn1/der/sequence/der_encode_sequence_multi.o ltc/pk/asn1/der/sequence/der_encode_subject_public_key_info.o \ +ltc/pk/asn1/der/sequence/der_encode_sequence_ex.o ltc/pk/asn1/der/sequence/der_encode_sequence_multi.o \ ltc/pk/asn1/der/sequence/der_length_sequence.o ltc/pk/asn1/der/sequence/der_sequence_free.o \ ltc/pk/asn1/der/sequence/der_sequence_shrink.o ltc/pk/asn1/der/set/der_encode_set.o \ ltc/pk/asn1/der/set/der_encode_setof.o ltc/pk/asn1/der/short_integer/der_decode_short_integer.o \ @@ -87,6 +91,7 @@ ltc/pk/asn1/der/teletex_string/der_decode_teletex_string.o ltc/pk/asn1/der/telet ltc/pk/asn1/der/utctime/der_decode_utctime.o ltc/pk/asn1/der/utctime/der_encode_utctime.o \ ltc/pk/asn1/der/utctime/der_length_utctime.o ltc/pk/asn1/der/utf8/der_decode_utf8_string.o \ ltc/pk/asn1/der/utf8/der_encode_utf8_string.o ltc/pk/asn1/der/utf8/der_length_utf8_string.o \ +ltc/pk/asn1/x509/x509_decode_subject_public_key_info.o ltc/pk/asn1/x509/x509_encode_subject_public_key_info.o \ ltc/pk/dh/dh.o ltc/pk/dh/dh_check_pubkey.o ltc/pk/dh/dh_export.o ltc/pk/dh/dh_export_key.o \ ltc/pk/dh/dh_free.o ltc/pk/dh/dh_generate_key.o ltc/pk/dh/dh_import.o ltc/pk/dh/dh_set.o \ ltc/pk/dh/dh_set_pg_dhparam.o ltc/pk/dh/dh_shared_secret.o ltc/pk/dsa/dsa_decrypt_key.o \ @@ -94,24 +99,23 @@ ltc/pk/dsa/dsa_encrypt_key.o ltc/pk/dsa/dsa_export.o ltc/pk/dsa/dsa_free.o ltc/p ltc/pk/dsa/dsa_generate_pqg.o ltc/pk/dsa/dsa_import.o ltc/pk/dsa/dsa_make_key.o ltc/pk/dsa/dsa_set.o \ 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_dp_clear.o \ -ltc/pk/ecc/ecc_dp_fill_from_sets.o ltc/pk/ecc/ecc_dp_from_oid.o ltc/pk/ecc/ecc_dp_from_params.o \ -ltc/pk/ecc/ecc_dp_init.o ltc/pk/ecc/ecc_dp_set.o ltc/pk/ecc/ecc_encrypt_key.o ltc/pk/ecc/ecc_export.o \ -ltc/pk/ecc/ecc_export_full.o ltc/pk/ecc/ecc_export_raw.o ltc/pk/ecc/ecc_free.o ltc/pk/ecc/ecc_get_size.o \ -ltc/pk/ecc/ecc_import.o ltc/pk/ecc/ecc_import_full.o ltc/pk/ecc/ecc_import_pkcs8.o \ -ltc/pk/ecc/ecc_import_raw.o ltc/pk/ecc/ecc_make_key.o ltc/pk/ecc/ecc_shared_secret.o \ -ltc/pk/ecc/ecc_sign_hash.o ltc/pk/ecc/ecc_sizes.o ltc/pk/ecc/ecc_verify_hash.o ltc/pk/ecc/ecc_verify_key.o \ -ltc/pk/ecc/ltc_ecc_export_point.o ltc/pk/ecc/ltc_ecc_import_point.o ltc/pk/ecc/ltc_ecc_is_point.o \ -ltc/pk/ecc/ltc_ecc_is_point_at_infinity.o ltc/pk/ecc/ltc_ecc_is_valid_idx.o ltc/pk/ecc/ltc_ecc_map.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_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 \ +ltc/pk/ecc/ecc_verify_hash.o ltc/pk/ecc/ltc_ecc_export_point.o ltc/pk/ecc/ltc_ecc_import_point.o \ +ltc/pk/ecc/ltc_ecc_is_point.o ltc/pk/ecc/ltc_ecc_is_point_at_infinity.o ltc/pk/ecc/ltc_ecc_map.o \ ltc/pk/ecc/ltc_ecc_mul2add.o ltc/pk/ecc/ltc_ecc_mulmod.o ltc/pk/ecc/ltc_ecc_mulmod_timing.o \ ltc/pk/ecc/ltc_ecc_points.o ltc/pk/ecc/ltc_ecc_projective_add_point.o ltc/pk/ecc/ltc_ecc_projective_dbl_point.o \ -ltc/pk/pkcs1/pkcs_1_i2osp.o ltc/pk/pkcs1/pkcs_1_mgf1.o ltc/pk/pkcs1/pkcs_1_oaep_decode.o \ -ltc/pk/pkcs1/pkcs_1_oaep_encode.o ltc/pk/pkcs1/pkcs_1_os2ip.o ltc/pk/pkcs1/pkcs_1_pss_decode.o \ -ltc/pk/pkcs1/pkcs_1_pss_encode.o ltc/pk/pkcs1/pkcs_1_v1_5_decode.o ltc/pk/pkcs1/pkcs_1_v1_5_encode.o \ -ltc/pk/rsa/rsa_decrypt_key.o ltc/pk/rsa/rsa_encrypt_key.o ltc/pk/rsa/rsa_export.o \ -ltc/pk/rsa/rsa_exptmod.o ltc/pk/rsa/rsa_free.o ltc/pk/rsa/rsa_get_size.o ltc/pk/rsa/rsa_import.o \ -ltc/pk/rsa/rsa_import_pkcs8.o ltc/pk/rsa/rsa_import_x509.o ltc/pk/rsa/rsa_make_key.o \ -ltc/pk/rsa/rsa_set.o ltc/pk/rsa/rsa_sign_hash.o ltc/pk/rsa/rsa_sign_saltlen_get.o \ +ltc/pk/ecc/ltc_ecc_verify_key.o ltc/pk/pkcs1/pkcs_1_i2osp.o ltc/pk/pkcs1/pkcs_1_mgf1.o \ +ltc/pk/pkcs1/pkcs_1_oaep_decode.o ltc/pk/pkcs1/pkcs_1_oaep_encode.o ltc/pk/pkcs1/pkcs_1_os2ip.o \ +ltc/pk/pkcs1/pkcs_1_pss_decode.o ltc/pk/pkcs1/pkcs_1_pss_encode.o ltc/pk/pkcs1/pkcs_1_v1_5_decode.o \ +ltc/pk/pkcs1/pkcs_1_v1_5_encode.o ltc/pk/rsa/rsa_decrypt_key.o ltc/pk/rsa/rsa_encrypt_key.o \ +ltc/pk/rsa/rsa_export.o ltc/pk/rsa/rsa_exptmod.o ltc/pk/rsa/rsa_free.o ltc/pk/rsa/rsa_get_size.o \ +ltc/pk/rsa/rsa_import.o ltc/pk/rsa/rsa_import_pkcs8.o ltc/pk/rsa/rsa_import_x509.o \ +ltc/pk/rsa/rsa_make_key.o ltc/pk/rsa/rsa_set.o ltc/pk/rsa/rsa_sign_hash.o ltc/pk/rsa/rsa_sign_saltlen_get.o \ ltc/pk/rsa/rsa_verify_hash.o ltc/prngs/chacha20.o ltc/prngs/fortuna.o ltc/prngs/rc4.o \ ltc/prngs/rng_get_bytes.o ltc/prngs/rng_make_prng.o ltc/prngs/sober128.o ltc/prngs/sprng.o \ ltc/prngs/yarrow.o ltc/stream/chacha/chacha_crypt.o ltc/stream/chacha/chacha_done.o \ diff --git a/src/Makefile.nmake b/src/Makefile.nmake index b2f400cb..3bef06ea 100644 --- a/src/Makefile.nmake +++ b/src/Makefile.nmake @@ -73,6 +73,11 @@ ltc/pk/asn1/der/bit/der_decode_raw_bit_string.obj ltc/pk/asn1/der/bit/der_encode ltc/pk/asn1/der/bit/der_encode_raw_bit_string.obj ltc/pk/asn1/der/bit/der_length_bit_string.obj \ ltc/pk/asn1/der/boolean/der_decode_boolean.obj ltc/pk/asn1/der/boolean/der_encode_boolean.obj \ ltc/pk/asn1/der/boolean/der_length_boolean.obj ltc/pk/asn1/der/choice/der_decode_choice.obj \ +ltc/pk/asn1/der/custom_type/der_decode_custom_type.obj ltc/pk/asn1/der/custom_type/der_encode_custom_type.obj \ +ltc/pk/asn1/der/custom_type/der_length_custom_type.obj ltc/pk/asn1/der/general/der_asn1_maps.obj \ +ltc/pk/asn1/der/general/der_decode_asn1_identifier.obj ltc/pk/asn1/der/general/der_decode_asn1_length.obj \ +ltc/pk/asn1/der/general/der_encode_asn1_identifier.obj ltc/pk/asn1/der/general/der_encode_asn1_length.obj \ +ltc/pk/asn1/der/general/der_length_asn1_identifier.obj ltc/pk/asn1/der/general/der_length_asn1_length.obj \ ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.obj ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.obj \ ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.obj ltc/pk/asn1/der/ia5/der_decode_ia5_string.obj \ ltc/pk/asn1/der/ia5/der_encode_ia5_string.obj ltc/pk/asn1/der/ia5/der_length_ia5_string.obj \ @@ -83,9 +88,8 @@ ltc/pk/asn1/der/octet/der_decode_octet_string.obj ltc/pk/asn1/der/octet/der_enco ltc/pk/asn1/der/octet/der_length_octet_string.obj ltc/pk/asn1/der/printable_string/der_decode_printable_string.obj \ ltc/pk/asn1/der/printable_string/der_encode_printable_string.obj ltc/pk/asn1/der/printable_string/der_length_printable_string.obj \ ltc/pk/asn1/der/sequence/der_decode_sequence_ex.obj ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.obj \ -ltc/pk/asn1/der/sequence/der_decode_sequence_multi.obj ltc/pk/asn1/der/sequence/der_decode_subject_public_key_info.obj \ -ltc/pk/asn1/der/sequence/der_encode_sequence_ex.obj ltc/pk/asn1/der/sequence/der_encode_sequence_multi.obj \ -ltc/pk/asn1/der/sequence/der_encode_subject_public_key_info.obj ltc/pk/asn1/der/sequence/der_length_sequence.obj \ +ltc/pk/asn1/der/sequence/der_decode_sequence_multi.obj ltc/pk/asn1/der/sequence/der_encode_sequence_ex.obj \ +ltc/pk/asn1/der/sequence/der_encode_sequence_multi.obj ltc/pk/asn1/der/sequence/der_length_sequence.obj \ ltc/pk/asn1/der/sequence/der_sequence_free.obj ltc/pk/asn1/der/sequence/der_sequence_shrink.obj \ ltc/pk/asn1/der/set/der_encode_set.obj ltc/pk/asn1/der/set/der_encode_setof.obj ltc/pk/asn1/der/short_integer/der_decode_short_integer.obj \ ltc/pk/asn1/der/short_integer/der_encode_short_integer.obj ltc/pk/asn1/der/short_integer/der_length_short_integer.obj \ @@ -93,6 +97,7 @@ ltc/pk/asn1/der/teletex_string/der_decode_teletex_string.obj ltc/pk/asn1/der/tel ltc/pk/asn1/der/utctime/der_decode_utctime.obj ltc/pk/asn1/der/utctime/der_encode_utctime.obj \ ltc/pk/asn1/der/utctime/der_length_utctime.obj ltc/pk/asn1/der/utf8/der_decode_utf8_string.obj \ ltc/pk/asn1/der/utf8/der_encode_utf8_string.obj ltc/pk/asn1/der/utf8/der_length_utf8_string.obj \ +ltc/pk/asn1/x509/x509_decode_subject_public_key_info.obj ltc/pk/asn1/x509/x509_encode_subject_public_key_info.obj \ ltc/pk/dh/dh.obj ltc/pk/dh/dh_check_pubkey.obj ltc/pk/dh/dh_export.obj ltc/pk/dh/dh_export_key.obj \ ltc/pk/dh/dh_free.obj ltc/pk/dh/dh_generate_key.obj ltc/pk/dh/dh_import.obj ltc/pk/dh/dh_set.obj \ ltc/pk/dh/dh_set_pg_dhparam.obj ltc/pk/dh/dh_shared_secret.obj ltc/pk/dsa/dsa_decrypt_key.obj \ @@ -101,25 +106,24 @@ ltc/pk/dsa/dsa_generate_key.obj ltc/pk/dsa/dsa_generate_pqg.obj ltc/pk/dsa/dsa_i ltc/pk/dsa/dsa_make_key.obj ltc/pk/dsa/dsa_set.obj ltc/pk/dsa/dsa_set_pqg_dsaparam.obj \ ltc/pk/dsa/dsa_shared_secret.obj ltc/pk/dsa/dsa_sign_hash.obj ltc/pk/dsa/dsa_verify_hash.obj \ 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_dp_clear.obj \ -ltc/pk/ecc/ecc_dp_fill_from_sets.obj ltc/pk/ecc/ecc_dp_from_oid.obj ltc/pk/ecc/ecc_dp_from_params.obj \ -ltc/pk/ecc/ecc_dp_init.obj ltc/pk/ecc/ecc_dp_set.obj ltc/pk/ecc/ecc_encrypt_key.obj \ -ltc/pk/ecc/ecc_export.obj ltc/pk/ecc/ecc_export_full.obj ltc/pk/ecc/ecc_export_raw.obj \ -ltc/pk/ecc/ecc_free.obj ltc/pk/ecc/ecc_get_size.obj ltc/pk/ecc/ecc_import.obj ltc/pk/ecc/ecc_import_full.obj \ -ltc/pk/ecc/ecc_import_pkcs8.obj ltc/pk/ecc/ecc_import_raw.obj ltc/pk/ecc/ecc_make_key.obj \ -ltc/pk/ecc/ecc_shared_secret.obj ltc/pk/ecc/ecc_sign_hash.obj ltc/pk/ecc/ecc_sizes.obj \ -ltc/pk/ecc/ecc_verify_hash.obj ltc/pk/ecc/ecc_verify_key.obj ltc/pk/ecc/ltc_ecc_export_point.obj \ -ltc/pk/ecc/ltc_ecc_import_point.obj ltc/pk/ecc/ltc_ecc_is_point.obj ltc/pk/ecc/ltc_ecc_is_point_at_infinity.obj \ -ltc/pk/ecc/ltc_ecc_is_valid_idx.obj ltc/pk/ecc/ltc_ecc_map.obj ltc/pk/ecc/ltc_ecc_mul2add.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_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 \ +ltc/pk/ecc/ecc_sign_hash.obj ltc/pk/ecc/ecc_sizes.obj ltc/pk/ecc/ecc_verify_hash.obj \ +ltc/pk/ecc/ltc_ecc_export_point.obj ltc/pk/ecc/ltc_ecc_import_point.obj ltc/pk/ecc/ltc_ecc_is_point.obj \ +ltc/pk/ecc/ltc_ecc_is_point_at_infinity.obj ltc/pk/ecc/ltc_ecc_map.obj ltc/pk/ecc/ltc_ecc_mul2add.obj \ ltc/pk/ecc/ltc_ecc_mulmod.obj ltc/pk/ecc/ltc_ecc_mulmod_timing.obj ltc/pk/ecc/ltc_ecc_points.obj \ ltc/pk/ecc/ltc_ecc_projective_add_point.obj ltc/pk/ecc/ltc_ecc_projective_dbl_point.obj \ -ltc/pk/pkcs1/pkcs_1_i2osp.obj ltc/pk/pkcs1/pkcs_1_mgf1.obj ltc/pk/pkcs1/pkcs_1_oaep_decode.obj \ -ltc/pk/pkcs1/pkcs_1_oaep_encode.obj ltc/pk/pkcs1/pkcs_1_os2ip.obj ltc/pk/pkcs1/pkcs_1_pss_decode.obj \ -ltc/pk/pkcs1/pkcs_1_pss_encode.obj ltc/pk/pkcs1/pkcs_1_v1_5_decode.obj ltc/pk/pkcs1/pkcs_1_v1_5_encode.obj \ -ltc/pk/rsa/rsa_decrypt_key.obj ltc/pk/rsa/rsa_encrypt_key.obj ltc/pk/rsa/rsa_export.obj \ -ltc/pk/rsa/rsa_exptmod.obj ltc/pk/rsa/rsa_free.obj ltc/pk/rsa/rsa_get_size.obj ltc/pk/rsa/rsa_import.obj \ -ltc/pk/rsa/rsa_import_pkcs8.obj ltc/pk/rsa/rsa_import_x509.obj ltc/pk/rsa/rsa_make_key.obj \ -ltc/pk/rsa/rsa_set.obj ltc/pk/rsa/rsa_sign_hash.obj ltc/pk/rsa/rsa_sign_saltlen_get.obj \ +ltc/pk/ecc/ltc_ecc_verify_key.obj ltc/pk/pkcs1/pkcs_1_i2osp.obj ltc/pk/pkcs1/pkcs_1_mgf1.obj \ +ltc/pk/pkcs1/pkcs_1_oaep_decode.obj ltc/pk/pkcs1/pkcs_1_oaep_encode.obj ltc/pk/pkcs1/pkcs_1_os2ip.obj \ +ltc/pk/pkcs1/pkcs_1_pss_decode.obj ltc/pk/pkcs1/pkcs_1_pss_encode.obj ltc/pk/pkcs1/pkcs_1_v1_5_decode.obj \ +ltc/pk/pkcs1/pkcs_1_v1_5_encode.obj ltc/pk/rsa/rsa_decrypt_key.obj ltc/pk/rsa/rsa_encrypt_key.obj \ +ltc/pk/rsa/rsa_export.obj ltc/pk/rsa/rsa_exptmod.obj ltc/pk/rsa/rsa_free.obj ltc/pk/rsa/rsa_get_size.obj \ +ltc/pk/rsa/rsa_import.obj ltc/pk/rsa/rsa_import_pkcs8.obj ltc/pk/rsa/rsa_import_x509.obj \ +ltc/pk/rsa/rsa_make_key.obj ltc/pk/rsa/rsa_set.obj ltc/pk/rsa/rsa_sign_hash.obj ltc/pk/rsa/rsa_sign_saltlen_get.obj \ ltc/pk/rsa/rsa_verify_hash.obj ltc/prngs/chacha20.obj ltc/prngs/fortuna.obj ltc/prngs/rc4.obj \ ltc/prngs/rng_get_bytes.obj ltc/prngs/rng_make_prng.obj ltc/prngs/sober128.obj ltc/prngs/sprng.obj \ ltc/prngs/yarrow.obj ltc/stream/chacha/chacha_crypt.obj ltc/stream/chacha/chacha_done.obj \ diff --git a/src/ltc/hashes/sha3.c b/src/ltc/hashes/sha3.c index c6faa0b9..1c01d6a1 100644 --- a/src/ltc/hashes/sha3.c +++ b/src/ltc/hashes/sha3.c @@ -72,6 +72,67 @@ const struct ltc_hash_descriptor sha3_512_desc = &sha3_512_test, NULL }; +#endif + +#ifdef LTC_KECCAK +const struct ltc_hash_descriptor keccak_224_desc = +{ + "keccak224", /* name of hash */ + 29, /* internal ID */ + 28, /* Size of digest in octets */ + 144, /* Input block size in octets */ + { 0 }, 0, /* no ASN.1 OID */ + &sha3_224_init, + &sha3_process, + &keccak_done, + &keccak_224_test, + NULL +}; + +const struct ltc_hash_descriptor keccak_256_desc = +{ + "keccak256", /* name of hash */ + 30, /* internal ID */ + 32, /* Size of digest in octets */ + 136, /* Input block size in octets */ + { 0 }, 0, /* no ASN.1 OID */ + &sha3_256_init, + &sha3_process, + &keccak_done, + &keccak_256_test, + NULL +}; + +const struct ltc_hash_descriptor keccak_384_desc = +{ + "keccak384", /* name of hash */ + 31, /* internal ID */ + 48, /* Size of digest in octets */ + 104, /* Input block size in octets */ + { 0 }, 0, /* no ASN.1 OID */ + &sha3_384_init, + &sha3_process, + &keccak_done, + &keccak_384_test, + NULL +}; + +const struct ltc_hash_descriptor keccak_512_desc = +{ + "keccak512", /* name of hash */ + 32, /* internal ID */ + 64, /* Size of digest in octets */ + 72, /* Input block size in octets */ + { 0 }, 0, /* no ASN.1 OID */ + &sha3_512_init, + &sha3_process, + &keccak_done, + &keccak_512_test, + NULL +}; +#endif + +#if defined(LTC_SHA3) || defined(LTC_KECCAK) #define SHA3_KECCAK_SPONGE_WORDS 25 /* 1600 bits > 200 bytes > 25 x ulong64 */ #define SHA3_KECCAK_ROUNDS 24 @@ -134,6 +195,26 @@ static void keccakf(ulong64 s[25]) } } +static LTC_INLINE int _done(hash_state *md, unsigned char *hash, ulong64 pad) +{ + unsigned i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(hash != NULL); + + md->sha3.s[md->sha3.word_index] ^= (md->sha3.saved ^ (pad << (md->sha3.byte_index * 8))); + md->sha3.s[SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words - 1] ^= CONST64(0x8000000000000000); + keccakf(md->sha3.s); + + /* store sha3.s[] as little-endian bytes into sha3.sb */ + for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) { + STORE64L(md->sha3.s[i], md->sha3.sb + i * 8); + } + + XMEMCPY(hash, md->sha3.sb, md->sha3.capacity_words * 4); + return CRYPT_OK; +} + /* Public Inteface */ int sha3_224_init(hash_state *md) @@ -168,6 +249,7 @@ int sha3_512_init(hash_state *md) return CRYPT_OK; } +#ifdef LTC_SHA3 int sha3_shake_init(hash_state *md, int num) { LTC_ARGCHK(md != NULL); @@ -176,6 +258,7 @@ int sha3_shake_init(hash_state *md, int num) md->sha3.capacity_words = (unsigned short)(2 * num / (8 * sizeof(ulong64))); return CRYPT_OK; } +#endif int sha3_process(hash_state *md, const unsigned char *in, unsigned long inlen) { @@ -229,26 +312,21 @@ int sha3_process(hash_state *md, const unsigned char *in, unsigned long inlen) return CRYPT_OK; } +#ifdef LTC_SHA3 int sha3_done(hash_state *md, unsigned char *hash) { - unsigned i; - - LTC_ARGCHK(md != NULL); - LTC_ARGCHK(hash != NULL); - - md->sha3.s[md->sha3.word_index] ^= (md->sha3.saved ^ (CONST64(0x06) << (md->sha3.byte_index * 8))); - md->sha3.s[SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words - 1] ^= CONST64(0x8000000000000000); - keccakf(md->sha3.s); - - /* store sha3.s[] as little-endian bytes into sha3.sb */ - for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) { - STORE64L(md->sha3.s[i], md->sha3.sb + i * 8); - } + return _done(md, hash, CONST64(0x06)); +} +#endif - XMEMCPY(hash, md->sha3.sb, md->sha3.capacity_words * 4); - return CRYPT_OK; +#ifdef LTC_KECCAK +int keccak_done(hash_state *md, unsigned char *hash) +{ + return _done(md, hash, CONST64(0x01)); } +#endif +#ifdef LTC_SHA3 int sha3_shake_done(hash_state *md, unsigned char *out, unsigned long outlen) { /* IMPORTANT NOTE: sha3_shake_done can be called many times */ @@ -298,6 +376,7 @@ int sha3_shake_memory(int num, const unsigned char *in, unsigned long inlen, uns if ((err = sha3_shake_done(&md, out, *outlen)) != CRYPT_OK) return err; return CRYPT_OK; } +#endif #endif diff --git a/src/ltc/hashes/sha3_test.c b/src/ltc/hashes/sha3_test.c index 5ae86506..2bf74823 100644 --- a/src/ltc/hashes/sha3_test.c +++ b/src/ltc/hashes/sha3_test.c @@ -396,6 +396,334 @@ int sha3_shake_test(void) #endif +#ifdef LTC_KECCAK + +int keccak_224_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + hash_state c; + unsigned char hash[MAXBLOCKSIZE]; + + keccak_224_init(&c); + keccak_process(&c, (unsigned char*) "\xcc", 1); + keccak_done(&c, hash); + if(compare_testvector(hash, 28, + "\xa9\xca\xb5\x9e\xb4\x0a\x10\xb2" + "\x46\x29\x0f\x2d\x60\x86\xe3\x2e" + "\x36\x89\xfa\xf1\xd2\x6b\x47\x0c" + "\x89\x9f\x28\x02", 28, + "KECCAK-224", 0) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + keccak_224_init(&c); + keccak_process(&c, (unsigned char*)"\x41\xfb", 2); + keccak_done(&c, hash); + if(compare_testvector(hash, 28, + "\x61\x5b\xa3\x67\xaf\xdc\x35\xaa" + "\xc3\x97\xbc\x7e\xb5\xd5\x8d\x10" + "\x6a\x73\x4b\x24\x98\x6d\x5d\x97" + "\x8f\xef\xd6\x2c", 28, + "KECCAK-224", 1) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + keccak_224_init(&c); + keccak_process(&c, (unsigned char*) + "\x52\xa6\x08\xab\x21\xcc\xdd\x8a" + "\x44\x57\xa5\x7e\xde\x78\x21\x76", 16); + keccak_done(&c, hash); + if(compare_testvector(hash, 28, + "\x56\x79\xcd\x50\x9c\x51\x20\xaf" + "\x54\x79\x5c\xf4\x77\x14\x96\x41" + "\xcf\x27\xb2\xeb\xb6\xa5\xf9\x03" + "\x40\x70\x4e\x57", 28, + "KECCAK-224", 2) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + keccak_224_init(&c); + keccak_process(&c, (unsigned char*) + "\x43\x3c\x53\x03\x13\x16\x24\xc0" + "\x02\x1d\x86\x8a\x30\x82\x54\x75" + "\xe8\xd0\xbd\x30\x52\xa0\x22\x18" + "\x03\x98\xf4\xca\x44\x23\xb9\x82" + "\x14\xb6\xbe\xaa\xc2\x1c\x88\x07" + "\xa2\xc3\x3f\x8c\x93\xbd\x42\xb0" + "\x92\xcc\x1b\x06\xce\xdf\x32\x24" + "\xd5\xed\x1e\xc2\x97\x84\x44\x4f" + "\x22\xe0\x8a\x55\xaa\x58\x54\x2b" + "\x52\x4b\x02\xcd\x3d\x5d\x5f\x69" + "\x07\xaf\xe7\x1c\x5d\x74\x62\x22" + "\x4a\x3f\x9d\x9e\x53\xe7\xe0\x84" + "\x6d\xcb\xb4\xce", 100); + keccak_done(&c, hash); + if(compare_testvector(hash, 28, + "\x62\xb1\x0f\x1b\x62\x36\xeb\xc2" + "\xda\x72\x95\x77\x42\xa8\xd4\xe4" + "\x8e\x21\x3b\x5f\x89\x34\x60\x4b" + "\xfd\x4d\x2c\x3a", 28, + "KECCAK-224", 3) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; +#endif +} + +int keccak_256_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + hash_state c; + unsigned char hash[MAXBLOCKSIZE]; + + keccak_256_init(&c); + keccak_process(&c, (unsigned char*) "\xcc", 1); + keccak_done(&c, hash); + if(compare_testvector(hash, 32, + "\xee\xad\x6d\xbf\xc7\x34\x0a\x56" + "\xca\xed\xc0\x44\x69\x6a\x16\x88" + "\x70\x54\x9a\x6a\x7f\x6f\x56\x96" + "\x1e\x84\xa5\x4b\xd9\x97\x0b\x8a", 32, + "KECCAK-256", 0) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + keccak_256_init(&c); + keccak_process(&c, (unsigned char*)"\x41\xfb", 2); + keccak_done(&c, hash); + if(compare_testvector(hash, 32, + "\xa8\xea\xce\xda\x4d\x47\xb3\x28" + "\x1a\x79\x5a\xd9\xe1\xea\x21\x22" + "\xb4\x07\xba\xf9\xaa\xbc\xb9\xe1" + "\x8b\x57\x17\xb7\x87\x35\x37\xd2", 32, + "KECCAK-256", 1) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + keccak_256_init(&c); + keccak_process(&c, (unsigned char*) + "\x52\xa6\x08\xab\x21\xcc\xdd\x8a" + "\x44\x57\xa5\x7e\xde\x78\x21\x76", 16); + keccak_done(&c, hash); + if(compare_testvector(hash, 32, + "\x0e\x32\xde\xfa\x20\x71\xf0\xb5" + "\xac\x0e\x6a\x10\x8b\x84\x2e\xd0" + "\xf1\xd3\x24\x97\x12\xf5\x8e\xe0" + "\xdd\xf9\x56\xfe\x33\x2a\x5f\x95", 32, + "KECCAK-256", 2) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + keccak_256_init(&c); + keccak_process(&c, (unsigned char*) + "\x43\x3c\x53\x03\x13\x16\x24\xc0" + "\x02\x1d\x86\x8a\x30\x82\x54\x75" + "\xe8\xd0\xbd\x30\x52\xa0\x22\x18" + "\x03\x98\xf4\xca\x44\x23\xb9\x82" + "\x14\xb6\xbe\xaa\xc2\x1c\x88\x07" + "\xa2\xc3\x3f\x8c\x93\xbd\x42\xb0" + "\x92\xcc\x1b\x06\xce\xdf\x32\x24" + "\xd5\xed\x1e\xc2\x97\x84\x44\x4f" + "\x22\xe0\x8a\x55\xaa\x58\x54\x2b" + "\x52\x4b\x02\xcd\x3d\x5d\x5f\x69" + "\x07\xaf\xe7\x1c\x5d\x74\x62\x22" + "\x4a\x3f\x9d\x9e\x53\xe7\xe0\x84" + "\x6d\xcb\xb4\xce", 100); + keccak_done(&c, hash); + if(compare_testvector(hash, 32, + "\xce\x87\xa5\x17\x3b\xff\xd9\x23" + "\x99\x22\x16\x58\xf8\x01\xd4\x5c" + "\x29\x4d\x90\x06\xee\x9f\x3f\x9d" + "\x41\x9c\x8d\x42\x77\x48\xdc\x41", 32, + "KECCAK-256", 3) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; +#endif +} + +int keccak_384_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + hash_state c; + unsigned char hash[MAXBLOCKSIZE]; + + keccak_384_init(&c); + keccak_process(&c, (unsigned char*) "\xcc", 1); + keccak_done(&c, hash); + if(compare_testvector(hash, 48, + "\x1b\x84\xe6\x2a\x46\xe5\xa2\x01" + "\x86\x17\x54\xaf\x5d\xc9\x5c\x4a" + "\x1a\x69\xca\xf4\xa7\x96\xae\x40" + "\x56\x80\x16\x1e\x29\x57\x26\x41" + "\xf5\xfa\x1e\x86\x41\xd7\x95\x83" + "\x36\xee\x7b\x11\xc5\x8f\x73\xe9", 48, + "KECCAK-384", 0) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + keccak_384_init(&c); + keccak_process(&c, (unsigned char*)"\x41\xfb", 2); + keccak_done(&c, hash); + if(compare_testvector(hash, 48, + "\x49\x5c\xce\x27\x14\xcd\x72\xc8" + "\xc5\x3c\x33\x63\xd2\x2c\x58\xb5" + "\x59\x60\xfe\x26\xbe\x0b\xf3\xbb" + "\xc7\xa3\x31\x6d\xd5\x63\xad\x1d" + "\xb8\x41\x0e\x75\xee\xfe\xa6\x55" + "\xe3\x9d\x46\x70\xec\x0b\x17\x92", 48, + "KECCAK-384", 1) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + keccak_384_init(&c); + keccak_process(&c, (unsigned char*) + "\x52\xa6\x08\xab\x21\xcc\xdd\x8a" + "\x44\x57\xa5\x7e\xde\x78\x21\x76", 16); + keccak_done(&c, hash); + if(compare_testvector(hash, 48, + "\x18\x42\x2a\xc1\xd3\xa1\xe5\x4b" + "\xad\x87\x68\x83\xd2\xd6\xdd\x65" + "\xf6\x5c\x1d\x5f\x33\xa7\x12\x5c" + "\xc4\xc1\x86\x40\x5a\x12\xed\x64" + "\xba\x96\x67\x2e\xed\xda\x8c\x5a" + "\x63\x31\xd2\x86\x83\xf4\x88\xeb", 48, + "KECCAK-384", 2) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + keccak_384_init(&c); + keccak_process(&c, (unsigned char*) + "\x43\x3c\x53\x03\x13\x16\x24\xc0" + "\x02\x1d\x86\x8a\x30\x82\x54\x75" + "\xe8\xd0\xbd\x30\x52\xa0\x22\x18" + "\x03\x98\xf4\xca\x44\x23\xb9\x82" + "\x14\xb6\xbe\xaa\xc2\x1c\x88\x07" + "\xa2\xc3\x3f\x8c\x93\xbd\x42\xb0" + "\x92\xcc\x1b\x06\xce\xdf\x32\x24" + "\xd5\xed\x1e\xc2\x97\x84\x44\x4f" + "\x22\xe0\x8a\x55\xaa\x58\x54\x2b" + "\x52\x4b\x02\xcd\x3d\x5d\x5f\x69" + "\x07\xaf\xe7\x1c\x5d\x74\x62\x22" + "\x4a\x3f\x9d\x9e\x53\xe7\xe0\x84" + "\x6d\xcb\xb4\xce", 100); + keccak_done(&c, hash); + if(compare_testvector(hash, 48, + "\x13\x51\x14\x50\x8d\xd6\x3e\x27" + "\x9e\x70\x9c\x26\xf7\x81\x7c\x04" + "\x82\x76\x6c\xde\x49\x13\x2e\x3e" + "\xdf\x2e\xed\xd8\x99\x6f\x4e\x35" + "\x96\xd1\x84\x10\x0b\x38\x48\x68" + "\x24\x9f\x1d\x8b\x8f\xda\xa2\xc9", 48, + "KECCAK-384", 3) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; +#endif +} + +int keccak_512_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + hash_state c; + unsigned char hash[MAXBLOCKSIZE]; + + keccak_512_init(&c); + keccak_process(&c, (unsigned char*) "\xcc", 1); + keccak_done(&c, hash); + if(compare_testvector(hash, 64, + "\x86\x30\xc1\x3c\xbd\x06\x6e\xa7" + "\x4b\xbe\x7f\xe4\x68\xfe\xc1\xde" + "\xe1\x0e\xdc\x12\x54\xfb\x4c\x1b" + "\x7c\x5f\xd6\x9b\x64\x6e\x44\x16" + "\x0b\x8c\xe0\x1d\x05\xa0\x90\x8c" + "\xa7\x90\xdf\xb0\x80\xf4\xb5\x13" + "\xbc\x3b\x62\x25\xec\xe7\xa8\x10" + "\x37\x14\x41\xa5\xac\x66\x6e\xb9", 64, + "KECCAK-512", 0) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + keccak_512_init(&c); + keccak_process(&c, (unsigned char*)"\x41\xfb", 2); + keccak_done(&c, hash); + if(compare_testvector(hash, 64, + "\x55\x1d\xa6\x23\x6f\x8b\x96\xfc" + "\xe9\xf9\x7f\x11\x90\xe9\x01\x32" + "\x4f\x0b\x45\xe0\x6d\xbb\xb5\xcd" + "\xb8\x35\x5d\x6e\xd1\xdc\x34\xb3" + "\xf0\xea\xe7\xdc\xb6\x86\x22\xff" + "\x23\x2f\xa3\xce\xce\x0d\x46\x16" + "\xcd\xeb\x39\x31\xf9\x38\x03\x66" + "\x2a\x28\xdf\x1c\xd5\x35\xb7\x31", 64, + "KECCAK-512", 1) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + keccak_512_init(&c); + keccak_process(&c, (unsigned char*) + "\x52\xa6\x08\xab\x21\xcc\xdd\x8a" + "\x44\x57\xa5\x7e\xde\x78\x21\x76", 16); + keccak_done(&c, hash); + if(compare_testvector(hash, 64, + "\x4b\x39\xd3\xda\x5b\xcd\xf4\xd9" + "\xb7\x69\x01\x59\x95\x64\x43\x11" + "\xc1\x4c\x43\x5b\xf7\x2b\x10\x09" + "\xd6\xdd\x71\xb0\x1a\x63\xb9\x7c" + "\xfb\x59\x64\x18\xe8\xe4\x23\x42" + "\xd1\x17\xe0\x74\x71\xa8\x91\x43" + "\x14\xba\x7b\x0e\x26\x4d\xad\xf0" + "\xce\xa3\x81\x86\x8c\xbd\x43\xd1", 64, + "KECCAK-512", 2) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + keccak_512_init(&c); + keccak_process(&c, (unsigned char*) + "\x43\x3c\x53\x03\x13\x16\x24\xc0" + "\x02\x1d\x86\x8a\x30\x82\x54\x75" + "\xe8\xd0\xbd\x30\x52\xa0\x22\x18" + "\x03\x98\xf4\xca\x44\x23\xb9\x82" + "\x14\xb6\xbe\xaa\xc2\x1c\x88\x07" + "\xa2\xc3\x3f\x8c\x93\xbd\x42\xb0" + "\x92\xcc\x1b\x06\xce\xdf\x32\x24" + "\xd5\xed\x1e\xc2\x97\x84\x44\x4f" + "\x22\xe0\x8a\x55\xaa\x58\x54\x2b" + "\x52\x4b\x02\xcd\x3d\x5d\x5f\x69" + "\x07\xaf\xe7\x1c\x5d\x74\x62\x22" + "\x4a\x3f\x9d\x9e\x53\xe7\xe0\x84" + "\x6d\xcb\xb4\xce", 100); + keccak_done(&c, hash); + if(compare_testvector(hash, 64, + "\x52\x7d\x28\xe3\x41\xe6\xb1\x4f" + "\x46\x84\xad\xb4\xb8\x24\xc4\x96" + "\xc6\x48\x2e\x51\x14\x95\x65\xd3" + "\xd1\x72\x26\x82\x88\x84\x30\x6b" + "\x51\xd6\x14\x8a\x72\x62\x2c\x2b" + "\x75\xf5\xd3\x51\x0b\x79\x9d\x8b" + "\xdc\x03\xea\xed\xe4\x53\x67\x6a" + "\x6e\xc8\xfe\x03\xa1\xad\x0e\xab", 64, + "KECCAK-512", 3) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; +#endif +} + +#endif + /* ref: $Format:%D$ */ /* git commit: $Format:%H$ */ /* commit time: $Format:%ai$ */ diff --git a/src/ltc/headers/tomcrypt.h b/src/ltc/headers/tomcrypt.h index 9ed77509..1aca366e 100644 --- a/src/ltc/headers/tomcrypt.h +++ b/src/ltc/headers/tomcrypt.h @@ -27,13 +27,13 @@ extern "C" { /* version */ #define CRYPT 0x0118 -#define SCRYPT "1.18.0" +#define SCRYPT "1.18.1-develop" /* max size of either a cipher/hash block or symmetric key [largest of the two] */ #define MAXBLOCKSIZE 144 /* descriptor table size */ -#define TAB_SIZE 32 +#define TAB_SIZE 34 /* error codes [will be expanded in future releases] */ enum { @@ -67,7 +67,7 @@ enum { CRYPT_OVERFLOW, /* An overflow of a value was detected/prevented */ - CRYPT_UNUSED1, /* UNUSED1 */ + CRYPT_PK_ASN1_ERROR, /* An error occurred while en- or decoding ASN.1 data */ CRYPT_INPUT_TOO_LONG, /* The input was longer than expected. */ diff --git a/src/ltc/headers/tomcrypt_custom.h b/src/ltc/headers/tomcrypt_custom.h index 5a218ff3..c4af2165 100644 --- a/src/ltc/headers/tomcrypt_custom.h +++ b/src/ltc/headers/tomcrypt_custom.h @@ -248,6 +248,7 @@ #define LTC_CHC_HASH #define LTC_WHIRLPOOL #define LTC_SHA3 +#define LTC_KECCAK #define LTC_SHA512 #define LTC_SHA512_256 #define LTC_SHA512_224 @@ -468,32 +469,39 @@ #ifdef LTC_MECC /* Supported ECC Key Sizes */ #ifndef LTC_NO_CURVES + #define LTC_ECC_BRAINPOOLP160R1 + #define LTC_ECC_BRAINPOOLP160T1 + #define LTC_ECC_BRAINPOOLP192R1 + #define LTC_ECC_BRAINPOOLP192T1 + #define LTC_ECC_BRAINPOOLP224R1 + #define LTC_ECC_BRAINPOOLP224T1 + #define LTC_ECC_BRAINPOOLP256R1 + #define LTC_ECC_BRAINPOOLP256T1 + #define LTC_ECC_BRAINPOOLP320R1 + #define LTC_ECC_BRAINPOOLP320T1 + #define LTC_ECC_BRAINPOOLP384R1 + #define LTC_ECC_BRAINPOOLP384T1 + #define LTC_ECC_BRAINPOOLP512R1 + #define LTC_ECC_BRAINPOOLP512T1 + #define LTC_ECC_PRIME192V2 + #define LTC_ECC_PRIME192V3 + #define LTC_ECC_PRIME239V1 + #define LTC_ECC_PRIME239V2 + #define LTC_ECC_PRIME239V3 #define LTC_ECC_SECP112R1 #define LTC_ECC_SECP112R2 #define LTC_ECC_SECP128R1 #define LTC_ECC_SECP128R2 + #define LTC_ECC_SECP160K1 #define LTC_ECC_SECP160R1 #define LTC_ECC_SECP160R2 - #define LTC_ECC_SECP160K1 - #define LTC_ECC_BRAINPOOLP160R1 - #define LTC_ECC_SECP192R1 - #define LTC_ECC_PRIME192V2 - #define LTC_ECC_PRIME192V3 #define LTC_ECC_SECP192K1 - #define LTC_ECC_BRAINPOOLP192R1 - #define LTC_ECC_SECP224R1 + #define LTC_ECC_SECP192R1 #define LTC_ECC_SECP224K1 - #define LTC_ECC_BRAINPOOLP224R1 - #define LTC_ECC_PRIME239V1 - #define LTC_ECC_PRIME239V2 - #define LTC_ECC_PRIME239V3 - #define LTC_ECC_SECP256R1 + #define LTC_ECC_SECP224R1 #define LTC_ECC_SECP256K1 - #define LTC_ECC_BRAINPOOLP256R1 - #define LTC_ECC_BRAINPOOLP320R1 + #define LTC_ECC_SECP256R1 #define LTC_ECC_SECP384R1 - #define LTC_ECC_BRAINPOOLP384R1 - #define LTC_ECC_BRAINPOOLP512R1 #define LTC_ECC_SECP521R1 /* OLD deprecated (but still working) defines */ #define LTC_ECC112 diff --git a/src/ltc/headers/tomcrypt_hash.h b/src/ltc/headers/tomcrypt_hash.h index ef494f72..134085d7 100644 --- a/src/ltc/headers/tomcrypt_hash.h +++ b/src/ltc/headers/tomcrypt_hash.h @@ -8,7 +8,7 @@ */ /* ---- HASH FUNCTIONS ---- */ -#ifdef LTC_SHA3 +#if defined(LTC_SHA3) || defined(LTC_KECCAK) struct sha3_state { ulong64 saved; /* the portion of the input message that we didn't consume yet */ ulong64 s[25]; @@ -155,7 +155,7 @@ typedef union Hash_state { #ifdef LTC_WHIRLPOOL struct whirlpool_state whirlpool; #endif -#ifdef LTC_SHA3 +#if defined(LTC_SHA3) || defined(LTC_KECCAK) struct sha3_state sha3; #endif #ifdef LTC_SHA512 @@ -263,21 +263,25 @@ int whirlpool_test(void); extern const struct ltc_hash_descriptor whirlpool_desc; #endif -#ifdef LTC_SHA3 +#if defined(LTC_SHA3) || defined(LTC_KECCAK) +/* sha3_NNN_init are shared by SHA3 and KECCAK */ int sha3_512_init(hash_state * md); +int sha3_384_init(hash_state * md); +int sha3_256_init(hash_state * md); +int sha3_224_init(hash_state * md); +/* sha3_process is the same for all variants of SHA3 + KECCAK */ +int sha3_process(hash_state * md, const unsigned char *in, unsigned long inlen); +#endif + +#ifdef LTC_SHA3 int sha3_512_test(void); extern const struct ltc_hash_descriptor sha3_512_desc; -int sha3_384_init(hash_state * md); int sha3_384_test(void); extern const struct ltc_hash_descriptor sha3_384_desc; -int sha3_256_init(hash_state * md); int sha3_256_test(void); extern const struct ltc_hash_descriptor sha3_256_desc; -int sha3_224_init(hash_state * md); int sha3_224_test(void); extern const struct ltc_hash_descriptor sha3_224_desc; -/* process + done are the same for all variants */ -int sha3_process(hash_state * md, const unsigned char *in, unsigned long inlen); int sha3_done(hash_state *md, unsigned char *hash); /* SHAKE128 + SHAKE256 */ int sha3_shake_init(hash_state *md, int num); @@ -287,6 +291,23 @@ int sha3_shake_test(void); int sha3_shake_memory(int num, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); #endif +#ifdef LTC_KECCAK +#define keccak_512_init(a) sha3_512_init(a) +#define keccak_384_init(a) sha3_384_init(a) +#define keccak_256_init(a) sha3_256_init(a) +#define keccak_224_init(a) sha3_224_init(a) +#define keccak_process(a,b,c) sha3_process(a,b,c) +extern const struct ltc_hash_descriptor keccak_512_desc; +int keccak_512_test(void); +extern const struct ltc_hash_descriptor keccak_384_desc; +int keccak_384_test(void); +extern const struct ltc_hash_descriptor keccak_256_desc; +int keccak_256_test(void); +extern const struct ltc_hash_descriptor keccak_224_desc; +int keccak_224_test(void); +int keccak_done(hash_state *md, unsigned char *hash); +#endif + #ifdef LTC_SHA512 int sha512_init(hash_state * md); int sha512_process(hash_state * md, const unsigned char *in, unsigned long inlen); diff --git a/src/ltc/headers/tomcrypt_math.h b/src/ltc/headers/tomcrypt_math.h index d73bb91d..f0e9699f 100644 --- a/src/ltc/headers/tomcrypt_math.h +++ b/src/ltc/headers/tomcrypt_math.h @@ -374,48 +374,48 @@ typedef struct { @param k The integer to multiply the point by @param G The point to multiply @param R The destination for kG - @param a ECC curve parameter a (if NULL we assume a == -3) + @param a ECC curve parameter a @param modulus The modulus for the field @param map Boolean indicated whether to map back to affine or not (can be ignored if you work in affine only) @return CRYPT_OK on success */ int (*ecc_ptmul)( void *k, - ecc_point *G, - ecc_point *R, - void *a, - void *modulus, - int map); + const ecc_point *G, + ecc_point *R, + void *a, + void *modulus, + int map); /** ECC GF(p) point addition @param P The first point @param Q The second point @param R The destination of P + Q - @param a ECC curve parameter a (if NULL we assume a == -3) + @param ma The curve parameter "a" in montgomery form @param modulus The modulus @param mp The "b" value from montgomery_setup() @return CRYPT_OK on success */ - int (*ecc_ptadd)(ecc_point *P, - ecc_point *Q, - ecc_point *R, - void *a, - void *modulus, - void *mp); + int (*ecc_ptadd)(const ecc_point *P, + const ecc_point *Q, + ecc_point *R, + void *ma, + void *modulus, + void *mp); /** ECC GF(p) point double @param P The first point @param R The destination of 2P - @param a ECC curve parameter a (if NULL we assume a == -3) + @param ma The curve parameter "a" in montgomery form @param modulus The modulus @param mp The "b" value from montgomery_setup() @return CRYPT_OK on success */ - int (*ecc_ptdbl)(ecc_point *P, - ecc_point *R, - void *a, - void *modulus, - void *mp); + int (*ecc_ptdbl)(const ecc_point *P, + ecc_point *R, + void *ma, + void *modulus, + void *mp); /** ECC mapping from projective to affine, currently uses (x,y,z) => (x/z^2, y/z^3, 1) @@ -435,14 +435,15 @@ typedef struct { @param B Second point to multiply @param kB What to multiple B by @param C [out] Destination point (can overlap with A or B) + @param ma The curve parameter "a" in montgomery form @param modulus Modulus for curve @return CRYPT_OK on success */ - int (*ecc_mul2add)(ecc_point *A, void *kA, - ecc_point *B, void *kB, - ecc_point *C, - void *a, - void *modulus); + int (*ecc_mul2add)(const ecc_point *A, void *kA, + const ecc_point *B, void *kB, + ecc_point *C, + void *ma, + void *modulus); /* ---- (optional) rsa optimized math (for internal CRT) ---- */ diff --git a/src/ltc/headers/tomcrypt_pk.h b/src/ltc/headers/tomcrypt_pk.h index d12308c0..ac4353ca 100644 --- a/src/ltc/headers/tomcrypt_pk.h +++ b/src/ltc/headers/tomcrypt_pk.h @@ -32,17 +32,17 @@ enum public_key_algorithms { PKA_RSA, PKA_DSA, PKA_EC, - EC_PRIME_FIELD + PKA_EC_PRIMEF }; -#endif /* LTC_SOURCE */ typedef struct Oid { unsigned long OID[16]; - /** Length of DER encoding */ + /** Number of OID digits in use */ unsigned long OIDlen; } oid_st; int pk_get_oid(int pk, oid_st *st); +#endif /* LTC_SOURCE */ /* ---- RSA ---- */ #ifdef LTC_MRSA @@ -254,37 +254,35 @@ int dh_check_pubkey(dh_key *key); /* max private key size */ #define ECC_MAXSIZE 66 -/** Structure defines a NIST GF(p) curve */ +/** Structure defines a GF(p) curve */ typedef struct { - /** The size of the curve in octets */ - int size; - /** name of curve */ - char *name; + const char *name; /** The prime that defines the field the curve is in (encoded in hex) */ - char *prime; + const char *prime; /** The fields A param (hex) */ - char *A; + const char *A; /** The fields B param (hex) */ - char *B; + const char *B; /** The order of the curve (hex) */ - char *order; + const char *order; /** The x co-ordinate of the base point on the curve (hex) */ - char *Gx; + const char *Gx; /** The y co-ordinate of the base point on the curve (hex) */ - char *Gy; + const char *Gy; /** The co-factor */ unsigned long cofactor; - /** The OID stucture */ - oid_st oid; + /** The OID */ + unsigned long oid[16]; + unsigned long oidlen; } ltc_ecc_set_type; /** 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 */ @@ -299,18 +297,36 @@ typedef struct { void *z; } ecc_point; +/** ECC key's domain parameters */ +typedef struct { + /** The size of the curve in octets */ + int size; + /** The prime that defines the field the curve is in */ + void *prime; + /** The fields A param */ + void *A; + /** The fields B param */ + void *B; + /** The order of the curve */ + void *order; + /** The base point G on the curve */ + ecc_point base; + /** The co-factor */ + unsigned long cofactor; + /** The OID */ + unsigned long oid[16]; + unsigned long oidlen; +} ltc_ecc_dp; + /** An ECC key */ typedef struct { /** Type of key, PK_PRIVATE or PK_PUBLIC */ int type; - /** Index into the ltc_ecc_sets[] for the parameters of this curve; if -1, then this key is using user supplied curve in dp */ - int idx; + /** Structure with domain parameters */ + ltc_ecc_dp dp; - /** pointer to domain parameters; either points to NIST curves (identified by idx >= 0) or user supplied curve */ - const ltc_ecc_set_type *dp; - - /** The public key */ + /** Structure with the public key */ ecc_point pubkey; /** The private key */ @@ -324,12 +340,11 @@ int ecc_test(void); void ecc_sizes(int *low, int *high); int ecc_get_size(ecc_key *key); -int ecc_dp_init(ltc_ecc_set_type *dp); -int ecc_dp_set(ltc_ecc_set_type *dp, char *ch_prime, char *ch_A, char *ch_B, char *ch_order, char *ch_Gx, char *ch_Gy, unsigned long cofactor, char *ch_name, char *oid); -int ecc_dp_set_bn(ltc_ecc_set_type *dp, void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor); -int ecc_dp_set_by_oid(ltc_ecc_set_type *dp, unsigned long *oid, unsigned long oidsize); -int ecc_dp_fill_from_sets(ltc_ecc_set_type *dp); -int ecc_dp_clear(ltc_ecc_set_type *dp); +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_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); @@ -338,15 +353,15 @@ 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_pkcs8(const unsigned char *in, unsigned long inlen, const void *pwd, unsigned long pwdlen, ecc_key *key, ltc_ecc_set_type *dp); -int ecc_export_full(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); -int ecc_import_full(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp); -int ecc_export_raw(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); -int ecc_import_raw(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp); 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, ltc_ecc_set_type *dp); +int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp); + +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); +int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen, const void *pwd, unsigned long pwdlen, ecc_key *key); +int ecc_import_x509(const unsigned char *in, unsigned long inlen, ecc_key *key); int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, unsigned char *out, unsigned long *outlen); @@ -376,24 +391,31 @@ int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int *stat, ecc_key *key); -int ecc_verify_key(ecc_key *key); + +#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); /* low level functions */ ecc_point *ltc_ecc_new_point(void); void ltc_ecc_del_point(ecc_point *p); -int ltc_ecc_is_valid_idx(int n); -int ltc_ecc_is_point(const ltc_ecc_set_type *dp, void *x, void *y); -int ltc_ecc_is_point_at_infinity(ecc_point *p, void *modulus); +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_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); /* point ops (mp == montgomery digit) */ #if !defined(LTC_MECC_ACCEL) || defined(LTM_DESC) || defined(GMP_DESC) /* R = 2P */ -int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *a, void *modulus, void *mp); +int ltc_ecc_projective_dbl_point(const ecc_point *P, ecc_point *R, void *ma, void *modulus, void *mp); /* R = P + Q */ -int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *a, void *modulus, void *mp); +int ltc_ecc_projective_add_point(const ecc_point *P, const ecc_point *Q, ecc_point *R, void *ma, void *modulus, void *mp); #endif #if defined(LTC_MECC_FP) @@ -411,23 +433,23 @@ void ltc_ecc_fp_tablelock(int lock); #endif /* R = kG */ -int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map); +int ltc_ecc_mulmod(void *k, const ecc_point *G, ecc_point *R, void *a, void *modulus, int map); #ifdef LTC_ECC_SHAMIR /* kA*A + kB*B = C */ -int ltc_ecc_mul2add(ecc_point *A, void *kA, - ecc_point *B, void *kB, - ecc_point *C, - void *a, - void *modulus); +int ltc_ecc_mul2add(const ecc_point *A, void *kA, + const ecc_point *B, void *kB, + ecc_point *C, + void *ma, + void *modulus); #ifdef LTC_MECC_FP /* Shamir's trick with optimized point multiplication using fixed point cache */ -int ltc_ecc_fp_mul2add(ecc_point *A, void *kA, - ecc_point *B, void *kB, - ecc_point *C, - void *a, - void *modulus); +int ltc_ecc_fp_mul2add(const ecc_point *A, void *kA, + const ecc_point *B, void *kB, + ecc_point *C, + void *ma, + void *modulus); #endif #endif @@ -436,6 +458,8 @@ int ltc_ecc_fp_mul2add(ecc_point *A, void *kA, /* map P to affine from projective */ int ltc_ecc_map(ecc_point *P, void *modulus, void *mp); +#endif /* LTC_SOURCE */ + #endif #ifdef LTC_MDSA @@ -549,12 +573,22 @@ typedef enum ltc_asn1_type_ { LTC_ASN1_SETOF, LTC_ASN1_RAW_BIT_STRING, LTC_ASN1_TELETEX_STRING, - LTC_ASN1_CONSTRUCTED, - LTC_ASN1_CONTEXT_SPECIFIC, - /* 20 */ LTC_ASN1_GENERALIZEDTIME, + LTC_ASN1_CUSTOM_TYPE, } ltc_asn1_type; +typedef enum { + LTC_ASN1_CL_UNIVERSAL = 0x0, + LTC_ASN1_CL_APPLICATION = 0x1, + LTC_ASN1_CL_CONTEXT_SPECIFIC = 0x2, + LTC_ASN1_CL_PRIVATE = 0x3, +} ltc_asn1_class; + +typedef enum { + LTC_ASN1_PC_PRIMITIVE = 0x0, + LTC_ASN1_PC_CONSTRUCTED = 0x1, +} ltc_asn1_pc; + /** A LTC ASN.1 list type */ typedef struct ltc_asn1_list_ { /** The LTC ASN.1 enumerated type identifier */ @@ -563,12 +597,17 @@ typedef struct ltc_asn1_list_ { void *data; /** The size of the input or resulting output */ unsigned long size; - /** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */ + /** The used flag + * 1. This is used by the CHOICE ASN.1 type to indicate which choice was made + * 2. This is used by the ASN.1 decoder to indicate if an element is used + * 3. This is used by the flexi-decoder to indicate the first byte of the identifier */ int used; /** Flag used to indicate optional items in ASN.1 sequences */ int optional; - /** Flag used to indicate context specific tags on ASN.1 sequence items */ - unsigned char tag; + /** ASN.1 identifier */ + ltc_asn1_class class; + ltc_asn1_pc pc; + ulong64 tag; /** prev/next entry in the list */ struct ltc_asn1_list_ *prev, *next, *child, *parent; } ltc_asn1_list; @@ -581,46 +620,120 @@ typedef struct ltc_asn1_list_ { LTC_MACRO_list[LTC_MACRO_temp].data = (void*)(Data); \ LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \ LTC_MACRO_list[LTC_MACRO_temp].used = 0; \ - LTC_MACRO_list[LTC_MACRO_temp].tag = 0; \ LTC_MACRO_list[LTC_MACRO_temp].optional = 0; \ + LTC_MACRO_list[LTC_MACRO_temp].class = 0; \ + LTC_MACRO_list[LTC_MACRO_temp].pc = 0; \ + LTC_MACRO_list[LTC_MACRO_temp].tag = 0; \ + } while (0) + +#define __LTC_SET_ASN1_IDENTIFIER(list, index, Class, Pc, Tag) \ + do { \ + int LTC_MACRO_temp = (index); \ + ltc_asn1_list *LTC_MACRO_list = (list); \ + LTC_MACRO_list[LTC_MACRO_temp].type = LTC_ASN1_CUSTOM_TYPE; \ + LTC_MACRO_list[LTC_MACRO_temp].class = (Class); \ + LTC_MACRO_list[LTC_MACRO_temp].pc = (Pc); \ + LTC_MACRO_list[LTC_MACRO_temp].tag = (Tag); \ + } while (0) + +#define LTC_SET_ASN1_CUSTOM_CONSTRUCTED(list, index, Class, Tag, Data) \ + do { \ + int LTC_MACRO_temp##__LINE__ = (index); \ + LTC_SET_ASN1(list, LTC_MACRO_temp##__LINE__, LTC_ASN1_CUSTOM_TYPE, Data, 1); \ + __LTC_SET_ASN1_IDENTIFIER(list, LTC_MACRO_temp##__LINE__, Class, LTC_ASN1_PC_CONSTRUCTED, Tag); \ + } while (0) + +#define LTC_SET_ASN1_CUSTOM_PRIMITIVE(list, index, Class, Tag, Type, Data, Size) \ + do { \ + int LTC_MACRO_temp##__LINE__ = (index); \ + LTC_SET_ASN1(list, LTC_MACRO_temp##__LINE__, LTC_ASN1_CUSTOM_TYPE, Data, Size); \ + __LTC_SET_ASN1_IDENTIFIER(list, LTC_MACRO_temp##__LINE__, Class, LTC_ASN1_PC_PRIMITIVE, Tag); \ + list[LTC_MACRO_temp##__LINE__].used = (int)(Type); \ } while (0) +extern const char* der_asn1_class_to_string_map[]; +extern const unsigned long der_asn1_class_to_string_map_sz; + +extern const char* der_asn1_pc_to_string_map[]; +extern const unsigned long der_asn1_pc_to_string_map_sz; + +extern const char* der_asn1_tag_to_string_map[]; +extern const unsigned long der_asn1_tag_to_string_map_sz; + /* SEQUENCE */ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, unsigned char *out, unsigned long *outlen, int type_of); #define der_encode_sequence(list, inlen, out, outlen) der_encode_sequence_ex(list, inlen, out, outlen, LTC_ASN1_SEQUENCE) +/** The supported bitmap for all the + * decoders with a `flags` argument. + */ +enum ltc_der_seq { + LTC_DER_SEQ_ZERO = 0x0u, + + /** Bit0 - [0]=Unordered (SET or SETOF) + * [1]=Ordered (SEQUENCE) */ + LTC_DER_SEQ_UNORDERED = LTC_DER_SEQ_ZERO, + LTC_DER_SEQ_ORDERED = 0x1u, + + /** Bit1 - [0]=Relaxed + * [1]=Strict */ + LTC_DER_SEQ_RELAXED = LTC_DER_SEQ_ZERO, + LTC_DER_SEQ_STRICT = 0x2u, + + /** Alternative naming */ + LTC_DER_SEQ_SET = LTC_DER_SEQ_UNORDERED, + LTC_DER_SEQ_SEQUENCE = LTC_DER_SEQ_ORDERED, +}; + int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, - ltc_asn1_list *list, unsigned long outlen, int ordered); + ltc_asn1_list *list, unsigned long outlen, unsigned int flags); -#define der_decode_sequence(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 1) +#define der_decode_sequence(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, LTC_DER_SEQ_SEQUENCE | LTC_DER_SEQ_RELAXED) +#define der_decode_sequence_strict(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, LTC_DER_SEQ_SEQUENCE | LTC_DER_SEQ_STRICT) int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, unsigned long *outlen); +/* Custom-types */ +int der_encode_custom_type(const ltc_asn1_list *root, + unsigned char *out, unsigned long *outlen); + +int der_decode_custom_type(const unsigned char *in, unsigned long inlen, + ltc_asn1_list *root); + +int der_length_custom_type(const ltc_asn1_list *root, + unsigned long *outlen, + unsigned long *payloadlen); + #ifdef LTC_SOURCE /* internal helper functions */ +int der_decode_custom_type_ex(const unsigned char *in, unsigned long inlen, + ltc_asn1_list *root, + ltc_asn1_list *list, unsigned long outlen, unsigned int flags); + +int der_encode_asn1_identifier(const ltc_asn1_list *id, unsigned char *out, unsigned long *outlen); +int der_decode_asn1_identifier(const unsigned char *in, unsigned long *inlen, ltc_asn1_list *id); +int der_length_asn1_identifier(const ltc_asn1_list *id, unsigned long *idlen); + +int der_encode_asn1_length(unsigned long len, unsigned char* out, unsigned long* outlen); +int der_decode_asn1_length(const unsigned char* len, unsigned long* lenlen, unsigned long* outlen); +int der_length_asn1_length(unsigned long len, unsigned long *outlen); + int der_length_sequence_ex(ltc_asn1_list *list, unsigned long inlen, unsigned long *outlen, unsigned long *payloadlen); -/* SUBJECT PUBLIC KEY INFO */ -int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen, - unsigned int algorithm, void* public_key, unsigned long public_key_len, - unsigned long parameters_type, void* parameters, unsigned long parameters_len); -int der_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen, - unsigned int algorithm, void* public_key, unsigned long* public_key_len, - unsigned long parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len); +extern const ltc_asn1_type der_asn1_tag_to_type_map[]; +extern const unsigned long der_asn1_tag_to_type_map_sz; -int der_decode_subject_public_key_info_ex(const unsigned char *in, unsigned long inlen, - unsigned int algorithm, void* public_key, unsigned long* public_key_len, - unsigned long parameters_type, void* parameters, unsigned long parameters_len, - unsigned long *parameters_outsize); +extern const int der_asn1_type_to_identifier_map[]; +extern const unsigned long der_asn1_type_to_identifier_map_sz; #endif /* LTC_SOURCE */ /* SET */ -#define der_decode_set(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 0) +#define der_decode_set(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, LTC_DER_SEQ_SET) #define der_length_set der_length_sequence int der_encode_set(ltc_asn1_list *list, unsigned long inlen, unsigned char *out, unsigned long *outlen); @@ -631,6 +744,10 @@ int der_encode_setof(ltc_asn1_list *list, unsigned long inlen, /* VA list handy helpers with triplets of <type, size, data> */ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...); int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...); +#ifdef LTC_SOURCE +/* internal helper functions */ +int der_decode_sequence_multi_ex(const unsigned char *in, unsigned long inlen, unsigned int flags, ...); +#endif /* LTC_SOURCE */ /* FLEXI DECODER handle unknown list decoder */ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out); @@ -786,6 +903,17 @@ int der_decode_generalizedtime(const unsigned char *in, unsigned long *inlen, int der_length_generalizedtime(ltc_generalizedtime *gtime, unsigned long *outlen); +#ifdef LTC_SOURCE +/* internal helper functions */ +/* SUBJECT PUBLIC KEY INFO */ +int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen, + unsigned int algorithm, void* public_key, unsigned long public_key_len, + unsigned long parameters_type, void* parameters, unsigned long parameters_len); + +int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen, + unsigned int algorithm, void* public_key, unsigned long* public_key_len, + unsigned long parameters_type, void* parameters, unsigned long *parameters_len); +#endif /* LTC_SOURCE */ #endif diff --git a/src/ltc/mac/blake2/blake2bmac_file.c b/src/ltc/mac/blake2/blake2bmac_file.c index 64c9e4d1..c1e9c6b5 100644 --- a/src/ltc/mac/blake2/blake2bmac_file.c +++ b/src/ltc/mac/blake2/blake2bmac_file.c @@ -23,6 +23,11 @@ int blake2bmac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen) { #ifdef LTC_NO_FILE + LTC_UNUSED_PARAM(fname); + LTC_UNUSED_PARAM(key); + LTC_UNUSED_PARAM(keylen); + LTC_UNUSED_PARAM(mac); + LTC_UNUSED_PARAM(maclen); return CRYPT_NOP; #else blake2bmac_state st; diff --git a/src/ltc/mac/blake2/blake2smac_file.c b/src/ltc/mac/blake2/blake2smac_file.c index c5248a29..1ac66797 100644 --- a/src/ltc/mac/blake2/blake2smac_file.c +++ b/src/ltc/mac/blake2/blake2smac_file.c @@ -23,6 +23,11 @@ int blake2smac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen) { #ifdef LTC_NO_FILE + LTC_UNUSED_PARAM(fname); + LTC_UNUSED_PARAM(key); + LTC_UNUSED_PARAM(keylen); + LTC_UNUSED_PARAM(mac); + LTC_UNUSED_PARAM(maclen); return CRYPT_NOP; #else blake2smac_state st; diff --git a/src/ltc/mac/f9/f9_file.c b/src/ltc/mac/f9/f9_file.c index a6e6532c..04d509bf 100644 --- a/src/ltc/mac/f9/f9_file.c +++ b/src/ltc/mac/f9/f9_file.c @@ -31,6 +31,12 @@ int f9_file(int cipher, unsigned char *out, unsigned long *outlen) { #ifdef LTC_NO_FILE + LTC_UNUSED_PARAM(cipher); + LTC_UNUSED_PARAM(key); + LTC_UNUSED_PARAM(keylen); + LTC_UNUSED_PARAM(fname); + LTC_UNUSED_PARAM(out); + LTC_UNUSED_PARAM(outlen); return CRYPT_NOP; #else size_t x; diff --git a/src/ltc/mac/hmac/hmac_file.c b/src/ltc/mac/hmac/hmac_file.c index 2d10e21c..0e1a1631 100644 --- a/src/ltc/mac/hmac/hmac_file.c +++ b/src/ltc/mac/hmac/hmac_file.c @@ -30,6 +30,12 @@ int hmac_file(int hash, const char *fname, unsigned char *out, unsigned long *outlen) { #ifdef LTC_NO_FILE + LTC_UNUSED_PARAM(hash); + LTC_UNUSED_PARAM(fname); + LTC_UNUSED_PARAM(key); + LTC_UNUSED_PARAM(keylen); + LTC_UNUSED_PARAM(out); + LTC_UNUSED_PARAM(outlen); return CRYPT_NOP; #else hmac_state hmac; diff --git a/src/ltc/mac/omac/omac_file.c b/src/ltc/mac/omac/omac_file.c index a9104e8e..3f6a85d0 100644 --- a/src/ltc/mac/omac/omac_file.c +++ b/src/ltc/mac/omac/omac_file.c @@ -31,6 +31,12 @@ int omac_file(int cipher, unsigned char *out, unsigned long *outlen) { #ifdef LTC_NO_FILE + LTC_UNUSED_PARAM(cipher); + LTC_UNUSED_PARAM(key); + LTC_UNUSED_PARAM(keylen); + LTC_UNUSED_PARAM(filename); + LTC_UNUSED_PARAM(out); + LTC_UNUSED_PARAM(outlen); return CRYPT_NOP; #else size_t x; diff --git a/src/ltc/mac/pmac/pmac_file.c b/src/ltc/mac/pmac/pmac_file.c index abe04f1e..fe202a2f 100644 --- a/src/ltc/mac/pmac/pmac_file.c +++ b/src/ltc/mac/pmac/pmac_file.c @@ -31,6 +31,12 @@ int pmac_file(int cipher, unsigned char *out, unsigned long *outlen) { #ifdef LTC_NO_FILE + LTC_UNUSED_PARAM(cipher); + LTC_UNUSED_PARAM(key); + LTC_UNUSED_PARAM(keylen); + LTC_UNUSED_PARAM(filename); + LTC_UNUSED_PARAM(out); + LTC_UNUSED_PARAM(outlen); return CRYPT_NOP; #else size_t x; diff --git a/src/ltc/mac/poly1305/poly1305_file.c b/src/ltc/mac/poly1305/poly1305_file.c index 77263056..e57437b3 100644 --- a/src/ltc/mac/poly1305/poly1305_file.c +++ b/src/ltc/mac/poly1305/poly1305_file.c @@ -28,6 +28,11 @@ int poly1305_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen) { #ifdef LTC_NO_FILE + LTC_UNUSED_PARAM(fname); + LTC_UNUSED_PARAM(key); + LTC_UNUSED_PARAM(keylen); + LTC_UNUSED_PARAM(mac); + LTC_UNUSED_PARAM(maclen); return CRYPT_NOP; #else poly1305_state st; diff --git a/src/ltc/mac/xcbc/xcbc_file.c b/src/ltc/mac/xcbc/xcbc_file.c index f121cd0e..27eb0dec 100644 --- a/src/ltc/mac/xcbc/xcbc_file.c +++ b/src/ltc/mac/xcbc/xcbc_file.c @@ -31,6 +31,12 @@ int xcbc_file(int cipher, unsigned char *out, unsigned long *outlen) { #ifdef LTC_NO_FILE + LTC_UNUSED_PARAM(cipher); + LTC_UNUSED_PARAM(key); + LTC_UNUSED_PARAM(keylen); + LTC_UNUSED_PARAM(filename); + LTC_UNUSED_PARAM(out); + LTC_UNUSED_PARAM(outlen); return CRYPT_NOP; #else size_t x; diff --git a/src/ltc/math/rand_bn.c b/src/ltc/math/rand_bn.c index a42ba642..aa6539cc 100644 --- a/src/ltc/math/rand_bn.c +++ b/src/ltc/math/rand_bn.c @@ -8,7 +8,7 @@ */ #include "tomcrypt.h" -#ifdef LTC_MDSA +#if defined(LTC_MDSA) || defined(LTC_MECC) /** Generate a random number N with given bitlength (note: MSB can be 0) */ diff --git a/src/ltc/math/tfm_desc.c b/src/ltc/math/tfm_desc.c index 2a5a57d9..9247db65 100644 --- a/src/ltc/math/tfm_desc.c +++ b/src/ltc/math/tfm_desc.c @@ -265,6 +265,16 @@ static int sqr(void *a, void *b) 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; +} + /* div */ static int divide(void *a, void *b, void *c, void *d) { @@ -424,7 +434,7 @@ static int isprime(void *a, int b, int *c) #if defined(LTC_MECC) && defined(LTC_MECC_ACCEL) -static int tfm_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *Mp) +static int tfm_ecc_projective_dbl_point(const ecc_point *P, ecc_point *R, void *ma, void *modulus, void *Mp) { fp_int t1, t2; fp_digit mp; @@ -445,6 +455,14 @@ static int tfm_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulu fp_copy(P->z, R->z); } + if (ltc_ecc_is_point_at_infinity(P, modulus)) { + /* if P is point at infinity >> Result = point at infinity */ + ltc_mp.set_int(R->x, 1); + ltc_mp.set_int(R->y, 1); + ltc_mp.set_int(R->z, 0); + return CRYPT_OK; + } + /* t1 = Z * Z */ fp_sqr(R->z, &t1); fp_montgomery_reduce(&t1, modulus, mp); @@ -457,28 +475,56 @@ static int tfm_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulu fp_sub(R->z, modulus, R->z); } - /* &t2 = X - T1 */ - fp_sub(R->x, &t1, &t2); - if (fp_cmp_d(&t2, 0) == FP_LT) { - fp_add(&t2, modulus, &t2); - } - /* T1 = X + T1 */ - fp_add(&t1, R->x, &t1); - if (fp_cmp(&t1, modulus) != FP_LT) { - fp_sub(&t1, modulus, &t1); - } - /* T2 = T1 * T2 */ - fp_mul(&t1, &t2, &t2); - fp_montgomery_reduce(&t2, modulus, mp); - /* T1 = 2T2 */ - fp_add(&t2, &t2, &t1); - if (fp_cmp(&t1, modulus) != FP_LT) { - fp_sub(&t1, modulus, &t1); - } - /* T1 = T1 + T2 */ - fp_add(&t1, &t2, &t1); - if (fp_cmp(&t1, modulus) != FP_LT) { - fp_sub(&t1, modulus, &t1); + if (ma == NULL) { /* special case for curves with a == -3 (10% faster than general case) */ + /* T2 = X - T1 */ + fp_sub(R->x, &t1, &t2); + if (fp_cmp_d(&t2, 0) == LTC_MP_LT) { + fp_add(&t2, modulus, &t2); + } + /* T1 = X + T1 */ + fp_add(&t1, R->x, &t1); + if (fp_cmp(&t1, modulus) != FP_LT) { + fp_sub(&t1, modulus, &t1); + } + /* T2 = T1 * T2 */ + fp_mul(&t1, &t2, &t2); + fp_montgomery_reduce(&t2, modulus, mp); + /* T1 = 2T2 */ + fp_add(&t2, &t2, &t1); + if (fp_cmp(&t1, modulus) != FP_LT) { + fp_sub(&t1, modulus, &t1); + } + /* T1 = T1 + T2 */ + fp_add(&t1, &t2, &t1); + if (fp_cmp(&t1, modulus) != FP_LT) { + fp_sub(&t1, modulus, &t1); + } + } + else { + /* T2 = T1 * T1 */ + fp_sqr(&t1, &t2); + fp_montgomery_reduce(&t2, modulus, mp); + /* T1 = T2 * a */ + fp_mul(&t2, ma, &t1); + fp_montgomery_reduce(&t1, modulus, mp); + /* T2 = X * X */ + fp_sqr(R->x, &t2); + fp_montgomery_reduce(&t2, modulus, mp); + /* T1 = T1 + T2 */ + fp_add(&t1, &t2, &t1); + if (fp_cmp(&t1, modulus) != FP_LT) { + fp_sub(&t1, modulus, &t1); + } + /* T1 = T1 + T2 */ + fp_add(&t1, &t2, &t1); + if (fp_cmp(&t1, modulus) != FP_LT) { + fp_sub(&t1, modulus, &t1); + } + /* T1 = T1 + T2 */ + fp_add(&t1, &t2, &t1); + if (fp_cmp(&t1, modulus) != FP_LT) { + fp_sub(&t1, modulus, &t1); + } } /* Y = 2Y */ @@ -541,7 +587,7 @@ static int tfm_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulu @param Mp The "b" value from montgomery_setup() @return CRYPT_OK on success */ -static int tfm_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *Mp) +static int tfm_ecc_projective_add_point(const ecc_point *P, const ecc_point *Q, ecc_point *R, void *ma, void *modulus, void *Mp) { fp_int t1, t2, x, y, z; fp_digit mp; @@ -560,12 +606,28 @@ static int tfm_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R fp_init(&y); fp_init(&z); + if (ltc_ecc_is_point_at_infinity(P, modulus)) { + /* P is point at infinity >> Result = Q */ + ltc_mp.copy(Q->x, R->x); + ltc_mp.copy(Q->y, R->y); + ltc_mp.copy(Q->z, R->z); + return CRYPT_OK; + } + + if (ltc_ecc_is_point_at_infinity(Q, modulus)) { + /* Q is point at infinity >> Result = P */ + ltc_mp.copy(P->x, R->x); + ltc_mp.copy(P->y, R->y); + ltc_mp.copy(P->z, R->z); + return CRYPT_OK; + } + /* should we dbl instead? */ fp_sub(modulus, Q->y, &t1); if ( (fp_cmp(P->x, Q->x) == FP_EQ) && (Q->z != NULL && fp_cmp(P->z, Q->z) == FP_EQ) && (fp_cmp(P->y, Q->y) == FP_EQ || fp_cmp(P->y, &t1) == FP_EQ)) { - return tfm_ecc_projective_dbl_point(P, R, modulus, Mp); + return tfm_ecc_projective_dbl_point(P, R, ma, modulus, Mp); } fp_copy(P->x, &x); @@ -741,6 +803,7 @@ const ltc_math_descriptor tfm_desc = { &mul, &muli, &sqr, + &sqrtmod_prime, ÷, &div_2, &modi, diff --git a/src/ltc/misc/crypt/crypt.c b/src/ltc/misc/crypt/crypt.c index bd656325..bd57a0aa 100644 --- a/src/ltc/misc/crypt/crypt.c +++ b/src/ltc/misc/crypt/crypt.c @@ -152,6 +152,9 @@ const char *crypt_build_settings = #if defined(LTC_SHA3) " SHA3\n" #endif +#if defined(LTC_KECCAK) + " KECCAK\n" +#endif #if defined(LTC_SHA512) " SHA-512\n" #endif diff --git a/src/ltc/misc/crypt/crypt_constants.c b/src/ltc/misc/crypt/crypt_constants.c index a7418d5e..9e76322c 100644 --- a/src/ltc/misc/crypt/crypt_constants.c +++ b/src/ltc/misc/crypt/crypt_constants.c @@ -47,7 +47,7 @@ static const crypt_constant _crypt_constants[] = { _C_STRINGIFY(CRYPT_FILE_NOTFOUND), _C_STRINGIFY(CRYPT_PK_INVALID_TYPE), _C_STRINGIFY(CRYPT_OVERFLOW), - _C_STRINGIFY(CRYPT_UNUSED1), + _C_STRINGIFY(CRYPT_PK_ASN1_ERROR), _C_STRINGIFY(CRYPT_INPUT_TOO_LONG), _C_STRINGIFY(CRYPT_PK_INVALID_SIZE), _C_STRINGIFY(CRYPT_INVALID_PRIME_SIZE), @@ -129,9 +129,8 @@ static const crypt_constant _crypt_constants[] = { _C_STRINGIFY(LTC_ASN1_SETOF), _C_STRINGIFY(LTC_ASN1_RAW_BIT_STRING), _C_STRINGIFY(LTC_ASN1_TELETEX_STRING), - _C_STRINGIFY(LTC_ASN1_CONSTRUCTED), - _C_STRINGIFY(LTC_ASN1_CONTEXT_SPECIFIC), _C_STRINGIFY(LTC_ASN1_GENERALIZEDTIME), + _C_STRINGIFY(LTC_ASN1_CUSTOM_TYPE), #endif #ifdef LTC_CTR_MODE diff --git a/src/ltc/misc/crypt/crypt_register_all_hashes.c b/src/ltc/misc/crypt/crypt_register_all_hashes.c index b5293894..585b9b61 100644 --- a/src/ltc/misc/crypt/crypt_register_all_hashes.c +++ b/src/ltc/misc/crypt/crypt_register_all_hashes.c @@ -60,6 +60,12 @@ int register_all_hashes(void) REGISTER_HASH(&sha3_384_desc); REGISTER_HASH(&sha3_512_desc); #endif +#ifdef LTC_KECCAK + REGISTER_HASH(&keccak_224_desc); + REGISTER_HASH(&keccak_256_desc); + REGISTER_HASH(&keccak_384_desc); + REGISTER_HASH(&keccak_512_desc); +#endif #ifdef LTC_RIPEMD128 REGISTER_HASH(&rmd128_desc); #endif diff --git a/src/ltc/misc/error_to_string.c b/src/ltc/misc/error_to_string.c index 707f8359..3d168286 100644 --- a/src/ltc/misc/error_to_string.c +++ b/src/ltc/misc/error_to_string.c @@ -46,7 +46,7 @@ static const char * const err_2_str[] = "An overflow of a value was detected/prevented.", - "UNUSED1.", + "An ASN.1 decoding error occurred.", "The input was longer than expected.", diff --git a/src/ltc/misc/pk_get_oid.c b/src/ltc/misc/pk_get_oid.c index 8ea3e075..003925aa 100644 --- a/src/ltc/misc/pk_get_oid.c +++ b/src/ltc/misc/pk_get_oid.c @@ -45,7 +45,7 @@ int pk_get_oid(int pk, oid_st *st) case PKA_EC: XMEMCPY(st, &ec_oid, sizeof(*st)); break; - case EC_PRIME_FIELD: + case PKA_EC_PRIMEF: XMEMCPY(st, &ec_primef, sizeof(*st)); break; default: diff --git a/src/ltc/modes/ctr/ctr_encrypt.c b/src/ltc/modes/ctr/ctr_encrypt.c index ecc7b01b..7319cf53 100644 --- a/src/ltc/modes/ctr/ctr_encrypt.c +++ b/src/ltc/modes/ctr/ctr_encrypt.c @@ -53,6 +53,8 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s 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; } diff --git a/src/ltc/pk/asn1/der/bit/der_decode_bit_string.c b/src/ltc/pk/asn1/der/bit/der_decode_bit_string.c index 5203fcfd..6f25cd9a 100644 --- a/src/ltc/pk/asn1/der/bit/der_decode_bit_string.c +++ b/src/ltc/pk/asn1/der/bit/der_decode_bit_string.c @@ -28,6 +28,7 @@ int der_decode_bit_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { unsigned long dlen, blen, x, y; + int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); @@ -47,27 +48,13 @@ int der_decode_bit_string(const unsigned char *in, unsigned long inlen, x = 1; /* get the length of the data */ - if (in[x] & 0x80) { - /* long format get number of length bytes */ - y = in[x++] & 0x7F; - - /* invalid if 0 or > 2 */ - if (y == 0 || y > 2) { - return CRYPT_INVALID_PACKET; - } - - /* read the data len */ - dlen = 0; - while (y--) { - dlen = (dlen << 8) | (unsigned long)in[x++]; - } - } else { - /* short format */ - dlen = in[x++] & 0x7F; + y = inlen - 1; + if ((err = der_decode_asn1_length(in + x, &y, &dlen)) != CRYPT_OK) { + return err; } - + x += y; /* is the data len too long or too short? */ - if ((dlen == 0) || (dlen + x > inlen)) { + if ((dlen == 0) || (dlen > (inlen - x))) { return CRYPT_INVALID_PACKET; } diff --git a/src/ltc/pk/asn1/der/bit/der_decode_raw_bit_string.c b/src/ltc/pk/asn1/der/bit/der_decode_raw_bit_string.c index 223899b3..7e7a4608 100644 --- a/src/ltc/pk/asn1/der/bit/der_decode_raw_bit_string.c +++ b/src/ltc/pk/asn1/der/bit/der_decode_raw_bit_string.c @@ -31,6 +31,7 @@ int der_decode_raw_bit_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { unsigned long dlen, blen, x, y; + int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); @@ -50,27 +51,13 @@ int der_decode_raw_bit_string(const unsigned char *in, unsigned long inlen, x = 1; /* get the length of the data */ - if (in[x] & 0x80) { - /* long format get number of length bytes */ - y = in[x++] & 0x7F; - - /* invalid if 0 or > 2 */ - if (y == 0 || y > 2) { - return CRYPT_INVALID_PACKET; - } - - /* read the data len */ - dlen = 0; - while (y--) { - dlen = (dlen << 8) | (unsigned long)in[x++]; - } - } else { - /* short format */ - dlen = in[x++] & 0x7F; + y = inlen - 1; + if ((err = der_decode_asn1_length(in + x, &y, &dlen)) != CRYPT_OK) { + return err; } - + x += y; /* is the data len too long or too short? */ - if ((dlen == 0) || (dlen + x > inlen)) { + if ((dlen == 0) || (dlen > (inlen - x))) { return CRYPT_INVALID_PACKET; } diff --git a/src/ltc/pk/asn1/der/bit/der_encode_bit_string.c b/src/ltc/pk/asn1/der/bit/der_encode_bit_string.c index 2a674790..7b2c6afa 100644 --- a/src/ltc/pk/asn1/der/bit/der_encode_bit_string.c +++ b/src/ltc/pk/asn1/der/bit/der_encode_bit_string.c @@ -50,16 +50,11 @@ int der_encode_bit_string(const unsigned char *in, unsigned long inlen, y = ((inlen + 7) >> 3) + 1; out[x++] = 0x03; - if (y < 128) { - out[x++] = (unsigned char)y; - } else if (y < 256) { - out[x++] = 0x81; - out[x++] = (unsigned char)y; - } else if (y < 65536) { - out[x++] = 0x82; - out[x++] = (unsigned char)((y>>8)&255); - out[x++] = (unsigned char)(y&255); + len = *outlen - x; + if ((err = der_encode_asn1_length(y, out + x, &len)) != CRYPT_OK) { + return err; } + x += len; /* store number of zero padding bits */ out[x++] = (unsigned char)((8 - inlen) & 7); diff --git a/src/ltc/pk/asn1/der/bit/der_encode_raw_bit_string.c b/src/ltc/pk/asn1/der/bit/der_encode_raw_bit_string.c index 4101a1da..e884dabe 100644 --- a/src/ltc/pk/asn1/der/bit/der_encode_raw_bit_string.c +++ b/src/ltc/pk/asn1/der/bit/der_encode_raw_bit_string.c @@ -52,16 +52,11 @@ int der_encode_raw_bit_string(const unsigned char *in, unsigned long inlen, y = ((inlen + 7) >> 3) + 1; out[x++] = 0x03; - if (y < 128) { - out[x++] = (unsigned char)y; - } else if (y < 256) { - out[x++] = 0x81; - out[x++] = (unsigned char)y; - } else if (y < 65536) { - out[x++] = 0x82; - out[x++] = (unsigned char)((y>>8)&255); - out[x++] = (unsigned char)(y&255); + len = *outlen - x; + if ((err = der_encode_asn1_length(y, out + x, &len)) != CRYPT_OK) { + return err; } + x += len; /* store number of zero padding bits */ out[x++] = (unsigned char)((8 - inlen) & 7); diff --git a/src/ltc/pk/asn1/der/bit/der_length_bit_string.c b/src/ltc/pk/asn1/der/bit/der_length_bit_string.c index b9c99fb1..7a652084 100644 --- a/src/ltc/pk/asn1/der/bit/der_length_bit_string.c +++ b/src/ltc/pk/asn1/der/bit/der_length_bit_string.c @@ -22,24 +22,18 @@ */ int der_length_bit_string(unsigned long nbits, unsigned long *outlen) { - unsigned long nbytes; + unsigned long nbytes, x; + int err; + LTC_ARGCHK(outlen != NULL); /* get the number of the bytes */ nbytes = (nbits >> 3) + ((nbits & 7) ? 1 : 0) + 1; - if (nbytes < 128) { - /* 03 LL PP DD DD DD ... */ - *outlen = 2 + nbytes; - } else if (nbytes < 256) { - /* 03 81 LL PP DD DD DD ... */ - *outlen = 3 + nbytes; - } else if (nbytes < 65536) { - /* 03 82 LL LL PP DD DD DD ... */ - *outlen = 4 + nbytes; - } else { - return CRYPT_INVALID_ARG; + if ((err = der_length_asn1_length(nbytes, &x)) != CRYPT_OK) { + return err; } + *outlen = 1 + x + nbytes; return CRYPT_OK; } diff --git a/src/ltc/pk/asn1/der/choice/der_decode_choice.c b/src/ltc/pk/asn1/der/choice/der_decode_choice.c index 0bfd3bb6..6e17a4b7 100644 --- a/src/ltc/pk/asn1/der/choice/der_decode_choice.c +++ b/src/ltc/pk/asn1/der/choice/der_decode_choice.c @@ -205,9 +205,17 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen, } break; + case LTC_ASN1_CUSTOM_TYPE: + if (der_decode_custom_type(in, *inlen, &list[x]) == CRYPT_OK) { + if (der_length_custom_type(&list[x], &z, NULL) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + } + break; + case LTC_ASN1_CHOICE: - case LTC_ASN1_CONSTRUCTED: - case LTC_ASN1_CONTEXT_SPECIFIC: case LTC_ASN1_EOL: return CRYPT_INVALID_ARG; } diff --git a/src/ltc/pk/asn1/der/custom_type/der_decode_custom_type.c b/src/ltc/pk/asn1/der/custom_type/der_decode_custom_type.c new file mode 100644 index 00000000..9bc34312 --- /dev/null +++ b/src/ltc/pk/asn1/der/custom_type/der_decode_custom_type.c @@ -0,0 +1,420 @@ +/* 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" + + +/** + @file der_decode_custom_type.c + ASN.1 DER, decode a Custom type, Steffen Jaeckel +*/ + +#ifdef LTC_DER + +/** + Decode a Custom type + @param in The DER encoded input + @param inlen The size of the input + @param root The item that defines the custom type to decode + @return CRYPT_OK on success +*/ +int der_decode_custom_type(const unsigned char *in, unsigned long inlen, + ltc_asn1_list *root) +{ + LTC_ARGCHK(root != NULL); + return der_decode_custom_type_ex(in, inlen, root, NULL, 0, LTC_DER_SEQ_ORDERED | LTC_DER_SEQ_RELAXED); +} + +/** + Extended-decode a Custom type + + This function is used to decode custom types and sequences/sets + For custom types root is used + For sequences/sets list and outlen are used + + @param in The DER encoded input + @param inlen The size of the input + @param root The item that defines the custom type to decode + @param list The list of items to decode + @param outlen The number of items in the list + @param flags c.f. enum ltc_der_seq + @return CRYPT_OK on success +*/ +int der_decode_custom_type_ex(const unsigned char *in, unsigned long inlen, + ltc_asn1_list *root, + ltc_asn1_list *list, unsigned long outlen, + unsigned int flags) +{ + int err, seq_err, i, ordered; + ltc_asn1_type type; + ltc_asn1_list ident; + unsigned long size, x, y, z, blksize; + unsigned char* in_new = NULL; + void *data; + + LTC_ARGCHK(in != NULL); + + /* get blk size */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + x = 0; + + if (root == NULL) { + LTC_ARGCHK(list != NULL); + + /* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */ + if (in[x] != 0x30 && in[x] != 0x31) { + return CRYPT_INVALID_PACKET; + } + ++x; + } else { + if (root->type != LTC_ASN1_CUSTOM_TYPE) { + return CRYPT_INVALID_PACKET; + } + + /* Alloc a copy of the data for primitive handling. */ + if (root->pc == LTC_ASN1_PC_PRIMITIVE) { + in_new = XMALLOC(inlen); + if (in_new == NULL) { + return CRYPT_MEM; + } + XMEMCPY(in_new, in, inlen); + in = in_new; + } + + y = inlen; + if ((err = der_decode_asn1_identifier(in, &y, &ident)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((ident.type != root->type) || + (ident.class != root->class) || + (ident.pc != root->pc) || + (ident.tag != root->tag)) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + x += y; + + list = root->data; + outlen = root->size; + } + + if (root != NULL && root->pc == LTC_ASN1_PC_PRIMITIVE) { + if (((unsigned long)root->used >= der_asn1_type_to_identifier_map_sz) || + (der_asn1_type_to_identifier_map[root->used] == -1)) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + root->type = (ltc_asn1_type)root->used; + list = root; + outlen = 1; + + x -= 1; + in_new[x] = (unsigned char)der_asn1_type_to_identifier_map[list[0].type]; + blksize = inlen - x; + } else { + + y = inlen - x; + if ((err = der_decode_asn1_length(&in[x], &y, &blksize)) != CRYPT_OK) { + goto LBL_ERR; + } + x += y; + } + + /* would this blksize overflow? */ + if (blksize > (inlen - x)) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + /* mark all as unused */ + for (i = 0; i < (int)outlen; i++) { + list[i].used = 0; + } + ordered = flags & LTC_DER_SEQ_ORDERED; + + /* ok read data */ + seq_err = CRYPT_OK; + blksize += x; + inlen -= x; + for (i = 0; i < (int)outlen; i++) { + z = 0; + type = list[i].type; + size = list[i].size; + data = list[i].data; + if (!ordered && list[i].used == 1) { continue; } + + if (type == LTC_ASN1_EOL) { + break; + } + + if (root != NULL && root->pc == LTC_ASN1_PC_PRIMITIVE && i != 0) { + err = CRYPT_PK_ASN1_ERROR; + goto LBL_ERR; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + z = inlen; + if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + if ((err = der_length_boolean(&z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_INTEGER: + z = inlen; + if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + if ((err = der_length_integer(data, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_SHORT_INTEGER: + z = inlen; + if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) { + goto LBL_ERR; + } + + break; + + case LTC_ASN1_BIT_STRING: + z = inlen; + if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_RAW_BIT_STRING: + z = inlen; + if ((err = der_decode_raw_bit_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_OCTET_STRING: + z = inlen; + if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_NULL: + if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) { + if (!ordered || list[i].optional) { continue; } + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + z = 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + z = inlen; + if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_TELETEX_STRING: + z = inlen; + if ((err = der_decode_teletex_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_teletex_string(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_IA5_STRING: + z = inlen; + if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_PRINTABLE_STRING: + z = inlen; + if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_UTF8_STRING: + z = inlen; + if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_utf8_string(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_UTCTIME: + z = inlen; + if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + break; + + case LTC_ASN1_GENERALIZEDTIME: + z = inlen; + if ((err = der_decode_generalizedtime(in + x, &z, data)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + break; + + case LTC_ASN1_SET: + z = inlen; + if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_SETOF: + case LTC_ASN1_SEQUENCE: + /* detect if we have the right type */ + if ((type == LTC_ASN1_SETOF && (in[x] & 0x3F) != 0x31) || (type == LTC_ASN1_SEQUENCE && (in[x] & 0x3F) != 0x30)) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + z = inlen; + err = der_decode_sequence_ex(in + x, z, data, size, flags); + if (err == CRYPT_INPUT_TOO_LONG) { + seq_err = CRYPT_INPUT_TOO_LONG; + err = CRYPT_OK; + } + if (err != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_CUSTOM_TYPE: + z = inlen; + err = der_decode_custom_type(in + x, z, &list[i]); + if (err == CRYPT_INPUT_TOO_LONG) { + seq_err = CRYPT_INPUT_TOO_LONG; + err = CRYPT_OK; + } + if (err != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + if ((err = der_length_custom_type(&list[i], &z, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_CHOICE: + z = inlen; + if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) { + if (!ordered || list[i].optional) { continue; } + goto LBL_ERR; + } + break; + + case LTC_ASN1_EOL: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + x += z; + inlen -= z; + list[i].used = 1; + if (!ordered) { + /* restart the decoder */ + i = -1; + } + } + + for (i = 0; i < (int)outlen; i++) { + if (list[i].used == 0 && list[i].optional == 0) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + } + + if (blksize == x && seq_err == CRYPT_OK && inlen == 0) { + /* everything decoded and no errors in nested sequences */ + err = CRYPT_OK; + } else if (blksize == x && seq_err == CRYPT_INPUT_TOO_LONG && inlen == 0) { + /* a sequence reported too-long input, but now we've decoded everything */ + err = CRYPT_OK; + } else if (blksize != x && ((flags & LTC_DER_SEQ_STRICT) == LTC_DER_SEQ_STRICT)) { + err = CRYPT_INVALID_PACKET; + } else { + err = CRYPT_INPUT_TOO_LONG; + } + +LBL_ERR: + if (in_new != NULL) { + XFREE(in_new); + } + return err; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/asn1/der/custom_type/der_encode_custom_type.c b/src/ltc/pk/asn1/der/custom_type/der_encode_custom_type.c new file mode 100644 index 00000000..d19774c4 --- /dev/null +++ b/src/ltc/pk/asn1/der/custom_type/der_encode_custom_type.c @@ -0,0 +1,238 @@ +/* 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" + + +/** + @file der_encode_custom_type.c + ASN.1 DER, encode a Custom Type, Steffen Jaeckel +*/ + +#ifdef LTC_DER + +/** + Encode a Custom Type + + This function is a bit special compared to the others, as it requires the + root-ltc_asn1_list where the type is defined. + + @param root The root of the list of items to encode + @param out [out] The destination + @param outlen [in/out] The size of the output + @return CRYPT_OK on success +*/ +int der_encode_custom_type(const ltc_asn1_list *root, + unsigned char *out, unsigned long *outlen) +{ + int err; + ltc_asn1_type type; + const ltc_asn1_list *list; + unsigned long size, x, y, z, i, inlen, id_len; + void *data; + + LTC_ARGCHK(root != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get size of output that will be required */ + y = 0; z = 0; + if ((err = der_length_custom_type(root, &y, &z)) != CRYPT_OK) return CRYPT_INVALID_ARG; + + /* too big ? */ + if (*outlen < y) { + *outlen = y; + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + /* get length of the identifier, so we know the offset where to start writing */ + if ((err = der_length_asn1_identifier(root, &id_len)) != CRYPT_OK) return CRYPT_INVALID_ARG; + x = id_len; + + + if (root->pc == LTC_ASN1_PC_PRIMITIVE) { + list = root; + inlen = 1; + /* In case it's a PRIMITIVE type we encode directly to the output + * but leave space for a potentially longer identifier as it will + * simply be replaced afterwards. + */ + x -= 1; + } else { + list = root->data; + inlen = root->size; + /* store length, identifier will be added later */ + y = *outlen - x; + if ((err = der_encode_asn1_length(z, &out[x], &y)) != CRYPT_OK) { + goto LBL_ERR; + } + x += y; + } + + /* store data */ + *outlen -= x; + for (i = 0; i < inlen; i++) { + if (root->pc == LTC_ASN1_PC_PRIMITIVE) { + type = (ltc_asn1_type)list[i].used; + } else { + type = list[i].type; + } + size = list[i].size; + data = list[i].data; + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + z = *outlen; + if ((err = der_encode_boolean(*((int *)data), out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_INTEGER: + z = *outlen; + if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_SHORT_INTEGER: + z = *outlen; + if ((err = der_encode_short_integer(*((unsigned long*)data), out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_BIT_STRING: + z = *outlen; + if ((err = der_encode_bit_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_RAW_BIT_STRING: + z = *outlen; + if ((err = der_encode_raw_bit_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_OCTET_STRING: + z = *outlen; + if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_NULL: + out[x] = 0x05; + out[x+1] = 0x00; + z = 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + z = *outlen; + if ((err = der_encode_object_identifier(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_IA5_STRING: + z = *outlen; + if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_PRINTABLE_STRING: + z = *outlen; + if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_UTF8_STRING: + z = *outlen; + if ((err = der_encode_utf8_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_UTCTIME: + z = *outlen; + if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_GENERALIZEDTIME: + z = *outlen; + if ((err = der_encode_generalizedtime(data, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_SET: + z = *outlen; + if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_SETOF: + z = *outlen; + if ((err = der_encode_setof(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_SEQUENCE: + z = *outlen; + if ((err = der_encode_sequence_ex(data, size, out + x, &z, type)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_CUSTOM_TYPE: + z = *outlen; + if ((err = der_encode_custom_type(&list[i], out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_CHOICE: + case LTC_ASN1_EOL: + case LTC_ASN1_TELETEX_STRING: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + + + x += z; + *outlen -= z; + } + + if ((err = der_encode_asn1_identifier(root, out, &id_len)) != CRYPT_OK) { + goto LBL_ERR; + } + *outlen = x; + err = CRYPT_OK; + +LBL_ERR: + return err; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/asn1/der/custom_type/der_length_custom_type.c b/src/ltc/pk/asn1/der/custom_type/der_length_custom_type.c new file mode 100644 index 00000000..aecc4647 --- /dev/null +++ b/src/ltc/pk/asn1/der/custom_type/der_length_custom_type.c @@ -0,0 +1,213 @@ +/* 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" + +/** + @file der_length_custom_type.c + ASN.1 DER, length of a custom type, Steffen Jaeckel +*/ + +#ifdef LTC_DER + +/** + Get the length of a DER custom type + + This function is a bit special compared to the others, as it requires the + root-ltc_asn1_list where the type is defined. + + @param root The root of the struct to encode + @param outlen [out] The length required in octets to store it + @param payloadlen [out] The length of the payload in octets + @return CRYPT_OK on success +*/ +int der_length_custom_type(const ltc_asn1_list *root, unsigned long *outlen, unsigned long *payloadlen) +{ + int err; + const ltc_asn1_list *list; + ltc_asn1_type type; + unsigned long size, x, y, i, inlen, id_len; + void *data; + + LTC_ARGCHK(root != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get size of output that will be required */ + if ((err = der_length_asn1_identifier(root, &id_len)) != CRYPT_OK) { + return err; + } + y = id_len; + + if (root->pc == LTC_ASN1_PC_PRIMITIVE) { + list = root; + inlen = 1; + } else { + list = root->data; + inlen = root->size; + } + for (i = 0; i < inlen; i++) { + if (root->pc == LTC_ASN1_PC_PRIMITIVE) { + type = (ltc_asn1_type)list[i].used; + } else { + type = list[i].type; + } + size = list[i].size; + data = list[i].data; + + if (type == LTC_ASN1_EOL) { + break; + } + + /* some items may be optional during import */ + if (!list[i].used && list[i].optional) continue; + + switch (type) { + case LTC_ASN1_BOOLEAN: + if ((err = der_length_boolean(&x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_INTEGER: + if ((err = der_length_integer(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_SHORT_INTEGER: + if ((err = der_length_short_integer(*((unsigned long *)data), &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_RAW_BIT_STRING: + if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_OCTET_STRING: + if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_NULL: + y += 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_IA5_STRING: + if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_TELETEX_STRING: + if ((err = der_length_teletex_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_PRINTABLE_STRING: + if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_UTCTIME: + if ((err = der_length_utctime(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_GENERALIZEDTIME: + if ((err = der_length_generalizedtime(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_UTF8_STRING: + if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_CUSTOM_TYPE: + if ((err = der_length_custom_type(&list[i], &x, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + case LTC_ASN1_SEQUENCE: + if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_CHOICE: + case LTC_ASN1_EOL: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + + if (root->pc == LTC_ASN1_PC_PRIMITIVE) { + /* In case it's a PRIMITIVE element we're going + * to only replace the identifier of the one element + * by the custom identifier. + */ + y -= 1; + if (payloadlen != NULL) { + *payloadlen = y - id_len; + } + } else { + /* calc length of length */ + if ((err = der_length_asn1_length(y, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + if (payloadlen != NULL) { + *payloadlen = y - id_len; + } + y += x; + } + + /* store size */ + *outlen = y; + +LBL_ERR: + return err; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/asn1/der/general/der_asn1_maps.c b/src/ltc/pk/asn1/der/general/der_asn1_maps.c new file mode 100644 index 00000000..ba9820f4 --- /dev/null +++ b/src/ltc/pk/asn1/der/general/der_asn1_maps.c @@ -0,0 +1,167 @@ +/* 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" + +/** + @file der_asn1_maps.c + ASN.1 DER, a collection of maps to convert between different representations, Steffen Jaeckel +*/ + +#ifdef LTC_DER + +/** + A Map from ltc_asn1_type to the regularly used ASN.1 identifier +*/ +const int der_asn1_type_to_identifier_map[] = +{ + /* 0 */ + -1, /* LTC_ASN1_EOL, */ + 1, /* LTC_ASN1_BOOLEAN, */ + 2, /* LTC_ASN1_INTEGER, */ + 2, /* LTC_ASN1_SHORT_INTEGER, */ + 3, /* LTC_ASN1_BIT_STRING, */ + /* 5 */ + 4, /* LTC_ASN1_OCTET_STRING, */ + 5, /* LTC_ASN1_NULL, */ + 6, /* LTC_ASN1_OBJECT_IDENTIFIER, */ + 22, /* LTC_ASN1_IA5_STRING, */ + 19, /* LTC_ASN1_PRINTABLE_STRING, */ + /* 10 */ + 12, /* LTC_ASN1_UTF8_STRING, */ + 23, /* LTC_ASN1_UTCTIME, */ + -1, /* LTC_ASN1_CHOICE, */ + 48, /* LTC_ASN1_SEQUENCE, */ + 49, /* LTC_ASN1_SET, */ + /* 15 */ + 49, /* LTC_ASN1_SETOF, */ + 3, /* LTC_ASN1_RAW_BIT_STRING, */ + 20, /* LTC_ASN1_TELETEX_STRING, */ + 24, /* LTC_ASN1_GENERALIZEDTIME, */ + -1, /* LTC_ASN1_CUSTOM_TYPE, */ +}; +const unsigned long der_asn1_type_to_identifier_map_sz = sizeof(der_asn1_type_to_identifier_map)/sizeof(der_asn1_type_to_identifier_map[0]); + +/** + A Map from the ASN.1 Class to its string +*/ +const char* der_asn1_class_to_string_map[] = +{ + "UNIVERSAL", + "APPLICATION", + "CONTEXT-SPECIFIC", + "PRIVATE", +}; +const unsigned long der_asn1_class_to_string_map_sz = sizeof(der_asn1_class_to_string_map)/sizeof(der_asn1_class_to_string_map[0]); + +/** + A Map from the ASN.1 P/C-bit to its string +*/ +const char* der_asn1_pc_to_string_map[] = +{ + "PRIMITIVE", + "CONSTRUCTED", +}; +const unsigned long der_asn1_pc_to_string_map_sz = sizeof(der_asn1_pc_to_string_map)/sizeof(der_asn1_pc_to_string_map[0]); + +/** + A Map from the ASN.1 tag to its string +*/ +const char* der_asn1_tag_to_string_map[] = +{ + "Reserved for use by the encoding rules", + "Boolean type", + "Integer type", + "Bitstring type", + "Octetstring type", + "Null type", + "Object identifier type", + "Object descriptor type", + "External type and Instance-of type", + "Real type", + "Enumerated type", + "Embedded-pdv type", + "UTF8String type", + "Relative object identifier type", + "The time type", + "Reserved for future editions of this Recommendation | International Standard", + "Sequence and Sequence-of types", + "Set and Set-of types", + "NumericString type", + "PrintableString type", + "TeletexString (T61String) type", + "VideotexString type", + "IA5String type", + "UTCTime type", + "GeneralizedTime type", + "GraphicString type", + "VisibleString (ISO646String) type", + "GeneralString type", + "UniversalString type", + "UnrestrictedCharacterString type", + "BMPString type", + "Date type", + "TimeOfDay type", + "DateTime type", + "Duration type", + "OID internationalized resource identifier type", + "Relative OID internationalized resource identifier type", +}; +const unsigned long der_asn1_tag_to_string_map_sz = sizeof(der_asn1_tag_to_string_map)/sizeof(der_asn1_tag_to_string_map[0]); + +/** + A Map from ASN.1 Tags to ltc_asn1_type +*/ +const ltc_asn1_type der_asn1_tag_to_type_map[] = +{ + /* 0 */ + LTC_ASN1_EOL, /* Reserved for use by the encoding rules */ + LTC_ASN1_BOOLEAN, /* Boolean type */ + LTC_ASN1_INTEGER, /* Integer type */ + LTC_ASN1_BIT_STRING, /* Bitstring type */ + LTC_ASN1_OCTET_STRING, /* Octetstring type */ + /* 5 */ + LTC_ASN1_NULL, /* Null type */ + LTC_ASN1_OBJECT_IDENTIFIER, /* Object identifier type */ + LTC_ASN1_CUSTOM_TYPE, /* Object descriptor type */ + LTC_ASN1_CUSTOM_TYPE, /* External type and Instance-of type */ + LTC_ASN1_CUSTOM_TYPE, /* Real type */ + /* 10 */ + LTC_ASN1_CUSTOM_TYPE, /* Enumerated type */ + LTC_ASN1_CUSTOM_TYPE, /* Embedded-pdv type */ + LTC_ASN1_UTF8_STRING, /* UTF8String type */ + LTC_ASN1_CUSTOM_TYPE, /* Relative object identifier type */ + LTC_ASN1_CUSTOM_TYPE, /* The time type */ + /* 15 */ + LTC_ASN1_EOL, /* Reserved for future editions of this Recommendation | International Standard */ + LTC_ASN1_SEQUENCE, /* Sequence and Sequence-of types */ + LTC_ASN1_SET, /* Set and Set-of types */ + LTC_ASN1_CUSTOM_TYPE, /* NumericString types */ + LTC_ASN1_PRINTABLE_STRING, /* PrintableString types */ + /* 20 */ + LTC_ASN1_TELETEX_STRING, /* TeletexString (T61String) types */ + LTC_ASN1_CUSTOM_TYPE, /* VideotexString types */ + LTC_ASN1_IA5_STRING, /* IA5String types */ + LTC_ASN1_UTCTIME, /* UTCTime types */ + LTC_ASN1_GENERALIZEDTIME, /* GeneralizedTime types */ + /* 25 */ + LTC_ASN1_CUSTOM_TYPE, /* GraphicString types */ + LTC_ASN1_CUSTOM_TYPE, /* VisibleString (ISO646String) types */ + LTC_ASN1_CUSTOM_TYPE, /* GeneralString types */ + LTC_ASN1_CUSTOM_TYPE, /* UniversalString types */ + LTC_ASN1_CUSTOM_TYPE, /* UnrestrictedCharacterString types */ + /* 30 */ + LTC_ASN1_CUSTOM_TYPE, /* BMPString types */ +}; +const unsigned long der_asn1_tag_to_type_map_sz = sizeof(der_asn1_tag_to_type_map)/sizeof(der_asn1_tag_to_type_map[0]); + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/asn1/der/general/der_decode_asn1_identifier.c b/src/ltc/pk/asn1/der/general/der_decode_asn1_identifier.c new file mode 100644 index 00000000..b4689f6a --- /dev/null +++ b/src/ltc/pk/asn1/der/general/der_decode_asn1_identifier.c @@ -0,0 +1,133 @@ +/* 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" + +/** + @file der_decode_asn1_identifier.c + ASN.1 DER, decode the ASN.1 Identifier, Steffen Jaeckel +*/ + +#ifdef LTC_DER +/* c.f. X.680 & X.690, some decisions backed by X.690 ch. 10.2 */ +static const unsigned char tag_constructed_map[] = +{ + /* 0 */ + 255, + LTC_ASN1_PC_PRIMITIVE, + LTC_ASN1_PC_PRIMITIVE, + LTC_ASN1_PC_PRIMITIVE, + LTC_ASN1_PC_PRIMITIVE, + /* 5 */ + LTC_ASN1_PC_PRIMITIVE, + LTC_ASN1_PC_PRIMITIVE, + LTC_ASN1_PC_PRIMITIVE, + LTC_ASN1_PC_PRIMITIVE, + LTC_ASN1_PC_PRIMITIVE, + /* 10 */ + LTC_ASN1_PC_PRIMITIVE, + LTC_ASN1_PC_PRIMITIVE, + LTC_ASN1_PC_PRIMITIVE, + LTC_ASN1_PC_PRIMITIVE, + LTC_ASN1_PC_PRIMITIVE, + /* 15 */ + 255, + LTC_ASN1_PC_CONSTRUCTED, + LTC_ASN1_PC_CONSTRUCTED, + LTC_ASN1_PC_PRIMITIVE, + LTC_ASN1_PC_PRIMITIVE, + /* 20 */ + LTC_ASN1_PC_PRIMITIVE, + LTC_ASN1_PC_PRIMITIVE, + LTC_ASN1_PC_PRIMITIVE, + LTC_ASN1_PC_PRIMITIVE, + LTC_ASN1_PC_PRIMITIVE, + /* 25 */ + LTC_ASN1_PC_PRIMITIVE, + LTC_ASN1_PC_PRIMITIVE, + LTC_ASN1_PC_PRIMITIVE, + LTC_ASN1_PC_PRIMITIVE, +}; + static const unsigned long tag_constructed_map_sz = sizeof(tag_constructed_map)/sizeof(tag_constructed_map[0]); + +/** + Decode the ASN.1 Identifier + @param id Where to store the decoded Identifier + @param in Where to read the Identifier from + @param inlen [in/out] The size of in available/read + @return CRYPT_OK if successful +*/ +int der_decode_asn1_identifier(const unsigned char *in, unsigned long *inlen, ltc_asn1_list *id) +{ + ulong64 tmp; + unsigned long tag_len; + int err; + + LTC_ARGCHK(id != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != NULL); + + if (*inlen == 0) { + return CRYPT_BUFFER_OVERFLOW; + } + + tag_len = 1; + id->class = (in[0] >> 6) & 0x3; + id->pc = (in[0] >> 5) & 0x1; + id->tag = in[0] & 0x1f; + + err = CRYPT_OK; + if (id->tag == 0x1f) { + id->tag = 0; + do { + if (*inlen < tag_len) { + /* break the loop and trigger the BOF error-code */ + tmp = 0xff; + break; + } + id->tag <<= 7; + id->tag |= in[tag_len] & 0x7f; + tmp = in[tag_len] & 0x80; + tag_len++; + } while ((tmp != 0) && (tag_len < 10)); + + if (tmp != 0) { + err = CRYPT_BUFFER_OVERFLOW; + } else if (id->tag < 0x1f) { + err = CRYPT_PK_ASN1_ERROR; + } + } + + if (err != CRYPT_OK) { + id->pc = 0; + id->class = 0; + id->tag = 0; + } else { + *inlen = tag_len; + if ((id->class == LTC_ASN1_CL_UNIVERSAL) && + (id->tag < der_asn1_tag_to_type_map_sz) && + (id->tag < tag_constructed_map_sz) && + (id->pc == tag_constructed_map[id->tag])) { + id->type = der_asn1_tag_to_type_map[id->tag]; + } else { + if ((id->class == LTC_ASN1_CL_UNIVERSAL) && (id->tag == 0)) { + id->type = LTC_ASN1_EOL; + } else { + id->type = LTC_ASN1_CUSTOM_TYPE; + } + } + } + + return CRYPT_OK; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/asn1/der/general/der_decode_asn1_length.c b/src/ltc/pk/asn1/der/general/der_decode_asn1_length.c new file mode 100644 index 00000000..0e1bc6c2 --- /dev/null +++ b/src/ltc/pk/asn1/der/general/der_decode_asn1_length.c @@ -0,0 +1,67 @@ +/* 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" + +/** + @file der_decode_asn1_length.c + ASN.1 DER, decode the ASN.1 Length field, Steffen Jaeckel +*/ + +#ifdef LTC_DER +/** + Decode the ASN.1 Length field + @param in Where to read the length field from + @param inlen [in/out] The size of in available/read + @param outlen [out] The decoded ASN.1 length + @return CRYPT_OK if successful +*/ +int der_decode_asn1_length(const unsigned char *in, unsigned long *inlen, unsigned long *outlen) +{ + unsigned long real_len, decoded_len, offset, i; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != NULL); + + if (*inlen < 1) { + return CRYPT_BUFFER_OVERFLOW; + } + + real_len = in[0]; + + if (real_len < 128) { + decoded_len = real_len; + offset = 1; + } else { + real_len &= 0x7F; + if (real_len == 0) { + return CRYPT_PK_ASN1_ERROR; + } else if (real_len > sizeof(decoded_len)) { + return CRYPT_OVERFLOW; + } else if (real_len > (*inlen - 1)) { + return CRYPT_BUFFER_OVERFLOW; + } + decoded_len = 0; + offset = 1 + real_len; + for (i = 0; i < real_len; i++) { + decoded_len = (decoded_len << 8) | in[1 + i]; + } + } + + if (outlen != NULL) *outlen = decoded_len; + if (decoded_len > (*inlen - offset)) return CRYPT_OVERFLOW; + *inlen = offset; + + return CRYPT_OK; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/asn1/der/general/der_encode_asn1_identifier.c b/src/ltc/pk/asn1/der/general/der_encode_asn1_identifier.c new file mode 100644 index 00000000..367bb699 --- /dev/null +++ b/src/ltc/pk/asn1/der/general/der_encode_asn1_identifier.c @@ -0,0 +1,97 @@ +/* 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" + +/** + @file der_encode_asn1_identifier.c + ASN.1 DER, encode the ASN.1 Identifier, Steffen Jaeckel +*/ + +#ifdef LTC_DER +/** + Encode the ASN.1 Identifier + @param id The ASN.1 Identifer to encode + @param out Where to write the identifier to + @param outlen [in/out] The size of out available/written + @return CRYPT_OK if successful +*/ +int der_encode_asn1_identifier(const ltc_asn1_list *id, unsigned char *out, unsigned long *outlen) +{ + ulong64 tmp; + unsigned long tag_len; + + LTC_ARGCHK(id != NULL); + LTC_ARGCHK(outlen != NULL); + + if (id->type != LTC_ASN1_CUSTOM_TYPE) { + if ((unsigned)id->type >= der_asn1_type_to_identifier_map_sz) { + return CRYPT_INVALID_ARG; + } + if (der_asn1_type_to_identifier_map[id->type] == -1) { + return CRYPT_INVALID_ARG; + } + if (out != NULL) { + *out = der_asn1_type_to_identifier_map[id->type]; + } + *outlen = 1; + return CRYPT_OK; + } else { + if (id->class < LTC_ASN1_CL_UNIVERSAL || id->class > LTC_ASN1_CL_PRIVATE) { + return CRYPT_INVALID_ARG; + } + if (id->pc < LTC_ASN1_PC_PRIMITIVE || id->pc > LTC_ASN1_PC_CONSTRUCTED) { + return CRYPT_INVALID_ARG; + } + if (id->tag > (ULONG_MAX >> (8 + 7))) { + return CRYPT_INVALID_ARG; + } + } + + if (out != NULL) { + if (*outlen < 1) { + return CRYPT_BUFFER_OVERFLOW; + } + + out[0] = id->class << 6 | id->pc << 5; + } + + if (id->tag < 0x1f) { + if (out != NULL) { + out[0] |= id->tag & 0x1f; + } + *outlen = 1; + } else { + tag_len = 0; + tmp = id->tag; + do { + tag_len++; + tmp >>= 7; + } while (tmp); + + if (out != NULL) { + if (*outlen < tag_len + 1) { + return CRYPT_BUFFER_OVERFLOW; + } + out[0] |= 0x1f; + for (tmp = 1; tmp <= tag_len; ++tmp) { + out[tmp] = ((id->tag >> (7 * (tag_len - tmp))) & 0x7f) | 0x80; + } + out[tag_len] &= ~0x80; + } + *outlen = tag_len + 1; + } + + return CRYPT_OK; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/asn1/der/general/der_encode_asn1_length.c b/src/ltc/pk/asn1/der/general/der_encode_asn1_length.c new file mode 100644 index 00000000..0d871afe --- /dev/null +++ b/src/ltc/pk/asn1/der/general/der_encode_asn1_length.c @@ -0,0 +1,127 @@ +/* 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" + +/** + @file der_encode_asn1_length.c + ASN.1 DER, encode the ASN.1 length field, Steffen Jaeckel +*/ + +#ifdef LTC_DER +/** + Encode the ASN.1 length field + @param len The length to encode + @param out Where to write the length field to + @param outlen [in/out] The size of out available/written + @return CRYPT_OK if successful +*/ +int der_encode_asn1_length(unsigned long len, unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y; + + LTC_ARGCHK(outlen != NULL); + + x = len; + y = 0; + + while(x != 0) { + y++; + x >>= 8; + } + if (y == 0) { + return CRYPT_PK_ASN1_ERROR; + } + + if (out == NULL) { + if (len < 128) { + x = y; + } else { + x = y + 1; + } + } else { + if (*outlen < y) { + return CRYPT_BUFFER_OVERFLOW; + } + x = 0; + if (len < 128) { + out[x++] = (unsigned char)len; + } else if (len <= 0xffUL) { + out[x++] = 0x81; + out[x++] = (unsigned char)len; + } else if (len <= 0xffffUL) { + out[x++] = 0x82; + out[x++] = (unsigned char)((len>>8UL)&255); + out[x++] = (unsigned char)(len&255); + } else if (len <= 0xffffffUL) { + out[x++] = 0x83; + out[x++] = (unsigned char)((len>>16UL)&255); + out[x++] = (unsigned char)((len>>8UL)&255); + out[x++] = (unsigned char)(len&255); + #if ULONG_MAX != ULLONG_MAX + } else { + out[x++] = 0x84; + out[x++] = (unsigned char)((len>>24UL)&255); + out[x++] = (unsigned char)((len>>16UL)&255); + out[x++] = (unsigned char)((len>>8UL)&255); + out[x++] = (unsigned char)(len&255); + } + #else + } else if (len <= 0xffffffffUL) { + out[x++] = 0x84; + out[x++] = (unsigned char)((len>>24UL)&255); + out[x++] = (unsigned char)((len>>16UL)&255); + out[x++] = (unsigned char)((len>>8UL)&255); + out[x++] = (unsigned char)(len&255); + } else if (len <= 0xffffffffffULL) { + out[x++] = 0x85; + out[x++] = (unsigned char)((len>>32ULL)&255); + out[x++] = (unsigned char)((len>>24ULL)&255); + out[x++] = (unsigned char)((len>>16ULL)&255); + out[x++] = (unsigned char)((len>>8ULL)&255); + out[x++] = (unsigned char)(len&255); + } else if (len <= 0xffffffffffffULL) { + out[x++] = 0x86; + out[x++] = (unsigned char)((len>>40ULL)&255); + out[x++] = (unsigned char)((len>>32ULL)&255); + out[x++] = (unsigned char)((len>>24ULL)&255); + out[x++] = (unsigned char)((len>>16ULL)&255); + out[x++] = (unsigned char)((len>>8ULL)&255); + out[x++] = (unsigned char)(len&255); + } else if (len <= 0xffffffffffffffULL) { + out[x++] = 0x87; + out[x++] = (unsigned char)((len>>48ULL)&255); + out[x++] = (unsigned char)((len>>40ULL)&255); + out[x++] = (unsigned char)((len>>32ULL)&255); + out[x++] = (unsigned char)((len>>24ULL)&255); + out[x++] = (unsigned char)((len>>16ULL)&255); + out[x++] = (unsigned char)((len>>8ULL)&255); + out[x++] = (unsigned char)(len&255); + } else { + out[x++] = 0x88; + out[x++] = (unsigned char)((len>>56ULL)&255); + out[x++] = (unsigned char)((len>>48ULL)&255); + out[x++] = (unsigned char)((len>>40ULL)&255); + out[x++] = (unsigned char)((len>>32ULL)&255); + out[x++] = (unsigned char)((len>>24ULL)&255); + out[x++] = (unsigned char)((len>>16ULL)&255); + out[x++] = (unsigned char)((len>>8ULL)&255); + out[x++] = (unsigned char)(len&255); + } + #endif + } + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/asn1/der/general/der_length_asn1_identifier.c b/src/ltc/pk/asn1/der/general/der_length_asn1_identifier.c new file mode 100644 index 00000000..40e76f02 --- /dev/null +++ b/src/ltc/pk/asn1/der/general/der_length_asn1_identifier.c @@ -0,0 +1,33 @@ +/* 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" + +/** + @file der_length_asn1_identifier.c + ASN.1 DER, determine the length when encoding the ASN.1 Identifier, Steffen Jaeckel +*/ + +#ifdef LTC_DER +/** + Determine the length required when encoding the ASN.1 Identifier + @param id The ASN.1 identifier to encode + @param idlen [out] The required length to encode list + @return CRYPT_OK if successful +*/ + +int der_length_asn1_identifier(const ltc_asn1_list *id, unsigned long *idlen) +{ + return der_encode_asn1_identifier(id, NULL, idlen); +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/asn1/der/general/der_length_asn1_length.c b/src/ltc/pk/asn1/der/general/der_length_asn1_length.c new file mode 100644 index 00000000..1271e1cb --- /dev/null +++ b/src/ltc/pk/asn1/der/general/der_length_asn1_length.c @@ -0,0 +1,32 @@ +/* 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" + +/** + @file der_length_asn1_length.c + ASN.1 DER, determine the length of the ASN.1 length field, Steffen Jaeckel +*/ + +#ifdef LTC_DER +/** + Determine the length required to encode len in the ASN.1 length field + @param len The length to encode + @param outlen [out] The length that's required to store len + @return CRYPT_OK if successful +*/ +int der_length_asn1_length(unsigned long len, unsigned long *outlen) +{ + return der_encode_asn1_length(len, NULL, outlen); +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/asn1/der/ia5/der_decode_ia5_string.c b/src/ltc/pk/asn1/der/ia5/der_decode_ia5_string.c index c3472519..15e90f88 100644 --- a/src/ltc/pk/asn1/der/ia5/der_decode_ia5_string.c +++ b/src/ltc/pk/asn1/der/ia5/der_decode_ia5_string.c @@ -28,7 +28,7 @@ int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { unsigned long x, y, len; - int t; + int t, err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); @@ -45,23 +45,12 @@ int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, } x = 1; - /* decode the length */ - if (in[x] & 0x80) { - /* valid # of bytes in length are 1,2,3 */ - y = in[x] & 0x7F; - if ((y == 0) || (y > 3) || ((x + y) > inlen)) { - return CRYPT_INVALID_PACKET; - } - - /* read the length in */ - len = 0; - ++x; - while (y--) { - len = (len << 8) | in[x++]; - } - } else { - len = in[x++] & 0x7F; + /* get the length of the data */ + y = inlen - x; + if ((err = der_decode_asn1_length(in + x, &y, &len)) != CRYPT_OK) { + return err; } + x += y; /* is it too long? */ if (len > *outlen) { @@ -69,7 +58,7 @@ int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, return CRYPT_BUFFER_OVERFLOW; } - if (len + x > inlen) { + if (len > (inlen - x)) { return CRYPT_INVALID_PACKET; } diff --git a/src/ltc/pk/asn1/der/ia5/der_encode_ia5_string.c b/src/ltc/pk/asn1/der/ia5/der_encode_ia5_string.c index 18b926ea..fee1c703 100644 --- a/src/ltc/pk/asn1/der/ia5/der_encode_ia5_string.c +++ b/src/ltc/pk/asn1/der/ia5/der_encode_ia5_string.c @@ -47,23 +47,11 @@ int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, /* encode the header+len */ x = 0; out[x++] = 0x16; - if (inlen < 128) { - out[x++] = (unsigned char)inlen; - } else if (inlen < 256) { - out[x++] = 0x81; - out[x++] = (unsigned char)inlen; - } else if (inlen < 65536UL) { - out[x++] = 0x82; - out[x++] = (unsigned char)((inlen>>8)&255); - out[x++] = (unsigned char)(inlen&255); - } else if (inlen < 16777216UL) { - out[x++] = 0x83; - out[x++] = (unsigned char)((inlen>>16)&255); - out[x++] = (unsigned char)((inlen>>8)&255); - out[x++] = (unsigned char)(inlen&255); - } else { - return CRYPT_INVALID_ARG; + len = *outlen - x; + if ((err = der_encode_asn1_length(inlen, out + x, &len)) != CRYPT_OK) { + return err; } + x += len; /* store octets */ for (y = 0; y < inlen; y++) { diff --git a/src/ltc/pk/asn1/der/ia5/der_length_ia5_string.c b/src/ltc/pk/asn1/der/ia5/der_length_ia5_string.c index 5f1a78d1..422c4d33 100644 --- a/src/ltc/pk/asn1/der/ia5/der_length_ia5_string.c +++ b/src/ltc/pk/asn1/der/ia5/der_length_ia5_string.c @@ -154,6 +154,7 @@ int der_ia5_value_decode(int v) int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen) { unsigned long x; + int err; LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(octets != NULL); @@ -165,21 +166,10 @@ int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, un } } - if (noctets < 128) { - /* 16 LL DD DD DD ... */ - *outlen = 2 + noctets; - } else if (noctets < 256) { - /* 16 81 LL DD DD DD ... */ - *outlen = 3 + noctets; - } else if (noctets < 65536UL) { - /* 16 82 LL LL DD DD DD ... */ - *outlen = 4 + noctets; - } else if (noctets < 16777216UL) { - /* 16 83 LL LL LL DD DD DD ... */ - *outlen = 5 + noctets; - } else { - return CRYPT_INVALID_ARG; + if ((err = der_length_asn1_length(noctets, &x)) != CRYPT_OK) { + return err; } + *outlen = 1 + x + noctets; return CRYPT_OK; } diff --git a/src/ltc/pk/asn1/der/integer/der_decode_integer.c b/src/ltc/pk/asn1/der/integer/der_decode_integer.c index 88cf93f3..e5c5c122 100644 --- a/src/ltc/pk/asn1/der/integer/der_decode_integer.c +++ b/src/ltc/pk/asn1/der/integer/der_decode_integer.c @@ -25,7 +25,7 @@ */ int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num) { - unsigned long x, y, z; + unsigned long x, y; int err; LTC_ARGCHK(num != NULL); @@ -42,45 +42,15 @@ int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num) return CRYPT_INVALID_PACKET; } - /* now decode the len stuff */ - z = in[x++]; - - if ((z & 0x80) == 0x00) { - /* short form */ - - /* will it overflow? */ - if (x + z > inlen) { - return CRYPT_INVALID_PACKET; - } - - /* no so read it */ - if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, z)) != CRYPT_OK) { - return err; - } - } else { - /* long form */ - z &= 0x7F; - - /* will number of length bytes overflow? (or > 4) */ - if (((x + z) > inlen) || (z > 4) || (z == 0)) { - return CRYPT_INVALID_PACKET; - } - - /* now read it in */ - y = 0; - while (z--) { - y = ((unsigned long)(in[x++])) | (y << 8); - } - - /* now will reading y bytes overrun? */ - if ((x + y) > inlen) { - return CRYPT_INVALID_PACKET; - } + /* get the length of the data */ + inlen -= x; + if ((err = der_decode_asn1_length(in + x, &inlen, &y)) != CRYPT_OK) { + return err; + } + x += inlen; - /* no so read it */ - if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, y)) != CRYPT_OK) { - return err; - } + if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, y)) != CRYPT_OK) { + return err; } /* see if it's negative */ diff --git a/src/ltc/pk/asn1/der/integer/der_encode_integer.c b/src/ltc/pk/asn1/der/integer/der_encode_integer.c index a8bada55..3bd95932 100644 --- a/src/ltc/pk/asn1/der/integer/der_encode_integer.c +++ b/src/ltc/pk/asn1/der/integer/der_encode_integer.c @@ -26,7 +26,7 @@ */ int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen) { - unsigned long tmplen, y; + unsigned long tmplen, y, len; int err, leading_zero; LTC_ARGCHK(num != NULL); @@ -63,24 +63,11 @@ int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen) /* now store initial data */ *out++ = 0x02; - if (y < 128) { - /* short form */ - *out++ = (unsigned char)y; - } else if (y < 256) { - *out++ = 0x81; - *out++ = (unsigned char)y; - } else if (y < 65536UL) { - *out++ = 0x82; - *out++ = (unsigned char)((y>>8)&255); - *out++ = (unsigned char)y; - } else if (y < 16777216UL) { - *out++ = 0x83; - *out++ = (unsigned char)((y>>16)&255); - *out++ = (unsigned char)((y>>8)&255); - *out++ = (unsigned char)y; - } else { - return CRYPT_INVALID_ARG; + len = *outlen - 1; + if ((err = der_encode_asn1_length(y, out, &len)) != CRYPT_OK) { + return err; } + out += len; /* now store msbyte of zero if num is non-zero */ if (leading_zero) { diff --git a/src/ltc/pk/asn1/der/integer/der_length_integer.c b/src/ltc/pk/asn1/der/integer/der_length_integer.c index 753ef0e0..60daffa7 100644 --- a/src/ltc/pk/asn1/der/integer/der_length_integer.c +++ b/src/ltc/pk/asn1/der/integer/der_length_integer.c @@ -24,7 +24,7 @@ int der_length_integer(void *num, unsigned long *outlen) { unsigned long z, len; - int leading_zero; + int leading_zero, err; LTC_ARGCHK(num != NULL); LTC_ARGCHK(outlen != NULL); @@ -40,35 +40,21 @@ int der_length_integer(void *num, unsigned long *outlen) } /* size for bignum */ - z = len = leading_zero + mp_unsigned_bin_size(num); + len = leading_zero + mp_unsigned_bin_size(num); } else { /* it's negative */ /* find power of 2 that is a multiple of eight and greater than count bits */ z = mp_count_bits(num); z = z + (8 - (z & 7)); if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --z; - len = z = z >> 3; + len = z >> 3; } - /* now we need a length */ - if (z < 128) { - /* short form */ - ++len; - } else { - /* long form (relies on z != 0), assumes length bytes < 128 */ - ++len; - - while (z) { - ++len; - z >>= 8; - } + if ((err = der_length_asn1_length(len, &z)) != CRYPT_OK) { + return err; } + *outlen = 1 + z + len; - /* we need a 0x02 to indicate it's INTEGER */ - ++len; - - /* return length */ - *outlen = len; return CRYPT_OK; } diff --git a/src/ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.c b/src/ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.c index c957565d..48a95473 100644 --- a/src/ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.c +++ b/src/ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.c @@ -26,6 +26,7 @@ int der_decode_object_identifier(const unsigned char *in, unsigned long inle unsigned long *words, unsigned long *outlen) { unsigned long x, y, t, len; + int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(words != NULL); @@ -38,6 +39,7 @@ int der_decode_object_identifier(const unsigned char *in, unsigned long inle /* must be room for at least two words */ if (*outlen < 2) { + *outlen = 2; return CRYPT_BUFFER_OVERFLOW; } @@ -47,21 +49,14 @@ int der_decode_object_identifier(const unsigned char *in, unsigned long inle return CRYPT_INVALID_PACKET; } - /* get the length */ - if (in[x] < 128) { - len = in[x++]; - } else { - if (in[x] < 0x81 || in[x] > 0x82) { - return CRYPT_INVALID_PACKET; - } - y = in[x++] & 0x7F; - len = 0; - while (y--) { - len = (len << 8) | (unsigned long)in[x++]; - } + /* get the length of the data */ + y = inlen - x; + if ((err = der_decode_asn1_length(in + x, &y, &len)) != CRYPT_OK) { + return err; } + x += y; - if (len < 1 || (len + x) > inlen) { + if ((len == 0) || (len > (inlen - x))) { return CRYPT_INVALID_PACKET; } @@ -73,21 +68,28 @@ int der_decode_object_identifier(const unsigned char *in, unsigned long inle if (!(in[x++] & 0x80)) { /* store t */ if (y >= *outlen) { - return CRYPT_BUFFER_OVERFLOW; - } - if (y == 0) { - words[0] = t / 40; - words[1] = t % 40; - y = 2; + y++; } else { - words[y++] = t; + if (y == 0) { + words[0] = t / 40; + words[1] = t % 40; + y = 2; + } else { + words[y++] = t; + } } - t = 0; + t = 0; } } + if (y > *outlen) { + err = CRYPT_BUFFER_OVERFLOW; + } else { + err = CRYPT_OK; + } + *outlen = y; - return CRYPT_OK; + return err; } #endif diff --git a/src/ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.c b/src/ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.c index b1ce62c9..4b397b64 100644 --- a/src/ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.c +++ b/src/ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.c @@ -55,18 +55,11 @@ int der_encode_object_identifier(unsigned long *words, unsigned long nwords, /* store header + length */ x = 0; out[x++] = 0x06; - if (z < 128) { - out[x++] = (unsigned char)z; - } else if (z < 256) { - out[x++] = 0x81; - out[x++] = (unsigned char)z; - } else if (z < 65536UL) { - out[x++] = 0x82; - out[x++] = (unsigned char)((z>>8)&255); - out[x++] = (unsigned char)(z&255); - } else { - return CRYPT_INVALID_ARG; + y = *outlen - x; + if ((err = der_encode_asn1_length(z, out + x, &y)) != CRYPT_OK) { + return err; } + x += y; /* store first byte */ wordbuf = words[0] * 40 + words[1]; diff --git a/src/ltc/pk/asn1/der/octet/der_decode_octet_string.c b/src/ltc/pk/asn1/der/octet/der_decode_octet_string.c index 02859dca..a9b3cdc5 100644 --- a/src/ltc/pk/asn1/der/octet/der_decode_octet_string.c +++ b/src/ltc/pk/asn1/der/octet/der_decode_octet_string.c @@ -28,6 +28,7 @@ int der_decode_octet_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { unsigned long x, y, len; + int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); @@ -44,23 +45,12 @@ int der_decode_octet_string(const unsigned char *in, unsigned long inlen, } x = 1; - /* decode the length */ - if (in[x] & 0x80) { - /* valid # of bytes in length are 1,2,3 */ - y = in[x] & 0x7F; - if ((y == 0) || (y > 3) || ((x + y) > inlen)) { - return CRYPT_INVALID_PACKET; - } - - /* read the length in */ - len = 0; - ++x; - while (y--) { - len = (len << 8) | in[x++]; - } - } else { - len = in[x++] & 0x7F; + /* get the length of the data */ + y = inlen - x; + if ((err = der_decode_asn1_length(in + x, &y, &len)) != CRYPT_OK) { + return err; } + x += y; /* is it too long? */ if (len > *outlen) { @@ -68,7 +58,7 @@ int der_decode_octet_string(const unsigned char *in, unsigned long inlen, return CRYPT_BUFFER_OVERFLOW; } - if (len + x > inlen) { + if (len > (inlen - x)) { return CRYPT_INVALID_PACKET; } diff --git a/src/ltc/pk/asn1/der/octet/der_encode_octet_string.c b/src/ltc/pk/asn1/der/octet/der_encode_octet_string.c index 9c9d1a65..fd79c673 100644 --- a/src/ltc/pk/asn1/der/octet/der_encode_octet_string.c +++ b/src/ltc/pk/asn1/der/octet/der_encode_octet_string.c @@ -48,23 +48,11 @@ int der_encode_octet_string(const unsigned char *in, unsigned long inlen, /* encode the header+len */ x = 0; out[x++] = 0x04; - if (inlen < 128) { - out[x++] = (unsigned char)inlen; - } else if (inlen < 256) { - out[x++] = 0x81; - out[x++] = (unsigned char)inlen; - } else if (inlen < 65536UL) { - out[x++] = 0x82; - out[x++] = (unsigned char)((inlen>>8)&255); - out[x++] = (unsigned char)(inlen&255); - } else if (inlen < 16777216UL) { - out[x++] = 0x83; - out[x++] = (unsigned char)((inlen>>16)&255); - out[x++] = (unsigned char)((inlen>>8)&255); - out[x++] = (unsigned char)(inlen&255); - } else { - return CRYPT_INVALID_ARG; + len = *outlen - x; + if ((err = der_encode_asn1_length(inlen, out + x, &len)) != CRYPT_OK) { + return err; } + x += len; /* store octets */ for (y = 0; y < inlen; y++) { diff --git a/src/ltc/pk/asn1/der/octet/der_length_octet_string.c b/src/ltc/pk/asn1/der/octet/der_length_octet_string.c index 10c9e892..9e5386a3 100644 --- a/src/ltc/pk/asn1/der/octet/der_length_octet_string.c +++ b/src/ltc/pk/asn1/der/octet/der_length_octet_string.c @@ -22,23 +22,15 @@ */ int der_length_octet_string(unsigned long noctets, unsigned long *outlen) { + unsigned long x; + int err; + LTC_ARGCHK(outlen != NULL); - if (noctets < 128) { - /* 04 LL DD DD DD ... */ - *outlen = 2 + noctets; - } else if (noctets < 256) { - /* 04 81 LL DD DD DD ... */ - *outlen = 3 + noctets; - } else if (noctets < 65536UL) { - /* 04 82 LL LL DD DD DD ... */ - *outlen = 4 + noctets; - } else if (noctets < 16777216UL) { - /* 04 83 LL LL LL DD DD DD ... */ - *outlen = 5 + noctets; - } else { - return CRYPT_INVALID_ARG; + if ((err = der_length_asn1_length(noctets, &x)) != CRYPT_OK) { + return err; } + *outlen = 1 + x + noctets; return CRYPT_OK; } diff --git a/src/ltc/pk/asn1/der/printable_string/der_decode_printable_string.c b/src/ltc/pk/asn1/der/printable_string/der_decode_printable_string.c index 69474292..1ec9e3c7 100644 --- a/src/ltc/pk/asn1/der/printable_string/der_decode_printable_string.c +++ b/src/ltc/pk/asn1/der/printable_string/der_decode_printable_string.c @@ -28,7 +28,7 @@ int der_decode_printable_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { unsigned long x, y, len; - int t; + int t, err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); @@ -45,23 +45,12 @@ int der_decode_printable_string(const unsigned char *in, unsigned long inlen, } x = 1; - /* decode the length */ - if (in[x] & 0x80) { - /* valid # of bytes in length are 1,2,3 */ - y = in[x] & 0x7F; - if ((y == 0) || (y > 3) || ((x + y) > inlen)) { - return CRYPT_INVALID_PACKET; - } - - /* read the length in */ - len = 0; - ++x; - while (y--) { - len = (len << 8) | in[x++]; - } - } else { - len = in[x++] & 0x7F; + /* get the length of the data */ + y = inlen - x; + if ((err = der_decode_asn1_length(in + x, &y, &len)) != CRYPT_OK) { + return err; } + x += y; /* is it too long? */ if (len > *outlen) { @@ -69,7 +58,7 @@ int der_decode_printable_string(const unsigned char *in, unsigned long inlen, return CRYPT_BUFFER_OVERFLOW; } - if (len + x > inlen) { + if (len > (inlen - x)) { return CRYPT_INVALID_PACKET; } diff --git a/src/ltc/pk/asn1/der/printable_string/der_encode_printable_string.c b/src/ltc/pk/asn1/der/printable_string/der_encode_printable_string.c index ee54e48f..bd593916 100644 --- a/src/ltc/pk/asn1/der/printable_string/der_encode_printable_string.c +++ b/src/ltc/pk/asn1/der/printable_string/der_encode_printable_string.c @@ -47,23 +47,11 @@ int der_encode_printable_string(const unsigned char *in, unsigned long inlen, /* encode the header+len */ x = 0; out[x++] = 0x13; - if (inlen < 128) { - out[x++] = (unsigned char)inlen; - } else if (inlen < 256) { - out[x++] = 0x81; - out[x++] = (unsigned char)inlen; - } else if (inlen < 65536UL) { - out[x++] = 0x82; - out[x++] = (unsigned char)((inlen>>8)&255); - out[x++] = (unsigned char)(inlen&255); - } else if (inlen < 16777216UL) { - out[x++] = 0x83; - out[x++] = (unsigned char)((inlen>>16)&255); - out[x++] = (unsigned char)((inlen>>8)&255); - out[x++] = (unsigned char)(inlen&255); - } else { - return CRYPT_INVALID_ARG; + len = *outlen - x; + if ((err = der_encode_asn1_length(inlen, out + x, &len)) != CRYPT_OK) { + return err; } + x += len; /* store octets */ for (y = 0; y < inlen; y++) { diff --git a/src/ltc/pk/asn1/der/printable_string/der_length_printable_string.c b/src/ltc/pk/asn1/der/printable_string/der_length_printable_string.c index 40f0beb4..b6eb8502 100644 --- a/src/ltc/pk/asn1/der/printable_string/der_length_printable_string.c +++ b/src/ltc/pk/asn1/der/printable_string/der_length_printable_string.c @@ -126,6 +126,7 @@ int der_printable_value_decode(int v) int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen) { unsigned long x; + int err; LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(octets != NULL); @@ -137,21 +138,10 @@ int der_length_printable_string(const unsigned char *octets, unsigned long nocte } } - if (noctets < 128) { - /* 16 LL DD DD DD ... */ - *outlen = 2 + noctets; - } else if (noctets < 256) { - /* 16 81 LL DD DD DD ... */ - *outlen = 3 + noctets; - } else if (noctets < 65536UL) { - /* 16 82 LL LL DD DD DD ... */ - *outlen = 4 + noctets; - } else if (noctets < 16777216UL) { - /* 16 83 LL LL LL DD DD DD ... */ - *outlen = 5 + noctets; - } else { - return CRYPT_INVALID_ARG; + if ((err = der_length_asn1_length(noctets, &x)) != CRYPT_OK) { + return err; } + *outlen = 1 + x + noctets; return CRYPT_OK; } diff --git a/src/ltc/pk/asn1/der/sequence/der_decode_sequence_ex.c b/src/ltc/pk/asn1/der/sequence/der_decode_sequence_ex.c index b1473819..10cfd218 100644 --- a/src/ltc/pk/asn1/der/sequence/der_decode_sequence_ex.c +++ b/src/ltc/pk/asn1/der/sequence/der_decode_sequence_ex.c @@ -22,317 +22,13 @@ @param inlen The size of the input @param list The list of items to decode @param outlen The number of items in the list - @param ordered Search an unordeded or ordered list + @param flags c.f. enum ltc_der_seq @return CRYPT_OK on success */ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, - ltc_asn1_list *list, unsigned long outlen, int ordered) + ltc_asn1_list *list, unsigned long outlen, unsigned int flags) { - int err, i; - ltc_asn1_type type; - unsigned long size, x, y, z, blksize; - void *data; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(list != NULL); - - /* get blk size */ - if (inlen < 2) { - return CRYPT_INVALID_PACKET; - } - - /* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */ - x = 0; - if (in[x] != 0x30 && in[x] != 0x31) { - return CRYPT_INVALID_PACKET; - } - ++x; - - /* check if the msb is set, which signals that the - * 7 lsb bits represent the number of bytes of the length - */ - if (in[x] < 128) { - blksize = in[x++]; - } else { - if (in[x] < 0x81 || in[x] > 0x83) { - return CRYPT_INVALID_PACKET; - } - y = in[x++] & 0x7F; - - /* would reading the len bytes overrun? */ - if (x + y > inlen) { - return CRYPT_INVALID_PACKET; - } - - /* read len */ - blksize = 0; - while (y--) { - blksize = (blksize << 8) | (unsigned long)in[x++]; - } - } - - /* would this blksize overflow? */ - if (x + blksize > inlen) { - return CRYPT_INVALID_PACKET; - } - - /* mark all as unused */ - for (i = 0; i < (int)outlen; i++) { - list[i].used = 0; - } - - /* ok read data */ - inlen = blksize; - for (i = 0; i < (int)outlen; i++) { - z = 0; - type = list[i].type; - size = list[i].size; - data = list[i].data; - if (!ordered && list[i].used == 1) { continue; } - - if (type == LTC_ASN1_EOL) { - break; - } - - /* handle context specific tags - just skip the tag + len bytes */ - z = 0; - if (list[i].tag > 0 && list[i].tag == in[x + z++]) { - if (in[x+z] & 0x80) { - y = in[x + z++] & 0x7F; - if (y == 0 || y > 2) { return CRYPT_INVALID_PACKET; } - z += y; - } else { - z++; - } - x += z; - inlen -= z; - } - - switch (type) { - case LTC_ASN1_BOOLEAN: - z = inlen; - if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) { - if (!ordered || list[i].optional) { continue; } - goto LBL_ERR; - } - if ((err = der_length_boolean(&z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - case LTC_ASN1_INTEGER: - z = inlen; - if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) { - if (!ordered || list[i].optional) { continue; } - goto LBL_ERR; - } - if ((err = der_length_integer(data, &z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - case LTC_ASN1_SHORT_INTEGER: - z = inlen; - if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) { - if (!ordered || list[i].optional) { continue; } - goto LBL_ERR; - } - if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) { - goto LBL_ERR; - } - - break; - - case LTC_ASN1_BIT_STRING: - z = inlen; - if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) { - if (!ordered || list[i].optional) { continue; } - goto LBL_ERR; - } - list[i].size = size; - if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - case LTC_ASN1_RAW_BIT_STRING: - z = inlen; - if ((err = der_decode_raw_bit_string(in + x, z, data, &size)) != CRYPT_OK) { - if (!ordered || list[i].optional) { continue; } - goto LBL_ERR; - } - list[i].size = size; - if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - case LTC_ASN1_OCTET_STRING: - z = inlen; - if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) { - if (!ordered || list[i].optional) { continue; } - goto LBL_ERR; - } - list[i].size = size; - if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - case LTC_ASN1_NULL: - if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) { - if (!ordered || list[i].optional) { continue; } - err = CRYPT_INVALID_PACKET; - goto LBL_ERR; - } - z = 2; - break; - - case LTC_ASN1_OBJECT_IDENTIFIER: - z = inlen; - if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) { - if (!ordered || list[i].optional) { continue; } - goto LBL_ERR; - } - list[i].size = size; - if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - case LTC_ASN1_TELETEX_STRING: - z = inlen; - if ((err = der_decode_teletex_string(in + x, z, data, &size)) != CRYPT_OK) { - if (!ordered || list[i].optional) { continue; } - goto LBL_ERR; - } - list[i].size = size; - if ((err = der_length_teletex_string(data, size, &z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - case LTC_ASN1_IA5_STRING: - z = inlen; - if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) { - if (!ordered || list[i].optional) { continue; } - goto LBL_ERR; - } - list[i].size = size; - if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - - case LTC_ASN1_PRINTABLE_STRING: - z = inlen; - if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) { - if (!ordered || list[i].optional) { continue; } - goto LBL_ERR; - } - list[i].size = size; - if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - case LTC_ASN1_UTF8_STRING: - z = inlen; - if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) { - if (!ordered || list[i].optional) { continue; } - goto LBL_ERR; - } - list[i].size = size; - if ((err = der_length_utf8_string(data, size, &z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - case LTC_ASN1_UTCTIME: - z = inlen; - if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) { - if (!ordered || list[i].optional) { continue; } - goto LBL_ERR; - } - break; - - case LTC_ASN1_GENERALIZEDTIME: - z = inlen; - if ((err = der_decode_generalizedtime(in + x, &z, data)) != CRYPT_OK) { - if (!ordered) { continue; } - goto LBL_ERR; - } - break; - - case LTC_ASN1_SET: - z = inlen; - if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) { - if (!ordered || list[i].optional) { continue; } - goto LBL_ERR; - } - if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - case LTC_ASN1_SETOF: - case LTC_ASN1_SEQUENCE: - /* detect if we have the right type */ - if ((type == LTC_ASN1_SETOF && (in[x] & 0x3F) != 0x31) || (type == LTC_ASN1_SEQUENCE && (in[x] & 0x3F) != 0x30)) { - err = CRYPT_INVALID_PACKET; - goto LBL_ERR; - } - - z = inlen; - if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) { - if (!ordered || list[i].optional) { continue; } - goto LBL_ERR; - } - if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - - case LTC_ASN1_CHOICE: - z = inlen; - if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) { - if (!ordered || list[i].optional) { continue; } - goto LBL_ERR; - } - break; - - case LTC_ASN1_CONSTRUCTED: - case LTC_ASN1_CONTEXT_SPECIFIC: - case LTC_ASN1_EOL: - err = CRYPT_INVALID_ARG; - goto LBL_ERR; - } - x += z; - inlen -= z; - list[i].used = 1; - if (!ordered) { - /* restart the decoder */ - i = -1; - } - } - - for (i = 0; i < (int)outlen; i++) { - if (list[i].used == 0 && list[i].optional == 0) { - err = CRYPT_INVALID_PACKET; - goto LBL_ERR; - } - } - - if (inlen == 0) { - err = CRYPT_OK; - } else { - err = CRYPT_INPUT_TOO_LONG; - } - -LBL_ERR: - return err; + return der_decode_custom_type_ex(in, inlen, NULL, list, outlen, flags); } #endif diff --git a/src/ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.c b/src/ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.c index 142ef95a..44c9c478 100644 --- a/src/ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.c +++ b/src/ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.c @@ -15,42 +15,6 @@ #ifdef LTC_DER -static unsigned long _fetch_length(const unsigned char *in, unsigned long inlen, unsigned long *data_offset) -{ - unsigned long x, z; - - *data_offset = 0; - - /* skip type and read len */ - if (inlen < 2) { - return 0xFFFFFFFF; - } - ++in; ++(*data_offset); - - /* read len */ - x = *in++; ++(*data_offset); - - /* <128 means literal */ - if (x < 128) { - return x+*data_offset; - } - x &= 0x7F; /* the lower 7 bits are the length of the length */ - inlen -= 2; - - /* len means len of len! */ - if (x == 0 || x > 4 || x > inlen) { - return 0xFFFFFFFF; - } - - *data_offset += x; - z = 0; - while (x--) { - z = (z<<8) | ((unsigned long)*in); - ++in; - } - return z+*data_offset; -} - static int _new_element(ltc_asn1_list **l) { /* alloc new link */ @@ -80,7 +44,7 @@ static int _new_element(ltc_asn1_list **l) int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out) { ltc_asn1_list *l; - unsigned long err, type, len, totlen, data_offset; + unsigned long err, identifier, len, totlen, data_offset, id_len, len_len; void *realloc_tmp; LTC_ARGCHK(in != NULL); @@ -99,38 +63,77 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc /* scan the input and and get lengths and what not */ while (*inlen) { - /* read the type byte */ - type = *in; - - /* fetch length */ - len = _fetch_length(in, *inlen, &data_offset); - if (len > *inlen) { - err = CRYPT_INVALID_PACKET; - goto error; - } - /* alloc new link */ if ((err = _new_element(&l)) != CRYPT_OK) { goto error; } - if ((type & 0x20) && (type != 0x30) && (type != 0x31)) { - /* constructed, use the 'used' field to store the original identifier */ - l->used = type; - /* treat constructed elements like SETs */ - type = 0x20; + id_len = *inlen; + if ((err = der_decode_asn1_identifier(in, &id_len, l)) != CRYPT_OK) { + goto error; } - else if ((type & 0xC0) == 0x80) { - /* context-specific, use the 'used' field to store the original identifier */ - l->used = type; - /* context-specific elements are treated as opaque data */ - type = 0x80; + /* read the type byte */ + identifier = *in; + + if (l->type != LTC_ASN1_EOL) { + /* fetch length */ + len_len = *inlen - id_len; +#if defined(LTC_TEST_DBG) + data_offset = 666; + len = 0; +#endif + if ((err = der_decode_asn1_length(&in[id_len], &len_len, &len)) != CRYPT_OK) { +#if defined(LTC_TEST_DBG) + fprintf(stderr, "E1 %02lx: hl=%4lu l=%4lu - %s (%s)\n", identifier, data_offset, len, der_asn1_tag_to_string_map[l->tag], error_to_string(err)); +#endif + goto error; + } else if (len > (*inlen - id_len - len_len)) { + err = CRYPT_INVALID_PACKET; +#if defined(LTC_TEST_DBG) + fprintf(stderr, "E2 %02lx: hl=%4lu l=%4lu - %s (%s)\n", identifier, data_offset, len, der_asn1_tag_to_string_map[l->tag], error_to_string(err)); +#endif + goto error; + } + data_offset = id_len + len_len; +#if defined(LTC_TEST_DBG) && LTC_TEST_DBG > 1 + if (l->type == LTC_ASN1_CUSTOM_TYPE && l->class == LTC_ASN1_CL_CONTEXT_SPECIFIC) { + fprintf(stderr, "OK %02lx: hl=%4lu l=%4lu - Context Specific[%s %llu]\n", identifier, data_offset, len, der_asn1_pc_to_string_map[l->pc], l->tag); + } else { + fprintf(stderr, "OK %02lx: hl=%4lu l=%4lu - %s\n", identifier, data_offset, len, der_asn1_tag_to_string_map[l->tag]); + } +#endif + len += data_offset; + + if (l->type == LTC_ASN1_CUSTOM_TYPE) { + /* Custom type, use the 'used' field to store the original identifier */ + l->used = identifier; + if (l->pc == LTC_ASN1_PC_CONSTRUCTED) { + /* treat constructed elements like SEQUENCEs */ + identifier = 0x20; + } else { + /* primitive elements are treated as opaque data */ + identifier = 0x80; + } + } + } else { + /* Init this so gcc won't complain, + * as this case will only be hit when we + * can't decode the identifier so the + * switch-case should go to default anyway... + */ + data_offset = 0; + len = 0; } /* now switch on type */ - switch (type) { + switch (identifier) { case 0x01: /* BOOLEAN */ - l->type = LTC_ASN1_BOOLEAN; + if (l->type != LTC_ASN1_BOOLEAN) { + err = CRYPT_PK_ASN1_ERROR; + goto error; + } + + /* init field */ l->size = 1; l->data = XCALLOC(1, sizeof(int)); @@ -144,8 +147,12 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc break; case 0x02: /* INTEGER */ + if (l->type != LTC_ASN1_INTEGER) { + err = CRYPT_PK_ASN1_ERROR; + goto error; + } + /* init field */ - l->type = LTC_ASN1_INTEGER; l->size = 1; if ((err = mp_init(&l->data)) != CRYPT_OK) { goto error; @@ -163,8 +170,12 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc break; case 0x03: /* BIT */ + if (l->type != LTC_ASN1_BIT_STRING) { + err = CRYPT_PK_ASN1_ERROR; + goto error; + } + /* init field */ - l->type = LTC_ASN1_BIT_STRING; l->size = len * 8; /* *8 because we store decoded bits one per char and they are encoded 8 per char. */ if ((l->data = XCALLOC(1, l->size)) == NULL) { @@ -182,9 +193,12 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc break; case 0x04: /* OCTET */ + if (l->type != LTC_ASN1_OCTET_STRING) { + err = CRYPT_PK_ASN1_ERROR; + goto error; + } /* init field */ - l->type = LTC_ASN1_OCTET_STRING; l->size = len; if ((l->data = XCALLOC(1, l->size)) == NULL) { @@ -202,6 +216,10 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc break; case 0x05: /* NULL */ + if (l->type != LTC_ASN1_NULL) { + err = CRYPT_PK_ASN1_ERROR; + goto error; + } /* valid NULL is 0x05 0x00 */ if (in[0] != 0x05 || in[1] != 0x00) { @@ -210,7 +228,6 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc } /* simple to store ;-) */ - l->type = LTC_ASN1_NULL; l->data = NULL; l->size = 0; len = 2; @@ -218,9 +235,12 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc break; case 0x06: /* OID */ + if (l->type != LTC_ASN1_OBJECT_IDENTIFIER) { + err = CRYPT_PK_ASN1_ERROR; + goto error; + } /* init field */ - l->type = LTC_ASN1_OBJECT_IDENTIFIER; l->size = len; if ((l->data = XCALLOC(len, sizeof(unsigned long))) == NULL) { @@ -247,7 +267,10 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc case 0x0C: /* UTF8 */ /* init field */ - l->type = LTC_ASN1_UTF8_STRING; + if (l->type != LTC_ASN1_UTF8_STRING) { + err = CRYPT_PK_ASN1_ERROR; + goto error; + } l->size = len; if ((l->data = XCALLOC(sizeof(wchar_t), l->size)) == NULL) { @@ -265,9 +288,12 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc break; case 0x13: /* PRINTABLE */ + if (l->type != LTC_ASN1_PRINTABLE_STRING) { + err = CRYPT_PK_ASN1_ERROR; + goto error; + } /* init field */ - l->type = LTC_ASN1_PRINTABLE_STRING; l->size = len; if ((l->data = XCALLOC(1, l->size)) == NULL) { @@ -285,9 +311,12 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc break; case 0x14: /* TELETEXT */ + if (l->type != LTC_ASN1_TELETEX_STRING) { + err = CRYPT_PK_ASN1_ERROR; + goto error; + } /* init field */ - l->type = LTC_ASN1_TELETEX_STRING; l->size = len; if ((l->data = XCALLOC(1, l->size)) == NULL) { @@ -305,9 +334,12 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc break; case 0x16: /* IA5 */ + if (l->type != LTC_ASN1_IA5_STRING) { + err = CRYPT_PK_ASN1_ERROR; + goto error; + } /* init field */ - l->type = LTC_ASN1_IA5_STRING; l->size = len; if ((l->data = XCALLOC(1, l->size)) == NULL) { @@ -325,9 +357,12 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc break; case 0x17: /* UTC TIME */ + if (l->type != LTC_ASN1_UTCTIME) { + err = CRYPT_PK_ASN1_ERROR; + goto error; + } /* init field */ - l->type = LTC_ASN1_UTCTIME; l->size = 1; if ((l->data = XCALLOC(1, sizeof(ltc_utctime))) == NULL) { @@ -346,7 +381,12 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc break; case 0x18: - l->type = LTC_ASN1_GENERALIZEDTIME; + if (l->type != LTC_ASN1_GENERALIZEDTIME) { + err = CRYPT_PK_ASN1_ERROR; + goto error; + } + + /* init field */ l->size = len; if ((l->data = XCALLOC(1, sizeof(ltc_generalizedtime))) == NULL) { @@ -369,14 +409,23 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc case 0x31: /* SET */ /* init field */ - if (type == 0x20) { - l->type = LTC_ASN1_CONSTRUCTED; + if (identifier == 0x20) { + if (l->type != LTC_ASN1_CUSTOM_TYPE) { + err = CRYPT_PK_ASN1_ERROR; + goto error; + } } - else if (type == 0x30) { - l->type = LTC_ASN1_SEQUENCE; + else if (identifier == 0x30) { + if (l->type != LTC_ASN1_SEQUENCE) { + err = CRYPT_PK_ASN1_ERROR; + goto error; + } } else { - l->type = LTC_ASN1_SET; + if (l->type != LTC_ASN1_SET) { + err = CRYPT_PK_ASN1_ERROR; + goto error; + } } if ((l->data = XMALLOC(len)) == NULL) { @@ -391,12 +440,19 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc /* jump to the start of the data */ in += data_offset; *inlen -= data_offset; - len = len - data_offset; + len -= data_offset; + + /* save the decoded ASN.1 len */ + len_len = len; /* Sequence elements go as child */ if ((err = der_decode_sequence_flexi(in, &len, &(l->child))) != CRYPT_OK) { goto error; } + if (len_len != len) { + err = CRYPT_PK_ASN1_ERROR; + goto error; + } /* len update */ totlen += data_offset; @@ -410,7 +466,10 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc break; case 0x80: /* Context-specific */ - l->type = LTC_ASN1_CONTEXT_SPECIFIC; + if (l->type != LTC_ASN1_CUSTOM_TYPE) { + err = CRYPT_PK_ASN1_ERROR; + goto error; + } if ((l->data = XCALLOC(1, len - data_offset)) == NULL) { err = CRYPT_MEM; diff --git a/src/ltc/pk/asn1/der/sequence/der_decode_sequence_multi.c b/src/ltc/pk/asn1/der/sequence/der_decode_sequence_multi.c index 1361b761..280d7cdb 100644 --- a/src/ltc/pk/asn1/der/sequence/der_decode_sequence_multi.c +++ b/src/ltc/pk/asn1/der/sequence/der_decode_sequence_multi.c @@ -21,27 +21,27 @@ Decode a SEQUENCE type using a VA list @param in Input buffer @param inlen Length of input in octets - @remark <...> is of the form <type, size, data> (int, unsigned long, void*) + @param a1 Initialized argument list #1 + @param a2 Initialized argument list #2 (copy of #1) + @param flags c.f. enum ltc_der_seq @return CRYPT_OK on success */ -int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) +static int _der_decode_sequence_va(const unsigned char *in, unsigned long inlen, va_list a1, va_list a2, unsigned int flags) { int err; ltc_asn1_type type; unsigned long size, x; void *data; - va_list args; ltc_asn1_list *list; LTC_ARGCHK(in != NULL); /* get size of output that will be required */ - va_start(args, inlen); x = 0; for (;;) { - type = (ltc_asn1_type)va_arg(args, int); - size = va_arg(args, unsigned long); - data = va_arg(args, void*); + type = (ltc_asn1_type)va_arg(a1, int); + size = va_arg(a1, unsigned long); + data = va_arg(a1, void*); LTC_UNUSED_PARAM(size); LTC_UNUSED_PARAM(data); @@ -72,13 +72,10 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) break; case LTC_ASN1_EOL: - case LTC_ASN1_CONSTRUCTED: - case LTC_ASN1_CONTEXT_SPECIFIC: - va_end(args); + case LTC_ASN1_CUSTOM_TYPE: return CRYPT_INVALID_ARG; } } - va_end(args); /* allocate structure for x elements */ if (x == 0) { @@ -91,12 +88,11 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) } /* fill in the structure */ - va_start(args, inlen); x = 0; for (;;) { - type = (ltc_asn1_type)va_arg(args, int); - size = va_arg(args, unsigned long); - data = va_arg(args, void*); + type = (ltc_asn1_type)va_arg(a2, int); + size = va_arg(a2, unsigned long); + data = va_arg(a2, void*); if (type == LTC_ASN1_EOL) { break; @@ -125,18 +121,67 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) break; /* coverity[dead_error_line] */ case LTC_ASN1_EOL: - case LTC_ASN1_CONSTRUCTED: - case LTC_ASN1_CONTEXT_SPECIFIC: + case LTC_ASN1_CUSTOM_TYPE: break; } } - va_end(args); - err = der_decode_sequence(in, inlen, list, x); + err = der_decode_sequence_ex(in, inlen, list, x, flags); XFREE(list); return err; } +/** + Decode a SEQUENCE type using a VA list + @param in Input buffer + @param inlen Length of input in octets + @remark <...> is of the form <type, size, data> (int, unsigned long, void*) + @return CRYPT_OK on success +*/ +int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) +{ + va_list a1, a2; + int err; + + LTC_ARGCHK(in != NULL); + + va_start(a1, inlen); + va_start(a2, inlen); + + err = _der_decode_sequence_va(in, inlen, a1, a2, LTC_DER_SEQ_SEQUENCE | LTC_DER_SEQ_RELAXED); + + va_end(a2); + va_end(a1); + + return err; +} + +/** + Decode a SEQUENCE type using a VA list + @param in Input buffer + @param inlen Length of input in octets + @param flags c.f. enum ltc_der_seq + @remark <...> is of the form <type, size, data> (int, unsigned long, void*) + @return CRYPT_OK on success +*/ +int der_decode_sequence_multi_ex(const unsigned char *in, unsigned long inlen, unsigned int flags, ...) +{ + va_list a1, a2; + int err; + + LTC_ARGCHK(in != NULL); + + va_start(a1, flags); + va_start(a2, flags); + + err = _der_decode_sequence_va(in, inlen, a1, a2, flags); + + va_end(a2); + va_end(a1); + + return err; +} + #endif diff --git a/src/ltc/pk/asn1/der/sequence/der_encode_sequence_ex.c b/src/ltc/pk/asn1/der/sequence/der_encode_sequence_ex.c index d8ad196c..1a5d9681 100644 --- a/src/ltc/pk/asn1/der/sequence/der_encode_sequence_ex.c +++ b/src/ltc/pk/asn1/der/sequence/der_encode_sequence_ex.c @@ -31,7 +31,6 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, int err; ltc_asn1_type type; unsigned long size, x, y, z, i; - unsigned char tmptag[6]; void *data; LTC_ARGCHK(list != NULL); @@ -53,21 +52,11 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, x = 0; out[x++] = (type_of == LTC_ASN1_SEQUENCE) ? 0x30 : 0x31; - if (z < 128) { - out[x++] = (unsigned char)z; - } else if (z < 256) { - out[x++] = 0x81; - out[x++] = (unsigned char)z; - } else if (z < 65536UL) { - out[x++] = 0x82; - out[x++] = (unsigned char)((z>>8UL)&255); - out[x++] = (unsigned char)(z&255); - } else if (z < 16777216UL) { - out[x++] = 0x83; - out[x++] = (unsigned char)((z>>16UL)&255); - out[x++] = (unsigned char)((z>>8UL)&255); - out[x++] = (unsigned char)(z&255); + y = *outlen - x; + if ((err = der_encode_asn1_length(z, &out[x], &y)) != CRYPT_OK) { + goto LBL_ERR; } + x += y; /* store data */ *outlen -= x; @@ -192,43 +181,20 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, } break; + case LTC_ASN1_CUSTOM_TYPE: + z = *outlen; + if ((err = der_encode_custom_type(&list[i], out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + case LTC_ASN1_CHOICE: - case LTC_ASN1_CONSTRUCTED: - case LTC_ASN1_CONTEXT_SPECIFIC: case LTC_ASN1_EOL: case LTC_ASN1_TELETEX_STRING: err = CRYPT_INVALID_ARG; goto LBL_ERR; } - if (list[i].tag > 0) { - tmptag[0] = list[i].tag; - y = 0; - if (z < 128) { - tmptag[1] = (unsigned char)z; - y = 2; - } else if (z < 256) { - tmptag[1] = 0x81; - tmptag[2] = (unsigned char)z; - y = 3; - } else if (z < 65536UL) { - tmptag[1] = 0x82; - tmptag[2] = (unsigned char)((z>>8UL)&255); - tmptag[3] = (unsigned char)(z&255); - y = 4; - } else if (z < 16777216UL) { - tmptag[1] = 0x83; - tmptag[2] = (unsigned char)((z>>16UL)&255); - tmptag[3] = (unsigned char)((z>>8UL)&255); - tmptag[4] = (unsigned char)(z&255); - y = 5; - } - XMEMMOVE(out + x + y, out + x, z); - XMEMCPY(out + x, tmptag, y); - - z += y; - } - x += z; *outlen -= z; } diff --git a/src/ltc/pk/asn1/der/sequence/der_encode_sequence_multi.c b/src/ltc/pk/asn1/der/sequence/der_encode_sequence_multi.c index c1b40c77..c8ec59a9 100644 --- a/src/ltc/pk/asn1/der/sequence/der_encode_sequence_multi.c +++ b/src/ltc/pk/asn1/der/sequence/der_encode_sequence_multi.c @@ -71,8 +71,7 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) break; case LTC_ASN1_CHOICE: - case LTC_ASN1_CONSTRUCTED: - case LTC_ASN1_CONTEXT_SPECIFIC: + case LTC_ASN1_CUSTOM_TYPE: case LTC_ASN1_EOL: case LTC_ASN1_TELETEX_STRING: va_end(args); @@ -124,8 +123,7 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) break; case LTC_ASN1_CHOICE: - case LTC_ASN1_CONSTRUCTED: - case LTC_ASN1_CONTEXT_SPECIFIC: + case LTC_ASN1_CUSTOM_TYPE: case LTC_ASN1_EOL: case LTC_ASN1_TELETEX_STRING: va_end(args); diff --git a/src/ltc/pk/asn1/der/sequence/der_length_sequence.c b/src/ltc/pk/asn1/der/sequence/der_length_sequence.c index 7908c5b3..a80f96b0 100644 --- a/src/ltc/pk/asn1/der/sequence/der_length_sequence.c +++ b/src/ltc/pk/asn1/der/sequence/der_length_sequence.c @@ -33,7 +33,7 @@ int der_length_sequence_ex(ltc_asn1_list *list, unsigned long inlen, { int err; ltc_asn1_type type; - unsigned long size, x, y, i, z; + unsigned long size, x, y, i; void *data; LTC_ARGCHK(list != NULL); @@ -143,6 +143,13 @@ int der_length_sequence_ex(ltc_asn1_list *list, unsigned long inlen, y += x; break; + case LTC_ASN1_CUSTOM_TYPE: + if ((err = der_length_custom_type(&list[i], &x, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + case LTC_ASN1_SET: case LTC_ASN1_SETOF: case LTC_ASN1_SEQUENCE: @@ -152,53 +159,23 @@ int der_length_sequence_ex(ltc_asn1_list *list, unsigned long inlen, y += x; break; - case LTC_ASN1_CHOICE: - case LTC_ASN1_CONSTRUCTED: - case LTC_ASN1_CONTEXT_SPECIFIC: case LTC_ASN1_EOL: err = CRYPT_INVALID_ARG; goto LBL_ERR; } - - /* handle context specific tags size */ - if (list[i].tag > 0) { - if (x < 128) { - y += 2; - } else if (x < 256) { - y += 3; - } else if (x < 65536UL) { - y += 4; - } else if (x < 16777216UL) { - y += 5; - } else { - err = CRYPT_INVALID_ARG; - goto LBL_ERR; - } - } } - /* calc header size */ - z = y; - if (y < 128) { - y += 2; - } else if (y < 256) { - /* 0x30 0x81 LL */ - y += 3; - } else if (y < 65536UL) { - /* 0x30 0x82 LL LL */ - y += 4; - } else if (y < 16777216UL) { - /* 0x30 0x83 LL LL LL */ - y += 5; - } else { - err = CRYPT_INVALID_ARG; + if ((err = der_length_asn1_length(y, &x)) != CRYPT_OK) { goto LBL_ERR; } + if (payloadlen != NULL) { + *payloadlen = y; + } + /* store size */ - if (payloadlen) *payloadlen = z; - *outlen = y; + *outlen = y + x + 1; err = CRYPT_OK; LBL_ERR: diff --git a/src/ltc/pk/asn1/der/sequence/der_sequence_shrink.c b/src/ltc/pk/asn1/der/sequence/der_sequence_shrink.c index 9b9e036a..fdfe91bb 100644 --- a/src/ltc/pk/asn1/der/sequence/der_sequence_shrink.c +++ b/src/ltc/pk/asn1/der/sequence/der_sequence_shrink.c @@ -32,7 +32,7 @@ void der_sequence_shrink(ltc_asn1_list *in) } switch (in->type) { - case LTC_ASN1_CONSTRUCTED: + case LTC_ASN1_CUSTOM_TYPE: case LTC_ASN1_SET: case LTC_ASN1_SEQUENCE : if (in->data != NULL) { XFREE(in->data); in->data = NULL; } break; default: break; diff --git a/src/ltc/pk/asn1/der/set/der_encode_set.c b/src/ltc/pk/asn1/der/set/der_encode_set.c index fef3092b..a3485f2d 100644 --- a/src/ltc/pk/asn1/der/set/der_encode_set.c +++ b/src/ltc/pk/asn1/der/set/der_encode_set.c @@ -18,30 +18,7 @@ /* LTC define to ASN.1 TAG */ static int _ltc_to_asn1(ltc_asn1_type v) { - switch (v) { - case LTC_ASN1_BOOLEAN: return 0x01; - case LTC_ASN1_INTEGER: - case LTC_ASN1_SHORT_INTEGER: return 0x02; - case LTC_ASN1_RAW_BIT_STRING: - case LTC_ASN1_BIT_STRING: return 0x03; - case LTC_ASN1_OCTET_STRING: return 0x04; - case LTC_ASN1_NULL: return 0x05; - case LTC_ASN1_OBJECT_IDENTIFIER: return 0x06; - case LTC_ASN1_UTF8_STRING: return 0x0C; - case LTC_ASN1_PRINTABLE_STRING: return 0x13; - case LTC_ASN1_TELETEX_STRING: return 0x14; - case LTC_ASN1_IA5_STRING: return 0x16; - case LTC_ASN1_UTCTIME: return 0x17; - case LTC_ASN1_GENERALIZEDTIME: return 0x18; - case LTC_ASN1_SEQUENCE: return 0x30; - case LTC_ASN1_SET: - case LTC_ASN1_SETOF: return 0x31; - case LTC_ASN1_CHOICE: - case LTC_ASN1_CONSTRUCTED: - case LTC_ASN1_CONTEXT_SPECIFIC: - case LTC_ASN1_EOL: return -1; - } - return -1; + return der_asn1_type_to_identifier_map[v]; } diff --git a/src/ltc/pk/asn1/der/short_integer/der_length_short_integer.c b/src/ltc/pk/asn1/der/short_integer/der_length_short_integer.c index 52d0e1ae..8c1de289 100644 --- a/src/ltc/pk/asn1/der/short_integer/der_length_short_integer.c +++ b/src/ltc/pk/asn1/der/short_integer/der_length_short_integer.c @@ -23,7 +23,8 @@ */ int der_length_short_integer(unsigned long num, unsigned long *outlen) { - unsigned long z, y, len; + unsigned long z, y; + int err; LTC_ARGCHK(outlen != NULL); @@ -41,22 +42,15 @@ int der_length_short_integer(unsigned long num, unsigned long *outlen) /* handle zero */ if (z == 0) { z = 1; + } else if ((num&(1UL<<((z<<3) - 1))) != 0) { + /* in case msb is set */ + ++z; } - /* we need a 0x02 to indicate it's INTEGER */ - len = 1; - - /* length byte */ - ++len; - - /* bytes in value */ - len += z; - - /* see if msb is set */ - len += (num&(1UL<<((z<<3) - 1))) ? 1 : 0; - - /* return length */ - *outlen = len; + if ((err = der_length_asn1_length(z, &y)) != CRYPT_OK) { + return err; + } + *outlen = 1 + y + z; return CRYPT_OK; } diff --git a/src/ltc/pk/asn1/der/teletex_string/der_decode_teletex_string.c b/src/ltc/pk/asn1/der/teletex_string/der_decode_teletex_string.c index 0c7c3c8f..cd530a2b 100644 --- a/src/ltc/pk/asn1/der/teletex_string/der_decode_teletex_string.c +++ b/src/ltc/pk/asn1/der/teletex_string/der_decode_teletex_string.c @@ -27,7 +27,7 @@ int der_decode_teletex_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { unsigned long x, y, len; - int t; + int t, err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); @@ -44,23 +44,12 @@ int der_decode_teletex_string(const unsigned char *in, unsigned long inlen, } x = 1; - /* decode the length */ - if (in[x] & 0x80) { - /* valid # of bytes in length are 1,2,3 */ - y = in[x] & 0x7F; - if ((y == 0) || (y > 3) || ((x + y) > inlen)) { - return CRYPT_INVALID_PACKET; - } - - /* read the length in */ - len = 0; - ++x; - while (y--) { - len = (len << 8) | in[x++]; - } - } else { - len = in[x++] & 0x7F; + /* get the length of the data */ + y = inlen - x; + if ((err = der_decode_asn1_length(in + x, &y, &len)) != CRYPT_OK) { + return err; } + x += y; /* is it too long? */ if (len > *outlen) { @@ -68,7 +57,7 @@ int der_decode_teletex_string(const unsigned char *in, unsigned long inlen, return CRYPT_BUFFER_OVERFLOW; } - if (len + x > inlen) { + if (len > (inlen - x)) { return CRYPT_INVALID_PACKET; } diff --git a/src/ltc/pk/asn1/der/teletex_string/der_length_teletex_string.c b/src/ltc/pk/asn1/der/teletex_string/der_length_teletex_string.c index 29fe5b0b..a35c6d76 100644 --- a/src/ltc/pk/asn1/der/teletex_string/der_length_teletex_string.c +++ b/src/ltc/pk/asn1/der/teletex_string/der_length_teletex_string.c @@ -170,6 +170,7 @@ int der_teletex_value_decode(int v) int der_length_teletex_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen) { unsigned long x; + int err; LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(octets != NULL); @@ -181,21 +182,10 @@ int der_length_teletex_string(const unsigned char *octets, unsigned long noctets } } - if (noctets < 128) { - /* 16 LL DD DD DD ... */ - *outlen = 2 + noctets; - } else if (noctets < 256) { - /* 16 81 LL DD DD DD ... */ - *outlen = 3 + noctets; - } else if (noctets < 65536UL) { - /* 16 82 LL LL DD DD DD ... */ - *outlen = 4 + noctets; - } else if (noctets < 16777216UL) { - /* 16 83 LL LL LL DD DD DD ... */ - *outlen = 5 + noctets; - } else { - return CRYPT_INVALID_ARG; + if ((err = der_length_asn1_length(noctets, &x)) != CRYPT_OK) { + return err; } + *outlen = 1 + x + noctets; return CRYPT_OK; } diff --git a/src/ltc/pk/asn1/der/utf8/der_decode_utf8_string.c b/src/ltc/pk/asn1/der/utf8/der_decode_utf8_string.c index d857ce95..c86d6603 100644 --- a/src/ltc/pk/asn1/der/utf8/der_decode_utf8_string.c +++ b/src/ltc/pk/asn1/der/utf8/der_decode_utf8_string.c @@ -29,6 +29,7 @@ int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, { wchar_t tmp; unsigned long x, y, z, len; + int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); @@ -45,25 +46,14 @@ int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, } x = 1; - /* decode the length */ - if (in[x] & 0x80) { - /* valid # of bytes in length are 1,2,3 */ - y = in[x] & 0x7F; - if ((y == 0) || (y > 3) || ((x + y) > inlen)) { - return CRYPT_INVALID_PACKET; - } - - /* read the length in */ - len = 0; - ++x; - while (y--) { - len = (len << 8) | in[x++]; - } - } else { - len = in[x++] & 0x7F; + /* get the length of the data */ + y = inlen - x; + if ((err = der_decode_asn1_length(in + x, &y, &len)) != CRYPT_OK) { + return err; } + x += y; - if (len + x > inlen) { + if (len > (inlen - x)) { return CRYPT_INVALID_PACKET; } @@ -91,15 +81,19 @@ int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, tmp = (tmp << 6) | ((wchar_t)in[x++] & 0x3F); } - if (y > *outlen) { - *outlen = y; - return CRYPT_BUFFER_OVERFLOW; + if (y < *outlen) { + out[y] = tmp; } - out[y++] = tmp; + y++; + } + if (y > *outlen) { + err = CRYPT_BUFFER_OVERFLOW; + } else { + err = CRYPT_OK; } *outlen = y; - return CRYPT_OK; + return err; } #endif diff --git a/src/ltc/pk/asn1/der/utf8/der_encode_utf8_string.c b/src/ltc/pk/asn1/der/utf8/der_encode_utf8_string.c index 63ad840f..1c6e09b5 100644 --- a/src/ltc/pk/asn1/der/utf8/der_encode_utf8_string.c +++ b/src/ltc/pk/asn1/der/utf8/der_encode_utf8_string.c @@ -28,6 +28,7 @@ int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { unsigned long x, y, len; + int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); @@ -38,46 +39,26 @@ int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, if (!der_utf8_valid_char(in[x])) return CRYPT_INVALID_ARG; len += der_utf8_charsize(in[x]); } - - if (len < 128) { - y = 2 + len; - } else if (len < 256) { - y = 3 + len; - } else if (len < 65536UL) { - y = 4 + len; - } else if (len < 16777216UL) { - y = 5 + len; - } else { - return CRYPT_INVALID_ARG; + if ((err = der_length_asn1_length(len, &x)) != CRYPT_OK) { + return err; } + x += len + 1; /* too big? */ - if (y > *outlen) { - *outlen = len; + if (x > *outlen) { + *outlen = x; return CRYPT_BUFFER_OVERFLOW; } /* encode the header+len */ x = 0; out[x++] = 0x0C; - if (len < 128) { - out[x++] = (unsigned char)len; - } else if (len < 256) { - out[x++] = 0x81; - out[x++] = (unsigned char)len; - } else if (len < 65536UL) { - out[x++] = 0x82; - out[x++] = (unsigned char)((len>>8)&255); - out[x++] = (unsigned char)(len&255); - } else if (len < 16777216UL) { - out[x++] = 0x83; - out[x++] = (unsigned char)((len>>16)&255); - out[x++] = (unsigned char)((len>>8)&255); - out[x++] = (unsigned char)(len&255); - } else { - /* coverity[dead_error_line] */ - return CRYPT_INVALID_ARG; + + y = *outlen - x; + if ((err = der_encode_asn1_length(len, out + x, &y)) != CRYPT_OK) { + return err; } + x += y; /* store UTF8 */ for (y = 0; y < inlen; y++) { @@ -91,7 +72,7 @@ int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, } } - /* retun length */ + /* return length */ *outlen = x; return CRYPT_OK; diff --git a/src/ltc/pk/asn1/der/utf8/der_length_utf8_string.c b/src/ltc/pk/asn1/der/utf8/der_length_utf8_string.c index 88f4355e..b4292846 100644 --- a/src/ltc/pk/asn1/der/utf8/der_length_utf8_string.c +++ b/src/ltc/pk/asn1/der/utf8/der_length_utf8_string.c @@ -65,6 +65,7 @@ int der_utf8_valid_char(const wchar_t c) int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen) { unsigned long x, len; + int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(outlen != NULL); @@ -75,21 +76,10 @@ int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned lo len += der_utf8_charsize(in[x]); } - if (len < 128) { - /* 0C LL DD DD DD ... */ - *outlen = 2 + len; - } else if (len < 256) { - /* 0C 81 LL DD DD DD ... */ - *outlen = 3 + len; - } else if (len < 65536UL) { - /* 0C 82 LL LL DD DD DD ... */ - *outlen = 4 + len; - } else if (len < 16777216UL) { - /* 0C 83 LL LL LL DD DD DD ... */ - *outlen = 5 + len; - } else { - return CRYPT_INVALID_ARG; + if ((err = der_length_asn1_length(len, &x)) != CRYPT_OK) { + return err; } + *outlen = 1 + x + len; return CRYPT_OK; } diff --git a/src/ltc/pk/asn1/der/sequence/der_decode_subject_public_key_info.c b/src/ltc/pk/asn1/x509/x509_decode_subject_public_key_info.c index 51bf37c5..c68b4a3b 100644 --- a/src/ltc/pk/asn1/der/sequence/der_decode_subject_public_key_info.c +++ b/src/ltc/pk/asn1/x509/x509_decode_subject_public_key_info.c @@ -7,9 +7,10 @@ * guarantee it works. */ #include "tomcrypt.h" + /** - @file der_decode_subject_public_key_info.c - ASN.1 DER, encode a Subject Public Key structure --nmav + @file x509_decode_subject_public_key_info.c + ASN.1 DER/X.509, encode a SubjectPublicKeyInfo structure --nmav */ #ifdef LTC_DER @@ -25,7 +26,7 @@ * } */ /** - Decode a subject public key info + Decode a SubjectPublicKeyInfo @param in The input buffer @param inlen The length of the input buffer @param algorithm One out of the enum #public_key_algorithms @@ -33,21 +34,12 @@ @param public_key_len [in/out] The length of the public key buffer and the written length @param parameters_type The parameters' type out of the enum ltc_asn1_type @param parameters The parameters to include - @param parameters_len The number of parameters to include + @param parameters_len [in/out]The number of parameters to include @return CRYPT_OK on success */ -int der_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen, - unsigned int algorithm, void* public_key, unsigned long* public_key_len, - unsigned long parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len) -{ - return der_decode_subject_public_key_info_ex(in, inlen, algorithm, public_key, public_key_len, - parameters_type, parameters, parameters_len, NULL); -} - -int der_decode_subject_public_key_info_ex(const unsigned char *in, unsigned long inlen, +int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen, unsigned int algorithm, void* public_key, unsigned long* public_key_len, - unsigned long parameters_type, void* parameters, unsigned long parameters_len, - unsigned long *parameters_outsize) + unsigned long parameters_type, void* parameters, unsigned long *parameters_len) { int err; unsigned long len; @@ -60,6 +52,7 @@ int der_decode_subject_public_key_info_ex(const unsigned char *in, unsigned long LTC_ARGCHK(in != NULL); LTC_ARGCHK(inlen != 0); LTC_ARGCHK(public_key_len != NULL); + LTC_ARGCHK(parameters_len != NULL); err = pk_get_oid(algorithm, &oid); if (err != CRYPT_OK) { @@ -75,7 +68,7 @@ int der_decode_subject_public_key_info_ex(const unsigned char *in, unsigned long /* this includes the internal hash ID and optional params (NULL in this case) */ LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0])); - LTC_SET_ASN1(alg_id, 1, (ltc_asn1_type)parameters_type, parameters, parameters_len); + LTC_SET_ASN1(alg_id, 1, (ltc_asn1_type)parameters_type, parameters, *parameters_len); /* the actual format of the SSL DER key is odd, it stores a RSAPublicKey * in a **BIT** string ... so we have to extract it then proceed to convert bit to octet @@ -88,7 +81,7 @@ int der_decode_subject_public_key_info_ex(const unsigned char *in, unsigned long goto LBL_ERR; } - if (parameters_outsize) *parameters_outsize = alg_id[1].size; + *parameters_len = alg_id[1].size; if ((alg_id[0].size != oid.OIDlen) || XMEMCMP(oid.OID, alg_id[0].data, oid.OIDlen * sizeof(oid.OID[0]))) { diff --git a/src/ltc/pk/asn1/der/sequence/der_encode_subject_public_key_info.c b/src/ltc/pk/asn1/x509/x509_encode_subject_public_key_info.c index dcb869a9..8148a185 100644 --- a/src/ltc/pk/asn1/der/sequence/der_encode_subject_public_key_info.c +++ b/src/ltc/pk/asn1/x509/x509_encode_subject_public_key_info.c @@ -9,8 +9,8 @@ #include "tomcrypt.h" /** - @file der_encode_subject_public_key_info.c - ASN.1 DER, encode a Subject Public Key structure --nmav + @file x509_encode_subject_public_key_info.c + ASN.1 DER/X.509, encode a SubjectPublicKeyInfo structure --nmav */ #ifdef LTC_DER @@ -26,7 +26,7 @@ * } */ /** - Encode a subject public key info + Encode a SubjectPublicKeyInfo @param out The output buffer @param outlen [in/out] Length of buffer and resulting length of output @param algorithm One out of the enum #public_key_algorithms @@ -37,7 +37,7 @@ @param parameters_len The number of parameters to include @return CRYPT_OK on success */ -int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen, +int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen, unsigned int algorithm, void* public_key, unsigned long public_key_len, unsigned long parameters_type, void* parameters, unsigned long parameters_len) { diff --git a/src/ltc/pk/dsa/dsa_export.c b/src/ltc/pk/dsa/dsa_export.c index 1f6bb5a3..dde54583 100644 --- a/src/ltc/pk/dsa/dsa_export.c +++ b/src/ltc/pk/dsa/dsa_export.c @@ -86,7 +86,7 @@ int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key LTC_SET_ASN1(int_list, 1, LTC_ASN1_INTEGER, key->q, 1UL); LTC_SET_ASN1(int_list, 2, LTC_ASN1_INTEGER, key->g, 1UL); - err = der_encode_subject_public_key_info(out, outlen, PKA_DSA, tmp, + err = x509_encode_subject_public_key_info(out, outlen, PKA_DSA, tmp, tmplen, LTC_ASN1_SEQUENCE, int_list, sizeof(int_list) / sizeof(int_list[0])); diff --git a/src/ltc/pk/dsa/dsa_import.c b/src/ltc/pk/dsa/dsa_import.c index e6a75602..5e77b1e7 100644 --- a/src/ltc/pk/dsa/dsa_import.c +++ b/src/ltc/pk/dsa/dsa_import.c @@ -25,7 +25,7 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key) { int err, stat; - unsigned long zero = 0; + unsigned long zero = 0, len; unsigned char* tmpbuf = NULL; unsigned char flags[1]; @@ -102,9 +102,10 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key) goto LBL_ERR; } - err = der_decode_subject_public_key_info(in, inlen, PKA_DSA, + len = 3; + err = x509_decode_subject_public_key_info(in, inlen, PKA_DSA, tmpbuf, &tmpbuf_len, - LTC_ASN1_SEQUENCE, params, 3); + LTC_ASN1_SEQUENCE, params, &len); if (err != CRYPT_OK) { XFREE(tmpbuf); goto LBL_ERR; diff --git a/src/ltc/pk/dsa/dsa_verify_hash.c b/src/ltc/pk/dsa/dsa_verify_hash.c index 3d3fab5f..eb642d5b 100644 --- a/src/ltc/pk/dsa/dsa_verify_hash.c +++ b/src/ltc/pk/dsa/dsa_verify_hash.c @@ -111,7 +111,7 @@ int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, LTC_SET_ASN1(sig_seq, 0, LTC_ASN1_INTEGER, r, 1UL); LTC_SET_ASN1(sig_seq, 1, LTC_ASN1_INTEGER, s, 1UL); - err = der_decode_sequence(sig, siglen, sig_seq, 2); + err = der_decode_sequence_strict(sig, siglen, sig_seq, 2); if (err != CRYPT_OK) { goto LBL_ERR; } diff --git a/src/ltc/pk/ecc/ecc.c b/src/ltc/pk/ecc/ecc.c index 0eb55023..b90afc71 100644 --- a/src/ltc/pk/ecc/ecc.c +++ b/src/ltc/pk/ecc/ecc.c @@ -7,9 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ #include "tomcrypt.h" /** @@ -19,10 +16,7 @@ #ifdef LTC_MECC -/* This array holds the curve parameters: - * - it ***MUST*** be organized by size from smallest to largest - * - due to curve lookup by keysize the ordering is very important - * - be careful when adding/removing items to/from this list +/* This array holds the curve parameters. * Curves (prime field only) are taken from: * - http://www.secg.org/collateral/sec2_final.pdf (named: SECP*) * - http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf (named: NISTP*) @@ -31,8 +25,7 @@ */ const ltc_ecc_set_type ltc_ecc_sets[] = { #if defined(LTC_ECC_SECP112R1) || defined(LTC_ECC112) -{ /* this curve ***MUST*** be the first from all with size 14 (backward compatibility reasons) */ - /* size/bytes */ 14, +{ /* curve name */ "SECP112R1", /* prime */ "DB7C2ABF62E35E668076BEAD208B", /* A */ "DB7C2ABF62E35E668076BEAD2088", @@ -41,12 +34,11 @@ const ltc_ecc_set_type ltc_ecc_sets[] = { /* Gx */ "09487239995A5EE76B55F9C2F098", /* Gy */ "A89CE5AF8724C0A23E0E0FF77500", /* cofactor */ 1, - /* OID struct */ { {1,3,132,0,6}, 5 } + /* OID */ { 1,3,132,0,6 }, 5 }, #endif #ifdef LTC_ECC_SECP112R2 { - /* size/bytes */ 14, /* curve name */ "SECP112R2", /* prime */ "DB7C2ABF62E35E668076BEAD208B", /* A */ "6127C24C05F38A0AAAF65C0EF02C", @@ -55,12 +47,11 @@ const ltc_ecc_set_type ltc_ecc_sets[] = { /* Gx */ "4BA30AB5E892B4E1649DD0928643", /* Gy */ "ADCD46F5882E3747DEF36E956E97", /* cofactor */ 4, - /* OID struct */ { {1,3,132,0,7}, 5 } + /* OID */ { 1,3,132,0,7 }, 5 }, #endif #if defined(LTC_ECC_SECP128R1) || defined(LTC_ECC128) -{ /* this curve ***MUST*** be the first from all with size 16 (backward compatibility reasons) */ - /* size/bytes */ 16, +{ /* curve name */ "SECP128R1", /* prime */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* A */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", @@ -69,12 +60,11 @@ const ltc_ecc_set_type ltc_ecc_sets[] = { /* Gx */ "161FF7528B899B2D0C28607CA52C5B86", /* Gy */ "CF5AC8395BAFEB13C02DA292DDED7A83", /* cofactor */ 1, - /* OID struct */ { {1,3,132,0,28}, 5 } + /* OID */ { 1,3,132,0,28 }, 5 }, #endif #ifdef LTC_ECC_SECP128R2 { - /* size/bytes */ 16, /* curve name */ "SECP128R2", /* prime */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* A */ "D6031998D1B3BBFEBF59CC9BBFF9AEE1", @@ -83,12 +73,11 @@ const ltc_ecc_set_type ltc_ecc_sets[] = { /* Gx */ "7B6AA5D85E572983E6FB32A7CDEBC140", /* Gy */ "27B6916A894D3AEE7106FE805FC34B44", /* cofactor */ 4, - /* OID struct */ { {1,3,132,0,29}, 5 } + /* OID */ { 1,3,132,0,29 }, 5 }, #endif #if defined(LTC_ECC_SECP160R1) || defined(LTC_ECC160) -{ /* this curve ***MUST*** be the first from all with size 20 (backward compatibility reasons) */ - /* size/bytes */ 20, +{ /* curve name */ "SECP160R1", /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", @@ -97,12 +86,11 @@ const ltc_ecc_set_type ltc_ecc_sets[] = { /* Gx */ "4A96B5688EF573284664698968C38BB913CBFC82", /* Gy */ "23A628553168947D59DCC912042351377AC5FB32", /* cofactor */ 1, - /* OID struct */ { {1,3,132,0,8}, 5 } + /* OID */ { 1,3,132,0,8 }, 5 }, #endif #ifdef LTC_ECC_SECP160R2 { - /* size/bytes */ 20, /* curve name */ "SECP160R2", /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", @@ -111,12 +99,11 @@ const ltc_ecc_set_type ltc_ecc_sets[] = { /* Gx */ "52DCB034293A117E1F4FF11B30F7199D3144CE6D", /* Gy */ "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", /* cofactor */ 1, - /* OID struct */ { {1,3,132,0,30}, 5 } + /* OID */ { 1,3,132,0,30 }, 5 }, #endif #ifdef LTC_ECC_SECP160K1 { - /* size/bytes */ 20, /* curve name */ "SECP160K1", /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* A */ "0000000000000000000000000000000000000000", @@ -125,26 +112,11 @@ const ltc_ecc_set_type ltc_ecc_sets[] = { /* Gx */ "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", /* Gy */ "938CF935318FDCED6BC28286531733C3F03C4FEE", /* cofactor */ 1, - /* OID struct */ { {1,3,132,0,9}, 5 } -}, -#endif -#ifdef LTC_ECC_BRAINPOOLP160R1 -{ - /* size/bytes */ 20, - /* curve name */ "BRAINPOOLP160R1", - /* prime */ "E95E4A5F737059DC60DFC7AD95B3D8139515620F", - /* A */ "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", - /* B */ "1E589A8595423412134FAA2DBDEC95C8D8675E58", - /* order */ "E95E4A5F737059DC60DF5991D45029409E60FC09", - /* Gx */ "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", - /* Gy */ "1667CB477A1A8EC338F94741669C976316DA6321", - /* cofactor */ 1, - /* OID struct */ { {1,3,36,3,3,2,8,1,1,1}, 10 } + /* OID */ { 1,3,132,0,9 }, 5 }, #endif #if defined(LTC_ECC_SECP192R1) || defined(LTC_ECC192) -{ /* this curve ***MUST*** be the first from all with size 24 (backward compatibility reasons) */ - /* size/bytes */ 24, +{ /* curve name */ "SECP192R1", /* same as: NISTP192 PRIME192V1, old libtomcrypt name: ECC-192 */ /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", @@ -153,12 +125,11 @@ const ltc_ecc_set_type ltc_ecc_sets[] = { /* Gx */ "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", /* Gy */ "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811", /* cofactor */ 1, - /* OID struct */ { {1,2,840,10045,3,1,1}, 7 } + /* OID */ { 1,2,840,10045,3,1,1 }, 7 }, #endif #ifdef LTC_ECC_PRIME192V2 { - /* size/bytes */ 24, /* curve name */ "PRIME192V2", /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", @@ -167,12 +138,11 @@ const ltc_ecc_set_type ltc_ecc_sets[] = { /* Gx */ "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", /* Gy */ "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", /* cofactor */ 1, - /* OID struct */ { {1,2,840,10045,3,1,2}, 7 } + /* OID */ { 1,2,840,10045,3,1,2 }, 7 }, #endif #ifdef LTC_ECC_PRIME192V3 { - /* size/bytes */ 24, /* curve name */ "PRIME192V3", /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", @@ -181,12 +151,11 @@ const ltc_ecc_set_type ltc_ecc_sets[] = { /* Gx */ "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", /* Gy */ "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", /* cofactor */ 1, - /* OID struct */ { {1,2,840,10045,3,1,3}, 7 } + /* OID */ { 1,2,840,10045,3,1,3 }, 7 }, #endif #ifdef LTC_ECC_SECP192K1 { - /* size/bytes */ 24, /* curve name */ "SECP192K1", /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* A */ "000000000000000000000000000000000000000000000000", @@ -195,26 +164,11 @@ const ltc_ecc_set_type ltc_ecc_sets[] = { /* Gx */ "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", /* Gy */ "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", /* cofactor */ 1, - /* OID struct */ { {1,3,132,0,31}, 5 } -}, -#endif -#ifdef LTC_ECC_BRAINPOOLP192R1 -{ - /* size/bytes */ 24, - /* curve name */ "BRAINPOOLP192R1", - /* prime */ "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", - /* A */ "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", - /* B */ "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", - /* order */ "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", - /* Gx */ "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", - /* Gy */ "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", - /* cofactor */ 1, - /* OID struct */ { {1,3,36,3,3,2,8,1,1,3}, 10 } + /* OID */ { 1,3,132,0,31 }, 5 }, #endif #if defined(LTC_ECC_SECP224R1) || defined(LTC_ECC224) -{ /* this curve ***MUST*** be the first from all with size 28 (backward compatibility reasons) */ - /* size/bytes */ 28, +{ /* curve name */ "SECP224R1", /* same as: NISTP224, old libtomcrypt name: ECC-224 */ /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", @@ -223,12 +177,11 @@ const ltc_ecc_set_type ltc_ecc_sets[] = { /* Gx */ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gy */ "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* cofactor */ 1, - /* OID struct */ { {1,3,132,0,33}, 5 } + /* OID */ { 1,3,132,0,33 }, 5 }, #endif #ifdef LTC_ECC_SECP224K1 { - /* size/bytes */ 28, /* curve name */ "SECP224K1", /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* A */ "00000000000000000000000000000000000000000000000000000000", @@ -237,26 +190,63 @@ const ltc_ecc_set_type ltc_ecc_sets[] = { /* Gx */ "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", /* Gy */ "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", /* cofactor */ 1, - /* OID struct */ { {1,3,132,0,32}, 5 } + /* OID */ { 1,3,132,0,32 }, 5 }, #endif -#ifdef LTC_ECC_BRAINPOOLP224R1 +#if defined(LTC_ECC_SECP256R1) || defined(LTC_ECC256) { - /* size/bytes */ 28, - /* curve name */ "BRAINPOOLP224R1", - /* prime */ "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", - /* A */ "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", - /* B */ "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", - /* order */ "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", - /* Gx */ "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", - /* Gy */ "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", + /* curve name */ "SECP256R1", /* same as: NISTP256 PRIME256V1, old libtomcrypt name: ECC-256 */ + /* prime */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", + /* A */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", + /* B */ "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", + /* order */ "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", + /* Gx */ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", + /* Gy */ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", /* cofactor */ 1, - /* OID struct */ { {1,3,36,3,3,2,8,1,1,5}, 10 } + /* OID */ { 1,2,840,10045,3,1,7 }, 7 +}, +#endif +#ifdef LTC_ECC_SECP256K1 +{ + /* curve name */ "SECP256K1", + /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", + /* A */ "0000000000000000000000000000000000000000000000000000000000000000", + /* B */ "0000000000000000000000000000000000000000000000000000000000000007", + /* order */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", + /* Gx */ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", + /* Gy */ "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", + /* cofactor */ 1, + /* OID */ { 1,3,132,0,10 }, 5 +}, +#endif +#if defined(LTC_ECC_SECP384R1) || defined(LTC_ECC384) +{ + /* curve name */ "SECP384R1", /* same as: NISTP384, old libtomcrypt name: ECC-384 */ + /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", + /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", + /* B */ "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", + /* order */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", + /* Gx */ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", + /* Gy */ "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", + /* cofactor */ 1, + /* OID */ { 1,3,132,0,34 }, 5 +}, +#endif +#if defined(LTC_ECC_SECP521R1) || defined(LTC_ECC521) +{ + /* curve name */ "SECP521R1", /* same as: NISTP521, old libtomcrypt name: ECC-521 */ + /* prime */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + /* A */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", + /* B */ "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", + /* order */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", + /* Gx */ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", + /* Gy */ "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", + /* cofactor */ 1, + /* OID */ { 1,3,132,0,35 }, 5 }, #endif #ifdef LTC_ECC_PRIME239V1 { - /* size/bytes */ 30, /* curve name */ "PRIME239V1", /* prime */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* A */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", @@ -265,12 +255,11 @@ const ltc_ecc_set_type ltc_ecc_sets[] = { /* Gx */ "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", /* Gy */ "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", /* cofactor */ 1, - /* OID struct */ { {1,2,840,10045,3,1,4}, 7 } + /* OID */ { 1,2,840,10045,3,1,4 }, 7 }, #endif #ifdef LTC_ECC_PRIME239V2 { - /* size/bytes */ 30, /* curve name */ "PRIME239V2", /* prime */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* A */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", @@ -279,12 +268,11 @@ const ltc_ecc_set_type ltc_ecc_sets[] = { /* Gx */ "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", /* Gy */ "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", /* cofactor */ 1, - /* OID struct */ { {1,2,840,10045,3,1,5}, 7 } + /* OID */ { 1,2,840,10045,3,1,5 }, 7 }, #endif #ifdef LTC_ECC_PRIME239V3 { - /* size/bytes */ 30, /* curve name */ "PRIME239V3", /* prime */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* A */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", @@ -293,40 +281,50 @@ const ltc_ecc_set_type ltc_ecc_sets[] = { /* Gx */ "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", /* Gy */ "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", /* cofactor */ 1, - /* OID struct */ { {1,2,840,10045,3,1,6}, 7 } + /* OID */ { 1,2,840,10045,3,1,6 }, 7 }, #endif -#if defined(LTC_ECC_SECP256R1) || defined(LTC_ECC256) -{ /* this curve ***MUST*** be the first from all with size 32 (backward compatibility reasons) */ - /* size/bytes */ 32, - /* curve name */ "SECP256R1", /* same as: NISTP256 PRIME256V1, old libtomcrypt name: ECC-256 */ - /* prime */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", - /* A */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", - /* B */ "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", - /* order */ "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", - /* Gx */ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", - /* Gy */ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", +#ifdef LTC_ECC_BRAINPOOLP160R1 +{ + /* curve name */ "BRAINPOOLP160R1", + /* prime */ "E95E4A5F737059DC60DFC7AD95B3D8139515620F", + /* A */ "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", + /* B */ "1E589A8595423412134FAA2DBDEC95C8D8675E58", + /* order */ "E95E4A5F737059DC60DF5991D45029409E60FC09", + /* Gx */ "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", + /* Gy */ "1667CB477A1A8EC338F94741669C976316DA6321", /* cofactor */ 1, - /* OID struct */ { {1,2,840,10045,3,1,7}, 7 } + /* OID */ { 1,3,36,3,3,2,8,1,1,1 }, 10 }, #endif -#ifdef LTC_ECC_SECP256K1 +#ifdef LTC_ECC_BRAINPOOLP192R1 { - /* size/bytes */ 32, - /* curve name */ "SECP256K1", - /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", - /* A */ "0000000000000000000000000000000000000000000000000000000000000000", - /* B */ "0000000000000000000000000000000000000000000000000000000000000007", - /* order */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", - /* Gx */ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", - /* Gy */ "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", + /* curve name */ "BRAINPOOLP192R1", + /* prime */ "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", + /* A */ "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", + /* B */ "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", + /* order */ "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", + /* Gx */ "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", + /* Gy */ "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", /* cofactor */ 1, - /* OID struct */ { {1,3,132,0,10}, 5 } + /* OID */ { 1,3,36,3,3,2,8,1,1,3 }, 10 +}, +#endif +#ifdef LTC_ECC_BRAINPOOLP224R1 +{ + /* curve name */ "BRAINPOOLP224R1", + /* prime */ "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", + /* A */ "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", + /* B */ "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", + /* order */ "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", + /* Gx */ "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", + /* Gy */ "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", + /* cofactor */ 1, + /* OID */ { 1,3,36,3,3,2,8,1,1,5 }, 10 }, #endif #ifdef LTC_ECC_BRAINPOOLP256R1 { - /* size/bytes */ 32, /* curve name */ "BRAINPOOLP256R1", /* prime */ "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* A */ "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", @@ -335,12 +333,11 @@ const ltc_ecc_set_type ltc_ecc_sets[] = { /* Gx */ "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gy */ "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* cofactor */ 1, - /* OID struct */ { {1,3,36,3,3,2,8,1,1,7}, 10 } + /* OID */ { 1,3,36,3,3,2,8,1,1,7 }, 10 }, #endif #ifdef LTC_ECC_BRAINPOOLP320R1 { - /* size/bytes */ 40, /* curve name */ "BRAINPOOLP320R1", /* prime */ "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", /* A */ "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", @@ -349,26 +346,11 @@ const ltc_ecc_set_type ltc_ecc_sets[] = { /* Gx */ "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", /* Gy */ "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", /* cofactor */ 1, - /* OID struct */ { {1,3,36,3,3,2,8,1,1,9}, 10 } -}, -#endif -#if defined(LTC_ECC_SECP384R1) || defined(LTC_ECC384) -{ /* this curve ***MUST*** be the first from all with size 48 (backward compatibility reasons) */ - /* size/bytes */ 48, - /* curve name */ "SECP384R1", /* same as: NISTP384, old libtomcrypt name: ECC-384 */ - /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", - /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", - /* B */ "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", - /* order */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", - /* Gx */ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", - /* Gy */ "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", - /* cofactor */ 1, - /* OID struct */ { {1,3,132,0,34}, 5 } + /* OID */ { 1,3,36,3,3,2,8,1,1,9 }, 10 }, #endif #ifdef LTC_ECC_BRAINPOOLP384R1 { - /* size/bytes */ 48, /* curve name */ "BRAINPOOLP384R1", /* prime */ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* A */ "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", @@ -377,12 +359,11 @@ const ltc_ecc_set_type ltc_ecc_sets[] = { /* Gx */ "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* Gy */ "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* cofactor */ 1, - /* OID struct */ { {1,3,36,3,3,2,8,1,1,11}, 10 } + /* OID */ { 1,3,36,3,3,2,8,1,1,11 }, 10 }, #endif #ifdef LTC_ECC_BRAINPOOLP512R1 { - /* size/bytes */ 64, /* curve name */ "BRAINPOOLP512R1", /* prime */ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* A */ "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", @@ -391,28 +372,104 @@ const ltc_ecc_set_type ltc_ecc_sets[] = { /* Gx */ "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* Gy */ "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* cofactor */ 1, - /* OID struct */ { {1,3,36,3,3,2,8,1,1,13}, 10 } + /* OID */ { 1,3,36,3,3,2,8,1,1,13 }, 10 }, #endif -#if defined(LTC_ECC_SECP521R1) || defined(LTC_ECC521) -{ /* this curve ***MUST*** be the first from all with size 66 (backward compatibility reasons) */ - /* size/bytes */ 66, - /* curve name */ "SECP521R1", /* same as: NISTP521, old libtomcrypt name: ECC-521 */ - /* prime */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", - /* A */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", - /* B */ "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", - /* order */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", - /* Gx */ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", - /* Gy */ "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", +#ifdef LTC_ECC_BRAINPOOLP160T1 +{ + /* curve name */ "BRAINPOOLP160T1", + /* prime */ "E95E4A5F737059DC60DFC7AD95B3D8139515620F", + /* A */ "E95E4A5F737059DC60DFC7AD95B3D8139515620C", + /* B */ "7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380", + /* order */ "E95E4A5F737059DC60DF5991D45029409E60FC09", + /* Gx */ "B199B13B9B34EFC1397E64BAEB05ACC265FF2378", + /* Gy */ "ADD6718B7C7C1961F0991B842443772152C9E0AD", /* cofactor */ 1, - /* OID struct */ { {1,3,132,0,35}, 5 } + /* OID */ { 1,3,36,3,3,2,8,1,1,2 }, 10 +}, +#endif +#ifdef LTC_ECC_BRAINPOOLP192T1 +{ + /* curve name */ "BRAINPOOLP192T1", + /* prime */ "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", + /* A */ "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294", + /* B */ "13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79", + /* order */ "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", + /* Gx */ "3AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129", + /* Gy */ "097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9", + /* cofactor */ 1, + /* OID */ { 1,3,36,3,3,2,8,1,1,4 }, 10 +}, +#endif +#ifdef LTC_ECC_BRAINPOOLP224T1 +{ + /* curve name */ "BRAINPOOLP224T1", + /* prime */ "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", + /* A */ "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC", + /* B */ "4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D", + /* order */ "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", + /* Gx */ "6AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D580", + /* Gy */ "0374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C", + /* cofactor */ 1, + /* OID */ { 1,3,36,3,3,2,8,1,1,6 }, 10 +}, +#endif +#ifdef LTC_ECC_BRAINPOOLP256T1 +{ + /* curve name */ "BRAINPOOLP256T1", + /* prime */ "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", + /* A */ "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374", + /* B */ "662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04", + /* order */ "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", + /* Gx */ "A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F4", + /* Gy */ "2D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE", + /* cofactor */ 1, + /* OID */ { 1,3,36,3,3,2,8,1,1,8 }, 10 +}, +#endif +#ifdef LTC_ECC_BRAINPOOLP320T1 +{ + /* curve name */ "BRAINPOOLP320T1", + /* prime */ "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", + /* A */ "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E24", + /* B */ "A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CEB5B4FEF422340353", + /* order */ "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", + /* Gx */ "925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF3357F624A21BED52", + /* Gy */ "63BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B1B9BC0455FB0D2C3", + /* cofactor */ 1, + /* OID */ { 1,3,36,3,3,2,8,1,1,10 }, 10 +}, +#endif +#ifdef LTC_ECC_BRAINPOOLP384T1 +{ + /* curve name */ "BRAINPOOLP384T1", + /* prime */ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", + /* A */ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC50", + /* B */ "7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B88805CED70355A33B471EE", + /* order */ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", + /* Gx */ "18DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946A5F54D8D0AA2F418808CC", + /* Gy */ "25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC2B2912675BF5B9E582928", + /* cofactor */ 1, + /* OID */ { 1,3,36,3,3,2,8,1,1,12 }, 10 +}, +#endif +#ifdef LTC_ECC_BRAINPOOLP512T1 +{ + /* curve name */ "BRAINPOOLP512T1", + /* prime */ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", + /* A */ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0", + /* B */ "7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E", + /* order */ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", + /* Gx */ "640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CDB3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA", + /* Gy */ "5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEEF216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332", + /* cofactor */ 1, + /* OID */ { 1,3,36,3,3,2,8,1,1,14 }, 10 }, #endif { - 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, - { { 0 }, 0 } + { 0 }, 0 } }; diff --git a/src/ltc/pk/ecc/ecc_ansi_x963_export.c b/src/ltc/pk/ecc/ecc_ansi_x963_export.c index 8bb4cc5f..528dcd80 100644 --- a/src/ltc/pk/ecc/ecc_ansi_x963_export.c +++ b/src/ltc/pk/ecc/ecc_ansi_x963_export.c @@ -7,9 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ #include "tomcrypt.h" /** @@ -34,10 +31,7 @@ int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); - if (ltc_ecc_is_valid_idx(key->idx) == 0) { - return CRYPT_INVALID_ARG; - } - numlen = key->dp->size; + numlen = key->dp.size; xlen = mp_unsigned_bin_size(key->pubkey.x); ylen = mp_unsigned_bin_size(key->pubkey.y); diff --git a/src/ltc/pk/ecc/ecc_ansi_x963_import.c b/src/ltc/pk/ecc/ecc_ansi_x963_import.c index 9c5a84e5..bcc8575f 100644 --- a/src/ltc/pk/ecc/ecc_ansi_x963_import.c +++ b/src/ltc/pk/ecc/ecc_ansi_x963_import.c @@ -7,9 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ #include "tomcrypt.h" /** @@ -29,9 +26,9 @@ int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key * 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, ltc_ecc_set_type *dp) +int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp) { - int x, err; + int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(key != NULL); @@ -41,60 +38,21 @@ int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_ke return CRYPT_INVALID_ARG; } - /* init key */ - if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL) != CRYPT_OK) { - return CRYPT_MEM; - } - - /* check for 4, 6 or 7 */ - if (in[0] != 4 && in[0] != 6 && in[0] != 7) { - err = CRYPT_INVALID_PACKET; - goto error; - } - - /* read data */ - if ((err = mp_read_unsigned_bin(key->pubkey.x, (unsigned char *)in+1, (inlen-1)>>1)) != CRYPT_OK) { - goto error; + /* initialize key->dp */ + if (dp == 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 = mp_read_unsigned_bin(key->pubkey.y, (unsigned char *)in+1+((inlen-1)>>1), (inlen-1)>>1)) != CRYPT_OK) { - goto error; + else { + /* this one works for both compressed / uncompressed pubkeys */ + if ((err = ecc_set_dp(dp, key)) != CRYPT_OK) { return err; } } - if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto error; } - if (dp == NULL) { - /* BEWARE: Here we are looking up the curve params by keysize (neither curve name nor curve oid), - * which might be ambiguous (there can more than one curve for given keysize). - * Thus the chosen curve depends on order of items in ltc_ecc_sets[] - see ecc.c file. - */ - /* determine the idx */ - for (x = 0; ltc_ecc_sets[x].size != 0; x++) { - if ((unsigned)ltc_ecc_sets[x].size >= ((inlen-1)>>1)) { - break; - } - } - if (ltc_ecc_sets[x].size == 0) { - err = CRYPT_INVALID_PACKET; - goto error; - } - /* set the idx */ - key->idx = x; - key->dp = <c_ecc_sets[x]; - } else { - if (((inlen-1)>>1) != (unsigned long) dp->size) { - err = CRYPT_INVALID_PACKET; - goto error; - } - key->idx = -1; - key->dp = dp; - } - key->type = PK_PUBLIC; + /* load public key */ + if ((err = ecc_set_key((unsigned char *)in, inlen, PK_PUBLIC, key)) != CRYPT_OK) { return err; } /* we're done */ return CRYPT_OK; -error: - mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL); - return err; } #endif diff --git a/src/ltc/pk/ecc/ecc_decrypt_key.c b/src/ltc/pk/ecc/ecc_decrypt_key.c index d86c168b..ebfa5156 100644 --- a/src/ltc/pk/ecc/ecc_decrypt_key.c +++ b/src/ltc/pk/ecc/ecc_decrypt_key.c @@ -7,9 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ #include "tomcrypt.h" /** @@ -33,7 +30,8 @@ int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, ecc_key *key) { unsigned char *ecc_shared, *skey, *pub_expt; - unsigned long x, y, hashOID[32]; + unsigned long x, y; + unsigned long hashOID[32] = { 0 }; int hash, err; ecc_key pubkey; ltc_asn1_list decode[3]; @@ -87,9 +85,8 @@ int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, } /* import ECC key from packet */ - if ((err = ecc_import_raw(decode[1].data, decode[1].size, &pubkey, (ltc_ecc_set_type *)key->dp)) != CRYPT_OK) { - goto LBL_ERR; - } + if ((err = ecc_set_dp_copy(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 */ x = ECC_BUF_SIZE; diff --git a/src/ltc/pk/ecc/ecc_dp_clear.c b/src/ltc/pk/ecc/ecc_dp_clear.c deleted file mode 100644 index 76fa375e..00000000 --- a/src/ltc/pk/ecc/ecc_dp_clear.c +++ /dev/null @@ -1,36 +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. - * - */ - -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ - -#include "tomcrypt.h" - -#ifdef LTC_MECC - -int ecc_dp_clear(ltc_ecc_set_type *dp) -{ - if (dp == NULL) return CRYPT_INVALID_ARG; - - if (dp->name != NULL) { XFREE(dp->name ); dp->name = NULL; } - if (dp->prime != NULL) { XFREE(dp->prime); dp->prime = NULL; } - if (dp->A != NULL) { XFREE(dp->A ); dp->A = NULL; } - if (dp->B != NULL) { XFREE(dp->B ); dp->B = NULL; } - if (dp->order != NULL) { XFREE(dp->order); dp->order = NULL; } - if (dp->Gx != NULL) { XFREE(dp->Gx ); dp->Gx = NULL; } - if (dp->Gy != NULL) { XFREE(dp->Gy ); dp->Gy = NULL; } - dp->cofactor = 0; - dp->oid.OIDlen = 0; - - return CRYPT_OK; -} - -#endif diff --git a/src/ltc/pk/ecc/ecc_dp_fill_from_sets.c b/src/ltc/pk/ecc/ecc_dp_fill_from_sets.c deleted file mode 100644 index 06c66be4..00000000 --- a/src/ltc/pk/ecc/ecc_dp_fill_from_sets.c +++ /dev/null @@ -1,76 +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 - -static int hexstrcmp(const char *hexa, const char *hexb) -{ - #define MY_TOLOWER(a) ((((a)>='A')&&((a)<='Z')) ? ((a)|0x60) : (a)) - /* ignore leading zeroes */ - while(*hexa == '0') hexa++; - while(*hexb == '0') hexb++; - /* compare: case insensitive, hexadecimal chars only */ - while (*hexa && *hexb) { - if ( (*hexa < '0' || *hexa > '9') && - (*hexa < 'a' || *hexa > 'f') && - (*hexa < 'A' || *hexa > 'F') ) return 1; - if ( (*hexb < '0' || *hexb > '9') && - (*hexb < 'a' || *hexb > 'f') && - (*hexb < 'A' || *hexb > 'F') ) return 1; - if (MY_TOLOWER(*hexa) != MY_TOLOWER(*hexb)) return 1; - hexa++; - hexb++; - } - if (*hexa == '\0' && *hexb == '\0') return 0; /* success - match */ - return 1; -} - -/* search known curve by curve parameters and fill in missing parameters into dp - * we assume every parameter has the same case (usually uppercase) and no leading zeros - */ -int ecc_dp_fill_from_sets(ltc_ecc_set_type *dp) -{ - ltc_ecc_set_type params; - int x; - - if (!dp) return CRYPT_INVALID_ARG; - if (dp->oid.OIDlen > 0) return CRYPT_OK; - if (!dp->prime || !dp->A || !dp->B || !dp->order || !dp->Gx || !dp->Gy || dp->cofactor == 0) return CRYPT_INVALID_ARG; - - for (x = 0; ltc_ecc_sets[x].size != 0; x++) { - if (hexstrcmp(ltc_ecc_sets[x].prime, dp->prime) == 0 && - hexstrcmp(ltc_ecc_sets[x].A, dp->A) == 0 && - hexstrcmp(ltc_ecc_sets[x].B, dp->B) == 0 && - hexstrcmp(ltc_ecc_sets[x].order, dp->order) == 0 && - hexstrcmp(ltc_ecc_sets[x].Gx, dp->Gx) == 0 && - hexstrcmp(ltc_ecc_sets[x].Gy, dp->Gy) == 0 && - ltc_ecc_sets[x].cofactor == dp->cofactor) { - - params = ltc_ecc_sets[x]; - - /* copy oid */ - dp->oid.OIDlen = params.oid.OIDlen; - XMEMCPY(dp->oid.OID, params.oid.OID, dp->oid.OIDlen * sizeof(dp->oid.OID[0])); - - /* copy name */ - if (dp->name != NULL) XFREE(dp->name); - if ((dp->name = XMALLOC(1+strlen(params.name))) == NULL) return CRYPT_MEM; - strcpy(dp->name, params.name); - - return CRYPT_OK; - } - } - - return CRYPT_INVALID_ARG; -} - -#endif diff --git a/src/ltc/pk/ecc/ecc_dp_from_oid.c b/src/ltc/pk/ecc/ecc_dp_from_oid.c deleted file mode 100644 index 5ddd1aba..00000000 --- a/src/ltc/pk/ecc/ecc_dp_from_oid.c +++ /dev/null @@ -1,84 +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. - */ - -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ - -#include "tomcrypt.h" - -#ifdef LTC_MECC - -int ecc_dp_set_by_oid(ltc_ecc_set_type *dp, unsigned long *oid, unsigned long oidsize) -{ - int i; - unsigned long len; - - for(i=0; ltc_ecc_sets[i].size != 0; i++) { - if ((oidsize == ltc_ecc_sets[i].oid.OIDlen) && - (XMEM_NEQ(oid, ltc_ecc_sets[i].oid.OID, sizeof(unsigned long) * ltc_ecc_sets[i].oid.OIDlen) == 0)) { - break; - } - } - if (ltc_ecc_sets[i].size == 0) return CRYPT_INVALID_ARG; /* not found */ - - /* a */ - len = (unsigned long)strlen(ltc_ecc_sets[i].A); - if ((dp->A = XMALLOC(1+len)) == NULL) goto cleanup1; - strncpy(dp->A, ltc_ecc_sets[i].A, 1+len); - /* b */ - len = (unsigned long)strlen(ltc_ecc_sets[i].B); - if ((dp->B = XMALLOC(1+len)) == NULL) goto cleanup2; - strncpy(dp->B, ltc_ecc_sets[i].B, 1+len); - /* order */ - len = (unsigned long)strlen(ltc_ecc_sets[i].order); - if ((dp->order = XMALLOC(1+len)) == NULL) goto cleanup3; - strncpy(dp->order, ltc_ecc_sets[i].order, 1+len); - /* prime */ - len = (unsigned long)strlen(ltc_ecc_sets[i].prime); - if ((dp->prime = XMALLOC(1+len)) == NULL) goto cleanup4; - strncpy(dp->prime, ltc_ecc_sets[i].prime, 1+len); - /* gx */ - len = (unsigned long)strlen(ltc_ecc_sets[i].Gx); - if ((dp->Gx = XMALLOC(1+len)) == NULL) goto cleanup5; - strncpy(dp->Gx, ltc_ecc_sets[i].Gx, 1+len); - /* gy */ - len = (unsigned long)strlen(ltc_ecc_sets[i].Gy); - if ((dp->Gy = XMALLOC(1+len)) == NULL) goto cleanup6; - strncpy(dp->Gy, ltc_ecc_sets[i].Gy, 1+len); - /* cofactor & size */ - dp->cofactor = ltc_ecc_sets[i].cofactor; - dp->size = ltc_ecc_sets[i].size; - /* name */ - len = (unsigned long)strlen(ltc_ecc_sets[i].name); - if ((dp->name = XMALLOC(1+len)) == NULL) goto cleanup7; - strncpy(dp->name, ltc_ecc_sets[i].name, 1+len); - /* oid */ - dp->oid.OIDlen = ltc_ecc_sets[i].oid.OIDlen; - XMEMCPY(dp->oid.OID, ltc_ecc_sets[i].oid.OID, dp->oid.OIDlen * sizeof(dp->oid.OID[0])); - /* done - success */ - return CRYPT_OK; - -cleanup7: - XFREE(dp->Gy); -cleanup6: - XFREE(dp->Gx); -cleanup5: - XFREE(dp->prime); -cleanup4: - XFREE(dp->order); -cleanup3: - XFREE(dp->B); -cleanup2: - XFREE(dp->A); -cleanup1: - return CRYPT_MEM; -} - -#endif diff --git a/src/ltc/pk/ecc/ecc_dp_from_params.c b/src/ltc/pk/ecc/ecc_dp_from_params.c deleted file mode 100644 index a1ddee97..00000000 --- a/src/ltc/pk/ecc/ecc_dp_from_params.c +++ /dev/null @@ -1,84 +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. - */ - -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ - -#include "tomcrypt.h" - -#ifdef LTC_MECC - -int ecc_dp_set_bn(ltc_ecc_set_type *dp, void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor) -{ - unsigned char buf[ECC_BUF_SIZE]; - unsigned long len; - - /* a */ - mp_tohex(a, (char *)buf); - len = (unsigned long)strlen((char *)buf); - if ((dp->A = XMALLOC(1+len)) == NULL) goto cleanup1; - strncpy(dp->A, (char*)buf, 1+len); - /* b */ - mp_tohex(b, (char *)buf); - len = (unsigned long)strlen((char *)buf); - if ((dp->B = XMALLOC(1+len)) == NULL) goto cleanup2; - strncpy(dp->B, (char*)buf, 1+len); - /* order */ - mp_tohex(order, (char *)buf); - len = (unsigned long)strlen((char *)buf); - if ((dp->order = XMALLOC(1+len)) == NULL) goto cleanup3; - strncpy(dp->order, (char*)buf, 1+len); - /* prime */ - mp_tohex(prime, (char *)buf); - len = (unsigned long)strlen((char *)buf); - if ((dp->prime = XMALLOC(1+len)) == NULL) goto cleanup4; - strncpy(dp->prime, (char*)buf, 1+len); - /* gx */ - mp_tohex(gx, (char *)buf); - len = (unsigned long)strlen((char *)buf); - if ((dp->Gx = XMALLOC(1+len)) == NULL) goto cleanup5; - strncpy(dp->Gx, (char*)buf, 1+len); - /* gy */ - mp_tohex(gy, (char *)buf); - len = (unsigned long)strlen((char *)buf); - if ((dp->Gy = XMALLOC(1+len)) == NULL) goto cleanup6; - strncpy(dp->Gy, (char*)buf, 1+len); - /* cofactor & size */ - dp->cofactor = cofactor; - dp->size = mp_unsigned_bin_size(prime); - /* see if we can fill in the missing parameters from known curves */ - if ((ecc_dp_fill_from_sets(dp)) != CRYPT_OK) { - /* custom name */ - if ((dp->name = XMALLOC(7)) == NULL) goto cleanup7; - strcpy(dp->name, "custom"); /* XXX-TODO check this */ - /* no oid */ - dp->oid.OIDlen = 0; - } - /* done - success */ - return CRYPT_OK; - - /* XFREE(dp->name); **** warning: statement not reached *** */ -cleanup7: - XFREE(dp->Gy); -cleanup6: - XFREE(dp->Gx); -cleanup5: - XFREE(dp->prime); -cleanup4: - XFREE(dp->order); -cleanup3: - XFREE(dp->B); -cleanup2: - XFREE(dp->A); -cleanup1: - return CRYPT_MEM; -} - -#endif diff --git a/src/ltc/pk/ecc/ecc_dp_init.c b/src/ltc/pk/ecc/ecc_dp_init.c deleted file mode 100644 index 36c8f5c6..00000000 --- a/src/ltc/pk/ecc/ecc_dp_init.c +++ /dev/null @@ -1,36 +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. - * - */ - -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ - -#include "tomcrypt.h" - -#ifdef LTC_MECC - -int ecc_dp_init(ltc_ecc_set_type *dp) -{ - if (dp == NULL) return CRYPT_INVALID_ARG; - - dp->name = NULL; - dp->prime = NULL; - dp->A = NULL; - dp->B = NULL; - dp->order = NULL; - dp->Gx = NULL; - dp->Gy = NULL; - dp->oid.OIDlen = 0; - dp->cofactor = 0; - - return CRYPT_OK; -} - -#endif diff --git a/src/ltc/pk/ecc/ecc_dp_set.c b/src/ltc/pk/ecc/ecc_dp_set.c deleted file mode 100644 index 33c72816..00000000 --- a/src/ltc/pk/ecc/ecc_dp_set.c +++ /dev/null @@ -1,100 +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. - * - */ - -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ - -#include "tomcrypt.h" -#include <errno.h> - -#ifdef LTC_MECC - -int ecc_dp_set(ltc_ecc_set_type *dp, char *ch_prime, char *ch_A, char *ch_B, char *ch_order, char *ch_Gx, char *ch_Gy, unsigned long cofactor, char *ch_name, char *oid) -{ - unsigned long l_name, l_prime, l_A, l_B, l_order, l_Gx, l_Gy; - - if (!dp || !ch_prime || !ch_A || !ch_B || !ch_order || !ch_Gx || !ch_Gy || cofactor==0) return CRYPT_INVALID_ARG; - - l_prime = (unsigned long)strlen(ch_prime); - l_A = (unsigned long)strlen(ch_A); - l_B = (unsigned long)strlen(ch_B); - l_order = (unsigned long)strlen(ch_order); - l_Gx = (unsigned long)strlen(ch_Gx); - l_Gy = (unsigned long)strlen(ch_Gy); - - dp->cofactor = cofactor; - - { /* calculate size */ - void *p_num; - mp_init(&p_num); - mp_read_radix(p_num, ch_prime, 16); - dp->size = mp_unsigned_bin_size(p_num); - mp_clear(p_num); - } - - if (dp->name != NULL) { XFREE(dp->name ); dp->name = NULL; } - if (dp->prime != NULL) { XFREE(dp->prime); dp->prime = NULL; } - if (dp->A != NULL) { XFREE(dp->A ); dp->A = NULL; } - if (dp->B != NULL) { XFREE(dp->B ); dp->B = NULL; } - if (dp->order != NULL) { XFREE(dp->order); dp->order = NULL; } - if (dp->Gx != NULL) { XFREE(dp->Gx ); dp->Gx = NULL; } - if (dp->Gy != NULL) { XFREE(dp->Gy ); dp->Gy = NULL; } - - dp->prime = XMALLOC(1+l_prime); strncpy(dp->prime, ch_prime, 1+l_prime); - dp->A = XMALLOC(1+l_A); strncpy(dp->A, ch_A, 1+l_A); - dp->B = XMALLOC(1+l_B); strncpy(dp->B, ch_B, 1+l_B); - dp->order = XMALLOC(1+l_order); strncpy(dp->order, ch_order, 1+l_order); - dp->Gx = XMALLOC(1+l_Gx); strncpy(dp->Gx, ch_Gx, 1+l_Gx); - dp->Gy = XMALLOC(1+l_Gy); strncpy(dp->Gy, ch_Gy, 1+l_Gy); - - /* optional parameters */ - if (ch_name == NULL && oid == NULL) { - (void)ecc_dp_fill_from_sets(dp); - } - else { - if (ch_name != NULL) { - l_name = (unsigned long)strlen(ch_name); - dp->name = XMALLOC(1+l_name); - strncpy(dp->name, ch_name, 1+l_name); - } - - if (oid != NULL) { - char *end_ptr; - unsigned int i = 0; - unsigned long val; - - end_ptr = oid; - while (i < sizeof(dp->oid.OID)/sizeof(dp->oid.OID[0]) && *oid != '\0') { - errno = 0; - val = strtoul(oid, &end_ptr, 10); - if (errno != 0 || oid == end_ptr) break; /* parsing failed */ - if (val > 0xFFFFFFFF) break; /* x64 check */ - dp->oid.OID[i++] = val; - oid = end_ptr; - if (*oid != '.') break; - oid++; - } - if (i == 0 || *end_ptr != '\0') return CRYPT_INVALID_ARG; - dp->oid.OIDlen = i; - } - } - - /* in case the parameters are really custom (unlikely) */ - if (dp->name == NULL) { - dp->name = XMALLOC(7); - strcpy(dp->name, "custom"); - dp->oid.OIDlen = 0; - } - - return CRYPT_OK; -} - -#endif diff --git a/src/ltc/pk/ecc/ecc_encrypt_key.c b/src/ltc/pk/ecc/ecc_encrypt_key.c index 8a32190b..530eadd8 100644 --- a/src/ltc/pk/ecc/ecc_encrypt_key.c +++ b/src/ltc/pk/ecc/ecc_encrypt_key.c @@ -7,9 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ #include "tomcrypt.h" /** @@ -60,9 +57,8 @@ int ecc_encrypt_key(const unsigned char *in, unsigned long inlen, } /* make a random key and export the public copy */ - if ((err = ecc_make_key_ex(prng, wprng, &pubkey, key->dp)) != CRYPT_OK) { - return err; - } + if ((err = ecc_set_dp_copy(key, &pubkey)) != CRYPT_OK) { return err; } + if ((err = ecc_generate_key(prng, wprng, &pubkey)) != CRYPT_OK) { return err; } pub_expt = XMALLOC(ECC_BUF_SIZE); ecc_shared = XMALLOC(ECC_BUF_SIZE); @@ -82,7 +78,12 @@ int ecc_encrypt_key(const unsigned char *in, unsigned long inlen, } pubkeysize = ECC_BUF_SIZE; - if ((err = ecc_export_raw(pub_expt, &pubkeysize, PK_PUBLIC|PK_COMPRESSED, &pubkey)) != CRYPT_OK) { +#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 ecc_free(&pubkey); goto LBL_ERR; } diff --git a/src/ltc/pk/ecc/ecc_export.c b/src/ltc/pk/ecc/ecc_export.c index 05aacfed..a095e9a2 100644 --- a/src/ltc/pk/ecc/ecc_export.c +++ b/src/ltc/pk/ecc/ecc_export.c @@ -7,9 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ #include "tomcrypt.h" /** @@ -42,12 +39,8 @@ int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key return CRYPT_PK_TYPE_MISMATCH; } - if (ltc_ecc_is_valid_idx(key->idx) == 0) { - return CRYPT_INVALID_ARG; - } - /* we store the NIST byte size */ - key_size = key->dp->size; + key_size = key->dp.size; if (type == PK_PRIVATE) { flags[0] = 1; diff --git a/src/ltc/pk/ecc/ecc_export_full.c b/src/ltc/pk/ecc/ecc_export_openssl.c index e7d940d5..c9181376 100644 --- a/src/ltc/pk/ecc/ecc_export_full.c +++ b/src/ltc/pk/ecc/ecc_export_openssl.c @@ -5,11 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - */ - -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * */ #include "tomcrypt.h" @@ -25,7 +20,7 @@ @return CRYPT_OK if successful */ -int ecc_export_full(unsigned char *out, unsigned long *outlen, int type, ecc_key *key) +int ecc_export_openssl(unsigned char *out, unsigned long *outlen, int type, ecc_key *key) { int err; void *prime, *order, *a, *b, *gx, *gy; @@ -33,24 +28,23 @@ int ecc_export_full(unsigned char *out, unsigned long *outlen, int type, ecc_key unsigned long len_a, len_b, len_k, len_g, len_xy; unsigned long cofactor, one = 1; oid_st oid; - ltc_asn1_list seq_fieldid[2], seq_curve[2], seq_ecparams[6], seq_priv[4], asn_ecparams[1]; + ltc_asn1_list seq_fieldid[2], seq_curve[2], seq_ecparams[6], seq_priv[4], pub_xy, ecparams; + int flag_oid = type & PK_CURVEOID ? 1 : 0; + int flag_com = type & PK_COMPRESSED ? 1 : 0; + int flag_pri = type & PK_PRIVATE ? 1 : 0; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); - if (key->type != PK_PRIVATE && type == PK_PRIVATE) return CRYPT_PK_TYPE_MISMATCH; - if (ltc_ecc_is_valid_idx(key->idx) == 0) return CRYPT_INVALID_ARG; - if (key->dp == NULL) return CRYPT_INVALID_ARG; - - if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, NULL)) != CRYPT_OK) return err; + if (key->type != PK_PRIVATE && flag_pri) return CRYPT_PK_TYPE_MISMATCH; - if ((err = mp_read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) goto error; - if ((err = mp_read_radix(order, key->dp->order, 16)) != CRYPT_OK) goto error; - if ((err = mp_read_radix(b, key->dp->B, 16)) != CRYPT_OK) goto error; - if ((err = mp_read_radix(a, key->dp->A, 16)) != CRYPT_OK) goto error; - if ((err = mp_read_radix(gx, key->dp->Gx, 16)) != CRYPT_OK) goto error; - if ((err = mp_read_radix(gy, key->dp->Gy, 16)) != CRYPT_OK) goto error; + prime = key->dp.prime; + order = key->dp.order; + b = key->dp.B; + a = key->dp.A; + gx = key->dp.base.x; + gy = key->dp.base.y; /* curve param a */ len_a = mp_unsigned_bin_size(a); @@ -64,33 +58,32 @@ int ecc_export_full(unsigned char *out, unsigned long *outlen, int type, ecc_key if ((err = mp_to_unsigned_bin(b, bin_b)) != CRYPT_OK) goto error; if (len_b == 0) { len_b = 1; bin_b[0] = 0; } /* XXX-TODO hack to handle case b == 0 */ - /* base point - we export uncompressed form */ + /* base point - (un)compressed based on flag_com */ len_g = sizeof(bin_g); - if ((err = ltc_ecc_export_point(bin_g, &len_g, gx, gy, key->dp->size, 0)) != CRYPT_OK) goto error; + if ((err = ltc_ecc_export_point(bin_g, &len_g, gx, gy, key->dp.size, flag_com)) != CRYPT_OK) goto error; - /* public key */ + /* public key - (un)compressed based on flag_com */ len_xy = sizeof(bin_xy); - if ((err = ltc_ecc_export_point(bin_xy, &len_xy, key->pubkey.x, key->pubkey.y, key->dp->size, 0)) != CRYPT_OK) goto error; + if ((err = ltc_ecc_export_point(bin_xy, &len_xy, key->pubkey.x, key->pubkey.y, key->dp.size, flag_com)) != CRYPT_OK) goto error; /* co-factor */ - cofactor = key->dp->cofactor; + cofactor = key->dp.cofactor; /* we support only prime-field EC */ - if ((err = pk_get_oid(EC_PRIME_FIELD, &oid)) != CRYPT_OK) goto error; + if ((err = pk_get_oid(PKA_EC_PRIMEF, &oid)) != CRYPT_OK) goto error; - if (type & PK_CURVEOID) { + if (flag_oid) { /* from http://tools.ietf.org/html/rfc5912 ECParameters ::= CHOICE { namedCurve CURVE.&id({NamedCurve}) # OBJECT } */ - - /* BEWARE: exporting PK_CURVEOID with custom OID means we're unable to read the curve again */ - if (key->dp->oid.OIDlen == 0) { err = CRYPT_INVALID_ARG; goto error; } - - /* ECParameters used by ECPrivateKey or SubjectPublicKeyInfo below */ - LTC_SET_ASN1(asn_ecparams, 0, LTC_ASN1_OBJECT_IDENTIFIER, key->dp->oid.OID, key->dp->oid.OIDlen); + if (key->dp.oidlen == 0) { + err = CRYPT_INVALID_ARG; + goto error; + } + LTC_SET_ASN1(&ecparams, 0, LTC_ASN1_OBJECT_IDENTIFIER, key->dp.oid, key->dp.oidlen); } else { /* from http://tools.ietf.org/html/rfc3279 @@ -129,12 +122,10 @@ int ecc_export_full(unsigned char *out, unsigned long *outlen, int type, ecc_key LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL); /* ECParameters used by ECPrivateKey or SubjectPublicKeyInfo below */ - LTC_SET_ASN1(asn_ecparams, 0, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL); + LTC_SET_ASN1(&ecparams, 0, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL); } - type &= ~PK_CURVEOID; - - if (type == PK_PRIVATE) { + if (flag_pri) { /* private key format: http://tools.ietf.org/html/rfc5915 ECPrivateKey ::= SEQUENCE { # SEQUENCE @@ -150,12 +141,11 @@ int ecc_export_full(unsigned char *out, unsigned long *outlen, int type, ecc_key if (len_k > sizeof(bin_k)) { err = CRYPT_BUFFER_OVERFLOW; goto error; } if ((err = mp_to_unsigned_bin(key->k, bin_k)) != CRYPT_OK) goto error; - LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &one, 1UL); - LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, len_k); - LTC_SET_ASN1(seq_priv, 2, asn_ecparams[0].type, asn_ecparams[0].data, asn_ecparams[0].size); - LTC_SET_ASN1(seq_priv, 3, LTC_ASN1_RAW_BIT_STRING, bin_xy, 8*len_xy); - seq_priv[2].tag = 0xA0; - seq_priv[3].tag = 0xA1; + LTC_SET_ASN1(&pub_xy, 0, LTC_ASN1_RAW_BIT_STRING, bin_xy, 8*len_xy); + LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &one, 1); + LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, len_k); + LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 2, LTC_ASN1_CL_CONTEXT_SPECIFIC, 0, &ecparams); /* context specific 0 */ + LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 3, LTC_ASN1_CL_CONTEXT_SPECIFIC, 1, &pub_xy); /* context specific 1 */ err = der_encode_sequence(seq_priv, 4, out, outlen); } @@ -170,14 +160,17 @@ int ecc_export_full(unsigned char *out, unsigned long *outlen, int type, ecc_key subjectPublicKey BIT STRING # BIT STRING } */ - err = der_encode_subject_public_key_info( out, outlen, + err = x509_encode_subject_public_key_info( out, outlen, PKA_EC, bin_xy, len_xy, - asn_ecparams[0].type, asn_ecparams[0].data, asn_ecparams[0].size ); + ecparams.type, ecparams.data, ecparams.size ); } error: - mp_clear_multi(prime, order, a, b, gx, gy, NULL); return err; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/ecc/ecc_free.c b/src/ltc/pk/ecc/ecc_free.c index e25d7c58..c8033b3b 100644 --- a/src/ltc/pk/ecc/ecc_free.c +++ b/src/ltc/pk/ecc/ecc_free.c @@ -7,9 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ #include "tomcrypt.h" /** @@ -26,7 +23,14 @@ void ecc_free(ecc_key *key) { LTC_ARGCHKVD(key != NULL); - mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, 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); } #endif diff --git a/src/ltc/pk/ecc/ecc_export_raw.c b/src/ltc/pk/ecc/ecc_get_key.c index ed4966dd..2b4e8574 100644 --- a/src/ltc/pk/ecc/ecc_export_raw.c +++ b/src/ltc/pk/ecc/ecc_get_key.c @@ -5,11 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - */ - -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * */ #include "tomcrypt.h" @@ -24,7 +19,7 @@ Return CRYPT_OK on success */ -int ecc_export_raw(unsigned char *out, unsigned long *outlen, int type, ecc_key *key) +int ecc_get_key(unsigned char *out, unsigned long *outlen, int type, ecc_key *key) { unsigned long size, ksize; int err, compressed; @@ -33,19 +28,14 @@ int ecc_export_raw(unsigned char *out, unsigned long *outlen, int type, ecc_key LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); - if (ltc_ecc_is_valid_idx(key->idx) == 0) { - return CRYPT_INVALID_ARG; - } - size = key->dp->size; - - compressed = type & PK_COMPRESSED; + size = key->dp.size; + compressed = type & PK_COMPRESSED ? 1 : 0; type &= ~PK_COMPRESSED; - if (type == PK_PUBLIC && compressed) { - if ((err = ltc_ecc_export_point(out, outlen, key->pubkey.x, key->pubkey.y, size, 1)) != CRYPT_OK) return err; - } - else if (type == PK_PUBLIC) { - if ((err = ltc_ecc_export_point(out, outlen, key->pubkey.x, key->pubkey.y, size, 0)) != CRYPT_OK) return err; + if (type == PK_PUBLIC) { + if ((err = ltc_ecc_export_point(out, outlen, key->pubkey.x, key->pubkey.y, size, compressed)) != CRYPT_OK) { + return err; + } } else if (type == PK_PRIVATE) { if (key->type != PK_PRIVATE) return CRYPT_PK_TYPE_MISMATCH; @@ -64,3 +54,7 @@ int ecc_export_raw(unsigned char *out, unsigned long *outlen, int type, ecc_key } #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 new file mode 100644 index 00000000..f00cf45f --- /dev/null +++ b/src/ltc/pk/ecc/ecc_get_set.c @@ -0,0 +1,40 @@ +/* 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_get_size.c b/src/ltc/pk/ecc/ecc_get_size.c index f77ab8b3..8d1c9362 100644 --- a/src/ltc/pk/ecc/ecc_get_size.c +++ b/src/ltc/pk/ecc/ecc_get_size.c @@ -7,9 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ #include "tomcrypt.h" /** @@ -26,11 +23,10 @@ */ int ecc_get_size(ecc_key *key) { - LTC_ARGCHK(key != NULL); - if (ltc_ecc_is_valid_idx(key->idx)) - return key->dp->size; - else - return INT_MAX; /* large value known to cause it to fail when passed to ecc_make_key() */ + if (key == NULL) { + return INT_MAX; + } + return key->dp.size; } #endif diff --git a/src/ltc/pk/ecc/ecc_import.c b/src/ltc/pk/ecc/ecc_import.c index 38465b12..3a1dcc57 100644 --- a/src/ltc/pk/ecc/ecc_import.c +++ b/src/ltc/pk/ecc/ecc_import.c @@ -7,9 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ #include "tomcrypt.h" /** @@ -49,18 +46,20 @@ int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, co LTC_ARGCHK(key != NULL); LTC_ARGCHK(ltc_mp.name != NULL); - /* init key */ - if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL) != CRYPT_OK) { - return CRYPT_MEM; - } - /* find out what type of key it is */ - err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, flags, - LTC_ASN1_EOL, 0UL, NULL); + err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, + LTC_ASN1_EOL, 0UL, NULL); if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) { - goto done; + return err; } + /* allocate & initialize the key */ + if (dp == NULL) { + if ((err = ecc_set_dp_size(key_size, key)) != CRYPT_OK) { goto done; } + } else { + if ((err = ecc_set_dp(dp, key)) != CRYPT_OK) { goto done; } + } if (flags[0] == 1) { /* private key */ @@ -91,30 +90,17 @@ int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, co goto done; } - if (dp == NULL) { - /* find the idx */ - for (key->idx = 0; ltc_ecc_sets[key->idx].size && (unsigned long)ltc_ecc_sets[key->idx].size != key_size; ++key->idx); - if (ltc_ecc_sets[key->idx].size == 0) { - err = CRYPT_INVALID_PACKET; - goto done; - } - key->dp = <c_ecc_sets[key->idx]; - } else { - key->idx = -1; - key->dp = dp; - } /* set z */ if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto done; } - /* is it a point on the curve? */ - if ((err = ltc_ecc_is_point(key->dp, key->pubkey.x, key->pubkey.y)) != CRYPT_OK) { - goto done; - } + /* point on the curve + other checks */ + if ((err = ltc_ecc_verify_key(key)) != CRYPT_OK) { goto done; } /* we're good */ return CRYPT_OK; + done: - mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL); + ecc_free(key); return err; } #endif diff --git a/src/ltc/pk/ecc/ecc_import_full.c b/src/ltc/pk/ecc/ecc_import_full.c deleted file mode 100644 index 0e5093d4..00000000 --- a/src/ltc/pk/ecc/ecc_import_full.c +++ /dev/null @@ -1,152 +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. - */ - -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ - -#include "tomcrypt.h" - -#ifdef LTC_MECC - -int ecc_import_full(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp) -{ - void *prime, *order, *a, *b, *gx, *gy; - ltc_asn1_list seq_fieldid[2], seq_curve[3], seq_ecparams[6], seq_priv[4]; - unsigned char bin_a[ECC_MAXSIZE], bin_b[ECC_MAXSIZE], bin_k[ECC_MAXSIZE], bin_g[2*ECC_MAXSIZE+1], bin_xy[2*ECC_MAXSIZE+2], bin_seed[128]; - unsigned long len_a, len_b, len_k, len_g, len_xy, len_oid; - unsigned long cofactor = 0, ecver = 0, pkver = 0, tmpoid[16], curveoid[16]; - int err; - - if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, NULL)) != CRYPT_OK) return err; - - /* ### 1. try to load public key - no curve parameters just curve OID */ - - len_xy = sizeof(bin_xy); - err = der_decode_subject_public_key_info_ex(in, inlen, PKA_EC, bin_xy, &len_xy, LTC_ASN1_OBJECT_IDENTIFIER, curveoid, 16UL, &len_oid); - if (err == CRYPT_OK) { - /* load curve parameters for given curve OID */ - if ((err = ecc_dp_set_by_oid(dp, curveoid, len_oid)) != CRYPT_OK) { goto error; } - /* load public key */ - if ((err = ecc_import_raw(bin_xy, len_xy, key, dp)) != CRYPT_OK) { goto error; } - goto success; - } - - /* ### 2. try to load public key - curve parameters included */ - - /* ECParameters SEQUENCE */ - LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL); - LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL); - LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL); - LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, (unsigned long)2*ECC_MAXSIZE+1); - LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL); - LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL); - seq_ecparams[5].optional = 1; - /* FieldID SEQUENCE */ - LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL); - LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL); - /* Curve SEQUENCE */ - LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, (unsigned long)ECC_MAXSIZE); - LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, (unsigned long)ECC_MAXSIZE); - LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, (unsigned long)8*128); - seq_curve[2].optional = 1; - /* try to load public key */ - len_xy = sizeof(bin_xy); - err = der_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy, LTC_ASN1_SEQUENCE, seq_ecparams, 6); - - if (err == CRYPT_OK) { - len_a = seq_curve[0].size; - len_b = seq_curve[1].size; - len_g = seq_ecparams[3].size; - /* create bignums */ - if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; } - 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_dp_set_bn(dp, a, b, prime, order, gx, gy, cofactor)) != CRYPT_OK) { goto error; } - /* load public key */ - if ((err = ecc_import_raw(bin_xy, len_xy, key, dp)) != CRYPT_OK) { goto error; } - goto success; - } - - /* ### 3. try to load private key - no curve parameters just curve OID */ - - /* ECPrivateKey SEQUENCE */ - LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &pkver, 1UL); - LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, (unsigned long)ECC_MAXSIZE); - LTC_SET_ASN1(seq_priv, 2, LTC_ASN1_OBJECT_IDENTIFIER, curveoid, 16UL); - LTC_SET_ASN1(seq_priv, 3, LTC_ASN1_RAW_BIT_STRING, bin_xy, (unsigned long)8*(2*ECC_MAXSIZE+2)); - seq_priv[2].tag = 0xA0; /* context specific 0 */ - seq_priv[3].tag = 0xA1; /* context specific 1 */ - /* try to load private key */ - err = der_decode_sequence(in, inlen, seq_priv, 4); - - if (err == CRYPT_OK) { - /* load curve parameters for given curve OID */ - if ((err = ecc_dp_set_by_oid(dp, curveoid, seq_priv[2].size)) != CRYPT_OK) { goto error; } - /* load private+public key */ - if ((err = ecc_import_raw(bin_k, seq_priv[1].size, key, dp)) != CRYPT_OK) { goto error; } - goto success; - } - - /* ### 4. try to load private key - curve parameters included */ - - /* ECPrivateKey SEQUENCE */ - LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &pkver, 1UL); - LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, (unsigned long)ECC_MAXSIZE); - LTC_SET_ASN1(seq_priv, 2, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL); - LTC_SET_ASN1(seq_priv, 3, LTC_ASN1_RAW_BIT_STRING, bin_xy, (unsigned long)8*(2*ECC_MAXSIZE+2)); - seq_priv[2].tag = 0xA0; /* context specific 0 */ - seq_priv[3].tag = 0xA1; /* context specific 1 */ - /* ECParameters SEQUENCE */ - LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL); - LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL); - LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL); - LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, (unsigned long)2*ECC_MAXSIZE+1); - LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL); - LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL); - seq_ecparams[5].optional = 1; - /* FieldID SEQUENCE */ - LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL); - LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL); - /* Curve SEQUENCE */ - LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, (unsigned long)ECC_MAXSIZE); - LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, (unsigned long)ECC_MAXSIZE); - LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, (unsigned long)8*128); - seq_curve[2].optional = 1; - /* try to load private key */ - err = der_decode_sequence(in, inlen, seq_priv, 4); - if (err == CRYPT_OK) { - len_k = seq_priv[1].size; - len_xy = seq_priv[3].size; - len_a = seq_curve[0].size; - len_b = seq_curve[1].size; - len_g = seq_ecparams[3].size; - /* create bignums */ - if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; } - 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_dp_set_bn(dp, a, b, prime, order, gx, gy, cofactor)) != CRYPT_OK) { goto error; } - /* load private+public key */ - if ((err = ecc_import_raw(bin_k, len_k, key, dp)) != CRYPT_OK) { goto error; } - goto success; - } - - /* ### 5. backward compatibility - try to load old-DER format */ - if ((err = ecc_import(in, inlen, key)) != CRYPT_OK) { goto error; } - -success: - err = CRYPT_OK; -error: - mp_clear_multi(prime, order, a, b, gx, gy, NULL); - return err; -} - -#endif diff --git a/src/ltc/pk/ecc/ecc_import_openssl.c b/src/ltc/pk/ecc/ecc_import_openssl.c new file mode 100644 index 00000000..abbf5052 --- /dev/null +++ b/src/ltc/pk/ecc/ecc_import_openssl.c @@ -0,0 +1,157 @@ +/* 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_import_openssl(const unsigned char *in, unsigned long inlen, ecc_key *key) +{ + void *prime, *order, *a, *b, *gx, *gy; + ltc_asn1_list seq_fieldid[2], seq_curve[3], seq_ecparams[6], seq_priv[4], custom[2]; + unsigned char bin_a[ECC_MAXSIZE], bin_b[ECC_MAXSIZE], bin_k[ECC_MAXSIZE], bin_g[2*ECC_MAXSIZE+1], bin_xy[2*ECC_MAXSIZE+2], bin_seed[128]; + unsigned long len_a, len_b, len_k, len_g, len_xy, len_oid, len; + unsigned long cofactor = 0, ecver = 0, pkver = 0, tmpoid[16], curveoid[16]; + int err; + + if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, NULL)) != CRYPT_OK) { + return err; + } + + /* ### 1. try to load public key - no curve parameters just curve OID */ + + len_xy = sizeof(bin_xy); + len_oid = 16; + err = x509_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy, LTC_ASN1_OBJECT_IDENTIFIER, 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; } + /* load public key */ + if ((err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key)) != CRYPT_OK) { goto error; } + goto success; + } + + /* ### 2. try to load public key - curve parameters included */ + + /* ECParameters SEQUENCE */ + LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL); + LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL); + LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL); + LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, (unsigned long)2*ECC_MAXSIZE+1); + LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL); + LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL); + seq_ecparams[5].optional = 1; + /* FieldID SEQUENCE */ + LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL); + LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL); + /* Curve SEQUENCE */ + LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, (unsigned long)ECC_MAXSIZE); + LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, (unsigned long)ECC_MAXSIZE); + LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, (unsigned long)8*128); + seq_curve[2].optional = 1; + /* try to load public key */ + len_xy = sizeof(bin_xy); + len = 6; + err = x509_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy, LTC_ASN1_SEQUENCE, seq_ecparams, &len); + + if (err == CRYPT_OK) { + len_a = seq_curve[0].size; + len_b = seq_curve[1].size; + len_g = seq_ecparams[3].size; + /* create bignums */ + if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; } + 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; } + /* load public key */ + if ((err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key)) != CRYPT_OK) { goto error; } + goto success; + } + + /* ### 3. try to load private key - no curve parameters just curve OID */ + + /* ECPrivateKey SEQUENCE */ + LTC_SET_ASN1(custom, 0, LTC_ASN1_OBJECT_IDENTIFIER, curveoid, 16UL); + LTC_SET_ASN1(custom, 1, LTC_ASN1_RAW_BIT_STRING, bin_xy, (unsigned long)8*(2*ECC_MAXSIZE+2)); + LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &pkver, 1UL); + LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, (unsigned long)ECC_MAXSIZE); + LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 2, LTC_ASN1_CL_CONTEXT_SPECIFIC, 0, custom); /* context specific 0 */ + LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 3, LTC_ASN1_CL_CONTEXT_SPECIFIC, 1, custom + 1); /* context specific 1 */ + + /* try to load private key */ + 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; } + /* load private+public key */ + if ((err = ecc_set_key(bin_k, seq_priv[1].size, PK_PRIVATE, key)) != CRYPT_OK) { goto error; } + goto success; + } + + /* ### 4. try to load private key - curve parameters included */ + + /* ECPrivateKey SEQUENCE */ + LTC_SET_ASN1(custom, 0, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL); + LTC_SET_ASN1(custom, 1, LTC_ASN1_RAW_BIT_STRING, bin_xy, (unsigned long)8*(2*ECC_MAXSIZE+2)); + LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &pkver, 1UL); + LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, (unsigned long)ECC_MAXSIZE); + LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 2, LTC_ASN1_CL_CONTEXT_SPECIFIC, 0, custom); /* context specific 0 */ + LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 3, LTC_ASN1_CL_CONTEXT_SPECIFIC, 1, custom + 1); /* context specific 1 */ + /* ECParameters SEQUENCE */ + LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL); + LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL); + LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL); + LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, (unsigned long)2*ECC_MAXSIZE+1); + LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL); + LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL); + seq_ecparams[5].optional = 1; + /* FieldID SEQUENCE */ + LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL); + LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL); + /* Curve SEQUENCE */ + LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, (unsigned long)ECC_MAXSIZE); + LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, (unsigned long)ECC_MAXSIZE); + LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, (unsigned long)8*128); + seq_curve[2].optional = 1; + /* try to load private key */ + err = der_decode_sequence(in, inlen, seq_priv, 4); + if (err == CRYPT_OK) { + len_xy = custom[1].size; + len_k = seq_priv[1].size; + len_a = seq_curve[0].size; + len_b = seq_curve[1].size; + len_g = seq_ecparams[3].size; + /* create bignums */ + if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; } + 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; } + /* load private+public key */ + if ((err = ecc_set_key(bin_k, len_k, PK_PRIVATE, key)) != CRYPT_OK) { goto error; } + goto success; + } + + /* ### 5. backward compatibility - try to load old-DER format */ + + if ((err = ecc_import(in, inlen, key)) != CRYPT_OK) { goto error; } + +success: + err = CRYPT_OK; +error: + mp_clear_multi(prime, order, a, b, gx, gy, NULL); + return err; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/ecc/ecc_import_pkcs8.c b/src/ltc/pk/ecc/ecc_import_pkcs8.c index 85f8d218..6b5b0c71 100644 --- a/src/ltc/pk/ecc/ecc_import_pkcs8.c +++ b/src/ltc/pk/ecc/ecc_import_pkcs8.c @@ -7,153 +7,597 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ - #include "tomcrypt.h" #ifdef LTC_MECC -int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen, - const void *pwd, unsigned long pwdlen, - ecc_key *key, ltc_ecc_set_type *dp) +enum algorithm_oid { + PBE_MD2_DES, /* 0 */ + PBE_MD2_RC2, + PBE_MD5_DES, + PBE_MD5_RC2, + PBE_SHA1_DES, + PBE_SHA1_RC2, /* 5 */ + PBES2, + PBKDF2, + DES_CBC, + RC2_CBC, + DES_EDE3_CBC, /* 10 */ + HMAC_WITH_SHA1, + HMAC_WITH_SHA224, + HMAC_WITH_SHA256, + HMAC_WITH_SHA384, + HMAC_WITH_SHA512, /* 15 */ + PBE_SHA1_3DES +}; + +static const oid_st oid_list[] = { + { { 1,2,840,113549,1,5,1 }, 7 }, /* [0] http://www.oid-info.com/get/1.2.840.113549.1.5.1 pbeWithMD2AndDES-CBC */ + { { 1,2,840,113549,1,5,4 }, 7 }, /* [1] http://www.oid-info.com/get/1.2.840.113549.1.5.4 pbeWithMD2AndRC2-CBC */ + { { 1,2,840,113549,1,5,3 }, 7 }, /* [2] http://www.oid-info.com/get/1.2.840.113549.1.5.3 pbeWithMD5AndDES-CBC */ + { { 1,2,840,113549,1,5,6 }, 7 }, /* [3] http://www.oid-info.com/get/1.2.840.113549.1.5.6 pbeWithMD5AndRC2-CBC */ + { { 1,2,840,113549,1,5,10 }, 7 }, /* [4] http://www.oid-info.com/get/1.2.840.113549.1.5.10 pbeWithSHA1AndDES-CBC */ + { { 1,2,840,113549,1,5,11 }, 7 }, /* [5] http://www.oid-info.com/get/1.2.840.113549.1.5.11 pbeWithSHA1AndRC2-CBC */ + { { 1,2,840,113549,1,5,13 }, 7 }, /* [6] http://www.oid-info.com/get/1.2.840.113549.1.5.13 pbes2 */ + { { 1,2,840,113549,1,5,12 }, 7 }, /* [7] http://www.oid-info.com/get/1.2.840.113549.1.5.12 pBKDF2 */ + { { 1,3,14,3,2,7 }, 6 }, /* [8] http://www.oid-info.com/get/1.3.14.3.2.7 desCBC */ + { { 1,2,840,113549,3,2 }, 6 }, /* [9] http://www.oid-info.com/get/1.2.840.113549.3.2 rc2CBC */ + { { 1,2,840,113549,3,7 }, 6 }, /* [10] http://www.oid-info.com/get/1.2.840.113549.3.7 des-EDE3-CBC */ + { { 1,2,840,113549,2,7 }, 6 }, /* [11] http://www.oid-info.com/get/1.2.840.113549.2.7 hmacWithSHA1 */ + { { 1,2,840,113549,2,8 }, 6 }, /* [12] http://www.oid-info.com/get/1.2.840.113549.2.8 hmacWithSHA224 */ + { { 1,2,840,113549,2,9 }, 6 }, /* [13] http://www.oid-info.com/get/1.2.840.113549.2.9 hmacWithSHA256 */ + { { 1,2,840,113549,2,10 }, 6 }, /* [14] http://www.oid-info.com/get/1.2.840.113549.2.10 hmacWithSHA384 */ + { { 1,2,840,113549,2,11 }, 6 }, /* [15] http://www.oid-info.com/get/1.2.840.113549.2.11 hmacWithSHA512 */ + { { 1,2,840,113549,1,12,1,3 }, 8 }, /* [16] http://www.oid-info.com/get/1.2.840.113549.1.12.1.3 pbeWithSHAAnd3-KeyTripleDES-CBC */ + { { 0 }, 0 }, +}; + +static int _simple_utf8_to_utf16(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) { + unsigned long len = 0; + const unsigned char* in_end = in + inlen; + const ulong32 offset[6] = { + 0x00000000UL, 0x00003080UL, 0x000E2080UL, + 0x03C82080UL, 0xFA082080UL, 0x82082080UL + }; + int err = CRYPT_ERROR; + + while (in < in_end) { + ulong32 ch = 0; + unsigned short extra = 0; /* 0 */ + if (*in >= 192) extra++; /* 1 */ + if (*in >= 224) extra++; /* 2 */ + if (*in >= 240) extra++; /* 3 */ + if (*in >= 248) extra++; /* 4 */ + if (*in >= 252) extra++; /* 5 */ + if (in + extra >= in_end) goto ERROR; + switch (extra) { + case 5: ch += *in++; ch <<= 6; + case 4: ch += *in++; ch <<= 6; + case 3: ch += *in++; ch <<= 6; + case 2: ch += *in++; ch <<= 6; + case 1: ch += *in++; ch <<= 6; + case 0: ch += *in++; + } + ch -= offset[extra]; + if (ch > 0xFFFF) goto ERROR; + if (*outlen >= len + 2) { + out[len] = (unsigned short)((ch >> 8) & 0xFF); + out[len + 1] = (unsigned char)(ch & 0xFF); + } + len += 2; + } + + err = len > *outlen ? CRYPT_BUFFER_OVERFLOW : CRYPT_OK; + *outlen = len; +ERROR: + return err; +} + +static int _kdf_pkcs12(int hash_id, const unsigned char *pw, unsigned long pwlen, + const unsigned char *salt, unsigned long saltlen, + unsigned int iterations, unsigned char purpose, + unsigned char *out, unsigned long outlen) { - int err; - void *zero, *one, *iter; - unsigned char *buf1=NULL, *buf2=NULL; - unsigned long buf1len, buf2len; - unsigned long oid[16]; - oid_st ecoid; - ltc_asn1_list alg_seq[2], top_seq[3]; - ltc_asn1_list alg_seq_e[2], key_seq_e[2], top_seq_e[2]; - unsigned char *decrypted=NULL; - unsigned long decryptedlen; - void *prime, *order, *a, *b, *gx, *gy; - ltc_asn1_list seq_fieldid[2], seq_curve[3], seq_ecparams[6], seq_priv[4]; - unsigned char bin_a[ECC_MAXSIZE], bin_b[ECC_MAXSIZE], bin_k[ECC_MAXSIZE], bin_g[2*ECC_MAXSIZE+1], bin_xy[2*ECC_MAXSIZE+2], bin_seed[128]; - unsigned long len_a, len_b, len_g; - unsigned long cofactor = 0, ecver = 0, tmpoid[16], curveoid[16]; + unsigned long u = hash_descriptor[hash_id].hashsize; + unsigned long v = hash_descriptor[hash_id].blocksize; + unsigned long c = (outlen + u - 1) / u; + unsigned long Slen = ((saltlen + v - 1) / v) * v; + unsigned long Plen = ((pwlen + v - 1) / v) * v; + unsigned long k = (Plen + Slen) / v; + unsigned long Alen, keylen = 0; + unsigned int tmp, i, j, n; + unsigned char ch; + unsigned char D[MAXBLOCKSIZE], A[MAXBLOCKSIZE], B[MAXBLOCKSIZE]; + unsigned char *I = NULL, *key = NULL; + int err = CRYPT_ERROR; - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(key != NULL); - LTC_ARGCHK(ltc_mp.name != NULL); + key = XMALLOC(u * c); + I = XMALLOC(Plen + Slen); + if (key == NULL || I == NULL) goto DONE; - /* get EC alg oid */ - err = pk_get_oid(PKA_EC, &ecoid); - if (err != CRYPT_OK) { goto LBL_NOFREE; } + for (i = 0; i < v; i++) D[i] = purpose; /* D - diversifier */ + for (i = 0; i < Slen; i++) I[i] = salt[i % saltlen]; + for (i = 0; i < Plen; i++) I[Slen + i] = pw[i % pwlen]; /* I = Salt || Pass */ + + for (i = 0; i < c; i++) { + Alen = u; /* hash size */ + err = hash_memory_multi(hash_id, A, &Alen, D, v, I, Slen + Plen, NULL); /* A = HASH(D || I) */ + if (err != CRYPT_OK) goto DONE; + for (j = 1; j < iterations; j++) { + err = hash_memory(hash_id, A, Alen, A, &Alen); /* A = HASH(A) */ + if (err != CRYPT_OK) goto DONE; + } + /* fill buffer B with A */ + for (j = 0; j < v; j++) B[j] = A[j % Alen]; + /* B += 1 */ + for (j = v; j > 0; j--) { + if (++B[j - 1] != 0) break; + } + /* I_n += B */ + for (n = 0; n < k; n++) { + ch = 0; + for (j = v; j > 0; j--) { + tmp = I[n * v + j - 1] + B[j - 1] + ch; + ch = (unsigned char)((tmp >> 8) & 0xFF); + I[n * v + j - 1] = (unsigned char)(tmp & 0xFF); + } + } + /* store derived key block */ + for (j = 0; j < Alen; j++) key[keylen++] = A[j]; + } - /* alloc buffers */ - buf1len = inlen; /* approx. guess */ - buf1 = XMALLOC(buf1len); - if (buf1 == NULL) { err = CRYPT_MEM; goto LBL_NOFREE; } - buf2len = inlen; /* approx. guess */ - buf2 = XMALLOC(buf2len); - if (buf2 == NULL) { err = CRYPT_MEM; goto LBL_FREE; } + for (i = 0; i < outlen; i++) out[i] = key[i]; + err = CRYPT_OK; +DONE: + if (I) XFREE(I); + if (key) XFREE(key); + return err; +} - /* init key */ - err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, &zero, &one, &iter, NULL); - if (err != CRYPT_OK) { goto LBL_NOCLEAR; } - - /* try to decode encrypted priv key */ - LTC_SET_ASN1(key_seq_e, 0, LTC_ASN1_OCTET_STRING, buf1, buf1len); - LTC_SET_ASN1(key_seq_e, 1, LTC_ASN1_INTEGER, iter, 1UL); - LTC_SET_ASN1(alg_seq_e, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, 16UL); - LTC_SET_ASN1(alg_seq_e, 1, LTC_ASN1_SEQUENCE, key_seq_e, 2UL); - LTC_SET_ASN1(top_seq_e, 0, LTC_ASN1_SEQUENCE, alg_seq_e, 2UL); - LTC_SET_ASN1(top_seq_e, 1, LTC_ASN1_OCTET_STRING, buf2, buf2len); - err=der_decode_sequence(in, inlen, top_seq_e, 2UL); - if (err == CRYPT_OK) { - LTC_UNUSED_PARAM(pwd); - LTC_UNUSED_PARAM(pwdlen); - /* unsigned long icount = mp_get_int(iter); */ - /* XXX: TODO decrypt buf1 with a key derived form password + salt + iter */ - /* fprintf(stderr, "XXX-DEBUG: gonna decrypt: iter=%ld salt.len=%ld encdata.len=%ld\n", icount, key_seq_e[0].size, top_seq_e[1].size); */ - err = CRYPT_PK_INVALID_TYPE; - goto LBL_ERR; +static int _oid_to_id(const unsigned long *oid, unsigned long oid_size) +{ + int i, j; + for (j = 0; oid_list[j].OIDlen > 0; j++) { + int match = 1; + if (oid_list[j].OIDlen != oid_size) continue; + for (i = 0; i < (int)oid_size && match; i++) if (oid_list[j].OID[i] != oid[i]) match = 0; + if (match) return j; } - else { - decrypted = (unsigned char*)in; - decryptedlen = inlen; + return -1; +} + +static int _pbes1_decrypt(const unsigned char *enc_data, unsigned long enc_size, + const unsigned char *pass, unsigned long pass_size, + const unsigned char *salt, unsigned long salt_size, + unsigned long iterations, + const unsigned long *oid, unsigned long oid_size, + unsigned char *dec_data, unsigned long *dec_size) +{ + int id = _oid_to_id(oid, oid_size); + int err, hid = -1, cid = -1; + unsigned int keylen, blklen; + unsigned char key_iv[32] = { 0 }, pad; + unsigned long len = sizeof(key_iv), pwlen = pass_size; + symmetric_CBC cbc; + unsigned char *pw = NULL; + + /* https://tools.ietf.org/html/rfc8018#section-6.1.2 */ + if (id == PBE_MD2_DES || id == PBE_MD2_RC2) hid = find_hash("md2"); + if (id == PBE_MD5_DES || id == PBE_MD5_RC2) hid = find_hash("md5"); + if (id == PBE_SHA1_DES || id == PBE_SHA1_RC2 || id == PBE_SHA1_3DES) hid = find_hash("sha1"); + + if (id == PBE_MD2_RC2 || id == PBE_MD5_RC2 || id == PBE_SHA1_RC2) { + cid = find_cipher("rc2"); + keylen = 8; + blklen = 8; + } + if (id == PBE_MD2_DES || id == PBE_MD5_DES || id == PBE_SHA1_DES) { + cid = find_cipher("des"); + keylen = 8; + blklen = 8; + } + if (id == PBE_SHA1_3DES) { + cid = find_cipher("3des"); + keylen = 24; + blklen = 8; } - /* try to decode unencrypted priv key - curve defined by OID */ - LTC_SET_ASN1(alg_seq, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, 16UL); - LTC_SET_ASN1(alg_seq, 1, LTC_ASN1_OBJECT_IDENTIFIER, curveoid, 16UL); - LTC_SET_ASN1(top_seq, 0, LTC_ASN1_INTEGER, zero, 1UL); - LTC_SET_ASN1(top_seq, 1, LTC_ASN1_SEQUENCE, alg_seq, 2UL); - LTC_SET_ASN1(top_seq, 2, LTC_ASN1_OCTET_STRING, buf1, buf1len); - err=der_decode_sequence(decrypted, decryptedlen, top_seq, 3UL); - if (err == CRYPT_OK) { - /* load curve parameters for given curve OID */ - err = ecc_dp_set_by_oid(dp, curveoid, alg_seq[1].size); - if (err != CRYPT_OK) { goto LBL_ERR; } + if (id == PBE_SHA1_3DES) { + /* convert password to unicode/utf16-be */ + pwlen = pass_size * 2; + pw = XMALLOC(pwlen + 2); + if (pw == NULL) goto LBL_ERROR; + if ((err = _simple_utf8_to_utf16(pass, pass_size, pw, &pwlen) != CRYPT_OK)) goto LBL_ERROR; + pw[pwlen++] = 0; + pw[pwlen++] = 0; + /* derive KEY */ + if ((err = _kdf_pkcs12(hid, pw, pwlen, salt, salt_size, iterations, 1, key_iv, keylen)) != CRYPT_OK) goto LBL_ERROR; + /* derive IV */ + if ((err = _kdf_pkcs12(hid, pw, pwlen, salt, salt_size, iterations, 2, key_iv+24, blklen)) != CRYPT_OK) goto LBL_ERROR; } else { - /* try to decode unencrypted priv key - curve defined by params */ - /* ECParameters SEQUENCE */ - LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL); - LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL); - LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL); - LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, (unsigned long)2*ECC_MAXSIZE+1); - LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL); - LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL); - seq_ecparams[5].optional = 1; - /* FieldID SEQUENCE */ - LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL); - LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL); - /* Curve SEQUENCE */ - LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, (unsigned long)ECC_MAXSIZE); - LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, (unsigned long)ECC_MAXSIZE); - LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, (unsigned long)8*128); - /* */ - LTC_SET_ASN1(alg_seq, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, 16UL); - LTC_SET_ASN1(alg_seq, 1, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL); - LTC_SET_ASN1(top_seq, 0, LTC_ASN1_INTEGER, zero, 1UL); - LTC_SET_ASN1(top_seq, 1, LTC_ASN1_SEQUENCE, alg_seq, 2UL); - LTC_SET_ASN1(top_seq, 2, LTC_ASN1_OCTET_STRING, buf1, buf1len); - seq_curve[2].optional = 1; - err=der_decode_sequence(decrypted, decryptedlen, top_seq, 3UL); - if (err != CRYPT_OK) { goto LBL_ERR; } - len_a = seq_curve[0].size; - len_b = seq_curve[1].size; - len_g = seq_ecparams[3].size; - /* create bignums */ - if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto LBL_ERR; } - if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto LBL_ERR; } - if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto LBL_ERR; } - /* load curve parameters */ - if ((err = ecc_dp_set_bn(dp, a, b, prime, order, gx, gy, cofactor)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = pkcs_5_alg1(pass, pass_size, salt, iterations, hid, key_iv, &len)) != CRYPT_OK) goto LBL_ERROR; + /* the output has 16 bytes: [KEY-8-bytes][IV-8-bytes] */ } - /* check alg oid */ - if ((alg_seq[0].size != ecoid.OIDlen) || - XMEMCMP(ecoid.OID, alg_seq[0].data, ecoid.OIDlen * sizeof(ecoid.OID[0]))) { - err = CRYPT_PK_INVALID_TYPE; - goto LBL_ERR; + if (hid != -1 && cid != -1) { + if (salt_size != 8 || enc_size < blklen) goto LBL_ERROR; + if ((err = cbc_start(cid, key_iv + keylen, key_iv, keylen, 0, &cbc)) != CRYPT_OK) goto LBL_ERROR; + if ((err = cbc_decrypt(enc_data, dec_data, enc_size, &cbc)) != CRYPT_OK) goto LBL_ERROR; + if ((err = cbc_done(&cbc)) != CRYPT_OK) goto LBL_ERROR; + pad = dec_data[enc_size-1]; + if (pad < 1 || pad > blklen) goto LBL_ERROR; + *dec_size = enc_size - pad; + return CRYPT_OK; } - /* ECPrivateKey SEQUENCE */ - LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &one, 1UL); - LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, (unsigned long)ECC_MAXSIZE); - LTC_SET_ASN1(seq_priv, 2, LTC_ASN1_RAW_BIT_STRING, bin_xy, (unsigned long)8*(2*ECC_MAXSIZE+2)); - seq_priv[2].tag = 0xA1; /* context specific 1 */ - /* try to load private key */ - err = der_decode_sequence(buf1, top_seq[2].size, seq_priv, 3); - if (err != CRYPT_OK) { goto LBL_ERR; } - /* load private+public key */ - if ((err = ecc_import_raw(bin_k, seq_priv[1].size, key, dp)) != CRYPT_OK) { goto LBL_ERR; } - /* success */ +LBL_ERROR: + zeromem(key_iv, sizeof(key_iv)); + if (pw) { zeromem(pw, pwlen); XFREE(pw); } + return CRYPT_INVALID_ARG; +} + +static int _pbes2_pbkdf2_decrypt(const unsigned char *enc_data, unsigned long enc_size, + const unsigned char *pass, unsigned long pass_size, + const unsigned char *salt, unsigned long salt_size, + const unsigned char *iv, unsigned long iv_size, + unsigned long iterations, + int hmacid, + int encid, + int extra_arg, + unsigned char *dec_data, unsigned long *dec_size) +{ + int err, hid = -1, cid = -1; + unsigned char k[32], pad; + unsigned long klen = sizeof(k); + symmetric_CBC cbc; + + /* https://tools.ietf.org/html/rfc8018#section-6.2.2 */ + + if (hmacid == HMAC_WITH_SHA1) hid = find_hash("sha1"); + if (hmacid == HMAC_WITH_SHA224) hid = find_hash("sha224"); + if (hmacid == HMAC_WITH_SHA256) hid = find_hash("sha256"); + if (hmacid == HMAC_WITH_SHA384) hid = find_hash("sha384"); + if (hmacid == HMAC_WITH_SHA512) hid = find_hash("sha512"); + if (hid == -1) return CRYPT_INVALID_ARG; + + if (encid == DES_EDE3_CBC) { + /* https://tools.ietf.org/html/rfc8018#appendix-B.2.2 */ + cid = find_cipher("3des"); + klen = 24; + if (klen > sizeof(k) || iv_size != 8 || iv == NULL || cid == -1) goto LBL_ERROR; + if ((err = pkcs_5_alg2(pass, pass_size, salt, salt_size, iterations, hid, k, &klen)) != CRYPT_OK) goto LBL_ERROR; + if ((err = cbc_start(cid, iv, k, klen, 0, &cbc)) != CRYPT_OK) goto LBL_ERROR; + if ((err = cbc_decrypt(enc_data, dec_data, enc_size, &cbc)) != CRYPT_OK) goto LBL_ERROR; + if ((err = cbc_done(&cbc)) != CRYPT_OK) goto LBL_ERROR; + pad = dec_data[enc_size-1]; + if (pad < 1 || pad > 8) goto LBL_ERROR; + *dec_size = enc_size - pad; + return CRYPT_OK; + } + + if (encid == DES_CBC) { + /* https://tools.ietf.org/html/rfc8018#appendix-B.2.1 */ + cid = find_cipher("des"); + klen = 8; /* 64 bits */ + if (klen > sizeof(k) || iv_size != 8 || iv == NULL || cid == -1) goto LBL_ERROR; + if ((err = pkcs_5_alg2(pass, pass_size, salt, salt_size, iterations, hid, k, &klen)) != CRYPT_OK) goto LBL_ERROR; + if ((err = cbc_start(cid, iv, k, klen, 0, &cbc)) != CRYPT_OK) goto LBL_ERROR; + if ((err = cbc_decrypt(enc_data, dec_data, enc_size, &cbc)) != CRYPT_OK) goto LBL_ERROR; + if ((err = cbc_done(&cbc)) != CRYPT_OK) goto LBL_ERROR; + pad = dec_data[enc_size-1]; + if (pad < 1 || pad > 8) goto LBL_ERROR; + *dec_size = enc_size - pad; + return CRYPT_OK; + } + + if (encid == RC2_CBC) { + /* https://tools.ietf.org/html/rfc8018#appendix-B.2.3 */ + cid = find_cipher("rc2"); + klen = 4; /* default: 32 bits */ + if (extra_arg == 160) klen = 5; + if (extra_arg == 120) klen = 8; + if (extra_arg == 58) klen = 16; + if (extra_arg >= 256) klen = extra_arg / 8; + if (klen > sizeof(k) || iv_size != 8 || iv == NULL || cid == -1) goto LBL_ERROR; + if ((err = pkcs_5_alg2(pass, pass_size, salt, salt_size, iterations, hid, k, &klen)) != CRYPT_OK) goto LBL_ERROR; + if ((err = cbc_start(cid, iv, k, klen, 0, &cbc)) != CRYPT_OK) goto LBL_ERROR; + if ((err = cbc_decrypt(enc_data, dec_data, enc_size, &cbc)) != CRYPT_OK) goto LBL_ERROR; + if ((err = cbc_done(&cbc)) != CRYPT_OK) goto LBL_ERROR; + pad = dec_data[enc_size-1]; + if (pad < 1 || pad > 8) goto LBL_ERROR; + *dec_size = enc_size - pad; + return CRYPT_OK; + } + +LBL_ERROR: + zeromem(k, sizeof(k)); + return CRYPT_INVALID_ARG; +} + +static int _der_decode_pkcs8_flexi(const unsigned char *in, unsigned long inlen, + const void *pwd, unsigned long pwdlen, + ltc_asn1_list **decoded_list) +{ + unsigned long len = inlen; + unsigned long dec_size; + unsigned char *dec_data = NULL; + ltc_asn1_list *l = NULL; + int err; + + *decoded_list = NULL; + if ((err = der_decode_sequence_flexi(in, &len, &l)) == CRYPT_OK) { + /* the following "if" detects whether it is encrypted or not */ + if (l->type == LTC_ASN1_SEQUENCE && + l->child && l->child->type == LTC_ASN1_SEQUENCE && + l->child->child && l->child->child->type == LTC_ASN1_OBJECT_IDENTIFIER && + l->child->child->next && l->child->child->next->type == LTC_ASN1_SEQUENCE && + l->child->next && l->child->next->type == LTC_ASN1_OCTET_STRING) { + ltc_asn1_list *lalgoid = l->child->child; + ltc_asn1_list *lalgparam = l->child->child->next; + unsigned char *enc_data = l->child->next->data; + unsigned long enc_size = l->child->next->size; + dec_size = enc_size; + if ((dec_data = XMALLOC(dec_size)) == NULL) { + err = CRYPT_MEM; + goto LBL_DONE; + } + if (lalgparam->child && lalgparam->child->type == LTC_ASN1_OCTET_STRING && + lalgparam->child->next && lalgparam->child->next->type == LTC_ASN1_INTEGER) { + /* PBES1: encrypted pkcs8 - pbeWithMD5AndDES-CBC: + * 0:d=0 hl=4 l= 329 cons: SEQUENCE + * 4:d=1 hl=2 l= 27 cons: SEQUENCE (== *lalg) + * 6:d=2 hl=2 l= 9 prim: OBJECT :pbeWithMD5AndDES-CBC (== 1.2.840.113549.1.5.3) + * 17:d=2 hl=2 l= 14 cons: SEQUENCE (== *lalgparam) + * 19:d=3 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:8EDF749A06CCDE51 (== salt) + * 29:d=3 hl=2 l= 2 prim: INTEGER :0800 (== iterations) + * 33:d=1 hl=4 l= 296 prim: OCTET STRING :bytes (== encrypted data) + */ + unsigned long iter = mp_get_int(lalgparam->child->next->data); + unsigned long salt_size = lalgparam->child->size; + unsigned char *salt = lalgparam->child->data; + err = _pbes1_decrypt(enc_data, enc_size, pwd, pwdlen, salt, salt_size, iter, lalgoid->data, lalgoid->size, dec_data, &dec_size); + if (err != CRYPT_OK) goto LBL_DONE; + } + else if (PBES2 == _oid_to_id(lalgoid->data, lalgoid->size) && + lalgparam->child && lalgparam->child->type == LTC_ASN1_SEQUENCE && + lalgparam->child->child && lalgparam->child->child->type == LTC_ASN1_OBJECT_IDENTIFIER && + lalgparam->child->child->next && lalgparam->child->child->next->type == LTC_ASN1_SEQUENCE && + lalgparam->child->next && lalgparam->child->next->type == LTC_ASN1_SEQUENCE && + lalgparam->child->next->child && lalgparam->child->next->child->type == LTC_ASN1_OBJECT_IDENTIFIER) { + /* PBES2: encrypted pkcs8 - PBES2+PBKDF2+des-ede3-cbc: + * 0:d=0 hl=4 l= 380 cons: SEQUENCE + * 4:d=1 hl=2 l= 78 cons: SEQUENCE (== *lalg) + * 6:d=2 hl=2 l= 9 prim: OBJECT :PBES2 (== 1.2.840.113549.1.5.13) + * 17:d=2 hl=2 l= 65 cons: SEQUENCE (== *lalgparam) + * 19:d=3 hl=2 l= 41 cons: SEQUENCE + * 21:d=4 hl=2 l= 9 prim: OBJECT :PBKDF2 + * 32:d=4 hl=2 l= 28 cons: SEQUENCE + * 34:d=5 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:28BA4ABF6AA76A3D (== salt) + * 44:d=5 hl=2 l= 2 prim: INTEGER :0800 (== iterations) + * 48:d=5 hl=2 l= 12 cons: SEQUENCE (this sequence is optional, may be missing) + * 50:d=6 hl=2 l= 8 prim: OBJECT :hmacWithSHA256 + * 60:d=6 hl=2 l= 0 prim: NULL + * 62:d=3 hl=2 l= 20 cons: SEQUENCE + * 64:d=4 hl=2 l= 8 prim: OBJECT :des-ede3-cbc + * 74:d=4 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:B1404C4688DC9A5A + * 84:d=1 hl=4 l= 296 prim: OCTET STRING :bytes (== encrypted data) + */ + ltc_asn1_list *lkdf = lalgparam->child->child; + ltc_asn1_list *lenc = lalgparam->child->next->child; + int kdfid = _oid_to_id(lkdf->data, lkdf->size); + int encid = _oid_to_id(lenc->data, lenc->size); + if (PBKDF2 == kdfid && + lkdf->next && lkdf->next->type == LTC_ASN1_SEQUENCE && + lkdf->next->child && lkdf->next->child->type == LTC_ASN1_OCTET_STRING && + lkdf->next->child->next && lkdf->next->child->next->type == LTC_ASN1_INTEGER) { + unsigned long iter = mp_get_int(lkdf->next->child->next->data); + unsigned long salt_size = lkdf->next->child->size; + unsigned char *salt = lkdf->next->child->data; + unsigned char *iv = NULL; + unsigned long iv_size = 0; + unsigned long arg = 0; + ltc_asn1_list *loptseq = lkdf->next->child->next->next; + int hmacid = HMAC_WITH_SHA1; /* this is default */ + if (loptseq && loptseq->type == LTC_ASN1_SEQUENCE && + loptseq->child && loptseq->child->type == LTC_ASN1_OBJECT_IDENTIFIER) { + /* this sequence is optional */ + hmacid = _oid_to_id(loptseq->child->data, loptseq->child->size); + } + if (lenc->next && lenc->next->type == LTC_ASN1_OCTET_STRING) { + /* DES-CBC + DES_EDE3_CBC */ + iv = lenc->next->data; + iv_size = lenc->next->size; + } + else if (lenc->next && lenc->next->type == LTC_ASN1_SEQUENCE && + lenc->next->child && lenc->next->child->type == LTC_ASN1_INTEGER && + lenc->next->child->next && lenc->next->child->next->type == LTC_ASN1_OCTET_STRING) { + /* RC2-CBC is a bit special */ + iv = lenc->next->child->next->data; + iv_size = lenc->next->child->next->size; + arg = mp_get_int(lenc->next->child->data); + } + err = _pbes2_pbkdf2_decrypt(enc_data, enc_size, pwd, pwdlen, salt, salt_size, iv, iv_size, iter, hmacid, encid, arg, dec_data, &dec_size); + if (err != CRYPT_OK) goto LBL_DONE; + } + else { + /* non-PBKDF2 algorithms are not supported */ + err = CRYPT_INVALID_PACKET; + goto LBL_DONE; + } + } + else { + /* unsupported encryption */ + err = CRYPT_INVALID_PACKET; + goto LBL_DONE; + } + der_free_sequence_flexi(l); + l = NULL; + err = der_decode_sequence_flexi(dec_data, &dec_size, &l); + if (err != CRYPT_OK) goto LBL_DONE; + *decoded_list = l; + } + else { + /* not encrypted */ + err = CRYPT_OK; + *decoded_list = l; + } + } + +LBL_DONE: + if (dec_data) XFREE(dec_data); return err; +} + +/* NOTE: _der_decode_pkcs8_flexi & related stuff can be shared with rsa_import_pkcs8() */ -LBL_ERR: - mp_clear_multi(prime, order, a, b, gx, gy, NULL); -LBL_NOCLEAR: - XFREE(buf2); -LBL_FREE: - XFREE(buf1); -LBL_NOFREE: +int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen, + const void *pwd, unsigned long pwdlen, + ecc_key *key) +{ + void *a, *b, *gx, *gy; + unsigned long len, cofactor; + oid_st ecoid; + int err; + ltc_asn1_list *p = NULL, *l = NULL; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + + /* get EC alg oid */ + err = pk_get_oid(PKA_EC, &ecoid); + if (err != CRYPT_OK) return err; + + /* init key */ + err = mp_init_multi(&a, &b, &gx, &gy, NULL); + if (err != CRYPT_OK) return err; + + if ((err = _der_decode_pkcs8_flexi(in, inlen, pwd, pwdlen, &l)) == CRYPT_OK) { + if (l->type == LTC_ASN1_SEQUENCE && + l->child && l->child->type == LTC_ASN1_INTEGER && + l->child->next && l->child->next->type == LTC_ASN1_SEQUENCE && + l->child->next->child && l->child->next->child->type == LTC_ASN1_OBJECT_IDENTIFIER && + l->child->next->next && l->child->next->next->type == LTC_ASN1_OCTET_STRING) { + ltc_asn1_list *lseq = l->child->next; + ltc_asn1_list *lpri = l->child->next->next; + ltc_asn1_list *lecoid = l->child->next->child; + + if ((lecoid->size != ecoid.OIDlen) || + XMEMCMP(ecoid.OID, lecoid->data, ecoid.OIDlen * sizeof(ecoid.OID[0]))) { + err = CRYPT_PK_INVALID_TYPE; + goto LBL_DONE; + } + + if (lseq->child->next && lseq->child->next->type == LTC_ASN1_OBJECT_IDENTIFIER) { + /* CASE 1: curve by OID (AKA short variant): + * 0:d=0 hl=2 l= 100 cons: SEQUENCE + * 2:d=1 hl=2 l= 1 prim: INTEGER :00 + * 5:d=1 hl=2 l= 16 cons: SEQUENCE (== *lseq) + * 7:d=2 hl=2 l= 7 prim: OBJECT :id-ecPublicKey + * 16:d=2 hl=2 l= 5 prim: OBJECT :secp256k1 (== 1.3.132.0.10) + * 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) { + goto LBL_DONE; + } + } + else if (lseq->child->next && lseq->child->next->type == LTC_ASN1_SEQUENCE) { + /* CASE 2: explicit curve parameters (AKA long variant): + * 0:d=0 hl=3 l= 227 cons: SEQUENCE + * 3:d=1 hl=2 l= 1 prim: INTEGER :00 + * 6:d=1 hl=3 l= 142 cons: SEQUENCE (== *lseq) + * 9:d=2 hl=2 l= 7 prim: OBJECT :id-ecPublicKey + * 18:d=2 hl=3 l= 130 cons: SEQUENCE (== *lcurve) + * 21:d=3 hl=2 l= 1 prim: INTEGER :01 + * 24:d=3 hl=2 l= 44 cons: SEQUENCE (== *lfield) + * 26:d=4 hl=2 l= 7 prim: OBJECT :prime-field + * 35:d=4 hl=2 l= 33 prim: INTEGER :(== curve.prime) + * 70:d=3 hl=2 l= 6 cons: SEQUENCE (== *lpoint) + * 72:d=4 hl=2 l= 1 prim: OCTET STRING :bytes (== curve.A) + * 75:d=4 hl=2 l= 1 prim: OCTET STRING :bytes (== curve.B) + * 78:d=3 hl=2 l= 33 prim: OCTET STRING :bytes (== curve.G-point) + * 113:d=3 hl=2 l= 33 prim: INTEGER :(== curve.order) + * 148:d=3 hl=2 l= 1 prim: INTEGER :(== curve.cofactor) + * 151:d=1 hl=2 l= 77 prim: OCTET STRING :bytes (== privatekey) + */ + ltc_asn1_list *lcurve = lseq->child->next; + + if (lcurve->child && lcurve->child->type == LTC_ASN1_INTEGER && + lcurve->child->next && lcurve->child->next->type == LTC_ASN1_SEQUENCE && + lcurve->child->next->next && lcurve->child->next->next->type == LTC_ASN1_SEQUENCE && + lcurve->child->next->next->next && lcurve->child->next->next->next->type == LTC_ASN1_OCTET_STRING && + lcurve->child->next->next->next->next && lcurve->child->next->next->next->next->type == LTC_ASN1_INTEGER && + lcurve->child->next->next->next->next->next && lcurve->child->next->next->next->next->next->type == LTC_ASN1_INTEGER) { + + ltc_asn1_list *lfield = lcurve->child->next; + ltc_asn1_list *lpoint = lcurve->child->next->next; + ltc_asn1_list *lg = lcurve->child->next->next->next; + ltc_asn1_list *lorder = lcurve->child->next->next->next->next; + cofactor = mp_get_int(lcurve->child->next->next->next->next->next->data); + + if (lfield->child && lfield->child->type == LTC_ASN1_OBJECT_IDENTIFIER && + lfield->child->next && lfield->child->next->type == LTC_ASN1_INTEGER && + lpoint->child && lpoint->child->type == LTC_ASN1_OCTET_STRING && + lpoint->child->next && lpoint->child->next->type == LTC_ASN1_OCTET_STRING) { + + ltc_asn1_list *lprime = lfield->child->next; + if ((err = mp_read_unsigned_bin(a, lpoint->child->data, lpoint->child->size)) != CRYPT_OK) { + goto LBL_DONE; + } + if ((err = mp_read_unsigned_bin(b, lpoint->child->next->data, lpoint->child->next->size)) != CRYPT_OK) { + goto LBL_DONE; + } + 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) { + goto LBL_DONE; + } + } + } + } + else { + err = CRYPT_INVALID_PACKET; + goto LBL_DONE; + } + + /* load private key value 'k' */ + len = lpri->size; + if ((err = der_decode_sequence_flexi(lpri->data, &len, &p)) == CRYPT_OK) { + err = CRYPT_INVALID_PACKET; + if (p->type == LTC_ASN1_SEQUENCE && + p->child && p->child->type == LTC_ASN1_INTEGER && + p->child->next && p->child->next->type == LTC_ASN1_OCTET_STRING) { + ltc_asn1_list *lk = p->child->next; + if (mp_cmp_d(p->child->data, 1) != LTC_MP_EQ) { + err = CRYPT_INVALID_PACKET; + goto LBL_ECCFREE; + } + if ((err = ecc_set_key(lk->data, lk->size, PK_PRIVATE, key)) != CRYPT_OK) { + goto LBL_ECCFREE; + } + goto LBL_DONE; /* success */ + } + } + } + } + err = CRYPT_INVALID_PACKET; + goto LBL_DONE; + +LBL_ECCFREE: + ecc_free(key); +LBL_DONE: + mp_clear_multi(a, b, gx, gy, NULL); + if (l) der_free_sequence_flexi(l); + if (p) der_free_sequence_flexi(p); return err; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/ecc/ecc_import_raw.c b/src/ltc/pk/ecc/ecc_import_raw.c deleted file mode 100644 index 1ea4bb1e..00000000 --- a/src/ltc/pk/ecc/ecc_import_raw.c +++ /dev/null @@ -1,100 +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. - * - */ - -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ - -#include "tomcrypt.h" - -#ifdef LTC_MECC - -/** Import raw public or private key (public keys = ANSI X9.63 compressed or uncompressed; private keys = raw bytes) - @param in The input data to read - @param inlen The length of the input data - @param key [out] destination to store imported key - @param dp Curve parameters - Return CRYPT_OK on success -*/ - -int ecc_import_raw(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp) -{ - int err, type = -1; - unsigned long size = 0; - void *prime, *a, *b; - ecc_point *base; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(key != NULL); - LTC_ARGCHK(dp != NULL); - - /* init key + temporary numbers */ - if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, &a, &b, NULL) != CRYPT_OK) { - return CRYPT_MEM; - } - - if (inlen <= (unsigned long)dp->size) { - /* read PRIVATE key */ - type = PK_PRIVATE; - size = inlen; - /* load private k */ - if ((err = mp_read_unsigned_bin(key->k, (unsigned char *)in, size)) != CRYPT_OK) { - goto cleanup; - } - if (mp_iszero(key->k)) { - err = CRYPT_INVALID_PACKET; - goto cleanup; - } - /* init base point */ - if ((base = ltc_ecc_new_point()) == NULL) { - err = CRYPT_MEM; - goto cleanup; - } - /* load prime + base point */ - if ((err = mp_read_radix(prime, dp->prime, 16)) != CRYPT_OK) { goto cleanup; } - if ((err = mp_read_radix(base->x, dp->Gx, 16)) != CRYPT_OK) { goto cleanup; } - if ((err = mp_read_radix(base->y, dp->Gy, 16)) != CRYPT_OK) { goto cleanup; } - if ((err = mp_set(base->z, 1)) != CRYPT_OK) { goto cleanup; } - /* make the public key */ - if ((err = mp_read_radix(a, dp->A, 16)) != CRYPT_OK) { goto cleanup; } - if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, a, prime, 1)) != CRYPT_OK) { goto cleanup; } - /* cleanup */ - ltc_ecc_del_point(base); - } - else { - /* read PUBLIC key */ - type = PK_PUBLIC; - /* load prime + A + B */ - if ((err = mp_read_radix(prime, dp->prime, 16)) != CRYPT_OK) { goto cleanup; } - if ((err = mp_read_radix(b, dp->B, 16)) != CRYPT_OK) { goto cleanup; } - if ((err = mp_read_radix(a, dp->A, 16)) != CRYPT_OK) { goto cleanup; } - err = ltc_ecc_import_point(in, inlen, prime, a, b, key->pubkey.x, key->pubkey.y); - if (err != CRYPT_OK) { goto cleanup; } - if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto cleanup; } - } - - if ((err = ltc_ecc_is_point(dp, key->pubkey.x, key->pubkey.y)) != CRYPT_OK) { - err = CRYPT_INVALID_PACKET; - goto cleanup; - } - - key->type = type; - key->idx = -1; - key->dp = dp; - - /* we're done */ - mp_clear_multi(prime, a, b, NULL); - return CRYPT_OK; -cleanup: - mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, prime, a, b, NULL); - return err; -} - -#endif diff --git a/src/ltc/pk/ecc/ecc_import_x509.c b/src/ltc/pk/ecc/ecc_import_x509.c new file mode 100644 index 00000000..e57b156f --- /dev/null +++ b/src/ltc/pk/ecc/ecc_import_x509.c @@ -0,0 +1,59 @@ +/* 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 + +/** + Import an ECC key from a X.509 certificate + @param in The packet to import from + @param inlen It's length (octets) + @param key [out] Destination for newly imported key + @return CRYPT_OK if successful, upon error allocated memory is freed +*/ +int ecc_import_x509(const unsigned char *in, unsigned long inlen, ecc_key *key) +{ + int err; + unsigned long len; + ltc_asn1_list *decoded_list = NULL, *l; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + + len = inlen; + if ((err = der_decode_sequence_flexi(in, &len, &decoded_list)) == CRYPT_OK) { + l = decoded_list; + if (l->type == LTC_ASN1_SEQUENCE && + l->child && l->child->type == LTC_ASN1_SEQUENCE) { + err = CRYPT_ERROR; + l = l->child->child; + while (l) { + if (l->type == LTC_ASN1_SEQUENCE && l->data && + l->child && l->child->type == LTC_ASN1_SEQUENCE && + l->child->child && l->child->child->type == LTC_ASN1_OBJECT_IDENTIFIER && + l->child->next && l->child->next->type == LTC_ASN1_BIT_STRING) { + err = ecc_import_openssl(l->data, l->size, key); + goto LBL_DONE; + } + l = l->next; + } + } + } + +LBL_DONE: + if (decoded_list) der_free_sequence_flexi(decoded_list); + return err; +} + +#endif /* LTC_MECC */ + + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/ecc/ecc_make_key.c b/src/ltc/pk/ecc/ecc_make_key.c index 0d89552e..4617befb 100644 --- a/src/ltc/pk/ecc/ecc_make_key.c +++ b/src/ltc/pk/ecc/ecc_make_key.c @@ -7,9 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ #include "tomcrypt.h" /** @@ -29,76 +26,34 @@ */ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key) { - /* BEWARE: Here we are looking up the curve params by keysize (neither curve name nor curve oid), - * which might be ambiguous (there can more than one curve for given keysize). - * Thus the chosen curve depends on order of items in ltc_ecc_sets[] - see ecc.c file. - */ - int x, err; + int err; - /* find key size */ - for (x = 0; (keysize > ltc_ecc_sets[x].size) && (ltc_ecc_sets[x].size != 0); x++); - keysize = ltc_ecc_sets[x].size; - - if (keysize > ECC_MAXSIZE || ltc_ecc_sets[x].size == 0) { - return CRYPT_INVALID_KEYSIZE; - } - err = ecc_make_key_ex(prng, wprng, key, <c_ecc_sets[x]); - key->idx = x; - return err; + if ((err = ecc_set_dp_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 err; + if ((err = ecc_set_dp(dp, key)) != CRYPT_OK) { return err; } + if ((err = ecc_generate_key(prng, wprng, key)) != CRYPT_OK) { return err; } + return CRYPT_OK; +} + +int ecc_generate_key(prng_state *prng, int wprng, ecc_key *key) +{ int err; - ecc_point *base; - void *prime, *order, *a; - unsigned char *buf; - int keysize, orderbits; - LTC_ARGCHK(key != NULL); LTC_ARGCHK(ltc_mp.name != NULL); - LTC_ARGCHK(dp != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(key->dp.size > 0); /* good prng? */ if ((err = prng_is_valid(wprng)) != CRYPT_OK) { return err; } - key->idx = -1; - key->dp = dp; - keysize = dp->size; - - /* allocate ram */ - base = NULL; - buf = XMALLOC(ECC_MAXSIZE); - if (buf == NULL) { - return CRYPT_MEM; - } - - /* make up random string */ - if (prng_descriptor[wprng].read(buf, (unsigned long)keysize, prng) != (unsigned long)keysize) { - err = CRYPT_ERROR_READPRNG; - goto ERR_BUF; - } - - /* setup the key variables */ - if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, &order, &a, NULL)) != CRYPT_OK) { - goto ERR_BUF; - } - base = ltc_ecc_new_point(); - if (base == NULL) { - err = CRYPT_MEM; - goto errkey; - } - - /* read in the specs for this key */ - if ((err = mp_read_radix(prime, (char *)key->dp->prime, 16)) != CRYPT_OK) { goto errkey; } - if ((err = mp_read_radix(order, (char *)key->dp->order, 16)) != CRYPT_OK) { goto errkey; } - if ((err = mp_read_radix(base->x, (char *)key->dp->Gx, 16)) != CRYPT_OK) { goto errkey; } - if ((err = mp_read_radix(base->y, (char *)key->dp->Gy, 16)) != CRYPT_OK) { goto errkey; } - if ((err = mp_set(base->z, 1)) != CRYPT_OK) { goto errkey; } - if ((err = mp_read_unsigned_bin(key->k, (unsigned char *)buf, keysize)) != CRYPT_OK) { goto errkey; } - /* ECC key pair generation according to FIPS-186-4 (B.4.2 Key Pair Generation by Testing Candidates): * the generated private key k should be the range [1, order-1] * a/ N = bitlen(order) @@ -106,29 +61,23 @@ int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set * c/ if k not in [1, order-1] go to b/ * e/ Q = k*G */ - orderbits = mp_count_bits(order); - do { - if ((err = rand_bn_bits(key->k, orderbits, prng, wprng)) != CRYPT_OK) { goto errkey; } - } while (mp_iszero(key->k) || mp_cmp(key->k, order) != LTC_MP_LT); + if ((err = rand_bn_upto(key->k, key->dp.order, prng, wprng)) != CRYPT_OK) { + goto error; + } /* make the public key */ - if ((err = mp_read_radix(a, (char *)key->dp->A, 16)) != CRYPT_OK) { goto errkey; } - if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, a, prime, 1)) != CRYPT_OK) { goto errkey; } + if ((err = ltc_mp.ecc_ptmul(key->k, &key->dp.base, &key->pubkey, key->dp.A, key->dp.prime, 1)) != CRYPT_OK) { + goto error; + } key->type = PK_PRIVATE; - /* free up ram */ + /* success */ err = CRYPT_OK; goto cleanup; -errkey: - mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL); + +error: + ecc_free(key); cleanup: - ltc_ecc_del_point(base); - mp_clear_multi(prime, order, a, NULL); -ERR_BUF: -#ifdef LTC_CLEAN_STACK - zeromem(buf, ECC_MAXSIZE); -#endif - XFREE(buf); return err; } diff --git a/src/ltc/pk/ecc/ecc_set_dp.c b/src/ltc/pk/ecc/ecc_set_dp.c new file mode 100644 index 00000000..17a0d2aa --- /dev/null +++ b/src/ltc/pk/ecc/ecc_set_dp.c @@ -0,0 +1,97 @@ +/* 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_set_dp(const ltc_ecc_set_type *set, ecc_key *key) +{ + unsigned long i; + int err; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(set != 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, + &key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, + NULL)) != CRYPT_OK) { + return err; + } + + /* 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; } + /* cofactor & size */ + key->dp.cofactor = set->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]; + /* success */ + return CRYPT_OK; + +error: + ecc_free(key); + return err; +} + +int ecc_set_dp_size(int size, ecc_key *key) +{ + const ltc_ecc_set_type *dp = NULL; + int err; + + /* 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); + } + else if (size <= 16) { + if ((err = ecc_get_set_by_name("SECP128R1", &dp)) != CRYPT_OK) return err; + return ecc_set_dp(dp, key); + } + else if (size <= 20) { + if ((err = ecc_get_set_by_name("SECP160R1", &dp)) != CRYPT_OK) return err; + return ecc_set_dp(dp, key); + } + else if (size <= 24) { + if ((err = ecc_get_set_by_name("SECP192R1", &dp)) != CRYPT_OK) return err; + return ecc_set_dp(dp, key); + } + else if (size <= 28) { + if ((err = ecc_get_set_by_name("SECP224R1", &dp)) != CRYPT_OK) return err; + return ecc_set_dp(dp, key); + } + else if (size <= 32) { + if ((err = ecc_get_set_by_name("SECP256R1", &dp)) != CRYPT_OK) return err; + return ecc_set_dp(dp, key); + } + else if (size <= 48) { + if ((err = ecc_get_set_by_name("SECP384R1", &dp)) != CRYPT_OK) return err; + return ecc_set_dp(dp, key); + } + else if (size <= 66) { + if ((err = ecc_get_set_by_name("SECP521R1", &dp)) != CRYPT_OK) return err; + return ecc_set_dp(dp, key); + } + + return CRYPT_INVALID_ARG; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/ecc/ecc_set_dp_internal.c b/src/ltc/pk/ecc/ecc_set_dp_internal.c new file mode 100644 index 00000000..bd7c0403 --- /dev/null +++ b/src/ltc/pk/ecc/ecc_set_dp_internal.c @@ -0,0 +1,150 @@ +/* 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 + +static void _ecc_oid_lookup(ecc_key *key) +{ + int err; + unsigned i; + void *tmp; + const ltc_ecc_set_type *set; + + 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; + if ((mp_cmp(tmp, key->dp.prime) != LTC_MP_EQ)) continue; + if ((err = mp_read_radix(tmp, set->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 ((mp_cmp(tmp, key->dp.A) != LTC_MP_EQ)) continue; + if ((err = mp_read_radix(tmp, set->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 ((mp_cmp(tmp, key->dp.base.x) != LTC_MP_EQ)) continue; + if ((err = mp_read_radix(tmp, set->Gy, 16)) != CRYPT_OK) continue; + if ((mp_cmp(tmp, key->dp.base.y) != LTC_MP_EQ)) continue; + if (key->dp.cofactor != set->cofactor) continue; + break; /* found */ + } + mp_clear(tmp); + if (set->name != NULL) { + /* OID found */ + key->dp.oidlen = set->oidlen; + for(i = 0; i < set->oidlen; i++) key->dp.oid[i] = set->oid[i]; + } +} + +int ecc_set_dp_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)) { + break; + } + } + if (ltc_ecc_sets[i].name == NULL) return CRYPT_ERROR; /* not found */ + return ecc_set_dp(<c_ecc_sets[i], key); +} + +int ecc_set_dp_copy(ecc_key *srckey, ecc_key *key) +{ + unsigned long i; + int err; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(srckey != 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, + &key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, + NULL)) != CRYPT_OK) { + return err; + } + + /* A, B, order, prime, Gx, Gy */ + if ((err = mp_copy(srckey->dp.prime, key->dp.prime )) != CRYPT_OK) { goto error; } + 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; } + /* cofactor & size */ + key->dp.cofactor = srckey->dp.cofactor; + key->dp.size = srckey->dp.size; + /* OID */ + if (srckey->dp.oidlen > 0) { + key->dp.oidlen = srckey->dp.oidlen; + 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 */ + } + /* success */ + return CRYPT_OK; + +error: + ecc_free(key); + 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 err; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(prime != NULL); + LTC_ARGCHK(order != NULL); + LTC_ARGCHK(gx != NULL); + LTC_ARGCHK(gy != 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, + &key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, + NULL)) != CRYPT_OK) { + return err; + } + + /* A, B, order, prime, Gx, Gy */ + if ((err = mp_copy(prime, key->dp.prime )) != CRYPT_OK) { goto error; } + if ((err = mp_copy(order, key->dp.order )) != CRYPT_OK) { goto error; } + if ((err = mp_copy(a, key->dp.A )) != CRYPT_OK) { goto error; } + if ((err = mp_copy(b, key->dp.B )) != CRYPT_OK) { goto error; } + if ((err = mp_copy(gx, key->dp.base.x)) != CRYPT_OK) { goto error; } + if ((err = mp_copy(gy, key->dp.base.y)) != CRYPT_OK) { goto error; } + if ((err = mp_set(key->dp.base.z, 1)) != CRYPT_OK) { goto error; } + /* cofactor & size */ + key->dp.cofactor = cofactor; + key->dp.size = mp_unsigned_bin_size(prime); + /* try to find OID in ltc_ecc_sets */ + _ecc_oid_lookup(key); + /* success */ + return CRYPT_OK; + +error: + ecc_free(key); + return err; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/ecc/ecc_set_key.c b/src/ltc/pk/ecc/ecc_set_key.c new file mode 100644 index 00000000..9fabcf2e --- /dev/null +++ b/src/ltc/pk/ecc/ecc_set_key.c @@ -0,0 +1,67 @@ +/* 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_set_key(const unsigned char *in, unsigned long inlen, int type, ecc_key *key) +{ + int err; + void *prime, *a, *b; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen > 0); + + prime = key->dp.prime; + a = key->dp.A; + b = key->dp.B; + + if (type == PK_PRIVATE && inlen <= (unsigned long)key->dp.size) { + /* load private key */ + if ((err = mp_read_unsigned_bin(key->k, (unsigned char *)in, inlen)) != CRYPT_OK) { + goto error; + } + if (mp_iszero(key->k)) { + err = CRYPT_INVALID_PACKET; + goto error; + } + /* compute public key */ + if ((err = ltc_mp.ecc_ptmul(key->k, &key->dp.base, &key->pubkey, a, prime, 1)) != CRYPT_OK) { goto error; } + key->type = type; + } + else if (type == PK_PUBLIC) { + /* load public key */ + if ((err = ltc_ecc_import_point(in, inlen, prime, a, b, key->pubkey.x, key->pubkey.y)) != CRYPT_OK) { goto error; } + if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto error; } + key->type = type; + } + else { + err = CRYPT_INVALID_PACKET; + goto error; + } + + /* point on the curve + other checks */ + if ((err = ltc_ecc_verify_key(key)) != CRYPT_OK) { + goto error; + } + + return CRYPT_OK; + +error: + ecc_free(key); + return err; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/ecc/ecc_shared_secret.c b/src/ltc/pk/ecc/ecc_shared_secret.c index d21d45cf..92917cc1 100644 --- a/src/ltc/pk/ecc/ecc_shared_secret.c +++ b/src/ltc/pk/ecc/ecc_shared_secret.c @@ -7,9 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ #include "tomcrypt.h" /** @@ -45,29 +42,16 @@ int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, return CRYPT_PK_NOT_PRIVATE; } - if (ltc_ecc_is_valid_idx(private_key->idx) == 0 || ltc_ecc_is_valid_idx(public_key->idx) == 0) { - return CRYPT_INVALID_ARG; - } - -/* XXX FIXME names can be different in some situations - if (XSTRCMP(private_key->dp->name, public_key->dp->name) != 0) { - return CRYPT_PK_TYPE_MISMATCH; - } -*/ /* make new point */ result = ltc_ecc_new_point(); if (result == NULL) { return CRYPT_MEM; } - if ((err = mp_init_multi(&prime, &a, NULL)) != CRYPT_OK) { - ltc_ecc_del_point(result); - return err; - } + prime = private_key->dp.prime; + a = private_key->dp.A; - if ((err = mp_read_radix(prime, (char *)private_key->dp->prime, 16)) != CRYPT_OK) { goto done; } - if ((err = mp_read_radix(a, (char *)private_key->dp->A, 16)) != CRYPT_OK) { goto done; } - if ((err = ltc_mp.ecc_ptmul(private_key->k, &public_key->pubkey, result, a, prime, 1)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.ecc_ptmul(private_key->k, &public_key->pubkey, result, a, prime, 1)) != CRYPT_OK) { goto done; } x = (unsigned long)mp_unsigned_bin_size(prime); if (*outlen < x) { @@ -76,12 +60,11 @@ int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, goto done; } zeromem(out, x); - if ((err = mp_to_unsigned_bin(result->x, out + (x - mp_unsigned_bin_size(result->x)))) != CRYPT_OK) { goto done; } + if ((err = mp_to_unsigned_bin(result->x, out + (x - mp_unsigned_bin_size(result->x)))) != CRYPT_OK) { goto done; } err = CRYPT_OK; *outlen = x; done: - mp_clear_multi(prime, a, NULL); ltc_ecc_del_point(result); return err; } diff --git a/src/ltc/pk/ecc/ecc_sign_hash.c b/src/ltc/pk/ecc/ecc_sign_hash.c index 7f0a4e47..87e95060 100644 --- a/src/ltc/pk/ecc/ecc_sign_hash.c +++ b/src/ltc/pk/ecc/ecc_sign_hash.c @@ -7,10 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ - #include "tomcrypt.h" #ifdef LTC_MECC @@ -20,13 +16,13 @@ ECC Crypto, Tom St Denis */ -static int ecc_sign_hash_ex(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - prng_state *prng, int wprng, ecc_key *key, int sigformat) +static int _ecc_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, ecc_key *key, int sigformat) { ecc_key pubkey; void *r, *s, *e, *p; - int err; + int err, max_iterations = LTC_PK_MAX_RETRIES; unsigned long pbits, pbytes, i, shift_right; unsigned char ch, buf[MAXBLOCKSIZE]; @@ -40,22 +36,17 @@ static int ecc_sign_hash_ex(const unsigned char *in, unsigned long inlen, return CRYPT_PK_NOT_PRIVATE; } - /* is the IDX valid ? */ - if (ltc_ecc_is_valid_idx(key->idx) != 1) { - return CRYPT_PK_INVALID_TYPE; - } - if ((err = prng_is_valid(wprng)) != CRYPT_OK) { return err; } /* init the bignums */ - if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) { + if ((err = mp_init_multi(&r, &s, &e, NULL)) != CRYPT_OK) { return err; } - if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK) { goto errnokey; } /* get the hash and load it as a bignum into 'e' */ + p = key->dp.order; pbits = mp_count_bits(p); pbytes = (pbits+7) >> 3; if (pbits > inlen*8) { @@ -75,16 +66,16 @@ static int ecc_sign_hash_ex(const unsigned char *in, unsigned long inlen, } /* make up a key and export the public copy */ - for (;;) { - if ((err = ecc_make_key_ex(prng, wprng, &pubkey, key->dp)) != CRYPT_OK) { goto errnokey; } + do { + if ((err = ecc_set_dp_copy(key, &pubkey)) != CRYPT_OK) { goto errnokey; } + if ((err = ecc_generate_key(prng, wprng, &pubkey)) != CRYPT_OK) { goto errnokey; } /* find r = x1 mod n */ - if ((err = mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK) { goto error; } + if ((err = mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK) { goto error; } if (mp_iszero(r) == LTC_MP_YES) { ecc_free(&pubkey); - } - else { + } else { /* find s = (e + xr)/k */ if ((err = mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = 1/k */ if ((err = mp_mulmod(key->k, r, p, s)) != CRYPT_OK) { goto error; } /* s = xr */ @@ -96,6 +87,10 @@ static int ecc_sign_hash_ex(const unsigned char *in, unsigned long inlen, break; } } + } while (--max_iterations > 0); + + if (max_iterations == 0) { + goto errnokey; } if (sigformat == 1) { @@ -120,7 +115,7 @@ static int ecc_sign_hash_ex(const unsigned char *in, unsigned long inlen, error: ecc_free(&pubkey); errnokey: - mp_clear_multi(r, s, p, e, NULL); + mp_clear_multi(r, s, e, NULL); return err; } @@ -139,7 +134,7 @@ int ecc_sign_hash(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, prng_state *prng, int wprng, ecc_key *key) { - return ecc_sign_hash_ex(in, inlen, out, outlen, prng, wprng, key, 0); + return _ecc_sign_hash(in, inlen, out, outlen, prng, wprng, key, 0); } /** @@ -157,7 +152,11 @@ int ecc_sign_hash_rfc7518(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, prng_state *prng, int wprng, ecc_key *key) { - return ecc_sign_hash_ex(in, inlen, out, outlen, prng, wprng, key, 1); + return _ecc_sign_hash(in, inlen, out, outlen, prng, wprng, key, 1); } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/ecc/ecc_sizes.c b/src/ltc/pk/ecc/ecc_sizes.c index 8f61d5fd..dcd310c8 100644 --- a/src/ltc/pk/ecc/ecc_sizes.c +++ b/src/ltc/pk/ecc/ecc_sizes.c @@ -7,9 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ #include "tomcrypt.h" /** @@ -21,20 +18,25 @@ void ecc_sizes(int *low, int *high) { - int i; - LTC_ARGCHKVD(low != NULL); - LTC_ARGCHKVD(high != NULL); - - *low = INT_MAX; - *high = 0; - for (i = 0; ltc_ecc_sets[i].size != 0; i++) { - if (ltc_ecc_sets[i].size < *low) { - *low = ltc_ecc_sets[i].size; - } - if (ltc_ecc_sets[i].size > *high) { - *high = ltc_ecc_sets[i].size; - } - } + int i, size; + void *prime; + + LTC_ARGCHKVD(low != NULL); + LTC_ARGCHKVD(high != NULL); + + *low = INT_MAX; + *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) { + size = mp_unsigned_bin_size(prime); + if (size < *low) *low = size; + if (size > *high) *high = size; + } + } + mp_clear(prime); + } } #endif diff --git a/src/ltc/pk/ecc/ecc_verify_hash.c b/src/ltc/pk/ecc/ecc_verify_hash.c index f9165603..34a49041 100644 --- a/src/ltc/pk/ecc/ecc_verify_hash.c +++ b/src/ltc/pk/ecc/ecc_verify_hash.c @@ -7,10 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ - #include "tomcrypt.h" #ifdef LTC_MECC @@ -20,13 +16,13 @@ ECC Crypto, Tom St Denis */ -static int ecc_verify_hash_ex(const unsigned char *sig, unsigned long siglen, - const unsigned char *hash, unsigned long hashlen, - int *stat, ecc_key *key, int sigformat) +static int _ecc_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, ecc_key *key, int sigformat) { - ecc_point *mG, *mQ; - void *r, *s, *v, *w, *u1, *u2, *e, *p, *m, *a, *mu, *ma; - void *mp; + ecc_point *mG = NULL, *mQ = NULL; + void *r, *s, *v, *w, *u1, *u2, *e, *p, *m, *a, *a_plus3 = NULL, *mu = NULL, *ma = NULL; + void *mp = NULL; int err; unsigned long pbits, pbytes, i, shift_right; unsigned char ch, buf[MAXBLOCKSIZE]; @@ -38,18 +34,19 @@ static int ecc_verify_hash_ex(const unsigned char *sig, unsigned long siglen, /* default to invalid signature */ *stat = 0; - mp = NULL; - - /* is the IDX valid ? */ - if (ltc_ecc_is_valid_idx(key->idx) != 1) { - return CRYPT_PK_INVALID_TYPE; - } /* allocate ints */ - if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, &a, &mu, &ma, NULL)) != CRYPT_OK) { + if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &e, &a_plus3, NULL)) != CRYPT_OK) { return CRYPT_MEM; } + p = key->dp.order; + m = key->dp.prime; + a = key->dp.A; + if ((err = mp_add_d(a, 3, a_plus3)) != CRYPT_OK) { + goto error; + } + /* allocate points */ mG = ltc_ecc_new_point(); mQ = ltc_ecc_new_point(); @@ -70,23 +67,15 @@ static int ecc_verify_hash_ex(const unsigned char *sig, unsigned long siglen, } else { /* ASN.1 format */ - if ((err = der_decode_sequence_multi(sig, siglen, + if ((err = der_decode_sequence_multi_ex(sig, siglen, LTC_DER_SEQ_SEQUENCE | LTC_DER_SEQ_STRICT, LTC_ASN1_INTEGER, 1UL, r, LTC_ASN1_INTEGER, 1UL, s, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto error; } } - /* get the order */ - if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK) { goto error; } - - /* get the modulus */ - if ((err = mp_read_radix(m, (char *)key->dp->prime, 16)) != CRYPT_OK) { goto error; } - - /* get the a */ - if ((err = mp_read_radix(a, (char *)key->dp->A, 16)) != CRYPT_OK) { goto error; } - /* check for zero */ - if (mp_iszero(r) || mp_iszero(s) || mp_cmp(r, p) != LTC_MP_LT || mp_cmp(s, p) != LTC_MP_LT) { + if (mp_cmp_d(r, 0) != LTC_MP_GT || mp_cmp_d(s, 0) != LTC_MP_GT || + mp_cmp(r, p) != LTC_MP_LT || mp_cmp(s, p) != LTC_MP_LT) { err = CRYPT_INVALID_PACKET; goto error; } @@ -120,24 +109,28 @@ static int ecc_verify_hash_ex(const unsigned char *sig, unsigned long siglen, if ((err = mp_mulmod(r, w, p, u2)) != CRYPT_OK) { goto error; } /* find mG and mQ */ - if ((err = mp_read_radix(mG->x, (char *)key->dp->Gx, 16)) != CRYPT_OK) { goto error; } - if ((err = mp_read_radix(mG->y, (char *)key->dp->Gy, 16)) != CRYPT_OK) { goto error; } - if ((err = mp_set(mG->z, 1)) != CRYPT_OK) { goto error; } - + 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; } + /* find the montgomery mp */ + if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK) { goto error; } + + /* for curves with a == -3 keep ma == NULL */ + if (mp_cmp(a_plus3, m) != LTC_MP_EQ) { + if ((err = mp_init_multi(&mu, &ma, NULL)) != CRYPT_OK) { goto error; } + if ((err = mp_montgomery_normalization(mu, m)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(a, mu, m, ma)) != CRYPT_OK) { goto error; } + } + /* compute u1*mG + u2*mQ = mG */ if (ltc_mp.ecc_mul2add == NULL) { if ((err = ltc_mp.ecc_ptmul(u1, mG, mG, a, m, 0)) != CRYPT_OK) { goto error; } if ((err = ltc_mp.ecc_ptmul(u2, mQ, mQ, a, m, 0)) != CRYPT_OK) { goto error; } - /* find the montgomery mp */ - if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK) { goto error; } - if ((err = mp_montgomery_normalization(mu, m)) != CRYPT_OK) { goto error; } - if ((err = mp_mulmod(a, mu, m, ma)) != CRYPT_OK) { goto error; } - /* add them */ if ((err = ltc_mp.ecc_ptadd(mQ, mG, mG, ma, m, mp)) != CRYPT_OK) { goto error; } @@ -145,7 +138,7 @@ static int ecc_verify_hash_ex(const unsigned char *sig, unsigned long siglen, if ((err = ltc_mp.ecc_map(mG, m, mp)) != CRYPT_OK) { goto error; } } else { /* use Shamir's trick to compute u1*mG + u2*mQ using half of the doubles */ - if ((err = ltc_mp.ecc_mul2add(mG, u1, mQ, u2, mG, a, m)) != CRYPT_OK) { goto error; } + if ((err = ltc_mp.ecc_mul2add(mG, u1, mQ, u2, mG, ma, m)) != CRYPT_OK) { goto error; } } /* v = X_x1 mod n */ @@ -159,9 +152,11 @@ static int ecc_verify_hash_ex(const unsigned char *sig, unsigned long siglen, /* clear up and return */ err = CRYPT_OK; error: - ltc_ecc_del_point(mG); - ltc_ecc_del_point(mQ); - mp_clear_multi(r, s, v, w, u1, u2, p, e, m, a, mu, ma, NULL); + if (mG != NULL) ltc_ecc_del_point(mG); + if (mQ != NULL) ltc_ecc_del_point(mQ); + if (mu != NULL) mp_clear(mu); + if (ma != NULL) mp_clear(ma); + mp_clear_multi(r, s, v, w, u1, u2, e, a_plus3, NULL); if (mp != NULL) { mp_montgomery_free(mp); } @@ -182,7 +177,7 @@ int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int *stat, ecc_key *key) { - return ecc_verify_hash_ex(sig, siglen, hash, hashlen, stat, key, 0); + return _ecc_verify_hash(sig, siglen, hash, hashlen, stat, key, 0); } /** @@ -199,7 +194,11 @@ int ecc_verify_hash_rfc7518(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int *stat, ecc_key *key) { - return ecc_verify_hash_ex(sig, siglen, hash, hashlen, stat, key, 1); + return _ecc_verify_hash(sig, siglen, hash, hashlen, stat, key, 1); } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/ecc/ltc_ecc_export_point.c b/src/ltc/pk/ecc/ltc_ecc_export_point.c index 086e4c2e..84750c80 100644 --- a/src/ltc/pk/ecc/ltc_ecc_export_point.c +++ b/src/ltc/pk/ecc/ltc_ecc_export_point.c @@ -5,11 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - */ - -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * */ #include "tomcrypt.h" @@ -62,3 +57,7 @@ int ltc_ecc_export_point(unsigned char *out, unsigned long *outlen, void *x, voi } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/ecc/ltc_ecc_import_point.c b/src/ltc/pk/ecc/ltc_ecc_import_point.c index d4d028d5..6c8107c8 100644 --- a/src/ltc/pk/ecc/ltc_ecc_import_point.c +++ b/src/ltc/pk/ecc/ltc_ecc_import_point.c @@ -5,11 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - */ - -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * */ #include "tomcrypt.h" @@ -70,3 +65,7 @@ cleanup: } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/ecc/ltc_ecc_is_point.c b/src/ltc/pk/ecc/ltc_ecc_is_point.c index 9ea963c5..46e1a6d4 100644 --- a/src/ltc/pk/ecc/ltc_ecc_is_point.c +++ b/src/ltc/pk/ecc/ltc_ecc_is_point.c @@ -5,10 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - */ - -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b */ #include "tomcrypt.h" @@ -22,42 +18,39 @@ @return CRYPT_OK if valid */ -int ltc_ecc_is_point(const ltc_ecc_set_type *dp, void *x, void *y) +int ltc_ecc_is_point(const ltc_ecc_dp *dp, void *x, void *y) { void *prime, *a, *b, *t1, *t2; int err; - if ((err = mp_init_multi(&prime, &a, &b, &t1, &t2, NULL)) != CRYPT_OK) { - return err; - } + prime = dp->prime; + b = dp->B; + a = dp->A; - /* load prime, a and b */ - if ((err = mp_read_radix(prime, dp->prime, 16)) != CRYPT_OK) goto cleanup; - if ((err = mp_read_radix(b, dp->B, 16)) != CRYPT_OK) goto cleanup; - if ((err = mp_read_radix(a, dp->A, 16)) != CRYPT_OK) goto cleanup; + if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) return err; /* compute y^2 */ - if ((err = mp_sqr(y, t1)) != CRYPT_OK) goto cleanup; + if ((err = mp_sqr(y, t1)) != CRYPT_OK) goto cleanup; /* compute x^3 */ - if ((err = mp_sqr(x, t2)) != CRYPT_OK) goto cleanup; - if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK) goto cleanup; - if ((err = mp_mul(x, t2, t2)) != CRYPT_OK) goto cleanup; + if ((err = mp_sqr(x, t2)) != CRYPT_OK) goto cleanup; + if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK) goto cleanup; + if ((err = mp_mul(x, t2, t2)) != CRYPT_OK) goto cleanup; /* compute y^2 - x^3 */ - if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK) goto cleanup; + if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK) goto cleanup; /* compute y^2 - x^3 - a*x */ - if ((err = mp_submod(prime, a, prime, t2)) != CRYPT_OK) goto cleanup; - if ((err = mp_mulmod(t2, x, prime, t2)) != CRYPT_OK) goto cleanup; - if ((err = mp_addmod(t1, t2, prime, t1)) != CRYPT_OK) goto cleanup; + if ((err = mp_submod(prime, a, prime, t2)) != CRYPT_OK) goto cleanup; + if ((err = mp_mulmod(t2, x, prime, t2)) != CRYPT_OK) goto cleanup; + if ((err = mp_addmod(t1, t2, prime, t1)) != CRYPT_OK) goto cleanup; /* adjust range (0, prime) */ while (mp_cmp_d(t1, 0) == LTC_MP_LT) { - if ((err = mp_add(t1, prime, t1)) != CRYPT_OK) goto cleanup; + if ((err = mp_add(t1, prime, t1)) != CRYPT_OK) goto cleanup; } while (mp_cmp(t1, prime) != LTC_MP_LT) { - if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK) goto cleanup; + if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK) goto cleanup; } /* compare to b */ @@ -68,8 +61,12 @@ int ltc_ecc_is_point(const ltc_ecc_set_type *dp, void *x, void *y) } cleanup: - mp_clear_multi(prime, a, b, t1, t2, NULL); + mp_clear_multi(t1, t2, NULL); return err; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ 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 d5f0f0b2..87f3b0c3 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,7 +15,7 @@ * 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(ecc_point *P, void *modulus) +int ltc_ecc_is_point_at_infinity(const ecc_point *P, void *modulus) { int err, retval = 0; void *x3, *y2; @@ -46,3 +46,7 @@ done: } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/ecc/ltc_ecc_is_valid_idx.c b/src/ltc/pk/ecc/ltc_ecc_is_valid_idx.c deleted file mode 100644 index d14ab330..00000000 --- a/src/ltc/pk/ecc/ltc_ecc_is_valid_idx.c +++ /dev/null @@ -1,42 +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. - */ - -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ -#include "tomcrypt.h" - -/** - @file ltc_ecc_is_valid_idx.c - ECC Crypto, Tom St Denis -*/ - -#ifdef LTC_MECC - -/** Returns whether an ECC idx is valid or not - @param n The idx number to check - @return 1 if valid, 0 if not -*/ -int ltc_ecc_is_valid_idx(int n) -{ - int x; - - for (x = 0; ltc_ecc_sets[x].size != 0; x++); - /* -1 is a valid index --- indicating that the domain params were supplied by the user */ - if ((n >= -1) && (n < x)) { - return 1; - } - return 0; -} - -#endif -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - diff --git a/src/ltc/pk/ecc/ltc_ecc_map.c b/src/ltc/pk/ecc/ltc_ecc_map.c index 9dd202f9..92d059d1 100644 --- a/src/ltc/pk/ecc/ltc_ecc_map.c +++ b/src/ltc/pk/ecc/ltc_ecc_map.c @@ -7,9 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ #include "tomcrypt.h" /** @@ -43,7 +40,7 @@ int ltc_ecc_map(ecc_point *P, void *modulus, void *mp) } if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) { - return CRYPT_MEM; + return err; } /* first map z back to normal */ diff --git a/src/ltc/pk/ecc/ltc_ecc_mul2add.c b/src/ltc/pk/ecc/ltc_ecc_mul2add.c index a9b780df..80ceb863 100644 --- a/src/ltc/pk/ecc/ltc_ecc_mul2add.c +++ b/src/ltc/pk/ecc/ltc_ecc_mul2add.c @@ -7,9 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ #include "tomcrypt.h" /** @@ -26,22 +23,23 @@ @param kA What to multiple A by @param B Second point to multiply @param kB What to multiple B by - @param C [out] Destination point (can overlap with A or B + @param C [out] Destination point (can overlap with A or B) + @param ma ECC curve parameter a in montgomery form @param modulus Modulus for curve @return CRYPT_OK on success */ -int ltc_ecc_mul2add(ecc_point *A, void *kA, - ecc_point *B, void *kB, - ecc_point *C, - void *a, - void *modulus) +int ltc_ecc_mul2add(const ecc_point *A, void *kA, + const ecc_point *B, void *kB, + ecc_point *C, + void *ma, + void *modulus) { ecc_point *precomp[16]; unsigned bitbufA, bitbufB, lenA, lenB, len, nA, nB, nibble; unsigned x, y; unsigned char *tA, *tB; int err, first; - void *mp, *mu, *ma; + void *mp, *mu; /* argchks */ LTC_ARGCHK(A != NULL); @@ -95,15 +93,12 @@ int ltc_ecc_mul2add(ecc_point *A, void *kA, if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto ERR_P; } - if ((err = mp_init_multi(&mu, &ma, NULL)) != CRYPT_OK) { + if ((err = mp_init(&mu)) != CRYPT_OK) { goto ERR_MP; } if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { goto ERR_MU; } - if ((err = mp_mulmod(a, mu, modulus, ma)) != CRYPT_OK) { - goto ERR_MU; - } /* copy ones ... */ if ((err = mp_mulmod(A->x, mu, modulus, precomp[1]->x)) != CRYPT_OK) { goto ERR_MU; } @@ -183,7 +178,7 @@ int ltc_ecc_mul2add(ecc_point *A, void *kA, /* clean up */ ERR_MU: - mp_clear_multi(mu, ma, NULL); + mp_clear(mu); ERR_MP: mp_montgomery_free(mp); ERR_P: diff --git a/src/ltc/pk/ecc/ltc_ecc_mulmod.c b/src/ltc/pk/ecc/ltc_ecc_mulmod.c index 8b65ebf6..50dedc16 100644 --- a/src/ltc/pk/ecc/ltc_ecc_mulmod.c +++ b/src/ltc/pk/ecc/ltc_ecc_mulmod.c @@ -7,9 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ #include "tomcrypt.h" /** @@ -32,11 +29,11 @@ @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective) @return CRYPT_OK on success */ -int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map) +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; - void *mu, *mp, *ma; + void *mp = NULL, *mu = NULL, *ma = NULL, *a_plus3 = NULL; ltc_mp_digit buf; int first, bitbuf, bitcpy, bitcnt, mode, digidx; @@ -54,22 +51,16 @@ int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, } /* init montgomery reduction */ - if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { - return err; - } - if ((err = mp_init_multi(&mu, &ma, NULL)) != CRYPT_OK) { - mp_montgomery_free(mp); - return err; - } - if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { - mp_montgomery_free(mp); - mp_clear_multi(mu, ma, NULL); - return err; - } - if ((err = mp_mulmod(a, mu, modulus, ma)) != CRYPT_OK) { - mp_montgomery_free(mp); - mp_clear_multi(mu, ma, NULL); - return err; + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto error; } + if ((err = mp_init(&mu)) != CRYPT_OK) { goto error; } + if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { goto error; } + + /* for curves with a == -3 keep ma == NULL */ + if ((err = mp_init(&a_plus3)) != CRYPT_OK) { goto error; } + if ((err = mp_add_d(a, 3, a_plus3)) != CRYPT_OK) { goto error; } + if (mp_cmp(a_plus3, modulus) != LTC_MP_EQ) { + if ((err = mp_init(&ma)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(a, mu, modulus, ma)) != CRYPT_OK) { goto error; } } /* alloc ram for window temps */ @@ -79,9 +70,8 @@ int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, for (j = 0; j < i; j++) { ltc_ecc_del_point(M[j]); } - mp_montgomery_free(mp); - mp_clear_multi(mu, ma, NULL); - return CRYPT_MEM; + err = CRYPT_MEM; + goto error; } } @@ -209,15 +199,15 @@ int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, err = CRYPT_OK; } done: - if (mu != NULL) { - mp_clear(mu); - } - mp_clear(ma); - mp_montgomery_free(mp); ltc_ecc_del_point(tG); for (i = 0; i < 8; i++) { ltc_ecc_del_point(M[i]); } +error: + if (ma != NULL) mp_clear(ma); + if (a_plus3 != NULL) mp_clear(a_plus3); + if (mu != NULL) mp_clear(mu); + if (mp != NULL) mp_montgomery_free(mp); return err; } diff --git a/src/ltc/pk/ecc/ltc_ecc_mulmod_timing.c b/src/ltc/pk/ecc/ltc_ecc_mulmod_timing.c index d6f7f1df..068240ae 100644 --- a/src/ltc/pk/ecc/ltc_ecc_mulmod_timing.c +++ b/src/ltc/pk/ecc/ltc_ecc_mulmod_timing.c @@ -7,9 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ #include "tomcrypt.h" /** @@ -31,11 +28,11 @@ @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective) @return CRYPT_OK on success */ -int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map) +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; - void *mu, *mp, *ma; + void *mp = NULL, *mu = NULL, *ma = NULL, *a_plus3 = NULL; ltc_mp_digit buf; int bitcnt, mode, digidx; @@ -53,22 +50,16 @@ int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, } /* init montgomery reduction */ - if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { - return err; - } - if ((err = mp_init_multi(&mu, &ma, NULL)) != CRYPT_OK) { - mp_montgomery_free(mp); - return err; - } - if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { - mp_clear(mu); - mp_montgomery_free(mp); - return err; - } - if ((err = mp_mulmod(a, mu, modulus, ma)) != CRYPT_OK) { - mp_montgomery_free(mp); - mp_clear_multi(mu, ma, NULL); - return err; + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto error; } + if ((err = mp_init(&mu)) != CRYPT_OK) { goto error; } + if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { goto error; } + + /* for curves with a == -3 keep ma == NULL */ + if ((err = mp_init(&a_plus3)) != CRYPT_OK) { goto error; } + if ((err = mp_add_d(a, 3, a_plus3)) != CRYPT_OK) { goto error; } + if (mp_cmp(a_plus3, modulus) != LTC_MP_EQ) { + if ((err = mp_init(&ma)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(a, mu, modulus, ma)) != CRYPT_OK) { goto error; } } /* alloc ram for window temps */ @@ -156,15 +147,15 @@ int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, err = CRYPT_OK; } done: - if (mu != NULL) { - mp_clear(mu); - } - mp_clear(ma); - mp_montgomery_free(mp); ltc_ecc_del_point(tG); for (i = 0; i < 3; i++) { ltc_ecc_del_point(M[i]); } +error: + if (ma != NULL) mp_clear(ma); + if (a_plus3 != NULL) mp_clear(a_plus3); + if (mu != NULL) mp_clear(mu); + if (mp != NULL) mp_montgomery_free(mp); return err; } diff --git a/src/ltc/pk/ecc/ltc_ecc_points.c b/src/ltc/pk/ecc/ltc_ecc_points.c index 416fc909..772e8efd 100644 --- a/src/ltc/pk/ecc/ltc_ecc_points.c +++ b/src/ltc/pk/ecc/ltc_ecc_points.c @@ -7,9 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ #include "tomcrypt.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 3434902a..0182d0a8 100644 --- a/src/ltc/pk/ecc/ltc_ecc_projective_add_point.c +++ b/src/ltc/pk/ecc/ltc_ecc_projective_add_point.c @@ -7,9 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ #include "tomcrypt.h" /** @@ -24,12 +21,12 @@ @param P The point to add @param Q The point to add @param R [out] The destination of the double - @param ma ECC curve parameter a in montgomery form (if NULL we assume a == -3) + @param ma ECC curve parameter a in montgomery form @param modulus The modulus of the field the ECC curve is in @param mp The "b" value from montgomery_setup() @return CRYPT_OK on success */ -int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *ma, void *modulus, void *mp) +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; 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 cc01b233..57cfd6fd 100644 --- a/src/ltc/pk/ecc/ltc_ecc_projective_dbl_point.c +++ b/src/ltc/pk/ecc/ltc_ecc_projective_dbl_point.c @@ -7,9 +7,6 @@ * guarantee it works. */ -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * - */ #include "tomcrypt.h" /* ### Point doubling in Jacobian coordinate system ### @@ -41,12 +38,12 @@ Double an ECC point @param P The point to double @param R [out] The destination of the double - @param ma ECC curve parameter a in montgomery form (if NULL we assume a == -3) + @param ma ECC curve parameter a in montgomery form @param modulus The modulus of the field the ECC curve is in @param mp The "b" value from montgomery_setup() @return CRYPT_OK on success */ -int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *ma, void *modulus, void *mp) +int ltc_ecc_projective_dbl_point(const ecc_point *P, ecc_point *R, void *ma, void *modulus, void *mp) { void *t1, *t2; int err; @@ -86,7 +83,7 @@ int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *ma, void *mod if ((err = mp_sub(R->z, modulus, R->z)) != CRYPT_OK) { goto done; } } - if (ma == NULL) { /* special case for ma == -3 (slightly faster than general case) */ + if (ma == NULL) { /* special case for curves with a == -3 (10% faster than general case) */ /* T2 = X - T1 */ if ((err = mp_sub(R->x, t1, t2)) != CRYPT_OK) { goto done; } if (mp_cmp_d(t2, 0) == LTC_MP_LT) { @@ -188,7 +185,7 @@ int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *ma, void *mod err = CRYPT_OK; done: - mp_clear_multi(t1, t2, NULL); + mp_clear_multi(t2, t1, NULL); return err; } #endif diff --git a/src/ltc/pk/ecc/ecc_verify_key.c b/src/ltc/pk/ecc/ltc_ecc_verify_key.c index 0ca1914f..b417465b 100644 --- a/src/ltc/pk/ecc/ecc_verify_key.c +++ b/src/ltc/pk/ecc/ltc_ecc_verify_key.c @@ -5,11 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - */ - -/* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b - * */ #include "tomcrypt.h" @@ -24,7 +19,7 @@ @return CRYPT_OK if successful */ -int ecc_verify_key(ecc_key *key) +int ltc_ecc_verify_key(ecc_key *key) { int err; void *prime = NULL; @@ -32,18 +27,17 @@ int ecc_verify_key(ecc_key *key) void *a = NULL; ecc_point *point; - if (mp_init_multi(&order, &prime, NULL) != CRYPT_OK) { - return CRYPT_MEM; - } - - /* Test 1: Are the x amd y points of the public key in the field? */ - if ((err = ltc_mp.read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) { goto done2; } + prime = key->dp.prime; + order = key->dp.order; + a = key->dp.A; + /* Test 1: Are the x and y points of the public key in the field? */ if (ltc_mp.compare_d(key->pubkey.z, 1) == LTC_MP_EQ) { if ((ltc_mp.compare(key->pubkey.x, prime) != LTC_MP_LT) || (ltc_mp.compare(key->pubkey.y, prime) != LTC_MP_LT) || - (ltc_mp.compare_d(key->pubkey.x, 0) != LTC_MP_GT) || - (ltc_mp.compare_d(key->pubkey.y, 0) != LTC_MP_GT) + (ltc_mp.compare_d(key->pubkey.x, 0) == LTC_MP_LT) || + (ltc_mp.compare_d(key->pubkey.y, 0) == LTC_MP_LT) || + (mp_iszero(key->pubkey.x) && mp_iszero(key->pubkey.y)) ) { err = CRYPT_INVALID_PACKET; @@ -52,12 +46,10 @@ int ecc_verify_key(ecc_key *key) } /* Test 2: is the public key on the curve? */ - if ((err = ltc_ecc_is_point(key->dp, key->pubkey.x, key->pubkey.y)) != CRYPT_OK) { goto done2; } + if ((err = ltc_ecc_is_point(&key->dp, key->pubkey.x, key->pubkey.y)) != CRYPT_OK) { goto done2; } /* Test 3: does nG = O? (n = order, O = point at infinity, G = public key) */ point = ltc_ecc_new_point(); - if ((err = ltc_mp.read_radix(order, key->dp->order, 16)) != CRYPT_OK) { goto done1; } - if ((err = ltc_mp.read_radix(a, key->dp->A, 16)) != CRYPT_OK) { goto done1; } 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)) { @@ -70,8 +62,11 @@ int ecc_verify_key(ecc_key *key) done1: ltc_ecc_del_point(point); done2: - mp_clear_multi(prime, order, NULL); return err; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/rsa/rsa_export.c b/src/ltc/pk/rsa/rsa_export.c index a9885de8..b156a83f 100644 --- a/src/ltc/pk/rsa/rsa_export.c +++ b/src/ltc/pk/rsa/rsa_export.c @@ -79,7 +79,7 @@ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key goto finish; } - err = der_encode_subject_public_key_info(out, outlen, + err = x509_encode_subject_public_key_info(out, outlen, PKA_RSA, tmp, tmplen, LTC_ASN1_NULL, NULL, 0); finish: diff --git a/src/ltc/pk/rsa/rsa_import.c b/src/ltc/pk/rsa/rsa_import.c index 84cd6f65..85771783 100644 --- a/src/ltc/pk/rsa/rsa_import.c +++ b/src/ltc/pk/rsa/rsa_import.c @@ -27,7 +27,7 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) int err; void *zero; unsigned char *tmpbuf=NULL; - unsigned long tmpbuf_len; + unsigned long tmpbuf_len, len; LTC_ARGCHK(in != NULL); LTC_ARGCHK(key != NULL); @@ -47,9 +47,10 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) goto LBL_ERR; } - err = der_decode_subject_public_key_info(in, inlen, + len = 0; + err = x509_decode_subject_public_key_info(in, inlen, PKA_RSA, tmpbuf, &tmpbuf_len, - LTC_ASN1_NULL, NULL, 0); + LTC_ASN1_NULL, NULL, &len); if (err == CRYPT_OK) { /* SubjectPublicKeyInfo format */ diff --git a/src/ltc/pk/rsa/rsa_import_x509.c b/src/ltc/pk/rsa/rsa_import_x509.c index 0f2d5f1c..aa35e644 100644 --- a/src/ltc/pk/rsa/rsa_import_x509.c +++ b/src/ltc/pk/rsa/rsa_import_x509.c @@ -26,7 +26,7 @@ int rsa_import_x509(const unsigned char *in, unsigned long inlen, rsa_key *key) { int err; unsigned char *tmpbuf; - unsigned long tmpbuf_len, tmp_inlen; + unsigned long tmpbuf_len, tmp_inlen, len; ltc_asn1_list *decoded_list = NULL, *l; LTC_ARGCHK(in != NULL); @@ -77,9 +77,10 @@ int rsa_import_x509(const unsigned char *in, unsigned long inlen, rsa_key *key) l->child->type == LTC_ASN1_SEQUENCE && l->child->child && l->child->child->type == LTC_ASN1_OBJECT_IDENTIFIER && l->child->next && l->child->next->type == LTC_ASN1_BIT_STRING) { - err = der_decode_subject_public_key_info(l->data, l->size, + len = 0; + err = x509_decode_subject_public_key_info(l->data, l->size, PKA_RSA, tmpbuf, &tmpbuf_len, - LTC_ASN1_NULL, NULL, 0); + LTC_ASN1_NULL, NULL, &len); if (err == CRYPT_OK) { /* now it should be SEQUENCE { INTEGER, INTEGER } */ if ((err = der_decode_sequence_multi(tmpbuf, tmpbuf_len, diff --git a/src/ltc/pk/rsa/rsa_verify_hash.c b/src/ltc/pk/rsa/rsa_verify_hash.c index b5846965..361f2378 100644 --- a/src/ltc/pk/rsa/rsa_verify_hash.c +++ b/src/ltc/pk/rsa/rsa_verify_hash.c @@ -142,10 +142,10 @@ int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen); - if ((err = der_decode_sequence(out, outlen, siginfo, 2)) != CRYPT_OK) { + if ((err = der_decode_sequence_strict(out, outlen, siginfo, 2)) != CRYPT_OK) { /* fallback to Legacy:missing NULL */ LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 1); - if ((err = der_decode_sequence(out, outlen, siginfo, 2)) != CRYPT_OK) { + if ((err = der_decode_sequence_strict(out, outlen, siginfo, 2)) != CRYPT_OK) { XFREE(out); goto bail_2; } diff --git a/t/001_compile.t b/t/001_compile.t index e0e0c789..1abc45f6 100644 --- a/t/001_compile.t +++ b/t/001_compile.t @@ -68,6 +68,10 @@ use Crypt::Digest::SHA3_224; use Crypt::Digest::SHA3_256; use Crypt::Digest::SHA3_384; use Crypt::Digest::SHA3_512; +use Crypt::Digest::Keccak224; +use Crypt::Digest::Keccak256; +use Crypt::Digest::Keccak384; +use Crypt::Digest::Keccak512; use Crypt::Digest::SHA512; use Crypt::Digest::SHA512_224; use Crypt::Digest::SHA512_256; diff --git a/t/002_all_pm.t b/t/002_all_pm.t index 0d7e12b5..3daceed3 100644 --- a/t/002_all_pm.t +++ b/t/002_all_pm.t @@ -31,7 +31,7 @@ for my $m (sort @files) { $m =~ s|[\\/]|::|g; $m =~ s|^lib::||; $m =~ s|\.pm$||; - push @err, "ERROR: '$m' is missing in CryptX.pm" unless $cryptx =~ /L<$m>/s || $m =~ /^(CryptX|Math::BigInt::LTM|Crypt::(PK|Mode|Mac|AuthEnc))$/; + push @err, "ERROR: '$m' is missing in CryptX.pm" unless $cryptx =~ /L<$m>/s || $m =~ /^(CryptX|Math::BigInt::LTM|Crypt::(PK|Mode|Mac|AuthEnc|Checksum))$/; push @err, "ERROR: '$m' is missing in 001_compile.t" unless $compile_t =~ /\nuse $m;/s; eval "use $m; 1;" or push @err, "ERROR: 'use $m' failed"; } diff --git a/t/003_all_pm_pod.t b/t/003_all_pm_pod.t index 5bc59af3..47c3ccce 100644 --- a/t/003_all_pm_pod.t +++ b/t/003_all_pm_pod.t @@ -6,7 +6,7 @@ use Test::More; plan skip_all => "set TEST_POD to enable this test (developer only!)" unless $ENV{TEST_POD}; plan skip_all => "File::Find not installed" unless eval { require File::Find }; plan skip_all => "Test::Pod not installed" unless eval { require Test::Pod }; -plan tests => 103; +plan tests => 107; my @files; File::Find::find({ wanted=>sub { push @files, $_ if /\.pm$/ }, no_chdir=>1 }, 'lib'); diff --git a/t/004_all_pm_pod_spelling.t b/t/004_all_pm_pod_spelling.t index 0cb3ed6f..5e6de670 100644 --- a/t/004_all_pm_pod_spelling.t +++ b/t/004_all_pm_pod_spelling.t @@ -17,11 +17,12 @@ Test::Pod::Spelling->import( params paramshash irand perl endian zbase bumac bmac budigest bdigest md de blakes_ blakeb_ XOR'ing XOR'ed + keccak )] }, ); -plan tests => 103; +plan tests => 107; my @files; File::Find::find({ wanted=>sub { push @files, $_ if /\.pm$/ }, no_chdir=>1 }, 'lib'); diff --git a/t/005_all_pm_pod_coverage.t b/t/005_all_pm_pod_coverage.t index 4065c23d..ce06bc4b 100644 --- a/t/005_all_pm_pod_coverage.t +++ b/t/005_all_pm_pod_coverage.t @@ -6,7 +6,7 @@ use Test::More; plan skip_all => "set TEST_POD to enable this test (developer only!)" unless $ENV{TEST_POD}; plan skip_all => "Pod::Coverage not installed" unless eval { require Pod::Coverage }; plan skip_all => "File::Find not installed" unless eval { require File::Find }; -plan tests => 103; +plan tests => 107; my @files; File::Find::find({ wanted=>sub { push @files, $_ if /\.pm$/ }, no_chdir=>1 }, 'lib'); @@ -28,9 +28,15 @@ for my $m (sort @files) { elsif ($m eq 'Crypt::Mode') { $pc = Pod::Coverage->new(package => $m, pod_from => $f, trustme => [qr/^(add|decrypt|encrypt|finish|new|start_decrypt|start_encrypt)$/] ); } + elsif ($m eq 'Crypt::Checksum') { + $pc = Pod::Coverage->new(package => $m, pod_from => $f, trustme => [qr/^(addfile|(adler32_|crc32_)(file_hex|file_int|file|data_hex|data_int|data))$/] ); + } elsif ($m eq 'Crypt::Mac') { $pc = Pod::Coverage->new(package => $m, pod_from => $f, trustme => [qr/^(add|addfile)$/] ); } + elsif ($m =~ /^Crypt::Mode::(CTR|CFB|OFB)$/) { + $pc = Pod::Coverage->new(package => $m, pod_from => $f, trustme => [qr/^(finish)$/] ); + } elsif ($m eq 'Crypt::AuthEnc::OCB') { $pc = Pod::Coverage->new(package => $m, pod_from => $f, trustme => [qr/^(blocksize|aad_add)$/] ); } diff --git a/t/auth_enc_ccm.t b/t/auth_enc_ccm.t index fc8a7276..1f32583e 100644 --- a/t/auth_enc_ccm.t +++ b/t/auth_enc_ccm.t @@ -1,7 +1,7 @@ use strict; use warnings; -use Test::More tests => 12; +use Test::More tests => 13; use Crypt::AuthEnc::CCM qw( ccm_encrypt_authenticate ccm_decrypt_verify ); @@ -45,7 +45,9 @@ my $key = "12345678901234561234567890123456"; } { - my ($ct, $tag) = ccm_encrypt_authenticate('AES', $key, $nonce, "", 16, "plain_halfplain_half"); + my ($ct, $tag) = ccm_encrypt_authenticate('AES', $key, $nonce, "", 16, "plain_halfplain_half"); + my ($ct2, $tag2) = ccm_encrypt_authenticate('AES', $key, $nonce, undef, 16, "plain_halfplain_half"); + ok($ct eq $ct2 && $tag eq $tag2, "header '' vs. undef"); is(unpack('H*', $ct), "96b0114ff47da72e92631aadce84f203a8168b20", "ccm_encrypt_authenticate: ciphertext (no header)"); is(unpack('H*', $tag), "9e9cba5dd4939d0d8e2687c85c5d3b89", "ccm_encrypt_authenticate: tag (no header)"); my $pt = ccm_decrypt_verify('AES', $key, $nonce, "", $ct, $tag); diff --git a/t/checksum.t b/t/checksum.t index b61a4b1b..53488da0 100644 --- a/t/checksum.t +++ b/t/checksum.t @@ -1,47 +1,103 @@ use strict; use warnings; -use Test::More tests => 24; - -use Crypt::Checksum ':all'; -use Crypt::Checksum::Adler32; -use Crypt::Checksum::CRC32; - -my $a32 = Crypt::Checksum::Adler32->new; -is($a32->hexdigest, "00000001"); -is($a32->hexdigest, "00000001"); -$a32->add("a"); -is($a32->hexdigest, "00620062"); -$a32->reset; -is($a32->hexdigest, "00000001"); -$a32->add("abc"); -is($a32->hexdigest, "024d0127"); -$a32->reset; -$a32->add("abc"); -$a32->add("abc"); -is($a32->hexdigest, "080c024d"); -$a32->reset; -$a32->add("abcabc"); -is($a32->hexdigest, "080c024d"); -$a32->reset; -$a32->add("\xFF" x 32); -is($a32->hexdigest, "0e2e1fe1"); -is(adler32_data_hex("a"), "00620062"); -is(adler32_data("a"), pack("H*","00620062")); - -is(crc32_data_hex("a"), "e8b7be43"); -is(crc32_data_hex("libtomcrypt"), "b37376ef"); -is(crc32_data_hex("This is the test string"), "6d680973"); -is(crc32_data_int("This is the test string"), 1835534707); -is(crc32_data_hex("This is another test string"), "806e15e9"); -is(crc32_data_int("This is another test string"), 2154698217); - -is(crc32_file_hex("t/data/binary-test.file"), "24111fed"); -is(crc32_file_hex("t/data/text-CR.file"), "1ca430c6"); -is(crc32_file_hex("t/data/text-CRLF.file"), "4d434dfb"); -is(crc32_file_hex("t/data/text-LF.file"), "9f9b8258"); - -is(adler32_file_hex("t/data/binary-test.file"), "f35fb68a"); -is(adler32_file_hex("t/data/text-CR.file"), "948e2644"); -is(adler32_file_hex("t/data/text-CRLF.file"), "3f0e2702"); -is(adler32_file_hex("t/data/text-LF.file"), "86ba260b"); +use Test::More tests => 56; + +use Crypt::Checksum::Adler32 ':all'; +use Crypt::Checksum::CRC32 ':all'; + +{ + my $a32 = Crypt::Checksum::Adler32->new; + is($a32->hexdigest, "00000001"); + $a32->add("a"); + is($a32->hexdigest, "00620062"); + $a32->reset; + is($a32->hexdigest, "00000001"); + $a32->add("abc"); + is($a32->hexdigest, "024d0127"); + $a32->reset; + $a32->add("abc"); + $a32->add("abc"); + is($a32->hexdigest, "080c024d"); + $a32->reset; + $a32->add("abc", "abc"); + is($a32->hexdigest, "080c024d"); + $a32->reset; + $a32->add("abcabc"); + is($a32->hexdigest, "080c024d"); + $a32->reset; + $a32->add("\xFF" x 32); + is($a32->hexdigest, "0e2e1fe1"); + is($a32->intdigest, 237903841); + is($a32->digest, pack("H*", "0e2e1fe1")); + + is(adler32_data_hex("aaa"), "02490124"); + is(adler32_data_int("aaa"), 38338852); + is(adler32_data("aaa"), pack("H*","02490124")); + is(adler32_data_hex("a","a","a"), "02490124"); + is(adler32_data_int("a","a","a"), 38338852); + is(adler32_data("a","a","a"), pack("H*","02490124")); + + is(adler32_data_hex("libtomcrypt"), "1be804ba"); + is(adler32_data_hex("This is the test string"), "6363088d"); + is(adler32_data_int("This is the test string"), 1667434637); + is(adler32_data_hex("This is another test string"), "8b900a3d"); + is(adler32_data_int("This is another test string"), 2341472829); + + is(adler32_file("t/data/binary-test.file"), pack("H*", "f35fb68a")); + is(adler32_file_int("t/data/binary-test.file"), 4083136138); + is(adler32_file_hex("t/data/binary-test.file"), "f35fb68a"); + is(Crypt::Checksum::Adler32->new->addfile("t/data/binary-test.file")->hexdigest, "f35fb68a"); + + is(adler32_file_hex("t/data/text-CR.file"), "948e2644"); + is(adler32_file_hex("t/data/text-CRLF.file"), "3f0e2702"); + is(adler32_file_hex("t/data/text-LF.file"), "86ba260b"); +} + +{ + my $a32 = Crypt::Checksum::CRC32->new; + is($a32->hexdigest, "00000000"); + $a32->add("a"); + is($a32->hexdigest, "e8b7be43"); + $a32->reset; + is($a32->hexdigest, "00000000"); + $a32->add("abc"); + is($a32->hexdigest, "352441c2"); + $a32->reset; + $a32->add("abc"); + $a32->add("abc"); + is($a32->hexdigest, "726e994c"); + $a32->reset; + $a32->add("abc", "abc"); + is($a32->hexdigest, "726e994c"); + $a32->reset; + $a32->add("abcabc"); + is($a32->hexdigest, "726e994c"); + $a32->reset; + $a32->add("\xFF" x 32); + is($a32->hexdigest, "ff6cab0b"); + is($a32->intdigest, 4285311755); + is($a32->digest, pack("H*", "ff6cab0b")); + + is(crc32_data_hex("aaa"), "f007732d"); + is(crc32_data_int("aaa"), 4027020077); + is(crc32_data("aaa"), pack("H*","f007732d")); + is(crc32_data_hex("a","a","a"), "f007732d"); + is(crc32_data_int("a","a","a"), 4027020077); + is(crc32_data("a","a","a"), pack("H*","f007732d")); + + is(crc32_data_hex("libtomcrypt"), "b37376ef"); + is(crc32_data_hex("This is the test string"), "6d680973"); + is(crc32_data_int("This is the test string"), 1835534707); + is(crc32_data_hex("This is another test string"), "806e15e9"); + is(crc32_data_int("This is another test string"), 2154698217); + + is(crc32_file("t/data/binary-test.file"), pack("H*", "24111fed")); + is(crc32_file_int("t/data/binary-test.file"), 605102061); + is(crc32_file_hex("t/data/binary-test.file"), "24111fed"); + is(Crypt::Checksum::CRC32->new->addfile("t/data/binary-test.file")->hexdigest, "24111fed"); + + is(crc32_file_hex("t/data/text-CR.file"), "1ca430c6"); + is(crc32_file_hex("t/data/text-CRLF.file"), "4d434dfb"); + is(crc32_file_hex("t/data/text-LF.file"), "9f9b8258"); +} diff --git a/t/crypt-misc.t b/t/crypt-misc.t index 9cd323d4..d8892f3a 100644 --- a/t/crypt-misc.t +++ b/t/crypt-misc.t @@ -1,6 +1,6 @@ use strict; use warnings; -use Test::More tests => 679; +use Test::More tests => 680; use Crypt::Misc qw( encode_b64 decode_b64 encode_b64u decode_b64u @@ -143,3 +143,5 @@ for my $h (@hex) { is(unpack("H*", decode_b32z(encode_b32z($b))), $h); is(unpack("H*", decode_b32c(encode_b32c($b))), $h); } + +is(decode_b58b("111OIl0"), undef, "bug: decode_b58b + invalid input"); diff --git a/t/digest_blake2b_160.t b/t/digest_blake2b_160.t index be06610d..c8c39f33 100644 --- a/t/digest_blake2b_160.t +++ b/t/digest_blake2b_160.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::BLAKE2b_160 qw( blake2b_160 blake2b_160_hex blake2b_160_b64 blake2b_160_b64u blake2b_160_file blake2b_160_file_hex blake2b_160_file_b64 blake2b_160_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::BLAKE2b_160->hashsize, 20, 'hashsize/4'); is( Crypt::Digest->new('BLAKE2b_160')->hashsize, 20, 'hashsize/5'); is( Crypt::Digest::BLAKE2b_160->new->hashsize, 20, 'hashsize/6'); +is( blake2b_160("A","A","A"), pack("H*","14517ce78b0c7e5e5b7f096f1f3c046f01c46901"), 'blake2b_160 (raw/tripple_A)'); +is( blake2b_160_hex("A","A","A"), "14517ce78b0c7e5e5b7f096f1f3c046f01c46901", 'blake2b_160 (hex/tripple_A)'); +is( blake2b_160_b64("A","A","A"), "FFF854sMfl5bfwlvHzwEbwHEaQE=", 'blake2b_160 (base64/tripple_A)'); +is( blake2b_160_b64u("A","A","A"), "FFF854sMfl5bfwlvHzwEbwHEaQE", 'blake2b_160 (base64url/tripple_A)'); +is( digest_data('BLAKE2b_160', "A","A","A"), pack("H*","14517ce78b0c7e5e5b7f096f1f3c046f01c46901"), 'blake2b_160 (digest_data_raw/tripple_A)'); +is( digest_data_hex('BLAKE2b_160', "A","A","A"), "14517ce78b0c7e5e5b7f096f1f3c046f01c46901", 'blake2b_160 (digest_data_hex/tripple_A)'); +is( digest_data_b64('BLAKE2b_160', "A","A","A"), "FFF854sMfl5bfwlvHzwEbwHEaQE=", 'blake2b_160 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('BLAKE2b_160', "A","A","A"), "FFF854sMfl5bfwlvHzwEbwHEaQE", 'blake2b_160 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::BLAKE2b_160->new->add("A","A","A")->hexdigest, "14517ce78b0c7e5e5b7f096f1f3c046f01c46901", 'blake2b_160 (OO/tripple_A)'); +is( Crypt::Digest::BLAKE2b_160->new->add("A")->add("A")->add("A")->hexdigest, "14517ce78b0c7e5e5b7f096f1f3c046f01c46901", 'blake2b_160 (OO3/tripple_A)'); + is( blake2b_160(""), pack("H*","3345524abf6bbe1809449224b5972c41790b6cf2"), 'blake2b_160 (raw/1)'); is( blake2b_160_hex(""), "3345524abf6bbe1809449224b5972c41790b6cf2", 'blake2b_160 (hex/1)'); diff --git a/t/digest_blake2b_256.t b/t/digest_blake2b_256.t index 1b717378..a4f1d09b 100644 --- a/t/digest_blake2b_256.t +++ b/t/digest_blake2b_256.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::BLAKE2b_256 qw( blake2b_256 blake2b_256_hex blake2b_256_b64 blake2b_256_b64u blake2b_256_file blake2b_256_file_hex blake2b_256_file_b64 blake2b_256_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::BLAKE2b_256->hashsize, 32, 'hashsize/4'); is( Crypt::Digest->new('BLAKE2b_256')->hashsize, 32, 'hashsize/5'); is( Crypt::Digest::BLAKE2b_256->new->hashsize, 32, 'hashsize/6'); +is( blake2b_256("A","A","A"), pack("H*","cdc4339296753f930aa454700fd0ded6e1e08772dea849859e17dbbd85cae649"), 'blake2b_256 (raw/tripple_A)'); +is( blake2b_256_hex("A","A","A"), "cdc4339296753f930aa454700fd0ded6e1e08772dea849859e17dbbd85cae649", 'blake2b_256 (hex/tripple_A)'); +is( blake2b_256_b64("A","A","A"), "zcQzkpZ1P5MKpFRwD9De1uHgh3LeqEmFnhfbvYXK5kk=", 'blake2b_256 (base64/tripple_A)'); +is( blake2b_256_b64u("A","A","A"), "zcQzkpZ1P5MKpFRwD9De1uHgh3LeqEmFnhfbvYXK5kk", 'blake2b_256 (base64url/tripple_A)'); +is( digest_data('BLAKE2b_256', "A","A","A"), pack("H*","cdc4339296753f930aa454700fd0ded6e1e08772dea849859e17dbbd85cae649"), 'blake2b_256 (digest_data_raw/tripple_A)'); +is( digest_data_hex('BLAKE2b_256', "A","A","A"), "cdc4339296753f930aa454700fd0ded6e1e08772dea849859e17dbbd85cae649", 'blake2b_256 (digest_data_hex/tripple_A)'); +is( digest_data_b64('BLAKE2b_256', "A","A","A"), "zcQzkpZ1P5MKpFRwD9De1uHgh3LeqEmFnhfbvYXK5kk=", 'blake2b_256 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('BLAKE2b_256', "A","A","A"), "zcQzkpZ1P5MKpFRwD9De1uHgh3LeqEmFnhfbvYXK5kk", 'blake2b_256 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::BLAKE2b_256->new->add("A","A","A")->hexdigest, "cdc4339296753f930aa454700fd0ded6e1e08772dea849859e17dbbd85cae649", 'blake2b_256 (OO/tripple_A)'); +is( Crypt::Digest::BLAKE2b_256->new->add("A")->add("A")->add("A")->hexdigest, "cdc4339296753f930aa454700fd0ded6e1e08772dea849859e17dbbd85cae649", 'blake2b_256 (OO3/tripple_A)'); + is( blake2b_256(""), pack("H*","0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8"), 'blake2b_256 (raw/1)'); is( blake2b_256_hex(""), "0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8", 'blake2b_256 (hex/1)'); diff --git a/t/digest_blake2b_384.t b/t/digest_blake2b_384.t index 1ed548ba..f686152a 100644 --- a/t/digest_blake2b_384.t +++ b/t/digest_blake2b_384.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::BLAKE2b_384 qw( blake2b_384 blake2b_384_hex blake2b_384_b64 blake2b_384_b64u blake2b_384_file blake2b_384_file_hex blake2b_384_file_b64 blake2b_384_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::BLAKE2b_384->hashsize, 48, 'hashsize/4'); is( Crypt::Digest->new('BLAKE2b_384')->hashsize, 48, 'hashsize/5'); is( Crypt::Digest::BLAKE2b_384->new->hashsize, 48, 'hashsize/6'); +is( blake2b_384("A","A","A"), pack("H*","9aa07d9caf17bff49747fc9488eb6babcdcd575616f85a91758ee50e6e49a4884bf6fb46b424e0ae669071ccd8cb1685"), 'blake2b_384 (raw/tripple_A)'); +is( blake2b_384_hex("A","A","A"), "9aa07d9caf17bff49747fc9488eb6babcdcd575616f85a91758ee50e6e49a4884bf6fb46b424e0ae669071ccd8cb1685", 'blake2b_384 (hex/tripple_A)'); +is( blake2b_384_b64("A","A","A"), "mqB9nK8Xv/SXR/yUiOtrq83NV1YW+FqRdY7lDm5JpIhL9vtGtCTgrmaQcczYyxaF", 'blake2b_384 (base64/tripple_A)'); +is( blake2b_384_b64u("A","A","A"), "mqB9nK8Xv_SXR_yUiOtrq83NV1YW-FqRdY7lDm5JpIhL9vtGtCTgrmaQcczYyxaF", 'blake2b_384 (base64url/tripple_A)'); +is( digest_data('BLAKE2b_384', "A","A","A"), pack("H*","9aa07d9caf17bff49747fc9488eb6babcdcd575616f85a91758ee50e6e49a4884bf6fb46b424e0ae669071ccd8cb1685"), 'blake2b_384 (digest_data_raw/tripple_A)'); +is( digest_data_hex('BLAKE2b_384', "A","A","A"), "9aa07d9caf17bff49747fc9488eb6babcdcd575616f85a91758ee50e6e49a4884bf6fb46b424e0ae669071ccd8cb1685", 'blake2b_384 (digest_data_hex/tripple_A)'); +is( digest_data_b64('BLAKE2b_384', "A","A","A"), "mqB9nK8Xv/SXR/yUiOtrq83NV1YW+FqRdY7lDm5JpIhL9vtGtCTgrmaQcczYyxaF", 'blake2b_384 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('BLAKE2b_384', "A","A","A"), "mqB9nK8Xv_SXR_yUiOtrq83NV1YW-FqRdY7lDm5JpIhL9vtGtCTgrmaQcczYyxaF", 'blake2b_384 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::BLAKE2b_384->new->add("A","A","A")->hexdigest, "9aa07d9caf17bff49747fc9488eb6babcdcd575616f85a91758ee50e6e49a4884bf6fb46b424e0ae669071ccd8cb1685", 'blake2b_384 (OO/tripple_A)'); +is( Crypt::Digest::BLAKE2b_384->new->add("A")->add("A")->add("A")->hexdigest, "9aa07d9caf17bff49747fc9488eb6babcdcd575616f85a91758ee50e6e49a4884bf6fb46b424e0ae669071ccd8cb1685", 'blake2b_384 (OO3/tripple_A)'); + is( blake2b_384(""), pack("H*","b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100"), 'blake2b_384 (raw/1)'); is( blake2b_384_hex(""), "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100", 'blake2b_384 (hex/1)'); diff --git a/t/digest_blake2b_512.t b/t/digest_blake2b_512.t index 02d2a33b..ac1132a4 100644 --- a/t/digest_blake2b_512.t +++ b/t/digest_blake2b_512.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::BLAKE2b_512 qw( blake2b_512 blake2b_512_hex blake2b_512_b64 blake2b_512_b64u blake2b_512_file blake2b_512_file_hex blake2b_512_file_b64 blake2b_512_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::BLAKE2b_512->hashsize, 64, 'hashsize/4'); is( Crypt::Digest->new('BLAKE2b_512')->hashsize, 64, 'hashsize/5'); is( Crypt::Digest::BLAKE2b_512->new->hashsize, 64, 'hashsize/6'); +is( blake2b_512("A","A","A"), pack("H*","dda5c92ae5adba047d317f99dc58a9059b5a8c0907f95d8cddcf5bfdaa8e4c74ddd84bc2683cdc2d16a340ff5798e1bf4bd2c838332611f266bb62870d33b823"), 'blake2b_512 (raw/tripple_A)'); +is( blake2b_512_hex("A","A","A"), "dda5c92ae5adba047d317f99dc58a9059b5a8c0907f95d8cddcf5bfdaa8e4c74ddd84bc2683cdc2d16a340ff5798e1bf4bd2c838332611f266bb62870d33b823", 'blake2b_512 (hex/tripple_A)'); +is( blake2b_512_b64("A","A","A"), "3aXJKuWtugR9MX+Z3FipBZtajAkH+V2M3c9b/aqOTHTd2EvCaDzcLRajQP9XmOG/S9LIODMmEfJmu2KHDTO4Iw==", 'blake2b_512 (base64/tripple_A)'); +is( blake2b_512_b64u("A","A","A"), "3aXJKuWtugR9MX-Z3FipBZtajAkH-V2M3c9b_aqOTHTd2EvCaDzcLRajQP9XmOG_S9LIODMmEfJmu2KHDTO4Iw", 'blake2b_512 (base64url/tripple_A)'); +is( digest_data('BLAKE2b_512', "A","A","A"), pack("H*","dda5c92ae5adba047d317f99dc58a9059b5a8c0907f95d8cddcf5bfdaa8e4c74ddd84bc2683cdc2d16a340ff5798e1bf4bd2c838332611f266bb62870d33b823"), 'blake2b_512 (digest_data_raw/tripple_A)'); +is( digest_data_hex('BLAKE2b_512', "A","A","A"), "dda5c92ae5adba047d317f99dc58a9059b5a8c0907f95d8cddcf5bfdaa8e4c74ddd84bc2683cdc2d16a340ff5798e1bf4bd2c838332611f266bb62870d33b823", 'blake2b_512 (digest_data_hex/tripple_A)'); +is( digest_data_b64('BLAKE2b_512', "A","A","A"), "3aXJKuWtugR9MX+Z3FipBZtajAkH+V2M3c9b/aqOTHTd2EvCaDzcLRajQP9XmOG/S9LIODMmEfJmu2KHDTO4Iw==", 'blake2b_512 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('BLAKE2b_512', "A","A","A"), "3aXJKuWtugR9MX-Z3FipBZtajAkH-V2M3c9b_aqOTHTd2EvCaDzcLRajQP9XmOG_S9LIODMmEfJmu2KHDTO4Iw", 'blake2b_512 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::BLAKE2b_512->new->add("A","A","A")->hexdigest, "dda5c92ae5adba047d317f99dc58a9059b5a8c0907f95d8cddcf5bfdaa8e4c74ddd84bc2683cdc2d16a340ff5798e1bf4bd2c838332611f266bb62870d33b823", 'blake2b_512 (OO/tripple_A)'); +is( Crypt::Digest::BLAKE2b_512->new->add("A")->add("A")->add("A")->hexdigest, "dda5c92ae5adba047d317f99dc58a9059b5a8c0907f95d8cddcf5bfdaa8e4c74ddd84bc2683cdc2d16a340ff5798e1bf4bd2c838332611f266bb62870d33b823", 'blake2b_512 (OO3/tripple_A)'); + is( blake2b_512(""), pack("H*","786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce"), 'blake2b_512 (raw/1)'); is( blake2b_512_hex(""), "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce", 'blake2b_512 (hex/1)'); diff --git a/t/digest_blake2s_128.t b/t/digest_blake2s_128.t index eafbcf7f..b46783ba 100644 --- a/t/digest_blake2s_128.t +++ b/t/digest_blake2s_128.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::BLAKE2s_128 qw( blake2s_128 blake2s_128_hex blake2s_128_b64 blake2s_128_b64u blake2s_128_file blake2s_128_file_hex blake2s_128_file_b64 blake2s_128_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::BLAKE2s_128->hashsize, 16, 'hashsize/4'); is( Crypt::Digest->new('BLAKE2s_128')->hashsize, 16, 'hashsize/5'); is( Crypt::Digest::BLAKE2s_128->new->hashsize, 16, 'hashsize/6'); +is( blake2s_128("A","A","A"), pack("H*","a2a5699c7579ee354f4d20fa75f09cb6"), 'blake2s_128 (raw/tripple_A)'); +is( blake2s_128_hex("A","A","A"), "a2a5699c7579ee354f4d20fa75f09cb6", 'blake2s_128 (hex/tripple_A)'); +is( blake2s_128_b64("A","A","A"), "oqVpnHV57jVPTSD6dfCctg==", 'blake2s_128 (base64/tripple_A)'); +is( blake2s_128_b64u("A","A","A"), "oqVpnHV57jVPTSD6dfCctg", 'blake2s_128 (base64url/tripple_A)'); +is( digest_data('BLAKE2s_128', "A","A","A"), pack("H*","a2a5699c7579ee354f4d20fa75f09cb6"), 'blake2s_128 (digest_data_raw/tripple_A)'); +is( digest_data_hex('BLAKE2s_128', "A","A","A"), "a2a5699c7579ee354f4d20fa75f09cb6", 'blake2s_128 (digest_data_hex/tripple_A)'); +is( digest_data_b64('BLAKE2s_128', "A","A","A"), "oqVpnHV57jVPTSD6dfCctg==", 'blake2s_128 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('BLAKE2s_128', "A","A","A"), "oqVpnHV57jVPTSD6dfCctg", 'blake2s_128 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::BLAKE2s_128->new->add("A","A","A")->hexdigest, "a2a5699c7579ee354f4d20fa75f09cb6", 'blake2s_128 (OO/tripple_A)'); +is( Crypt::Digest::BLAKE2s_128->new->add("A")->add("A")->add("A")->hexdigest, "a2a5699c7579ee354f4d20fa75f09cb6", 'blake2s_128 (OO3/tripple_A)'); + is( blake2s_128(""), pack("H*","64550d6ffe2c0a01a14aba1eade0200c"), 'blake2s_128 (raw/1)'); is( blake2s_128_hex(""), "64550d6ffe2c0a01a14aba1eade0200c", 'blake2s_128 (hex/1)'); diff --git a/t/digest_blake2s_160.t b/t/digest_blake2s_160.t index e30a01b5..03802391 100644 --- a/t/digest_blake2s_160.t +++ b/t/digest_blake2s_160.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::BLAKE2s_160 qw( blake2s_160 blake2s_160_hex blake2s_160_b64 blake2s_160_b64u blake2s_160_file blake2s_160_file_hex blake2s_160_file_b64 blake2s_160_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::BLAKE2s_160->hashsize, 20, 'hashsize/4'); is( Crypt::Digest->new('BLAKE2s_160')->hashsize, 20, 'hashsize/5'); is( Crypt::Digest::BLAKE2s_160->new->hashsize, 20, 'hashsize/6'); +is( blake2s_160("A","A","A"), pack("H*","f44c709aebd62a7a13bd6ee5979981970a60e117"), 'blake2s_160 (raw/tripple_A)'); +is( blake2s_160_hex("A","A","A"), "f44c709aebd62a7a13bd6ee5979981970a60e117", 'blake2s_160 (hex/tripple_A)'); +is( blake2s_160_b64("A","A","A"), "9ExwmuvWKnoTvW7ll5mBlwpg4Rc=", 'blake2s_160 (base64/tripple_A)'); +is( blake2s_160_b64u("A","A","A"), "9ExwmuvWKnoTvW7ll5mBlwpg4Rc", 'blake2s_160 (base64url/tripple_A)'); +is( digest_data('BLAKE2s_160', "A","A","A"), pack("H*","f44c709aebd62a7a13bd6ee5979981970a60e117"), 'blake2s_160 (digest_data_raw/tripple_A)'); +is( digest_data_hex('BLAKE2s_160', "A","A","A"), "f44c709aebd62a7a13bd6ee5979981970a60e117", 'blake2s_160 (digest_data_hex/tripple_A)'); +is( digest_data_b64('BLAKE2s_160', "A","A","A"), "9ExwmuvWKnoTvW7ll5mBlwpg4Rc=", 'blake2s_160 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('BLAKE2s_160', "A","A","A"), "9ExwmuvWKnoTvW7ll5mBlwpg4Rc", 'blake2s_160 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::BLAKE2s_160->new->add("A","A","A")->hexdigest, "f44c709aebd62a7a13bd6ee5979981970a60e117", 'blake2s_160 (OO/tripple_A)'); +is( Crypt::Digest::BLAKE2s_160->new->add("A")->add("A")->add("A")->hexdigest, "f44c709aebd62a7a13bd6ee5979981970a60e117", 'blake2s_160 (OO3/tripple_A)'); + is( blake2s_160(""), pack("H*","354c9c33f735962418bdacb9479873429c34916f"), 'blake2s_160 (raw/1)'); is( blake2s_160_hex(""), "354c9c33f735962418bdacb9479873429c34916f", 'blake2s_160 (hex/1)'); diff --git a/t/digest_blake2s_224.t b/t/digest_blake2s_224.t index b96349a9..eeb96f77 100644 --- a/t/digest_blake2s_224.t +++ b/t/digest_blake2s_224.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::BLAKE2s_224 qw( blake2s_224 blake2s_224_hex blake2s_224_b64 blake2s_224_b64u blake2s_224_file blake2s_224_file_hex blake2s_224_file_b64 blake2s_224_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::BLAKE2s_224->hashsize, 28, 'hashsize/4'); is( Crypt::Digest->new('BLAKE2s_224')->hashsize, 28, 'hashsize/5'); is( Crypt::Digest::BLAKE2s_224->new->hashsize, 28, 'hashsize/6'); +is( blake2s_224("A","A","A"), pack("H*","8c2738e18d0b9645870d7da4b52756cef46c5f3d185f4ea93c361006"), 'blake2s_224 (raw/tripple_A)'); +is( blake2s_224_hex("A","A","A"), "8c2738e18d0b9645870d7da4b52756cef46c5f3d185f4ea93c361006", 'blake2s_224 (hex/tripple_A)'); +is( blake2s_224_b64("A","A","A"), "jCc44Y0LlkWHDX2ktSdWzvRsXz0YX06pPDYQBg==", 'blake2s_224 (base64/tripple_A)'); +is( blake2s_224_b64u("A","A","A"), "jCc44Y0LlkWHDX2ktSdWzvRsXz0YX06pPDYQBg", 'blake2s_224 (base64url/tripple_A)'); +is( digest_data('BLAKE2s_224', "A","A","A"), pack("H*","8c2738e18d0b9645870d7da4b52756cef46c5f3d185f4ea93c361006"), 'blake2s_224 (digest_data_raw/tripple_A)'); +is( digest_data_hex('BLAKE2s_224', "A","A","A"), "8c2738e18d0b9645870d7da4b52756cef46c5f3d185f4ea93c361006", 'blake2s_224 (digest_data_hex/tripple_A)'); +is( digest_data_b64('BLAKE2s_224', "A","A","A"), "jCc44Y0LlkWHDX2ktSdWzvRsXz0YX06pPDYQBg==", 'blake2s_224 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('BLAKE2s_224', "A","A","A"), "jCc44Y0LlkWHDX2ktSdWzvRsXz0YX06pPDYQBg", 'blake2s_224 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::BLAKE2s_224->new->add("A","A","A")->hexdigest, "8c2738e18d0b9645870d7da4b52756cef46c5f3d185f4ea93c361006", 'blake2s_224 (OO/tripple_A)'); +is( Crypt::Digest::BLAKE2s_224->new->add("A")->add("A")->add("A")->hexdigest, "8c2738e18d0b9645870d7da4b52756cef46c5f3d185f4ea93c361006", 'blake2s_224 (OO3/tripple_A)'); + is( blake2s_224(""), pack("H*","1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4"), 'blake2s_224 (raw/1)'); is( blake2s_224_hex(""), "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4", 'blake2s_224 (hex/1)'); diff --git a/t/digest_blake2s_256.t b/t/digest_blake2s_256.t index 7441c1b0..71ff957e 100644 --- a/t/digest_blake2s_256.t +++ b/t/digest_blake2s_256.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::BLAKE2s_256 qw( blake2s_256 blake2s_256_hex blake2s_256_b64 blake2s_256_b64u blake2s_256_file blake2s_256_file_hex blake2s_256_file_b64 blake2s_256_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::BLAKE2s_256->hashsize, 32, 'hashsize/4'); is( Crypt::Digest->new('BLAKE2s_256')->hashsize, 32, 'hashsize/5'); is( Crypt::Digest::BLAKE2s_256->new->hashsize, 32, 'hashsize/6'); +is( blake2s_256("A","A","A"), pack("H*","8d4fe9f5368ff397ce7444640f522f090597591c21392262138da6750bf1dff6"), 'blake2s_256 (raw/tripple_A)'); +is( blake2s_256_hex("A","A","A"), "8d4fe9f5368ff397ce7444640f522f090597591c21392262138da6750bf1dff6", 'blake2s_256 (hex/tripple_A)'); +is( blake2s_256_b64("A","A","A"), "jU/p9TaP85fOdERkD1IvCQWXWRwhOSJiE42mdQvx3/Y=", 'blake2s_256 (base64/tripple_A)'); +is( blake2s_256_b64u("A","A","A"), "jU_p9TaP85fOdERkD1IvCQWXWRwhOSJiE42mdQvx3_Y", 'blake2s_256 (base64url/tripple_A)'); +is( digest_data('BLAKE2s_256', "A","A","A"), pack("H*","8d4fe9f5368ff397ce7444640f522f090597591c21392262138da6750bf1dff6"), 'blake2s_256 (digest_data_raw/tripple_A)'); +is( digest_data_hex('BLAKE2s_256', "A","A","A"), "8d4fe9f5368ff397ce7444640f522f090597591c21392262138da6750bf1dff6", 'blake2s_256 (digest_data_hex/tripple_A)'); +is( digest_data_b64('BLAKE2s_256', "A","A","A"), "jU/p9TaP85fOdERkD1IvCQWXWRwhOSJiE42mdQvx3/Y=", 'blake2s_256 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('BLAKE2s_256', "A","A","A"), "jU_p9TaP85fOdERkD1IvCQWXWRwhOSJiE42mdQvx3_Y", 'blake2s_256 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::BLAKE2s_256->new->add("A","A","A")->hexdigest, "8d4fe9f5368ff397ce7444640f522f090597591c21392262138da6750bf1dff6", 'blake2s_256 (OO/tripple_A)'); +is( Crypt::Digest::BLAKE2s_256->new->add("A")->add("A")->add("A")->hexdigest, "8d4fe9f5368ff397ce7444640f522f090597591c21392262138da6750bf1dff6", 'blake2s_256 (OO3/tripple_A)'); + is( blake2s_256(""), pack("H*","69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9"), 'blake2s_256 (raw/1)'); is( blake2s_256_hex(""), "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9", 'blake2s_256 (hex/1)'); diff --git a/t/digest_chaes.t b/t/digest_chaes.t index 82534d19..82b496e6 100644 --- a/t/digest_chaes.t +++ b/t/digest_chaes.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::CHAES qw( chaes chaes_hex chaes_b64 chaes_b64u chaes_file chaes_file_hex chaes_file_b64 chaes_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::CHAES->hashsize, 16, 'hashsize/4'); is( Crypt::Digest->new('CHAES')->hashsize, 16, 'hashsize/5'); is( Crypt::Digest::CHAES->new->hashsize, 16, 'hashsize/6'); +is( chaes("A","A","A"), pack("H*","f01416b4c3f6389816b2fcd0b4cf9e41"), 'chaes (raw/tripple_A)'); +is( chaes_hex("A","A","A"), "f01416b4c3f6389816b2fcd0b4cf9e41", 'chaes (hex/tripple_A)'); +is( chaes_b64("A","A","A"), "8BQWtMP2OJgWsvzQtM+eQQ==", 'chaes (base64/tripple_A)'); +is( chaes_b64u("A","A","A"), "8BQWtMP2OJgWsvzQtM-eQQ", 'chaes (base64url/tripple_A)'); +is( digest_data('CHAES', "A","A","A"), pack("H*","f01416b4c3f6389816b2fcd0b4cf9e41"), 'chaes (digest_data_raw/tripple_A)'); +is( digest_data_hex('CHAES', "A","A","A"), "f01416b4c3f6389816b2fcd0b4cf9e41", 'chaes (digest_data_hex/tripple_A)'); +is( digest_data_b64('CHAES', "A","A","A"), "8BQWtMP2OJgWsvzQtM+eQQ==", 'chaes (digest_data_b64/tripple_A)'); +is( digest_data_b64u('CHAES', "A","A","A"), "8BQWtMP2OJgWsvzQtM-eQQ", 'chaes (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::CHAES->new->add("A","A","A")->hexdigest, "f01416b4c3f6389816b2fcd0b4cf9e41", 'chaes (OO/tripple_A)'); +is( Crypt::Digest::CHAES->new->add("A")->add("A")->add("A")->hexdigest, "f01416b4c3f6389816b2fcd0b4cf9e41", 'chaes (OO3/tripple_A)'); + is( chaes(""), pack("H*","4047929f1f572643b55f829eb3291d11"), 'chaes (raw/1)'); is( chaes_hex(""), "4047929f1f572643b55f829eb3291d11", 'chaes (hex/1)'); diff --git a/t/digest_keccak224.t b/t/digest_keccak224.t new file mode 100644 index 00000000..10daf0e6 --- /dev/null +++ b/t/digest_keccak224.t @@ -0,0 +1,116 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 10 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::Keccak224 qw( keccak224 keccak224_hex keccak224_b64 keccak224_b64u keccak224_file keccak224_file_hex keccak224_file_b64 keccak224_file_b64u ); + +is( Crypt::Digest::hashsize('Keccak224'), 28, 'hashsize/1'); +is( Crypt::Digest->hashsize('Keccak224'), 28, 'hashsize/2'); +is( Crypt::Digest::Keccak224::hashsize, 28, 'hashsize/3'); +is( Crypt::Digest::Keccak224->hashsize, 28, 'hashsize/4'); +is( Crypt::Digest->new('Keccak224')->hashsize, 28, 'hashsize/5'); +is( Crypt::Digest::Keccak224->new->hashsize, 28, 'hashsize/6'); + +is( keccak224("A","A","A"), pack("H*","92b9d2a25222d2a036c53bd4dd246b4073d100e0ae20ac7240f5b252"), 'keccak224 (raw/tripple_A)'); +is( keccak224_hex("A","A","A"), "92b9d2a25222d2a036c53bd4dd246b4073d100e0ae20ac7240f5b252", 'keccak224 (hex/tripple_A)'); +is( keccak224_b64("A","A","A"), "krnSolIi0qA2xTvU3SRrQHPRAOCuIKxyQPWyUg==", 'keccak224 (base64/tripple_A)'); +is( keccak224_b64u("A","A","A"), "krnSolIi0qA2xTvU3SRrQHPRAOCuIKxyQPWyUg", 'keccak224 (base64url/tripple_A)'); +is( digest_data('Keccak224', "A","A","A"), pack("H*","92b9d2a25222d2a036c53bd4dd246b4073d100e0ae20ac7240f5b252"), 'keccak224 (digest_data_raw/tripple_A)'); +is( digest_data_hex('Keccak224', "A","A","A"), "92b9d2a25222d2a036c53bd4dd246b4073d100e0ae20ac7240f5b252", 'keccak224 (digest_data_hex/tripple_A)'); +is( digest_data_b64('Keccak224', "A","A","A"), "krnSolIi0qA2xTvU3SRrQHPRAOCuIKxyQPWyUg==", 'keccak224 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('Keccak224', "A","A","A"), "krnSolIi0qA2xTvU3SRrQHPRAOCuIKxyQPWyUg", 'keccak224 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::Keccak224->new->add("A","A","A")->hexdigest, "92b9d2a25222d2a036c53bd4dd246b4073d100e0ae20ac7240f5b252", 'keccak224 (OO/tripple_A)'); +is( Crypt::Digest::Keccak224->new->add("A")->add("A")->add("A")->hexdigest, "92b9d2a25222d2a036c53bd4dd246b4073d100e0ae20ac7240f5b252", 'keccak224 (OO3/tripple_A)'); + + +is( keccak224(""), pack("H*","f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd"), 'keccak224 (raw/1)'); +is( keccak224_hex(""), "f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd", 'keccak224 (hex/1)'); +is( keccak224_b64(""), "9xg3UCuo4Qg3vdjTZa24VZGJVgL8VStItzkKvQ==", 'keccak224 (base64/1)'); +is( digest_data('Keccak224', ""), pack("H*","f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd"), 'keccak224 (digest_data_raw/1)'); +is( digest_data_hex('Keccak224', ""), "f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd", 'keccak224 (digest_data_hex/1)'); +is( digest_data_b64('Keccak224', ""), "9xg3UCuo4Qg3vdjTZa24VZGJVgL8VStItzkKvQ==", 'keccak224 (digest_data_b64/1)'); +is( digest_data_b64u('Keccak224', ""), "9xg3UCuo4Qg3vdjTZa24VZGJVgL8VStItzkKvQ", 'keccak224 (digest_data_b64u/1)'); +is( Crypt::Digest::Keccak224->new->add("")->hexdigest, "f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd", 'keccak224 (OO/1)'); + +is( keccak224("123"), pack("H*","5c52615361ce4c5469f9d8c90113c7a543a4bf43490782d291cb32d8"), 'keccak224 (raw/2)'); +is( keccak224_hex("123"), "5c52615361ce4c5469f9d8c90113c7a543a4bf43490782d291cb32d8", 'keccak224 (hex/2)'); +is( keccak224_b64("123"), "XFJhU2HOTFRp+djJARPHpUOkv0NJB4LSkcsy2A==", 'keccak224 (base64/2)'); +is( digest_data('Keccak224', "123"), pack("H*","5c52615361ce4c5469f9d8c90113c7a543a4bf43490782d291cb32d8"), 'keccak224 (digest_data_raw/2)'); +is( digest_data_hex('Keccak224', "123"), "5c52615361ce4c5469f9d8c90113c7a543a4bf43490782d291cb32d8", 'keccak224 (digest_data_hex/2)'); +is( digest_data_b64('Keccak224', "123"), "XFJhU2HOTFRp+djJARPHpUOkv0NJB4LSkcsy2A==", 'keccak224 (digest_data_b64/2)'); +is( digest_data_b64u('Keccak224', "123"), "XFJhU2HOTFRp-djJARPHpUOkv0NJB4LSkcsy2A", 'keccak224 (digest_data_b64u/2)'); +is( Crypt::Digest::Keccak224->new->add("123")->hexdigest, "5c52615361ce4c5469f9d8c90113c7a543a4bf43490782d291cb32d8", 'keccak224 (OO/2)'); + +is( keccak224("test\0test\0test\n"), pack("H*","7cbb8e9a6026e7c8324ab2f1cba55a1aff03b7b0424b8915b0439179"), 'keccak224 (raw/3)'); +is( keccak224_hex("test\0test\0test\n"), "7cbb8e9a6026e7c8324ab2f1cba55a1aff03b7b0424b8915b0439179", 'keccak224 (hex/3)'); +is( keccak224_b64("test\0test\0test\n"), "fLuOmmAm58gySrLxy6VaGv8Dt7BCS4kVsEOReQ==", 'keccak224 (base64/3)'); +is( digest_data('Keccak224', "test\0test\0test\n"), pack("H*","7cbb8e9a6026e7c8324ab2f1cba55a1aff03b7b0424b8915b0439179"), 'keccak224 (digest_data_raw/3)'); +is( digest_data_hex('Keccak224', "test\0test\0test\n"), "7cbb8e9a6026e7c8324ab2f1cba55a1aff03b7b0424b8915b0439179", 'keccak224 (digest_data_hex/3)'); +is( digest_data_b64('Keccak224', "test\0test\0test\n"), "fLuOmmAm58gySrLxy6VaGv8Dt7BCS4kVsEOReQ==", 'keccak224 (digest_data_b64/3)'); +is( digest_data_b64u('Keccak224', "test\0test\0test\n"), "fLuOmmAm58gySrLxy6VaGv8Dt7BCS4kVsEOReQ", 'keccak224 (digest_data_b64u/3)'); +is( Crypt::Digest::Keccak224->new->add("test\0test\0test\n")->hexdigest, "7cbb8e9a6026e7c8324ab2f1cba55a1aff03b7b0424b8915b0439179", 'keccak224 (OO/3)'); + + +is( keccak224_file('t/data/binary-test.file'), pack("H*","8f1651ffab903619314a1b3d7c89aefbc1f8f541289b1889320b1a8e"), 'keccak224 (raw/file/1)'); +is( keccak224_file_hex('t/data/binary-test.file'), "8f1651ffab903619314a1b3d7c89aefbc1f8f541289b1889320b1a8e", 'keccak224 (hex/file/1)'); +is( keccak224_file_b64('t/data/binary-test.file'), "jxZR/6uQNhkxShs9fImu+8H49UEomxiJMgsajg==", 'keccak224 (base64/file/1)'); +is( digest_file('Keccak224', 't/data/binary-test.file'), pack("H*","8f1651ffab903619314a1b3d7c89aefbc1f8f541289b1889320b1a8e"), 'keccak224 (digest_file_raw/file/1)'); +is( digest_file_hex('Keccak224', 't/data/binary-test.file'), "8f1651ffab903619314a1b3d7c89aefbc1f8f541289b1889320b1a8e", 'keccak224 (digest_file_hex/file/1)'); +is( digest_file_b64('Keccak224', 't/data/binary-test.file'), "jxZR/6uQNhkxShs9fImu+8H49UEomxiJMgsajg==", 'keccak224 (digest_file_b64/file/1)'); +is( digest_file_b64u('Keccak224', 't/data/binary-test.file'), "jxZR_6uQNhkxShs9fImu-8H49UEomxiJMgsajg", 'keccak224 (digest_file_b64u/file/1)'); +is( Crypt::Digest::Keccak224->new->addfile('t/data/binary-test.file')->hexdigest, "8f1651ffab903619314a1b3d7c89aefbc1f8f541289b1889320b1a8e", 'keccak224 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::Keccak224->new->addfile($fh)->hexdigest, "8f1651ffab903619314a1b3d7c89aefbc1f8f541289b1889320b1a8e", 'keccak224 (OO/filehandle/1)'); + close($fh); +} + +is( keccak224_file('t/data/text-CR.file'), pack("H*","28ff8a17382e1fa11c37cd6e2543bf257f914aae3760ef77073987c8"), 'keccak224 (raw/file/2)'); +is( keccak224_file_hex('t/data/text-CR.file'), "28ff8a17382e1fa11c37cd6e2543bf257f914aae3760ef77073987c8", 'keccak224 (hex/file/2)'); +is( keccak224_file_b64('t/data/text-CR.file'), "KP+KFzguH6EcN81uJUO/JX+RSq43YO93BzmHyA==", 'keccak224 (base64/file/2)'); +is( digest_file('Keccak224', 't/data/text-CR.file'), pack("H*","28ff8a17382e1fa11c37cd6e2543bf257f914aae3760ef77073987c8"), 'keccak224 (digest_file_raw/file/2)'); +is( digest_file_hex('Keccak224', 't/data/text-CR.file'), "28ff8a17382e1fa11c37cd6e2543bf257f914aae3760ef77073987c8", 'keccak224 (digest_file_hex/file/2)'); +is( digest_file_b64('Keccak224', 't/data/text-CR.file'), "KP+KFzguH6EcN81uJUO/JX+RSq43YO93BzmHyA==", 'keccak224 (digest_file_b64/file/2)'); +is( digest_file_b64u('Keccak224', 't/data/text-CR.file'), "KP-KFzguH6EcN81uJUO_JX-RSq43YO93BzmHyA", 'keccak224 (digest_file_b64u/file/2)'); +is( Crypt::Digest::Keccak224->new->addfile('t/data/text-CR.file')->hexdigest, "28ff8a17382e1fa11c37cd6e2543bf257f914aae3760ef77073987c8", 'keccak224 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::Keccak224->new->addfile($fh)->hexdigest, "28ff8a17382e1fa11c37cd6e2543bf257f914aae3760ef77073987c8", 'keccak224 (OO/filehandle/2)'); + close($fh); +} + +is( keccak224_file('t/data/text-CRLF.file'), pack("H*","26659008759423cde44c4984748af6b61d7d4ea5c7e81be58fb72faa"), 'keccak224 (raw/file/3)'); +is( keccak224_file_hex('t/data/text-CRLF.file'), "26659008759423cde44c4984748af6b61d7d4ea5c7e81be58fb72faa", 'keccak224 (hex/file/3)'); +is( keccak224_file_b64('t/data/text-CRLF.file'), "JmWQCHWUI83kTEmEdIr2th19TqXH6Bvlj7cvqg==", 'keccak224 (base64/file/3)'); +is( digest_file('Keccak224', 't/data/text-CRLF.file'), pack("H*","26659008759423cde44c4984748af6b61d7d4ea5c7e81be58fb72faa"), 'keccak224 (digest_file_raw/file/3)'); +is( digest_file_hex('Keccak224', 't/data/text-CRLF.file'), "26659008759423cde44c4984748af6b61d7d4ea5c7e81be58fb72faa", 'keccak224 (digest_file_hex/file/3)'); +is( digest_file_b64('Keccak224', 't/data/text-CRLF.file'), "JmWQCHWUI83kTEmEdIr2th19TqXH6Bvlj7cvqg==", 'keccak224 (digest_file_b64/file/3)'); +is( digest_file_b64u('Keccak224', 't/data/text-CRLF.file'), "JmWQCHWUI83kTEmEdIr2th19TqXH6Bvlj7cvqg", 'keccak224 (digest_file_b64u/file/3)'); +is( Crypt::Digest::Keccak224->new->addfile('t/data/text-CRLF.file')->hexdigest, "26659008759423cde44c4984748af6b61d7d4ea5c7e81be58fb72faa", 'keccak224 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::Keccak224->new->addfile($fh)->hexdigest, "26659008759423cde44c4984748af6b61d7d4ea5c7e81be58fb72faa", 'keccak224 (OO/filehandle/3)'); + close($fh); +} + +is( keccak224_file('t/data/text-LF.file'), pack("H*","2021717d16f99f493960d0839a3cb2b01be8078c28b425d7f1c8662b"), 'keccak224 (raw/file/4)'); +is( keccak224_file_hex('t/data/text-LF.file'), "2021717d16f99f493960d0839a3cb2b01be8078c28b425d7f1c8662b", 'keccak224 (hex/file/4)'); +is( keccak224_file_b64('t/data/text-LF.file'), "ICFxfRb5n0k5YNCDmjyysBvoB4wotCXX8chmKw==", 'keccak224 (base64/file/4)'); +is( digest_file('Keccak224', 't/data/text-LF.file'), pack("H*","2021717d16f99f493960d0839a3cb2b01be8078c28b425d7f1c8662b"), 'keccak224 (digest_file_raw/file/4)'); +is( digest_file_hex('Keccak224', 't/data/text-LF.file'), "2021717d16f99f493960d0839a3cb2b01be8078c28b425d7f1c8662b", 'keccak224 (digest_file_hex/file/4)'); +is( digest_file_b64('Keccak224', 't/data/text-LF.file'), "ICFxfRb5n0k5YNCDmjyysBvoB4wotCXX8chmKw==", 'keccak224 (digest_file_b64/file/4)'); +is( digest_file_b64u('Keccak224', 't/data/text-LF.file'), "ICFxfRb5n0k5YNCDmjyysBvoB4wotCXX8chmKw", 'keccak224 (digest_file_b64u/file/4)'); +is( Crypt::Digest::Keccak224->new->addfile('t/data/text-LF.file')->hexdigest, "2021717d16f99f493960d0839a3cb2b01be8078c28b425d7f1c8662b", 'keccak224 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::Keccak224->new->addfile($fh)->hexdigest, "2021717d16f99f493960d0839a3cb2b01be8078c28b425d7f1c8662b", 'keccak224 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_keccak256.t b/t/digest_keccak256.t new file mode 100644 index 00000000..25821470 --- /dev/null +++ b/t/digest_keccak256.t @@ -0,0 +1,116 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 10 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::Keccak256 qw( keccak256 keccak256_hex keccak256_b64 keccak256_b64u keccak256_file keccak256_file_hex keccak256_file_b64 keccak256_file_b64u ); + +is( Crypt::Digest::hashsize('Keccak256'), 32, 'hashsize/1'); +is( Crypt::Digest->hashsize('Keccak256'), 32, 'hashsize/2'); +is( Crypt::Digest::Keccak256::hashsize, 32, 'hashsize/3'); +is( Crypt::Digest::Keccak256->hashsize, 32, 'hashsize/4'); +is( Crypt::Digest->new('Keccak256')->hashsize, 32, 'hashsize/5'); +is( Crypt::Digest::Keccak256->new->hashsize, 32, 'hashsize/6'); + +is( keccak256("A","A","A"), pack("H*","2070504003a07b4713d783ae7a6642ab3b959b7c575c6e4fa4f33eb743db631a"), 'keccak256 (raw/tripple_A)'); +is( keccak256_hex("A","A","A"), "2070504003a07b4713d783ae7a6642ab3b959b7c575c6e4fa4f33eb743db631a", 'keccak256 (hex/tripple_A)'); +is( keccak256_b64("A","A","A"), "IHBQQAOge0cT14OuemZCqzuVm3xXXG5PpPM+t0PbYxo=", 'keccak256 (base64/tripple_A)'); +is( keccak256_b64u("A","A","A"), "IHBQQAOge0cT14OuemZCqzuVm3xXXG5PpPM-t0PbYxo", 'keccak256 (base64url/tripple_A)'); +is( digest_data('Keccak256', "A","A","A"), pack("H*","2070504003a07b4713d783ae7a6642ab3b959b7c575c6e4fa4f33eb743db631a"), 'keccak256 (digest_data_raw/tripple_A)'); +is( digest_data_hex('Keccak256', "A","A","A"), "2070504003a07b4713d783ae7a6642ab3b959b7c575c6e4fa4f33eb743db631a", 'keccak256 (digest_data_hex/tripple_A)'); +is( digest_data_b64('Keccak256', "A","A","A"), "IHBQQAOge0cT14OuemZCqzuVm3xXXG5PpPM+t0PbYxo=", 'keccak256 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('Keccak256', "A","A","A"), "IHBQQAOge0cT14OuemZCqzuVm3xXXG5PpPM-t0PbYxo", 'keccak256 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::Keccak256->new->add("A","A","A")->hexdigest, "2070504003a07b4713d783ae7a6642ab3b959b7c575c6e4fa4f33eb743db631a", 'keccak256 (OO/tripple_A)'); +is( Crypt::Digest::Keccak256->new->add("A")->add("A")->add("A")->hexdigest, "2070504003a07b4713d783ae7a6642ab3b959b7c575c6e4fa4f33eb743db631a", 'keccak256 (OO3/tripple_A)'); + + +is( keccak256(""), pack("H*","c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"), 'keccak256 (raw/1)'); +is( keccak256_hex(""), "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", 'keccak256 (hex/1)'); +is( keccak256_b64(""), "xdJGAYb3IzySfn2y3McDwOUAtlPKgic7e/rYBF2FpHA=", 'keccak256 (base64/1)'); +is( digest_data('Keccak256', ""), pack("H*","c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"), 'keccak256 (digest_data_raw/1)'); +is( digest_data_hex('Keccak256', ""), "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", 'keccak256 (digest_data_hex/1)'); +is( digest_data_b64('Keccak256', ""), "xdJGAYb3IzySfn2y3McDwOUAtlPKgic7e/rYBF2FpHA=", 'keccak256 (digest_data_b64/1)'); +is( digest_data_b64u('Keccak256', ""), "xdJGAYb3IzySfn2y3McDwOUAtlPKgic7e_rYBF2FpHA", 'keccak256 (digest_data_b64u/1)'); +is( Crypt::Digest::Keccak256->new->add("")->hexdigest, "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", 'keccak256 (OO/1)'); + +is( keccak256("123"), pack("H*","64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107"), 'keccak256 (raw/2)'); +is( keccak256_hex("123"), "64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107", 'keccak256 (hex/2)'); +is( keccak256_b64("123"), "ZOYEeHy/GUhB57aNfNKHhvbJoKOrn4sKDofLQ4erAQc=", 'keccak256 (base64/2)'); +is( digest_data('Keccak256', "123"), pack("H*","64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107"), 'keccak256 (digest_data_raw/2)'); +is( digest_data_hex('Keccak256', "123"), "64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107", 'keccak256 (digest_data_hex/2)'); +is( digest_data_b64('Keccak256', "123"), "ZOYEeHy/GUhB57aNfNKHhvbJoKOrn4sKDofLQ4erAQc=", 'keccak256 (digest_data_b64/2)'); +is( digest_data_b64u('Keccak256', "123"), "ZOYEeHy_GUhB57aNfNKHhvbJoKOrn4sKDofLQ4erAQc", 'keccak256 (digest_data_b64u/2)'); +is( Crypt::Digest::Keccak256->new->add("123")->hexdigest, "64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107", 'keccak256 (OO/2)'); + +is( keccak256("test\0test\0test\n"), pack("H*","fbc121310d505fb7172a28e0e9e8c7d2976c9f63a739fe60bc298467bc72bb86"), 'keccak256 (raw/3)'); +is( keccak256_hex("test\0test\0test\n"), "fbc121310d505fb7172a28e0e9e8c7d2976c9f63a739fe60bc298467bc72bb86", 'keccak256 (hex/3)'); +is( keccak256_b64("test\0test\0test\n"), "+8EhMQ1QX7cXKijg6ejH0pdsn2OnOf5gvCmEZ7xyu4Y=", 'keccak256 (base64/3)'); +is( digest_data('Keccak256', "test\0test\0test\n"), pack("H*","fbc121310d505fb7172a28e0e9e8c7d2976c9f63a739fe60bc298467bc72bb86"), 'keccak256 (digest_data_raw/3)'); +is( digest_data_hex('Keccak256', "test\0test\0test\n"), "fbc121310d505fb7172a28e0e9e8c7d2976c9f63a739fe60bc298467bc72bb86", 'keccak256 (digest_data_hex/3)'); +is( digest_data_b64('Keccak256', "test\0test\0test\n"), "+8EhMQ1QX7cXKijg6ejH0pdsn2OnOf5gvCmEZ7xyu4Y=", 'keccak256 (digest_data_b64/3)'); +is( digest_data_b64u('Keccak256', "test\0test\0test\n"), "-8EhMQ1QX7cXKijg6ejH0pdsn2OnOf5gvCmEZ7xyu4Y", 'keccak256 (digest_data_b64u/3)'); +is( Crypt::Digest::Keccak256->new->add("test\0test\0test\n")->hexdigest, "fbc121310d505fb7172a28e0e9e8c7d2976c9f63a739fe60bc298467bc72bb86", 'keccak256 (OO/3)'); + + +is( keccak256_file('t/data/binary-test.file'), pack("H*","7046f5fad76cf793a1f44c159b656277ada3f428057ac8160d04fdcdc5b0fcb8"), 'keccak256 (raw/file/1)'); +is( keccak256_file_hex('t/data/binary-test.file'), "7046f5fad76cf793a1f44c159b656277ada3f428057ac8160d04fdcdc5b0fcb8", 'keccak256 (hex/file/1)'); +is( keccak256_file_b64('t/data/binary-test.file'), "cEb1+tds95Oh9EwVm2Vid62j9CgFesgWDQT9zcWw/Lg=", 'keccak256 (base64/file/1)'); +is( digest_file('Keccak256', 't/data/binary-test.file'), pack("H*","7046f5fad76cf793a1f44c159b656277ada3f428057ac8160d04fdcdc5b0fcb8"), 'keccak256 (digest_file_raw/file/1)'); +is( digest_file_hex('Keccak256', 't/data/binary-test.file'), "7046f5fad76cf793a1f44c159b656277ada3f428057ac8160d04fdcdc5b0fcb8", 'keccak256 (digest_file_hex/file/1)'); +is( digest_file_b64('Keccak256', 't/data/binary-test.file'), "cEb1+tds95Oh9EwVm2Vid62j9CgFesgWDQT9zcWw/Lg=", 'keccak256 (digest_file_b64/file/1)'); +is( digest_file_b64u('Keccak256', 't/data/binary-test.file'), "cEb1-tds95Oh9EwVm2Vid62j9CgFesgWDQT9zcWw_Lg", 'keccak256 (digest_file_b64u/file/1)'); +is( Crypt::Digest::Keccak256->new->addfile('t/data/binary-test.file')->hexdigest, "7046f5fad76cf793a1f44c159b656277ada3f428057ac8160d04fdcdc5b0fcb8", 'keccak256 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::Keccak256->new->addfile($fh)->hexdigest, "7046f5fad76cf793a1f44c159b656277ada3f428057ac8160d04fdcdc5b0fcb8", 'keccak256 (OO/filehandle/1)'); + close($fh); +} + +is( keccak256_file('t/data/text-CR.file'), pack("H*","288d47897222a6fbd6d8593cd06796e6c3eb5637a6eaf8fc033dc9243ce01c18"), 'keccak256 (raw/file/2)'); +is( keccak256_file_hex('t/data/text-CR.file'), "288d47897222a6fbd6d8593cd06796e6c3eb5637a6eaf8fc033dc9243ce01c18", 'keccak256 (hex/file/2)'); +is( keccak256_file_b64('t/data/text-CR.file'), "KI1HiXIipvvW2Fk80GeW5sPrVjem6vj8Az3JJDzgHBg=", 'keccak256 (base64/file/2)'); +is( digest_file('Keccak256', 't/data/text-CR.file'), pack("H*","288d47897222a6fbd6d8593cd06796e6c3eb5637a6eaf8fc033dc9243ce01c18"), 'keccak256 (digest_file_raw/file/2)'); +is( digest_file_hex('Keccak256', 't/data/text-CR.file'), "288d47897222a6fbd6d8593cd06796e6c3eb5637a6eaf8fc033dc9243ce01c18", 'keccak256 (digest_file_hex/file/2)'); +is( digest_file_b64('Keccak256', 't/data/text-CR.file'), "KI1HiXIipvvW2Fk80GeW5sPrVjem6vj8Az3JJDzgHBg=", 'keccak256 (digest_file_b64/file/2)'); +is( digest_file_b64u('Keccak256', 't/data/text-CR.file'), "KI1HiXIipvvW2Fk80GeW5sPrVjem6vj8Az3JJDzgHBg", 'keccak256 (digest_file_b64u/file/2)'); +is( Crypt::Digest::Keccak256->new->addfile('t/data/text-CR.file')->hexdigest, "288d47897222a6fbd6d8593cd06796e6c3eb5637a6eaf8fc033dc9243ce01c18", 'keccak256 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::Keccak256->new->addfile($fh)->hexdigest, "288d47897222a6fbd6d8593cd06796e6c3eb5637a6eaf8fc033dc9243ce01c18", 'keccak256 (OO/filehandle/2)'); + close($fh); +} + +is( keccak256_file('t/data/text-CRLF.file'), pack("H*","a44703b85d5ee7f35b3c0c21c646d695978d0ec5ea36a1a05a77427c5f964ee1"), 'keccak256 (raw/file/3)'); +is( keccak256_file_hex('t/data/text-CRLF.file'), "a44703b85d5ee7f35b3c0c21c646d695978d0ec5ea36a1a05a77427c5f964ee1", 'keccak256 (hex/file/3)'); +is( keccak256_file_b64('t/data/text-CRLF.file'), "pEcDuF1e5/NbPAwhxkbWlZeNDsXqNqGgWndCfF+WTuE=", 'keccak256 (base64/file/3)'); +is( digest_file('Keccak256', 't/data/text-CRLF.file'), pack("H*","a44703b85d5ee7f35b3c0c21c646d695978d0ec5ea36a1a05a77427c5f964ee1"), 'keccak256 (digest_file_raw/file/3)'); +is( digest_file_hex('Keccak256', 't/data/text-CRLF.file'), "a44703b85d5ee7f35b3c0c21c646d695978d0ec5ea36a1a05a77427c5f964ee1", 'keccak256 (digest_file_hex/file/3)'); +is( digest_file_b64('Keccak256', 't/data/text-CRLF.file'), "pEcDuF1e5/NbPAwhxkbWlZeNDsXqNqGgWndCfF+WTuE=", 'keccak256 (digest_file_b64/file/3)'); +is( digest_file_b64u('Keccak256', 't/data/text-CRLF.file'), "pEcDuF1e5_NbPAwhxkbWlZeNDsXqNqGgWndCfF-WTuE", 'keccak256 (digest_file_b64u/file/3)'); +is( Crypt::Digest::Keccak256->new->addfile('t/data/text-CRLF.file')->hexdigest, "a44703b85d5ee7f35b3c0c21c646d695978d0ec5ea36a1a05a77427c5f964ee1", 'keccak256 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::Keccak256->new->addfile($fh)->hexdigest, "a44703b85d5ee7f35b3c0c21c646d695978d0ec5ea36a1a05a77427c5f964ee1", 'keccak256 (OO/filehandle/3)'); + close($fh); +} + +is( keccak256_file('t/data/text-LF.file'), pack("H*","188476c71de2afcb7eda9dbc560b5eb5e4e681a558568a41068eb6d738efa4f4"), 'keccak256 (raw/file/4)'); +is( keccak256_file_hex('t/data/text-LF.file'), "188476c71de2afcb7eda9dbc560b5eb5e4e681a558568a41068eb6d738efa4f4", 'keccak256 (hex/file/4)'); +is( keccak256_file_b64('t/data/text-LF.file'), "GIR2xx3ir8t+2p28VgteteTmgaVYVopBBo621zjvpPQ=", 'keccak256 (base64/file/4)'); +is( digest_file('Keccak256', 't/data/text-LF.file'), pack("H*","188476c71de2afcb7eda9dbc560b5eb5e4e681a558568a41068eb6d738efa4f4"), 'keccak256 (digest_file_raw/file/4)'); +is( digest_file_hex('Keccak256', 't/data/text-LF.file'), "188476c71de2afcb7eda9dbc560b5eb5e4e681a558568a41068eb6d738efa4f4", 'keccak256 (digest_file_hex/file/4)'); +is( digest_file_b64('Keccak256', 't/data/text-LF.file'), "GIR2xx3ir8t+2p28VgteteTmgaVYVopBBo621zjvpPQ=", 'keccak256 (digest_file_b64/file/4)'); +is( digest_file_b64u('Keccak256', 't/data/text-LF.file'), "GIR2xx3ir8t-2p28VgteteTmgaVYVopBBo621zjvpPQ", 'keccak256 (digest_file_b64u/file/4)'); +is( Crypt::Digest::Keccak256->new->addfile('t/data/text-LF.file')->hexdigest, "188476c71de2afcb7eda9dbc560b5eb5e4e681a558568a41068eb6d738efa4f4", 'keccak256 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::Keccak256->new->addfile($fh)->hexdigest, "188476c71de2afcb7eda9dbc560b5eb5e4e681a558568a41068eb6d738efa4f4", 'keccak256 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_keccak384.t b/t/digest_keccak384.t new file mode 100644 index 00000000..935816dd --- /dev/null +++ b/t/digest_keccak384.t @@ -0,0 +1,116 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 10 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::Keccak384 qw( keccak384 keccak384_hex keccak384_b64 keccak384_b64u keccak384_file keccak384_file_hex keccak384_file_b64 keccak384_file_b64u ); + +is( Crypt::Digest::hashsize('Keccak384'), 48, 'hashsize/1'); +is( Crypt::Digest->hashsize('Keccak384'), 48, 'hashsize/2'); +is( Crypt::Digest::Keccak384::hashsize, 48, 'hashsize/3'); +is( Crypt::Digest::Keccak384->hashsize, 48, 'hashsize/4'); +is( Crypt::Digest->new('Keccak384')->hashsize, 48, 'hashsize/5'); +is( Crypt::Digest::Keccak384->new->hashsize, 48, 'hashsize/6'); + +is( keccak384("A","A","A"), pack("H*","173b545e0fd81784f8c024ca803641936082eef9a5ace73faf73ad68ecde6029cc345a5c549384e0d7627dcbf58d0297"), 'keccak384 (raw/tripple_A)'); +is( keccak384_hex("A","A","A"), "173b545e0fd81784f8c024ca803641936082eef9a5ace73faf73ad68ecde6029cc345a5c549384e0d7627dcbf58d0297", 'keccak384 (hex/tripple_A)'); +is( keccak384_b64("A","A","A"), "FztUXg/YF4T4wCTKgDZBk2CC7vmlrOc/r3OtaOzeYCnMNFpcVJOE4Ndifcv1jQKX", 'keccak384 (base64/tripple_A)'); +is( keccak384_b64u("A","A","A"), "FztUXg_YF4T4wCTKgDZBk2CC7vmlrOc_r3OtaOzeYCnMNFpcVJOE4Ndifcv1jQKX", 'keccak384 (base64url/tripple_A)'); +is( digest_data('Keccak384', "A","A","A"), pack("H*","173b545e0fd81784f8c024ca803641936082eef9a5ace73faf73ad68ecde6029cc345a5c549384e0d7627dcbf58d0297"), 'keccak384 (digest_data_raw/tripple_A)'); +is( digest_data_hex('Keccak384', "A","A","A"), "173b545e0fd81784f8c024ca803641936082eef9a5ace73faf73ad68ecde6029cc345a5c549384e0d7627dcbf58d0297", 'keccak384 (digest_data_hex/tripple_A)'); +is( digest_data_b64('Keccak384', "A","A","A"), "FztUXg/YF4T4wCTKgDZBk2CC7vmlrOc/r3OtaOzeYCnMNFpcVJOE4Ndifcv1jQKX", 'keccak384 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('Keccak384', "A","A","A"), "FztUXg_YF4T4wCTKgDZBk2CC7vmlrOc_r3OtaOzeYCnMNFpcVJOE4Ndifcv1jQKX", 'keccak384 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::Keccak384->new->add("A","A","A")->hexdigest, "173b545e0fd81784f8c024ca803641936082eef9a5ace73faf73ad68ecde6029cc345a5c549384e0d7627dcbf58d0297", 'keccak384 (OO/tripple_A)'); +is( Crypt::Digest::Keccak384->new->add("A")->add("A")->add("A")->hexdigest, "173b545e0fd81784f8c024ca803641936082eef9a5ace73faf73ad68ecde6029cc345a5c549384e0d7627dcbf58d0297", 'keccak384 (OO3/tripple_A)'); + + +is( keccak384(""), pack("H*","2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff"), 'keccak384 (raw/1)'); +is( keccak384_hex(""), "2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff", 'keccak384 (hex/1)'); +is( keccak384_b64(""), "LCMUamOims+Z5zuI+MJOqn3GCqdxeAzMAGr7+o/iR5st0rITYjN0QawStRWRGVf/", 'keccak384 (base64/1)'); +is( digest_data('Keccak384', ""), pack("H*","2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff"), 'keccak384 (digest_data_raw/1)'); +is( digest_data_hex('Keccak384', ""), "2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff", 'keccak384 (digest_data_hex/1)'); +is( digest_data_b64('Keccak384', ""), "LCMUamOims+Z5zuI+MJOqn3GCqdxeAzMAGr7+o/iR5st0rITYjN0QawStRWRGVf/", 'keccak384 (digest_data_b64/1)'); +is( digest_data_b64u('Keccak384', ""), "LCMUamOims-Z5zuI-MJOqn3GCqdxeAzMAGr7-o_iR5st0rITYjN0QawStRWRGVf_", 'keccak384 (digest_data_b64u/1)'); +is( Crypt::Digest::Keccak384->new->add("")->hexdigest, "2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff", 'keccak384 (OO/1)'); + +is( keccak384("123"), pack("H*","7dd34ccaae92bfc7eb541056d200db23b6bbeefe95be0d2bb43625113361906f0afc701dbef1cfb615bf98b1535a84c1"), 'keccak384 (raw/2)'); +is( keccak384_hex("123"), "7dd34ccaae92bfc7eb541056d200db23b6bbeefe95be0d2bb43625113361906f0afc701dbef1cfb615bf98b1535a84c1", 'keccak384 (hex/2)'); +is( keccak384_b64("123"), "fdNMyq6Sv8frVBBW0gDbI7a77v6Vvg0rtDYlETNhkG8K/HAdvvHPthW/mLFTWoTB", 'keccak384 (base64/2)'); +is( digest_data('Keccak384', "123"), pack("H*","7dd34ccaae92bfc7eb541056d200db23b6bbeefe95be0d2bb43625113361906f0afc701dbef1cfb615bf98b1535a84c1"), 'keccak384 (digest_data_raw/2)'); +is( digest_data_hex('Keccak384', "123"), "7dd34ccaae92bfc7eb541056d200db23b6bbeefe95be0d2bb43625113361906f0afc701dbef1cfb615bf98b1535a84c1", 'keccak384 (digest_data_hex/2)'); +is( digest_data_b64('Keccak384', "123"), "fdNMyq6Sv8frVBBW0gDbI7a77v6Vvg0rtDYlETNhkG8K/HAdvvHPthW/mLFTWoTB", 'keccak384 (digest_data_b64/2)'); +is( digest_data_b64u('Keccak384', "123"), "fdNMyq6Sv8frVBBW0gDbI7a77v6Vvg0rtDYlETNhkG8K_HAdvvHPthW_mLFTWoTB", 'keccak384 (digest_data_b64u/2)'); +is( Crypt::Digest::Keccak384->new->add("123")->hexdigest, "7dd34ccaae92bfc7eb541056d200db23b6bbeefe95be0d2bb43625113361906f0afc701dbef1cfb615bf98b1535a84c1", 'keccak384 (OO/2)'); + +is( keccak384("test\0test\0test\n"), pack("H*","d05c31062f5401c5d370cf84949937c52764626a61d2bbd5bf5c50f6f742ebcf9269691a3c70ef83dc49f4e186e5d908"), 'keccak384 (raw/3)'); +is( keccak384_hex("test\0test\0test\n"), "d05c31062f5401c5d370cf84949937c52764626a61d2bbd5bf5c50f6f742ebcf9269691a3c70ef83dc49f4e186e5d908", 'keccak384 (hex/3)'); +is( keccak384_b64("test\0test\0test\n"), "0FwxBi9UAcXTcM+ElJk3xSdkYmph0rvVv1xQ9vdC68+SaWkaPHDvg9xJ9OGG5dkI", 'keccak384 (base64/3)'); +is( digest_data('Keccak384', "test\0test\0test\n"), pack("H*","d05c31062f5401c5d370cf84949937c52764626a61d2bbd5bf5c50f6f742ebcf9269691a3c70ef83dc49f4e186e5d908"), 'keccak384 (digest_data_raw/3)'); +is( digest_data_hex('Keccak384', "test\0test\0test\n"), "d05c31062f5401c5d370cf84949937c52764626a61d2bbd5bf5c50f6f742ebcf9269691a3c70ef83dc49f4e186e5d908", 'keccak384 (digest_data_hex/3)'); +is( digest_data_b64('Keccak384', "test\0test\0test\n"), "0FwxBi9UAcXTcM+ElJk3xSdkYmph0rvVv1xQ9vdC68+SaWkaPHDvg9xJ9OGG5dkI", 'keccak384 (digest_data_b64/3)'); +is( digest_data_b64u('Keccak384', "test\0test\0test\n"), "0FwxBi9UAcXTcM-ElJk3xSdkYmph0rvVv1xQ9vdC68-SaWkaPHDvg9xJ9OGG5dkI", 'keccak384 (digest_data_b64u/3)'); +is( Crypt::Digest::Keccak384->new->add("test\0test\0test\n")->hexdigest, "d05c31062f5401c5d370cf84949937c52764626a61d2bbd5bf5c50f6f742ebcf9269691a3c70ef83dc49f4e186e5d908", 'keccak384 (OO/3)'); + + +is( keccak384_file('t/data/binary-test.file'), pack("H*","16a5a7d82de1eec1cbbb51c403dd0fc02560ddf488c1b8c69b9b4cf1585e751424dfcc06cf0baf2ff73d931c6f7240bc"), 'keccak384 (raw/file/1)'); +is( keccak384_file_hex('t/data/binary-test.file'), "16a5a7d82de1eec1cbbb51c403dd0fc02560ddf488c1b8c69b9b4cf1585e751424dfcc06cf0baf2ff73d931c6f7240bc", 'keccak384 (hex/file/1)'); +is( keccak384_file_b64('t/data/binary-test.file'), "FqWn2C3h7sHLu1HEA90PwCVg3fSIwbjGm5tM8VhedRQk38wGzwuvL/c9kxxvckC8", 'keccak384 (base64/file/1)'); +is( digest_file('Keccak384', 't/data/binary-test.file'), pack("H*","16a5a7d82de1eec1cbbb51c403dd0fc02560ddf488c1b8c69b9b4cf1585e751424dfcc06cf0baf2ff73d931c6f7240bc"), 'keccak384 (digest_file_raw/file/1)'); +is( digest_file_hex('Keccak384', 't/data/binary-test.file'), "16a5a7d82de1eec1cbbb51c403dd0fc02560ddf488c1b8c69b9b4cf1585e751424dfcc06cf0baf2ff73d931c6f7240bc", 'keccak384 (digest_file_hex/file/1)'); +is( digest_file_b64('Keccak384', 't/data/binary-test.file'), "FqWn2C3h7sHLu1HEA90PwCVg3fSIwbjGm5tM8VhedRQk38wGzwuvL/c9kxxvckC8", 'keccak384 (digest_file_b64/file/1)'); +is( digest_file_b64u('Keccak384', 't/data/binary-test.file'), "FqWn2C3h7sHLu1HEA90PwCVg3fSIwbjGm5tM8VhedRQk38wGzwuvL_c9kxxvckC8", 'keccak384 (digest_file_b64u/file/1)'); +is( Crypt::Digest::Keccak384->new->addfile('t/data/binary-test.file')->hexdigest, "16a5a7d82de1eec1cbbb51c403dd0fc02560ddf488c1b8c69b9b4cf1585e751424dfcc06cf0baf2ff73d931c6f7240bc", 'keccak384 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::Keccak384->new->addfile($fh)->hexdigest, "16a5a7d82de1eec1cbbb51c403dd0fc02560ddf488c1b8c69b9b4cf1585e751424dfcc06cf0baf2ff73d931c6f7240bc", 'keccak384 (OO/filehandle/1)'); + close($fh); +} + +is( keccak384_file('t/data/text-CR.file'), pack("H*","d42a0bfb2a95bbfeba375b146ebe37ef9972d25809b93a18fd1754fb86ad9139ac2ca71e5cd1713024ecda06263a39cc"), 'keccak384 (raw/file/2)'); +is( keccak384_file_hex('t/data/text-CR.file'), "d42a0bfb2a95bbfeba375b146ebe37ef9972d25809b93a18fd1754fb86ad9139ac2ca71e5cd1713024ecda06263a39cc", 'keccak384 (hex/file/2)'); +is( keccak384_file_b64('t/data/text-CR.file'), "1CoL+yqVu/66N1sUbr4375ly0lgJuToY/RdU+4atkTmsLKceXNFxMCTs2gYmOjnM", 'keccak384 (base64/file/2)'); +is( digest_file('Keccak384', 't/data/text-CR.file'), pack("H*","d42a0bfb2a95bbfeba375b146ebe37ef9972d25809b93a18fd1754fb86ad9139ac2ca71e5cd1713024ecda06263a39cc"), 'keccak384 (digest_file_raw/file/2)'); +is( digest_file_hex('Keccak384', 't/data/text-CR.file'), "d42a0bfb2a95bbfeba375b146ebe37ef9972d25809b93a18fd1754fb86ad9139ac2ca71e5cd1713024ecda06263a39cc", 'keccak384 (digest_file_hex/file/2)'); +is( digest_file_b64('Keccak384', 't/data/text-CR.file'), "1CoL+yqVu/66N1sUbr4375ly0lgJuToY/RdU+4atkTmsLKceXNFxMCTs2gYmOjnM", 'keccak384 (digest_file_b64/file/2)'); +is( digest_file_b64u('Keccak384', 't/data/text-CR.file'), "1CoL-yqVu_66N1sUbr4375ly0lgJuToY_RdU-4atkTmsLKceXNFxMCTs2gYmOjnM", 'keccak384 (digest_file_b64u/file/2)'); +is( Crypt::Digest::Keccak384->new->addfile('t/data/text-CR.file')->hexdigest, "d42a0bfb2a95bbfeba375b146ebe37ef9972d25809b93a18fd1754fb86ad9139ac2ca71e5cd1713024ecda06263a39cc", 'keccak384 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::Keccak384->new->addfile($fh)->hexdigest, "d42a0bfb2a95bbfeba375b146ebe37ef9972d25809b93a18fd1754fb86ad9139ac2ca71e5cd1713024ecda06263a39cc", 'keccak384 (OO/filehandle/2)'); + close($fh); +} + +is( keccak384_file('t/data/text-CRLF.file'), pack("H*","06288b3506e5080aebbcdfaaba5985ac89e3e4227fd32b8a532640064c98bfea991a5e88cc00b307fd0dd2d1c87a3982"), 'keccak384 (raw/file/3)'); +is( keccak384_file_hex('t/data/text-CRLF.file'), "06288b3506e5080aebbcdfaaba5985ac89e3e4227fd32b8a532640064c98bfea991a5e88cc00b307fd0dd2d1c87a3982", 'keccak384 (hex/file/3)'); +is( keccak384_file_b64('t/data/text-CRLF.file'), "BiiLNQblCArrvN+qulmFrInj5CJ/0yuKUyZABkyYv+qZGl6IzACzB/0N0tHIejmC", 'keccak384 (base64/file/3)'); +is( digest_file('Keccak384', 't/data/text-CRLF.file'), pack("H*","06288b3506e5080aebbcdfaaba5985ac89e3e4227fd32b8a532640064c98bfea991a5e88cc00b307fd0dd2d1c87a3982"), 'keccak384 (digest_file_raw/file/3)'); +is( digest_file_hex('Keccak384', 't/data/text-CRLF.file'), "06288b3506e5080aebbcdfaaba5985ac89e3e4227fd32b8a532640064c98bfea991a5e88cc00b307fd0dd2d1c87a3982", 'keccak384 (digest_file_hex/file/3)'); +is( digest_file_b64('Keccak384', 't/data/text-CRLF.file'), "BiiLNQblCArrvN+qulmFrInj5CJ/0yuKUyZABkyYv+qZGl6IzACzB/0N0tHIejmC", 'keccak384 (digest_file_b64/file/3)'); +is( digest_file_b64u('Keccak384', 't/data/text-CRLF.file'), "BiiLNQblCArrvN-qulmFrInj5CJ_0yuKUyZABkyYv-qZGl6IzACzB_0N0tHIejmC", 'keccak384 (digest_file_b64u/file/3)'); +is( Crypt::Digest::Keccak384->new->addfile('t/data/text-CRLF.file')->hexdigest, "06288b3506e5080aebbcdfaaba5985ac89e3e4227fd32b8a532640064c98bfea991a5e88cc00b307fd0dd2d1c87a3982", 'keccak384 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::Keccak384->new->addfile($fh)->hexdigest, "06288b3506e5080aebbcdfaaba5985ac89e3e4227fd32b8a532640064c98bfea991a5e88cc00b307fd0dd2d1c87a3982", 'keccak384 (OO/filehandle/3)'); + close($fh); +} + +is( keccak384_file('t/data/text-LF.file'), pack("H*","14b54d1188154f7017ff7b33e21e42ef93c91d79ea6b44a223002adc6d89b875d3bcb25c189aea827560540afbe5cf71"), 'keccak384 (raw/file/4)'); +is( keccak384_file_hex('t/data/text-LF.file'), "14b54d1188154f7017ff7b33e21e42ef93c91d79ea6b44a223002adc6d89b875d3bcb25c189aea827560540afbe5cf71", 'keccak384 (hex/file/4)'); +is( keccak384_file_b64('t/data/text-LF.file'), "FLVNEYgVT3AX/3sz4h5C75PJHXnqa0SiIwAq3G2JuHXTvLJcGJrqgnVgVAr75c9x", 'keccak384 (base64/file/4)'); +is( digest_file('Keccak384', 't/data/text-LF.file'), pack("H*","14b54d1188154f7017ff7b33e21e42ef93c91d79ea6b44a223002adc6d89b875d3bcb25c189aea827560540afbe5cf71"), 'keccak384 (digest_file_raw/file/4)'); +is( digest_file_hex('Keccak384', 't/data/text-LF.file'), "14b54d1188154f7017ff7b33e21e42ef93c91d79ea6b44a223002adc6d89b875d3bcb25c189aea827560540afbe5cf71", 'keccak384 (digest_file_hex/file/4)'); +is( digest_file_b64('Keccak384', 't/data/text-LF.file'), "FLVNEYgVT3AX/3sz4h5C75PJHXnqa0SiIwAq3G2JuHXTvLJcGJrqgnVgVAr75c9x", 'keccak384 (digest_file_b64/file/4)'); +is( digest_file_b64u('Keccak384', 't/data/text-LF.file'), "FLVNEYgVT3AX_3sz4h5C75PJHXnqa0SiIwAq3G2JuHXTvLJcGJrqgnVgVAr75c9x", 'keccak384 (digest_file_b64u/file/4)'); +is( Crypt::Digest::Keccak384->new->addfile('t/data/text-LF.file')->hexdigest, "14b54d1188154f7017ff7b33e21e42ef93c91d79ea6b44a223002adc6d89b875d3bcb25c189aea827560540afbe5cf71", 'keccak384 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::Keccak384->new->addfile($fh)->hexdigest, "14b54d1188154f7017ff7b33e21e42ef93c91d79ea6b44a223002adc6d89b875d3bcb25c189aea827560540afbe5cf71", 'keccak384 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_keccak512.t b/t/digest_keccak512.t new file mode 100644 index 00000000..1c8618d9 --- /dev/null +++ b/t/digest_keccak512.t @@ -0,0 +1,116 @@ +### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY! + +use strict; +use warnings; + +use Test::More tests => 8*3 + 9*4 + 10 + 6; + +use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); +use Crypt::Digest::Keccak512 qw( keccak512 keccak512_hex keccak512_b64 keccak512_b64u keccak512_file keccak512_file_hex keccak512_file_b64 keccak512_file_b64u ); + +is( Crypt::Digest::hashsize('Keccak512'), 64, 'hashsize/1'); +is( Crypt::Digest->hashsize('Keccak512'), 64, 'hashsize/2'); +is( Crypt::Digest::Keccak512::hashsize, 64, 'hashsize/3'); +is( Crypt::Digest::Keccak512->hashsize, 64, 'hashsize/4'); +is( Crypt::Digest->new('Keccak512')->hashsize, 64, 'hashsize/5'); +is( Crypt::Digest::Keccak512->new->hashsize, 64, 'hashsize/6'); + +is( keccak512("A","A","A"), pack("H*","a0243a891584f48aeb59677458705d209c0defd977655cb8a6c78298ac9d5981571659e1d35024285d718dd1f603876ad785f59ea814b91ee61a4433856c6391"), 'keccak512 (raw/tripple_A)'); +is( keccak512_hex("A","A","A"), "a0243a891584f48aeb59677458705d209c0defd977655cb8a6c78298ac9d5981571659e1d35024285d718dd1f603876ad785f59ea814b91ee61a4433856c6391", 'keccak512 (hex/tripple_A)'); +is( keccak512_b64("A","A","A"), "oCQ6iRWE9IrrWWd0WHBdIJwN79l3ZVy4pseCmKydWYFXFlnh01AkKF1xjdH2A4dq14X1nqgUuR7mGkQzhWxjkQ==", 'keccak512 (base64/tripple_A)'); +is( keccak512_b64u("A","A","A"), "oCQ6iRWE9IrrWWd0WHBdIJwN79l3ZVy4pseCmKydWYFXFlnh01AkKF1xjdH2A4dq14X1nqgUuR7mGkQzhWxjkQ", 'keccak512 (base64url/tripple_A)'); +is( digest_data('Keccak512', "A","A","A"), pack("H*","a0243a891584f48aeb59677458705d209c0defd977655cb8a6c78298ac9d5981571659e1d35024285d718dd1f603876ad785f59ea814b91ee61a4433856c6391"), 'keccak512 (digest_data_raw/tripple_A)'); +is( digest_data_hex('Keccak512', "A","A","A"), "a0243a891584f48aeb59677458705d209c0defd977655cb8a6c78298ac9d5981571659e1d35024285d718dd1f603876ad785f59ea814b91ee61a4433856c6391", 'keccak512 (digest_data_hex/tripple_A)'); +is( digest_data_b64('Keccak512', "A","A","A"), "oCQ6iRWE9IrrWWd0WHBdIJwN79l3ZVy4pseCmKydWYFXFlnh01AkKF1xjdH2A4dq14X1nqgUuR7mGkQzhWxjkQ==", 'keccak512 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('Keccak512', "A","A","A"), "oCQ6iRWE9IrrWWd0WHBdIJwN79l3ZVy4pseCmKydWYFXFlnh01AkKF1xjdH2A4dq14X1nqgUuR7mGkQzhWxjkQ", 'keccak512 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::Keccak512->new->add("A","A","A")->hexdigest, "a0243a891584f48aeb59677458705d209c0defd977655cb8a6c78298ac9d5981571659e1d35024285d718dd1f603876ad785f59ea814b91ee61a4433856c6391", 'keccak512 (OO/tripple_A)'); +is( Crypt::Digest::Keccak512->new->add("A")->add("A")->add("A")->hexdigest, "a0243a891584f48aeb59677458705d209c0defd977655cb8a6c78298ac9d5981571659e1d35024285d718dd1f603876ad785f59ea814b91ee61a4433856c6391", 'keccak512 (OO3/tripple_A)'); + + +is( keccak512(""), pack("H*","0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e"), 'keccak512 (raw/1)'); +is( keccak512_hex(""), "0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e", 'keccak512 (hex/1)'); +is( keccak512_b64(""), "DqtC3kw865I1/JGs/+dGspwpqMNmt8YOTmfEZvNqQwTAD6nK+dh5drpGm8vgZxO0NfCR7ydp+xYM2rM9NnBoDg==", 'keccak512 (base64/1)'); +is( digest_data('Keccak512', ""), pack("H*","0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e"), 'keccak512 (digest_data_raw/1)'); +is( digest_data_hex('Keccak512', ""), "0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e", 'keccak512 (digest_data_hex/1)'); +is( digest_data_b64('Keccak512', ""), "DqtC3kw865I1/JGs/+dGspwpqMNmt8YOTmfEZvNqQwTAD6nK+dh5drpGm8vgZxO0NfCR7ydp+xYM2rM9NnBoDg==", 'keccak512 (digest_data_b64/1)'); +is( digest_data_b64u('Keccak512', ""), "DqtC3kw865I1_JGs_-dGspwpqMNmt8YOTmfEZvNqQwTAD6nK-dh5drpGm8vgZxO0NfCR7ydp-xYM2rM9NnBoDg", 'keccak512 (digest_data_b64u/1)'); +is( Crypt::Digest::Keccak512->new->add("")->hexdigest, "0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e", 'keccak512 (OO/1)'); + +is( keccak512("123"), pack("H*","8ca32d950873fd2b5b34a7d79c4a294b2fd805abe3261beb04fab61a3b4b75609afd6478aa8d34e03f262d68bb09a2ba9d655e228c96723b2854838a6e613b9d"), 'keccak512 (raw/2)'); +is( keccak512_hex("123"), "8ca32d950873fd2b5b34a7d79c4a294b2fd805abe3261beb04fab61a3b4b75609afd6478aa8d34e03f262d68bb09a2ba9d655e228c96723b2854838a6e613b9d", 'keccak512 (hex/2)'); +is( keccak512_b64("123"), "jKMtlQhz/StbNKfXnEopSy/YBavjJhvrBPq2GjtLdWCa/WR4qo004D8mLWi7CaK6nWVeIoyWcjsoVIOKbmE7nQ==", 'keccak512 (base64/2)'); +is( digest_data('Keccak512', "123"), pack("H*","8ca32d950873fd2b5b34a7d79c4a294b2fd805abe3261beb04fab61a3b4b75609afd6478aa8d34e03f262d68bb09a2ba9d655e228c96723b2854838a6e613b9d"), 'keccak512 (digest_data_raw/2)'); +is( digest_data_hex('Keccak512', "123"), "8ca32d950873fd2b5b34a7d79c4a294b2fd805abe3261beb04fab61a3b4b75609afd6478aa8d34e03f262d68bb09a2ba9d655e228c96723b2854838a6e613b9d", 'keccak512 (digest_data_hex/2)'); +is( digest_data_b64('Keccak512', "123"), "jKMtlQhz/StbNKfXnEopSy/YBavjJhvrBPq2GjtLdWCa/WR4qo004D8mLWi7CaK6nWVeIoyWcjsoVIOKbmE7nQ==", 'keccak512 (digest_data_b64/2)'); +is( digest_data_b64u('Keccak512', "123"), "jKMtlQhz_StbNKfXnEopSy_YBavjJhvrBPq2GjtLdWCa_WR4qo004D8mLWi7CaK6nWVeIoyWcjsoVIOKbmE7nQ", 'keccak512 (digest_data_b64u/2)'); +is( Crypt::Digest::Keccak512->new->add("123")->hexdigest, "8ca32d950873fd2b5b34a7d79c4a294b2fd805abe3261beb04fab61a3b4b75609afd6478aa8d34e03f262d68bb09a2ba9d655e228c96723b2854838a6e613b9d", 'keccak512 (OO/2)'); + +is( keccak512("test\0test\0test\n"), pack("H*","32c764ac224dfa7a5c8205dada12006a56d15a6377b6fcd65b6e17be8759459ae847d9d7cadf335d4b477541db19883a4d4a7e2dae8f9f8504f4e36cc3417e00"), 'keccak512 (raw/3)'); +is( keccak512_hex("test\0test\0test\n"), "32c764ac224dfa7a5c8205dada12006a56d15a6377b6fcd65b6e17be8759459ae847d9d7cadf335d4b477541db19883a4d4a7e2dae8f9f8504f4e36cc3417e00", 'keccak512 (hex/3)'); +is( keccak512_b64("test\0test\0test\n"), "MsdkrCJN+npcggXa2hIAalbRWmN3tvzWW24XvodZRZroR9nXyt8zXUtHdUHbGYg6TUp+La6Pn4UE9ONsw0F+AA==", 'keccak512 (base64/3)'); +is( digest_data('Keccak512', "test\0test\0test\n"), pack("H*","32c764ac224dfa7a5c8205dada12006a56d15a6377b6fcd65b6e17be8759459ae847d9d7cadf335d4b477541db19883a4d4a7e2dae8f9f8504f4e36cc3417e00"), 'keccak512 (digest_data_raw/3)'); +is( digest_data_hex('Keccak512', "test\0test\0test\n"), "32c764ac224dfa7a5c8205dada12006a56d15a6377b6fcd65b6e17be8759459ae847d9d7cadf335d4b477541db19883a4d4a7e2dae8f9f8504f4e36cc3417e00", 'keccak512 (digest_data_hex/3)'); +is( digest_data_b64('Keccak512', "test\0test\0test\n"), "MsdkrCJN+npcggXa2hIAalbRWmN3tvzWW24XvodZRZroR9nXyt8zXUtHdUHbGYg6TUp+La6Pn4UE9ONsw0F+AA==", 'keccak512 (digest_data_b64/3)'); +is( digest_data_b64u('Keccak512', "test\0test\0test\n"), "MsdkrCJN-npcggXa2hIAalbRWmN3tvzWW24XvodZRZroR9nXyt8zXUtHdUHbGYg6TUp-La6Pn4UE9ONsw0F-AA", 'keccak512 (digest_data_b64u/3)'); +is( Crypt::Digest::Keccak512->new->add("test\0test\0test\n")->hexdigest, "32c764ac224dfa7a5c8205dada12006a56d15a6377b6fcd65b6e17be8759459ae847d9d7cadf335d4b477541db19883a4d4a7e2dae8f9f8504f4e36cc3417e00", 'keccak512 (OO/3)'); + + +is( keccak512_file('t/data/binary-test.file'), pack("H*","369b779f34f5eb28cbc04f5624e64897a63dc5e5652e9414fb24e252f91d4d64358d1d837c343c5f338f6afd888f0ccc4770ca6c34a81e0c0f28836b7e4047f8"), 'keccak512 (raw/file/1)'); +is( keccak512_file_hex('t/data/binary-test.file'), "369b779f34f5eb28cbc04f5624e64897a63dc5e5652e9414fb24e252f91d4d64358d1d837c343c5f338f6afd888f0ccc4770ca6c34a81e0c0f28836b7e4047f8", 'keccak512 (hex/file/1)'); +is( keccak512_file_b64('t/data/binary-test.file'), "Npt3nzT16yjLwE9WJOZIl6Y9xeVlLpQU+yTiUvkdTWQ1jR2DfDQ8XzOPav2IjwzMR3DKbDSoHgwPKINrfkBH+A==", 'keccak512 (base64/file/1)'); +is( digest_file('Keccak512', 't/data/binary-test.file'), pack("H*","369b779f34f5eb28cbc04f5624e64897a63dc5e5652e9414fb24e252f91d4d64358d1d837c343c5f338f6afd888f0ccc4770ca6c34a81e0c0f28836b7e4047f8"), 'keccak512 (digest_file_raw/file/1)'); +is( digest_file_hex('Keccak512', 't/data/binary-test.file'), "369b779f34f5eb28cbc04f5624e64897a63dc5e5652e9414fb24e252f91d4d64358d1d837c343c5f338f6afd888f0ccc4770ca6c34a81e0c0f28836b7e4047f8", 'keccak512 (digest_file_hex/file/1)'); +is( digest_file_b64('Keccak512', 't/data/binary-test.file'), "Npt3nzT16yjLwE9WJOZIl6Y9xeVlLpQU+yTiUvkdTWQ1jR2DfDQ8XzOPav2IjwzMR3DKbDSoHgwPKINrfkBH+A==", 'keccak512 (digest_file_b64/file/1)'); +is( digest_file_b64u('Keccak512', 't/data/binary-test.file'), "Npt3nzT16yjLwE9WJOZIl6Y9xeVlLpQU-yTiUvkdTWQ1jR2DfDQ8XzOPav2IjwzMR3DKbDSoHgwPKINrfkBH-A", 'keccak512 (digest_file_b64u/file/1)'); +is( Crypt::Digest::Keccak512->new->addfile('t/data/binary-test.file')->hexdigest, "369b779f34f5eb28cbc04f5624e64897a63dc5e5652e9414fb24e252f91d4d64358d1d837c343c5f338f6afd888f0ccc4770ca6c34a81e0c0f28836b7e4047f8", 'keccak512 (OO/file/1)'); +{ + open(my $fh, '<', 't/data/binary-test.file'); + binmode($fh); + is( Crypt::Digest::Keccak512->new->addfile($fh)->hexdigest, "369b779f34f5eb28cbc04f5624e64897a63dc5e5652e9414fb24e252f91d4d64358d1d837c343c5f338f6afd888f0ccc4770ca6c34a81e0c0f28836b7e4047f8", 'keccak512 (OO/filehandle/1)'); + close($fh); +} + +is( keccak512_file('t/data/text-CR.file'), pack("H*","6ec6b5af9b8a35ab4991000286f85b2e253fe00f5904ad4b999859c61c50b1c8f23050f6ad97f87bebd8e0e6b8277896b5123be2a3f961eb594759952c49b793"), 'keccak512 (raw/file/2)'); +is( keccak512_file_hex('t/data/text-CR.file'), "6ec6b5af9b8a35ab4991000286f85b2e253fe00f5904ad4b999859c61c50b1c8f23050f6ad97f87bebd8e0e6b8277896b5123be2a3f961eb594759952c49b793", 'keccak512 (hex/file/2)'); +is( keccak512_file_b64('t/data/text-CR.file'), "bsa1r5uKNatJkQAChvhbLiU/4A9ZBK1LmZhZxhxQscjyMFD2rZf4e+vY4Oa4J3iWtRI74qP5YetZR1mVLEm3kw==", 'keccak512 (base64/file/2)'); +is( digest_file('Keccak512', 't/data/text-CR.file'), pack("H*","6ec6b5af9b8a35ab4991000286f85b2e253fe00f5904ad4b999859c61c50b1c8f23050f6ad97f87bebd8e0e6b8277896b5123be2a3f961eb594759952c49b793"), 'keccak512 (digest_file_raw/file/2)'); +is( digest_file_hex('Keccak512', 't/data/text-CR.file'), "6ec6b5af9b8a35ab4991000286f85b2e253fe00f5904ad4b999859c61c50b1c8f23050f6ad97f87bebd8e0e6b8277896b5123be2a3f961eb594759952c49b793", 'keccak512 (digest_file_hex/file/2)'); +is( digest_file_b64('Keccak512', 't/data/text-CR.file'), "bsa1r5uKNatJkQAChvhbLiU/4A9ZBK1LmZhZxhxQscjyMFD2rZf4e+vY4Oa4J3iWtRI74qP5YetZR1mVLEm3kw==", 'keccak512 (digest_file_b64/file/2)'); +is( digest_file_b64u('Keccak512', 't/data/text-CR.file'), "bsa1r5uKNatJkQAChvhbLiU_4A9ZBK1LmZhZxhxQscjyMFD2rZf4e-vY4Oa4J3iWtRI74qP5YetZR1mVLEm3kw", 'keccak512 (digest_file_b64u/file/2)'); +is( Crypt::Digest::Keccak512->new->addfile('t/data/text-CR.file')->hexdigest, "6ec6b5af9b8a35ab4991000286f85b2e253fe00f5904ad4b999859c61c50b1c8f23050f6ad97f87bebd8e0e6b8277896b5123be2a3f961eb594759952c49b793", 'keccak512 (OO/file/2)'); +{ + open(my $fh, '<', 't/data/text-CR.file'); + binmode($fh); + is( Crypt::Digest::Keccak512->new->addfile($fh)->hexdigest, "6ec6b5af9b8a35ab4991000286f85b2e253fe00f5904ad4b999859c61c50b1c8f23050f6ad97f87bebd8e0e6b8277896b5123be2a3f961eb594759952c49b793", 'keccak512 (OO/filehandle/2)'); + close($fh); +} + +is( keccak512_file('t/data/text-CRLF.file'), pack("H*","f68607a6a0c9845780ba2e39c41748ff57188d93dd9b8140573f0a3558dd4f77a8e2c8348a936e43600f2bb2fdf2a73bba27044fb51b6c11787f453be407fbaf"), 'keccak512 (raw/file/3)'); +is( keccak512_file_hex('t/data/text-CRLF.file'), "f68607a6a0c9845780ba2e39c41748ff57188d93dd9b8140573f0a3558dd4f77a8e2c8348a936e43600f2bb2fdf2a73bba27044fb51b6c11787f453be407fbaf", 'keccak512 (hex/file/3)'); +is( keccak512_file_b64('t/data/text-CRLF.file'), "9oYHpqDJhFeAui45xBdI/1cYjZPdm4FAVz8KNVjdT3eo4sg0ipNuQ2APK7L98qc7uicET7UbbBF4f0U75Af7rw==", 'keccak512 (base64/file/3)'); +is( digest_file('Keccak512', 't/data/text-CRLF.file'), pack("H*","f68607a6a0c9845780ba2e39c41748ff57188d93dd9b8140573f0a3558dd4f77a8e2c8348a936e43600f2bb2fdf2a73bba27044fb51b6c11787f453be407fbaf"), 'keccak512 (digest_file_raw/file/3)'); +is( digest_file_hex('Keccak512', 't/data/text-CRLF.file'), "f68607a6a0c9845780ba2e39c41748ff57188d93dd9b8140573f0a3558dd4f77a8e2c8348a936e43600f2bb2fdf2a73bba27044fb51b6c11787f453be407fbaf", 'keccak512 (digest_file_hex/file/3)'); +is( digest_file_b64('Keccak512', 't/data/text-CRLF.file'), "9oYHpqDJhFeAui45xBdI/1cYjZPdm4FAVz8KNVjdT3eo4sg0ipNuQ2APK7L98qc7uicET7UbbBF4f0U75Af7rw==", 'keccak512 (digest_file_b64/file/3)'); +is( digest_file_b64u('Keccak512', 't/data/text-CRLF.file'), "9oYHpqDJhFeAui45xBdI_1cYjZPdm4FAVz8KNVjdT3eo4sg0ipNuQ2APK7L98qc7uicET7UbbBF4f0U75Af7rw", 'keccak512 (digest_file_b64u/file/3)'); +is( Crypt::Digest::Keccak512->new->addfile('t/data/text-CRLF.file')->hexdigest, "f68607a6a0c9845780ba2e39c41748ff57188d93dd9b8140573f0a3558dd4f77a8e2c8348a936e43600f2bb2fdf2a73bba27044fb51b6c11787f453be407fbaf", 'keccak512 (OO/file/3)'); +{ + open(my $fh, '<', 't/data/text-CRLF.file'); + binmode($fh); + is( Crypt::Digest::Keccak512->new->addfile($fh)->hexdigest, "f68607a6a0c9845780ba2e39c41748ff57188d93dd9b8140573f0a3558dd4f77a8e2c8348a936e43600f2bb2fdf2a73bba27044fb51b6c11787f453be407fbaf", 'keccak512 (OO/filehandle/3)'); + close($fh); +} + +is( keccak512_file('t/data/text-LF.file'), pack("H*","241eac4274cd76c6263fa67911d3f768afb791c280f03c757f5c2d067eb020e52c4ac934e2712cd350bfcbe01114e0824dec72140f0355b615f126b20c57c446"), 'keccak512 (raw/file/4)'); +is( keccak512_file_hex('t/data/text-LF.file'), "241eac4274cd76c6263fa67911d3f768afb791c280f03c757f5c2d067eb020e52c4ac934e2712cd350bfcbe01114e0824dec72140f0355b615f126b20c57c446", 'keccak512 (hex/file/4)'); +is( keccak512_file_b64('t/data/text-LF.file'), "JB6sQnTNdsYmP6Z5EdP3aK+3kcKA8Dx1f1wtBn6wIOUsSsk04nEs01C/y+ARFOCCTexyFA8DVbYV8SayDFfERg==", 'keccak512 (base64/file/4)'); +is( digest_file('Keccak512', 't/data/text-LF.file'), pack("H*","241eac4274cd76c6263fa67911d3f768afb791c280f03c757f5c2d067eb020e52c4ac934e2712cd350bfcbe01114e0824dec72140f0355b615f126b20c57c446"), 'keccak512 (digest_file_raw/file/4)'); +is( digest_file_hex('Keccak512', 't/data/text-LF.file'), "241eac4274cd76c6263fa67911d3f768afb791c280f03c757f5c2d067eb020e52c4ac934e2712cd350bfcbe01114e0824dec72140f0355b615f126b20c57c446", 'keccak512 (digest_file_hex/file/4)'); +is( digest_file_b64('Keccak512', 't/data/text-LF.file'), "JB6sQnTNdsYmP6Z5EdP3aK+3kcKA8Dx1f1wtBn6wIOUsSsk04nEs01C/y+ARFOCCTexyFA8DVbYV8SayDFfERg==", 'keccak512 (digest_file_b64/file/4)'); +is( digest_file_b64u('Keccak512', 't/data/text-LF.file'), "JB6sQnTNdsYmP6Z5EdP3aK-3kcKA8Dx1f1wtBn6wIOUsSsk04nEs01C_y-ARFOCCTexyFA8DVbYV8SayDFfERg", 'keccak512 (digest_file_b64u/file/4)'); +is( Crypt::Digest::Keccak512->new->addfile('t/data/text-LF.file')->hexdigest, "241eac4274cd76c6263fa67911d3f768afb791c280f03c757f5c2d067eb020e52c4ac934e2712cd350bfcbe01114e0824dec72140f0355b615f126b20c57c446", 'keccak512 (OO/file/4)'); +{ + open(my $fh, '<', 't/data/text-LF.file'); + binmode($fh); + is( Crypt::Digest::Keccak512->new->addfile($fh)->hexdigest, "241eac4274cd76c6263fa67911d3f768afb791c280f03c757f5c2d067eb020e52c4ac934e2712cd350bfcbe01114e0824dec72140f0355b615f126b20c57c446", 'keccak512 (OO/filehandle/4)'); + close($fh); +} diff --git a/t/digest_md2.t b/t/digest_md2.t index 312011d7..58b56865 100644 --- a/t/digest_md2.t +++ b/t/digest_md2.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::MD2 qw( md2 md2_hex md2_b64 md2_b64u md2_file md2_file_hex md2_file_b64 md2_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::MD2->hashsize, 16, 'hashsize/4'); is( Crypt::Digest->new('MD2')->hashsize, 16, 'hashsize/5'); is( Crypt::Digest::MD2->new->hashsize, 16, 'hashsize/6'); +is( md2("A","A","A"), pack("H*","8788c1729761fdad983b830f04b19e86"), 'md2 (raw/tripple_A)'); +is( md2_hex("A","A","A"), "8788c1729761fdad983b830f04b19e86", 'md2 (hex/tripple_A)'); +is( md2_b64("A","A","A"), "h4jBcpdh/a2YO4MPBLGehg==", 'md2 (base64/tripple_A)'); +is( md2_b64u("A","A","A"), "h4jBcpdh_a2YO4MPBLGehg", 'md2 (base64url/tripple_A)'); +is( digest_data('MD2', "A","A","A"), pack("H*","8788c1729761fdad983b830f04b19e86"), 'md2 (digest_data_raw/tripple_A)'); +is( digest_data_hex('MD2', "A","A","A"), "8788c1729761fdad983b830f04b19e86", 'md2 (digest_data_hex/tripple_A)'); +is( digest_data_b64('MD2', "A","A","A"), "h4jBcpdh/a2YO4MPBLGehg==", 'md2 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('MD2', "A","A","A"), "h4jBcpdh_a2YO4MPBLGehg", 'md2 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::MD2->new->add("A","A","A")->hexdigest, "8788c1729761fdad983b830f04b19e86", 'md2 (OO/tripple_A)'); +is( Crypt::Digest::MD2->new->add("A")->add("A")->add("A")->hexdigest, "8788c1729761fdad983b830f04b19e86", 'md2 (OO3/tripple_A)'); + is( md2(""), pack("H*","8350e5a3e24c153df2275c9f80692773"), 'md2 (raw/1)'); is( md2_hex(""), "8350e5a3e24c153df2275c9f80692773", 'md2 (hex/1)'); diff --git a/t/digest_md4.t b/t/digest_md4.t index b83d0610..f20f9aae 100644 --- a/t/digest_md4.t +++ b/t/digest_md4.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::MD4 qw( md4 md4_hex md4_b64 md4_b64u md4_file md4_file_hex md4_file_b64 md4_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::MD4->hashsize, 16, 'hashsize/4'); is( Crypt::Digest->new('MD4')->hashsize, 16, 'hashsize/5'); is( Crypt::Digest::MD4->new->hashsize, 16, 'hashsize/6'); +is( md4("A","A","A"), pack("H*","17c3b38c112ac61c1f0d46555f379f14"), 'md4 (raw/tripple_A)'); +is( md4_hex("A","A","A"), "17c3b38c112ac61c1f0d46555f379f14", 'md4 (hex/tripple_A)'); +is( md4_b64("A","A","A"), "F8OzjBEqxhwfDUZVXzefFA==", 'md4 (base64/tripple_A)'); +is( md4_b64u("A","A","A"), "F8OzjBEqxhwfDUZVXzefFA", 'md4 (base64url/tripple_A)'); +is( digest_data('MD4', "A","A","A"), pack("H*","17c3b38c112ac61c1f0d46555f379f14"), 'md4 (digest_data_raw/tripple_A)'); +is( digest_data_hex('MD4', "A","A","A"), "17c3b38c112ac61c1f0d46555f379f14", 'md4 (digest_data_hex/tripple_A)'); +is( digest_data_b64('MD4', "A","A","A"), "F8OzjBEqxhwfDUZVXzefFA==", 'md4 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('MD4', "A","A","A"), "F8OzjBEqxhwfDUZVXzefFA", 'md4 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::MD4->new->add("A","A","A")->hexdigest, "17c3b38c112ac61c1f0d46555f379f14", 'md4 (OO/tripple_A)'); +is( Crypt::Digest::MD4->new->add("A")->add("A")->add("A")->hexdigest, "17c3b38c112ac61c1f0d46555f379f14", 'md4 (OO3/tripple_A)'); + is( md4(""), pack("H*","31d6cfe0d16ae931b73c59d7e0c089c0"), 'md4 (raw/1)'); is( md4_hex(""), "31d6cfe0d16ae931b73c59d7e0c089c0", 'md4 (hex/1)'); diff --git a/t/digest_md5.t b/t/digest_md5.t index c4b22400..2f617b12 100644 --- a/t/digest_md5.t +++ b/t/digest_md5.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::MD5 qw( md5 md5_hex md5_b64 md5_b64u md5_file md5_file_hex md5_file_b64 md5_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::MD5->hashsize, 16, 'hashsize/4'); is( Crypt::Digest->new('MD5')->hashsize, 16, 'hashsize/5'); is( Crypt::Digest::MD5->new->hashsize, 16, 'hashsize/6'); +is( md5("A","A","A"), pack("H*","e1faffb3e614e6c2fba74296962386b7"), 'md5 (raw/tripple_A)'); +is( md5_hex("A","A","A"), "e1faffb3e614e6c2fba74296962386b7", 'md5 (hex/tripple_A)'); +is( md5_b64("A","A","A"), "4fr/s+YU5sL7p0KWliOGtw==", 'md5 (base64/tripple_A)'); +is( md5_b64u("A","A","A"), "4fr_s-YU5sL7p0KWliOGtw", 'md5 (base64url/tripple_A)'); +is( digest_data('MD5', "A","A","A"), pack("H*","e1faffb3e614e6c2fba74296962386b7"), 'md5 (digest_data_raw/tripple_A)'); +is( digest_data_hex('MD5', "A","A","A"), "e1faffb3e614e6c2fba74296962386b7", 'md5 (digest_data_hex/tripple_A)'); +is( digest_data_b64('MD5', "A","A","A"), "4fr/s+YU5sL7p0KWliOGtw==", 'md5 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('MD5', "A","A","A"), "4fr_s-YU5sL7p0KWliOGtw", 'md5 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::MD5->new->add("A","A","A")->hexdigest, "e1faffb3e614e6c2fba74296962386b7", 'md5 (OO/tripple_A)'); +is( Crypt::Digest::MD5->new->add("A")->add("A")->add("A")->hexdigest, "e1faffb3e614e6c2fba74296962386b7", 'md5 (OO3/tripple_A)'); + is( md5(""), pack("H*","d41d8cd98f00b204e9800998ecf8427e"), 'md5 (raw/1)'); is( md5_hex(""), "d41d8cd98f00b204e9800998ecf8427e", 'md5 (hex/1)'); diff --git a/t/digest_ripemd128.t b/t/digest_ripemd128.t index e655aa23..d91faf10 100644 --- a/t/digest_ripemd128.t +++ b/t/digest_ripemd128.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::RIPEMD128 qw( ripemd128 ripemd128_hex ripemd128_b64 ripemd128_b64u ripemd128_file ripemd128_file_hex ripemd128_file_b64 ripemd128_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::RIPEMD128->hashsize, 16, 'hashsize/4'); is( Crypt::Digest->new('RIPEMD128')->hashsize, 16, 'hashsize/5'); is( Crypt::Digest::RIPEMD128->new->hashsize, 16, 'hashsize/6'); +is( ripemd128("A","A","A"), pack("H*","c2750c6ca0c35d367de2993c3f55e1df"), 'ripemd128 (raw/tripple_A)'); +is( ripemd128_hex("A","A","A"), "c2750c6ca0c35d367de2993c3f55e1df", 'ripemd128 (hex/tripple_A)'); +is( ripemd128_b64("A","A","A"), "wnUMbKDDXTZ94pk8P1Xh3w==", 'ripemd128 (base64/tripple_A)'); +is( ripemd128_b64u("A","A","A"), "wnUMbKDDXTZ94pk8P1Xh3w", 'ripemd128 (base64url/tripple_A)'); +is( digest_data('RIPEMD128', "A","A","A"), pack("H*","c2750c6ca0c35d367de2993c3f55e1df"), 'ripemd128 (digest_data_raw/tripple_A)'); +is( digest_data_hex('RIPEMD128', "A","A","A"), "c2750c6ca0c35d367de2993c3f55e1df", 'ripemd128 (digest_data_hex/tripple_A)'); +is( digest_data_b64('RIPEMD128', "A","A","A"), "wnUMbKDDXTZ94pk8P1Xh3w==", 'ripemd128 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('RIPEMD128', "A","A","A"), "wnUMbKDDXTZ94pk8P1Xh3w", 'ripemd128 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::RIPEMD128->new->add("A","A","A")->hexdigest, "c2750c6ca0c35d367de2993c3f55e1df", 'ripemd128 (OO/tripple_A)'); +is( Crypt::Digest::RIPEMD128->new->add("A")->add("A")->add("A")->hexdigest, "c2750c6ca0c35d367de2993c3f55e1df", 'ripemd128 (OO3/tripple_A)'); + is( ripemd128(""), pack("H*","cdf26213a150dc3ecb610f18f6b38b46"), 'ripemd128 (raw/1)'); is( ripemd128_hex(""), "cdf26213a150dc3ecb610f18f6b38b46", 'ripemd128 (hex/1)'); diff --git a/t/digest_ripemd160.t b/t/digest_ripemd160.t index f290f9e2..c9e064cc 100644 --- a/t/digest_ripemd160.t +++ b/t/digest_ripemd160.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::RIPEMD160 qw( ripemd160 ripemd160_hex ripemd160_b64 ripemd160_b64u ripemd160_file ripemd160_file_hex ripemd160_file_b64 ripemd160_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::RIPEMD160->hashsize, 20, 'hashsize/4'); is( Crypt::Digest->new('RIPEMD160')->hashsize, 20, 'hashsize/5'); is( Crypt::Digest::RIPEMD160->new->hashsize, 20, 'hashsize/6'); +is( ripemd160("A","A","A"), pack("H*","e4e130acc1d2a5a63c17efb1eedbd02be28443d1"), 'ripemd160 (raw/tripple_A)'); +is( ripemd160_hex("A","A","A"), "e4e130acc1d2a5a63c17efb1eedbd02be28443d1", 'ripemd160 (hex/tripple_A)'); +is( ripemd160_b64("A","A","A"), "5OEwrMHSpaY8F++x7tvQK+KEQ9E=", 'ripemd160 (base64/tripple_A)'); +is( ripemd160_b64u("A","A","A"), "5OEwrMHSpaY8F--x7tvQK-KEQ9E", 'ripemd160 (base64url/tripple_A)'); +is( digest_data('RIPEMD160', "A","A","A"), pack("H*","e4e130acc1d2a5a63c17efb1eedbd02be28443d1"), 'ripemd160 (digest_data_raw/tripple_A)'); +is( digest_data_hex('RIPEMD160', "A","A","A"), "e4e130acc1d2a5a63c17efb1eedbd02be28443d1", 'ripemd160 (digest_data_hex/tripple_A)'); +is( digest_data_b64('RIPEMD160', "A","A","A"), "5OEwrMHSpaY8F++x7tvQK+KEQ9E=", 'ripemd160 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('RIPEMD160', "A","A","A"), "5OEwrMHSpaY8F--x7tvQK-KEQ9E", 'ripemd160 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::RIPEMD160->new->add("A","A","A")->hexdigest, "e4e130acc1d2a5a63c17efb1eedbd02be28443d1", 'ripemd160 (OO/tripple_A)'); +is( Crypt::Digest::RIPEMD160->new->add("A")->add("A")->add("A")->hexdigest, "e4e130acc1d2a5a63c17efb1eedbd02be28443d1", 'ripemd160 (OO3/tripple_A)'); + is( ripemd160(""), pack("H*","9c1185a5c5e9fc54612808977ee8f548b2258d31"), 'ripemd160 (raw/1)'); is( ripemd160_hex(""), "9c1185a5c5e9fc54612808977ee8f548b2258d31", 'ripemd160 (hex/1)'); diff --git a/t/digest_ripemd256.t b/t/digest_ripemd256.t index 6b13664f..d9809bf7 100644 --- a/t/digest_ripemd256.t +++ b/t/digest_ripemd256.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::RIPEMD256 qw( ripemd256 ripemd256_hex ripemd256_b64 ripemd256_b64u ripemd256_file ripemd256_file_hex ripemd256_file_b64 ripemd256_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::RIPEMD256->hashsize, 32, 'hashsize/4'); is( Crypt::Digest->new('RIPEMD256')->hashsize, 32, 'hashsize/5'); is( Crypt::Digest::RIPEMD256->new->hashsize, 32, 'hashsize/6'); +is( ripemd256("A","A","A"), pack("H*","0c976582631435d4fbc424758105a05a622ae27726f395774858d7ea2b2f5d82"), 'ripemd256 (raw/tripple_A)'); +is( ripemd256_hex("A","A","A"), "0c976582631435d4fbc424758105a05a622ae27726f395774858d7ea2b2f5d82", 'ripemd256 (hex/tripple_A)'); +is( ripemd256_b64("A","A","A"), "DJdlgmMUNdT7xCR1gQWgWmIq4ncm85V3SFjX6isvXYI=", 'ripemd256 (base64/tripple_A)'); +is( ripemd256_b64u("A","A","A"), "DJdlgmMUNdT7xCR1gQWgWmIq4ncm85V3SFjX6isvXYI", 'ripemd256 (base64url/tripple_A)'); +is( digest_data('RIPEMD256', "A","A","A"), pack("H*","0c976582631435d4fbc424758105a05a622ae27726f395774858d7ea2b2f5d82"), 'ripemd256 (digest_data_raw/tripple_A)'); +is( digest_data_hex('RIPEMD256', "A","A","A"), "0c976582631435d4fbc424758105a05a622ae27726f395774858d7ea2b2f5d82", 'ripemd256 (digest_data_hex/tripple_A)'); +is( digest_data_b64('RIPEMD256', "A","A","A"), "DJdlgmMUNdT7xCR1gQWgWmIq4ncm85V3SFjX6isvXYI=", 'ripemd256 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('RIPEMD256', "A","A","A"), "DJdlgmMUNdT7xCR1gQWgWmIq4ncm85V3SFjX6isvXYI", 'ripemd256 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::RIPEMD256->new->add("A","A","A")->hexdigest, "0c976582631435d4fbc424758105a05a622ae27726f395774858d7ea2b2f5d82", 'ripemd256 (OO/tripple_A)'); +is( Crypt::Digest::RIPEMD256->new->add("A")->add("A")->add("A")->hexdigest, "0c976582631435d4fbc424758105a05a622ae27726f395774858d7ea2b2f5d82", 'ripemd256 (OO3/tripple_A)'); + is( ripemd256(""), pack("H*","02ba4c4e5f8ecd1877fc52d64d30e37a2d9774fb1e5d026380ae0168e3c5522d"), 'ripemd256 (raw/1)'); is( ripemd256_hex(""), "02ba4c4e5f8ecd1877fc52d64d30e37a2d9774fb1e5d026380ae0168e3c5522d", 'ripemd256 (hex/1)'); diff --git a/t/digest_ripemd320.t b/t/digest_ripemd320.t index 4dc576d7..716a4724 100644 --- a/t/digest_ripemd320.t +++ b/t/digest_ripemd320.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::RIPEMD320 qw( ripemd320 ripemd320_hex ripemd320_b64 ripemd320_b64u ripemd320_file ripemd320_file_hex ripemd320_file_b64 ripemd320_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::RIPEMD320->hashsize, 40, 'hashsize/4'); is( Crypt::Digest->new('RIPEMD320')->hashsize, 40, 'hashsize/5'); is( Crypt::Digest::RIPEMD320->new->hashsize, 40, 'hashsize/6'); +is( ripemd320("A","A","A"), pack("H*","4cf34b2887f1dd1543fb0ce950bf155fb7c93c63d61adc67e858c1083fd54e4a7e1dab1b9b33ba60"), 'ripemd320 (raw/tripple_A)'); +is( ripemd320_hex("A","A","A"), "4cf34b2887f1dd1543fb0ce950bf155fb7c93c63d61adc67e858c1083fd54e4a7e1dab1b9b33ba60", 'ripemd320 (hex/tripple_A)'); +is( ripemd320_b64("A","A","A"), "TPNLKIfx3RVD+wzpUL8VX7fJPGPWGtxn6FjBCD/VTkp+HasbmzO6YA==", 'ripemd320 (base64/tripple_A)'); +is( ripemd320_b64u("A","A","A"), "TPNLKIfx3RVD-wzpUL8VX7fJPGPWGtxn6FjBCD_VTkp-HasbmzO6YA", 'ripemd320 (base64url/tripple_A)'); +is( digest_data('RIPEMD320', "A","A","A"), pack("H*","4cf34b2887f1dd1543fb0ce950bf155fb7c93c63d61adc67e858c1083fd54e4a7e1dab1b9b33ba60"), 'ripemd320 (digest_data_raw/tripple_A)'); +is( digest_data_hex('RIPEMD320', "A","A","A"), "4cf34b2887f1dd1543fb0ce950bf155fb7c93c63d61adc67e858c1083fd54e4a7e1dab1b9b33ba60", 'ripemd320 (digest_data_hex/tripple_A)'); +is( digest_data_b64('RIPEMD320', "A","A","A"), "TPNLKIfx3RVD+wzpUL8VX7fJPGPWGtxn6FjBCD/VTkp+HasbmzO6YA==", 'ripemd320 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('RIPEMD320', "A","A","A"), "TPNLKIfx3RVD-wzpUL8VX7fJPGPWGtxn6FjBCD_VTkp-HasbmzO6YA", 'ripemd320 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::RIPEMD320->new->add("A","A","A")->hexdigest, "4cf34b2887f1dd1543fb0ce950bf155fb7c93c63d61adc67e858c1083fd54e4a7e1dab1b9b33ba60", 'ripemd320 (OO/tripple_A)'); +is( Crypt::Digest::RIPEMD320->new->add("A")->add("A")->add("A")->hexdigest, "4cf34b2887f1dd1543fb0ce950bf155fb7c93c63d61adc67e858c1083fd54e4a7e1dab1b9b33ba60", 'ripemd320 (OO3/tripple_A)'); + is( ripemd320(""), pack("H*","22d65d5661536cdc75c1fdf5c6de7b41b9f27325ebc61e8557177d705a0ec880151c3a32a00899b8"), 'ripemd320 (raw/1)'); is( ripemd320_hex(""), "22d65d5661536cdc75c1fdf5c6de7b41b9f27325ebc61e8557177d705a0ec880151c3a32a00899b8", 'ripemd320 (hex/1)'); diff --git a/t/digest_sha1.t b/t/digest_sha1.t index c042d09c..a77bef79 100644 --- a/t/digest_sha1.t +++ b/t/digest_sha1.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::SHA1 qw( sha1 sha1_hex sha1_b64 sha1_b64u sha1_file sha1_file_hex sha1_file_b64 sha1_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::SHA1->hashsize, 20, 'hashsize/4'); is( Crypt::Digest->new('SHA1')->hashsize, 20, 'hashsize/5'); is( Crypt::Digest::SHA1->new->hashsize, 20, 'hashsize/6'); +is( sha1("A","A","A"), pack("H*","606ec6e9bd8a8ff2ad14e5fade3f264471e82251"), 'sha1 (raw/tripple_A)'); +is( sha1_hex("A","A","A"), "606ec6e9bd8a8ff2ad14e5fade3f264471e82251", 'sha1 (hex/tripple_A)'); +is( sha1_b64("A","A","A"), "YG7G6b2Kj/KtFOX63j8mRHHoIlE=", 'sha1 (base64/tripple_A)'); +is( sha1_b64u("A","A","A"), "YG7G6b2Kj_KtFOX63j8mRHHoIlE", 'sha1 (base64url/tripple_A)'); +is( digest_data('SHA1', "A","A","A"), pack("H*","606ec6e9bd8a8ff2ad14e5fade3f264471e82251"), 'sha1 (digest_data_raw/tripple_A)'); +is( digest_data_hex('SHA1', "A","A","A"), "606ec6e9bd8a8ff2ad14e5fade3f264471e82251", 'sha1 (digest_data_hex/tripple_A)'); +is( digest_data_b64('SHA1', "A","A","A"), "YG7G6b2Kj/KtFOX63j8mRHHoIlE=", 'sha1 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('SHA1', "A","A","A"), "YG7G6b2Kj_KtFOX63j8mRHHoIlE", 'sha1 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::SHA1->new->add("A","A","A")->hexdigest, "606ec6e9bd8a8ff2ad14e5fade3f264471e82251", 'sha1 (OO/tripple_A)'); +is( Crypt::Digest::SHA1->new->add("A")->add("A")->add("A")->hexdigest, "606ec6e9bd8a8ff2ad14e5fade3f264471e82251", 'sha1 (OO3/tripple_A)'); + is( sha1(""), pack("H*","da39a3ee5e6b4b0d3255bfef95601890afd80709"), 'sha1 (raw/1)'); is( sha1_hex(""), "da39a3ee5e6b4b0d3255bfef95601890afd80709", 'sha1 (hex/1)'); diff --git a/t/digest_sha224.t b/t/digest_sha224.t index 7489768a..7d7244bf 100644 --- a/t/digest_sha224.t +++ b/t/digest_sha224.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::SHA224 qw( sha224 sha224_hex sha224_b64 sha224_b64u sha224_file sha224_file_hex sha224_file_b64 sha224_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::SHA224->hashsize, 28, 'hashsize/4'); is( Crypt::Digest->new('SHA224')->hashsize, 28, 'hashsize/5'); is( Crypt::Digest::SHA224->new->hashsize, 28, 'hashsize/6'); +is( sha224("A","A","A"), pack("H*","808751af5f7936f20d1c79508d98c079e42ec26802ee238a5a486018"), 'sha224 (raw/tripple_A)'); +is( sha224_hex("A","A","A"), "808751af5f7936f20d1c79508d98c079e42ec26802ee238a5a486018", 'sha224 (hex/tripple_A)'); +is( sha224_b64("A","A","A"), "gIdRr195NvINHHlQjZjAeeQuwmgC7iOKWkhgGA==", 'sha224 (base64/tripple_A)'); +is( sha224_b64u("A","A","A"), "gIdRr195NvINHHlQjZjAeeQuwmgC7iOKWkhgGA", 'sha224 (base64url/tripple_A)'); +is( digest_data('SHA224', "A","A","A"), pack("H*","808751af5f7936f20d1c79508d98c079e42ec26802ee238a5a486018"), 'sha224 (digest_data_raw/tripple_A)'); +is( digest_data_hex('SHA224', "A","A","A"), "808751af5f7936f20d1c79508d98c079e42ec26802ee238a5a486018", 'sha224 (digest_data_hex/tripple_A)'); +is( digest_data_b64('SHA224', "A","A","A"), "gIdRr195NvINHHlQjZjAeeQuwmgC7iOKWkhgGA==", 'sha224 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('SHA224', "A","A","A"), "gIdRr195NvINHHlQjZjAeeQuwmgC7iOKWkhgGA", 'sha224 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::SHA224->new->add("A","A","A")->hexdigest, "808751af5f7936f20d1c79508d98c079e42ec26802ee238a5a486018", 'sha224 (OO/tripple_A)'); +is( Crypt::Digest::SHA224->new->add("A")->add("A")->add("A")->hexdigest, "808751af5f7936f20d1c79508d98c079e42ec26802ee238a5a486018", 'sha224 (OO3/tripple_A)'); + is( sha224(""), pack("H*","d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f"), 'sha224 (raw/1)'); is( sha224_hex(""), "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", 'sha224 (hex/1)'); diff --git a/t/digest_sha256.t b/t/digest_sha256.t index c0f79ccd..0f1e2e6f 100644 --- a/t/digest_sha256.t +++ b/t/digest_sha256.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::SHA256 qw( sha256 sha256_hex sha256_b64 sha256_b64u sha256_file sha256_file_hex sha256_file_b64 sha256_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::SHA256->hashsize, 32, 'hashsize/4'); is( Crypt::Digest->new('SHA256')->hashsize, 32, 'hashsize/5'); is( Crypt::Digest::SHA256->new->hashsize, 32, 'hashsize/6'); +is( sha256("A","A","A"), pack("H*","cb1ad2119d8fafb69566510ee712661f9f14b83385006ef92aec47f523a38358"), 'sha256 (raw/tripple_A)'); +is( sha256_hex("A","A","A"), "cb1ad2119d8fafb69566510ee712661f9f14b83385006ef92aec47f523a38358", 'sha256 (hex/tripple_A)'); +is( sha256_b64("A","A","A"), "yxrSEZ2Pr7aVZlEO5xJmH58UuDOFAG75KuxH9SOjg1g=", 'sha256 (base64/tripple_A)'); +is( sha256_b64u("A","A","A"), "yxrSEZ2Pr7aVZlEO5xJmH58UuDOFAG75KuxH9SOjg1g", 'sha256 (base64url/tripple_A)'); +is( digest_data('SHA256', "A","A","A"), pack("H*","cb1ad2119d8fafb69566510ee712661f9f14b83385006ef92aec47f523a38358"), 'sha256 (digest_data_raw/tripple_A)'); +is( digest_data_hex('SHA256', "A","A","A"), "cb1ad2119d8fafb69566510ee712661f9f14b83385006ef92aec47f523a38358", 'sha256 (digest_data_hex/tripple_A)'); +is( digest_data_b64('SHA256', "A","A","A"), "yxrSEZ2Pr7aVZlEO5xJmH58UuDOFAG75KuxH9SOjg1g=", 'sha256 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('SHA256', "A","A","A"), "yxrSEZ2Pr7aVZlEO5xJmH58UuDOFAG75KuxH9SOjg1g", 'sha256 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::SHA256->new->add("A","A","A")->hexdigest, "cb1ad2119d8fafb69566510ee712661f9f14b83385006ef92aec47f523a38358", 'sha256 (OO/tripple_A)'); +is( Crypt::Digest::SHA256->new->add("A")->add("A")->add("A")->hexdigest, "cb1ad2119d8fafb69566510ee712661f9f14b83385006ef92aec47f523a38358", 'sha256 (OO3/tripple_A)'); + is( sha256(""), pack("H*","e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"), 'sha256 (raw/1)'); is( sha256_hex(""), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 'sha256 (hex/1)'); diff --git a/t/digest_sha384.t b/t/digest_sha384.t index 506bb4b3..c65defb3 100644 --- a/t/digest_sha384.t +++ b/t/digest_sha384.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::SHA384 qw( sha384 sha384_hex sha384_b64 sha384_b64u sha384_file sha384_file_hex sha384_file_b64 sha384_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::SHA384->hashsize, 48, 'hashsize/4'); is( Crypt::Digest->new('SHA384')->hashsize, 48, 'hashsize/5'); is( Crypt::Digest::SHA384->new->hashsize, 48, 'hashsize/6'); +is( sha384("A","A","A"), pack("H*","8a5b7c19bcd1704d521f86b9618d86de0ed48fa29711ad4d16230f7d26b36111beaf7fefe8b3be7a17ce0e140ca002fe"), 'sha384 (raw/tripple_A)'); +is( sha384_hex("A","A","A"), "8a5b7c19bcd1704d521f86b9618d86de0ed48fa29711ad4d16230f7d26b36111beaf7fefe8b3be7a17ce0e140ca002fe", 'sha384 (hex/tripple_A)'); +is( sha384_b64("A","A","A"), "ilt8GbzRcE1SH4a5YY2G3g7Uj6KXEa1NFiMPfSazYRG+r3/v6LO+ehfODhQMoAL+", 'sha384 (base64/tripple_A)'); +is( sha384_b64u("A","A","A"), "ilt8GbzRcE1SH4a5YY2G3g7Uj6KXEa1NFiMPfSazYRG-r3_v6LO-ehfODhQMoAL-", 'sha384 (base64url/tripple_A)'); +is( digest_data('SHA384', "A","A","A"), pack("H*","8a5b7c19bcd1704d521f86b9618d86de0ed48fa29711ad4d16230f7d26b36111beaf7fefe8b3be7a17ce0e140ca002fe"), 'sha384 (digest_data_raw/tripple_A)'); +is( digest_data_hex('SHA384', "A","A","A"), "8a5b7c19bcd1704d521f86b9618d86de0ed48fa29711ad4d16230f7d26b36111beaf7fefe8b3be7a17ce0e140ca002fe", 'sha384 (digest_data_hex/tripple_A)'); +is( digest_data_b64('SHA384', "A","A","A"), "ilt8GbzRcE1SH4a5YY2G3g7Uj6KXEa1NFiMPfSazYRG+r3/v6LO+ehfODhQMoAL+", 'sha384 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('SHA384', "A","A","A"), "ilt8GbzRcE1SH4a5YY2G3g7Uj6KXEa1NFiMPfSazYRG-r3_v6LO-ehfODhQMoAL-", 'sha384 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::SHA384->new->add("A","A","A")->hexdigest, "8a5b7c19bcd1704d521f86b9618d86de0ed48fa29711ad4d16230f7d26b36111beaf7fefe8b3be7a17ce0e140ca002fe", 'sha384 (OO/tripple_A)'); +is( Crypt::Digest::SHA384->new->add("A")->add("A")->add("A")->hexdigest, "8a5b7c19bcd1704d521f86b9618d86de0ed48fa29711ad4d16230f7d26b36111beaf7fefe8b3be7a17ce0e140ca002fe", 'sha384 (OO3/tripple_A)'); + is( sha384(""), pack("H*","38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b"), 'sha384 (raw/1)'); is( sha384_hex(""), "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", 'sha384 (hex/1)'); diff --git a/t/digest_sha3_224.t b/t/digest_sha3_224.t index 6e2ecf39..75aebe6d 100644 --- a/t/digest_sha3_224.t +++ b/t/digest_sha3_224.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::SHA3_224 qw( sha3_224 sha3_224_hex sha3_224_b64 sha3_224_b64u sha3_224_file sha3_224_file_hex sha3_224_file_b64 sha3_224_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::SHA3_224->hashsize, 28, 'hashsize/4'); is( Crypt::Digest->new('SHA3_224')->hashsize, 28, 'hashsize/5'); is( Crypt::Digest::SHA3_224->new->hashsize, 28, 'hashsize/6'); +is( sha3_224("A","A","A"), pack("H*","c09d5af7d9a021c484041218f3c3787fd4274b64ffd012edca0fe55b"), 'sha3_224 (raw/tripple_A)'); +is( sha3_224_hex("A","A","A"), "c09d5af7d9a021c484041218f3c3787fd4274b64ffd012edca0fe55b", 'sha3_224 (hex/tripple_A)'); +is( sha3_224_b64("A","A","A"), "wJ1a99mgIcSEBBIY88N4f9QnS2T/0BLtyg/lWw==", 'sha3_224 (base64/tripple_A)'); +is( sha3_224_b64u("A","A","A"), "wJ1a99mgIcSEBBIY88N4f9QnS2T_0BLtyg_lWw", 'sha3_224 (base64url/tripple_A)'); +is( digest_data('SHA3_224', "A","A","A"), pack("H*","c09d5af7d9a021c484041218f3c3787fd4274b64ffd012edca0fe55b"), 'sha3_224 (digest_data_raw/tripple_A)'); +is( digest_data_hex('SHA3_224', "A","A","A"), "c09d5af7d9a021c484041218f3c3787fd4274b64ffd012edca0fe55b", 'sha3_224 (digest_data_hex/tripple_A)'); +is( digest_data_b64('SHA3_224', "A","A","A"), "wJ1a99mgIcSEBBIY88N4f9QnS2T/0BLtyg/lWw==", 'sha3_224 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('SHA3_224', "A","A","A"), "wJ1a99mgIcSEBBIY88N4f9QnS2T_0BLtyg_lWw", 'sha3_224 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::SHA3_224->new->add("A","A","A")->hexdigest, "c09d5af7d9a021c484041218f3c3787fd4274b64ffd012edca0fe55b", 'sha3_224 (OO/tripple_A)'); +is( Crypt::Digest::SHA3_224->new->add("A")->add("A")->add("A")->hexdigest, "c09d5af7d9a021c484041218f3c3787fd4274b64ffd012edca0fe55b", 'sha3_224 (OO3/tripple_A)'); + is( sha3_224(""), pack("H*","6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7"), 'sha3_224 (raw/1)'); is( sha3_224_hex(""), "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", 'sha3_224 (hex/1)'); diff --git a/t/digest_sha3_256.t b/t/digest_sha3_256.t index 6c813bdc..bbb25d47 100644 --- a/t/digest_sha3_256.t +++ b/t/digest_sha3_256.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::SHA3_256 qw( sha3_256 sha3_256_hex sha3_256_b64 sha3_256_b64u sha3_256_file sha3_256_file_hex sha3_256_file_b64 sha3_256_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::SHA3_256->hashsize, 32, 'hashsize/4'); is( Crypt::Digest->new('SHA3_256')->hashsize, 32, 'hashsize/5'); is( Crypt::Digest::SHA3_256->new->hashsize, 32, 'hashsize/6'); +is( sha3_256("A","A","A"), pack("H*","7dcb827a1f5a7cbea423e763a7dd0c7824e3512c7f1ce48cd5710f603b4f1efa"), 'sha3_256 (raw/tripple_A)'); +is( sha3_256_hex("A","A","A"), "7dcb827a1f5a7cbea423e763a7dd0c7824e3512c7f1ce48cd5710f603b4f1efa", 'sha3_256 (hex/tripple_A)'); +is( sha3_256_b64("A","A","A"), "fcuCeh9afL6kI+djp90MeCTjUSx/HOSM1XEPYDtPHvo=", 'sha3_256 (base64/tripple_A)'); +is( sha3_256_b64u("A","A","A"), "fcuCeh9afL6kI-djp90MeCTjUSx_HOSM1XEPYDtPHvo", 'sha3_256 (base64url/tripple_A)'); +is( digest_data('SHA3_256', "A","A","A"), pack("H*","7dcb827a1f5a7cbea423e763a7dd0c7824e3512c7f1ce48cd5710f603b4f1efa"), 'sha3_256 (digest_data_raw/tripple_A)'); +is( digest_data_hex('SHA3_256', "A","A","A"), "7dcb827a1f5a7cbea423e763a7dd0c7824e3512c7f1ce48cd5710f603b4f1efa", 'sha3_256 (digest_data_hex/tripple_A)'); +is( digest_data_b64('SHA3_256', "A","A","A"), "fcuCeh9afL6kI+djp90MeCTjUSx/HOSM1XEPYDtPHvo=", 'sha3_256 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('SHA3_256', "A","A","A"), "fcuCeh9afL6kI-djp90MeCTjUSx_HOSM1XEPYDtPHvo", 'sha3_256 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::SHA3_256->new->add("A","A","A")->hexdigest, "7dcb827a1f5a7cbea423e763a7dd0c7824e3512c7f1ce48cd5710f603b4f1efa", 'sha3_256 (OO/tripple_A)'); +is( Crypt::Digest::SHA3_256->new->add("A")->add("A")->add("A")->hexdigest, "7dcb827a1f5a7cbea423e763a7dd0c7824e3512c7f1ce48cd5710f603b4f1efa", 'sha3_256 (OO3/tripple_A)'); + is( sha3_256(""), pack("H*","a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"), 'sha3_256 (raw/1)'); is( sha3_256_hex(""), "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", 'sha3_256 (hex/1)'); diff --git a/t/digest_sha3_384.t b/t/digest_sha3_384.t index dadc964c..91784b72 100644 --- a/t/digest_sha3_384.t +++ b/t/digest_sha3_384.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::SHA3_384 qw( sha3_384 sha3_384_hex sha3_384_b64 sha3_384_b64u sha3_384_file sha3_384_file_hex sha3_384_file_b64 sha3_384_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::SHA3_384->hashsize, 48, 'hashsize/4'); is( Crypt::Digest->new('SHA3_384')->hashsize, 48, 'hashsize/5'); is( Crypt::Digest::SHA3_384->new->hashsize, 48, 'hashsize/6'); +is( sha3_384("A","A","A"), pack("H*","3555ed8a634b235fb07a691e1934b3e81228c859bc1c17acdebb4bab82cd63f06e17caed585533b4615bc6e3fb2e0bc4"), 'sha3_384 (raw/tripple_A)'); +is( sha3_384_hex("A","A","A"), "3555ed8a634b235fb07a691e1934b3e81228c859bc1c17acdebb4bab82cd63f06e17caed585533b4615bc6e3fb2e0bc4", 'sha3_384 (hex/tripple_A)'); +is( sha3_384_b64("A","A","A"), "NVXtimNLI1+wemkeGTSz6BIoyFm8HBes3rtLq4LNY/BuF8rtWFUztGFbxuP7LgvE", 'sha3_384 (base64/tripple_A)'); +is( sha3_384_b64u("A","A","A"), "NVXtimNLI1-wemkeGTSz6BIoyFm8HBes3rtLq4LNY_BuF8rtWFUztGFbxuP7LgvE", 'sha3_384 (base64url/tripple_A)'); +is( digest_data('SHA3_384', "A","A","A"), pack("H*","3555ed8a634b235fb07a691e1934b3e81228c859bc1c17acdebb4bab82cd63f06e17caed585533b4615bc6e3fb2e0bc4"), 'sha3_384 (digest_data_raw/tripple_A)'); +is( digest_data_hex('SHA3_384', "A","A","A"), "3555ed8a634b235fb07a691e1934b3e81228c859bc1c17acdebb4bab82cd63f06e17caed585533b4615bc6e3fb2e0bc4", 'sha3_384 (digest_data_hex/tripple_A)'); +is( digest_data_b64('SHA3_384', "A","A","A"), "NVXtimNLI1+wemkeGTSz6BIoyFm8HBes3rtLq4LNY/BuF8rtWFUztGFbxuP7LgvE", 'sha3_384 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('SHA3_384', "A","A","A"), "NVXtimNLI1-wemkeGTSz6BIoyFm8HBes3rtLq4LNY_BuF8rtWFUztGFbxuP7LgvE", 'sha3_384 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::SHA3_384->new->add("A","A","A")->hexdigest, "3555ed8a634b235fb07a691e1934b3e81228c859bc1c17acdebb4bab82cd63f06e17caed585533b4615bc6e3fb2e0bc4", 'sha3_384 (OO/tripple_A)'); +is( Crypt::Digest::SHA3_384->new->add("A")->add("A")->add("A")->hexdigest, "3555ed8a634b235fb07a691e1934b3e81228c859bc1c17acdebb4bab82cd63f06e17caed585533b4615bc6e3fb2e0bc4", 'sha3_384 (OO3/tripple_A)'); + is( sha3_384(""), pack("H*","0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004"), 'sha3_384 (raw/1)'); is( sha3_384_hex(""), "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004", 'sha3_384 (hex/1)'); diff --git a/t/digest_sha3_512.t b/t/digest_sha3_512.t index f8ab9aaa..5dbf5c64 100644 --- a/t/digest_sha3_512.t +++ b/t/digest_sha3_512.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::SHA3_512 qw( sha3_512 sha3_512_hex sha3_512_b64 sha3_512_b64u sha3_512_file sha3_512_file_hex sha3_512_file_b64 sha3_512_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::SHA3_512->hashsize, 64, 'hashsize/4'); is( Crypt::Digest->new('SHA3_512')->hashsize, 64, 'hashsize/5'); is( Crypt::Digest::SHA3_512->new->hashsize, 64, 'hashsize/6'); +is( sha3_512("A","A","A"), pack("H*","852cf44eb8d38715c847976b6de526564136d756fa99b4ad5a825fd6e3ba5d891c7b4576b11410a6e951fffa3399b14be1da4222d53b5a35ff236d659899e857"), 'sha3_512 (raw/tripple_A)'); +is( sha3_512_hex("A","A","A"), "852cf44eb8d38715c847976b6de526564136d756fa99b4ad5a825fd6e3ba5d891c7b4576b11410a6e951fffa3399b14be1da4222d53b5a35ff236d659899e857", 'sha3_512 (hex/tripple_A)'); +is( sha3_512_b64("A","A","A"), "hSz0TrjThxXIR5drbeUmVkE211b6mbStWoJf1uO6XYkce0V2sRQQpulR//ozmbFL4dpCItU7WjX/I21lmJnoVw==", 'sha3_512 (base64/tripple_A)'); +is( sha3_512_b64u("A","A","A"), "hSz0TrjThxXIR5drbeUmVkE211b6mbStWoJf1uO6XYkce0V2sRQQpulR__ozmbFL4dpCItU7WjX_I21lmJnoVw", 'sha3_512 (base64url/tripple_A)'); +is( digest_data('SHA3_512', "A","A","A"), pack("H*","852cf44eb8d38715c847976b6de526564136d756fa99b4ad5a825fd6e3ba5d891c7b4576b11410a6e951fffa3399b14be1da4222d53b5a35ff236d659899e857"), 'sha3_512 (digest_data_raw/tripple_A)'); +is( digest_data_hex('SHA3_512', "A","A","A"), "852cf44eb8d38715c847976b6de526564136d756fa99b4ad5a825fd6e3ba5d891c7b4576b11410a6e951fffa3399b14be1da4222d53b5a35ff236d659899e857", 'sha3_512 (digest_data_hex/tripple_A)'); +is( digest_data_b64('SHA3_512', "A","A","A"), "hSz0TrjThxXIR5drbeUmVkE211b6mbStWoJf1uO6XYkce0V2sRQQpulR//ozmbFL4dpCItU7WjX/I21lmJnoVw==", 'sha3_512 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('SHA3_512', "A","A","A"), "hSz0TrjThxXIR5drbeUmVkE211b6mbStWoJf1uO6XYkce0V2sRQQpulR__ozmbFL4dpCItU7WjX_I21lmJnoVw", 'sha3_512 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::SHA3_512->new->add("A","A","A")->hexdigest, "852cf44eb8d38715c847976b6de526564136d756fa99b4ad5a825fd6e3ba5d891c7b4576b11410a6e951fffa3399b14be1da4222d53b5a35ff236d659899e857", 'sha3_512 (OO/tripple_A)'); +is( Crypt::Digest::SHA3_512->new->add("A")->add("A")->add("A")->hexdigest, "852cf44eb8d38715c847976b6de526564136d756fa99b4ad5a825fd6e3ba5d891c7b4576b11410a6e951fffa3399b14be1da4222d53b5a35ff236d659899e857", 'sha3_512 (OO3/tripple_A)'); + is( sha3_512(""), pack("H*","a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"), 'sha3_512 (raw/1)'); is( sha3_512_hex(""), "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26", 'sha3_512 (hex/1)'); diff --git a/t/digest_sha512.t b/t/digest_sha512.t index 15ce8b12..2af4c6b4 100644 --- a/t/digest_sha512.t +++ b/t/digest_sha512.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::SHA512 qw( sha512 sha512_hex sha512_b64 sha512_b64u sha512_file sha512_file_hex sha512_file_b64 sha512_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::SHA512->hashsize, 64, 'hashsize/4'); is( Crypt::Digest->new('SHA512')->hashsize, 64, 'hashsize/5'); is( Crypt::Digest::SHA512->new->hashsize, 64, 'hashsize/6'); +is( sha512("A","A","A"), pack("H*","8d708d18b54df3962d696f069ad42dad7762b5d4d3c97ee5fa2dae0673ed46545164c078b8db3d59c4b96020e4316f17bb3d91bf1f6bc0896bbe75416eb8c385"), 'sha512 (raw/tripple_A)'); +is( sha512_hex("A","A","A"), "8d708d18b54df3962d696f069ad42dad7762b5d4d3c97ee5fa2dae0673ed46545164c078b8db3d59c4b96020e4316f17bb3d91bf1f6bc0896bbe75416eb8c385", 'sha512 (hex/tripple_A)'); +is( sha512_b64("A","A","A"), "jXCNGLVN85YtaW8GmtQtrXditdTTyX7l+i2uBnPtRlRRZMB4uNs9WcS5YCDkMW8Xuz2Rvx9rwIlrvnVBbrjDhQ==", 'sha512 (base64/tripple_A)'); +is( sha512_b64u("A","A","A"), "jXCNGLVN85YtaW8GmtQtrXditdTTyX7l-i2uBnPtRlRRZMB4uNs9WcS5YCDkMW8Xuz2Rvx9rwIlrvnVBbrjDhQ", 'sha512 (base64url/tripple_A)'); +is( digest_data('SHA512', "A","A","A"), pack("H*","8d708d18b54df3962d696f069ad42dad7762b5d4d3c97ee5fa2dae0673ed46545164c078b8db3d59c4b96020e4316f17bb3d91bf1f6bc0896bbe75416eb8c385"), 'sha512 (digest_data_raw/tripple_A)'); +is( digest_data_hex('SHA512', "A","A","A"), "8d708d18b54df3962d696f069ad42dad7762b5d4d3c97ee5fa2dae0673ed46545164c078b8db3d59c4b96020e4316f17bb3d91bf1f6bc0896bbe75416eb8c385", 'sha512 (digest_data_hex/tripple_A)'); +is( digest_data_b64('SHA512', "A","A","A"), "jXCNGLVN85YtaW8GmtQtrXditdTTyX7l+i2uBnPtRlRRZMB4uNs9WcS5YCDkMW8Xuz2Rvx9rwIlrvnVBbrjDhQ==", 'sha512 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('SHA512', "A","A","A"), "jXCNGLVN85YtaW8GmtQtrXditdTTyX7l-i2uBnPtRlRRZMB4uNs9WcS5YCDkMW8Xuz2Rvx9rwIlrvnVBbrjDhQ", 'sha512 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::SHA512->new->add("A","A","A")->hexdigest, "8d708d18b54df3962d696f069ad42dad7762b5d4d3c97ee5fa2dae0673ed46545164c078b8db3d59c4b96020e4316f17bb3d91bf1f6bc0896bbe75416eb8c385", 'sha512 (OO/tripple_A)'); +is( Crypt::Digest::SHA512->new->add("A")->add("A")->add("A")->hexdigest, "8d708d18b54df3962d696f069ad42dad7762b5d4d3c97ee5fa2dae0673ed46545164c078b8db3d59c4b96020e4316f17bb3d91bf1f6bc0896bbe75416eb8c385", 'sha512 (OO3/tripple_A)'); + is( sha512(""), pack("H*","cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"), 'sha512 (raw/1)'); is( sha512_hex(""), "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", 'sha512 (hex/1)'); diff --git a/t/digest_sha512_224.t b/t/digest_sha512_224.t index dc2033d8..ad19e438 100644 --- a/t/digest_sha512_224.t +++ b/t/digest_sha512_224.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::SHA512_224 qw( sha512_224 sha512_224_hex sha512_224_b64 sha512_224_b64u sha512_224_file sha512_224_file_hex sha512_224_file_b64 sha512_224_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::SHA512_224->hashsize, 28, 'hashsize/4'); is( Crypt::Digest->new('SHA512_224')->hashsize, 28, 'hashsize/5'); is( Crypt::Digest::SHA512_224->new->hashsize, 28, 'hashsize/6'); +is( sha512_224("A","A","A"), pack("H*","3d5a0b742f4c61d315c6ce86457a9fa30903880d30558c68ce4713b3"), 'sha512_224 (raw/tripple_A)'); +is( sha512_224_hex("A","A","A"), "3d5a0b742f4c61d315c6ce86457a9fa30903880d30558c68ce4713b3", 'sha512_224 (hex/tripple_A)'); +is( sha512_224_b64("A","A","A"), "PVoLdC9MYdMVxs6GRXqfowkDiA0wVYxozkcTsw==", 'sha512_224 (base64/tripple_A)'); +is( sha512_224_b64u("A","A","A"), "PVoLdC9MYdMVxs6GRXqfowkDiA0wVYxozkcTsw", 'sha512_224 (base64url/tripple_A)'); +is( digest_data('SHA512_224', "A","A","A"), pack("H*","3d5a0b742f4c61d315c6ce86457a9fa30903880d30558c68ce4713b3"), 'sha512_224 (digest_data_raw/tripple_A)'); +is( digest_data_hex('SHA512_224', "A","A","A"), "3d5a0b742f4c61d315c6ce86457a9fa30903880d30558c68ce4713b3", 'sha512_224 (digest_data_hex/tripple_A)'); +is( digest_data_b64('SHA512_224', "A","A","A"), "PVoLdC9MYdMVxs6GRXqfowkDiA0wVYxozkcTsw==", 'sha512_224 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('SHA512_224', "A","A","A"), "PVoLdC9MYdMVxs6GRXqfowkDiA0wVYxozkcTsw", 'sha512_224 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::SHA512_224->new->add("A","A","A")->hexdigest, "3d5a0b742f4c61d315c6ce86457a9fa30903880d30558c68ce4713b3", 'sha512_224 (OO/tripple_A)'); +is( Crypt::Digest::SHA512_224->new->add("A")->add("A")->add("A")->hexdigest, "3d5a0b742f4c61d315c6ce86457a9fa30903880d30558c68ce4713b3", 'sha512_224 (OO3/tripple_A)'); + is( sha512_224(""), pack("H*","6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4"), 'sha512_224 (raw/1)'); is( sha512_224_hex(""), "6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4", 'sha512_224 (hex/1)'); diff --git a/t/digest_sha512_256.t b/t/digest_sha512_256.t index d5412c2e..147918ce 100644 --- a/t/digest_sha512_256.t +++ b/t/digest_sha512_256.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::SHA512_256 qw( sha512_256 sha512_256_hex sha512_256_b64 sha512_256_b64u sha512_256_file sha512_256_file_hex sha512_256_file_b64 sha512_256_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::SHA512_256->hashsize, 32, 'hashsize/4'); is( Crypt::Digest->new('SHA512_256')->hashsize, 32, 'hashsize/5'); is( Crypt::Digest::SHA512_256->new->hashsize, 32, 'hashsize/6'); +is( sha512_256("A","A","A"), pack("H*","b28a62969d8b9b02297ba615c485be2dffef907ca419c2a494004026d6c4bdf4"), 'sha512_256 (raw/tripple_A)'); +is( sha512_256_hex("A","A","A"), "b28a62969d8b9b02297ba615c485be2dffef907ca419c2a494004026d6c4bdf4", 'sha512_256 (hex/tripple_A)'); +is( sha512_256_b64("A","A","A"), "sopilp2LmwIpe6YVxIW+Lf/vkHykGcKklABAJtbEvfQ=", 'sha512_256 (base64/tripple_A)'); +is( sha512_256_b64u("A","A","A"), "sopilp2LmwIpe6YVxIW-Lf_vkHykGcKklABAJtbEvfQ", 'sha512_256 (base64url/tripple_A)'); +is( digest_data('SHA512_256', "A","A","A"), pack("H*","b28a62969d8b9b02297ba615c485be2dffef907ca419c2a494004026d6c4bdf4"), 'sha512_256 (digest_data_raw/tripple_A)'); +is( digest_data_hex('SHA512_256', "A","A","A"), "b28a62969d8b9b02297ba615c485be2dffef907ca419c2a494004026d6c4bdf4", 'sha512_256 (digest_data_hex/tripple_A)'); +is( digest_data_b64('SHA512_256', "A","A","A"), "sopilp2LmwIpe6YVxIW+Lf/vkHykGcKklABAJtbEvfQ=", 'sha512_256 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('SHA512_256', "A","A","A"), "sopilp2LmwIpe6YVxIW-Lf_vkHykGcKklABAJtbEvfQ", 'sha512_256 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::SHA512_256->new->add("A","A","A")->hexdigest, "b28a62969d8b9b02297ba615c485be2dffef907ca419c2a494004026d6c4bdf4", 'sha512_256 (OO/tripple_A)'); +is( Crypt::Digest::SHA512_256->new->add("A")->add("A")->add("A")->hexdigest, "b28a62969d8b9b02297ba615c485be2dffef907ca419c2a494004026d6c4bdf4", 'sha512_256 (OO3/tripple_A)'); + is( sha512_256(""), pack("H*","c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a"), 'sha512_256 (raw/1)'); is( sha512_256_hex(""), "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a", 'sha512_256 (hex/1)'); diff --git a/t/digest_tiger192.t b/t/digest_tiger192.t index 8f0cf7f0..9e14403c 100644 --- a/t/digest_tiger192.t +++ b/t/digest_tiger192.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::Tiger192 qw( tiger192 tiger192_hex tiger192_b64 tiger192_b64u tiger192_file tiger192_file_hex tiger192_file_b64 tiger192_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::Tiger192->hashsize, 24, 'hashsize/4'); is( Crypt::Digest->new('Tiger192')->hashsize, 24, 'hashsize/5'); is( Crypt::Digest::Tiger192->new->hashsize, 24, 'hashsize/6'); +is( tiger192("A","A","A"), pack("H*","04682253acc4e609201422ad50ad6be2c51cf1698b0a41c9"), 'tiger192 (raw/tripple_A)'); +is( tiger192_hex("A","A","A"), "04682253acc4e609201422ad50ad6be2c51cf1698b0a41c9", 'tiger192 (hex/tripple_A)'); +is( tiger192_b64("A","A","A"), "BGgiU6zE5gkgFCKtUK1r4sUc8WmLCkHJ", 'tiger192 (base64/tripple_A)'); +is( tiger192_b64u("A","A","A"), "BGgiU6zE5gkgFCKtUK1r4sUc8WmLCkHJ", 'tiger192 (base64url/tripple_A)'); +is( digest_data('Tiger192', "A","A","A"), pack("H*","04682253acc4e609201422ad50ad6be2c51cf1698b0a41c9"), 'tiger192 (digest_data_raw/tripple_A)'); +is( digest_data_hex('Tiger192', "A","A","A"), "04682253acc4e609201422ad50ad6be2c51cf1698b0a41c9", 'tiger192 (digest_data_hex/tripple_A)'); +is( digest_data_b64('Tiger192', "A","A","A"), "BGgiU6zE5gkgFCKtUK1r4sUc8WmLCkHJ", 'tiger192 (digest_data_b64/tripple_A)'); +is( digest_data_b64u('Tiger192', "A","A","A"), "BGgiU6zE5gkgFCKtUK1r4sUc8WmLCkHJ", 'tiger192 (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::Tiger192->new->add("A","A","A")->hexdigest, "04682253acc4e609201422ad50ad6be2c51cf1698b0a41c9", 'tiger192 (OO/tripple_A)'); +is( Crypt::Digest::Tiger192->new->add("A")->add("A")->add("A")->hexdigest, "04682253acc4e609201422ad50ad6be2c51cf1698b0a41c9", 'tiger192 (OO3/tripple_A)'); + is( tiger192(""), pack("H*","3293ac630c13f0245f92bbb1766e16167a4e58492dde73f3"), 'tiger192 (raw/1)'); is( tiger192_hex(""), "3293ac630c13f0245f92bbb1766e16167a4e58492dde73f3", 'tiger192 (hex/1)'); diff --git a/t/digest_whirlpool.t b/t/digest_whirlpool.t index 4eb7b6f3..16a1a3dd 100644 --- a/t/digest_whirlpool.t +++ b/t/digest_whirlpool.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 8*3 + 9*4 + 6; +use Test::More tests => 8*3 + 9*4 + 10 + 6; use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u digest_file digest_file_hex digest_file_b64 digest_file_b64u ); use Crypt::Digest::Whirlpool qw( whirlpool whirlpool_hex whirlpool_b64 whirlpool_b64u whirlpool_file whirlpool_file_hex whirlpool_file_b64 whirlpool_file_b64u ); @@ -15,6 +15,17 @@ is( Crypt::Digest::Whirlpool->hashsize, 64, 'hashsize/4'); is( Crypt::Digest->new('Whirlpool')->hashsize, 64, 'hashsize/5'); is( Crypt::Digest::Whirlpool->new->hashsize, 64, 'hashsize/6'); +is( whirlpool("A","A","A"), pack("H*","a4dea38c743f318db7169e28ac27aff173942b67b56f9881da464bdac48f47cc481ee29746557cf013d1c54c7a76912c1380b168251df7118293511fd89a9a64"), 'whirlpool (raw/tripple_A)'); +is( whirlpool_hex("A","A","A"), "a4dea38c743f318db7169e28ac27aff173942b67b56f9881da464bdac48f47cc481ee29746557cf013d1c54c7a76912c1380b168251df7118293511fd89a9a64", 'whirlpool (hex/tripple_A)'); +is( whirlpool_b64("A","A","A"), "pN6jjHQ/MY23Fp4orCev8XOUK2e1b5iB2kZL2sSPR8xIHuKXRlV88BPRxUx6dpEsE4CxaCUd9xGCk1Ef2JqaZA==", 'whirlpool (base64/tripple_A)'); +is( whirlpool_b64u("A","A","A"), "pN6jjHQ_MY23Fp4orCev8XOUK2e1b5iB2kZL2sSPR8xIHuKXRlV88BPRxUx6dpEsE4CxaCUd9xGCk1Ef2JqaZA", 'whirlpool (base64url/tripple_A)'); +is( digest_data('Whirlpool', "A","A","A"), pack("H*","a4dea38c743f318db7169e28ac27aff173942b67b56f9881da464bdac48f47cc481ee29746557cf013d1c54c7a76912c1380b168251df7118293511fd89a9a64"), 'whirlpool (digest_data_raw/tripple_A)'); +is( digest_data_hex('Whirlpool', "A","A","A"), "a4dea38c743f318db7169e28ac27aff173942b67b56f9881da464bdac48f47cc481ee29746557cf013d1c54c7a76912c1380b168251df7118293511fd89a9a64", 'whirlpool (digest_data_hex/tripple_A)'); +is( digest_data_b64('Whirlpool', "A","A","A"), "pN6jjHQ/MY23Fp4orCev8XOUK2e1b5iB2kZL2sSPR8xIHuKXRlV88BPRxUx6dpEsE4CxaCUd9xGCk1Ef2JqaZA==", 'whirlpool (digest_data_b64/tripple_A)'); +is( digest_data_b64u('Whirlpool', "A","A","A"), "pN6jjHQ_MY23Fp4orCev8XOUK2e1b5iB2kZL2sSPR8xIHuKXRlV88BPRxUx6dpEsE4CxaCUd9xGCk1Ef2JqaZA", 'whirlpool (digest_data_b64u/tripple_A)'); +is( Crypt::Digest::Whirlpool->new->add("A","A","A")->hexdigest, "a4dea38c743f318db7169e28ac27aff173942b67b56f9881da464bdac48f47cc481ee29746557cf013d1c54c7a76912c1380b168251df7118293511fd89a9a64", 'whirlpool (OO/tripple_A)'); +is( Crypt::Digest::Whirlpool->new->add("A")->add("A")->add("A")->hexdigest, "a4dea38c743f318db7169e28ac27aff173942b67b56f9881da464bdac48f47cc481ee29746557cf013d1c54c7a76912c1380b168251df7118293511fd89a9a64", 'whirlpool (OO3/tripple_A)'); + is( whirlpool(""), pack("H*","19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3"), 'whirlpool (raw/1)'); is( whirlpool_hex(""), "19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3", 'whirlpool (hex/1)'); @@ -147,7 +147,7 @@ my $EC1 = { curve_cofactor => 1, curve_Gx => "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", curve_Gy => "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", - curve_name => "secp256r1", + curve_oid => "1.2.840.10045.3.1.7", curve_order => "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", curve_prime => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", k => "F3BD0C07A81FB932781ED52752F60CC89A6BE5E51934FE01938DDB55D8F77801", @@ -167,7 +167,7 @@ my $EC2 = { curve_cofactor => 1, curve_Gx => "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", curve_Gy => "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", - curve_name => "secp256r1", + curve_oid => "1.2.840.10045.3.1.7", curve_order => "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", curve_prime => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", k => "", @@ -183,7 +183,7 @@ my $EC2 = { is($kh->{pub_x}, $EC1->{pub_x}, "EC x test HASH1"); is($kh->{pub_y}, $EC1->{pub_y}, "EC y test HASH1"); is($kh->{k}, $EC1->{k}, "EC k test HASH1"); - is($kh->{curve_name}, "secp256r1", "EC curve test HASH1"); + is($kh->{curve_oid}, "1.2.840.10045.3.1.7", "EC curve test HASH1"); ok($ec->is_private, "EC private test HASH1"); my $jwk = $ec->export_key_jwk('private'); my $jwkp = $ec->export_key_jwk('public'); @@ -205,7 +205,7 @@ my $EC2 = { is($kh->{pub_x}, $EC1->{pub_x}, "EC x test JWK1"); is($kh->{pub_y}, $EC1->{pub_y}, "EC y test JWK1"); is($kh->{k}, $EC1->{k}, "EC k test JWK1"); - is($kh->{curve_name}, "secp256r1", "EC curve test JWK1"); + is($kh->{curve_oid}, "1.2.840.10045.3.1.7", "EC curve test JWK1"); ok($ec->is_private, "EC private test JWK1"); $jwk_tp = $ec->export_key_jwk_thumbprint('SHA256'); is($jwk_tp, $ec1_jwk_thumbprint_sha256, 'export_key_jwk_thumbprint(SHA256)'); @@ -215,7 +215,7 @@ my $EC2 = { is($kh->{pub_x}, $EC1->{pub_x}, "EC x test JWK2"); is($kh->{pub_y}, $EC1->{pub_y}, "EC y test JWK2"); is($kh->{k}, "", "EC k test JWK2"); - is($kh->{curve_name}, "secp256r1", "EC curve test JWK2"); + is($kh->{curve_oid}, "1.2.840.10045.3.1.7", "EC curve test JWK2"); ok(!$ec->is_private, "EC !private test JWK2"); $jwk_tp = $ec->export_key_jwk_thumbprint('SHA256'); is($jwk_tp, $ec1_jwk_thumbprint_sha256, 'export_key_jwk_thumbprint(SHA256)'); @@ -227,7 +227,7 @@ my $EC2 = { is($kh->{pub_x}, $EC1->{pub_x}, "EC x test HASH2"); is($kh->{pub_y}, $EC1->{pub_y}, "EC y test HASH2"); is($kh->{k}, "", "EC k test HASH2"); - is($kh->{curve_name}, "secp256r1", "EC curve test HASH2"); + is($kh->{curve_oid}, "1.2.840.10045.3.1.7", "EC curve test HASH2"); ok(!$ec->is_private, "EC private test HASH2"); } diff --git a/t/mac_blake2b.t b/t/mac_blake2b.t index 0e275a90..b04b8aef 100644 --- a/t/mac_blake2b.t +++ b/t/mac_blake2b.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 36; +use Test::More tests => 36 + 8; use Crypt::Mac::BLAKE2b qw( blake2b blake2b_hex blake2b_b64 blake2b_b64u ); @@ -43,3 +43,12 @@ is( unpack('H*', blake2b(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test is( blake2b_hex(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'dc29010f123a4cd59c91da5fc494375962502ca2179021ebca2f6dd41befa8d2', 'BLAKE2b/func+hex/6'); is( blake2b_b64(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), '3CkBDxI6TNWckdpfxJQ3WWJQLKIXkCHryi9t1BvvqNI=', 'BLAKE2b/func+b64/6'); is( blake2b_b64u(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), '3CkBDxI6TNWckdpfxJQ3WWJQLKIXkCHryi9t1BvvqNI', 'BLAKE2b/func+b64u/6'); + +is( unpack('H*', Crypt::Mac::BLAKE2b->new(32, '12345678901234561234567890123456')->add("A","A","A")->mac), '794a20cc22c1f9f278aa1219ded10105cc9cfd264e66a327f32fbc309b2d404f', 'BLAKE2b/oo+raw/tripple_A'); +is( unpack('H*', Crypt::Mac::BLAKE2b->new(32, '12345678901234561234567890123456')->add("A")->add("A")->add("A")->mac), '794a20cc22c1f9f278aa1219ded10105cc9cfd264e66a327f32fbc309b2d404f', 'BLAKE2b/oo3+raw/tripple_A'); +is( Crypt::Mac::BLAKE2b->new(32, '12345678901234561234567890123456')->add("A","A","A")->hexmac, '794a20cc22c1f9f278aa1219ded10105cc9cfd264e66a327f32fbc309b2d404f', 'BLAKE2b/oo+hex/tripple_A'); +is( Crypt::Mac::BLAKE2b->new(32, '12345678901234561234567890123456')->add("A")->add("A")->add("A")->hexmac, '794a20cc22c1f9f278aa1219ded10105cc9cfd264e66a327f32fbc309b2d404f', 'BLAKE2b/oo3+hex/tripple_A'); +is( unpack('H*', blake2b(32, '12345678901234561234567890123456',"A","A","A")), '794a20cc22c1f9f278aa1219ded10105cc9cfd264e66a327f32fbc309b2d404f', 'BLAKE2b/func+raw/tripple_A'); +is( blake2b_hex (32, '12345678901234561234567890123456',"A","A","A"), '794a20cc22c1f9f278aa1219ded10105cc9cfd264e66a327f32fbc309b2d404f', 'BLAKE2b/func+hex/tripple_A'); +is( blake2b_b64 (32, '12345678901234561234567890123456',"A","A","A"), 'eUogzCLB+fJ4qhIZ3tEBBcyc/SZOZqMn8y+8MJstQE8=', 'BLAKE2b/func+b64/tripple_A'); +is( blake2b_b64u(32, '12345678901234561234567890123456',"A","A","A"), 'eUogzCLB-fJ4qhIZ3tEBBcyc_SZOZqMn8y-8MJstQE8', 'BLAKE2b/func+b64u/tripple_A'); diff --git a/t/mac_blake2s.t b/t/mac_blake2s.t index 5698556c..179ea9b9 100644 --- a/t/mac_blake2s.t +++ b/t/mac_blake2s.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 36; +use Test::More tests => 36 + 8; use Crypt::Mac::BLAKE2s qw( blake2s blake2s_hex blake2s_b64 blake2s_b64u ); @@ -43,3 +43,12 @@ is( unpack('H*', blake2s(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test is( blake2s_hex(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'a31f0e2ba5e73a3aab7e14503690515662758279075d7b68512709824923e65c', 'BLAKE2s/func+hex/6'); is( blake2s_b64(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'ox8OK6XnOjqrfhRQNpBRVmJ1gnkHXXtoUScJgkkj5lw=', 'BLAKE2s/func+b64/6'); is( blake2s_b64u(32,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'ox8OK6XnOjqrfhRQNpBRVmJ1gnkHXXtoUScJgkkj5lw', 'BLAKE2s/func+b64u/6'); + +is( unpack('H*', Crypt::Mac::BLAKE2s->new(32, '12345678901234561234567890123456')->add("A","A","A")->mac), '8acd7813fe7251676d1cf2817c09a25840fa9a1df7143536448a5dfdf7365725', 'BLAKE2s/oo+raw/tripple_A'); +is( unpack('H*', Crypt::Mac::BLAKE2s->new(32, '12345678901234561234567890123456')->add("A")->add("A")->add("A")->mac), '8acd7813fe7251676d1cf2817c09a25840fa9a1df7143536448a5dfdf7365725', 'BLAKE2s/oo3+raw/tripple_A'); +is( Crypt::Mac::BLAKE2s->new(32, '12345678901234561234567890123456')->add("A","A","A")->hexmac, '8acd7813fe7251676d1cf2817c09a25840fa9a1df7143536448a5dfdf7365725', 'BLAKE2s/oo+hex/tripple_A'); +is( Crypt::Mac::BLAKE2s->new(32, '12345678901234561234567890123456')->add("A")->add("A")->add("A")->hexmac, '8acd7813fe7251676d1cf2817c09a25840fa9a1df7143536448a5dfdf7365725', 'BLAKE2s/oo3+hex/tripple_A'); +is( unpack('H*', blake2s(32, '12345678901234561234567890123456',"A","A","A")), '8acd7813fe7251676d1cf2817c09a25840fa9a1df7143536448a5dfdf7365725', 'BLAKE2s/func+raw/tripple_A'); +is( blake2s_hex (32, '12345678901234561234567890123456',"A","A","A"), '8acd7813fe7251676d1cf2817c09a25840fa9a1df7143536448a5dfdf7365725', 'BLAKE2s/func+hex/tripple_A'); +is( blake2s_b64 (32, '12345678901234561234567890123456',"A","A","A"), 'is14E/5yUWdtHPKBfAmiWED6mh33FDU2RIpd/fc2VyU=', 'BLAKE2s/func+b64/tripple_A'); +is( blake2s_b64u(32, '12345678901234561234567890123456',"A","A","A"), 'is14E_5yUWdtHPKBfAmiWED6mh33FDU2RIpd_fc2VyU', 'BLAKE2s/func+b64u/tripple_A'); @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 72; +use Test::More tests => 72 + 8; use Crypt::Mac::F9 qw( f9 f9_hex f9_b64 f9_b64u ); @@ -79,3 +79,12 @@ is( unpack('H*', f9('Blowfish','12345678901234561234567890123456',"test\0test\0t is( f9_hex('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'fa83d84023c43a81', 'F9/func+hex/12'); is( f9_b64('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), '+oPYQCPEOoE=', 'F9/func+b64/12'); is( f9_b64u('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), '-oPYQCPEOoE', 'F9/func+b64u/12'); + +is( unpack('H*', Crypt::Mac::F9->new('AES', '1234567890123456')->add("A","A","A")->mac), 'a30e9e0ee8cd9d7401f9a9967e82b5a1', 'F9/oo+raw/tripple_A'); +is( unpack('H*', Crypt::Mac::F9->new('AES', '1234567890123456')->add("A")->add("A")->add("A")->mac), 'a30e9e0ee8cd9d7401f9a9967e82b5a1', 'F9/oo3+raw/tripple_A'); +is( Crypt::Mac::F9->new('AES', '1234567890123456')->add("A","A","A")->hexmac, 'a30e9e0ee8cd9d7401f9a9967e82b5a1', 'F9/oo+hex/tripple_A'); +is( Crypt::Mac::F9->new('AES', '1234567890123456')->add("A")->add("A")->add("A")->hexmac, 'a30e9e0ee8cd9d7401f9a9967e82b5a1', 'F9/oo3+hex/tripple_A'); +is( unpack('H*', f9('AES', '1234567890123456',"A","A","A")), 'a30e9e0ee8cd9d7401f9a9967e82b5a1', 'F9/func+raw/tripple_A'); +is( f9_hex ('AES', '1234567890123456',"A","A","A"), 'a30e9e0ee8cd9d7401f9a9967e82b5a1', 'F9/func+hex/tripple_A'); +is( f9_b64 ('AES', '1234567890123456',"A","A","A"), 'ow6eDujNnXQB+amWfoK1oQ==', 'F9/func+b64/tripple_A'); +is( f9_b64u('AES', '1234567890123456',"A","A","A"), 'ow6eDujNnXQB-amWfoK1oQ', 'F9/func+b64u/tripple_A'); diff --git a/t/mac_hmac.t b/t/mac_hmac.t index f7b4def3..404d1fc3 100644 --- a/t/mac_hmac.t +++ b/t/mac_hmac.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 72; +use Test::More tests => 72 + 8; use Crypt::Mac::HMAC qw( hmac hmac_hex hmac_b64 hmac_b64u ); @@ -79,3 +79,12 @@ is( unpack('H*', hmac('Whirlpool','secretkey',"test\0test\0test\n")), 'dab6a22e0 is( hmac_hex('Whirlpool','secretkey',"test\0test\0test\n"), 'dab6a22e05b46ce641e022e6ea2b42646a25b994ed15fed09145e3906d159efba37b899c344f589b3ad5868cd631a8eb304d21dedf47e364c791ccfa665681f7', 'HMAC/func+hex/12'); is( hmac_b64('Whirlpool','secretkey',"test\0test\0test\n"), '2raiLgW0bOZB4CLm6itCZGoluZTtFf7QkUXjkG0Vnvuje4mcNE9YmzrVhozWMajrME0h3t9H42THkcz6ZlaB9w==', 'HMAC/func+b64/12'); is( hmac_b64u('Whirlpool','secretkey',"test\0test\0test\n"), '2raiLgW0bOZB4CLm6itCZGoluZTtFf7QkUXjkG0Vnvuje4mcNE9YmzrVhozWMajrME0h3t9H42THkcz6ZlaB9w', 'HMAC/func+b64u/12'); + +is( unpack('H*', Crypt::Mac::HMAC->new('SHA1', 'secretkey')->add("A","A","A")->mac), '99070fd56a6595bbb458747d63808344fed0b9c1', 'HMAC/oo+raw/tripple_A'); +is( unpack('H*', Crypt::Mac::HMAC->new('SHA1', 'secretkey')->add("A")->add("A")->add("A")->mac), '99070fd56a6595bbb458747d63808344fed0b9c1', 'HMAC/oo3+raw/tripple_A'); +is( Crypt::Mac::HMAC->new('SHA1', 'secretkey')->add("A","A","A")->hexmac, '99070fd56a6595bbb458747d63808344fed0b9c1', 'HMAC/oo+hex/tripple_A'); +is( Crypt::Mac::HMAC->new('SHA1', 'secretkey')->add("A")->add("A")->add("A")->hexmac, '99070fd56a6595bbb458747d63808344fed0b9c1', 'HMAC/oo3+hex/tripple_A'); +is( unpack('H*', hmac('SHA1', 'secretkey',"A","A","A")), '99070fd56a6595bbb458747d63808344fed0b9c1', 'HMAC/func+raw/tripple_A'); +is( hmac_hex ('SHA1', 'secretkey',"A","A","A"), '99070fd56a6595bbb458747d63808344fed0b9c1', 'HMAC/func+hex/tripple_A'); +is( hmac_b64 ('SHA1', 'secretkey',"A","A","A"), 'mQcP1Wpllbu0WHR9Y4CDRP7QucE=', 'HMAC/func+b64/tripple_A'); +is( hmac_b64u('SHA1', 'secretkey',"A","A","A"), 'mQcP1Wpllbu0WHR9Y4CDRP7QucE', 'HMAC/func+b64u/tripple_A'); diff --git a/t/mac_omac.t b/t/mac_omac.t index 6f84bc80..ea8ae320 100644 --- a/t/mac_omac.t +++ b/t/mac_omac.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 72; +use Test::More tests => 72 + 8; use Crypt::Mac::OMAC qw( omac omac_hex omac_b64 omac_b64u ); @@ -79,3 +79,12 @@ is( unpack('H*', omac('Blowfish','12345678901234561234567890123456',"test\0test\ is( omac_hex('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), '40e6d018b49ada77', 'OMAC/func+hex/12'); is( omac_b64('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'QObQGLSa2nc=', 'OMAC/func+b64/12'); is( omac_b64u('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'QObQGLSa2nc', 'OMAC/func+b64u/12'); + +is( unpack('H*', Crypt::Mac::OMAC->new('AES', '1234567890123456')->add("A","A","A")->mac), '49b745733f380fb4cdd8ce1ff1e52abc', 'OMAC/oo+raw/tripple_A'); +is( unpack('H*', Crypt::Mac::OMAC->new('AES', '1234567890123456')->add("A")->add("A")->add("A")->mac), '49b745733f380fb4cdd8ce1ff1e52abc', 'OMAC/oo3+raw/tripple_A'); +is( Crypt::Mac::OMAC->new('AES', '1234567890123456')->add("A","A","A")->hexmac, '49b745733f380fb4cdd8ce1ff1e52abc', 'OMAC/oo+hex/tripple_A'); +is( Crypt::Mac::OMAC->new('AES', '1234567890123456')->add("A")->add("A")->add("A")->hexmac, '49b745733f380fb4cdd8ce1ff1e52abc', 'OMAC/oo3+hex/tripple_A'); +is( unpack('H*', omac('AES', '1234567890123456',"A","A","A")), '49b745733f380fb4cdd8ce1ff1e52abc', 'OMAC/func+raw/tripple_A'); +is( omac_hex ('AES', '1234567890123456',"A","A","A"), '49b745733f380fb4cdd8ce1ff1e52abc', 'OMAC/func+hex/tripple_A'); +is( omac_b64 ('AES', '1234567890123456',"A","A","A"), 'SbdFcz84D7TN2M4f8eUqvA==', 'OMAC/func+b64/tripple_A'); +is( omac_b64u('AES', '1234567890123456',"A","A","A"), 'SbdFcz84D7TN2M4f8eUqvA', 'OMAC/func+b64u/tripple_A'); diff --git a/t/mac_pelican.t b/t/mac_pelican.t index b46815fc..1ece329f 100644 --- a/t/mac_pelican.t +++ b/t/mac_pelican.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 72; +use Test::More tests => 72 + 8; use Crypt::Mac::Pelican qw( pelican pelican_hex pelican_b64 pelican_b64u ); @@ -79,3 +79,12 @@ is( unpack('H*', pelican('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n" is( pelican_hex('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), '8a798fcb2181d9f9ed81fcd2a7f6cd4e', 'Pelican/func+hex/12'); is( pelican_b64('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'inmPyyGB2fntgfzSp/bNTg==', 'Pelican/func+b64/12'); is( pelican_b64u('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'inmPyyGB2fntgfzSp_bNTg', 'Pelican/func+b64u/12'); + +is( unpack('H*', Crypt::Mac::Pelican->new('1234567890123456')->add("A","A","A")->mac), '6f7dda998b3fdfeaa80737e5127532a5', 'Pelican/oo+raw/tripple_A'); +is( unpack('H*', Crypt::Mac::Pelican->new('1234567890123456')->add("A")->add("A")->add("A")->mac), '6f7dda998b3fdfeaa80737e5127532a5', 'Pelican/oo3+raw/tripple_A'); +is( Crypt::Mac::Pelican->new('1234567890123456')->add("A","A","A")->hexmac, '6f7dda998b3fdfeaa80737e5127532a5', 'Pelican/oo+hex/tripple_A'); +is( Crypt::Mac::Pelican->new('1234567890123456')->add("A")->add("A")->add("A")->hexmac, '6f7dda998b3fdfeaa80737e5127532a5', 'Pelican/oo3+hex/tripple_A'); +is( unpack('H*', pelican('1234567890123456',"A","A","A")), '6f7dda998b3fdfeaa80737e5127532a5', 'Pelican/func+raw/tripple_A'); +is( pelican_hex ('1234567890123456',"A","A","A"), '6f7dda998b3fdfeaa80737e5127532a5', 'Pelican/func+hex/tripple_A'); +is( pelican_b64 ('1234567890123456',"A","A","A"), 'b33amYs/3+qoBzflEnUypQ==', 'Pelican/func+b64/tripple_A'); +is( pelican_b64u('1234567890123456',"A","A","A"), 'b33amYs_3-qoBzflEnUypQ', 'Pelican/func+b64u/tripple_A'); diff --git a/t/mac_pmac.t b/t/mac_pmac.t index 19bec12c..6ca6e539 100644 --- a/t/mac_pmac.t +++ b/t/mac_pmac.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 72; +use Test::More tests => 72 + 8; use Crypt::Mac::PMAC qw( pmac pmac_hex pmac_b64 pmac_b64u ); @@ -79,3 +79,12 @@ is( unpack('H*', pmac('Blowfish','12345678901234561234567890123456',"test\0test\ is( pmac_hex('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), '3797cde072a8e286', 'PMAC/func+hex/12'); is( pmac_b64('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'N5fN4HKo4oY=', 'PMAC/func+b64/12'); is( pmac_b64u('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'N5fN4HKo4oY', 'PMAC/func+b64u/12'); + +is( unpack('H*', Crypt::Mac::PMAC->new('AES', '1234567890123456')->add("A","A","A")->mac), 'c46c52ff026e4e24837bc51a7e21f8cb', 'PMAC/oo+raw/tripple_A'); +is( unpack('H*', Crypt::Mac::PMAC->new('AES', '1234567890123456')->add("A")->add("A")->add("A")->mac), 'c46c52ff026e4e24837bc51a7e21f8cb', 'PMAC/oo3+raw/tripple_A'); +is( Crypt::Mac::PMAC->new('AES', '1234567890123456')->add("A","A","A")->hexmac, 'c46c52ff026e4e24837bc51a7e21f8cb', 'PMAC/oo+hex/tripple_A'); +is( Crypt::Mac::PMAC->new('AES', '1234567890123456')->add("A")->add("A")->add("A")->hexmac, 'c46c52ff026e4e24837bc51a7e21f8cb', 'PMAC/oo3+hex/tripple_A'); +is( unpack('H*', pmac('AES', '1234567890123456',"A","A","A")), 'c46c52ff026e4e24837bc51a7e21f8cb', 'PMAC/func+raw/tripple_A'); +is( pmac_hex ('AES', '1234567890123456',"A","A","A"), 'c46c52ff026e4e24837bc51a7e21f8cb', 'PMAC/func+hex/tripple_A'); +is( pmac_b64 ('AES', '1234567890123456',"A","A","A"), 'xGxS/wJuTiSDe8UafiH4yw==', 'PMAC/func+b64/tripple_A'); +is( pmac_b64u('AES', '1234567890123456',"A","A","A"), 'xGxS_wJuTiSDe8UafiH4yw', 'PMAC/func+b64u/tripple_A'); diff --git a/t/mac_poly1305.t b/t/mac_poly1305.t index ed29f56c..2f0036fe 100644 --- a/t/mac_poly1305.t +++ b/t/mac_poly1305.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 36; +use Test::More tests => 36 + 8; use Crypt::Mac::Poly1305 qw( poly1305 poly1305_hex poly1305_b64 poly1305_b64u ); @@ -43,3 +43,12 @@ is( unpack('H*', poly1305('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n is( poly1305_hex('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), '4c02cea60201d83ae4b2d644789422e5', 'Poly1305/func+hex/6'); is( poly1305_b64('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'TALOpgIB2DrkstZEeJQi5Q==', 'Poly1305/func+b64/6'); is( poly1305_b64u('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',"test\0test\0test\n"), 'TALOpgIB2DrkstZEeJQi5Q', 'Poly1305/func+b64u/6'); + +is( unpack('H*', Crypt::Mac::Poly1305->new('12345678901234561234567890123456')->add("A","A","A")->mac), '7c1e6c34ad72384ac4f52eb49f642abc', 'Poly1305/oo+raw/tripple_A'); +is( unpack('H*', Crypt::Mac::Poly1305->new('12345678901234561234567890123456')->add("A")->add("A")->add("A")->mac), '7c1e6c34ad72384ac4f52eb49f642abc', 'Poly1305/oo3+raw/tripple_A'); +is( Crypt::Mac::Poly1305->new('12345678901234561234567890123456')->add("A","A","A")->hexmac, '7c1e6c34ad72384ac4f52eb49f642abc', 'Poly1305/oo+hex/tripple_A'); +is( Crypt::Mac::Poly1305->new('12345678901234561234567890123456')->add("A")->add("A")->add("A")->hexmac, '7c1e6c34ad72384ac4f52eb49f642abc', 'Poly1305/oo3+hex/tripple_A'); +is( unpack('H*', poly1305('12345678901234561234567890123456',"A","A","A")), '7c1e6c34ad72384ac4f52eb49f642abc', 'Poly1305/func+raw/tripple_A'); +is( poly1305_hex ('12345678901234561234567890123456',"A","A","A"), '7c1e6c34ad72384ac4f52eb49f642abc', 'Poly1305/func+hex/tripple_A'); +is( poly1305_b64 ('12345678901234561234567890123456',"A","A","A"), 'fB5sNK1yOErE9S60n2QqvA==', 'Poly1305/func+b64/tripple_A'); +is( poly1305_b64u('12345678901234561234567890123456',"A","A","A"), 'fB5sNK1yOErE9S60n2QqvA', 'Poly1305/func+b64u/tripple_A'); diff --git a/t/mac_xcbc.t b/t/mac_xcbc.t index 50686c42..b756356d 100644 --- a/t/mac_xcbc.t +++ b/t/mac_xcbc.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 72; +use Test::More tests => 72 + 8; use Crypt::Mac::XCBC qw( xcbc xcbc_hex xcbc_b64 xcbc_b64u ); @@ -79,3 +79,12 @@ is( unpack('H*', xcbc('Blowfish','12345678901234561234567890123456',"test\0test\ is( xcbc_hex('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), '98276a4a6aafd86b', 'XCBC/func+hex/12'); is( xcbc_b64('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'mCdqSmqv2Gs=', 'XCBC/func+b64/12'); is( xcbc_b64u('Blowfish','12345678901234561234567890123456',"test\0test\0test\n"), 'mCdqSmqv2Gs', 'XCBC/func+b64u/12'); + +is( unpack('H*', Crypt::Mac::XCBC->new('AES', '1234567890123456')->add("A","A","A")->mac), 'da243c0a133fc33cd1f96b872c0bec9b', 'XCBC/oo+raw/tripple_A'); +is( unpack('H*', Crypt::Mac::XCBC->new('AES', '1234567890123456')->add("A")->add("A")->add("A")->mac), 'da243c0a133fc33cd1f96b872c0bec9b', 'XCBC/oo3+raw/tripple_A'); +is( Crypt::Mac::XCBC->new('AES', '1234567890123456')->add("A","A","A")->hexmac, 'da243c0a133fc33cd1f96b872c0bec9b', 'XCBC/oo+hex/tripple_A'); +is( Crypt::Mac::XCBC->new('AES', '1234567890123456')->add("A")->add("A")->add("A")->hexmac, 'da243c0a133fc33cd1f96b872c0bec9b', 'XCBC/oo3+hex/tripple_A'); +is( unpack('H*', xcbc('AES', '1234567890123456',"A","A","A")), 'da243c0a133fc33cd1f96b872c0bec9b', 'XCBC/func+raw/tripple_A'); +is( xcbc_hex ('AES', '1234567890123456',"A","A","A"), 'da243c0a133fc33cd1f96b872c0bec9b', 'XCBC/func+hex/tripple_A'); +is( xcbc_b64 ('AES', '1234567890123456',"A","A","A"), '2iQ8ChM/wzzR+WuHLAvsmw==', 'XCBC/func+b64/tripple_A'); +is( xcbc_b64u('AES', '1234567890123456',"A","A","A"), '2iQ8ChM_wzzR-WuHLAvsmw', 'XCBC/func+b64u/tripple_A'); diff --git a/t/mode_ctr.t b/t/mode_ctr.t index 623894aa..ebe2128a 100644 --- a/t/mode_ctr.t +++ b/t/mode_ctr.t @@ -1,6 +1,6 @@ use strict; use warnings; -use Test::More tests => 8; +use Test::More tests => 24; use Crypt::Mode::CTR; @@ -15,10 +15,28 @@ sub do_test { my $pt = pack("H*", $a{pt}); my $key = pack("H*", $a{key}); my $iv = pack("H*", $a{iv}); + # test: encrypt/decrypt in a single step my $ct_out = Crypt::Mode::CTR->new('AES', $a{mode}, $a{width})->encrypt($pt, $key, $iv); - is(unpack("H*", $ct_out), $a{ct}, "cipher text [m=$a{mode}, w=$a{width}]"); + is(unpack("H*", $ct_out), $a{ct}, "cipher text1 [m=$a{mode}, w=$a{width}]"); my $pt_out = Crypt::Mode::CTR->new('AES', $a{mode}, $a{width})->decrypt($ct_out, $key, $iv); - is(unpack("H*", $pt_out), $a{pt}, "plain text [m=$a{mode}, w=$a{width}]"); + is(unpack("H*", $pt_out), $a{pt}, "plain text1 [m=$a{mode}, w=$a{width}]"); + # test: add(@in) + my $mode; + my @in = map { pack("H*", $_) } ($a{pt} =~ /(..)/g); + $mode = Crypt::Mode::CTR->new('AES', $a{mode}, $a{width})->start_encrypt($key, $iv); + $ct_out = $mode->add(@in) . $mode->finish; + is(unpack("H*", $ct_out), $a{ct}, "cipher text2 [m=$a{mode}, w=$a{width}]"); + $mode = Crypt::Mode::CTR->new('AES', $a{mode}, $a{width})->start_encrypt($key, $iv); + $ct_out = join ('', map { $mode->add($_) } @in) . $mode->finish; + is(unpack("H*", $ct_out), $a{ct}, "cipher text3 [m=$a{mode}, w=$a{width}]"); + # test: add(?)->add(?)->add(?)->add(?) + @in = split //, $ct_out; + $mode = Crypt::Mode::CTR->new('AES', $a{mode}, $a{width})->start_decrypt($key, $iv); + $pt_out = $mode->add(@in) . $mode->finish; + is(unpack("H*", $pt_out), $a{pt}, "plain text2 [m=$a{mode}, w=$a{width}]"); + $mode = Crypt::Mode::CTR->new('AES', $a{mode}, $a{width})->start_decrypt($key, $iv); + $pt_out = join ('', map { $mode->add($_) } @in) . $mode->finish; + is(unpack("H*", $pt_out), $a{pt}, "plain text3 [m=$a{mode}, w=$a{width}]"); } do_test(%$_) for ( @@ -75,9 +75,9 @@ use Crypt::Misc 'decode_b64'; ok($pu1->verify_message($sig, "message"), 'verify_message'); my $hash = pack("H*","04624fae618e9ad0c5e479f62e1420c71fff34dd"); - $sig = $pr1->sign_hash($hash, 'SHA1'); + $sig = $pr1->sign_hash($hash); ok(length $sig > 60, 'sign_hash ' . length($sig)); - ok($pu1->verify_hash($sig, $hash, 'SHA1'), 'verify_hash'); + ok($pu1->verify_hash($sig, $hash), 'verify_hash'); my $pr2 = Crypt::PK::DSA->new; $pr2->import_key('t/data/cryptx_priv_dsa2.der'); @@ -195,7 +195,7 @@ MARKER ok($sig, 'dsa_sign_message'); ok(dsa_verify_message('t/data/cryptx_pub_dsa1.der', $sig, 'test string'), 'dsa_verify_message'); my $hash = pack("H*","04624fae618e9ad0c5e479f62e1420c71fff34dd"); - $sig = dsa_sign_hash('t/data/cryptx_priv_dsa1.der', $hash, 'SHA1'); + $sig = dsa_sign_hash('t/data/cryptx_priv_dsa1.der', $hash); ok($sig, 'dsa_sign_hash'); - ok(dsa_verify_hash('t/data/cryptx_pub_dsa1.der', $sig, $hash, 'SHA1'), 'dsa_verify_hash'); + ok(dsa_verify_hash('t/data/cryptx_pub_dsa1.der', $sig, $hash), 'dsa_verify_hash'); } @@ -179,16 +179,24 @@ for my $pub (qw/openssl_ec-short.pub.pem openssl_ec-short.pub.der/) { ok($@, 'key not generated'); # known curves lookup - my $params = $Crypt::PK::ECC::curve{secp384r1}; + my $params = { # NIST P-384 + prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", + A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", + B => "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", + Gx => "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", + Gy => "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", + order => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", + cofactor => 1, + }; $k = Crypt::PK::ECC->new; ok($k->generate_key($params), "generate_key hash params"); is($k->key2hash->{curve_name}, 'secp384r1', "key2hash curve_name"); - is($k->key2hash->{curve_oid}, $params->{oid}, "key2hash curve_oid"); + is($k->key2hash->{curve_oid}, '1.3.132.0.34', "key2hash curve_oid"); ok($k->export_key_der('private_short'), "export_key_der auto oid"); $k = Crypt::PK::ECC->new; - ok($k->generate_key({ %$params, A => '0' }), "generate_key invalid auto oid"); - is($k->key2hash->{curve_name}, 'custom', "key2hash custom curve_name"); + ok($k->generate_key({ %$params, cofactor => 6 }), "generate_key invalid auto oid"); + ok(!exists($k->key2hash->{curve_name}) || $k->key2hash->{curve_name} eq 'custom', "key2hash custom curve_name"); ok(!exists($k->key2hash->{curve_oid}), "key2hash curve_oid doesn't exist"); eval { $k->export_key_der('private_short'); }; ok($@, "export_key_der invalid auto oid"); @@ -1,6 +1,6 @@ use strict; use warnings; -use Test::More tests => 8; +use Test::More tests => 12; use Crypt::PK::RSA; use Crypt::PK::ECC; @@ -38,7 +38,7 @@ for my $f (qw/pkcs8.rsa-priv-nopass.pem pkcs8.rsa-priv-nopass.der/) { ### XXX-FIXME password protected pkcs8 private keys are not supported ### for my $f (qw/pkcs8.rsa-priv-pass.der pkcs8.rsa-priv-pass.pem/) { -### $rsa->import_key("t/data/$f"); +### $rsa->import_key("t/data/$f", "secret"); ### ok($rsa->is_private, "RSA is_private $f"); ### } @@ -47,8 +47,7 @@ for my $f (qw/pkcs8.ec-short-priv-nopass.der pkcs8.ec-short-priv-nopass.pem pkcs ok($ec->is_private, "ECC is_private $f"); } -### XXX-FIXME password protected pkcs8 private keys are not supported -### for my $f (qw/pkcs8.ec-priv-pass.der pkcs8.ec-priv-pass.pem pkcs8.ec-short-priv-pass.der pkcs8.ec-short-priv-pass.pem/) { -### $ec->import_key("t/data/$f"); -### ok($ec->is_private, "ECC is_private $f"); -### } +for my $f (qw/pkcs8.ec-priv-pass.der pkcs8.ec-priv-pass.pem pkcs8.ec-short-priv-pass.der pkcs8.ec-short-priv-pass.pem/) { + $ec->import_key("t/data/$f", "secret"); + ok($ec->is_private, "ECC is_private $f (pw)"); +} diff --git a/t/wycheproof.t b/t/wycheproof.t index fa2217e3..608e8482 100644 --- a/t/wycheproof.t +++ b/t/wycheproof.t @@ -7,7 +7,7 @@ use warnings; use Test::More; plan skip_all => "No JSON::* module installed" unless eval { require JSON::PP } || eval { require JSON::XS } || eval { require Cpanel::JSON::XS }; -plan tests => 762; +plan tests => 1298; use CryptX; use Crypt::Misc 'read_rawfile'; @@ -117,9 +117,9 @@ if (1) { # do the test my $testname = "type=$type/$sha tcId=$tcId comment='$comment' expected-result=$result"; my $pk = Crypt::PK::DSA->new( \$keyPem ); - my $valid = $pk->verify_message($sig, $message, $sha); my $hash = digest_data($sha, $message); my $valid_h = $pk->verify_hash($sig, $hash); + my $valid = $pk->verify_message($sig, $message, $sha); if ($result eq 'valid' || $result eq 'acceptable') { ok($valid, $testname); } @@ -133,13 +133,7 @@ if (1) { } } -if (0) { - #XXX-TODO: - # not ok 749 - type=ECDSAVer/SHA256 tcId=50 comment='appending unused 0's' expected-result=invalid verify_message=1 - # not ok 819 - type=ECDSAVer/SHA256 tcId=120 comment='Modified r or s, e.g. by adding or subtracting the order of the group' expected-result=invalid verify_message=1 - # not ok 820 - type=ECDSAVer/SHA256 tcId=121 comment='Modified r or s, e.g. by adding or subtracting the order of the group' expected-result=invalid verify_message=1 - # not ok 821 - type=ECDSAVer/SHA256 tcId=122 comment='Modified r or s, e.g. by adding or subtracting the order of the group' expected-result=invalid verify_message=1 - +if (1) { use Crypt::PK::ECC; my $tests = CryptX::_decode_json read_rawfile 't/wycheproof/ecdsa_test.json'; @@ -157,17 +151,21 @@ if (0) { my $result = $t->{result}; my $message = pack "H*", $t->{message}; my $sig = pack "H*", $t->{sig}; + # skip unsupported tests: + next if $tcId==9 && $result eq 'acceptable' && $comment eq "BER:long form encoding of length"; + next if $tcId==10 && $result eq 'acceptable' && $comment eq "BER:long form encoding of length"; + next if $tcId==12 && $result eq 'acceptable' && $comment eq "BER:length contains leading 0"; + next if $tcId==13 && $result eq 'acceptable' && $comment eq "BER:length contains leading 0"; + next if $tcId==14 && $result eq 'acceptable' && $comment eq "BER:indefinite length"; + next if $tcId==15 && $result eq 'acceptable' && $comment eq "BER:prepending 0's to integer"; + next if $tcId==16 && $result eq 'acceptable' && $comment eq "BER:prepending 0's to integer"; # do the test my $testname = "type=$type/$sha tcId=$tcId comment='$comment' expected-result=$result"; my $pk = Crypt::PK::ECC->new( \$keyPem ); my $valid = $pk->verify_message($sig, $message, $sha); - if ($result eq 'valid') { + if ($result eq 'valid' || $result eq 'acceptable') { ok($valid, "$testname verify_message=$valid"); } - elsif ($result eq 'acceptable') { - #XXX-TODO - #ok($valid, "$testname verify_message=$valid"); - } elsif ($result eq 'invalid') { ok(!$valid, "$testname verify_message=$valid"); } @@ -178,7 +176,7 @@ if (0) { } } -if (0) { +if (1) { use Crypt::PK::ECC; my $tests = CryptX::_decode_json read_rawfile 't/wycheproof/ecdsa_webcrypto_test.json'; @@ -201,14 +199,10 @@ if (0) { # do the test my $testname = "type=$type/$sha tcId=$tcId comment='$comment' expected-result=$result"; my $pk = Crypt::PK::ECC->new( \$keyPem ); - my $valid = $pk->verify_message($sig, $message, $sha); - if ($result eq 'valid') { + my $valid = $pk->verify_message_rfc7518($sig, $message, $sha); + if ($result eq 'valid' || $result eq 'acceptable') { ok($valid, "$testname verify_message=$valid"); } - elsif ($result eq 'acceptable') { - #XXX-TODO - #ok($valid, "$testname verify_message=$valid"); - } elsif ($result eq 'invalid') { ok(!$valid, "$testname verify_message=$valid"); } |