1 /*
2 * Copyright 2022 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 if (!TEST_ptr(original = OPENSSL_malloc(BUFFER_SIZE))
87 || !TEST_ptr(result = OPENSSL_malloc(BUFFER_SIZE)))
88 goto err;
89
90 switch (type) {
91 case 0:
92 TEST_info("zeros of size %d\n", size);
93 memset(original, 0, BUFFER_SIZE);
94 break;
95 case 1:
96 TEST_info("ones of size %d\n", size);
97 memset(original, 1, BUFFER_SIZE);
98 break;
99 case 2:
100 TEST_info("sequential of size %d\n", size);
101 for (i = 0; i < BUFFER_SIZE; i++)
102 original[i] = i & 0xFF;
103 break;
104 case 3:
105 TEST_info("random of size %d\n", size);
106 if (!TEST_int_gt(RAND_bytes(original, BUFFER_SIZE), 0))
107 goto err;
108 break;
109 default:
110 goto err;
111 }
112
113 if (!TEST_true(do_bio_comp_test(meth, size)))
114 goto err;
115 success = 1;
116 err:
117 OPENSSL_free(original);
118 OPENSSL_free(result);
119 return success;
120 }
121
122 #ifndef OPENSSL_NO_ZSTD
test_zstd(int n)123 static int test_zstd(int n)
124 {
125 return do_bio_comp(BIO_f_zstd(), n);
126 }
127 #endif
128 #ifndef OPENSSL_NO_BROTLI
test_brotli(int n)129 static int test_brotli(int n)
130 {
131 return do_bio_comp(BIO_f_brotli(), n);
132 }
133 #endif
134 #ifndef OPENSSL_NO_ZLIB
test_zlib(int n)135 static int test_zlib(int n)
136 {
137 return do_bio_comp(BIO_f_zlib(), n);
138 }
139 #endif
140
setup_tests(void)141 int setup_tests(void)
142 {
143 #ifndef OPENSSL_NO_ZLIB
144 ADD_ALL_TESTS(test_zlib, NUM_SIZES * 4);
145 #endif
146 #ifndef OPENSSL_NO_BROTLI
147 ADD_ALL_TESTS(test_brotli, NUM_SIZES * 4);
148 #endif
149 #ifndef OPENSSL_NO_ZSTD
150 ADD_ALL_TESTS(test_zstd, NUM_SIZES * 4);
151 #endif
152 return 1;
153 }
154