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); }
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; } }
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); }