Converted the bio_enc tests to use new test framework.

This includes reworked reworked tests to do both encrypt and decrypt,
and a few more ciphers added.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3197)
This commit is contained in:
Jon Spillett 2017-04-12 16:09:05 +10:00 committed by Richard Levitte
parent 26fb4b033c
commit dd94c37a5c
2 changed files with 140 additions and 50 deletions

View file

@ -12,50 +12,74 @@
#include <openssl/bio.h>
#include <openssl/rand.h>
int main()
#include "test_main.h"
#include "testutil.h"
#define ENCRYPT 1
#define DECRYPT 0
#define DATA_SIZE 1024
#define MAX_IV 32
#define BUF_SIZE (DATA_SIZE + MAX_IV)
static const unsigned char KEY[] = {
0x51, 0x50, 0xd1, 0x77, 0x2f, 0x50, 0x83, 0x4a,
0x50, 0x3e, 0x06, 0x9a, 0x97, 0x3f, 0xbd, 0x7c,
0xe6, 0x1c, 0x43, 0x2b, 0x72, 0x0b, 0x19, 0xd1,
0x8e, 0xc8, 0xd8, 0x4b, 0xdc, 0x63, 0x15, 0x1b
};
static const unsigned char IV[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
};
static int do_bio_cipher(const EVP_CIPHER* cipher, const unsigned char* key,
const unsigned char* iv)
{
BIO *b;
static const unsigned char key[16] = { 0 };
static unsigned char inp[1024] = { 0 };
unsigned char out[1024], ref[1024];
static unsigned char inp[BUF_SIZE] = { 0 };
unsigned char out[BUF_SIZE], ref[BUF_SIZE];
int i, lref, len;
/* Fill buffer with non-zero data so that over steps can be detected */
if (RAND_bytes(inp, sizeof(inp)) <= 0)
return -1;
if (!TEST_int_gt(RAND_bytes(inp, DATA_SIZE), 0))
return 0;
/*
* Exercise CBC cipher
*/
/* Encrypt tests */
/* reference output for single-chunk operation */
b = BIO_new(BIO_f_cipher());
if (!BIO_set_cipher(b, EVP_aes_128_cbc(), key, NULL, 0))
return -1;
BIO_push(b, BIO_new_mem_buf(inp, sizeof(inp)));
if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, ENCRYPT)))
return 0;
BIO_push(b, BIO_new_mem_buf(inp, DATA_SIZE));
lref = BIO_read(b, ref, sizeof(ref));
BIO_free_all(b);
/* perform split operations and compare to reference */
for (i = 1; i < lref; i++) {
b = BIO_new(BIO_f_cipher());
if (!BIO_set_cipher(b, EVP_aes_128_cbc(), key, NULL, 0))
return -1;
BIO_push(b, BIO_new_mem_buf(inp, sizeof(inp)));
if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, ENCRYPT))) {
TEST_info("Split encrypt failed @ operation %d", i);
return 0;
}
BIO_push(b, BIO_new_mem_buf(inp, DATA_SIZE));
memset(out, 0, sizeof(out));
out[i] = ~ref[i];
len = BIO_read(b, out, i);
/* check for overstep */
if (out[i] != (unsigned char)~ref[i]) {
fprintf(stderr, "CBC output overstep@%d\n", i);
return 1;
if (!TEST_uchar_eq(out[i], (unsigned char)~ref[i])) {
TEST_info("Encrypt overstep check failed @ operation %d", i);
return 0;
}
len += BIO_read(b, out + len, sizeof(out) - len);
BIO_free_all(b);
if (len != lref || memcmp(out, ref, len)) {
fprintf(stderr, "CBC output mismatch@%d\n", i);
return 2;
if (!TEST_mem_eq(out, len, ref, lref)) {
TEST_info("Encrypt compare failed @ operation %d", i);
return 0;
}
}
@ -64,53 +88,61 @@ int main()
int delta;
b = BIO_new(BIO_f_cipher());
if (!BIO_set_cipher(b, EVP_aes_128_cbc(), key, NULL, 0))
return -1;
BIO_push(b, BIO_new_mem_buf(inp, sizeof(inp)));
if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, ENCRYPT))) {
TEST_info("Small chunk encrypt failed @ operation %d", i);
return 0;
}
BIO_push(b, BIO_new_mem_buf(inp, DATA_SIZE));
memset(out, 0, sizeof(out));
for (len = 0; (delta = BIO_read(b, out + len, i)); ) {
len += delta;
}
BIO_free_all(b);
if (len != lref || memcmp(out, ref, len)) {
fprintf(stderr, "CBC output mismatch@%d\n", i);
return 3;
if (!TEST_mem_eq(out, len, ref, lref)) {
TEST_info("Small chunk encrypt compare failed @ operation %d", i);
return 0;
}
}
/*
* Exercise CTR cipher
*/
/* Decrypt tests */
/* reference output for single-chunk operation */
b = BIO_new(BIO_f_cipher());
if (!BIO_set_cipher(b, EVP_aes_128_ctr(), key, NULL, 0))
return -1;
BIO_push(b, BIO_new_mem_buf(inp, sizeof(inp)));
lref = BIO_read(b, ref, sizeof(ref));
if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, DECRYPT)))
return 0;
/* Use original reference output as input */
BIO_push(b, BIO_new_mem_buf(ref, lref));
(void)BIO_flush(b);
memset(out, 0, sizeof(out));
len = BIO_read(b, out, sizeof(out));
BIO_free_all(b);
if (!TEST_mem_eq(inp, DATA_SIZE, out, len))
return 0;
/* perform split operations and compare to reference */
for (i = 1; i < lref; i++) {
b = BIO_new(BIO_f_cipher());
if (!BIO_set_cipher(b, EVP_aes_128_ctr(), key, NULL, 0))
return -1;
BIO_push(b, BIO_new_mem_buf(inp, sizeof(inp)));
if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, DECRYPT))) {
TEST_info("Split decrypt failed @ operation %d", i);
return 0;
}
BIO_push(b, BIO_new_mem_buf(ref, lref));
memset(out, 0, sizeof(out));
out[i] = ~ref[i];
len = BIO_read(b, out, i);
/* check for overstep */
if (out[i] != (unsigned char)~ref[i]) {
fprintf(stderr, "CTR output overstep@%d\n", i);
return 4;
if (!TEST_uchar_eq(out[i], (unsigned char)~ref[i])) {
TEST_info("Decrypt overstep check failed @ operation %d", i);
return 0;
}
len += BIO_read(b, out + len, sizeof(out) - len);
BIO_free_all(b);
if (len != lref || memcmp(out, ref, len)) {
fprintf(stderr, "CTR output mismatch@%d\n", i);
return 5;
if (!TEST_mem_eq(inp, DATA_SIZE, out, len)) {
TEST_info("Decrypt compare failed @ operation %d", i);
return 0;
}
}
@ -119,20 +151,78 @@ int main()
int delta;
b = BIO_new(BIO_f_cipher());
if (!BIO_set_cipher(b, EVP_aes_128_ctr(), key, NULL, 0))
return -1;
BIO_push(b, BIO_new_mem_buf(inp, sizeof(inp)));
if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, DECRYPT))) {
TEST_info("Small chunk decrypt failed @ operation %d", i);
return 0;
}
BIO_push(b, BIO_new_mem_buf(ref, lref));
memset(out, 0, sizeof(out));
for (len = 0; (delta = BIO_read(b, out + len, i)); ) {
len += delta;
}
BIO_free_all(b);
if (len != lref || memcmp(out, ref, len)) {
fprintf(stderr, "CTR output mismatch@%d\n", i);
return 6;
if (!TEST_mem_eq(inp, DATA_SIZE, out, len)) {
TEST_info("Small chunk decrypt compare failed @ operation %d", i);
return 0;
}
}
return 1;
}
static int do_test_bio_cipher(const EVP_CIPHER* cipher, int idx)
{
switch(idx)
{
case 0:
return do_bio_cipher(cipher, KEY, NULL);
case 1:
return do_bio_cipher(cipher, KEY, IV);
}
return 0;
}
static int test_bio_enc_aes_128_cbc(int idx)
{
return do_test_bio_cipher(EVP_aes_128_cbc(), idx);
}
static int test_bio_enc_aes_128_ctr(int idx)
{
return do_test_bio_cipher(EVP_aes_128_ctr(), idx);
}
static int test_bio_enc_aes_256_cfb(int idx)
{
return do_test_bio_cipher(EVP_aes_256_cfb(), idx);
}
static int test_bio_enc_aes_256_ofb(int idx)
{
return do_test_bio_cipher(EVP_aes_256_ofb(), idx);
}
static int test_bio_enc_chacha20(int idx)
{
return do_test_bio_cipher(EVP_chacha20(), idx);
}
static int test_bio_enc_chacha20_poly1305(int idx)
{
return do_test_bio_cipher(EVP_chacha20_poly1305(), idx);
}
void register_tests(void)
{
ADD_ALL_TESTS(test_bio_enc_aes_128_cbc, 2);
ADD_ALL_TESTS(test_bio_enc_aes_128_ctr, 2);
ADD_ALL_TESTS(test_bio_enc_aes_256_cfb, 2);
ADD_ALL_TESTS(test_bio_enc_aes_256_ofb, 2);
# ifndef OPENSSL_NO_CHACHA
ADD_ALL_TESTS(test_bio_enc_chacha20, 2);
# ifndef OPENSSL_NO_POLY1305
ADD_ALL_TESTS(test_bio_enc_chacha20_poly1305, 2);
# endif
# endif
}

View file

@ -280,7 +280,7 @@ IF[{- !$disabled{tests} -}]
INCLUDE[sslcorrupttest]=../include .
DEPEND[sslcorrupttest]=../libcrypto ../libssl
SOURCE[bio_enc_test]=bio_enc_test.c
SOURCE[bio_enc_test]=bio_enc_test.c testutil.c test_main.c
INCLUDE[bio_enc_test]=../include
DEPEND[bio_enc_test]=../libcrypto