1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include <stdio.h> 11e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 12e1051a39Sopenharmony_ci#include <openssl/pkcs12.h> 13e1051a39Sopenharmony_ci#include <openssl/bn.h> 14e1051a39Sopenharmony_ci#include <openssl/trace.h> 15e1051a39Sopenharmony_ci#include <openssl/kdf.h> 16e1051a39Sopenharmony_ci#include <openssl/core_names.h> 17e1051a39Sopenharmony_ci#include "internal/provider.h" 18e1051a39Sopenharmony_ci 19e1051a39Sopenharmony_ciint PKCS12_key_gen_asc_ex(const char *pass, int passlen, unsigned char *salt, 20e1051a39Sopenharmony_ci int saltlen, int id, int iter, int n, 21e1051a39Sopenharmony_ci unsigned char *out, const EVP_MD *md_type, 22e1051a39Sopenharmony_ci OSSL_LIB_CTX *ctx, const char *propq) 23e1051a39Sopenharmony_ci{ 24e1051a39Sopenharmony_ci int ret; 25e1051a39Sopenharmony_ci unsigned char *unipass; 26e1051a39Sopenharmony_ci int uniplen; 27e1051a39Sopenharmony_ci 28e1051a39Sopenharmony_ci if (pass == NULL) { 29e1051a39Sopenharmony_ci unipass = NULL; 30e1051a39Sopenharmony_ci uniplen = 0; 31e1051a39Sopenharmony_ci } else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) { 32e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); 33e1051a39Sopenharmony_ci return 0; 34e1051a39Sopenharmony_ci } 35e1051a39Sopenharmony_ci ret = PKCS12_key_gen_uni_ex(unipass, uniplen, salt, saltlen, id, iter, 36e1051a39Sopenharmony_ci n, out, md_type, ctx, propq); 37e1051a39Sopenharmony_ci OPENSSL_clear_free(unipass, uniplen); 38e1051a39Sopenharmony_ci return ret > 0; 39e1051a39Sopenharmony_ci} 40e1051a39Sopenharmony_ci 41e1051a39Sopenharmony_ciint PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, 42e1051a39Sopenharmony_ci int saltlen, int id, int iter, int n, 43e1051a39Sopenharmony_ci unsigned char *out, const EVP_MD *md_type) 44e1051a39Sopenharmony_ci{ 45e1051a39Sopenharmony_ci return PKCS12_key_gen_asc_ex(pass, passlen, salt, saltlen, id, iter, n, 46e1051a39Sopenharmony_ci out, md_type, NULL, NULL); 47e1051a39Sopenharmony_ci} 48e1051a39Sopenharmony_ci 49e1051a39Sopenharmony_ciint PKCS12_key_gen_utf8_ex(const char *pass, int passlen, unsigned char *salt, 50e1051a39Sopenharmony_ci int saltlen, int id, int iter, int n, 51e1051a39Sopenharmony_ci unsigned char *out, const EVP_MD *md_type, 52e1051a39Sopenharmony_ci OSSL_LIB_CTX *ctx, const char *propq) 53e1051a39Sopenharmony_ci{ 54e1051a39Sopenharmony_ci int ret; 55e1051a39Sopenharmony_ci unsigned char *unipass; 56e1051a39Sopenharmony_ci int uniplen; 57e1051a39Sopenharmony_ci 58e1051a39Sopenharmony_ci if (pass == NULL) { 59e1051a39Sopenharmony_ci unipass = NULL; 60e1051a39Sopenharmony_ci uniplen = 0; 61e1051a39Sopenharmony_ci } else if (!OPENSSL_utf82uni(pass, passlen, &unipass, &uniplen)) { 62e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); 63e1051a39Sopenharmony_ci return 0; 64e1051a39Sopenharmony_ci } 65e1051a39Sopenharmony_ci ret = PKCS12_key_gen_uni_ex(unipass, uniplen, salt, saltlen, id, iter, 66e1051a39Sopenharmony_ci n, out, md_type, ctx, propq); 67e1051a39Sopenharmony_ci OPENSSL_clear_free(unipass, uniplen); 68e1051a39Sopenharmony_ci return ret > 0; 69e1051a39Sopenharmony_ci} 70e1051a39Sopenharmony_ci 71e1051a39Sopenharmony_ciint PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt, 72e1051a39Sopenharmony_ci int saltlen, int id, int iter, int n, 73e1051a39Sopenharmony_ci unsigned char *out, const EVP_MD *md_type) 74e1051a39Sopenharmony_ci{ 75e1051a39Sopenharmony_ci return PKCS12_key_gen_utf8_ex(pass, passlen, salt, saltlen, id, iter, n, 76e1051a39Sopenharmony_ci out, md_type, NULL, NULL); 77e1051a39Sopenharmony_ci} 78e1051a39Sopenharmony_ci 79e1051a39Sopenharmony_ciint PKCS12_key_gen_uni_ex(unsigned char *pass, int passlen, unsigned char *salt, 80e1051a39Sopenharmony_ci int saltlen, int id, int iter, int n, 81e1051a39Sopenharmony_ci unsigned char *out, const EVP_MD *md_type, 82e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx, const char *propq) 83e1051a39Sopenharmony_ci{ 84e1051a39Sopenharmony_ci int res = 0; 85e1051a39Sopenharmony_ci EVP_KDF *kdf; 86e1051a39Sopenharmony_ci EVP_KDF_CTX *ctx; 87e1051a39Sopenharmony_ci OSSL_PARAM params[6], *p = params; 88e1051a39Sopenharmony_ci 89e1051a39Sopenharmony_ci if (n <= 0) 90e1051a39Sopenharmony_ci return 0; 91e1051a39Sopenharmony_ci 92e1051a39Sopenharmony_ci kdf = EVP_KDF_fetch(libctx, "PKCS12KDF", propq); 93e1051a39Sopenharmony_ci if (kdf == NULL) 94e1051a39Sopenharmony_ci return 0; 95e1051a39Sopenharmony_ci ctx = EVP_KDF_CTX_new(kdf); 96e1051a39Sopenharmony_ci EVP_KDF_free(kdf); 97e1051a39Sopenharmony_ci if (ctx == NULL) 98e1051a39Sopenharmony_ci return 0; 99e1051a39Sopenharmony_ci 100e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, 101e1051a39Sopenharmony_ci (char *)EVP_MD_get0_name(md_type), 102e1051a39Sopenharmony_ci 0); 103e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, 104e1051a39Sopenharmony_ci pass, passlen); 105e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, 106e1051a39Sopenharmony_ci salt, saltlen); 107e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_PKCS12_ID, &id); 108e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_ITER, &iter); 109e1051a39Sopenharmony_ci *p = OSSL_PARAM_construct_end(); 110e1051a39Sopenharmony_ci 111e1051a39Sopenharmony_ci OSSL_TRACE_BEGIN(PKCS12_KEYGEN) { 112e1051a39Sopenharmony_ci BIO_printf(trc_out, "PKCS12_key_gen_uni_ex(): ID %d, ITER %d\n", id, iter); 113e1051a39Sopenharmony_ci BIO_printf(trc_out, "Password (length %d):\n", passlen); 114e1051a39Sopenharmony_ci BIO_hex_string(trc_out, 0, passlen, pass, passlen); 115e1051a39Sopenharmony_ci BIO_printf(trc_out, "\n"); 116e1051a39Sopenharmony_ci BIO_printf(trc_out, "Salt (length %d):\n", saltlen); 117e1051a39Sopenharmony_ci BIO_hex_string(trc_out, 0, saltlen, salt, saltlen); 118e1051a39Sopenharmony_ci BIO_printf(trc_out, "\n"); 119e1051a39Sopenharmony_ci } OSSL_TRACE_END(PKCS12_KEYGEN); 120e1051a39Sopenharmony_ci 121e1051a39Sopenharmony_ci if (EVP_KDF_derive(ctx, out, (size_t)n, params)) { 122e1051a39Sopenharmony_ci res = 1; 123e1051a39Sopenharmony_ci OSSL_TRACE_BEGIN(PKCS12_KEYGEN) { 124e1051a39Sopenharmony_ci BIO_printf(trc_out, "Output KEY (length %d)\n", n); 125e1051a39Sopenharmony_ci BIO_hex_string(trc_out, 0, n, out, n); 126e1051a39Sopenharmony_ci BIO_printf(trc_out, "\n"); 127e1051a39Sopenharmony_ci } OSSL_TRACE_END(PKCS12_KEYGEN); 128e1051a39Sopenharmony_ci } 129e1051a39Sopenharmony_ci EVP_KDF_CTX_free(ctx); 130e1051a39Sopenharmony_ci return res; 131e1051a39Sopenharmony_ci} 132e1051a39Sopenharmony_ci 133e1051a39Sopenharmony_ciint PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, 134e1051a39Sopenharmony_ci int saltlen, int id, int iter, int n, 135e1051a39Sopenharmony_ci unsigned char *out, const EVP_MD *md_type) 136e1051a39Sopenharmony_ci{ 137e1051a39Sopenharmony_ci return PKCS12_key_gen_uni_ex(pass, passlen, salt, saltlen, id, iter, n, out, md_type, NULL, NULL); 138e1051a39Sopenharmony_ci} 139