xref: /freebsd/crypto/openssl/crypto/pkcs12/p12_key.c (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
16f9291ceSJung-uk Kim /*
29a3ae0cdSJung-uk Kim  * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
374664626SKris Kennaway  *
4*b077aed3SPierre Pronchery  * Licensed under the Apache License 2.0 (the "License").  You may not use
5e71b7053SJung-uk Kim  * this file except in compliance with the License.  You can obtain a copy
6e71b7053SJung-uk Kim  * in the file LICENSE in the source distribution or at
7e71b7053SJung-uk Kim  * https://www.openssl.org/source/license.html
874664626SKris Kennaway  */
974664626SKris Kennaway 
1074664626SKris Kennaway #include <stdio.h>
11e71b7053SJung-uk Kim #include "internal/cryptlib.h"
1274664626SKris Kennaway #include <openssl/pkcs12.h>
133b4e3dcbSSimon L. B. Nielsen #include <openssl/bn.h>
14*b077aed3SPierre Pronchery #include <openssl/trace.h>
15*b077aed3SPierre Pronchery #include <openssl/kdf.h>
16*b077aed3SPierre Pronchery #include <openssl/core_names.h>
17*b077aed3SPierre Pronchery #include "internal/provider.h"
1874664626SKris Kennaway 
PKCS12_key_gen_asc_ex(const char * pass,int passlen,unsigned char * salt,int saltlen,int id,int iter,int n,unsigned char * out,const EVP_MD * md_type,OSSL_LIB_CTX * ctx,const char * propq)19*b077aed3SPierre Pronchery int PKCS12_key_gen_asc_ex(const char *pass, int passlen, unsigned char *salt,
206f9291ceSJung-uk Kim                           int saltlen, int id, int iter, int n,
21*b077aed3SPierre Pronchery                           unsigned char *out, const EVP_MD *md_type,
22*b077aed3SPierre Pronchery                           OSSL_LIB_CTX *ctx, const char *propq)
2374664626SKris Kennaway {
2474664626SKris Kennaway     int ret;
2574664626SKris Kennaway     unsigned char *unipass;
2674664626SKris Kennaway     int uniplen;
271f13597dSJung-uk Kim 
28*b077aed3SPierre Pronchery     if (pass == NULL) {
29ddd58736SKris Kennaway         unipass = NULL;
30ddd58736SKris Kennaway         uniplen = 0;
311f13597dSJung-uk Kim     } else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) {
32*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE);
3374664626SKris Kennaway         return 0;
3474664626SKris Kennaway     }
35*b077aed3SPierre Pronchery     ret = PKCS12_key_gen_uni_ex(unipass, uniplen, salt, saltlen, id, iter,
36*b077aed3SPierre Pronchery                                 n, out, md_type, ctx, propq);
37e71b7053SJung-uk Kim     OPENSSL_clear_free(unipass, uniplen);
38*b077aed3SPierre Pronchery     return ret > 0;
39*b077aed3SPierre Pronchery }
40*b077aed3SPierre Pronchery 
PKCS12_key_gen_asc(const char * pass,int passlen,unsigned char * salt,int saltlen,int id,int iter,int n,unsigned char * out,const EVP_MD * md_type)41*b077aed3SPierre Pronchery int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
42*b077aed3SPierre Pronchery                        int saltlen, int id, int iter, int n,
43*b077aed3SPierre Pronchery                        unsigned char *out, const EVP_MD *md_type)
44*b077aed3SPierre Pronchery {
45*b077aed3SPierre Pronchery     return PKCS12_key_gen_asc_ex(pass, passlen, salt, saltlen, id, iter, n,
46*b077aed3SPierre Pronchery                                   out, md_type, NULL, NULL);
47*b077aed3SPierre Pronchery }
48*b077aed3SPierre Pronchery 
PKCS12_key_gen_utf8_ex(const char * pass,int passlen,unsigned char * salt,int saltlen,int id,int iter,int n,unsigned char * out,const EVP_MD * md_type,OSSL_LIB_CTX * ctx,const char * propq)49*b077aed3SPierre Pronchery int PKCS12_key_gen_utf8_ex(const char *pass, int passlen, unsigned char *salt,
50*b077aed3SPierre Pronchery                            int saltlen, int id, int iter, int n,
51*b077aed3SPierre Pronchery                            unsigned char *out, const EVP_MD *md_type,
52*b077aed3SPierre Pronchery                            OSSL_LIB_CTX *ctx, const char *propq)
53*b077aed3SPierre Pronchery {
54*b077aed3SPierre Pronchery     int ret;
55*b077aed3SPierre Pronchery     unsigned char *unipass;
56*b077aed3SPierre Pronchery     int uniplen;
57*b077aed3SPierre Pronchery 
58*b077aed3SPierre Pronchery     if (pass == NULL) {
59*b077aed3SPierre Pronchery         unipass = NULL;
60*b077aed3SPierre Pronchery         uniplen = 0;
61*b077aed3SPierre Pronchery     } else if (!OPENSSL_utf82uni(pass, passlen, &unipass, &uniplen)) {
62*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE);
63*b077aed3SPierre Pronchery         return 0;
64*b077aed3SPierre Pronchery     }
65*b077aed3SPierre Pronchery     ret = PKCS12_key_gen_uni_ex(unipass, uniplen, salt, saltlen, id, iter,
66*b077aed3SPierre Pronchery                                 n, out, md_type, ctx, propq);
67*b077aed3SPierre Pronchery     OPENSSL_clear_free(unipass, uniplen);
68*b077aed3SPierre Pronchery     return ret > 0;
69ddd58736SKris Kennaway }
70e71b7053SJung-uk Kim 
PKCS12_key_gen_utf8(const char * pass,int passlen,unsigned char * salt,int saltlen,int id,int iter,int n,unsigned char * out,const EVP_MD * md_type)71e71b7053SJung-uk Kim int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt,
72e71b7053SJung-uk Kim                         int saltlen, int id, int iter, int n,
73e71b7053SJung-uk Kim                         unsigned char *out, const EVP_MD *md_type)
74e71b7053SJung-uk Kim {
75*b077aed3SPierre Pronchery     return PKCS12_key_gen_utf8_ex(pass, passlen, salt, saltlen, id, iter, n,
76*b077aed3SPierre Pronchery                                   out, md_type, NULL, NULL);
77e71b7053SJung-uk Kim }
78*b077aed3SPierre Pronchery 
PKCS12_key_gen_uni_ex(unsigned char * pass,int passlen,unsigned char * salt,int saltlen,int id,int iter,int n,unsigned char * out,const EVP_MD * md_type,OSSL_LIB_CTX * libctx,const char * propq)79*b077aed3SPierre Pronchery int PKCS12_key_gen_uni_ex(unsigned char *pass, int passlen, unsigned char *salt,
80*b077aed3SPierre Pronchery                           int saltlen, int id, int iter, int n,
81*b077aed3SPierre Pronchery                           unsigned char *out, const EVP_MD *md_type,
82*b077aed3SPierre Pronchery                           OSSL_LIB_CTX *libctx, const char *propq)
83*b077aed3SPierre Pronchery {
84*b077aed3SPierre Pronchery     int res = 0;
85*b077aed3SPierre Pronchery     EVP_KDF *kdf;
86*b077aed3SPierre Pronchery     EVP_KDF_CTX *ctx;
87*b077aed3SPierre Pronchery     OSSL_PARAM params[6], *p = params;
88*b077aed3SPierre Pronchery 
89*b077aed3SPierre Pronchery     if (n <= 0)
90e71b7053SJung-uk Kim         return 0;
91*b077aed3SPierre Pronchery 
92*b077aed3SPierre Pronchery     kdf = EVP_KDF_fetch(libctx, "PKCS12KDF", propq);
93*b077aed3SPierre Pronchery     if (kdf == NULL)
94*b077aed3SPierre Pronchery         return 0;
95*b077aed3SPierre Pronchery     ctx = EVP_KDF_CTX_new(kdf);
96*b077aed3SPierre Pronchery     EVP_KDF_free(kdf);
97*b077aed3SPierre Pronchery     if (ctx == NULL)
98*b077aed3SPierre Pronchery         return 0;
99*b077aed3SPierre Pronchery 
100*b077aed3SPierre Pronchery     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
101*b077aed3SPierre Pronchery                                             (char *)EVP_MD_get0_name(md_type),
102*b077aed3SPierre Pronchery                                             0);
103*b077aed3SPierre Pronchery     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD,
104*b077aed3SPierre Pronchery                                              pass, passlen);
105*b077aed3SPierre Pronchery     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
106*b077aed3SPierre Pronchery                                              salt, saltlen);
107*b077aed3SPierre Pronchery     *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_PKCS12_ID, &id);
108*b077aed3SPierre Pronchery     *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_ITER, &iter);
109*b077aed3SPierre Pronchery     *p = OSSL_PARAM_construct_end();
110*b077aed3SPierre Pronchery 
111*b077aed3SPierre Pronchery     OSSL_TRACE_BEGIN(PKCS12_KEYGEN) {
112*b077aed3SPierre Pronchery         BIO_printf(trc_out, "PKCS12_key_gen_uni_ex(): ID %d, ITER %d\n", id, iter);
113*b077aed3SPierre Pronchery         BIO_printf(trc_out, "Password (length %d):\n", passlen);
114*b077aed3SPierre Pronchery         BIO_hex_string(trc_out, 0, passlen, pass, passlen);
115*b077aed3SPierre Pronchery         BIO_printf(trc_out, "\n");
116*b077aed3SPierre Pronchery         BIO_printf(trc_out, "Salt (length %d):\n", saltlen);
117*b077aed3SPierre Pronchery         BIO_hex_string(trc_out, 0, saltlen, salt, saltlen);
118*b077aed3SPierre Pronchery         BIO_printf(trc_out, "\n");
119*b077aed3SPierre Pronchery     } OSSL_TRACE_END(PKCS12_KEYGEN);
120*b077aed3SPierre Pronchery 
121*b077aed3SPierre Pronchery     if (EVP_KDF_derive(ctx, out, (size_t)n, params)) {
122*b077aed3SPierre Pronchery         res = 1;
123*b077aed3SPierre Pronchery         OSSL_TRACE_BEGIN(PKCS12_KEYGEN) {
124*b077aed3SPierre Pronchery             BIO_printf(trc_out, "Output KEY (length %d)\n", n);
125*b077aed3SPierre Pronchery             BIO_hex_string(trc_out, 0, n, out, n);
126*b077aed3SPierre Pronchery             BIO_printf(trc_out, "\n");
127*b077aed3SPierre Pronchery         } OSSL_TRACE_END(PKCS12_KEYGEN);
128*b077aed3SPierre Pronchery     }
129*b077aed3SPierre Pronchery     EVP_KDF_CTX_free(ctx);
130*b077aed3SPierre Pronchery     return res;
13174664626SKris Kennaway }
13274664626SKris Kennaway 
PKCS12_key_gen_uni(unsigned char * pass,int passlen,unsigned char * salt,int saltlen,int id,int iter,int n,unsigned char * out,const EVP_MD * md_type)13374664626SKris Kennaway int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
1346f9291ceSJung-uk Kim                        int saltlen, int id, int iter, int n,
1356f9291ceSJung-uk Kim                        unsigned char *out, const EVP_MD *md_type)
13674664626SKris Kennaway {
137*b077aed3SPierre Pronchery     return PKCS12_key_gen_uni_ex(pass, passlen, salt, saltlen, id, iter, n, out, md_type, NULL, NULL);
13874664626SKris Kennaway }
139