Crypt-GCrypt

 view release on metacpan or  search on metacpan

GCrypt.xs  view on Meta::CPAN

                    RETVAL->type = CG_TYPE_ASYMM;
                if (strcmp(s, "digest") == 0)
                    RETVAL->type = CG_TYPE_DIGEST;
            }
            if (strcmp(s, "algorithm") == 0) {
                algo_s = SvPV_nolen(ST(i+1));
            }
            if (strcmp(s, "mode") == 0) {
                mode_s = SvPV_nolen(ST(i+1));
                have_mode = 1;
            }
            if (strcmp(s, "padding") == 0) {
                s = SvPV_nolen(ST(i+1));
                if (strcmp(s, "none") == 0)
                    RETVAL->padding = CG_PADDING_NONE;
                if (strcmp(s, "standard") == 0)
                    RETVAL->padding = CG_PADDING_STANDARD;
                if (strcmp(s, "null") == 0)
                    RETVAL->padding = CG_PADDING_NULL;
            }
            if (strcmp(s, "secure") == 0) {
                if (SvTRUE(ST(i+1))) {
                   c_flags |= GCRY_CIPHER_SECURE;
                   md_flags |= GCRY_MD_FLAG_SECURE;
                }
            }
            if (strcmp(s, "hmac") == 0) {
                key_s = SvPV(ST(i+1), RETVAL->keylen);
                md_flags |= GCRY_MD_FLAG_HMAC;
            }
            if (strcmp(s, "enable_sync") == 0) {
                if (SvTRUE(ST(i+1))) c_flags |= GCRY_CIPHER_ENABLE_SYNC;
            }
            i = i + 2;
        }
        if (RETVAL->type == -1)
            croak("No valid type specified for Crypt::GCrypt->new()");
        if (!algo_s)
            croak("No algorithm specified for Crypt::GCrypt->new()");

        init_library();

        if (RETVAL->type == CG_TYPE_CIPHER) {
            /* Checking algorithm */
            if (!(algo = gcry_cipher_map_name(algo_s)))
                croak("Unknown cipher algorithm %s", algo_s);
            RETVAL->blklen = gcry_cipher_get_algo_blklen(algo);
            RETVAL->keylen = gcry_cipher_get_algo_keylen(algo);
            
            /* Checking mode */
            if (have_mode) {
                switch (mode_s[0]) {
                    case 'e':
                        if (strcmp(mode_s+1, "cb") == 0)
                            RETVAL->mode = GCRY_CIPHER_MODE_ECB;
                        break;
                    case 'c':
                        if (strcmp(mode_s+1, "fb") == 0)
                            RETVAL->mode = GCRY_CIPHER_MODE_CFB;
                        else if (strcmp(mode_s+1, "bc") == 0)
                            RETVAL->mode = GCRY_CIPHER_MODE_CBC;
                        break;
                    case 's':
                        if (strcmp(mode_s+1, "tream") == 0)
                            RETVAL->mode = GCRY_CIPHER_MODE_STREAM;
                        break;
                    case 'o':
                        if (strcmp(mode_s+1, "fb") == 0)
                            RETVAL->mode = GCRY_CIPHER_MODE_OFB;
                        break;
                }
            } else {
                RETVAL->mode = RETVAL->blklen > 1 ? GCRY_CIPHER_MODE_CBC
                        : GCRY_CIPHER_MODE_STREAM;
            }
            if (!RETVAL->mode)
                croak("Unknown mode %s", mode_s);
            
            /* Init cipher */
            RETVAL->err = gcry_cipher_open(&RETVAL->h, algo, RETVAL->mode, c_flags);
            if (RETVAL->h == NULL) XSRETURN_UNDEF;
        }
        if (RETVAL->type == CG_TYPE_DIGEST) {
            if (!(algo = gcry_md_map_name(algo_s)))
                croak("Unknown digest algorithm %s", algo_s);

        RETVAL->err = gcry_md_open(&RETVAL->h_md, algo, md_flags);
            if (RETVAL->h_md == NULL) XSRETURN_UNDEF;

        if (md_flags & GCRY_MD_FLAG_HMAC) {
            /* what if this overwrites the earlier error value? */
            RETVAL->err = gcry_md_setkey(RETVAL->h_md, key_s, RETVAL->keylen);
        }
    }
        if (RETVAL->type == CG_TYPE_ASYMM) {
        
            croak("Asymmetric cryptography is not yet supported by Crypt::GCrypt");
            
            RETVAL->err = gcry_ac_name_to_id(algo_s, &ac_algo);
            if (RETVAL->err)
                croak("Unknown algorithm %s", algo_s);
            
            /* Init ac */
            RETVAL->err = gcry_ac_open(&RETVAL->h_ac, ac_algo, ac_flags);
            if (RETVAL->h_ac == NULL) XSRETURN_UNDEF;
        }
        

    OUTPUT:
        RETVAL

SV *
cg_encrypt(gcr, in)
    Crypt_GCrypt gcr;
    SV *in;
    PREINIT:
        char *ibuf, *curbuf, *obuf;
        size_t len, ilen, buflen;
    CODE:
        if (gcr->action != CG_ACTION_ENCRYPT)
            croak("start('encrypting') was not called");
        
        ibuf = SvPV(in, ilen);
        
        if (gcr->padding == CG_PADDING_NONE && ilen % gcr->blklen > 0)
            croak("'None' padding requires that input to ->encrypt() is supplied as a multiple of blklen");
        
        /* Get total buffer+ibuf length */
        Newz(0, curbuf, ilen + gcr->buflen, char);
        memcpy(curbuf, gcr->buffer, gcr->buflen);
        memcpy(curbuf+gcr->buflen, ibuf, ilen);
        
        if ((len = (ilen+gcr->buflen) % gcr->blklen) == 0) {



( run in 0.698 second using v1.01-cache-2.11-cpan-e1769b4cff6 )