1b0d17251Schristos /*
2*4778aedeSchristos * Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved.
3b0d17251Schristos *
4b0d17251Schristos * Licensed under the Apache License 2.0 (the "License"). You may not use
5b0d17251Schristos * this file except in compliance with the License. You can obtain a copy
6b0d17251Schristos * in the file LICENSE in the source distribution or at
7b0d17251Schristos * https://www.openssl.org/source/license.html
8b0d17251Schristos */
9b0d17251Schristos
10b0d17251Schristos #include <string.h>
11b0d17251Schristos
12b0d17251Schristos #include "testutil.h"
13b0d17251Schristos
14b0d17251Schristos #include <openssl/evp.h>
15b0d17251Schristos #include <openssl/x509.h>
16b0d17251Schristos #include <openssl/rc4.h>
17b0d17251Schristos #include <openssl/md5.h>
18*4778aedeSchristos #include <openssl/configuration.h>
19*4778aedeSchristos #include <openssl/provider.h>
20b0d17251Schristos
21b0d17251Schristos #if !defined OPENSSL_NO_RC4 && !defined OPENSSL_NO_MD5 \
22b0d17251Schristos || !defined OPENSSL_NO_DES && !defined OPENSSL_NO_SHA1
23b0d17251Schristos static const char pbe_password[] = "MyVoiceIsMyPassport";
24b0d17251Schristos
25b0d17251Schristos static unsigned char pbe_salt[] = {
26b0d17251Schristos 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
27b0d17251Schristos };
28b0d17251Schristos
29b0d17251Schristos static const int pbe_iter = 1000;
30b0d17251Schristos
31b0d17251Schristos static unsigned char pbe_plaintext[] = {
32b0d17251Schristos 0x57, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61,
33b0d17251Schristos 0x6c, 0x6c, 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20,
34b0d17251Schristos 0x6f, 0x66, 0x20, 0x73, 0x74, 0x61, 0x72, 0x73,
35b0d17251Schristos };
36b0d17251Schristos #endif
37b0d17251Schristos
38b0d17251Schristos /* Expected output generated using OpenSSL 1.1.1 */
39b0d17251Schristos
40b0d17251Schristos #if !defined OPENSSL_NO_RC4 && !defined OPENSSL_NO_MD5
41b0d17251Schristos static const unsigned char pbe_ciphertext_rc4_md5[] = {
42b0d17251Schristos 0x21, 0x90, 0xfa, 0xee, 0x95, 0x66, 0x59, 0x45,
43b0d17251Schristos 0xfa, 0x1e, 0x9f, 0xe2, 0x25, 0xd2, 0xf9, 0x71,
44b0d17251Schristos 0x94, 0xe4, 0x3d, 0xc9, 0x7c, 0xb0, 0x07, 0x23,
45b0d17251Schristos };
46b0d17251Schristos #endif
47b0d17251Schristos
48b0d17251Schristos #if !defined OPENSSL_NO_DES && !defined OPENSSL_NO_SHA1
49b0d17251Schristos static const unsigned char pbe_ciphertext_des_sha1[] = {
50b0d17251Schristos 0xce, 0x4b, 0xb0, 0x0a, 0x7b, 0x48, 0xd7, 0xe3,
51b0d17251Schristos 0x9a, 0x9f, 0x46, 0xd6, 0x41, 0x42, 0x4b, 0x44,
52b0d17251Schristos 0x36, 0x45, 0x5f, 0x60, 0x8f, 0x3c, 0xd0, 0x55,
53b0d17251Schristos 0xd0, 0x8d, 0xa9, 0xab, 0x78, 0x5b, 0x63, 0xaf,
54b0d17251Schristos };
55b0d17251Schristos #endif
56b0d17251Schristos
57b0d17251Schristos #if !defined OPENSSL_NO_RC4 && !defined OPENSSL_NO_MD5 \
58b0d17251Schristos || !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)59b0d17251Schristos static int test_pkcs5_pbe(const EVP_CIPHER *cipher, const EVP_MD *md,
60b0d17251Schristos const unsigned char *exp, const int exp_len)
61b0d17251Schristos {
62b0d17251Schristos int ret = 0;
63b0d17251Schristos EVP_CIPHER_CTX *ctx;
64b0d17251Schristos X509_ALGOR *algor = NULL;
65b0d17251Schristos int i, outlen;
66b0d17251Schristos unsigned char out[32];
67b0d17251Schristos
68b0d17251Schristos ctx = EVP_CIPHER_CTX_new();
69b0d17251Schristos if (!TEST_ptr(ctx))
70b0d17251Schristos goto err;
71b0d17251Schristos
72b0d17251Schristos algor = X509_ALGOR_new();
73b0d17251Schristos if (!TEST_ptr(algor))
74b0d17251Schristos goto err;
75b0d17251Schristos
76b0d17251Schristos if (!TEST_true(PKCS5_pbe_set0_algor(algor, EVP_CIPHER_nid(cipher), pbe_iter,
77b0d17251Schristos pbe_salt, sizeof(pbe_salt)))
78b0d17251Schristos || !TEST_true(PKCS5_PBE_keyivgen(ctx, pbe_password, strlen(pbe_password),
79b0d17251Schristos algor->parameter, cipher, md, 1))
80b0d17251Schristos || !TEST_true(EVP_CipherUpdate(ctx, out, &i, pbe_plaintext,
81b0d17251Schristos sizeof(pbe_plaintext))))
82b0d17251Schristos goto err;
83b0d17251Schristos outlen = i;
84b0d17251Schristos
85b0d17251Schristos if (!TEST_true(EVP_CipherFinal_ex(ctx, out + i, &i)))
86b0d17251Schristos goto err;
87b0d17251Schristos outlen += i;
88b0d17251Schristos
89b0d17251Schristos if (!TEST_mem_eq(out, outlen, exp, exp_len))
90b0d17251Schristos goto err;
91b0d17251Schristos
92b0d17251Schristos /* Decrypt */
93b0d17251Schristos
94b0d17251Schristos if (!TEST_true(PKCS5_PBE_keyivgen(ctx, pbe_password, strlen(pbe_password),
95b0d17251Schristos algor->parameter, cipher, md, 0))
96b0d17251Schristos || !TEST_true(EVP_CipherUpdate(ctx, out, &i, exp, exp_len)))
97b0d17251Schristos goto err;
98b0d17251Schristos
99b0d17251Schristos outlen = i;
100b0d17251Schristos if (!TEST_true(EVP_CipherFinal_ex(ctx, out + i, &i)))
101b0d17251Schristos goto err;
102b0d17251Schristos
103b0d17251Schristos if (!TEST_mem_eq(out, outlen, pbe_plaintext, sizeof(pbe_plaintext)))
104b0d17251Schristos goto err;
105b0d17251Schristos
106b0d17251Schristos ret = 1;
107b0d17251Schristos err:
108b0d17251Schristos EVP_CIPHER_CTX_free(ctx);
109b0d17251Schristos X509_ALGOR_free(algor);
110b0d17251Schristos return ret;
111b0d17251Schristos }
112b0d17251Schristos #endif
113b0d17251Schristos
114b0d17251Schristos #if !defined OPENSSL_NO_RC4 && !defined OPENSSL_NO_MD5
test_pkcs5_pbe_rc4_md5(void)115b0d17251Schristos static int test_pkcs5_pbe_rc4_md5(void)
116b0d17251Schristos {
117b0d17251Schristos return test_pkcs5_pbe(EVP_rc4(), EVP_md5(), pbe_ciphertext_rc4_md5, sizeof(pbe_ciphertext_rc4_md5));
118b0d17251Schristos }
119b0d17251Schristos #endif
120b0d17251Schristos
121b0d17251Schristos #if !defined OPENSSL_NO_DES && !defined OPENSSL_NO_SHA1
test_pkcs5_pbe_des_sha1(void)122b0d17251Schristos static int test_pkcs5_pbe_des_sha1(void)
123b0d17251Schristos {
124b0d17251Schristos return test_pkcs5_pbe(EVP_des_cbc(), EVP_sha1(), pbe_ciphertext_des_sha1, sizeof(pbe_ciphertext_des_sha1));
125b0d17251Schristos }
126b0d17251Schristos #endif
127b0d17251Schristos
128*4778aedeSchristos #ifdef OPENSSL_NO_AUTOLOAD_CONFIG
129*4778aedeSchristos /*
130*4778aedeSchristos * For configurations where we are not autoloading configuration, we need
131*4778aedeSchristos * to access the legacy provider. The easiest way is to load both the
132*4778aedeSchristos * legacy and default providers directly and unload them on termination.
133*4778aedeSchristos */
134*4778aedeSchristos static OSSL_PROVIDER *legacy, *dflt;
135*4778aedeSchristos #endif
136*4778aedeSchristos
setup_tests(void)137b0d17251Schristos int setup_tests(void)
138b0d17251Schristos {
139*4778aedeSchristos #ifdef OPENSSL_NO_AUTOLOAD_CONFIG
140*4778aedeSchristos /* Load required providers if not done via configuration */
141*4778aedeSchristos legacy = OSSL_PROVIDER_load(NULL, "legacy");
142*4778aedeSchristos dflt = OSSL_PROVIDER_load(NULL, "default");
143*4778aedeSchristos if (!TEST_ptr(legacy) || !TEST_ptr(dflt)) {
144*4778aedeSchristos cleanup_tests();
145*4778aedeSchristos return -1;
146*4778aedeSchristos }
147*4778aedeSchristos #endif
148*4778aedeSchristos
149b0d17251Schristos #if !defined OPENSSL_NO_RC4 && !defined OPENSSL_NO_MD5
150b0d17251Schristos ADD_TEST(test_pkcs5_pbe_rc4_md5);
151b0d17251Schristos #endif
152b0d17251Schristos #if !defined OPENSSL_NO_DES && !defined OPENSSL_NO_SHA1
153b0d17251Schristos ADD_TEST(test_pkcs5_pbe_des_sha1);
154b0d17251Schristos #endif
155b0d17251Schristos
156b0d17251Schristos return 1;
157b0d17251Schristos }
158*4778aedeSchristos
159*4778aedeSchristos #ifdef OPENSSL_NO_AUTOLOAD_CONFIG
cleanup_tests(void)160*4778aedeSchristos void cleanup_tests(void)
161*4778aedeSchristos {
162*4778aedeSchristos /* Dispose of providers */
163*4778aedeSchristos OSSL_PROVIDER_unload(legacy);
164*4778aedeSchristos OSSL_PROVIDER_unload(dflt);
165*4778aedeSchristos legacy = dflt = NULL;
166*4778aedeSchristos }
167*4778aedeSchristos #endif
168