xref: /freebsd/crypto/openssl/test/bio_enc_test.c (revision e0c4386e7e71d93b0edc0c8fa156263fc4a8b0b6)
1*e0c4386eSCy Schubert /*
2*e0c4386eSCy Schubert  * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
3*e0c4386eSCy Schubert  *
4*e0c4386eSCy Schubert  * Licensed under the Apache License 2.0 (the "License").  You may not use
5*e0c4386eSCy Schubert  * this file except in compliance with the License.  You can obtain a copy
6*e0c4386eSCy Schubert  * in the file LICENSE in the source distribution or at
7*e0c4386eSCy Schubert  * https://www.openssl.org/source/license.html
8*e0c4386eSCy Schubert  */
9*e0c4386eSCy Schubert #include <stdio.h>
10*e0c4386eSCy Schubert #include <string.h>
11*e0c4386eSCy Schubert #include <openssl/evp.h>
12*e0c4386eSCy Schubert #include <openssl/bio.h>
13*e0c4386eSCy Schubert #include <openssl/rand.h>
14*e0c4386eSCy Schubert 
15*e0c4386eSCy Schubert #include "testutil.h"
16*e0c4386eSCy Schubert 
17*e0c4386eSCy Schubert #define ENCRYPT  1
18*e0c4386eSCy Schubert #define DECRYPT  0
19*e0c4386eSCy Schubert 
20*e0c4386eSCy Schubert #define DATA_SIZE    1024
21*e0c4386eSCy Schubert #define MAX_IV       32
22*e0c4386eSCy Schubert #define BUF_SIZE     (DATA_SIZE + MAX_IV)
23*e0c4386eSCy Schubert 
24*e0c4386eSCy Schubert static const unsigned char KEY[] = {
25*e0c4386eSCy Schubert     0x51, 0x50, 0xd1, 0x77, 0x2f, 0x50, 0x83, 0x4a,
26*e0c4386eSCy Schubert     0x50, 0x3e, 0x06, 0x9a, 0x97, 0x3f, 0xbd, 0x7c,
27*e0c4386eSCy Schubert     0xe6, 0x1c, 0x43, 0x2b, 0x72, 0x0b, 0x19, 0xd1,
28*e0c4386eSCy Schubert     0x8e, 0xc8, 0xd8, 0x4b, 0xdc, 0x63, 0x15, 0x1b
29*e0c4386eSCy Schubert };
30*e0c4386eSCy Schubert 
31*e0c4386eSCy Schubert static const unsigned char IV[] = {
32*e0c4386eSCy Schubert     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
33*e0c4386eSCy Schubert     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
34*e0c4386eSCy Schubert     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
35*e0c4386eSCy Schubert     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
36*e0c4386eSCy Schubert };
37*e0c4386eSCy Schubert 
do_bio_cipher(const EVP_CIPHER * cipher,const unsigned char * key,const unsigned char * iv)38*e0c4386eSCy Schubert static int do_bio_cipher(const EVP_CIPHER* cipher, const unsigned char* key,
39*e0c4386eSCy Schubert     const unsigned char* iv)
40*e0c4386eSCy Schubert {
41*e0c4386eSCy Schubert     BIO *b, *mem;
42*e0c4386eSCy Schubert     static unsigned char inp[BUF_SIZE] = { 0 };
43*e0c4386eSCy Schubert     unsigned char out[BUF_SIZE], ref[BUF_SIZE];
44*e0c4386eSCy Schubert     int i, lref, len;
45*e0c4386eSCy Schubert 
46*e0c4386eSCy Schubert     /* Fill buffer with non-zero data so that over steps can be detected */
47*e0c4386eSCy Schubert     if (!TEST_int_gt(RAND_bytes(inp, DATA_SIZE), 0))
48*e0c4386eSCy Schubert         return 0;
49*e0c4386eSCy Schubert 
50*e0c4386eSCy Schubert     /* Encrypt tests */
51*e0c4386eSCy Schubert 
52*e0c4386eSCy Schubert     /* reference output for single-chunk operation */
53*e0c4386eSCy Schubert     b = BIO_new(BIO_f_cipher());
54*e0c4386eSCy Schubert     if (!TEST_ptr(b))
55*e0c4386eSCy Schubert         return 0;
56*e0c4386eSCy Schubert     if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, ENCRYPT)))
57*e0c4386eSCy Schubert         goto err;
58*e0c4386eSCy Schubert     mem = BIO_new_mem_buf(inp, DATA_SIZE);
59*e0c4386eSCy Schubert     if (!TEST_ptr(mem))
60*e0c4386eSCy Schubert         goto err;
61*e0c4386eSCy Schubert     BIO_push(b, mem);
62*e0c4386eSCy Schubert     lref = BIO_read(b, ref, sizeof(ref));
63*e0c4386eSCy Schubert     BIO_free_all(b);
64*e0c4386eSCy Schubert 
65*e0c4386eSCy Schubert     /* perform split operations and compare to reference */
66*e0c4386eSCy Schubert     for (i = 1; i < lref; i++) {
67*e0c4386eSCy Schubert         b = BIO_new(BIO_f_cipher());
68*e0c4386eSCy Schubert         if (!TEST_ptr(b))
69*e0c4386eSCy Schubert             return 0;
70*e0c4386eSCy Schubert         if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, ENCRYPT))) {
71*e0c4386eSCy Schubert             TEST_info("Split encrypt failed @ operation %d", i);
72*e0c4386eSCy Schubert             goto err;
73*e0c4386eSCy Schubert         }
74*e0c4386eSCy Schubert         mem = BIO_new_mem_buf(inp, DATA_SIZE);
75*e0c4386eSCy Schubert         if (!TEST_ptr(mem))
76*e0c4386eSCy Schubert             goto err;
77*e0c4386eSCy Schubert         BIO_push(b, mem);
78*e0c4386eSCy Schubert         memset(out, 0, sizeof(out));
79*e0c4386eSCy Schubert         out[i] = ~ref[i];
80*e0c4386eSCy Schubert         len = BIO_read(b, out, i);
81*e0c4386eSCy Schubert         /* check for overstep */
82*e0c4386eSCy Schubert         if (!TEST_uchar_eq(out[i], (unsigned char)~ref[i])) {
83*e0c4386eSCy Schubert             TEST_info("Encrypt overstep check failed @ operation %d", i);
84*e0c4386eSCy Schubert             goto err;
85*e0c4386eSCy Schubert         }
86*e0c4386eSCy Schubert         len += BIO_read(b, out + len, sizeof(out) - len);
87*e0c4386eSCy Schubert         BIO_free_all(b);
88*e0c4386eSCy Schubert 
89*e0c4386eSCy Schubert         if (!TEST_mem_eq(out, len, ref, lref)) {
90*e0c4386eSCy Schubert             TEST_info("Encrypt compare failed @ operation %d", i);
91*e0c4386eSCy Schubert             return 0;
92*e0c4386eSCy Schubert         }
93*e0c4386eSCy Schubert     }
94*e0c4386eSCy Schubert 
95*e0c4386eSCy Schubert     /* perform small-chunk operations and compare to reference */
96*e0c4386eSCy Schubert     for (i = 1; i < lref / 2; i++) {
97*e0c4386eSCy Schubert         int delta;
98*e0c4386eSCy Schubert 
99*e0c4386eSCy Schubert         b = BIO_new(BIO_f_cipher());
100*e0c4386eSCy Schubert         if (!TEST_ptr(b))
101*e0c4386eSCy Schubert             return 0;
102*e0c4386eSCy Schubert         if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, ENCRYPT))) {
103*e0c4386eSCy Schubert             TEST_info("Small chunk encrypt failed @ operation %d", i);
104*e0c4386eSCy Schubert             goto err;
105*e0c4386eSCy Schubert         }
106*e0c4386eSCy Schubert         mem = BIO_new_mem_buf(inp, DATA_SIZE);
107*e0c4386eSCy Schubert         if (!TEST_ptr(mem))
108*e0c4386eSCy Schubert             goto err;
109*e0c4386eSCy Schubert         BIO_push(b, mem);
110*e0c4386eSCy Schubert         memset(out, 0, sizeof(out));
111*e0c4386eSCy Schubert         for (len = 0; (delta = BIO_read(b, out + len, i)); ) {
112*e0c4386eSCy Schubert             len += delta;
113*e0c4386eSCy Schubert         }
114*e0c4386eSCy Schubert         BIO_free_all(b);
115*e0c4386eSCy Schubert 
116*e0c4386eSCy Schubert         if (!TEST_mem_eq(out, len, ref, lref)) {
117*e0c4386eSCy Schubert             TEST_info("Small chunk encrypt compare failed @ operation %d", i);
118*e0c4386eSCy Schubert             return 0;
119*e0c4386eSCy Schubert         }
120*e0c4386eSCy Schubert     }
121*e0c4386eSCy Schubert 
122*e0c4386eSCy Schubert     /* Decrypt tests */
123*e0c4386eSCy Schubert 
124*e0c4386eSCy Schubert     /* reference output for single-chunk operation */
125*e0c4386eSCy Schubert     b = BIO_new(BIO_f_cipher());
126*e0c4386eSCy Schubert     if (!TEST_ptr(b))
127*e0c4386eSCy Schubert         return 0;
128*e0c4386eSCy Schubert     if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, DECRYPT)))
129*e0c4386eSCy Schubert         goto err;
130*e0c4386eSCy Schubert     /* Use original reference output as input */
131*e0c4386eSCy Schubert     mem = BIO_new_mem_buf(ref, lref);
132*e0c4386eSCy Schubert     if (!TEST_ptr(mem))
133*e0c4386eSCy Schubert         goto err;
134*e0c4386eSCy Schubert     BIO_push(b, mem);
135*e0c4386eSCy Schubert     (void)BIO_flush(b);
136*e0c4386eSCy Schubert     memset(out, 0, sizeof(out));
137*e0c4386eSCy Schubert     len = BIO_read(b, out, sizeof(out));
138*e0c4386eSCy Schubert     BIO_free_all(b);
139*e0c4386eSCy Schubert 
140*e0c4386eSCy Schubert     if (!TEST_mem_eq(inp, DATA_SIZE, out, len))
141*e0c4386eSCy Schubert         return 0;
142*e0c4386eSCy Schubert 
143*e0c4386eSCy Schubert     /* perform split operations and compare to reference */
144*e0c4386eSCy Schubert     for (i = 1; i < lref; i++) {
145*e0c4386eSCy Schubert         b = BIO_new(BIO_f_cipher());
146*e0c4386eSCy Schubert         if (!TEST_ptr(b))
147*e0c4386eSCy Schubert             return 0;
148*e0c4386eSCy Schubert         if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, DECRYPT))) {
149*e0c4386eSCy Schubert             TEST_info("Split decrypt failed @ operation %d", i);
150*e0c4386eSCy Schubert             goto err;
151*e0c4386eSCy Schubert         }
152*e0c4386eSCy Schubert         mem = BIO_new_mem_buf(ref, lref);
153*e0c4386eSCy Schubert         if (!TEST_ptr(mem))
154*e0c4386eSCy Schubert             goto err;
155*e0c4386eSCy Schubert         BIO_push(b, mem);
156*e0c4386eSCy Schubert         memset(out, 0, sizeof(out));
157*e0c4386eSCy Schubert         out[i] = ~ref[i];
158*e0c4386eSCy Schubert         len = BIO_read(b, out, i);
159*e0c4386eSCy Schubert         /* check for overstep */
160*e0c4386eSCy Schubert         if (!TEST_uchar_eq(out[i], (unsigned char)~ref[i])) {
161*e0c4386eSCy Schubert             TEST_info("Decrypt overstep check failed @ operation %d", i);
162*e0c4386eSCy Schubert             goto err;
163*e0c4386eSCy Schubert         }
164*e0c4386eSCy Schubert         len += BIO_read(b, out + len, sizeof(out) - len);
165*e0c4386eSCy Schubert         BIO_free_all(b);
166*e0c4386eSCy Schubert 
167*e0c4386eSCy Schubert         if (!TEST_mem_eq(inp, DATA_SIZE, out, len)) {
168*e0c4386eSCy Schubert             TEST_info("Decrypt compare failed @ operation %d", i);
169*e0c4386eSCy Schubert             return 0;
170*e0c4386eSCy Schubert         }
171*e0c4386eSCy Schubert     }
172*e0c4386eSCy Schubert 
173*e0c4386eSCy Schubert     /* perform small-chunk operations and compare to reference */
174*e0c4386eSCy Schubert     for (i = 1; i < lref / 2; i++) {
175*e0c4386eSCy Schubert         int delta;
176*e0c4386eSCy Schubert 
177*e0c4386eSCy Schubert         b = BIO_new(BIO_f_cipher());
178*e0c4386eSCy Schubert         if (!TEST_ptr(b))
179*e0c4386eSCy Schubert             return 0;
180*e0c4386eSCy Schubert         if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, DECRYPT))) {
181*e0c4386eSCy Schubert             TEST_info("Small chunk decrypt failed @ operation %d", i);
182*e0c4386eSCy Schubert             goto err;
183*e0c4386eSCy Schubert         }
184*e0c4386eSCy Schubert         mem = BIO_new_mem_buf(ref, lref);
185*e0c4386eSCy Schubert         if (!TEST_ptr(mem))
186*e0c4386eSCy Schubert             goto err;
187*e0c4386eSCy Schubert         BIO_push(b, mem);
188*e0c4386eSCy Schubert         memset(out, 0, sizeof(out));
189*e0c4386eSCy Schubert         for (len = 0; (delta = BIO_read(b, out + len, i)); ) {
190*e0c4386eSCy Schubert             len += delta;
191*e0c4386eSCy Schubert         }
192*e0c4386eSCy Schubert         BIO_free_all(b);
193*e0c4386eSCy Schubert 
194*e0c4386eSCy Schubert         if (!TEST_mem_eq(inp, DATA_SIZE, out, len)) {
195*e0c4386eSCy Schubert             TEST_info("Small chunk decrypt compare failed @ operation %d", i);
196*e0c4386eSCy Schubert             return 0;
197*e0c4386eSCy Schubert         }
198*e0c4386eSCy Schubert     }
199*e0c4386eSCy Schubert 
200*e0c4386eSCy Schubert     return 1;
201*e0c4386eSCy Schubert 
202*e0c4386eSCy Schubert err:
203*e0c4386eSCy Schubert     BIO_free_all(b);
204*e0c4386eSCy Schubert     return 0;
205*e0c4386eSCy Schubert }
206*e0c4386eSCy Schubert 
do_test_bio_cipher(const EVP_CIPHER * cipher,int idx)207*e0c4386eSCy Schubert static int do_test_bio_cipher(const EVP_CIPHER* cipher, int idx)
208*e0c4386eSCy Schubert {
209*e0c4386eSCy Schubert     switch(idx)
210*e0c4386eSCy Schubert     {
211*e0c4386eSCy Schubert         case 0:
212*e0c4386eSCy Schubert             return do_bio_cipher(cipher, KEY, NULL);
213*e0c4386eSCy Schubert         case 1:
214*e0c4386eSCy Schubert             return do_bio_cipher(cipher, KEY, IV);
215*e0c4386eSCy Schubert     }
216*e0c4386eSCy Schubert     return 0;
217*e0c4386eSCy Schubert }
218*e0c4386eSCy Schubert 
test_bio_enc_aes_128_cbc(int idx)219*e0c4386eSCy Schubert static int test_bio_enc_aes_128_cbc(int idx)
220*e0c4386eSCy Schubert {
221*e0c4386eSCy Schubert     return do_test_bio_cipher(EVP_aes_128_cbc(), idx);
222*e0c4386eSCy Schubert }
223*e0c4386eSCy Schubert 
test_bio_enc_aes_128_ctr(int idx)224*e0c4386eSCy Schubert static int test_bio_enc_aes_128_ctr(int idx)
225*e0c4386eSCy Schubert {
226*e0c4386eSCy Schubert     return do_test_bio_cipher(EVP_aes_128_ctr(), idx);
227*e0c4386eSCy Schubert }
228*e0c4386eSCy Schubert 
test_bio_enc_aes_256_cfb(int idx)229*e0c4386eSCy Schubert static int test_bio_enc_aes_256_cfb(int idx)
230*e0c4386eSCy Schubert {
231*e0c4386eSCy Schubert     return do_test_bio_cipher(EVP_aes_256_cfb(), idx);
232*e0c4386eSCy Schubert }
233*e0c4386eSCy Schubert 
test_bio_enc_aes_256_ofb(int idx)234*e0c4386eSCy Schubert static int test_bio_enc_aes_256_ofb(int idx)
235*e0c4386eSCy Schubert {
236*e0c4386eSCy Schubert     return do_test_bio_cipher(EVP_aes_256_ofb(), idx);
237*e0c4386eSCy Schubert }
238*e0c4386eSCy Schubert 
239*e0c4386eSCy Schubert # ifndef OPENSSL_NO_CHACHA
test_bio_enc_chacha20(int idx)240*e0c4386eSCy Schubert static int test_bio_enc_chacha20(int idx)
241*e0c4386eSCy Schubert {
242*e0c4386eSCy Schubert     return do_test_bio_cipher(EVP_chacha20(), idx);
243*e0c4386eSCy Schubert }
244*e0c4386eSCy Schubert 
245*e0c4386eSCy Schubert #  ifndef OPENSSL_NO_POLY1305
test_bio_enc_chacha20_poly1305(int idx)246*e0c4386eSCy Schubert static int test_bio_enc_chacha20_poly1305(int idx)
247*e0c4386eSCy Schubert {
248*e0c4386eSCy Schubert     return do_test_bio_cipher(EVP_chacha20_poly1305(), idx);
249*e0c4386eSCy Schubert }
250*e0c4386eSCy Schubert #  endif
251*e0c4386eSCy Schubert # endif
252*e0c4386eSCy Schubert 
setup_tests(void)253*e0c4386eSCy Schubert int setup_tests(void)
254*e0c4386eSCy Schubert {
255*e0c4386eSCy Schubert     ADD_ALL_TESTS(test_bio_enc_aes_128_cbc, 2);
256*e0c4386eSCy Schubert     ADD_ALL_TESTS(test_bio_enc_aes_128_ctr, 2);
257*e0c4386eSCy Schubert     ADD_ALL_TESTS(test_bio_enc_aes_256_cfb, 2);
258*e0c4386eSCy Schubert     ADD_ALL_TESTS(test_bio_enc_aes_256_ofb, 2);
259*e0c4386eSCy Schubert # ifndef OPENSSL_NO_CHACHA
260*e0c4386eSCy Schubert     ADD_ALL_TESTS(test_bio_enc_chacha20, 2);
261*e0c4386eSCy Schubert #  ifndef OPENSSL_NO_POLY1305
262*e0c4386eSCy Schubert     ADD_ALL_TESTS(test_bio_enc_chacha20_poly1305, 2);
263*e0c4386eSCy Schubert #  endif
264*e0c4386eSCy Schubert # endif
265*e0c4386eSCy Schubert     return 1;
266*e0c4386eSCy Schubert }
267