2 * Copyright 1995-2021 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
10 #define OPENSSL_SUPPRESS_DEPRECATED /* for BIO_get_callback */
14 #include "internal/cryptlib.h"
15 #include <openssl/buffer.h>
16 #include <openssl/evp.h>
17 #include "internal/bio.h"
19 static int enc_write(BIO
*h
, const char *buf
, int num
);
20 static int enc_read(BIO
*h
, char *buf
, int size
);
21 static long enc_ctrl(BIO
*h
, int cmd
, long arg1
, void *arg2
);
22 static int enc_new(BIO
*h
);
23 static int enc_free(BIO
*data
);
24 static long enc_callback_ctrl(BIO
*h
, int cmd
, BIO_info_cb
*fps
);
25 #define ENC_BLOCK_SIZE (1024*4)
26 #define ENC_MIN_CHUNK (256)
27 #define BUF_OFFSET (ENC_MIN_CHUNK + EVP_MAX_BLOCK_LENGTH)
29 typedef struct enc_struct
{
32 int cont
; /* <= 0 when finished */
34 int ok
; /* bad decrypt */
35 EVP_CIPHER_CTX
*cipher
;
36 unsigned char *read_start
, *read_end
;
38 * buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate can return
39 * up to a block more data than is presented to it
41 unsigned char buf
[BUF_OFFSET
+ ENC_BLOCK_SIZE
];
44 static const BIO_METHOD methods_enc
= {
59 const BIO_METHOD
*BIO_f_cipher(void)
64 static int enc_new(BIO
*bi
)
68 if ((ctx
= OPENSSL_zalloc(sizeof(*ctx
))) == NULL
)
71 ctx
->cipher
= EVP_CIPHER_CTX_new();
72 if (ctx
->cipher
== NULL
) {
78 ctx
->read_end
= ctx
->read_start
= &(ctx
->buf
[BUF_OFFSET
]);
79 BIO_set_data(bi
, ctx
);
85 static int enc_free(BIO
*a
)
96 EVP_CIPHER_CTX_free(b
->cipher
);
97 OPENSSL_clear_free(b
, sizeof(BIO_ENC_CTX
));
98 BIO_set_data(a
, NULL
);
104 static int enc_read(BIO
*b
, char *out
, int outl
)
106 int ret
= 0, i
, blocksize
;
112 ctx
= BIO_get_data(b
);
115 if ((ctx
== NULL
) || (next
== NULL
))
118 /* First check if there are bytes decoded/encoded */
119 if (ctx
->buf_len
> 0) {
120 i
= ctx
->buf_len
- ctx
->buf_off
;
123 memcpy(out
, &(ctx
->buf
[ctx
->buf_off
]), i
);
128 if (ctx
->buf_len
== ctx
->buf_off
) {
134 blocksize
= EVP_CIPHER_CTX_get_block_size(ctx
->cipher
);
139 * At this point, we have room of outl bytes and an empty buffer, so we
140 * should read in some more.
147 if (ctx
->read_start
== ctx
->read_end
) { /* time to read more data */
148 ctx
->read_end
= ctx
->read_start
= &(ctx
->buf
[BUF_OFFSET
]);
149 i
= BIO_read(next
, ctx
->read_start
, ENC_BLOCK_SIZE
);
153 i
= ctx
->read_end
- ctx
->read_start
;
157 /* Should be continue next time we are called? */
158 if (!BIO_should_retry(next
)) {
160 i
= EVP_CipherFinal_ex(ctx
->cipher
,
161 ctx
->buf
, &(ctx
->buf_len
));
165 ret
= (ret
== 0) ? i
: ret
;
169 if (outl
> ENC_MIN_CHUNK
) {
171 * Depending on flags block cipher decrypt can write
172 * one extra block and then back off, i.e. output buffer
173 * has to accommodate extra block...
175 int j
= outl
- blocksize
, buf_len
;
177 if (!EVP_CipherUpdate(ctx
->cipher
,
178 (unsigned char *)out
, &buf_len
,
179 ctx
->read_start
, i
> j
? j
: i
)) {
180 BIO_clear_retry_flags(b
);
188 ctx
->read_start
= ctx
->read_end
;
191 ctx
->read_start
+= j
;
193 if (i
> ENC_MIN_CHUNK
)
195 if (!EVP_CipherUpdate(ctx
->cipher
,
196 ctx
->buf
, &ctx
->buf_len
,
197 ctx
->read_start
, i
)) {
198 BIO_clear_retry_flags(b
);
202 ctx
->read_start
+= i
;
205 * Note: it is possible for EVP_CipherUpdate to decrypt zero
206 * bytes because this is or looks like the final block: if this
207 * happens we should retry and either read more data or decrypt
210 if (ctx
->buf_len
== 0)
214 if (ctx
->buf_len
<= outl
)
220 memcpy(out
, ctx
->buf
, i
);
227 BIO_clear_retry_flags(b
);
228 BIO_copy_next_retry(b
);
229 return ((ret
== 0) ? ctx
->cont
: ret
);
232 static int enc_write(BIO
*b
, const char *in
, int inl
)
238 ctx
= BIO_get_data(b
);
240 if ((ctx
== NULL
) || (next
== NULL
))
245 BIO_clear_retry_flags(b
);
246 n
= ctx
->buf_len
- ctx
->buf_off
;
248 i
= BIO_write(next
, &(ctx
->buf
[ctx
->buf_off
]), n
);
250 BIO_copy_next_retry(b
);
256 /* at this point all pending data has been written */
258 if ((in
== NULL
) || (inl
<= 0))
263 n
= (inl
> ENC_BLOCK_SIZE
) ? ENC_BLOCK_SIZE
: inl
;
264 if (!EVP_CipherUpdate(ctx
->cipher
,
265 ctx
->buf
, &ctx
->buf_len
,
266 (const unsigned char *)in
, n
)) {
267 BIO_clear_retry_flags(b
);
277 i
= BIO_write(next
, &(ctx
->buf
[ctx
->buf_off
]), n
);
279 BIO_copy_next_retry(b
);
280 return (ret
== inl
) ? i
: ret
- inl
;
288 BIO_copy_next_retry(b
);
292 static long enc_ctrl(BIO
*b
, int cmd
, long num
, void *ptr
)
295 BIO_ENC_CTX
*ctx
, *dctx
;
298 EVP_CIPHER_CTX
**c_ctx
;
301 ctx
= BIO_get_data(b
);
310 if (!EVP_CipherInit_ex(ctx
->cipher
, NULL
, NULL
, NULL
, NULL
,
311 EVP_CIPHER_CTX_is_encrypting(ctx
->cipher
)))
313 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
315 case BIO_CTRL_EOF
: /* More to read */
319 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
321 case BIO_CTRL_WPENDING
:
322 ret
= ctx
->buf_len
- ctx
->buf_off
;
324 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
326 case BIO_CTRL_PENDING
: /* More to read in buffer */
327 ret
= ctx
->buf_len
- ctx
->buf_off
;
329 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
332 /* do a final write */
334 while (ctx
->buf_len
!= ctx
->buf_off
) {
335 i
= enc_write(b
, NULL
, 0);
340 if (!ctx
->finished
) {
343 ret
= EVP_CipherFinal_ex(ctx
->cipher
,
344 (unsigned char *)ctx
->buf
,
350 /* push out the bytes */
354 /* Finally flush the underlying BIO */
355 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
357 case BIO_C_GET_CIPHER_STATUS
:
360 case BIO_C_DO_STATE_MACHINE
:
361 BIO_clear_retry_flags(b
);
362 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
363 BIO_copy_next_retry(b
);
365 case BIO_C_GET_CIPHER_CTX
:
366 c_ctx
= (EVP_CIPHER_CTX
**)ptr
;
367 *c_ctx
= ctx
->cipher
;
372 dctx
= BIO_get_data(dbio
);
373 dctx
->cipher
= EVP_CIPHER_CTX_new();
374 if (dctx
->cipher
== NULL
)
376 ret
= EVP_CIPHER_CTX_copy(dctx
->cipher
, ctx
->cipher
);
378 BIO_set_init(dbio
, 1);
381 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
387 static long enc_callback_ctrl(BIO
*b
, int cmd
, BIO_info_cb
*fp
)
389 BIO
*next
= BIO_next(b
);
394 return BIO_callback_ctrl(next
, cmd
, fp
);
397 int BIO_set_cipher(BIO
*b
, const EVP_CIPHER
*c
, const unsigned char *k
,
398 const unsigned char *i
, int e
)
401 BIO_callback_fn_ex callback_ex
;
402 #ifndef OPENSSL_NO_DEPRECATED_3_0
403 long (*callback
) (struct bio_st
*, int, const char *, int, long, long) = NULL
;
406 ctx
= BIO_get_data(b
);
410 if ((callback_ex
= BIO_get_callback_ex(b
)) != NULL
) {
411 if (callback_ex(b
, BIO_CB_CTRL
, (const char *)c
, 0, BIO_CTRL_SET
,
415 #ifndef OPENSSL_NO_DEPRECATED_3_0
417 callback
= BIO_get_callback(b
);
419 if ((callback
!= NULL
) &&
420 (callback(b
, BIO_CB_CTRL
, (const char *)c
, BIO_CTRL_SET
, e
,
428 if (!EVP_CipherInit_ex(ctx
->cipher
, c
, NULL
, k
, i
, e
))
431 if (callback_ex
!= NULL
)
432 return callback_ex(b
, BIO_CB_CTRL
| BIO_CB_RETURN
, (const char *)c
, 0,
433 BIO_CTRL_SET
, e
, 1, NULL
);
434 #ifndef OPENSSL_NO_DEPRECATED_3_0
435 else if (callback
!= NULL
)
436 return callback(b
, BIO_CB_CTRL
, (const char *)c
, BIO_CTRL_SET
, e
, 1L);