p5_pbev2.c
Go to the documentation of this file.
1 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2  * project 1999-2004.
3  */
4 /* ====================================================================
5  * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in
16  * the documentation and/or other materials provided with the
17  * distribution.
18  *
19  * 3. All advertising materials mentioning features or use of this
20  * software must display the following acknowledgment:
21  * "This product includes software developed by the OpenSSL Project
22  * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23  *
24  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25  * endorse or promote products derived from this software without
26  * prior written permission. For written permission, please contact
27  * licensing@OpenSSL.org.
28  *
29  * 5. Products derived from this software may not be called "OpenSSL"
30  * nor may "OpenSSL" appear in their names without prior written
31  * permission of the OpenSSL Project.
32  *
33  * 6. Redistributions of any form whatsoever must retain the following
34  * acknowledgment:
35  * "This product includes software developed by the OpenSSL Project
36  * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49  * OF THE POSSIBILITY OF SUCH DAMAGE.
50  * ====================================================================
51  *
52  * This product includes cryptographic software written by Eric Young
53  * (eay@cryptsoft.com). This product includes software written by Tim
54  * Hudson (tjh@cryptsoft.com). */
55 
56 #include <openssl/pkcs8.h>
57 
58 #include <limits.h>
59 #include <string.h>
60 
61 #include <openssl/bytestring.h>
62 #include <openssl/cipher.h>
63 #include <openssl/err.h>
64 #include <openssl/mem.h>
65 #include <openssl/nid.h>
66 #include <openssl/rand.h>
67 
68 #include "internal.h"
69 #include "../internal.h"
70 
71 
72 // 1.2.840.113549.1.5.12
73 static const uint8_t kPBKDF2[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
74  0x0d, 0x01, 0x05, 0x0c};
75 
76 // 1.2.840.113549.1.5.13
77 static const uint8_t kPBES2[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
78  0x0d, 0x01, 0x05, 0x0d};
79 
80 // 1.2.840.113549.2.7
81 static const uint8_t kHMACWithSHA1[] = {0x2a, 0x86, 0x48, 0x86,
82  0xf7, 0x0d, 0x02, 0x07};
83 
84 // 1.2.840.113549.2.9
85 static const uint8_t kHMACWithSHA256[] = {0x2a, 0x86, 0x48, 0x86,
86  0xf7, 0x0d, 0x02, 0x09};
87 
88 static const struct {
91  int nid;
92  const EVP_CIPHER *(*cipher_func)(void);
93 } kCipherOIDs[] = {
94  // 1.2.840.113549.3.2
95  {{0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02},
96  8,
98  &EVP_rc2_cbc},
99  // 1.2.840.113549.3.7
100  {{0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07},
101  8,
104  // 2.16.840.1.101.3.4.1.2
105  {{0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x02},
106  9,
108  &EVP_aes_128_cbc},
109  // 2.16.840.1.101.3.4.1.22
110  {{0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x16},
111  9,
113  &EVP_aes_192_cbc},
114  // 2.16.840.1.101.3.4.1.42
115  {{0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2a},
116  9,
118  &EVP_aes_256_cbc},
119 };
120 
121 static const EVP_CIPHER *cbs_to_cipher(const CBS *cbs) {
122  for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kCipherOIDs); i++) {
124  return kCipherOIDs[i].cipher_func();
125  }
126  }
127 
128  return NULL;
129 }
130 
131 static int add_cipher_oid(CBB *out, int nid) {
132  for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kCipherOIDs); i++) {
133  if (kCipherOIDs[i].nid == nid) {
134  CBB child;
135  return CBB_add_asn1(out, &child, CBS_ASN1_OBJECT) &&
137  kCipherOIDs[i].oid_len) &&
138  CBB_flush(out);
139  }
140  }
141 
143  return 0;
144 }
145 
147  const EVP_MD *pbkdf2_md, unsigned iterations,
148  const char *pass, size_t pass_len,
149  const uint8_t *salt, size_t salt_len,
150  const uint8_t *iv, size_t iv_len, int enc) {
151  if (iv_len != EVP_CIPHER_iv_length(cipher)) {
153  return 0;
154  }
155 
157  int ret = PKCS5_PBKDF2_HMAC(pass, pass_len, salt, salt_len, iterations,
158  pbkdf2_md, EVP_CIPHER_key_length(cipher), key) &&
159  EVP_CipherInit_ex(ctx, cipher, NULL /* engine */, key, iv, enc);
161  return ret;
162 }
163 
165  const EVP_CIPHER *cipher, unsigned iterations,
166  const char *pass, size_t pass_len,
167  const uint8_t *salt, size_t salt_len) {
168  int cipher_nid = EVP_CIPHER_nid(cipher);
169  if (cipher_nid == NID_undef) {
171  return 0;
172  }
173 
174  // Generate a random IV.
176  if (!RAND_bytes(iv, EVP_CIPHER_iv_length(cipher))) {
177  return 0;
178  }
179 
180  // See RFC 2898, appendix A.
181  CBB algorithm, oid, param, kdf, kdf_oid, kdf_param, salt_cbb, cipher_cbb,
182  iv_cbb;
183  if (!CBB_add_asn1(out, &algorithm, CBS_ASN1_SEQUENCE) ||
184  !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
185  !CBB_add_bytes(&oid, kPBES2, sizeof(kPBES2)) ||
186  !CBB_add_asn1(&algorithm, &param, CBS_ASN1_SEQUENCE) ||
187  !CBB_add_asn1(&param, &kdf, CBS_ASN1_SEQUENCE) ||
188  !CBB_add_asn1(&kdf, &kdf_oid, CBS_ASN1_OBJECT) ||
189  !CBB_add_bytes(&kdf_oid, kPBKDF2, sizeof(kPBKDF2)) ||
190  !CBB_add_asn1(&kdf, &kdf_param, CBS_ASN1_SEQUENCE) ||
191  !CBB_add_asn1(&kdf_param, &salt_cbb, CBS_ASN1_OCTETSTRING) ||
192  !CBB_add_bytes(&salt_cbb, salt, salt_len) ||
193  !CBB_add_asn1_uint64(&kdf_param, iterations) ||
194  // Specify a key length for RC2.
195  (cipher_nid == NID_rc2_cbc &&
196  !CBB_add_asn1_uint64(&kdf_param, EVP_CIPHER_key_length(cipher))) ||
197  // Omit the PRF. We use the default hmacWithSHA1.
198  !CBB_add_asn1(&param, &cipher_cbb, CBS_ASN1_SEQUENCE) ||
199  !add_cipher_oid(&cipher_cbb, cipher_nid) ||
200  // RFC 2898 says RC2-CBC and RC5-CBC-Pad use a SEQUENCE with version and
201  // IV, but OpenSSL always uses an OCTET STRING IV, so we do the same.
202  !CBB_add_asn1(&cipher_cbb, &iv_cbb, CBS_ASN1_OCTETSTRING) ||
203  !CBB_add_bytes(&iv_cbb, iv, EVP_CIPHER_iv_length(cipher)) ||
204  !CBB_flush(out)) {
205  return 0;
206  }
207 
208  return pkcs5_pbe2_cipher_init(ctx, cipher, EVP_sha1(), iterations, pass,
209  pass_len, salt, salt_len, iv,
210  EVP_CIPHER_iv_length(cipher), 1 /* encrypt */);
211 }
212 
214  const char *pass, size_t pass_len, CBS *param) {
215  CBS pbe_param, kdf, kdf_obj, enc_scheme, enc_obj;
216  if (!CBS_get_asn1(param, &pbe_param, CBS_ASN1_SEQUENCE) ||
217  CBS_len(param) != 0 ||
218  !CBS_get_asn1(&pbe_param, &kdf, CBS_ASN1_SEQUENCE) ||
219  !CBS_get_asn1(&pbe_param, &enc_scheme, CBS_ASN1_SEQUENCE) ||
220  CBS_len(&pbe_param) != 0 ||
221  !CBS_get_asn1(&kdf, &kdf_obj, CBS_ASN1_OBJECT) ||
222  !CBS_get_asn1(&enc_scheme, &enc_obj, CBS_ASN1_OBJECT)) {
224  return 0;
225  }
226 
227  // Only PBKDF2 is supported.
228  if (!CBS_mem_equal(&kdf_obj, kPBKDF2, sizeof(kPBKDF2))) {
230  return 0;
231  }
232 
233  // See if we recognise the encryption algorithm.
234  const EVP_CIPHER *cipher = cbs_to_cipher(&enc_obj);
235  if (cipher == NULL) {
237  return 0;
238  }
239 
240  // Parse the KDF parameters. See RFC 8018, appendix A.2.
241  CBS pbkdf2_params, salt;
242  uint64_t iterations;
243  if (!CBS_get_asn1(&kdf, &pbkdf2_params, CBS_ASN1_SEQUENCE) ||
244  CBS_len(&kdf) != 0 ||
245  !CBS_get_asn1(&pbkdf2_params, &salt, CBS_ASN1_OCTETSTRING) ||
246  !CBS_get_asn1_uint64(&pbkdf2_params, &iterations)) {
248  return 0;
249  }
250 
251  if (!pkcs12_iterations_acceptable(iterations)) {
253  return 0;
254  }
255 
256  // The optional keyLength parameter, if present, must match the key length of
257  // the cipher.
258  if (CBS_peek_asn1_tag(&pbkdf2_params, CBS_ASN1_INTEGER)) {
259  uint64_t key_len;
260  if (!CBS_get_asn1_uint64(&pbkdf2_params, &key_len)) {
262  return 0;
263  }
264 
265  if (key_len != EVP_CIPHER_key_length(cipher)) {
267  return 0;
268  }
269  }
270 
271  const EVP_MD *md = EVP_sha1();
272  if (CBS_len(&pbkdf2_params) != 0) {
273  CBS alg_id, prf;
274  if (!CBS_get_asn1(&pbkdf2_params, &alg_id, CBS_ASN1_SEQUENCE) ||
275  !CBS_get_asn1(&alg_id, &prf, CBS_ASN1_OBJECT) ||
276  CBS_len(&pbkdf2_params) != 0) {
278  return 0;
279  }
280 
281  if (CBS_mem_equal(&prf, kHMACWithSHA1, sizeof(kHMACWithSHA1))) {
282  // hmacWithSHA1 is the DEFAULT, so DER requires it be omitted, but we
283  // match OpenSSL in tolerating it being present.
284  md = EVP_sha1();
285  } else if (CBS_mem_equal(&prf, kHMACWithSHA256, sizeof(kHMACWithSHA256))) {
286  md = EVP_sha256();
287  } else {
289  return 0;
290  }
291 
292  // All supported PRFs use a NULL parameter.
293  CBS null;
294  if (!CBS_get_asn1(&alg_id, &null, CBS_ASN1_NULL) ||
295  CBS_len(&null) != 0 ||
296  CBS_len(&alg_id) != 0) {
298  return 0;
299  }
300  }
301 
302  // Parse the encryption scheme parameters. Note OpenSSL does not match the
303  // specification. Per RFC 2898, this should depend on the encryption scheme.
304  // In particular, RC2-CBC uses a SEQUENCE with version and IV. We align with
305  // OpenSSL.
306  CBS iv;
307  if (!CBS_get_asn1(&enc_scheme, &iv, CBS_ASN1_OCTETSTRING) ||
308  CBS_len(&enc_scheme) != 0) {
310  return 0;
311  }
312 
313  return pkcs5_pbe2_cipher_init(ctx, cipher, md, (unsigned)iterations, pass,
314  pass_len, CBS_data(&salt), CBS_len(&salt),
315  CBS_data(&iv), CBS_len(&iv), 0 /* decrypt */);
316 }
CBS_get_asn1_uint64
#define CBS_get_asn1_uint64
Definition: boringssl_prefix_symbols.h:1066
CBS_ASN1_INTEGER
#define CBS_ASN1_INTEGER
Definition: bytestring.h:207
CBB_flush
#define CBB_flush
Definition: boringssl_prefix_symbols.h:1045
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
RAND_bytes
#define RAND_bytes
Definition: boringssl_prefix_symbols.h:2060
cbs_st
Definition: bytestring.h:39
NID_aes_128_cbc
#define NID_aes_128_cbc
Definition: nid.h:1933
ctx
Definition: benchmark-async.c:30
OPENSSL_cleanse
#define OPENSSL_cleanse
Definition: boringssl_prefix_symbols.h:1864
pkcs5_pbe2_cipher_init
static int pkcs5_pbe2_cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, const EVP_MD *pbkdf2_md, unsigned iterations, const char *pass, size_t pass_len, const uint8_t *salt, size_t salt_len, const uint8_t *iv, size_t iv_len, int enc)
Definition: p5_pbev2.c:146
env_md_st
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/digest/internal.h:67
CBS_data
#define CBS_data
Definition: boringssl_prefix_symbols.h:1057
kPBKDF2
static const uint8_t kPBKDF2[]
Definition: p5_pbev2.c:73
regress.suite
suite
Definition: regress/regress.py:22
EVP_MAX_KEY_LENGTH
#define EVP_MAX_KEY_LENGTH
Definition: cipher.h:532
PKCS5_pbe2_decrypt_init
int PKCS5_pbe2_decrypt_init(const struct pbe_suite *suite, EVP_CIPHER_CTX *ctx, const char *pass, size_t pass_len, CBS *param)
Definition: p5_pbev2.c:213
OPENSSL_PUT_ERROR
#define OPENSSL_PUT_ERROR(library, reason)
Definition: err.h:423
internal.h
cbs_to_cipher
static const EVP_CIPHER * cbs_to_cipher(const CBS *cbs)
Definition: p5_pbev2.c:121
EVP_CIPHER_nid
#define EVP_CIPHER_nid
Definition: boringssl_prefix_symbols.h:1488
EVP_aes_256_cbc
const OPENSSL_EXPORT EVP_CIPHER * EVP_aes_256_cbc(void)
string.h
OPENSSL_ARRAY_SIZE
#define OPENSSL_ARRAY_SIZE(array)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:179
CBS_ASN1_OCTETSTRING
#define CBS_ASN1_OCTETSTRING
Definition: bytestring.h:209
EVP_aes_192_cbc
const OPENSSL_EXPORT EVP_CIPHER * EVP_aes_192_cbc(void)
CBS_mem_equal
#define CBS_mem_equal
Definition: boringssl_prefix_symbols.h:1090
CBS_len
#define CBS_len
Definition: boringssl_prefix_symbols.h:1089
EVP_CIPHER_iv_length
#define EVP_CIPHER_iv_length
Definition: boringssl_prefix_symbols.h:1485
kHMACWithSHA1
static const uint8_t kHMACWithSHA1[]
Definition: p5_pbev2.c:81
kPBES2
static const uint8_t kPBES2[]
Definition: p5_pbev2.c:77
nid
int nid
Definition: p5_pbev2.c:91
CBS_get_asn1
#define CBS_get_asn1
Definition: boringssl_prefix_symbols.h:1061
pkcs8.h
cbs
const CBS * cbs
Definition: third_party/boringssl-with-bazel/src/crypto/trust_token/internal.h:107
EVP_rc2_cbc
#define EVP_rc2_cbc
Definition: boringssl_prefix_symbols.h:1745
EVP_sha256
const OPENSSL_EXPORT EVP_MD * EVP_sha256(void)
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
evp_cipher_ctx_st
Definition: cipher.h:536
pkcs12_iterations_acceptable
#define pkcs12_iterations_acceptable
Definition: boringssl_prefix_symbols.h:3323
CBS_ASN1_NULL
#define CBS_ASN1_NULL
Definition: bytestring.h:210
bytestring.h
PKCS8_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION
#define PKCS8_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION
Definition: pkcs8.h:276
CBS_peek_asn1_tag
#define CBS_peek_asn1_tag
Definition: boringssl_prefix_symbols.h:1091
evp_cipher_st
Definition: cipher.h:585
PKCS8_R_UNSUPPORTED_PRF
#define PKCS8_R_UNSUPPORTED_PRF
Definition: pkcs8.h:278
NID_aes_256_cbc
#define NID_aes_256_cbc
Definition: nid.h:1973
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
CBB_add_asn1
#define CBB_add_asn1
Definition: boringssl_prefix_symbols.h:1019
err.h
cipher.h
googletest-filter-unittest.child
child
Definition: bloaty/third_party/googletest/googletest/test/googletest-filter-unittest.py:62
NID_undef
#define NID_undef
Definition: nid.h:85
NID_des_ede3_cbc
#define NID_des_ede3_cbc
Definition: nid.h:287
PKCS8_R_BAD_ITERATION_COUNT
#define PKCS8_R_BAD_ITERATION_COUNT
Definition: pkcs8.h:277
oid
uint8_t oid[9]
Definition: p5_pbev2.c:89
EVP_des_ede3_cbc
const OPENSSL_EXPORT EVP_CIPHER * EVP_des_ede3_cbc(void)
oid_len
uint8_t oid_len
Definition: p5_pbev2.c:90
PKCS8_R_ERROR_SETTING_CIPHER_PARAMS
#define PKCS8_R_ERROR_SETTING_CIPHER_PARAMS
Definition: pkcs8.h:255
PKCS5_pbe2_encrypt_init
int PKCS5_pbe2_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, unsigned iterations, const char *pass, size_t pass_len, const uint8_t *salt, size_t salt_len)
Definition: p5_pbev2.c:164
NID_aes_192_cbc
#define NID_aes_192_cbc
Definition: nid.h:1953
pbe_suite
Definition: third_party/boringssl-with-bazel/src/crypto/pkcs8/internal.h:100
kHMACWithSHA256
static const uint8_t kHMACWithSHA256[]
Definition: p5_pbev2.c:85
EVP_CipherInit_ex
#define EVP_CipherInit_ex
Definition: boringssl_prefix_symbols.h:1493
CBB_add_bytes
#define CBB_add_bytes
Definition: boringssl_prefix_symbols.h:1025
benchmark.md
md
Definition: benchmark.py:86
nid.h
rand.h
key
const char * key
Definition: hpack_parser_table.cc:164
kCipherOIDs
static const struct @358 kCipherOIDs[]
add_cipher_oid
static int add_cipher_oid(CBB *out, int nid)
Definition: p5_pbev2.c:131
PKCS5_PBKDF2_HMAC
#define PKCS5_PBKDF2_HMAC
Definition: boringssl_prefix_symbols.h:2009
CBS_ASN1_OBJECT
#define CBS_ASN1_OBJECT
Definition: bytestring.h:211
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
EVP_MAX_IV_LENGTH
#define EVP_MAX_IV_LENGTH
Definition: cipher.h:533
PKCS8_R_UNSUPPORTED_KEYLENGTH
#define PKCS8_R_UNSUPPORTED_KEYLENGTH
Definition: pkcs8.h:273
PKCS8_R_UNSUPPORTED_CIPHER
#define PKCS8_R_UNSUPPORTED_CIPHER
Definition: pkcs8.h:275
EVP_CIPHER_key_length
#define EVP_CIPHER_key_length
Definition: boringssl_prefix_symbols.h:1486
EVP_sha1
const OPENSSL_EXPORT EVP_MD * EVP_sha1(void)
NID_rc2_cbc
#define NID_rc2_cbc
Definition: nid.h:256
PKCS8_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER
#define PKCS8_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER
Definition: pkcs8.h:250
mem.h
PKCS8_R_DECODE_ERROR
#define PKCS8_R_DECODE_ERROR
Definition: pkcs8.h:252
CBS_ASN1_SEQUENCE
#define CBS_ASN1_SEQUENCE
Definition: bytestring.h:214
EVP_aes_128_cbc
const OPENSSL_EXPORT EVP_CIPHER * EVP_aes_128_cbc(void)
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
CBB_add_asn1_uint64
#define CBB_add_asn1_uint64
Definition: boringssl_prefix_symbols.h:1024
cbb_st
Definition: bytestring.h:375


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:38