]>
Commit | Line | Data |
---|---|---|
0f113f3e | 1 | /* |
b1322259 | 2 | * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. |
8d8c7266 | 3 | * |
54fffdf4 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
b1322259 RS |
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 | |
8d8c7266 DSH |
8 | */ |
9 | ||
10 | #include <stdio.h> | |
b39fc560 | 11 | #include "internal/cryptlib.h" |
ec577822 | 12 | #include <openssl/pkcs12.h> |
0f814687 | 13 | #include <openssl/bn.h> |
a902e43d | 14 | #include <openssl/trace.h> |
b7466c13 P |
15 | #include <openssl/kdf.h> |
16 | #include <openssl/core_names.h> | |
17 | #include "internal/provider.h" | |
8d8c7266 | 18 | |
a331a305 | 19 | int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, |
0f113f3e MC |
20 | int saltlen, int id, int iter, int n, |
21 | unsigned char *out, const EVP_MD *md_type) | |
8d8c7266 | 22 | { |
0f113f3e MC |
23 | int ret; |
24 | unsigned char *unipass; | |
25 | int uniplen; | |
0eab41fb | 26 | |
12a765a5 | 27 | if (pass == NULL) { |
0f113f3e MC |
28 | unipass = NULL; |
29 | uniplen = 0; | |
30 | } else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) { | |
31 | PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC, ERR_R_MALLOC_FAILURE); | |
32 | return 0; | |
33 | } | |
34 | ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen, | |
35 | id, iter, n, out, md_type); | |
4b45c6e5 | 36 | OPENSSL_clear_free(unipass, uniplen); |
ed4faae0 | 37 | return ret > 0; |
8d8c7266 DSH |
38 | } |
39 | ||
9e6b2f54 AP |
40 | int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt, |
41 | int saltlen, int id, int iter, int n, | |
42 | unsigned char *out, const EVP_MD *md_type) | |
43 | { | |
44 | int ret; | |
45 | unsigned char *unipass; | |
46 | int uniplen; | |
47 | ||
12a765a5 | 48 | if (pass == NULL) { |
9e6b2f54 AP |
49 | unipass = NULL; |
50 | uniplen = 0; | |
51 | } else if (!OPENSSL_utf82uni(pass, passlen, &unipass, &uniplen)) { | |
52 | PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UTF8, ERR_R_MALLOC_FAILURE); | |
53 | return 0; | |
54 | } | |
55 | ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen, | |
56 | id, iter, n, out, md_type); | |
9e6b2f54 | 57 | OPENSSL_clear_free(unipass, uniplen); |
ed4faae0 | 58 | return ret > 0; |
9e6b2f54 AP |
59 | } |
60 | ||
a331a305 | 61 | int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, |
0f113f3e MC |
62 | int saltlen, int id, int iter, int n, |
63 | unsigned char *out, const EVP_MD *md_type) | |
8d8c7266 | 64 | { |
b7466c13 P |
65 | int res = 0; |
66 | EVP_KDF *kdf; | |
67 | EVP_KDF_CTX *ctx; | |
68 | OSSL_PARAM params[6], *p = params; | |
69 | ||
70 | if (n <= 0) | |
71 | return 0; | |
3bf7ef53 | 72 | |
b7466c13 P |
73 | /* |
74 | * The parameter query isn't available but the library context can be | |
75 | * extracted from the passed digest. | |
76 | */ | |
a829b735 | 77 | kdf = EVP_KDF_fetch(ossl_provider_libctx(EVP_MD_provider(md_type)), |
b7466c13 P |
78 | "PKCS12KDF", NULL); |
79 | if (kdf == NULL) | |
80 | return 0; | |
81 | ctx = EVP_KDF_CTX_new(kdf); | |
82 | EVP_KDF_free(kdf); | |
6e59a892 | 83 | if (ctx == NULL) |
b7466c13 P |
84 | return 0; |
85 | ||
86 | *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, | |
87 | (char *)EVP_MD_name(md_type), 0); | |
88 | *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, | |
89 | pass, passlen); | |
90 | *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, | |
91 | salt, saltlen); | |
92 | *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_PKCS12_ID, &id); | |
93 | *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_ITER, &iter); | |
94 | *p = OSSL_PARAM_construct_end(); | |
95 | if (!EVP_KDF_CTX_set_params(ctx, params)) | |
6e59a892 RL |
96 | goto err; |
97 | ||
a902e43d RL |
98 | OSSL_TRACE_BEGIN(PKCS12_KEYGEN) { |
99 | BIO_printf(trc_out, "PKCS12_key_gen_uni(): ID %d, ITER %d\n", id, iter); | |
100 | BIO_printf(trc_out, "Password (length %d):\n", passlen); | |
101 | BIO_hex_string(trc_out, 0, passlen, pass, passlen); | |
102 | BIO_printf(trc_out, "\n"); | |
103 | BIO_printf(trc_out, "Salt (length %d):\n", saltlen); | |
104 | BIO_hex_string(trc_out, 0, saltlen, salt, saltlen); | |
105 | BIO_printf(trc_out, "\n"); | |
106 | } OSSL_TRACE_END(PKCS12_KEYGEN); | |
54c68d35 | 107 | |
b7466c13 P |
108 | if (EVP_KDF_derive(ctx, out, (size_t)n)) { |
109 | res = 1; | |
110 | OSSL_TRACE_BEGIN(PKCS12_KEYGEN) { | |
111 | BIO_printf(trc_out, "Output KEY (length %d)\n", n); | |
112 | BIO_hex_string(trc_out, 0, n, out, n); | |
113 | BIO_printf(trc_out, "\n"); | |
114 | } OSSL_TRACE_END(PKCS12_KEYGEN); | |
0f113f3e | 115 | } |
0f113f3e | 116 | err: |
b7466c13 P |
117 | EVP_KDF_CTX_free(ctx); |
118 | return res; | |
8d8c7266 | 119 | } |