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