Codebase list libcryptx-perl / upstream/0.064 inc / CryptX_Cipher.xs.inc
upstream/0.064

Tree @upstream/0.064 (Download .tar.gz)

CryptX_Cipher.xs.inc @upstream/0.064

dd9a707
 
da585c2
 
dd9a707
611fb98
dd9a707
 
 
611fb98
 
 
 
 
 
 
 
 
 
 
 
 
 
ce15e24
dd9a707
 
ce15e24
611fb98
4a2b9bf
dd9a707
 
 
 
 
b016410
4a2b9bf
 
 
 
dd9a707
 
 
 
 
611fb98
dd9a707
 
 
 
611fb98
dd9a707
 
 
 
 
 
5d507df
0debb3d
5d507df
8ea3915
71c5bc4
dd9a707
 
5d507df
 
 
 
 
 
 
 
dd9a707
 
 
 
 
 
611fb98
dd9a707
 
 
 
 
 
5d507df
0debb3d
5d507df
8ea3915
71c5bc4
dd9a707
 
5d507df
 
 
 
 
 
 
 
dd9a707
 
 
 
 
 
611fb98
dd9a707
 
611fb98
 
 
 
 
 
 
 
 
 
 
 
 
dd9a707
 
 
 
 
611fb98
dd9a707
 
611fb98
 
 
 
 
 
 
 
 
 
 
 
 
dd9a707
 
 
 
 
611fb98
dd9a707
 
611fb98
 
 
 
 
 
 
 
 
 
 
 
 
dd9a707
 
 
 
 
611fb98
dd9a707
 
611fb98
 
 
 
 
 
 
 
 
 
 
 
 
dd9a707
 
 
MODULE = CryptX         PACKAGE = Crypt::Cipher

PROTOTYPES: DISABLE

Crypt::Cipher
new(char * class, ...)
    CODE:
    {
        STRLEN key_len;
        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);
        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->desc = &cipher_descriptor[id];
        rv = RETVAL->desc->setup(key_data, (int)key_len, rounds, &RETVAL->skey);
        if (rv != CRYPT_OK) {
          Safefree(RETVAL);
          croak("FATAL: cipher setup failed: %s", error_to_string(rv));
        }
    }
    OUTPUT:
        RETVAL

void
DESTROY(Crypt::Cipher self)
    CODE:
        Safefree(self);

SV *
encrypt(Crypt::Cipher self, SV * data)
    CODE:
    {
        int rv;
        STRLEN len;
        void *plaintext = SvPVbyte(data, len);

        if (len == 0) {
          RETVAL = newSVpvn("", 0);
        }
        else if (len == (STRLEN)self->desc->block_length) {
          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);
          if (rv!=CRYPT_OK) {
            SvREFCNT_dec(RETVAL);
            croak("FATAL: encrypt failed: %s", error_to_string(rv));
          }
        }
        else {
          croak ("FATAL: input size not equal to blocksize (%d)", self->desc->block_length);
        }
    }
    OUTPUT:
        RETVAL

SV *
decrypt(Crypt::Cipher self, SV * data)
    CODE:
    {
        int rv;
        STRLEN len;
        void *ciphertext = SvPVbyte(data, len);

        if (len == 0) {
          RETVAL = newSVpvn("", 0);
        }
        else if (len == (STRLEN)self->desc->block_length) {
          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);
          if (rv!=CRYPT_OK) {
            SvREFCNT_dec(RETVAL);
            croak("FATAL: decrypt failed: %s", error_to_string(rv));
          }
        }
        else {
          croak ("FATAL: input size not equal to blocksize (%d)", self->desc->block_length);
        }
    }
    OUTPUT:
        RETVAL

int
blocksize(SV * param, char * extra = NULL)
    CODE:
    {
        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
max_keysize(SV * param, char * extra = NULL)
    CODE:
    {
        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
min_keysize(SV * param, char * extra = NULL)
    CODE:
    {
        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(SV * param, char * extra = NULL)
    CODE:
    {
        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