]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/evp/bio_enc.c
2 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
12 #include "internal/cryptlib.h"
13 #include <openssl/buffer.h>
14 #include <openssl/evp.h>
15 #include "internal/bio.h"
17 static int enc_write(BIO
*h
, const char *buf
, int num
);
18 static int enc_read(BIO
*h
, char *buf
, int size
);
19 static long enc_ctrl(BIO
*h
, int cmd
, long arg1
, void *arg2
);
20 static int enc_new(BIO
*h
);
21 static int enc_free(BIO
*data
);
22 static long enc_callback_ctrl(BIO
*h
, int cmd
, BIO_info_cb
*fps
);
23 #define ENC_BLOCK_SIZE (1024*4)
24 #define ENC_MIN_CHUNK (256)
25 #define BUF_OFFSET (ENC_MIN_CHUNK + EVP_MAX_BLOCK_LENGTH)
27 typedef struct enc_struct
{
30 int cont
; /* <= 0 when finished */
32 int ok
; /* bad decrypt */
33 EVP_CIPHER_CTX
*cipher
;
34 unsigned char *read_start
, *read_end
;
36 * buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate can return
37 * up to a block more data than is presented to it
39 unsigned char buf
[BUF_OFFSET
+ ENC_BLOCK_SIZE
];
42 static const BIO_METHOD methods_enc
= {
45 /* TODO: Convert to new style write function */
48 /* TODO: Convert to new style read function */
59 const BIO_METHOD
*BIO_f_cipher(void)
64 static int enc_new(BIO
*bi
)
68 if ((ctx
= OPENSSL_zalloc(sizeof(*ctx
))) == NULL
) {
69 EVPerr(EVP_F_ENC_NEW
, ERR_R_MALLOC_FAILURE
);
73 ctx
->cipher
= EVP_CIPHER_CTX_new();
74 if (ctx
->cipher
== NULL
) {
80 ctx
->read_end
= ctx
->read_start
= &(ctx
->buf
[BUF_OFFSET
]);
81 BIO_set_data(bi
, ctx
);
87 static int enc_free(BIO
*a
)
98 EVP_CIPHER_CTX_free(b
->cipher
);
99 OPENSSL_clear_free(b
, sizeof(BIO_ENC_CTX
));
100 BIO_set_data(a
, NULL
);
106 static int enc_read(BIO
*b
, char *out
, int outl
)
108 int ret
= 0, i
, blocksize
;
114 ctx
= BIO_get_data(b
);
117 if ((ctx
== NULL
) || (next
== NULL
))
120 /* First check if there are bytes decoded/encoded */
121 if (ctx
->buf_len
> 0) {
122 i
= ctx
->buf_len
- ctx
->buf_off
;
125 memcpy(out
, &(ctx
->buf
[ctx
->buf_off
]), i
);
130 if (ctx
->buf_len
== ctx
->buf_off
) {
136 blocksize
= EVP_CIPHER_CTX_block_size(ctx
->cipher
);
141 * At this point, we have room of outl bytes and an empty buffer, so we
142 * should read in some more.
149 if (ctx
->read_start
== ctx
->read_end
) { /* time to read more data */
150 ctx
->read_end
= ctx
->read_start
= &(ctx
->buf
[BUF_OFFSET
]);
151 i
= BIO_read(next
, ctx
->read_start
, ENC_BLOCK_SIZE
);
155 i
= ctx
->read_end
- ctx
->read_start
;
159 /* Should be continue next time we are called? */
160 if (!BIO_should_retry(next
)) {
162 i
= EVP_CipherFinal_ex(ctx
->cipher
,
163 ctx
->buf
, &(ctx
->buf_len
));
167 ret
= (ret
== 0) ? i
: ret
;
171 if (outl
> ENC_MIN_CHUNK
) {
173 * Depending on flags block cipher decrypt can write
174 * one extra block and then back off, i.e. output buffer
175 * has to accommodate extra block...
177 int j
= outl
- blocksize
, buf_len
;
179 if (!EVP_CipherUpdate(ctx
->cipher
,
180 (unsigned char *)out
, &buf_len
,
181 ctx
->read_start
, i
> j
? j
: i
)) {
182 BIO_clear_retry_flags(b
);
190 ctx
->read_start
= ctx
->read_end
;
193 ctx
->read_start
+= j
;
195 if (i
> ENC_MIN_CHUNK
)
197 if (!EVP_CipherUpdate(ctx
->cipher
,
198 ctx
->buf
, &ctx
->buf_len
,
199 ctx
->read_start
, i
)) {
200 BIO_clear_retry_flags(b
);
204 ctx
->read_start
+= i
;
207 * Note: it is possible for EVP_CipherUpdate to decrypt zero
208 * bytes because this is or looks like the final block: if this
209 * happens we should retry and either read more data or decrypt
212 if (ctx
->buf_len
== 0)
216 if (ctx
->buf_len
<= outl
)
222 memcpy(out
, ctx
->buf
, i
);
229 BIO_clear_retry_flags(b
);
230 BIO_copy_next_retry(b
);
231 return ((ret
== 0) ? ctx
->cont
: ret
);
234 static int enc_write(BIO
*b
, const char *in
, int inl
)
240 ctx
= BIO_get_data(b
);
242 if ((ctx
== NULL
) || (next
== NULL
))
247 BIO_clear_retry_flags(b
);
248 n
= ctx
->buf_len
- ctx
->buf_off
;
250 i
= BIO_write(next
, &(ctx
->buf
[ctx
->buf_off
]), n
);
252 BIO_copy_next_retry(b
);
258 /* at this point all pending data has been written */
260 if ((in
== NULL
) || (inl
<= 0))
265 n
= (inl
> ENC_BLOCK_SIZE
) ? ENC_BLOCK_SIZE
: inl
;
266 if (!EVP_CipherUpdate(ctx
->cipher
,
267 ctx
->buf
, &ctx
->buf_len
,
268 (const unsigned char *)in
, n
)) {
269 BIO_clear_retry_flags(b
);
279 i
= BIO_write(next
, &(ctx
->buf
[ctx
->buf_off
]), n
);
281 BIO_copy_next_retry(b
);
282 return (ret
== inl
) ? i
: ret
- inl
;
290 BIO_copy_next_retry(b
);
294 static long enc_ctrl(BIO
*b
, int cmd
, long num
, void *ptr
)
297 BIO_ENC_CTX
*ctx
, *dctx
;
300 EVP_CIPHER_CTX
**c_ctx
;
303 ctx
= BIO_get_data(b
);
312 if (!EVP_CipherInit_ex(ctx
->cipher
, NULL
, NULL
, NULL
, NULL
,
313 EVP_CIPHER_CTX_encrypting(ctx
->cipher
)))
315 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
317 case BIO_CTRL_EOF
: /* More to read */
321 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
323 case BIO_CTRL_WPENDING
:
324 ret
= ctx
->buf_len
- ctx
->buf_off
;
326 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
328 case BIO_CTRL_PENDING
: /* More to read in buffer */
329 ret
= ctx
->buf_len
- ctx
->buf_off
;
331 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
334 /* do a final write */
336 while (ctx
->buf_len
!= ctx
->buf_off
) {
337 i
= enc_write(b
, NULL
, 0);
342 if (!ctx
->finished
) {
345 ret
= EVP_CipherFinal_ex(ctx
->cipher
,
346 (unsigned char *)ctx
->buf
,
352 /* push out the bytes */
356 /* Finally flush the underlying BIO */
357 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
359 case BIO_C_GET_CIPHER_STATUS
:
362 case BIO_C_DO_STATE_MACHINE
:
363 BIO_clear_retry_flags(b
);
364 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
365 BIO_copy_next_retry(b
);
367 case BIO_C_GET_CIPHER_CTX
:
368 c_ctx
= (EVP_CIPHER_CTX
**)ptr
;
369 *c_ctx
= ctx
->cipher
;
374 dctx
= BIO_get_data(dbio
);
375 dctx
->cipher
= EVP_CIPHER_CTX_new();
376 if (dctx
->cipher
== NULL
)
378 ret
= EVP_CIPHER_CTX_copy(dctx
->cipher
, ctx
->cipher
);
380 BIO_set_init(dbio
, 1);
383 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
389 static long enc_callback_ctrl(BIO
*b
, int cmd
, BIO_info_cb
*fp
)
392 BIO
*next
= BIO_next(b
);
398 ret
= BIO_callback_ctrl(next
, cmd
, fp
);
404 int BIO_set_cipher(BIO
*b
, const EVP_CIPHER
*c
, const unsigned char *k
,
405 const unsigned char *i
, int e
)
408 long (*callback
) (struct bio_st
*, int, const char *, int, long, long);
410 ctx
= BIO_get_data(b
);
414 callback
= BIO_get_callback(b
);
416 if ((callback
!= NULL
) &&
417 (callback(b
, BIO_CB_CTRL
, (const char *)c
, BIO_CTRL_SET
, e
,
423 if (!EVP_CipherInit_ex(ctx
->cipher
, c
, NULL
, k
, i
, e
))
426 if (callback
!= NULL
)
427 return callback(b
, BIO_CB_CTRL
, (const char *)c
, BIO_CTRL_SET
, e
, 1L);