Adapt all build.info and test recipes to the new $disabled{'deprecated-x.y'}
[openssl.git] / test / evp_fetch_prov_test.c
1 /*
2  * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (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
10 /*
11  * SHA256 low level APIs are deprecated for public use, but still ok for
12  * internal use.  Note, that due to symbols not being exported, only the
13  * #defines can be accessed.  In this case SHA256_CBLOCK.
14  */
15 #include "internal/deprecated.h"
16
17 #include <string.h>
18 #include <openssl/sha.h>
19 #include <openssl/evp.h>
20 #include <openssl/provider.h>
21 #include "testutil.h"
22
23 static char *alg = "digest";
24 static int use_default_ctx = 0;
25 static char *fetch_property = NULL;
26 static int expected_fetch_result = 1;
27
28 typedef enum OPTION_choice {
29     OPT_ERR = -1,
30     OPT_EOF = 0,
31     OPT_ALG_FETCH_TYPE,
32     OPT_FETCH_PROPERTY,
33     OPT_FETCH_FAILURE,
34     OPT_USE_DEFAULTCTX,
35     OPT_TEST_ENUM
36 } OPTION_CHOICE;
37
38 const OPTIONS *test_get_options(void)
39 {
40     static const OPTIONS test_options[] = {
41         OPT_TEST_OPTIONS_WITH_EXTRA_USAGE("[provname...]\n"),
42         { "type", OPT_ALG_FETCH_TYPE, 's', "The fetch type to test" },
43         { "property", OPT_FETCH_PROPERTY, 's', "The fetch property e.g. fips=yes" },
44         { "fetchfail", OPT_FETCH_FAILURE, '-', "fetch is expected to fail" },
45         { "defaultctx", OPT_USE_DEFAULTCTX, '-',
46           "Use the default context if this is set" },
47         { OPT_HELP_STR, 1, '-',
48           "file\tProvider names to explicitly load\n" },
49         { NULL }
50     };
51     return test_options;
52 }
53
54 static int calculate_digest(const EVP_MD *md, const char *msg, size_t len,
55                             const unsigned char *exptd)
56 {
57     unsigned char out[SHA256_DIGEST_LENGTH];
58     EVP_MD_CTX *ctx;
59     int ret = 0;
60
61     if (!TEST_ptr(ctx = EVP_MD_CTX_new())
62             || !TEST_true(EVP_DigestInit_ex(ctx, md, NULL))
63             || !TEST_true(EVP_DigestUpdate(ctx, msg, len))
64             || !TEST_true(EVP_DigestFinal_ex(ctx, out, NULL))
65             || !TEST_mem_eq(out, SHA256_DIGEST_LENGTH, exptd,
66                             SHA256_DIGEST_LENGTH)
67             || !TEST_true(md == EVP_MD_CTX_md(ctx)))
68         goto err;
69
70     ret = 1;
71  err:
72     EVP_MD_CTX_free(ctx);
73     return ret;
74 }
75
76 static int load_providers(OPENSSL_CTX **libctx, OSSL_PROVIDER *prov[])
77 {
78     OPENSSL_CTX *ctx;
79     int ret = 0;
80     size_t i;
81
82     ctx = OPENSSL_CTX_new();
83     if (!TEST_ptr(ctx))
84         goto err;
85
86     if (test_get_argument_count() > 2)
87         goto err;
88
89     for (i = 0; i < test_get_argument_count(); ++i) {
90         char *provname = test_get_argument(i);
91         prov[i] = OSSL_PROVIDER_load(ctx, provname);
92         if (!TEST_ptr(prov[i]))
93             goto err;
94     }
95     ret = 1;
96     *libctx = ctx;
97 err:
98     return ret;
99 }
100
101 /*
102  * Test EVP_MD_fetch()
103  */
104 static int test_EVP_MD_fetch(void)
105 {
106     OPENSSL_CTX *ctx = NULL;
107     EVP_MD *md = NULL;
108     OSSL_PROVIDER *prov[2] = {NULL, NULL};
109     int ret = 0;
110     const char testmsg[] = "Hello world";
111     const unsigned char exptd[] = {
112       0x27, 0x51, 0x8b, 0xa9, 0x68, 0x30, 0x11, 0xf6, 0xb3, 0x96, 0x07, 0x2c,
113       0x05, 0xf6, 0x65, 0x6d, 0x04, 0xf5, 0xfb, 0xc3, 0x78, 0x7c, 0xf9, 0x24,
114       0x90, 0xec, 0x60, 0x6e, 0x50, 0x92, 0xe3, 0x26
115     };
116
117     if (use_default_ctx == 0 && !load_providers(&ctx, prov))
118         goto err;
119
120     /* Implicit fetching of the MD should produce the expected result */
121     if (!TEST_true(calculate_digest(EVP_sha256(), testmsg, sizeof(testmsg),
122                                     exptd))
123             || !TEST_int_eq(EVP_MD_size(EVP_sha256()), SHA256_DIGEST_LENGTH)
124             || !TEST_int_eq(EVP_MD_block_size(EVP_sha256()), SHA256_CBLOCK))
125         goto err;
126
127     /* Fetch the digest from a provider using properties. */
128     md = EVP_MD_fetch(ctx, "SHA256", fetch_property);
129     if (expected_fetch_result != 0) {
130         if (!TEST_ptr(md)
131             || !TEST_int_eq(EVP_MD_nid(md), NID_sha256)
132             || !TEST_true(calculate_digest(md, testmsg, sizeof(testmsg), exptd))
133             || !TEST_int_eq(EVP_MD_size(md), SHA256_DIGEST_LENGTH)
134             || !TEST_int_eq(EVP_MD_block_size(md), SHA256_CBLOCK))
135         goto err;
136
137         /* Also test EVP_MD_up_ref() while we're doing this */
138         if (!TEST_true(EVP_MD_up_ref(md)))
139             goto err;
140         /* Ref count should now be 2. Release first one here */
141         EVP_MD_meth_free(md);
142     } else {
143         if (!TEST_ptr_null(md))
144             goto err;
145     }
146     ret = 1;
147
148 err:
149     EVP_MD_meth_free(md);
150     OSSL_PROVIDER_unload(prov[0]);
151     OSSL_PROVIDER_unload(prov[1]);
152     /* Not normally needed, but we would like to test that
153      * OPENSSL_thread_stop_ex() behaves as expected.
154      */
155     if (ctx != NULL) {
156         OPENSSL_thread_stop_ex(ctx);
157         OPENSSL_CTX_free(ctx);
158     }
159     return ret;
160 }
161
162 static int encrypt_decrypt(const EVP_CIPHER *cipher, const unsigned char *msg,
163                            size_t len)
164 {
165     int ret = 0, ctlen, ptlen;
166     EVP_CIPHER_CTX *ctx = NULL;
167     unsigned char key[128 / 8];
168     unsigned char ct[64], pt[64];
169
170     memset(key, 0, sizeof(key));
171     if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())
172             || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, 1))
173             || !TEST_true(EVP_CipherUpdate(ctx, ct, &ctlen, msg, len))
174             || !TEST_true(EVP_CipherFinal_ex(ctx, ct, &ctlen))
175             || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, 0))
176             || !TEST_true(EVP_CipherUpdate(ctx, pt, &ptlen, ct, ctlen))
177             || !TEST_true(EVP_CipherFinal_ex(ctx, pt, &ptlen))
178             || !TEST_mem_eq(pt, ptlen, msg, len))
179         goto err;
180
181     ret = 1;
182 err:
183     EVP_CIPHER_CTX_free(ctx);
184     return ret;
185 }
186
187 /*
188  * Test EVP_CIPHER_fetch()
189  */
190 static int test_EVP_CIPHER_fetch(void)
191 {
192     OPENSSL_CTX *ctx = NULL;
193     EVP_CIPHER *cipher = NULL;
194     OSSL_PROVIDER *prov[2] = {NULL, NULL};
195     int ret = 0;
196     const unsigned char testmsg[] = "Hello world";
197
198     if (use_default_ctx == 0 && !load_providers(&ctx, prov))
199         goto err;
200
201     /* Implicit fetching of the cipher should produce the expected result */
202     if (!TEST_true(encrypt_decrypt(EVP_aes_128_cbc(), testmsg, sizeof(testmsg))))
203         goto err;
204
205     /* Fetch the cipher from a provider using properties. */
206     cipher = EVP_CIPHER_fetch(ctx, "AES-128-CBC", fetch_property);
207     if (expected_fetch_result != 0) {
208         if (!TEST_ptr(cipher)
209             || !TEST_true(encrypt_decrypt(cipher, testmsg, sizeof(testmsg)))) {
210             if (!TEST_true(EVP_CIPHER_up_ref(cipher)))
211                 goto err;
212             /* Ref count should now be 2. Release first one here */
213             EVP_CIPHER_meth_free(cipher);
214         }
215     } else {
216         if (!TEST_ptr_null(cipher))
217             goto err;
218     }
219     ret = 1;
220 err:
221     EVP_CIPHER_meth_free(cipher);
222     OSSL_PROVIDER_unload(prov[0]);
223     OSSL_PROVIDER_unload(prov[1]);
224     OPENSSL_CTX_free(ctx);
225     return ret;
226 }
227
228 int setup_tests(void)
229 {
230     OPTION_CHOICE o;
231
232     while ((o = opt_next()) != OPT_EOF) {
233         switch (o) {
234         case OPT_ALG_FETCH_TYPE:
235             alg = opt_arg();
236             break;
237         case OPT_FETCH_PROPERTY:
238             fetch_property = opt_arg();
239             break;
240         case OPT_FETCH_FAILURE:
241             expected_fetch_result = 0;
242             break;
243         case OPT_USE_DEFAULTCTX:
244             use_default_ctx = 1;
245             break;
246         case OPT_TEST_CASES:
247            break;
248         default:
249         case OPT_ERR:
250             return 0;
251         }
252     }
253     if (strcmp(alg, "digest") == 0)
254         ADD_TEST(test_EVP_MD_fetch);
255     else
256         ADD_TEST(test_EVP_CIPHER_fetch);
257     return 1;
258 }