1169689Skan/*
2169689Skan * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
3169689Skan *
4169689Skan * Licensed under the Apache License 2.0 (the "License").  You may not use
5169689Skan * this file except in compliance with the License.  You can obtain a copy
6169689Skan * in the file LICENSE in the source distribution or at
7169689Skan * https://www.openssl.org/source/license.html
8169689Skan */
9169689Skan
10169689Skan#include <stdio.h>
11169689Skan#include "internal/cryptlib.h"
12169689Skan#include <openssl/x509.h>
13169689Skan#include <openssl/objects.h>
14169689Skan#include <openssl/evp.h>
15169689Skan#include <openssl/ui.h>
16169689Skan
17169689Skan#ifndef BUFSIZ
18169689Skan# define BUFSIZ 256
19169689Skan#endif
20169689Skan
21169689Skan/* should be init to zeros. */
22169689Skanstatic char prompt_string[80];
23169689Skan
24169689Skanvoid EVP_set_pw_prompt(const char *prompt)
25169689Skan{
26169689Skan    if (prompt == NULL)
27169689Skan        prompt_string[0] = '\0';
28169689Skan    else {
29169689Skan        strncpy(prompt_string, prompt, 79);
30169689Skan        prompt_string[79] = '\0';
31169689Skan    }
32169689Skan}
33169689Skan
34169689Skanchar *EVP_get_pw_prompt(void)
35169689Skan{
36169689Skan    if (prompt_string[0] == '\0')
37169689Skan        return NULL;
38169689Skan    else
39169689Skan        return prompt_string;
40169689Skan}
41169689Skan
42169689Skan/*
43169689Skan * For historical reasons, the standard function for reading passwords is in
44169689Skan * the DES library -- if someone ever wants to disable DES, this function
45169689Skan * will fail
46169689Skan */
47169689Skanint EVP_read_pw_string(char *buf, int len, const char *prompt, int verify)
48169689Skan{
49169689Skan    return EVP_read_pw_string_min(buf, 0, len, prompt, verify);
50169689Skan}
51169689Skan
52169689Skanint EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt,
53169689Skan                           int verify)
54169689Skan{
55169689Skan    int ret = -1;
56169689Skan    char buff[BUFSIZ];
57169689Skan    UI *ui;
58169689Skan
59169689Skan    if ((prompt == NULL) && (prompt_string[0] != '\0'))
60169689Skan        prompt = prompt_string;
61169689Skan    ui = UI_new();
62169689Skan    if (ui == NULL)
63169689Skan        return ret;
64169689Skan    if (UI_add_input_string(ui, prompt, 0, buf, min,
65169689Skan                            (len >= BUFSIZ) ? BUFSIZ - 1 : len) < 0
66169689Skan        || (verify
67169689Skan            && UI_add_verify_string(ui, prompt, 0, buff, min,
68169689Skan                                    (len >= BUFSIZ) ? BUFSIZ - 1 : len,
69169689Skan                                    buf) < 0))
70169689Skan        goto end;
71169689Skan    ret = UI_process(ui);
72169689Skan    OPENSSL_cleanse(buff, BUFSIZ);
73169689Skan end:
74169689Skan    UI_free(ui);
75169689Skan    return ret;
76169689Skan}
77169689Skan
78169689Skanint EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
79169689Skan                   const unsigned char *salt, const unsigned char *data,
80169689Skan                   int datal, int count, unsigned char *key,
81235623Spfg                   unsigned char *iv)
82169689Skan{
83169689Skan    EVP_MD_CTX *c;
84169689Skan    unsigned char md_buf[EVP_MAX_MD_SIZE];
85169689Skan    int niv, nkey, addmd = 0;
86169689Skan    unsigned int mds = 0, i;
87169689Skan    int rv = 0;
88169689Skan    nkey = EVP_CIPHER_get_key_length(type);
89169689Skan    niv = EVP_CIPHER_get_iv_length(type);
90169689Skan    OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH);
91169689Skan    OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH);
92169689Skan
93169689Skan    if (data == NULL)
94169689Skan        return nkey;
95169689Skan
96169689Skan    c = EVP_MD_CTX_new();
97169689Skan    if (c == NULL)
98169689Skan        goto err;
99169689Skan    for (;;) {
100169689Skan        if (!EVP_DigestInit_ex(c, md, NULL))
101169689Skan            goto err;
102169689Skan        if (addmd++)
103169689Skan            if (!EVP_DigestUpdate(c, &(md_buf[0]), mds))
104169689Skan                goto err;
105169689Skan        if (!EVP_DigestUpdate(c, data, datal))
106169689Skan            goto err;
107169689Skan        if (salt != NULL)
108169689Skan            if (!EVP_DigestUpdate(c, salt, PKCS5_SALT_LEN))
109169689Skan                goto err;
110169689Skan        if (!EVP_DigestFinal_ex(c, &(md_buf[0]), &mds))
111169689Skan            goto err;
112169689Skan
113169689Skan        for (i = 1; i < (unsigned int)count; i++) {
114169689Skan            if (!EVP_DigestInit_ex(c, md, NULL))
115169689Skan                goto err;
116169689Skan            if (!EVP_DigestUpdate(c, &(md_buf[0]), mds))
117169689Skan                goto err;
118169689Skan            if (!EVP_DigestFinal_ex(c, &(md_buf[0]), &mds))
119169689Skan                goto err;
120169689Skan        }
121169689Skan        i = 0;
122169689Skan        if (nkey) {
123169689Skan            for (;;) {
124169689Skan                if (nkey == 0)
125169689Skan                    break;
126169689Skan                if (i == mds)
127169689Skan                    break;
128169689Skan                if (key != NULL)
129169689Skan                    *(key++) = md_buf[i];
130169689Skan                nkey--;
131169689Skan                i++;
132169689Skan            }
133169689Skan        }
134169689Skan        if (niv && (i != mds)) {
135169689Skan            for (;;) {
136169689Skan                if (niv == 0)
137169689Skan                    break;
138169689Skan                if (i == mds)
139169689Skan                    break;
140169689Skan                if (iv != NULL)
141169689Skan                    *(iv++) = md_buf[i];
142169689Skan                niv--;
143169689Skan                i++;
144169689Skan            }
145169689Skan        }
146169689Skan        if ((nkey == 0) && (niv == 0))
147169689Skan            break;
148169689Skan    }
149169689Skan    rv = EVP_CIPHER_get_key_length(type);
150169689Skan err:
151169689Skan    EVP_MD_CTX_free(c);
152169689Skan    OPENSSL_cleanse(md_buf, sizeof(md_buf));
153169689Skan    return rv;
154169689Skan}
155169689Skan