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
do_bio_comp_test(const BIO_METHOD * meth,size_t size)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
do_bio_comp(const BIO_METHOD * meth,int n)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
test_zstd(int n)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
test_brotli(int n)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
test_zlib(int n)137 static int test_zlib(int n)
138 {
139 return do_bio_comp(BIO_f_zlib(), n);
140 }
141 #endif
142
setup_tests(void)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