xref: /src/crypto/openssl/test/pbetest.c (revision f25b8c9fb4f58cf61adb47d7570abe7caa6d385d)
1 /*
2  * Copyright 2021-2023 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 #include <string.h>
11 
12 #include "testutil.h"
13 
14 #include <openssl/evp.h>
15 #include <openssl/x509.h>
16 #include <openssl/rc4.h>
17 #include <openssl/md5.h>
18 #include <openssl/configuration.h>
19 #include <openssl/provider.h>
20 
21 #if !defined OPENSSL_NO_RC4 && !defined OPENSSL_NO_MD5 \
22     || !defined OPENSSL_NO_DES && !defined OPENSSL_NO_SHA1
23 static const char pbe_password[] = "MyVoiceIsMyPassport";
24 
25 static unsigned char pbe_salt[] = {
26     0x01,
27     0x02,
28     0x03,
29     0x04,
30     0x05,
31     0x06,
32     0x07,
33     0x08,
34 };
35 
36 static const int pbe_iter = 1000;
37 
38 static unsigned char pbe_plaintext[] = {
39     0x57,
40     0x65,
41     0x20,
42     0x61,
43     0x72,
44     0x65,
45     0x20,
46     0x61,
47     0x6c,
48     0x6c,
49     0x20,
50     0x6d,
51     0x61,
52     0x64,
53     0x65,
54     0x20,
55     0x6f,
56     0x66,
57     0x20,
58     0x73,
59     0x74,
60     0x61,
61     0x72,
62     0x73,
63 };
64 #endif
65 
66 /* Expected output generated using OpenSSL 1.1.1 */
67 
68 #if !defined OPENSSL_NO_RC4 && !defined OPENSSL_NO_MD5
69 static const unsigned char pbe_ciphertext_rc4_md5[] = {
70     0x21,
71     0x90,
72     0xfa,
73     0xee,
74     0x95,
75     0x66,
76     0x59,
77     0x45,
78     0xfa,
79     0x1e,
80     0x9f,
81     0xe2,
82     0x25,
83     0xd2,
84     0xf9,
85     0x71,
86     0x94,
87     0xe4,
88     0x3d,
89     0xc9,
90     0x7c,
91     0xb0,
92     0x07,
93     0x23,
94 };
95 #endif
96 
97 #if !defined OPENSSL_NO_DES && !defined OPENSSL_NO_SHA1
98 static const unsigned char pbe_ciphertext_des_sha1[] = {
99     0xce,
100     0x4b,
101     0xb0,
102     0x0a,
103     0x7b,
104     0x48,
105     0xd7,
106     0xe3,
107     0x9a,
108     0x9f,
109     0x46,
110     0xd6,
111     0x41,
112     0x42,
113     0x4b,
114     0x44,
115     0x36,
116     0x45,
117     0x5f,
118     0x60,
119     0x8f,
120     0x3c,
121     0xd0,
122     0x55,
123     0xd0,
124     0x8d,
125     0xa9,
126     0xab,
127     0x78,
128     0x5b,
129     0x63,
130     0xaf,
131 };
132 #endif
133 
134 #if !defined OPENSSL_NO_RC4 && !defined OPENSSL_NO_MD5 \
135     || !defined OPENSSL_NO_DES && !defined OPENSSL_NO_SHA1
test_pkcs5_pbe(const EVP_CIPHER * cipher,const EVP_MD * md,const unsigned char * exp,const int exp_len)136 static int test_pkcs5_pbe(const EVP_CIPHER *cipher, const EVP_MD *md,
137     const unsigned char *exp, const int exp_len)
138 {
139     int ret = 0;
140     EVP_CIPHER_CTX *ctx;
141     X509_ALGOR *algor = NULL;
142     int i, outlen;
143     unsigned char out[32];
144 
145     ctx = EVP_CIPHER_CTX_new();
146     if (!TEST_ptr(ctx))
147         goto err;
148 
149     algor = X509_ALGOR_new();
150     if (!TEST_ptr(algor))
151         goto err;
152 
153     if (!TEST_true(PKCS5_pbe_set0_algor(algor, EVP_CIPHER_nid(cipher), pbe_iter,
154             pbe_salt, sizeof(pbe_salt)))
155         || !TEST_true(PKCS5_PBE_keyivgen(ctx, pbe_password, strlen(pbe_password),
156             algor->parameter, cipher, md, 1))
157         || !TEST_true(EVP_CipherUpdate(ctx, out, &i, pbe_plaintext,
158             sizeof(pbe_plaintext))))
159         goto err;
160     outlen = i;
161 
162     if (!TEST_true(EVP_CipherFinal_ex(ctx, out + i, &i)))
163         goto err;
164     outlen += i;
165 
166     if (!TEST_mem_eq(out, outlen, exp, exp_len))
167         goto err;
168 
169     /* Decrypt */
170 
171     if (!TEST_true(PKCS5_PBE_keyivgen(ctx, pbe_password, strlen(pbe_password),
172             algor->parameter, cipher, md, 0))
173         || !TEST_true(EVP_CipherUpdate(ctx, out, &i, exp, exp_len)))
174         goto err;
175 
176     outlen = i;
177     if (!TEST_true(EVP_CipherFinal_ex(ctx, out + i, &i)))
178         goto err;
179 
180     if (!TEST_mem_eq(out, outlen, pbe_plaintext, sizeof(pbe_plaintext)))
181         goto err;
182 
183     ret = 1;
184 err:
185     EVP_CIPHER_CTX_free(ctx);
186     X509_ALGOR_free(algor);
187     return ret;
188 }
189 #endif
190 
191 #if !defined OPENSSL_NO_RC4 && !defined OPENSSL_NO_MD5
test_pkcs5_pbe_rc4_md5(void)192 static int test_pkcs5_pbe_rc4_md5(void)
193 {
194     return test_pkcs5_pbe(EVP_rc4(), EVP_md5(), pbe_ciphertext_rc4_md5, sizeof(pbe_ciphertext_rc4_md5));
195 }
196 #endif
197 
198 #if !defined OPENSSL_NO_DES && !defined OPENSSL_NO_SHA1
test_pkcs5_pbe_des_sha1(void)199 static int test_pkcs5_pbe_des_sha1(void)
200 {
201     return test_pkcs5_pbe(EVP_des_cbc(), EVP_sha1(), pbe_ciphertext_des_sha1, sizeof(pbe_ciphertext_des_sha1));
202 }
203 #endif
204 
205 #ifdef OPENSSL_NO_AUTOLOAD_CONFIG
206 /*
207  * For configurations where we are not autoloading configuration, we need
208  * to access the legacy provider.  The easiest way is to load both the
209  * legacy and default providers directly and unload them on termination.
210  */
211 static OSSL_PROVIDER *legacy, *dflt;
212 #endif
213 
setup_tests(void)214 int setup_tests(void)
215 {
216 #ifdef OPENSSL_NO_AUTOLOAD_CONFIG
217     /* Load required providers if not done via configuration */
218     legacy = OSSL_PROVIDER_load(NULL, "legacy");
219     dflt = OSSL_PROVIDER_load(NULL, "default");
220     if (!TEST_ptr(legacy) || !TEST_ptr(dflt)) {
221         cleanup_tests();
222         return -1;
223     }
224 #endif
225 
226 #if !defined OPENSSL_NO_RC4 && !defined OPENSSL_NO_MD5
227     ADD_TEST(test_pkcs5_pbe_rc4_md5);
228 #endif
229 #if !defined OPENSSL_NO_DES && !defined OPENSSL_NO_SHA1
230     ADD_TEST(test_pkcs5_pbe_des_sha1);
231 #endif
232 
233     return 1;
234 }
235 
236 #ifdef OPENSSL_NO_AUTOLOAD_CONFIG
cleanup_tests(void)237 void cleanup_tests(void)
238 {
239     /* Dispose of providers */
240     OSSL_PROVIDER_unload(legacy);
241     OSSL_PROVIDER_unload(dflt);
242     legacy = dflt = NULL;
243 }
244 #endif
245