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