1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-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/x509.h> 13e1051a39Sopenharmony_ci#include <openssl/objects.h> 14e1051a39Sopenharmony_ci#include <openssl/evp.h> 15e1051a39Sopenharmony_ci#include <openssl/ui.h> 16e1051a39Sopenharmony_ci 17e1051a39Sopenharmony_ci#ifndef BUFSIZ 18e1051a39Sopenharmony_ci# define BUFSIZ 256 19e1051a39Sopenharmony_ci#endif 20e1051a39Sopenharmony_ci 21e1051a39Sopenharmony_ci/* should be init to zeros. */ 22e1051a39Sopenharmony_cistatic char prompt_string[80]; 23e1051a39Sopenharmony_ci 24e1051a39Sopenharmony_civoid EVP_set_pw_prompt(const char *prompt) 25e1051a39Sopenharmony_ci{ 26e1051a39Sopenharmony_ci if (prompt == NULL) 27e1051a39Sopenharmony_ci prompt_string[0] = '\0'; 28e1051a39Sopenharmony_ci else { 29e1051a39Sopenharmony_ci strncpy(prompt_string, prompt, 79); 30e1051a39Sopenharmony_ci prompt_string[79] = '\0'; 31e1051a39Sopenharmony_ci } 32e1051a39Sopenharmony_ci} 33e1051a39Sopenharmony_ci 34e1051a39Sopenharmony_cichar *EVP_get_pw_prompt(void) 35e1051a39Sopenharmony_ci{ 36e1051a39Sopenharmony_ci if (prompt_string[0] == '\0') 37e1051a39Sopenharmony_ci return NULL; 38e1051a39Sopenharmony_ci else 39e1051a39Sopenharmony_ci return prompt_string; 40e1051a39Sopenharmony_ci} 41e1051a39Sopenharmony_ci 42e1051a39Sopenharmony_ci/* 43e1051a39Sopenharmony_ci * For historical reasons, the standard function for reading passwords is in 44e1051a39Sopenharmony_ci * the DES library -- if someone ever wants to disable DES, this function 45e1051a39Sopenharmony_ci * will fail 46e1051a39Sopenharmony_ci */ 47e1051a39Sopenharmony_ciint EVP_read_pw_string(char *buf, int len, const char *prompt, int verify) 48e1051a39Sopenharmony_ci{ 49e1051a39Sopenharmony_ci return EVP_read_pw_string_min(buf, 0, len, prompt, verify); 50e1051a39Sopenharmony_ci} 51e1051a39Sopenharmony_ci 52e1051a39Sopenharmony_ciint EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt, 53e1051a39Sopenharmony_ci int verify) 54e1051a39Sopenharmony_ci{ 55e1051a39Sopenharmony_ci int ret = -1; 56e1051a39Sopenharmony_ci char buff[BUFSIZ]; 57e1051a39Sopenharmony_ci UI *ui; 58e1051a39Sopenharmony_ci 59e1051a39Sopenharmony_ci if ((prompt == NULL) && (prompt_string[0] != '\0')) 60e1051a39Sopenharmony_ci prompt = prompt_string; 61e1051a39Sopenharmony_ci ui = UI_new(); 62e1051a39Sopenharmony_ci if (ui == NULL) 63e1051a39Sopenharmony_ci return ret; 64e1051a39Sopenharmony_ci if (UI_add_input_string(ui, prompt, 0, buf, min, 65e1051a39Sopenharmony_ci (len >= BUFSIZ) ? BUFSIZ - 1 : len) < 0 66e1051a39Sopenharmony_ci || (verify 67e1051a39Sopenharmony_ci && UI_add_verify_string(ui, prompt, 0, buff, min, 68e1051a39Sopenharmony_ci (len >= BUFSIZ) ? BUFSIZ - 1 : len, 69e1051a39Sopenharmony_ci buf) < 0)) 70e1051a39Sopenharmony_ci goto end; 71e1051a39Sopenharmony_ci ret = UI_process(ui); 72e1051a39Sopenharmony_ci OPENSSL_cleanse(buff, BUFSIZ); 73e1051a39Sopenharmony_ci end: 74e1051a39Sopenharmony_ci UI_free(ui); 75e1051a39Sopenharmony_ci return ret; 76e1051a39Sopenharmony_ci} 77e1051a39Sopenharmony_ci 78e1051a39Sopenharmony_ciint EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, 79e1051a39Sopenharmony_ci const unsigned char *salt, const unsigned char *data, 80e1051a39Sopenharmony_ci int datal, int count, unsigned char *key, 81e1051a39Sopenharmony_ci unsigned char *iv) 82e1051a39Sopenharmony_ci{ 83e1051a39Sopenharmony_ci EVP_MD_CTX *c; 84e1051a39Sopenharmony_ci unsigned char md_buf[EVP_MAX_MD_SIZE]; 85e1051a39Sopenharmony_ci int niv, nkey, addmd = 0; 86e1051a39Sopenharmony_ci unsigned int mds = 0, i; 87e1051a39Sopenharmony_ci int rv = 0; 88e1051a39Sopenharmony_ci nkey = EVP_CIPHER_get_key_length(type); 89e1051a39Sopenharmony_ci niv = EVP_CIPHER_get_iv_length(type); 90e1051a39Sopenharmony_ci OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH); 91e1051a39Sopenharmony_ci OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH); 92e1051a39Sopenharmony_ci 93e1051a39Sopenharmony_ci if (data == NULL) 94e1051a39Sopenharmony_ci return nkey; 95e1051a39Sopenharmony_ci 96e1051a39Sopenharmony_ci c = EVP_MD_CTX_new(); 97e1051a39Sopenharmony_ci if (c == NULL) 98e1051a39Sopenharmony_ci goto err; 99e1051a39Sopenharmony_ci for (;;) { 100e1051a39Sopenharmony_ci if (!EVP_DigestInit_ex(c, md, NULL)) 101e1051a39Sopenharmony_ci goto err; 102e1051a39Sopenharmony_ci if (addmd++) 103e1051a39Sopenharmony_ci if (!EVP_DigestUpdate(c, &(md_buf[0]), mds)) 104e1051a39Sopenharmony_ci goto err; 105e1051a39Sopenharmony_ci if (!EVP_DigestUpdate(c, data, datal)) 106e1051a39Sopenharmony_ci goto err; 107e1051a39Sopenharmony_ci if (salt != NULL) 108e1051a39Sopenharmony_ci if (!EVP_DigestUpdate(c, salt, PKCS5_SALT_LEN)) 109e1051a39Sopenharmony_ci goto err; 110e1051a39Sopenharmony_ci if (!EVP_DigestFinal_ex(c, &(md_buf[0]), &mds)) 111e1051a39Sopenharmony_ci goto err; 112e1051a39Sopenharmony_ci 113e1051a39Sopenharmony_ci for (i = 1; i < (unsigned int)count; i++) { 114e1051a39Sopenharmony_ci if (!EVP_DigestInit_ex(c, md, NULL)) 115e1051a39Sopenharmony_ci goto err; 116e1051a39Sopenharmony_ci if (!EVP_DigestUpdate(c, &(md_buf[0]), mds)) 117e1051a39Sopenharmony_ci goto err; 118e1051a39Sopenharmony_ci if (!EVP_DigestFinal_ex(c, &(md_buf[0]), &mds)) 119e1051a39Sopenharmony_ci goto err; 120e1051a39Sopenharmony_ci } 121e1051a39Sopenharmony_ci i = 0; 122e1051a39Sopenharmony_ci if (nkey) { 123e1051a39Sopenharmony_ci for (;;) { 124e1051a39Sopenharmony_ci if (nkey == 0) 125e1051a39Sopenharmony_ci break; 126e1051a39Sopenharmony_ci if (i == mds) 127e1051a39Sopenharmony_ci break; 128e1051a39Sopenharmony_ci if (key != NULL) 129e1051a39Sopenharmony_ci *(key++) = md_buf[i]; 130e1051a39Sopenharmony_ci nkey--; 131e1051a39Sopenharmony_ci i++; 132e1051a39Sopenharmony_ci } 133e1051a39Sopenharmony_ci } 134e1051a39Sopenharmony_ci if (niv && (i != mds)) { 135e1051a39Sopenharmony_ci for (;;) { 136e1051a39Sopenharmony_ci if (niv == 0) 137e1051a39Sopenharmony_ci break; 138e1051a39Sopenharmony_ci if (i == mds) 139e1051a39Sopenharmony_ci break; 140e1051a39Sopenharmony_ci if (iv != NULL) 141e1051a39Sopenharmony_ci *(iv++) = md_buf[i]; 142e1051a39Sopenharmony_ci niv--; 143e1051a39Sopenharmony_ci i++; 144e1051a39Sopenharmony_ci } 145e1051a39Sopenharmony_ci } 146e1051a39Sopenharmony_ci if ((nkey == 0) && (niv == 0)) 147e1051a39Sopenharmony_ci break; 148e1051a39Sopenharmony_ci } 149e1051a39Sopenharmony_ci rv = EVP_CIPHER_get_key_length(type); 150e1051a39Sopenharmony_ci err: 151e1051a39Sopenharmony_ci EVP_MD_CTX_free(c); 152e1051a39Sopenharmony_ci OPENSSL_cleanse(md_buf, sizeof(md_buf)); 153e1051a39Sopenharmony_ci return rv; 154e1051a39Sopenharmony_ci} 155