blob: 2f0df4a0ab40229eb42a0db8e1c24073c388b6f8 [file] [log] [blame]
/*
* Copyright 2003-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <axis2_util.h>
#include <oxs_buffer.h>
#include <oxs_error.h>
#include <openssl_cipher_ctx.h>
#include <openssl_crypt.h>
#include <openssl/rand.h>
#define BUFSIZE 64
/**
* @param do_encrypt should be set to 1 for encryption, 0 for decryption and -1 to
* leave the value unchanged
*/
AXIS2_EXTERN int AXIS2_CALL openssl_block_cipher_crypt(const axis2_env_t *env,
openssl_cipher_ctx_t *oc_ctx,
unsigned char *in_main_buf,
int in_main_len,
unsigned char **out_main_buf,
int do_encrypt)
{
EVP_CIPHER_CTX ctx ;
unsigned char inbuf[BUFSIZE + 1 ], outbuf[BUFSIZE + EVP_MAX_BLOCK_LENGTH]; /*EVP_MAX_BLOCK_LENGTH = 32 in evp.h*/
unsigned char *tempbuf = NULL;
unsigned char *tempbuf2 = NULL;
int inlen, outlen, i, out_buf_index;
int ret;
i = 0;
out_buf_index = 0;
/*Init ctx*/
EVP_CIPHER_CTX_init(&ctx);
ret = EVP_CipherInit_ex(&ctx, (EVP_CIPHER *)OPENSSL_CIPHER_CTX_GET_CIPHER(oc_ctx, env), NULL, NULL, NULL, do_encrypt);
ret = EVP_CipherInit_ex(&ctx, NULL, NULL, (unsigned char*)OPENSSL_CIPHER_CTX_GET_KEY(oc_ctx, env),
(unsigned char*)OPENSSL_CIPHER_CTX_GET_IV(oc_ctx, env),
do_encrypt);
for (;;)
{
memset(inbuf, 0 , BUFSIZE);/*Reset memory for the inbuf*/
memcpy(inbuf, in_main_buf + (i * BUFSIZE) , BUFSIZE);/*Copy the first block to the inbuf*/
if (in_main_len <= i*BUFSIZE) break; /*Finish!!! */
/*If we are in the last block, set inlen according to the in_main_len */
if (in_main_len <= (i + 1)*BUFSIZE)
{
inlen = in_main_len - (i * BUFSIZE);
}
else
{
inlen = BUFSIZE;
}
if (do_encrypt == 1)
{
printf("\nEncrypting block[%d] %s", inlen, inbuf);
}
memset(outbuf, 0 , BUFSIZE + EVP_MAX_BLOCK_LENGTH);/*Reset memory for the outbuf*/
if (!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen))
{
/* Error */
oxs_error(ERROR_LOCATION, OXS_ERROR_OPENSSL_FUNC_FAILED,
"Encryption failed");
EVP_CIPHER_CTX_cleanup(&ctx);
return (-1);
}
/*TODO: Write the encrypted block to the tempbuf*/
tempbuf2 = malloc(out_buf_index + outlen);
if (i > 0)
{/*Skip for the i=0 step*/
memcpy(tempbuf2, tempbuf, out_buf_index);
/*free tempbuf*/
free(tempbuf);
}
memcpy(tempbuf2 + out_buf_index, outbuf, outlen);
tempbuf = tempbuf2; /*Assign new tempbuf2 to the old one*/
out_buf_index = out_buf_index + outlen;/*Update the writing position of the tempbuf*/
i++;
}/*End of for loop*/
ret = EVP_CipherFinal_ex(&ctx, outbuf, &outlen);
if (!ret)
{
/* Error */
EVP_CIPHER_CTX_cleanup(&ctx);
printf("\nERROR:EVP_CipherFinal_ex--- EVP_CIPHER_CTX_cleanup");
return (-1);
}
/*Alright now we need to write the last drop*/
tempbuf2 = malloc(out_buf_index + outlen);
memcpy(tempbuf2, tempbuf, out_buf_index);
/*free tempbuf*/
free(tempbuf);
memcpy(tempbuf2 + out_buf_index, outbuf, outlen);
tempbuf = tempbuf2; /*Assign new tempbuf2 to the old one*/
out_buf_index = out_buf_index + outlen;/*Update the writing position of the tempbuf*/
EVP_CIPHER_CTX_cleanup(&ctx);
/*Assign the temp buf to the out_main_buf*/
*out_main_buf = tempbuf;
free(tempbuf2);
return out_buf_index;
}