1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/evp/bio_ok.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/*
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	From: Arne Ansper <arne@cyber.ee>
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	Why BIO_f_reliable?
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	I wrote function which took BIO* as argument, read data from it
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	and processed it. Then I wanted to store the input file in
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	encrypted form. OK I pushed BIO_f_cipher to the BIO stack
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	and everything was OK. BUT if user types wrong password
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_f_cipher outputs only garbage and my function crashes. Yes
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	I can and I should fix my function, but BIO_f_cipher is
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	easy way to add encryption support to many existing applications
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	and it's hard to debug and fix them all.
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	So I wanted another BIO which would catch the incorrect passwords and
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	file damages which cause garbage on BIO_f_cipher's output.
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	The easy way is to push the BIO_f_md and save the checksum at
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	the end of the file. However there are several problems with this
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	approach:
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	1) you must somehow separate checksum from actual data.
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	2) you need lot's of memory when reading the file, because you
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	must read to the end of the file and verify the checksum before
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	letting the application to read the data.
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_f_reliable tries to solve both problems, so that you can
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	read and write arbitrary long streams using only fixed amount
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	of memory.
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_f_reliable splits data stream into blocks. Each block is prefixed
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	with it's length and suffixed with it's digest. So you need only
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	several Kbytes of memory to buffer single block before verifying
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	it's digest.
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_f_reliable goes further and adds several important capabilities:
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	1) the digest of the block is computed over the whole stream
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	-- so nobody can rearrange the blocks or remove or replace them.
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	2) to detect invalid passwords right at the start BIO_f_reliable
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	adds special prefix to the stream. In order to avoid known plain-text
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	attacks this prefix is generated as follows:
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*) digest is initialized with random seed instead of
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		standardized one.
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*) same seed is written to output
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*) well-known text is then hashed and the output
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		of the digest is also written to output.
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	reader can now read the seed from stream, hash the same string
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	and then compare the digest output.
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	Bad things: BIO_f_reliable knows what's going on in EVP_Digest. I
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	initially wrote and tested this code on x86 machine and wrote the
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	digests out in machine-dependent order :( There are people using
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	this code and I cannot change this easily without making existing
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	data files unreadable.
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project*/
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h>
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <errno.h>
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <assert.h>
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h"
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/buffer.h>
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/bio.h>
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/evp.h>
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/rand.h>
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ok_write(BIO *h, const char *buf, int num);
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ok_read(BIO *h, char *buf, int size);
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long ok_ctrl(BIO *h, int cmd, long arg1, void *arg2);
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ok_new(BIO *h);
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ok_free(BIO *data);
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long ok_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void sig_out(BIO* b);
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void sig_in(BIO* b);
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void block_out(BIO* b);
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void block_in(BIO* b);
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define OK_BLOCK_SIZE	(1024*4)
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define OK_BLOCK_BLOCK	4
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define IOBS		(OK_BLOCK_SIZE+ OK_BLOCK_BLOCK+ 3*EVP_MAX_MD_SIZE)
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define WELLKNOWN "The quick brown fox jumped over the lazy dog's back."
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct ok_struct
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	size_t buf_len;
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	size_t buf_off;
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	size_t buf_len_save;
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	size_t buf_off_save;
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int cont;		/* <= 0 when finished */
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int finished;
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_MD_CTX md;
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int blockout;		/* output block is ready */
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int sigio;		/* must process signature */
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char buf[IOBS];
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} BIO_OK_CTX;
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic BIO_METHOD methods_ok=
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_TYPE_CIPHER,"reliable",
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ok_write,
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ok_read,
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL, /* ok_puts, */
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL, /* ok_gets, */
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ok_ctrl,
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ok_new,
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ok_free,
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ok_callback_ctrl,
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	};
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIO_METHOD *BIO_f_reliable(void)
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(&methods_ok);
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ok_new(BIO *bi)
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_OK_CTX *ctx;
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx=(BIO_OK_CTX *)OPENSSL_malloc(sizeof(BIO_OK_CTX));
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ctx == NULL) return(0);
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->buf_len=0;
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->buf_off=0;
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->buf_len_save=0;
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->buf_off_save=0;
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->cont=1;
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->finished=0;
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->blockout= 0;
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->sigio=1;
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_MD_CTX_init(&ctx->md);
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bi->init=0;
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bi->ptr=(char *)ctx;
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bi->flags=0;
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(1);
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ok_free(BIO *a)
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (a == NULL) return(0);
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_MD_CTX_cleanup(&((BIO_OK_CTX *)a->ptr)->md);
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OPENSSL_cleanse(a->ptr,sizeof(BIO_OK_CTX));
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OPENSSL_free(a->ptr);
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	a->ptr=NULL;
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	a->init=0;
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	a->flags=0;
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(1);
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ok_read(BIO *b, char *out, int outl)
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret=0,i,n;
216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_OK_CTX *ctx;
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (out == NULL) return(0);
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx=(BIO_OK_CTX *)b->ptr;
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0)) return(0);
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while(outl > 0)
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* copy clean bytes to output buffer */
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ctx->blockout)
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			i=ctx->buf_len-ctx->buf_off;
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (i > outl) i=outl;
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			memcpy(out,&(ctx->buf[ctx->buf_off]),i);
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret+=i;
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			out+=i;
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			outl-=i;
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->buf_off+=i;
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* all clean bytes are out */
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (ctx->buf_len == ctx->buf_off)
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ctx->buf_off=0;
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				/* copy start of the next block into proper place */
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if(ctx->buf_len_save- ctx->buf_off_save > 0)
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					{
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					ctx->buf_len= ctx->buf_len_save- ctx->buf_off_save;
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					memmove(ctx->buf, &(ctx->buf[ctx->buf_off_save]),
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project							ctx->buf_len);
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					}
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				else
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					{
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					ctx->buf_len=0;
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					}
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ctx->blockout= 0;
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* output buffer full -- cancel */
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (outl == 0) break;
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* no clean bytes in buffer -- fill it */
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		n=IOBS- ctx->buf_len;
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		i=BIO_read(b->next_bio,&(ctx->buf[ctx->buf_len]),n);
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (i <= 0) break;	/* nothing new */
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->buf_len+= i;
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* no signature yet -- check if we got one */
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ctx->sigio == 1) sig_in(b);
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* signature ok -- check if we got block */
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ctx->sigio == 0) block_in(b);
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* invalid block -- cancel */
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ctx->cont <= 0) break;
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_clear_retry_flags(b);
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_copy_next_retry(b);
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ret);
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ok_write(BIO *b, const char *in, int inl)
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret=0,n,i;
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_OK_CTX *ctx;
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (inl <= 0) return inl;
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx=(BIO_OK_CTX *)b->ptr;
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret=inl;
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0)) return(0);
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ctx->sigio) sig_out(b);
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	do{
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_clear_retry_flags(b);
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		n=ctx->buf_len-ctx->buf_off;
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		while (ctx->blockout && n > 0)
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			i=BIO_write(b->next_bio,&(ctx->buf[ctx->buf_off]),n);
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (i <= 0)
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				BIO_copy_next_retry(b);
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if(!BIO_should_retry(b))
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					ctx->cont= 0;
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				return(i);
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->buf_off+=i;
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			n-=i;
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* at this point all pending data has been written */
316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->blockout= 0;
317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ctx->buf_len == ctx->buf_off)
318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->buf_len=OK_BLOCK_BLOCK;
320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->buf_off=0;
321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((in == NULL) || (inl <= 0)) return(0);
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		n= (inl+ ctx->buf_len > OK_BLOCK_SIZE+ OK_BLOCK_BLOCK) ?
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			(int)(OK_BLOCK_SIZE+OK_BLOCK_BLOCK-ctx->buf_len) : inl;
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		memcpy((unsigned char *)(&(ctx->buf[ctx->buf_len])),(unsigned char *)in,n);
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->buf_len+= n;
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		inl-=n;
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		in+=n;
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(ctx->buf_len >= OK_BLOCK_SIZE+ OK_BLOCK_BLOCK)
334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			block_out(b);
336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}while(inl > 0);
338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_clear_retry_flags(b);
340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_copy_next_retry(b);
341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ret);
342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long ok_ctrl(BIO *b, int cmd, long num, void *ptr)
345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_OK_CTX *ctx;
347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_MD *md;
348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const EVP_MD **ppmd;
349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	long ret=1;
350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i;
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx=b->ptr;
353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch (cmd)
355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_RESET:
357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->buf_len=0;
358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->buf_off=0;
359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->buf_len_save=0;
360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->buf_off_save=0;
361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->cont=1;
362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->finished=0;
363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->blockout= 0;
364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->sigio=1;
365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_EOF:	/* More to read */
368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ctx->cont <= 0)
369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=1;
370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_PENDING: /* More to read in buffer */
374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_WPENDING: /* More to read in buffer */
375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=ctx->blockout ? ctx->buf_len-ctx->buf_off : 0;
376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ret <= 0)
377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_FLUSH:
380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* do a final write */
381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(ctx->blockout == 0)
382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			block_out(b);
383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		while (ctx->blockout)
385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			i=ok_write(b,NULL,0);
387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (i < 0)
388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ret=i;
390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				break;
391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->finished=1;
395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->buf_off=ctx->buf_len=0;
396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->cont=(int)ret;
397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Finally flush the underlying BIO */
399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_DO_STATE_MACHINE:
402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_clear_retry_flags(b);
403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_copy_next_retry(b);
405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_INFO:
407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=(long)ctx->cont;
408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_SET_MD:
410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		md=ptr;
411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		EVP_DigestInit_ex(&ctx->md, md, NULL);
412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		b->init=1;
413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_GET_MD:
415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (b->init)
416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ppmd=ptr;
418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			*ppmd=ctx->md.digest;
419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret=0;
422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	default:
424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
425656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ret);
428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long ok_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
431656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	long ret=1;
433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b->next_bio == NULL) return(0);
435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch (cmd)
436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	default:
438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ret);
442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
444656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void longswap(void *_ptr, size_t len)
445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{	const union { long one; char little; } is_endian = {1};
446656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (is_endian.little) {
448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		size_t i;
449656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		unsigned char *p=_ptr,c;
450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
451656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		for(i= 0;i < len;i+= 4) {
452656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			c=p[0],p[0]=p[3],p[3]=c;
453656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			c=p[1],p[1]=p[2],p[2]=c;
454656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
455656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
456656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
457656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
458656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void sig_out(BIO* b)
459656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_OK_CTX *ctx;
461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_MD_CTX *md;
462656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx=b->ptr;
464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	md=&ctx->md;
465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ctx->buf_len+ 2* md->digest->md_size > OK_BLOCK_SIZE) return;
467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_DigestInit_ex(md, md->digest, NULL);
469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* FIXME: there's absolutely no guarantee this makes any sense at all,
470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * particularly now EVP_MD_CTX has been restructured.
471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 */
472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	RAND_pseudo_bytes(md->md_data, md->digest->md_size);
473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	memcpy(&(ctx->buf[ctx->buf_len]), md->md_data, md->digest->md_size);
474656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size);
475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->buf_len+= md->digest->md_size;
476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
477656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN));
478656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL);
479656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->buf_len+= md->digest->md_size;
480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->blockout= 1;
481656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->sigio= 0;
482656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
483656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
484656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void sig_in(BIO* b)
485656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
486656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_OK_CTX *ctx;
487656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_MD_CTX *md;
488656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char tmp[EVP_MAX_MD_SIZE];
489656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret= 0;
490656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx=b->ptr;
492656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	md=&ctx->md;
493656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
494656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((int)(ctx->buf_len-ctx->buf_off) < 2*md->digest->md_size) return;
495656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
496656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_DigestInit_ex(md, md->digest, NULL);
497656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	memcpy(md->md_data, &(ctx->buf[ctx->buf_off]), md->digest->md_size);
498656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	longswap(md->md_data, md->digest->md_size);
499656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->buf_off+= md->digest->md_size;
500656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
501656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN));
502656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_DigestFinal_ex(md, tmp, NULL);
503656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret= memcmp(&(ctx->buf[ctx->buf_off]), tmp, md->digest->md_size) == 0;
504656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->buf_off+= md->digest->md_size;
505656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ret == 1)
506656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
507656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->sigio= 0;
508656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(ctx->buf_len != ctx->buf_off)
509656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
510656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			memmove(ctx->buf, &(ctx->buf[ctx->buf_off]), ctx->buf_len- ctx->buf_off);
511656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
512656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->buf_len-= ctx->buf_off;
513656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->buf_off= 0;
514656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
515656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
516656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
517656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->cont= 0;
518656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
519656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
520656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
521656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void block_out(BIO* b)
522656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
523656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_OK_CTX *ctx;
524656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_MD_CTX *md;
525656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned long tl;
526656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
527656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx=b->ptr;
528656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	md=&ctx->md;
529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
530656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	tl= ctx->buf_len- OK_BLOCK_BLOCK;
531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->buf[0]=(unsigned char)(tl>>24);
532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->buf[1]=(unsigned char)(tl>>16);
533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->buf[2]=(unsigned char)(tl>>8);
534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->buf[3]=(unsigned char)(tl);
535656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_DigestUpdate(md, (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl);
536656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL);
537656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->buf_len+= md->digest->md_size;
538656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->blockout= 1;
539656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
540656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
541656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void block_in(BIO* b)
542656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
543656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_OK_CTX *ctx;
544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_MD_CTX *md;
545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned long tl= 0;
546656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char tmp[EVP_MAX_MD_SIZE];
547656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
548656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx=b->ptr;
549656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	md=&ctx->md;
550656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
551656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(sizeof(tl)>=OK_BLOCK_BLOCK);	/* always true */
552656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	tl =ctx->buf[0]; tl<<=8;
553656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	tl|=ctx->buf[1]; tl<<=8;
554656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	tl|=ctx->buf[2]; tl<<=8;
555656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	tl|=ctx->buf[3];
556656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
557656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ctx->buf_len < tl+ OK_BLOCK_BLOCK+ md->digest->md_size) return;
558656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
559656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_DigestUpdate(md, (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl);
560656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_DigestFinal_ex(md, tmp, NULL);
561656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(memcmp(&(ctx->buf[tl+ OK_BLOCK_BLOCK]), tmp, md->digest->md_size) == 0)
562656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
563656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* there might be parts from next block lurking around ! */
564656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->buf_off_save= tl+ OK_BLOCK_BLOCK+ md->digest->md_size;
565656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->buf_len_save= ctx->buf_len;
566656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->buf_off= OK_BLOCK_BLOCK;
567656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->buf_len= tl+ OK_BLOCK_BLOCK;
568656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->blockout= 1;
569656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
570656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
571656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
572656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->cont= 0;
573656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
574656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
575656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
576