1 /* 2 * Copyright 2016 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 int main() 16 { 17 BIO *b; 18 static const unsigned char key[16] = { 0 }; 19 static unsigned char inp[1024] = { 0 }; 20 unsigned char out[1024], ref[1024]; 21 int i, lref, len; 22 23 /* Fill buffer with non-zero data so that over steps can be detected */ 24 if (RAND_bytes(inp, sizeof(inp)) <= 0) 25 return -1; 26 27 /* 28 * Exercise CBC cipher 29 */ 30 31 /* reference output for single-chunk operation */ 32 b = BIO_new(BIO_f_cipher()); 33 if (!BIO_set_cipher(b, EVP_aes_128_cbc(), key, NULL, 0)) 34 return -1; 35 BIO_push(b, BIO_new_mem_buf(inp, sizeof(inp))); 36 lref = BIO_read(b, ref, sizeof(ref)); 37 BIO_free_all(b); 38 39 /* perform split operations and compare to reference */ 40 for (i = 1; i < lref; i++) { 41 b = BIO_new(BIO_f_cipher()); 42 if (!BIO_set_cipher(b, EVP_aes_128_cbc(), key, NULL, 0)) 43 return -1; 44 BIO_push(b, BIO_new_mem_buf(inp, sizeof(inp))); 45 memset(out, 0, sizeof(out)); 46 out[i] = ~ref[i]; 47 len = BIO_read(b, out, i); 48 /* check for overstep */ 49 if (out[i] != (unsigned char)~ref[i]) { 50 fprintf(stderr, "CBC output overstep@%d\n", i); 51 return 1; 52 } 53 len += BIO_read(b, out + len, sizeof(out) - len); 54 BIO_free_all(b); 55 56 if (len != lref || memcmp(out, ref, len)) { 57 fprintf(stderr, "CBC output mismatch@%d\n", i); 58 return 2; 59 } 60 } 61 62 /* perform small-chunk operations and compare to reference */ 63 for (i = 1; i < lref / 2; i++) { 64 int delta; 65 66 b = BIO_new(BIO_f_cipher()); 67 if (!BIO_set_cipher(b, EVP_aes_128_cbc(), key, NULL, 0)) 68 return -1; 69 BIO_push(b, BIO_new_mem_buf(inp, sizeof(inp))); 70 memset(out, 0, sizeof(out)); 71 for (len = 0; (delta = BIO_read(b, out + len, i)); ) { 72 len += delta; 73 } 74 BIO_free_all(b); 75 76 if (len != lref || memcmp(out, ref, len)) { 77 fprintf(stderr, "CBC output mismatch@%d\n", i); 78 return 3; 79 } 80 } 81 82 /* 83 * Exercise CTR cipher 84 */ 85 86 /* reference output for single-chunk operation */ 87 b = BIO_new(BIO_f_cipher()); 88 if (!BIO_set_cipher(b, EVP_aes_128_ctr(), key, NULL, 0)) 89 return -1; 90 BIO_push(b, BIO_new_mem_buf(inp, sizeof(inp))); 91 lref = BIO_read(b, ref, sizeof(ref)); 92 BIO_free_all(b); 93 94 /* perform split operations and compare to reference */ 95 for (i = 1; i < lref; i++) { 96 b = BIO_new(BIO_f_cipher()); 97 if (!BIO_set_cipher(b, EVP_aes_128_ctr(), key, NULL, 0)) 98 return -1; 99 BIO_push(b, BIO_new_mem_buf(inp, sizeof(inp))); 100 memset(out, 0, sizeof(out)); 101 out[i] = ~ref[i]; 102 len = BIO_read(b, out, i); 103 /* check for overstep */ 104 if (out[i] != (unsigned char)~ref[i]) { 105 fprintf(stderr, "CTR output overstep@%d\n", i); 106 return 4; 107 } 108 len += BIO_read(b, out + len, sizeof(out) - len); 109 BIO_free_all(b); 110 111 if (len != lref || memcmp(out, ref, len)) { 112 fprintf(stderr, "CTR output mismatch@%d\n", i); 113 return 5; 114 } 115 } 116 117 /* perform small-chunk operations and compare to reference */ 118 for (i = 1; i < lref / 2; i++) { 119 int delta; 120 121 b = BIO_new(BIO_f_cipher()); 122 if (!BIO_set_cipher(b, EVP_aes_128_ctr(), key, NULL, 0)) 123 return -1; 124 BIO_push(b, BIO_new_mem_buf(inp, sizeof(inp))); 125 memset(out, 0, sizeof(out)); 126 for (len = 0; (delta = BIO_read(b, out + len, i)); ) { 127 len += delta; 128 } 129 BIO_free_all(b); 130 131 if (len != lref || memcmp(out, ref, len)) { 132 fprintf(stderr, "CTR output mismatch@%d\n", i); 133 return 6; 134 } 135 } 136 137 return 0; 138 } 139