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