Blame test/bio_enc_test.c

Packit c4476c
/*
Packit c4476c
 * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
Packit c4476c
 *
Packit c4476c
 * Licensed under the OpenSSL license (the "License").  You may not use
Packit c4476c
 * this file except in compliance with the License.  You can obtain a copy
Packit c4476c
 * in the file LICENSE in the source distribution or at
Packit c4476c
 * https://www.openssl.org/source/license.html
Packit c4476c
 */
Packit c4476c
#include <stdio.h>
Packit c4476c
#include <string.h>
Packit c4476c
#include <openssl/evp.h>
Packit c4476c
#include <openssl/bio.h>
Packit c4476c
#include <openssl/rand.h>
Packit c4476c
Packit c4476c
#include "testutil.h"
Packit c4476c
Packit c4476c
#define ENCRYPT  1
Packit c4476c
#define DECRYPT  0
Packit c4476c
Packit c4476c
#define DATA_SIZE    1024
Packit c4476c
#define MAX_IV       32
Packit c4476c
#define BUF_SIZE     (DATA_SIZE + MAX_IV)
Packit c4476c
Packit c4476c
static const unsigned char KEY[] = {
Packit c4476c
    0x51, 0x50, 0xd1, 0x77, 0x2f, 0x50, 0x83, 0x4a,
Packit c4476c
    0x50, 0x3e, 0x06, 0x9a, 0x97, 0x3f, 0xbd, 0x7c,
Packit c4476c
    0xe6, 0x1c, 0x43, 0x2b, 0x72, 0x0b, 0x19, 0xd1,
Packit c4476c
    0x8e, 0xc8, 0xd8, 0x4b, 0xdc, 0x63, 0x15, 0x1b
Packit c4476c
};
Packit c4476c
Packit c4476c
static const unsigned char IV[] = {
Packit c4476c
    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
Packit c4476c
    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
Packit c4476c
    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
Packit c4476c
    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
Packit c4476c
};
Packit c4476c
Packit c4476c
static int do_bio_cipher(const EVP_CIPHER* cipher, const unsigned char* key,
Packit c4476c
    const unsigned char* iv)
Packit c4476c
{
Packit c4476c
    BIO *b;
Packit c4476c
    static unsigned char inp[BUF_SIZE] = { 0 };
Packit c4476c
    unsigned char out[BUF_SIZE], ref[BUF_SIZE];
Packit c4476c
    int i, lref, len;
Packit c4476c
Packit c4476c
    /* Fill buffer with non-zero data so that over steps can be detected */
Packit c4476c
    if (!TEST_int_gt(RAND_bytes(inp, DATA_SIZE), 0))
Packit c4476c
        return 0;
Packit c4476c
Packit c4476c
    /* Encrypt tests */
Packit c4476c
Packit c4476c
    /* reference output for single-chunk operation */
Packit c4476c
    b = BIO_new(BIO_f_cipher());
Packit c4476c
    if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, ENCRYPT)))
Packit c4476c
        return 0;
Packit c4476c
    BIO_push(b, BIO_new_mem_buf(inp, DATA_SIZE));
Packit c4476c
    lref = BIO_read(b, ref, sizeof(ref));
Packit c4476c
    BIO_free_all(b);
Packit c4476c
Packit c4476c
    /* perform split operations and compare to reference */
Packit c4476c
    for (i = 1; i < lref; i++) {
Packit c4476c
        b = BIO_new(BIO_f_cipher());
Packit c4476c
        if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, ENCRYPT))) {
Packit c4476c
            TEST_info("Split encrypt failed @ operation %d", i);
Packit c4476c
            return 0;
Packit c4476c
        }
Packit c4476c
        BIO_push(b, BIO_new_mem_buf(inp, DATA_SIZE));
Packit c4476c
        memset(out, 0, sizeof(out));
Packit c4476c
        out[i] = ~ref[i];
Packit c4476c
        len = BIO_read(b, out, i);
Packit c4476c
        /* check for overstep */
Packit c4476c
        if (!TEST_uchar_eq(out[i], (unsigned char)~ref[i])) {
Packit c4476c
            TEST_info("Encrypt overstep check failed @ operation %d", i);
Packit c4476c
            return 0;
Packit c4476c
        }
