2 * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
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
11 #include <openssl/evp.h>
12 #include <openssl/bio.h>
13 #include <openssl/rand.h>
15 #include "test_main.h"
21 #define DATA_SIZE 1024
23 #define BUF_SIZE (DATA_SIZE + MAX_IV)
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
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
39 static int do_bio_cipher(const EVP_CIPHER* cipher, const unsigned char* key,
40 const unsigned char* iv)
43 static unsigned char inp[BUF_SIZE] = { 0 };
44 unsigned char out[BUF_SIZE], ref[BUF_SIZE];
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))
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)))
57 BIO_push(b, BIO_new_mem_buf(inp, DATA_SIZE));
58 lref = BIO_read(b, ref, sizeof(ref));
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);
68 BIO_push(b, BIO_new_mem_buf(inp, DATA_SIZE));
69 memset(out, 0, sizeof(out));
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);
77 len += BIO_read(b, out + len, sizeof(out) - len);
80 if (!TEST_mem_eq(out, len, ref, lref)) {
81 TEST_info("Encrypt compare failed @ operation %d", i);
86 /* perform small-chunk operations and compare to reference */
87 for (i = 1; i < lref / 2; i++) {
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);
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)); ) {
102 if (!TEST_mem_eq(out, len, ref, lref)) {
103 TEST_info("Small chunk encrypt compare failed @ operation %d", i);
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)))
114 /* Use original reference output as input */
115 BIO_push(b, BIO_new_mem_buf(ref, lref));
117 memset(out, 0, sizeof(out));
118 len = BIO_read(b, out, sizeof(out));
121 if (!TEST_mem_eq(inp, DATA_SIZE, out, len))
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);
131 BIO_push(b, BIO_new_mem_buf(ref, lref));
132 memset(out, 0, sizeof(out));
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);
140 len += BIO_read(b, out + len, sizeof(out) - len);
143 if (!TEST_mem_eq(inp, DATA_SIZE, out, len)) {
144 TEST_info("Decrypt compare failed @ operation %d", i);
149 /* perform small-chunk operations and compare to reference */
150 for (i = 1; i < lref / 2; i++) {
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);
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)); ) {
165 if (!TEST_mem_eq(inp, DATA_SIZE, out, len)) {
166 TEST_info("Small chunk decrypt compare failed @ operation %d", i);
174 static int do_test_bio_cipher(const EVP_CIPHER* cipher, int idx)
179 return do_bio_cipher(cipher, KEY, NULL);
181 return do_bio_cipher(cipher, KEY, IV);
186 static int test_bio_enc_aes_128_cbc(int idx)
188 return do_test_bio_cipher(EVP_aes_128_cbc(), idx);
191 static int test_bio_enc_aes_128_ctr(int idx)
193 return do_test_bio_cipher(EVP_aes_128_ctr(), idx);
196 static int test_bio_enc_aes_256_cfb(int idx)
198 return do_test_bio_cipher(EVP_aes_256_cfb(), idx);
201 static int test_bio_enc_aes_256_ofb(int idx)
203 return do_test_bio_cipher(EVP_aes_256_ofb(), idx);
206 static int test_bio_enc_chacha20(int idx)
208 return do_test_bio_cipher(EVP_chacha20(), idx);
211 static int test_bio_enc_chacha20_poly1305(int idx)
213 return do_test_bio_cipher(EVP_chacha20_poly1305(), idx);
216 void register_tests(void)
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);