static int enc_free(BIO *data);
static long enc_callback_ctrl(BIO *h, int cmd, bio_info_cb *fps);
#define ENC_BLOCK_SIZE (1024*4)
-#define BUF_OFFSET 8 /* XXX: why? */
+#define BUF_OFFSET (EVP_MAX_BLOCK_LENGTH*2)
typedef struct enc_struct
{
int finished;
int ok; /* bad decrypt */
EVP_CIPHER_CTX cipher;
- char buf[ENC_BLOCK_SIZE+BUF_OFFSET+2/*why?*/];
+ /* buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate
+ * can return up to a block more data than is presented to it
+ */
+ char buf[ENC_BLOCK_SIZE+BUF_OFFSET+2];
} BIO_ENC_CTX;
static BIO_METHOD methods_enc=
BIO_ENC_CTX *ctx;
ctx=(BIO_ENC_CTX *)OPENSSL_malloc(sizeof(BIO_ENC_CTX));
- EVP_CIPHER_CTX_init(&ctx->cipher);
if (ctx == NULL) return(0);
+ EVP_CIPHER_CTX_init(&ctx->cipher);
ctx->buf_len=0;
ctx->buf_off=0;
if (a == NULL) return(0);
b=(BIO_ENC_CTX *)a->ptr;
EVP_CIPHER_CTX_cleanup(&(b->cipher));
- memset(a->ptr,0,sizeof(BIO_ENC_CTX));
+ OPENSSL_cleanse(a->ptr,sizeof(BIO_ENC_CTX));
OPENSSL_free(a->ptr);
a->ptr=NULL;
a->init=0;
{
if (ctx->cont <= 0) break;
- /* read in at offset 8, read the EVP_Cipher
+ /* read in at IV offset, read the EVP_Cipher
* documentation about why */
i=BIO_read(b->next_bio,&(ctx->buf[BUF_OFFSET]),ENC_BLOCK_SIZE);
if (!BIO_should_retry(b->next_bio))
{
ctx->cont=i;
- i=EVP_CipherFinal(&(ctx->cipher),
+ i=EVP_CipherFinal_ex(&(ctx->cipher),
(unsigned char *)ctx->buf,
&(ctx->buf_len));
ctx->ok=i;
if (i <= 0)
{
BIO_copy_next_retry(b);
- return(i);
+ return (ret == inl) ? i : ret - inl;
}
n-=i;
ctx->buf_off+=i;
case BIO_CTRL_RESET:
ctx->ok=1;
ctx->finished=0;
- EVP_CipherInit(&(ctx->cipher),NULL,NULL,NULL,
+ EVP_CipherInit_ex(&(ctx->cipher),NULL,NULL,NULL,NULL,
ctx->cipher.encrypt);
ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
break;
{
i=enc_write(b,NULL,0);
if (i < 0)
- {
- ret=i;
- break;
- }
+ return i;
}
if (!ctx->finished)
{
ctx->finished=1;
ctx->buf_off=0;
- ret=EVP_CipherFinal(&(ctx->cipher),
+ ret=EVP_CipherFinal_ex(&(ctx->cipher),
(unsigned char *)ctx->buf,
&(ctx->buf_len));
ctx->ok=(int)ret;
}
*/
-void BIO_set_cipher(BIO *b, const EVP_CIPHER *c, unsigned char *k,
- unsigned char *i, int e)
+void BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
+ const unsigned char *i, int e)
{
BIO_ENC_CTX *ctx;
b->init=1;
ctx=(BIO_ENC_CTX *)b->ptr;
- EVP_CipherInit(&(ctx->cipher),c,k,i,e);
+ EVP_CipherInit_ex(&(ctx->cipher),c,NULL, k,i,e);
if (b->callback != NULL)
b->callback(b,BIO_CB_CTRL,(const char *)c,BIO_CTRL_SET,e,1L);