1 /* 2 * Copyright 2022-2025 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 #include <stdio.h> 10 #include <string.h> 11 #include <openssl/evp.h> 12 #include <openssl/bio.h> 13 #include <openssl/rand.h> 14 #include <openssl/comp.h> 15 16 #include "testutil.h" 17 #include "testutil/output.h" 18 #include "testutil/tu_local.h" 19 20 #define COMPRESS 1 21 #define EXPAND 0 22 23 #define BUFFER_SIZE 32 * 1024 24 #define NUM_SIZES 4 25 static int sizes[NUM_SIZES] = { 64, 512, 2048, 16 * 1024 }; 26 27 /* using global buffers */ 28 static unsigned char *original = NULL; 29 static unsigned char *result = NULL; 30 31 /* 32 * For compression: 33 * the write operation compresses 34 * the read operation decompresses 35 */ 36 37 static int do_bio_comp_test(const BIO_METHOD *meth, size_t size) 38 { 39 BIO *bcomp = NULL; 40 BIO *bmem = NULL; 41 BIO *bexp = NULL; 42 int osize; 43 int rsize; 44 int ret = 0; 45 46 /* Compress */ 47 if (!TEST_ptr(meth)) 48 goto err; 49 if (!TEST_ptr(bcomp = BIO_new(meth))) 50 goto err; 51 if (!TEST_ptr(bmem = BIO_new(BIO_s_mem()))) 52 goto err; 53 BIO_push(bcomp, bmem); 54 osize = BIO_write(bcomp, original, size); 55 if (!TEST_int_eq(osize, size) 56 || !TEST_true(BIO_flush(bcomp))) 57 goto err; 58 BIO_free(bcomp); 59 bcomp = NULL; 60 61 /* decompress */ 62 if (!TEST_ptr(bexp = BIO_new(meth))) 63 goto err; 64 BIO_push(bexp, bmem); 65 rsize = BIO_read(bexp, result, size); 66 67 if (!TEST_int_eq(size, rsize) 68 || !TEST_mem_eq(original, osize, result, rsize)) 69 goto err; 70 71 ret = 1; 72 err: 73 BIO_free(bexp); 74 BIO_free(bcomp); 75 BIO_free(bmem); 76 return ret; 77 } 78 79 static int do_bio_comp(const BIO_METHOD *meth, int n) 80 { 81 int i; 82 int success = 0; 83 int size = sizes[n % 4]; 84 int type = n / 4; 85 86 original = OPENSSL_malloc(BUFFER_SIZE); 87 result = OPENSSL_malloc(BUFFER_SIZE); 88 89 if (!TEST_ptr(original) || !TEST_ptr(result)) 90 goto err; 91 92 switch (type) { 93 case 0: 94 TEST_info("zeros of size %d\n", size); 95 memset(original, 0, BUFFER_SIZE); 96 break; 97 case 1: 98 TEST_info("ones of size %d\n", size); 99 memset(original, 1, BUFFER_SIZE); 100 break; 101 case 2: 102 TEST_info("sequential of size %d\n", size); 103 for (i = 0; i < BUFFER_SIZE; i++) 104 original[i] = i & 0xFF; 105 break; 106 case 3: 107 TEST_info("random of size %d\n", size); 108 if (!TEST_int_gt(RAND_bytes(original, BUFFER_SIZE), 0)) 109 goto err; 110 break; 111 default: 112 goto err; 113 } 114 115 if (!TEST_true(do_bio_comp_test(meth, size))) 116 goto err; 117 success = 1; 118 err: 119 OPENSSL_free(original); 120 OPENSSL_free(result); 121 return success; 122 } 123 124 #ifndef OPENSSL_NO_ZSTD 125 static int test_zstd(int n) 126 { 127 return do_bio_comp(BIO_f_zstd(), n); 128 } 129 #endif 130 #ifndef OPENSSL_NO_BROTLI 131 static int test_brotli(int n) 132 { 133 return do_bio_comp(BIO_f_brotli(), n); 134 } 135 #endif 136 #ifndef OPENSSL_NO_ZLIB 137 static int test_zlib(int n) 138 { 139 return do_bio_comp(BIO_f_zlib(), n); 140 } 141 #endif 142 143 int setup_tests(void) 144 { 145 #ifndef OPENSSL_NO_ZLIB 146 ADD_ALL_TESTS(test_zlib, NUM_SIZES * 4); 147 #endif 148 #ifndef OPENSSL_NO_BROTLI 149 ADD_ALL_TESTS(test_brotli, NUM_SIZES * 4); 150 #endif 151 #ifndef OPENSSL_NO_ZSTD 152 ADD_ALL_TESTS(test_zstd, NUM_SIZES * 4); 153 #endif 154 return 1; 155 } 156