Packit c4476c
        len += BIO_read(b, out + len, sizeof(out) - len);
Packit c4476c
        BIO_free_all(b);
Packit c4476c
Packit c4476c
        if (!TEST_mem_eq(out, len, ref, lref)) {
Packit c4476c
            TEST_info("Encrypt compare failed @ operation %d", i);
Packit c4476c
            return 0;
Packit c4476c
        }
Packit c4476c
    }
Packit c4476c
Packit c4476c
    /* perform small-chunk operations and compare to reference */
Packit c4476c
    for (i = 1; i < lref / 2; i++) {
Packit c4476c
        int delta;
Packit c4476c
Packit c4476c
        b = BIO_new(BIO_f_cipher());
Packit c4476c
        if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, ENCRYPT))) {
Packit c4476c
            TEST_info("Small chunk encrypt failed @ operation %d", i);
Packit c4476c
            return 0;
Packit c4476c
        }
Packit c4476c
        BIO_push(b, BIO_new_mem_buf(inp, DATA_SIZE));
Packit c4476c
        memset(out, 0, sizeof(out));
Packit c4476c
        for (len = 0; (delta = BIO_read(b, out + len, i)); ) {
Packit c4476c
            len += delta;
Packit c4476c
        }
Packit c4476c
        BIO_free_all(b);
Packit c4476c
Packit c4476c
        if (!TEST_mem_eq(out, len, ref, lref)) {
Packit c4476c
            TEST_info("Small chunk encrypt compare failed @ operation %d", i);
Packit c4476c
            return 0;
Packit c4476c
        }
Packit c4476c
    }
Packit c4476c
Packit c4476c
    /* Decrypt tests */
Packit c4476c
Packit c4476c
    /* reference output for single-chunk operation */
Packit c4476c
    b = BIO_new(BIO_f_cipher());
Packit c4476c
    if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, DECRYPT)))
Packit c4476c
        return 0;
Packit c4476c
    /* Use original reference output as input */
Packit c4476c
    BIO_push(b, BIO_new_mem_buf(ref, lref));
Packit c4476c
    (void)BIO_flush(b);
Packit c4476c
    memset(out, 0, sizeof(out));
Packit c4476c
    len = BIO_read(b, out, sizeof(out));
Packit c4476c
    BIO_free_all(b);
Packit c4476c
Packit c4476c
    if (!TEST_mem_eq(inp, DATA_SIZE, out, len))
Packit c4476c
        return 0;
Packit c4476c
Packit c4476c
    /* perform split operations and compare to reference */
Packit c4476c
    for (i = 1; i < lref; i++) {
Packit c4476c
        b = BIO_new(BIO_f_cipher());
Packit c4476c
        if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, DECRYPT))) {
Packit c4476c
            TEST_info("Split decrypt failed @ operation %d", i);
Packit c4476c
            return 0;
Packit c4476c
        }
Packit c4476c
        BIO_push(b, BIO_new_mem_buf(ref, lref));
Packit c4476c
        memset(out, 0, sizeof(out));
Packit c4476c
        out[i] = ~ref[i];
Packit c4476c
        len = BIO_read(b, out, i);
Packit c4476c
        /* check for overstep */
Packit c4476c
        if (!TEST_uchar_eq(out[i], (unsigned char)~ref[i])) {
Packit c4476c
            TEST_info("Decrypt overstep check failed @ operation %d", i);
Packit c4476c
            return 0;
Packit c4476c
        }
Packit c4476c
        len += BIO_read(b, out + len, sizeof(out) - len);
Packit c4476c
        BIO_free_all(b);
Packit c4476c
Packit c4476c
        if (!TEST_mem_eq(inp, DATA_SIZE, out, len)) {
Packit c4476c
            TEST_info("Decrypt compare failed @ operation %d", i);
Packit c4476c
            return 0;
Packit c4476c
        }
Packit c4476c
    }
Packit c4476c
Packit c4476c
    /* perform small-chunk operations and compare to reference */
