Пример #1
1
int main(int argc, char *argv[])
{   FILE *inf, *outf;
    unsigned char buf[1024], tmp_buf1[16], tmp_buf2[16], salt[16], *fname, *cp;
    fcrypt_ctx  zcx[1];
    int len, flen, err = 0;
    unsigned char mode;

    if(argc != 3)   /* the command line is bad  */
    {
        err = ERROR_USAGE; goto error_0;
    }


    len = (int)strlen(argv[1]);

    if(len < 8)     /* password is too short    */
    {
        err = ERROR_PASSWORD_LENGTH; goto error_0;
    }

    /* set the key length based on password length assuming that there  */
    /* are about 4 bits of entropy per password character (the key      */
    /* length and other mode dependent parameter values are set using   */
    /* macros defined in fileenc.h)                                     */
    mode = (len < 32 ? 1 : len < 48 ? 2 : 3);

    /* save input file name to a temporary memory area with extra space */
    /* for the extension ".enc" to be added                             */
    fname = (unsigned char*)malloc(strlen(argv[2]) + 5);
    if(fname == NULL)
    {
        err = ERROR_OUT_OF_MEMORY; goto error_0;
    }

    /* open the input file  */
    strcpy(fname, argv[2]);
    if((inf = fopen(fname, "rb")) == NULL)
    {
        err = ERROR_INPUT_FILE; goto error_1;
    }

    /* if the file name extension is ".enc" assume this is an encrypted */
    /* file                                                             */
    if((cp = strrchr(fname, '.')) && strcmp(cp, ".enc") == 0)
    {
        *cp = 0;
        mode |= 4;  /* signal decryption */
    }
    else                        /* add ".enc" to file name to mark the  */
        strcat(fname, ".enc");  /* the file as an encrypted one         */

    /* open output file for binary output */
    if((outf = fopen(fname, "wb")) == NULL)
    {
        err = ERROR_OUTPUT_FILE; goto error_2;
    }

    if(!(mode & 4))         /* encryption operation     */
    {
        prng_ctx rng[1];    /* the context for the random number pool   */
        prng_init(entropy_fun, rng);                /* initialise RNG   */
        prng_rand(salt, SALT_LENGTH(mode), rng);    /* and the salt     */

        /* write salt value         */
        fwrite(salt, sizeof(unsigned char), SALT_LENGTH(mode), outf);

        /* initialise encryption and authentication */
#ifdef PASSWORD_VERIFIER
        fcrypt_init(mode, argv[1], (unsigned int)strlen(argv[1]), salt, tmp_buf1, zcx);
        /* write password verifier (if used)        */
        fwrite(tmp_buf1, sizeof(unsigned char), PWD_VER_LENGTH, outf);
#else
        fcrypt_init(mode, argv[1], (unsigned int)strlen(argv[1]), salt, zcx);
#endif
        /* encrypt and authenticate the file        */
        len = (int)fread(buf, sizeof(unsigned char), 1024, inf);
        while(len)
        {
            fcrypt_encrypt(buf, len, zcx);
            fwrite(buf, sizeof(unsigned char), len, outf);
            len = (int)fread(buf, sizeof(unsigned char), len, inf);
        }

        /* write the MAC    */
        fcrypt_end(tmp_buf1, zcx);
        fwrite(tmp_buf1, sizeof(unsigned char), MAC_LENGTH(mode), outf);

        /* and close random pool    */
        prng_end(rng);
    }
    else                    /* decryption operation     */
    {
        /* we need to know the file length to avoid reading the MAC */
        fseek(inf, 0, SEEK_END);
        flen = ftell(inf);
        fseek(inf, 0, SEEK_SET);
        mode &= 3;

        /* recover the password salt     */
        fread(salt, sizeof(unsigned char), SALT_LENGTH(mode), inf); flen -= SALT_LENGTH(mode);
#ifdef  PASSWORD_VERIFIER
        /* initialise encryption and authentication */
        fcrypt_init(mode, argv[1], (unsigned int)strlen(argv[1]), salt, tmp_buf2, zcx);
        /* recover the password verifier (if used)  */
        fread(tmp_buf1, sizeof(unsigned char), PWD_VER_LENGTH, inf); flen -= PWD_VER_LENGTH;
        /* check password verifier  */
        if(memcmp(tmp_buf1, tmp_buf2, PWD_VER_LENGTH))
        {
            err = ERROR_BAD_PASSWORD; fclose(outf); goto error_2;
        }
#else
        /* initialise encryption and authentication */
        fcrypt_init(mode, argv[1], (unsigned int)strlen(argv[1]), salt, zcx);
#endif

        flen -= MAC_LENGTH(mode);   /* avoid reading the MAC    */
        /* decrypt the file     */
        len = (int)fread(buf, sizeof(unsigned char),
                    (size_t)(flen < 1024 ? flen : 1024), inf);
        while(len)
        {   flen -= len;
            fcrypt_decrypt(buf, len, zcx);
            fwrite(buf, sizeof(unsigned char), len, outf);
            len = (int)fread(buf, sizeof(unsigned char),
                        (size_t)(flen < 1024 ? flen : 1024), inf);
        }

        /* calculate the MAC value          */
        fcrypt_end(tmp_buf2, zcx);

        /* now read the stored MAC value    */
        fread(tmp_buf1, sizeof(unsigned char), MAC_LENGTH(mode), inf);

        /* compare the stored and calculated MAC values */
        if(memcmp(tmp_buf1, tmp_buf2, MAC_LENGTH(mode)))
        {   /* authentication failed        */

            err = ERROR_BAD_AUTHENTICATION;
            fclose(outf);
            /* delete the (bad) output file */
            remove(fname);
            goto error_2;
        }
    }

    fclose(outf);
error_2:
    fclose(inf);
error_1:
    free(fname);
error_0:
    if(err)
        printf(err_string[err - 1], fname);
    return -err;
}
Пример #2
0
int fcrypt_end(unsigned char mac[], fcrypt_ctx cx[1])
{
    /*unsigned int res = cx->mode;*/

    hmac_sha_end(mac, MAC_LENGTH(cx->mode), cx->auth_ctx);
    memset(cx, 0, sizeof(fcrypt_ctx));	/* clear the encryption context	*/
    return MAC_LENGTH(res);		/* return MAC length in bytes   */
}