xref: /netbsd-src/crypto/external/bsd/openssl/dist/test/bio_enc_test.c (revision b0d1725196a7921d003d2c66a14f186abda4176b)
1c7da899bSchristos /*
2*b0d17251Schristos  * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
3c7da899bSchristos  *
4*b0d17251Schristos  * Licensed under the Apache License 2.0 (the "License").  You may not use
5c7da899bSchristos  * this file except in compliance with the License.  You can obtain a copy
6c7da899bSchristos  * in the file LICENSE in the source distribution or at
7c7da899bSchristos  * https://www.openssl.org/source/license.html
8c7da899bSchristos  */
9c7da899bSchristos #include <stdio.h>
10c7da899bSchristos #include <string.h>
11c7da899bSchristos #include <openssl/evp.h>
12c7da899bSchristos #include <openssl/bio.h>
13c7da899bSchristos #include <openssl/rand.h>
14c7da899bSchristos 
1513d40330Schristos #include "testutil.h"
1613d40330Schristos 
1713d40330Schristos #define ENCRYPT  1
1813d40330Schristos #define DECRYPT  0
1913d40330Schristos 
2013d40330Schristos #define DATA_SIZE    1024
2113d40330Schristos #define MAX_IV       32
2213d40330Schristos #define BUF_SIZE     (DATA_SIZE + MAX_IV)
2313d40330Schristos 
2413d40330Schristos static const unsigned char KEY[] = {
2513d40330Schristos     0x51, 0x50, 0xd1, 0x77, 0x2f, 0x50, 0x83, 0x4a,
2613d40330Schristos     0x50, 0x3e, 0x06, 0x9a, 0x97, 0x3f, 0xbd, 0x7c,
2713d40330Schristos     0xe6, 0x1c, 0x43, 0x2b, 0x72, 0x0b, 0x19, 0xd1,
2813d40330Schristos     0x8e, 0xc8, 0xd8, 0x4b, 0xdc, 0x63, 0x15, 0x1b
2913d40330Schristos };
3013d40330Schristos 
3113d40330Schristos static const unsigned char IV[] = {
3213d40330Schristos     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
3313d40330Schristos     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
3413d40330Schristos     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
3513d40330Schristos     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
3613d40330Schristos };
3713d40330Schristos 
do_bio_cipher(const EVP_CIPHER * cipher,const unsigned char * key,const unsigned char * iv)3813d40330Schristos static int do_bio_cipher(const EVP_CIPHER* cipher, const unsigned char* key,
3913d40330Schristos     const unsigned char* iv)
40c7da899bSchristos {
41*b0d17251Schristos     BIO *b, *mem;
4213d40330Schristos     static unsigned char inp[BUF_SIZE] = { 0 };
4313d40330Schristos     unsigned char out[BUF_SIZE], ref[BUF_SIZE];
44c7da899bSchristos     int i, lref, len;
45c7da899bSchristos 
46c7da899bSchristos     /* Fill buffer with non-zero data so that over steps can be detected */
4713d40330Schristos     if (!TEST_int_gt(RAND_bytes(inp, DATA_SIZE), 0))
4813d40330Schristos         return 0;
49c7da899bSchristos 
5013d40330Schristos     /* Encrypt tests */
51c7da899bSchristos 
52c7da899bSchristos     /* reference output for single-chunk operation */
53c7da899bSchristos     b = BIO_new(BIO_f_cipher());
54*b0d17251Schristos     if (!TEST_ptr(b))
5513d40330Schristos         return 0;
56*b0d17251Schristos     if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, ENCRYPT)))
57*b0d17251Schristos         goto err;
58*b0d17251Schristos     mem = BIO_new_mem_buf(inp, DATA_SIZE);
59*b0d17251Schristos     if (!TEST_ptr(mem))
60*b0d17251Schristos         goto err;
61*b0d17251Schristos     BIO_push(b, mem);
62c7da899bSchristos     lref = BIO_read(b, ref, sizeof(ref));
63c7da899bSchristos     BIO_free_all(b);
64c7da899bSchristos 
65c7da899bSchristos     /* perform split operations and compare to reference */
66c7da899bSchristos     for (i = 1; i < lref; i++) {
67c7da899bSchristos         b = BIO_new(BIO_f_cipher());
68*b0d17251Schristos         if (!TEST_ptr(b))
69*b0d17251Schristos             return 0;
7013d40330Schristos         if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, ENCRYPT))) {
7113d40330Schristos             TEST_info("Split encrypt failed @ operation %d", i);
72*b0d17251Schristos             goto err;
7313d40330Schristos         }
74*b0d17251Schristos         mem = BIO_new_mem_buf(inp, DATA_SIZE);
75*b0d17251Schristos         if (!TEST_ptr(mem))
76*b0d17251Schristos             goto err;
77*b0d17251Schristos         BIO_push(b, mem);
78c7da899bSchristos         memset(out, 0, sizeof(out));
79c7da899bSchristos         out[i] = ~ref[i];
80c7da899bSchristos         len = BIO_read(b, out, i);
81c7da899bSchristos         /* check for overstep */
8213d40330Schristos         if (!TEST_uchar_eq(out[i], (unsigned char)~ref[i])) {
8313d40330Schristos             TEST_info("Encrypt overstep check failed @ operation %d", i);
84*b0d17251Schristos             goto err;
8513d40330Schristos         }
8613d40330Schristos         len += BIO_read(b, out + len, sizeof(out) - len);
8713d40330Schristos         BIO_free_all(b);
8813d40330Schristos 
8913d40330Schristos         if (!TEST_mem_eq(out, len, ref, lref)) {
9013d40330Schristos             TEST_info("Encrypt compare failed @ operation %d", i);
9113d40330Schristos             return 0;
9213d40330Schristos         }
9313d40330Schristos     }
9413d40330Schristos 
9513d40330Schristos     /* perform small-chunk operations and compare to reference */
9613d40330Schristos     for (i = 1; i < lref / 2; i++) {
9713d40330Schristos         int delta;
9813d40330Schristos 
9913d40330Schristos         b = BIO_new(BIO_f_cipher());
100*b0d17251Schristos         if (!TEST_ptr(b))
101*b0d17251Schristos             return 0;
10213d40330Schristos         if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, ENCRYPT))) {
10313d40330Schristos             TEST_info("Small chunk encrypt failed @ operation %d", i);
104*b0d17251Schristos             goto err;
10513d40330Schristos         }
106*b0d17251Schristos         mem = BIO_new_mem_buf(inp, DATA_SIZE);
107*b0d17251Schristos         if (!TEST_ptr(mem))
108*b0d17251Schristos             goto err;
109*b0d17251Schristos         BIO_push(b, mem);
11013d40330Schristos         memset(out, 0, sizeof(out));
11113d40330Schristos         for (len = 0; (delta = BIO_read(b, out + len, i)); ) {
11213d40330Schristos             len += delta;
11313d40330Schristos         }
11413d40330Schristos         BIO_free_all(b);
11513d40330Schristos 
11613d40330Schristos         if (!TEST_mem_eq(out, len, ref, lref)) {
11713d40330Schristos             TEST_info("Small chunk encrypt compare failed @ operation %d", i);
11813d40330Schristos             return 0;
11913d40330Schristos         }
12013d40330Schristos     }
12113d40330Schristos 
12213d40330Schristos     /* Decrypt tests */
12313d40330Schristos 
12413d40330Schristos     /* reference output for single-chunk operation */
12513d40330Schristos     b = BIO_new(BIO_f_cipher());
126*b0d17251Schristos     if (!TEST_ptr(b))
12713d40330Schristos         return 0;
128*b0d17251Schristos     if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, DECRYPT)))
129*b0d17251Schristos         goto err;
13013d40330Schristos     /* Use original reference output as input */
131*b0d17251Schristos     mem = BIO_new_mem_buf(ref, lref);
132*b0d17251Schristos     if (!TEST_ptr(mem))
133*b0d17251Schristos         goto err;
134*b0d17251Schristos     BIO_push(b, mem);
13513d40330Schristos     (void)BIO_flush(b);
13613d40330Schristos     memset(out, 0, sizeof(out));
13713d40330Schristos     len = BIO_read(b, out, sizeof(out));
13813d40330Schristos     BIO_free_all(b);
13913d40330Schristos 
14013d40330Schristos     if (!TEST_mem_eq(inp, DATA_SIZE, out, len))
14113d40330Schristos         return 0;
14213d40330Schristos 
14313d40330Schristos     /* perform split operations and compare to reference */
14413d40330Schristos     for (i = 1; i < lref; i++) {
14513d40330Schristos         b = BIO_new(BIO_f_cipher());
146*b0d17251Schristos         if (!TEST_ptr(b))
147*b0d17251Schristos             return 0;
14813d40330Schristos         if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, DECRYPT))) {
14913d40330Schristos             TEST_info("Split decrypt failed @ operation %d", i);
150*b0d17251Schristos             goto err;
15113d40330Schristos         }
152*b0d17251Schristos         mem = BIO_new_mem_buf(ref, lref);
153*b0d17251Schristos         if (!TEST_ptr(mem))
154*b0d17251Schristos             goto err;
155*b0d17251Schristos         BIO_push(b, mem);
15613d40330Schristos         memset(out, 0, sizeof(out));
15713d40330Schristos         out[i] = ~ref[i];
15813d40330Schristos         len = BIO_read(b, out, i);
15913d40330Schristos         /* check for overstep */
16013d40330Schristos         if (!TEST_uchar_eq(out[i], (unsigned char)~ref[i])) {
16113d40330Schristos             TEST_info("Decrypt overstep check failed @ operation %d", i);
162*b0d17251Schristos             goto err;
16313d40330Schristos         }
16413d40330Schristos         len += BIO_read(b, out + len, sizeof(out) - len);
16513d40330Schristos         BIO_free_all(b);
16613d40330Schristos 
16713d40330Schristos         if (!TEST_mem_eq(inp, DATA_SIZE, out, len)) {
16813d40330Schristos             TEST_info("Decrypt compare failed @ operation %d", i);
16913d40330Schristos             return 0;
17013d40330Schristos         }
17113d40330Schristos     }
17213d40330Schristos 
17313d40330Schristos     /* perform small-chunk operations and compare to reference */
17413d40330Schristos     for (i = 1; i < lref / 2; i++) {
17513d40330Schristos         int delta;
17613d40330Schristos 
17713d40330Schristos         b = BIO_new(BIO_f_cipher());
178*b0d17251Schristos         if (!TEST_ptr(b))
179*b0d17251Schristos             return 0;
18013d40330Schristos         if (!TEST_true(BIO_set_cipher(b, cipher, key, iv, DECRYPT))) {
18113d40330Schristos             TEST_info("Small chunk decrypt failed @ operation %d", i);
182*b0d17251Schristos             goto err;
18313d40330Schristos         }
184*b0d17251Schristos         mem = BIO_new_mem_buf(ref, lref);
185*b0d17251Schristos         if (!TEST_ptr(mem))
186*b0d17251Schristos             goto err;
187*b0d17251Schristos         BIO_push(b, mem);
18813d40330Schristos         memset(out, 0, sizeof(out));
18913d40330Schristos         for (len = 0; (delta = BIO_read(b, out + len, i)); ) {
19013d40330Schristos             len += delta;
19113d40330Schristos         }
19213d40330Schristos         BIO_free_all(b);
19313d40330Schristos 
19413d40330Schristos         if (!TEST_mem_eq(inp, DATA_SIZE, out, len)) {
19513d40330Schristos             TEST_info("Small chunk decrypt compare failed @ operation %d", i);
19613d40330Schristos             return 0;
19713d40330Schristos         }
19813d40330Schristos     }
19913d40330Schristos 
200c7da899bSchristos     return 1;
201*b0d17251Schristos 
202*b0d17251Schristos err:
203*b0d17251Schristos     BIO_free_all(b);
204*b0d17251Schristos     return 0;
205c7da899bSchristos }
206c7da899bSchristos 
do_test_bio_cipher(const EVP_CIPHER * cipher,int idx)20713d40330Schristos static int do_test_bio_cipher(const EVP_CIPHER* cipher, int idx)
20813d40330Schristos {
20913d40330Schristos     switch(idx)
21013d40330Schristos     {
21113d40330Schristos         case 0:
21213d40330Schristos             return do_bio_cipher(cipher, KEY, NULL);
21313d40330Schristos         case 1:
21413d40330Schristos             return do_bio_cipher(cipher, KEY, IV);
215c7da899bSchristos     }
216c7da899bSchristos     return 0;
217c7da899bSchristos }
21813d40330Schristos 
test_bio_enc_aes_128_cbc(int idx)21913d40330Schristos static int test_bio_enc_aes_128_cbc(int idx)
22013d40330Schristos {
22113d40330Schristos     return do_test_bio_cipher(EVP_aes_128_cbc(), idx);
22213d40330Schristos }
22313d40330Schristos 
test_bio_enc_aes_128_ctr(int idx)22413d40330Schristos static int test_bio_enc_aes_128_ctr(int idx)
22513d40330Schristos {
22613d40330Schristos     return do_test_bio_cipher(EVP_aes_128_ctr(), idx);
22713d40330Schristos }
22813d40330Schristos 
test_bio_enc_aes_256_cfb(int idx)22913d40330Schristos static int test_bio_enc_aes_256_cfb(int idx)
23013d40330Schristos {
23113d40330Schristos     return do_test_bio_cipher(EVP_aes_256_cfb(), idx);
23213d40330Schristos }
23313d40330Schristos 
test_bio_enc_aes_256_ofb(int idx)23413d40330Schristos static int test_bio_enc_aes_256_ofb(int idx)
23513d40330Schristos {
23613d40330Schristos     return do_test_bio_cipher(EVP_aes_256_ofb(), idx);
23713d40330Schristos }
23813d40330Schristos 
23913d40330Schristos # ifndef OPENSSL_NO_CHACHA
test_bio_enc_chacha20(int idx)24013d40330Schristos static int test_bio_enc_chacha20(int idx)
24113d40330Schristos {
24213d40330Schristos     return do_test_bio_cipher(EVP_chacha20(), idx);
24313d40330Schristos }
24413d40330Schristos 
24513d40330Schristos #  ifndef OPENSSL_NO_POLY1305
test_bio_enc_chacha20_poly1305(int idx)24613d40330Schristos static int test_bio_enc_chacha20_poly1305(int idx)
24713d40330Schristos {
24813d40330Schristos     return do_test_bio_cipher(EVP_chacha20_poly1305(), idx);
24913d40330Schristos }
25013d40330Schristos #  endif
25113d40330Schristos # endif
25213d40330Schristos 
setup_tests(void)25313d40330Schristos int setup_tests(void)
25413d40330Schristos {
25513d40330Schristos     ADD_ALL_TESTS(test_bio_enc_aes_128_cbc, 2);
25613d40330Schristos     ADD_ALL_TESTS(test_bio_enc_aes_128_ctr, 2);
25713d40330Schristos     ADD_ALL_TESTS(test_bio_enc_aes_256_cfb, 2);
25813d40330Schristos     ADD_ALL_TESTS(test_bio_enc_aes_256_ofb, 2);
25913d40330Schristos # ifndef OPENSSL_NO_CHACHA
26013d40330Schristos     ADD_ALL_TESTS(test_bio_enc_chacha20, 2);
26113d40330Schristos #  ifndef OPENSSL_NO_POLY1305
26213d40330Schristos     ADD_ALL_TESTS(test_bio_enc_chacha20_poly1305, 2);
26313d40330Schristos #  endif
26413d40330Schristos # endif
26513d40330Schristos     return 1;
26613d40330Schristos }
267