Packit c4476c
    for (i = 1; i < lref / 2; i++) {
Packit c4476c
        int delta;
Packit c4476c
Packit c4476c
        b = BIO_new(BIO_f_cipher());
Packit c4476c
        if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, DECRYPT))) {
Packit c4476c
            TEST_info("Small chunk decrypt failed @ operation %d", i);
Packit c4476c
            return 0;
Packit c4476c
        }
Packit c4476c
        BIO_push(b, BIO_new_mem_buf(ref, lref));
Packit c4476c
        memset(out, 0, sizeof(out));
Packit c4476c
        for (len = 0; (delta = BIO_read(b, out + len, i)); ) {
Packit c4476c
            len += delta;
Packit c4476c
        }
Packit c4476c
        BIO_free_all(b);
Packit c4476c
Packit c4476c
        if (!TEST_mem_eq(inp, DATA_SIZE, out, len)) {
Packit c4476c
            TEST_info("Small chunk decrypt compare failed @ operation %d", i);
Packit c4476c
            return 0;
Packit c4476c
        }
Packit c4476c
    }
Packit c4476c
Packit c4476c
    return 1;
Packit c4476c
}
Packit c4476c
Packit c4476c
static int do_test_bio_cipher(const EVP_CIPHER* cipher, int idx)
Packit c4476c
{
Packit c4476c
    switch(idx)
Packit c4476c
    {
Packit c4476c
        case 0:
Packit c4476c
            return do_bio_cipher(cipher, KEY, NULL);
Packit c4476c
        case 1:
Packit c4476c
            return do_bio_cipher(cipher, KEY, IV);
Packit c4476c
    }
Packit c4476c
    return 0;
Packit c4476c
}
Packit c4476c
Packit c4476c
static int test_bio_enc_aes_128_cbc(int idx)
Packit c4476c
{
Packit c4476c
    return do_test_bio_cipher(EVP_aes_128_cbc(), idx);
Packit c4476c
}
Packit c4476c
Packit c4476c
static int test_bio_enc_aes_128_ctr(int idx)
Packit c4476c
{
Packit c4476c
    return do_test_bio_cipher(EVP_aes_128_ctr(), idx);
Packit c4476c
}
Packit c4476c
Packit c4476c
static int test_bio_enc_aes_256_cfb(int idx)
Packit c4476c
{
Packit c4476c
    return do_test_bio_cipher(EVP_aes_256_cfb(), idx);
Packit c4476c
}
Packit c4476c
Packit c4476c
static int test_bio_enc_aes_256_ofb(int idx)
Packit c4476c
{
Packit c4476c
    return do_test_bio_cipher(EVP_aes_256_ofb(), idx);
Packit c4476c
}
Packit c4476c
Packit c4476c
# ifndef OPENSSL_NO_CHACHA
Packit c4476c
static int test_bio_enc_chacha20(int idx)
Packit c4476c
{
Packit c4476c
    return do_test_bio_cipher(EVP_chacha20(), idx);
Packit c4476c
}
Packit c4476c
Packit c4476c
#  ifndef OPENSSL_NO_POLY1305
Packit c4476c
static int test_bio_enc_chacha20_poly1305(int idx)
Packit c4476c
{
Packit c4476c
    return do_test_bio_cipher(EVP_chacha20_poly1305(), idx);
Packit c4476c
}
Packit c4476c
#  endif
Packit c4476c
# endif
Packit c4476c
Packit c4476c
int setup_tests(void)
Packit c4476c
{
Packit c4476c
    ADD_ALL_TESTS(test_bio_enc_aes_128_cbc, 2);
Packit c4476c
    ADD_ALL_TESTS(test_bio_enc_aes_128_ctr, 2);
Packit c4476c
    ADD_ALL_TESTS(test_bio_enc_aes_256_cfb, 2);
Packit c4476c
    ADD_ALL_TESTS(test_bio_enc_aes_256_ofb, 2);
Packit c4476c
# ifndef OPENSSL_NO_CHACHA
Packit c4476c
    ADD_ALL_TESTS(test_bio_enc_chacha20, 2);
Packit c4476c
#  ifndef OPENSSL_NO_POLY1305
Packit c4476c
    ADD_ALL_TESTS(test_bio_enc_chacha20_poly1305, 2);
Packit c4476c
#  endif
Packit c4476c
# endif
Packit c4476c
    return 1;
Packit c4476c
}