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