2 * Copyright 1995-2024 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
);
143 * At this point, we have room of outl bytes and an empty buffer, so we
144 * should read in some more.
151 if (ctx
->read_start
== ctx
->read_end
) { /* time to read more data */
152 ctx
->read_end
= ctx
->read_start
= &(ctx
->buf
[BUF_OFFSET
]);
153 i
= BIO_read(next
, ctx
->read_start
, ENC_BLOCK_SIZE
);
157 i
= ctx
->read_end
- ctx
->read_start
;
161 /* Should be continue next time we are called? */
162 if (!BIO_should_retry(next
)) {
164 i
= EVP_CipherFinal_ex(ctx
->cipher
,
165 ctx
->buf
, &(ctx
->buf_len
));
169 ret
= (ret
== 0) ? i
: ret
;
173 if (outl
> ENC_MIN_CHUNK
) {
175 * Depending on flags block cipher decrypt can write
176 * one extra block and then back off, i.e. output buffer
177 * has to accommodate extra block...
179 int j
= outl
- blocksize
, buf_len
;
181 if (!EVP_CipherUpdate(ctx
->cipher
,
182 (unsigned char *)out
, &buf_len
,
183 ctx
->read_start
, i
> j
? j
: i
)) {
184 BIO_clear_retry_flags(b
);
192 ctx
->read_start
= ctx
->read_end
;
195 ctx
->read_start
+= j
;
197 if (i
> ENC_MIN_CHUNK
)
199 if (!EVP_CipherUpdate(ctx
->cipher
,
200 ctx
->buf
, &ctx
->buf_len
,
201 ctx
->read_start
, i
)) {
202 BIO_clear_retry_flags(b
);
206 ctx
->read_start
+= i
;
209 * Note: it is possible for EVP_CipherUpdate to decrypt zero
210 * bytes because this is or looks like the final block: if this
211 * happens we should retry and either read more data or decrypt
214 if (ctx
->buf_len
== 0)
218 if (ctx
->buf_len
<= outl
)
224 memcpy(out
, ctx
->buf
, i
);
231 BIO_clear_retry_flags(b
);
232 BIO_copy_next_retry(b
);
233 return ((ret
== 0) ? ctx
->cont
: ret
);
236 static int enc_write(BIO
*b
, const char *in
, int inl
)
242 ctx
= BIO_get_data(b
);
244 if ((ctx
== NULL
) || (next
== NULL
))
249 BIO_clear_retry_flags(b
);
250 n
= ctx
->buf_len
- ctx
->buf_off
;
252 i
= BIO_write(next
, &(ctx
->buf
[ctx
->buf_off
]), n
);
254 BIO_copy_next_retry(b
);
260 /* at this point all pending data has been written */
262 if ((in
== NULL
) || (inl
<= 0))
267 n
= (inl
> ENC_BLOCK_SIZE
) ? ENC_BLOCK_SIZE
: inl
;
268 if (!EVP_CipherUpdate(ctx
->cipher
,
269 ctx
->buf
, &ctx
->buf_len
,
270 (const unsigned char *)in
, n
)) {
271 BIO_clear_retry_flags(b
);
281 i
= BIO_write(next
, &(ctx
->buf
[ctx
->buf_off
]), n
);
283 BIO_copy_next_retry(b
);
284 return (ret
== inl
) ? i
: ret
- inl
;
292 BIO_copy_next_retry(b
);
296 static long enc_ctrl(BIO
*b
, int cmd
, long num
, void *ptr
)
299 BIO_ENC_CTX
*ctx
, *dctx
;
302 EVP_CIPHER_CTX
**c_ctx
;
306 ctx
= BIO_get_data(b
);
315 if (!EVP_CipherInit_ex(ctx
->cipher
, NULL
, NULL
, NULL
, NULL
,
316 EVP_CIPHER_CTX_is_encrypting(ctx
->cipher
)))
318 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
320 case BIO_CTRL_EOF
: /* More to read */
324 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
326 case BIO_CTRL_WPENDING
:
327 ret
= ctx
->buf_len
- ctx
->buf_off
;
329 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
331 case BIO_CTRL_PENDING
: /* More to read in buffer */
332 ret
= ctx
->buf_len
- ctx
->buf_off
;
334 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
337 /* do a final write */
339 while (ctx
->buf_len
!= ctx
->buf_off
) {
340 pend
= ctx
->buf_len
- ctx
->buf_off
;
341 i
= enc_write(b
, NULL
, 0);
343 * i should never be > 0 here because we didn't ask to write any
344 * new data. We stop if we get an error or we failed to make any
345 * progress writing pending data.
347 if (i
< 0 || (ctx
->buf_len
- ctx
->buf_off
) == pend
)
351 if (!ctx
->finished
) {
354 ret
= EVP_CipherFinal_ex(ctx
->cipher
,
355 (unsigned char *)ctx
->buf
,
361 /* push out the bytes */
365 /* Finally flush the underlying BIO */
366 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
367 BIO_copy_next_retry(b
);
369 case BIO_C_GET_CIPHER_STATUS
:
372 case BIO_C_DO_STATE_MACHINE
:
373 BIO_clear_retry_flags(b
);
374 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
375 BIO_copy_next_retry(b
);
377 case BIO_C_GET_CIPHER_CTX
:
378 c_ctx
= (EVP_CIPHER_CTX
**)ptr
;
379 *c_ctx
= ctx
->cipher
;
384 dctx
= BIO_get_data(dbio
);
385 dctx
->cipher
= EVP_CIPHER_CTX_new();
386 if (dctx
->cipher
== NULL
)
388 ret
= EVP_CIPHER_CTX_copy(dctx
->cipher
, ctx
->cipher
);
390 BIO_set_init(dbio
, 1);
393 ret
= BIO_ctrl(next
, cmd
, num
, ptr
);
399 static long enc_callback_ctrl(BIO
*b
, int cmd
, BIO_info_cb
*fp
)
401 BIO
*next
= BIO_next(b
);
406 return BIO_callback_ctrl(next
, cmd
, fp
);
409 int BIO_set_cipher(BIO
*b
, const EVP_CIPHER
*c
, const unsigned char *k
,
410 const unsigned char *i
, int e
)
413 BIO_callback_fn_ex callback_ex
;
414 #ifndef OPENSSL_NO_DEPRECATED_3_0
415 long (*callback
) (struct bio_st
*, int, const char *, int, long, long) = NULL
;
418 ctx
= BIO_get_data(b
);
422 if ((callback_ex
= BIO_get_callback_ex(b
)) != NULL
) {
423 if (callback_ex(b
, BIO_CB_CTRL
, (const char *)c
, 0, BIO_CTRL_SET
,
427 #ifndef OPENSSL_NO_DEPRECATED_3_0
429 callback
= BIO_get_callback(b
);
431 if ((callback
!= NULL
) &&
432 (callback(b
, BIO_CB_CTRL
, (const char *)c
, BIO_CTRL_SET
, e
,
440 if (!EVP_CipherInit_ex(ctx
->cipher
, c
, NULL
, k
, i
, e
))
443 if (callback_ex
!= NULL
)
444 return callback_ex(b
, BIO_CB_CTRL
| BIO_CB_RETURN
, (const char *)c
, 0,
445 BIO_CTRL_SET
, e
, 1, NULL
);
446 #ifndef OPENSSL_NO_DEPRECATED_3_0
447 else if (callback
!= NULL
)
448 return callback(b
, BIO_CB_CTRL
, (const char *)c
, BIO_CTRL_SET
, e
, 1L);