1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/evp/bio_enc.c */
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * All rights reserved.
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This package is an SSL implementation written
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * by Eric Young (eay@cryptsoft.com).
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The implementation was written so as to conform with Netscapes SSL.
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This library is free for commercial and non-commercial use as long as
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the following conditions are aheared to.  The following conditions
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * apply to all code found in this distribution, be it the RC4, RSA,
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * included with this distribution is covered by the same copyright terms
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright remains Eric Young's, and as such any Copyright notices in
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the code are not to be removed.
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * If this package is used in a product, Eric Young should be given attribution
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * as the author of the parts of the library used.
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This can be in the form of a textual message at program startup or
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * in documentation (online or textual) provided with the package.
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the copyright
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    documentation and/or other materials provided with the distribution.
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this software
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    must display the following acknowledgement:
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes cryptographic software written by
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *     Eric Young (eay@cryptsoft.com)"
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    The word 'cryptographic' can be left out if the rouines from the library
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    being used are not cryptographic related :-).
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. If you include any Windows specific code (or a derivative thereof) from
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the apps directory (application code) you must include an acknowledgement:
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SUCH DAMAGE.
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The licence and distribution terms for any publically available version or
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * derivative of this code cannot be changed.  i.e. this code cannot simply be
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * copied and put under another distribution licence
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * [including the GNU Public Licence.]
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h>
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <errno.h>
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h"
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/buffer.h>
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/evp.h>
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int enc_write(BIO *h, const char *buf, int num);
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int enc_read(BIO *h, char *buf, int size);
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*static int enc_puts(BIO *h, const char *str); */
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*static int enc_gets(BIO *h, char *str, int size); */
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long enc_ctrl(BIO *h, int cmd, long arg1, void *arg2);
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int enc_new(BIO *h);
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int enc_free(BIO *data);
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long enc_callback_ctrl(BIO *h, int cmd, bio_info_cb *fps);
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define ENC_BLOCK_SIZE	(1024*4)
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define BUF_OFFSET	(EVP_MAX_BLOCK_LENGTH*2)
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct enc_struct
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int buf_len;
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int buf_off;
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int cont;		/* <= 0 when finished */
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int finished;
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ok;			/* bad decrypt */
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPHER_CTX cipher;
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * can return up to a block more data than is presented to it
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 */
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char buf[ENC_BLOCK_SIZE+BUF_OFFSET+2];
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} BIO_ENC_CTX;
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic BIO_METHOD methods_enc=
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_TYPE_CIPHER,"cipher",
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	enc_write,
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	enc_read,
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL, /* enc_puts, */
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL, /* enc_gets, */
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	enc_ctrl,
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	enc_new,
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	enc_free,
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	enc_callback_ctrl,
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	};
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIO_METHOD *BIO_f_cipher(void)
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(&methods_enc);
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int enc_new(BIO *bi)
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_ENC_CTX *ctx;
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx=(BIO_ENC_CTX *)OPENSSL_malloc(sizeof(BIO_ENC_CTX));
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ctx == NULL) return(0);
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPHER_CTX_init(&ctx->cipher);
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->buf_len=0;
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->buf_off=0;
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->cont=1;
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->finished=0;
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->ok=1;
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bi->init=0;
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bi->ptr=(char *)ctx;
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bi->flags=0;
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(1);
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int enc_free(BIO *a)
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_ENC_CTX *b;
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (a == NULL) return(0);
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b=(BIO_ENC_CTX *)a->ptr;
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPHER_CTX_cleanup(&(b->cipher));
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OPENSSL_cleanse(a->ptr,sizeof(BIO_ENC_CTX));
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OPENSSL_free(a->ptr);
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	a->ptr=NULL;
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	a->init=0;
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	a->flags=0;
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(1);
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int enc_read(BIO *b, char *out, int outl)
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret=0,i;
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_ENC_CTX *ctx;
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (out == NULL) return(0);
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx=(BIO_ENC_CTX *)b->ptr;
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* First check if there are bytes decoded/encoded */
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ctx->buf_len > 0)
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		i=ctx->buf_len-ctx->buf_off;
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (i > outl) i=outl;
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		memcpy(out,&(ctx->buf[ctx->buf_off]),i);
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=i;
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		out+=i;
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		outl-=i;
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->buf_off+=i;
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ctx->buf_len == ctx->buf_off)
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->buf_len=0;
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->buf_off=0;
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* At this point, we have room of outl bytes and an empty
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * buffer, so we should read in some more. */
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while (outl > 0)
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ctx->cont <= 0) break;
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* read in at IV offset, read the EVP_Cipher
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * documentation about why */
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		i=BIO_read(b->next_bio,&(ctx->buf[BUF_OFFSET]),ENC_BLOCK_SIZE);
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (i <= 0)
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* Should be continue next time we are called? */
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!BIO_should_retry(b->next_bio))
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ctx->cont=i;
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				i=EVP_CipherFinal_ex(&(ctx->cipher),
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					(unsigned char *)ctx->buf,
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					&(ctx->buf_len));
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ctx->ok=i;
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ctx->buf_off=0;
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ret=(ret == 0)?i:ret;
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				break;
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			EVP_CipherUpdate(&(ctx->cipher),
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				(unsigned char *)ctx->buf,&ctx->buf_len,
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				(unsigned char *)&(ctx->buf[BUF_OFFSET]),i);
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->cont=1;
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* Note: it is possible for EVP_CipherUpdate to
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * decrypt zero bytes because this is or looks like
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * the final block: if this happens we should retry
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * and either read more data or decrypt the final
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * block
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 */
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if(ctx->buf_len == 0) continue;
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ctx->buf_len <= outl)
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			i=ctx->buf_len;
216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			i=outl;
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (i <= 0) break;
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		memcpy(out,ctx->buf,i);
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret+=i;
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->buf_off=i;
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		outl-=i;
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		out+=i;
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_clear_retry_flags(b);
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_copy_next_retry(b);
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return((ret == 0)?ctx->cont:ret);
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int enc_write(BIO *b, const char *in, int inl)
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret=0,n,i;
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_ENC_CTX *ctx;
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx=(BIO_ENC_CTX *)b->ptr;
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret=inl;
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_clear_retry_flags(b);
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	n=ctx->buf_len-ctx->buf_off;
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while (n > 0)
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		i=BIO_write(b->next_bio,&(ctx->buf[ctx->buf_off]),n);
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (i <= 0)
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			BIO_copy_next_retry(b);
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return(i);
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->buf_off+=i;
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		n-=i;
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* at this point all pending data has been written */
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((in == NULL) || (inl <= 0)) return(0);
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->buf_off=0;
257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while (inl > 0)
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		n=(inl > ENC_BLOCK_SIZE)?ENC_BLOCK_SIZE:inl;
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		EVP_CipherUpdate(&(ctx->cipher),
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			(unsigned char *)ctx->buf,&ctx->buf_len,
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			(unsigned char *)in,n);
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		inl-=n;
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		in+=n;
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->buf_off=0;
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		n=ctx->buf_len;
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		while (n > 0)
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			i=BIO_write(b->next_bio,&(ctx->buf[ctx->buf_off]),n);
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (i <= 0)
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				BIO_copy_next_retry(b);
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				return (ret == inl) ? i : ret - inl;
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			n-=i;
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->buf_off+=i;
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->buf_len=0;
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->buf_off=0;
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_copy_next_retry(b);
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ret);
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long enc_ctrl(BIO *b, int cmd, long num, void *ptr)
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO *dbio;
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_ENC_CTX *ctx,*dctx;
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	long ret=1;
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i;
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPHER_CTX **c_ctx;
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx=(BIO_ENC_CTX *)b->ptr;
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch (cmd)
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_RESET:
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->ok=1;
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->finished=0;
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		EVP_CipherInit_ex(&(ctx->cipher),NULL,NULL,NULL,NULL,
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->cipher.encrypt);
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_EOF:	/* More to read */
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ctx->cont <= 0)
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=1;
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_WPENDING:
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=ctx->buf_len-ctx->buf_off;
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ret <= 0)
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_PENDING: /* More to read in buffer */
317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=ctx->buf_len-ctx->buf_off;
318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ret <= 0)
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_FLUSH:
322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* do a final write */
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectagain:
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		while (ctx->buf_len != ctx->buf_off)
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			i=enc_write(b,NULL,0);
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (i < 0)
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				return i;
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!ctx->finished)
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->finished=1;
334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->buf_off=0;
335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=EVP_CipherFinal_ex(&(ctx->cipher),
336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				(unsigned char *)ctx->buf,
337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				&(ctx->buf_len));
338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->ok=(int)ret;
339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (ret <= 0) break;
340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* push out the bytes */
342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto again;
343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Finally flush the underlying BIO */
346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_GET_CIPHER_STATUS:
349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=(long)ctx->ok;
350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_DO_STATE_MACHINE:
352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_clear_retry_flags(b);
353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_copy_next_retry(b);
355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_GET_CIPHER_CTX:
357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		c_ctx=(EVP_CIPHER_CTX **)ptr;
358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		(*c_ctx)= &(ctx->cipher);
359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		b->init=1;
360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_DUP:
362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dbio=(BIO *)ptr;
363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dctx=(BIO_ENC_CTX *)dbio->ptr;
364221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVP_CIPHER_CTX_init(&dctx->cipher);
365221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ret = EVP_CIPHER_CTX_copy(&dctx->cipher,&ctx->cipher);
366221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (ret)
367221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			dbio->init=1;
368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	default:
370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ret);
374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long enc_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	long ret=1;
379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b->next_bio == NULL) return(0);
381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch (cmd)
382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	default:
384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ret);
388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*
391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid BIO_set_cipher_ctx(b,c)
392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIO *b;
393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectEVP_CIPHER_ctx *c;
394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b == NULL) return;
396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((b->callback != NULL) &&
398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		(b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0))
399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return;
400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b->init=1;
402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx=(BIO_ENC_CTX *)b->ptr;
403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	memcpy(ctx->cipher,c,sizeof(EVP_CIPHER_CTX));
404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b->callback != NULL)
406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L);
407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project*/
409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	     const unsigned char *i, int e)
412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_ENC_CTX *ctx;
414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b == NULL) return;
416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((b->callback != NULL) &&
418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		(b->callback(b,BIO_CB_CTRL,(const char *)c,BIO_CTRL_SET,e,0L) <= 0))
419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return;
420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b->init=1;
422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx=(BIO_ENC_CTX *)b->ptr;
423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CipherInit_ex(&(ctx->cipher),c,NULL, k,i,e);
424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
425656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b->callback != NULL)
426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		b->callback(b,BIO_CB_CTRL,(const char *)c,BIO_CTRL_SET,e,1L);
427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
429