1/* 2 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 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 8 */ 9 10#define OPENSSL_SUPPRESS_DEPRECATED /* for BIO_get_callback */ 11 12#include <stdio.h> 13#include <errno.h> 14#include "internal/cryptlib.h" 15#include <openssl/buffer.h> 16#include <openssl/evp.h> 17#include "internal/bio.h" 18 19static int enc_write(BIO *h, const char *buf, int num); 20static int enc_read(BIO *h, char *buf, int size); 21static long enc_ctrl(BIO *h, int cmd, long arg1, void *arg2); 22static int enc_new(BIO *h); 23static int enc_free(BIO *data); 24static 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) 28 29typedef struct enc_struct { 30 int buf_len; 31 int buf_off; 32 int cont; /* <= 0 when finished */ 33 int finished; 34 int ok; /* bad decrypt */ 35 EVP_CIPHER_CTX *cipher; 36 unsigned char *read_start, *read_end; 37 /* 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 40 */ 41 unsigned char buf[BUF_OFFSET + ENC_BLOCK_SIZE]; 42} BIO_ENC_CTX; 43 44static const BIO_METHOD methods_enc = { 45 BIO_TYPE_CIPHER, 46 "cipher", 47 bwrite_conv, 48 enc_write, 49 bread_conv, 50 enc_read, 51 NULL, /* enc_puts, */ 52 NULL, /* enc_gets, */ 53 enc_ctrl, 54 enc_new, 55 enc_free, 56 enc_callback_ctrl, 57}; 58 59const BIO_METHOD *BIO_f_cipher(void) 60{ 61 return &methods_enc; 62} 63 64static int enc_new(BIO *bi) 65{ 66 BIO_ENC_CTX *ctx; 67 68 if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { 69 ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); 70 return 0; 71 } 72 73 ctx->cipher = EVP_CIPHER_CTX_new(); 74 if (ctx->cipher == NULL) { 75 OPENSSL_free(ctx); 76 return 0; 77 } 78 ctx->cont = 1; 79 ctx->ok = 1; 80 ctx->read_end = ctx->read_start = &(ctx->buf[BUF_OFFSET]); 81 BIO_set_data(bi, ctx); 82 BIO_set_init(bi, 1); 83 84 return 1; 85} 86 87static int enc_free(BIO *a) 88{ 89 BIO_ENC_CTX *b; 90 91 if (a == NULL) 92 return 0; 93 94 b = BIO_get_data(a); 95 if (b == NULL) 96 return 0; 97 98 EVP_CIPHER_CTX_free(b->cipher); 99 OPENSSL_clear_free(b, sizeof(BIO_ENC_CTX)); 100 BIO_set_data(a, NULL); 101 BIO_set_init(a, 0); 102 103 return 1; 104} 105 106static int enc_read(BIO *b, char *out, int outl) 107{ 108 int ret = 0, i, blocksize; 109 BIO_ENC_CTX *ctx; 110 BIO *next; 111 112 if (out == NULL) 113 return 0; 114 ctx = BIO_get_data(b); 115 116 next = BIO_next(b); 117 if ((ctx == NULL) || (next == NULL)) 118 return 0; 119 120 /* First check if there are bytes decoded/encoded */ 121 if (ctx->buf_len > 0) { 122 i = ctx->buf_len - ctx->buf_off; 123 if (i > outl) 124 i = outl; 125 memcpy(out, &(ctx->buf[ctx->buf_off]), i); 126 ret = i; 127 out += i; 128 outl -= i; 129 ctx->buf_off += i; 130 if (ctx->buf_len == ctx->buf_off) { 131 ctx->buf_len = 0; 132 ctx->buf_off = 0; 133 } 134 } 135 136 blocksize = EVP_CIPHER_CTX_get_block_size(ctx->cipher); 137 if (blocksize == 1) 138 blocksize = 0; 139 140 /* 141 * At this point, we have room of outl bytes and an empty buffer, so we 142 * should read in some more. 143 */ 144 145 while (outl > 0) { 146 if (ctx->cont <= 0) 147 break; 148 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); 152 if (i > 0) 153 ctx->read_end += i; 154 } else { 155 i = ctx->read_end - ctx->read_start; 156 } 157 158 if (i <= 0) { 159 /* Should be continue next time we are called? */ 160 if (!BIO_should_retry(next)) { 161 ctx->cont = i; 162 i = EVP_CipherFinal_ex(ctx->cipher, 163 ctx->buf, &(ctx->buf_len)); 164 ctx->ok = i; 165 ctx->buf_off = 0; 166 } else { 167 ret = (ret == 0) ? i : ret; 168 break; 169 } 170 } else { 171 if (outl > ENC_MIN_CHUNK) { 172 /* 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... 176 */ 177 int j = outl - blocksize, buf_len; 178 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); 183 return 0; 184 } 185 ret += buf_len; 186 out += buf_len; 187 outl -= buf_len; 188 189 if ((i -= j) <= 0) { 190 ctx->read_start = ctx->read_end; 191 continue; 192 } 193 ctx->read_start += j; 194 } 195 if (i > ENC_MIN_CHUNK) 196 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); 201 ctx->ok = 0; 202 return 0; 203 } 204 ctx->read_start += i; 205 ctx->cont = 1; 206 /* 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 210 * the final block 211 */ 212 if (ctx->buf_len == 0) 213 continue; 214 } 215 216 if (ctx->buf_len <= outl) 217 i = ctx->buf_len; 218 else 219 i = outl; 220 if (i <= 0) 221 break; 222 memcpy(out, ctx->buf, i); 223 ret += i; 224 ctx->buf_off = i; 225 outl -= i; 226 out += i; 227 } 228 229 BIO_clear_retry_flags(b); 230 BIO_copy_next_retry(b); 231 return ((ret == 0) ? ctx->cont : ret); 232} 233 234static int enc_write(BIO *b, const char *in, int inl) 235{ 236 int ret = 0, n, i; 237 BIO_ENC_CTX *ctx; 238 BIO *next; 239 240 ctx = BIO_get_data(b); 241 next = BIO_next(b); 242 if ((ctx == NULL) || (next == NULL)) 243 return 0; 244 245 ret = inl; 246 247 BIO_clear_retry_flags(b); 248 n = ctx->buf_len - ctx->buf_off; 249 while (n > 0) { 250 i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n); 251 if (i <= 0) { 252 BIO_copy_next_retry(b); 253 return i; 254 } 255 ctx->buf_off += i; 256 n -= i; 257 } 258 /* at this point all pending data has been written */ 259 260 if ((in == NULL) || (inl <= 0)) 261 return 0; 262 263 ctx->buf_off = 0; 264 while (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); 270 ctx->ok = 0; 271 return 0; 272 } 273 inl -= n; 274 in += n; 275 276 ctx->buf_off = 0; 277 n = ctx->buf_len; 278 while (n > 0) { 279 i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n); 280 if (i <= 0) { 281 BIO_copy_next_retry(b); 282 return (ret == inl) ? i : ret - inl; 283 } 284 n -= i; 285 ctx->buf_off += i; 286 } 287 ctx->buf_len = 0; 288 ctx->buf_off = 0; 289 } 290 BIO_copy_next_retry(b); 291 return ret; 292} 293 294static long enc_ctrl(BIO *b, int cmd, long num, void *ptr) 295{ 296 BIO *dbio; 297 BIO_ENC_CTX *ctx, *dctx; 298 long ret = 1; 299 int i; 300 EVP_CIPHER_CTX **c_ctx; 301 BIO *next; 302 int pend; 303 304 ctx = BIO_get_data(b); 305 next = BIO_next(b); 306 if (ctx == NULL) 307 return 0; 308 309 switch (cmd) { 310 case BIO_CTRL_RESET: 311 ctx->ok = 1; 312 ctx->finished = 0; 313 if (!EVP_CipherInit_ex(ctx->cipher, NULL, NULL, NULL, NULL, 314 EVP_CIPHER_CTX_is_encrypting(ctx->cipher))) 315 return 0; 316 ret = BIO_ctrl(next, cmd, num, ptr); 317 break; 318 case BIO_CTRL_EOF: /* More to read */ 319 if (ctx->cont <= 0) 320 ret = 1; 321 else 322 ret = BIO_ctrl(next, cmd, num, ptr); 323 break; 324 case BIO_CTRL_WPENDING: 325 ret = ctx->buf_len - ctx->buf_off; 326 if (ret <= 0) 327 ret = BIO_ctrl(next, cmd, num, ptr); 328 break; 329 case BIO_CTRL_PENDING: /* More to read in buffer */ 330 ret = ctx->buf_len - ctx->buf_off; 331 if (ret <= 0) 332 ret = BIO_ctrl(next, cmd, num, ptr); 333 break; 334 case BIO_CTRL_FLUSH: 335 /* do a final write */ 336 again: 337 while (ctx->buf_len != ctx->buf_off) { 338 pend = ctx->buf_len - ctx->buf_off; 339 i = enc_write(b, NULL, 0); 340 /* 341 * i should never be > 0 here because we didn't ask to write any 342 * new data. We stop if we get an error or we failed to make any 343 * progress writing pending data. 344 */ 345 if (i < 0 || (ctx->buf_len - ctx->buf_off) == pend) 346 return i; 347 } 348 349 if (!ctx->finished) { 350 ctx->finished = 1; 351 ctx->buf_off = 0; 352 ret = EVP_CipherFinal_ex(ctx->cipher, 353 (unsigned char *)ctx->buf, 354 &(ctx->buf_len)); 355 ctx->ok = (int)ret; 356 if (ret <= 0) 357 break; 358 359 /* push out the bytes */ 360 goto again; 361 } 362 363 /* Finally flush the underlying BIO */ 364 ret = BIO_ctrl(next, cmd, num, ptr); 365 break; 366 case BIO_C_GET_CIPHER_STATUS: 367 ret = (long)ctx->ok; 368 break; 369 case BIO_C_DO_STATE_MACHINE: 370 BIO_clear_retry_flags(b); 371 ret = BIO_ctrl(next, cmd, num, ptr); 372 BIO_copy_next_retry(b); 373 break; 374 case BIO_C_GET_CIPHER_CTX: 375 c_ctx = (EVP_CIPHER_CTX **)ptr; 376 *c_ctx = ctx->cipher; 377 BIO_set_init(b, 1); 378 break; 379 case BIO_CTRL_DUP: 380 dbio = (BIO *)ptr; 381 dctx = BIO_get_data(dbio); 382 dctx->cipher = EVP_CIPHER_CTX_new(); 383 if (dctx->cipher == NULL) 384 return 0; 385 ret = EVP_CIPHER_CTX_copy(dctx->cipher, ctx->cipher); 386 if (ret) 387 BIO_set_init(dbio, 1); 388 break; 389 default: 390 ret = BIO_ctrl(next, cmd, num, ptr); 391 break; 392 } 393 return ret; 394} 395 396static long enc_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) 397{ 398 BIO *next = BIO_next(b); 399 400 if (next == NULL) 401 return 0; 402 403 return BIO_callback_ctrl(next, cmd, fp); 404} 405 406int BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k, 407 const unsigned char *i, int e) 408{ 409 BIO_ENC_CTX *ctx; 410 BIO_callback_fn_ex callback_ex; 411#ifndef OPENSSL_NO_DEPRECATED_3_0 412 long (*callback) (struct bio_st *, int, const char *, int, long, long) = NULL; 413#endif 414 415 ctx = BIO_get_data(b); 416 if (ctx == NULL) 417 return 0; 418 419 if ((callback_ex = BIO_get_callback_ex(b)) != NULL) { 420 if (callback_ex(b, BIO_CB_CTRL, (const char *)c, 0, BIO_CTRL_SET, 421 e, 1, NULL) <= 0) 422 return 0; 423 } 424#ifndef OPENSSL_NO_DEPRECATED_3_0 425 else { 426 callback = BIO_get_callback(b); 427 428 if ((callback != NULL) && 429 (callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 430 0L) <= 0)) 431 return 0; 432 } 433#endif 434 435 BIO_set_init(b, 1); 436 437 if (!EVP_CipherInit_ex(ctx->cipher, c, NULL, k, i, e)) 438 return 0; 439 440 if (callback_ex != NULL) 441 return callback_ex(b, BIO_CB_CTRL | BIO_CB_RETURN, (const char *)c, 0, 442 BIO_CTRL_SET, e, 1, NULL); 443#ifndef OPENSSL_NO_DEPRECATED_3_0 444 else if (callback != NULL) 445 return callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 1L); 446#endif 447 return 1; 448} 449