예제 #1
0
unsigned char *rncryptorc_decrypt_data_with_password(const unsigned char *indata,
        int indata_len,
        int kdf_iter,
        const char *password,
        int password_length,
        int *outdata_len,
        char *errbuf,
        int errbuf_len)
{
    MutilsBlob
        *blob = NULL;

    RNCryptorInfo
        *ci = NULL;

    int
        rc,
        outlen1=0,
        outlen2=0;

    EVP_CIPHER_CTX
        cipher_ctx;

    unsigned char
        *outdata = NULL;

    if (errbuf_len <= 0)
    {
        log_err("ERROR:Invalid errbuf len %d",errbuf_len);
        goto ExitProcessing;
    }

    if (indata == NULL)
    {
        (void)snprintf(errbuf,errbuf_len-1,"%s",
                "Input data is NULL");
        goto ExitProcessing;
    }
    if (password == NULL || *password == '\0')
    {
        (void)snprintf(errbuf,errbuf_len-1,"%s",
                "Password is NULL");
        goto ExitProcessing;
    }
    if (password_length <= 0)
    {
        (void)snprintf(errbuf,errbuf_len-1,
                "Invalid password length %d",password_length);
        goto ExitProcessing;
    }

    *outdata_len = 0;

    /* convert input data to our blob */
    blob = mutils_data_to_blob((unsigned char *)indata,indata_len);
    CHECK_MALLOC(blob);

    /* decode */
    log_debug("%s:%d - Decoding ..",MCFL);
    ci = decode_encrypted_blob(blob);
    if (!ci)
    {
        goto ExitProcessing;
    }
    ci->options = 0x01;

    rc = verify_rncryptor_format(ci->version,ci->options);
    if (rc != SUCCESS)
    {
        (void)snprintf(errbuf,errbuf_len-1,"%s",
                "Unknown RNCryptor Data Format");
        goto ExitProcessing;
    }
    log_debug("%s:%d - Decoded version 0x%02x options 0x%02x",
            MCFL,
            ci->version,
            ci->options);

    log_debug("%s:%d - Verifying HMAC-SHA256 digest",MCFL);
    /* very hmac */
    if (verify_hmac(ci,password,password_length) != SUCCESS)
    {
        (void)snprintf(errbuf,errbuf_len-1,"%s",
                "Could not verify HMAC");
        goto ExitProcessing;
    }
    log_debug("%s:%d - HMAC verified",MCFL);

    /* Derive cipher key from password using encr salt and iteration as per RFC2898 */
    log_debug("%s:%d - Deriving Cipher key with salt, iteration %d",
            MCFL,
            kdf_iter);
    rc = PKCS5_PBKDF2_HMAC_SHA1(password,password_length,
            ci->encryption_salt,
            sizeof(ci->encryption_salt),
            ci->kdf_iter,
            sizeof(ci->encr_key),
            ci->encr_key); /* ci->encr_key is returend */
    if (rc != 1)
    {
        log_err("ERROR: Could not derive key from password with encr salt and iter");
        goto ExitProcessing;
    }
    log_debug("%s:%d - Encryption key derived",MCFL);

    /* decrypt */
    outdata = (unsigned char *)malloc(ci->cipher_text_length *sizeof(unsigned char));
    CHECK_MALLOC(outdata);

    log_debug("%s:%d - Decrypting..",MCFL);
    EVP_DecryptInit(&cipher_ctx,EVP_aes_256_cbc(),ci->encr_key,ci->iv);
    EVP_DecryptUpdate(&cipher_ctx,outdata,&outlen1,ci->cipher_text,
            ci->cipher_text_length);
    EVP_DecryptFinal(&cipher_ctx,outdata + outlen1,&outlen2);
    EVP_CIPHER_CTX_cleanup(&cipher_ctx);

    *outdata_len = outlen1 + outlen2;
    log_debug("%s:%d - Done decrypting, output length %d bytes",MCFL,*outdata_len);
ExitProcessing:
    if (ci)
    {
        free_rncryptor_info(ci);
    }
    if (blob)
    {
        mutils_destroy_blob(blob);
    }

    return(outdata);
}
예제 #2
0
static zip_int64_t
winzip_aes_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
{
    struct winzip_aes *ctx;
    zip_int64_t n;
    zip_uint64_t total, offset;

    ctx = (struct winzip_aes *)ud;

    switch (cmd) {
    case ZIP_SOURCE_OPEN:
	if (decrypt_header(src, ctx) < 0) {
	    return -1;
	}
	ctx->current_position = 0;
	return 0;

    case ZIP_SOURCE_READ:
	if (len > ctx->data_length - ctx->current_position) {
	    len = ctx->data_length - ctx->current_position;
	}

	if (len == 0) {
	    if (!verify_hmac(src, ctx)) {
		return -1;
	    }
	    return 0;
	}
	
	if ((n=zip_source_read(src, data, len)) < 0) {
	    _zip_error_set_from_source(&ctx->error, src);
	    return -1;
	}
	ctx->current_position += n;

	total = (zip_uint64_t)n;
	for (offset = 0; offset < total; offset += ZIP_MIN(total - offset, UINT_MAX)) {
	    _zip_fcrypt_decrypt(data + offset, ZIP_MIN(total - offset, UINT_MAX), &ctx->fcrypt_ctx);
	}

	return n;

    case ZIP_SOURCE_CLOSE:
	return 0;

    case ZIP_SOURCE_STAT:
    {
	zip_stat_t *st;

	st = (zip_stat_t *)data;

	st->encryption_method = ZIP_EM_NONE;
	st->valid |= ZIP_STAT_ENCRYPTION_METHOD;
	if (st->valid & ZIP_STAT_COMP_SIZE) {
	    st->comp_size -= 12 + salt_length[ctx->mode];
	}
	
	return 0;
    }
            
    case ZIP_SOURCE_SUPPORTS:
	return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, -1);

    case ZIP_SOURCE_ERROR:
	return zip_error_to_data(&ctx->error, data, len);

    case ZIP_SOURCE_FREE:
	winzip_aes_free(ctx);
	return 0;

    default:
	zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
	return -1;
    }
}
예제 #3
0
unsigned char *rncryptorc_decrypt_data_with_key(const unsigned char *indata,
        int indata_len,
        int kdf_iter,
        const unsigned char *encr_key,
        const unsigned char *hmac_key,
        int *outdata_len,
        char *errbuf,
        int errbuf_len)
{
    MutilsBlob
        *blob = NULL;

    RNCryptorInfo
        *ci = NULL;

    int
        outlen1=0,
        outlen2=0;

    EVP_CIPHER_CTX
        cipher_ctx;

    unsigned char
        *outdata = NULL;

    if (errbuf_len <= 0)
    {
        log_err("ERROR:Invalid errbuf len %d",errbuf_len);
        goto ExitProcessing;
    }

    memset(errbuf,0,errbuf_len);

    if (indata == NULL)
    {
        (void)snprintf(errbuf,errbuf_len-1,"%s",
                "input data is NULL");
        goto ExitProcessing;
    }
    if (encr_key == NULL)
    {
        (void)snprintf(errbuf,errbuf_len-1,"%s",
                "Encryption key is NULL");
        goto ExitProcessing;
    }
    if (hmac_key == NULL)
    {
        (void)snprintf(errbuf,errbuf_len-1,"%s",
                "HMAC key is NULL");
        goto ExitProcessing;
    }

    *outdata_len = 0;

    /* convert input data to our blob */
    blob = mutils_data_to_blob((unsigned char *)indata,indata_len);
    CHECK_MALLOC(blob);

    /* decode */
    ci = decode_encrypted_blob(blob);
    if (!ci)
    {
        goto ExitProcessing;
    }
    log_debug("Decoded successfully");

    /*
    ** copy the keys to our data structure, this way we don't have
    ** to change code for decryptiion
    */
    memcpy(ci->encr_key,encr_key,32);
    memcpy(ci->hmac_key,hmac_key,32);
    /*
    ** pass password as NULL and length of password as 0 because we don't
    ** have to derive HMAC key
    */
    if (verify_hmac(ci,NULL,0) != SUCCESS)
    {
        (void)snprintf(errbuf,errbuf_len-1,"%s",
                "Could not verify HMAC");
        goto ExitProcessing;
    }
    log_debug("HMAC verified");


    /* malloc for returned data */
    outdata = (unsigned char *)malloc(ci->cipher_text_length *sizeof(unsigned char));
    CHECK_MALLOC(outdata);

    /* decrypt */
    EVP_DecryptInit(&cipher_ctx,EVP_aes_256_cbc(),ci->encr_key,ci->iv);
    EVP_DecryptUpdate(&cipher_ctx,outdata,&outlen1,ci->cipher_text,
            ci->cipher_text_length);
    EVP_DecryptFinal(&cipher_ctx,outdata + outlen1,&outlen2);
    EVP_CIPHER_CTX_cleanup(&cipher_ctx);

    *outdata_len = outlen1 + outlen2;

ExitProcessing:
    if (ci)
    {
        free_rncryptor_info(ci);
    }
    if (blob)
    {
        mutils_destroy_blob(blob);
    }

    return(outdata);
}