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