xref: /third_party/openssl/crypto/evp/p5_crpt.c (revision e1051a39)
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 <stdlib.h>
12e1051a39Sopenharmony_ci#include "internal/cryptlib.h"
13e1051a39Sopenharmony_ci#include <openssl/x509.h>
14e1051a39Sopenharmony_ci#include <openssl/evp.h>
15e1051a39Sopenharmony_ci#include <openssl/core_names.h>
16e1051a39Sopenharmony_ci#include <openssl/kdf.h>
17e1051a39Sopenharmony_ci
18e1051a39Sopenharmony_ci/*
19e1051a39Sopenharmony_ci * Doesn't do anything now: Builtin PBE algorithms in static table.
20e1051a39Sopenharmony_ci */
21e1051a39Sopenharmony_ci
22e1051a39Sopenharmony_civoid PKCS5_PBE_add(void)
23e1051a39Sopenharmony_ci{
24e1051a39Sopenharmony_ci}
25e1051a39Sopenharmony_ci
26e1051a39Sopenharmony_ciint PKCS5_PBE_keyivgen_ex(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
27e1051a39Sopenharmony_ci                          ASN1_TYPE *param, const EVP_CIPHER *cipher,
28e1051a39Sopenharmony_ci                          const EVP_MD *md, int en_de, OSSL_LIB_CTX *libctx,
29e1051a39Sopenharmony_ci                          const char *propq)
30e1051a39Sopenharmony_ci{
31e1051a39Sopenharmony_ci    unsigned char md_tmp[EVP_MAX_MD_SIZE];
32e1051a39Sopenharmony_ci    unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
33e1051a39Sopenharmony_ci    int ivl, kl;
34e1051a39Sopenharmony_ci    PBEPARAM *pbe = NULL;
35e1051a39Sopenharmony_ci    int saltlen, iter;
36e1051a39Sopenharmony_ci    unsigned char *salt;
37e1051a39Sopenharmony_ci    int mdsize;
38e1051a39Sopenharmony_ci    int rv = 0;
39e1051a39Sopenharmony_ci    EVP_KDF *kdf;
40e1051a39Sopenharmony_ci    EVP_KDF_CTX *kctx = NULL;
41e1051a39Sopenharmony_ci    OSSL_PARAM params[5], *p = params;
42e1051a39Sopenharmony_ci    const char *mdname = EVP_MD_name(md);
43e1051a39Sopenharmony_ci
44e1051a39Sopenharmony_ci    /* Extract useful info from parameter */
45e1051a39Sopenharmony_ci    if (param == NULL || param->type != V_ASN1_SEQUENCE ||
46e1051a39Sopenharmony_ci        param->value.sequence == NULL) {
47e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_EVP, EVP_R_DECODE_ERROR);
48e1051a39Sopenharmony_ci        return 0;
49e1051a39Sopenharmony_ci    }
50e1051a39Sopenharmony_ci
51e1051a39Sopenharmony_ci    pbe = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBEPARAM), param);
52e1051a39Sopenharmony_ci    if (pbe == NULL) {
53e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_EVP, EVP_R_DECODE_ERROR);
54e1051a39Sopenharmony_ci        return 0;
55e1051a39Sopenharmony_ci    }
56e1051a39Sopenharmony_ci
57e1051a39Sopenharmony_ci    ivl = EVP_CIPHER_get_iv_length(cipher);
58e1051a39Sopenharmony_ci    if (ivl < 0 || ivl > 16) {
59e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_IV_LENGTH);
60e1051a39Sopenharmony_ci        goto err;
61e1051a39Sopenharmony_ci    }
62e1051a39Sopenharmony_ci    kl = EVP_CIPHER_get_key_length(cipher);
63e1051a39Sopenharmony_ci    if (kl < 0 || kl > (int)sizeof(md_tmp)) {
64e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY_LENGTH);
65e1051a39Sopenharmony_ci        goto err;
66e1051a39Sopenharmony_ci    }
67e1051a39Sopenharmony_ci
68e1051a39Sopenharmony_ci    if (pbe->iter == NULL)
69e1051a39Sopenharmony_ci        iter = 1;
70e1051a39Sopenharmony_ci    else
71e1051a39Sopenharmony_ci        iter = ASN1_INTEGER_get(pbe->iter);
72e1051a39Sopenharmony_ci    salt = pbe->salt->data;
73e1051a39Sopenharmony_ci    saltlen = pbe->salt->length;
74e1051a39Sopenharmony_ci
75e1051a39Sopenharmony_ci    if (pass == NULL)
76e1051a39Sopenharmony_ci        passlen = 0;
77e1051a39Sopenharmony_ci    else if (passlen == -1)
78e1051a39Sopenharmony_ci        passlen = strlen(pass);
79e1051a39Sopenharmony_ci
80e1051a39Sopenharmony_ci    mdsize = EVP_MD_get_size(md);
81e1051a39Sopenharmony_ci    if (mdsize < 0)
82e1051a39Sopenharmony_ci        goto err;
83e1051a39Sopenharmony_ci
84e1051a39Sopenharmony_ci    kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_PBKDF1, propq);
85e1051a39Sopenharmony_ci    kctx = EVP_KDF_CTX_new(kdf);
86e1051a39Sopenharmony_ci    EVP_KDF_free(kdf);
87e1051a39Sopenharmony_ci    if (kctx == NULL)
88e1051a39Sopenharmony_ci        goto err;
89e1051a39Sopenharmony_ci    *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD,
90e1051a39Sopenharmony_ci                                             (char *)pass, (size_t)passlen);
91e1051a39Sopenharmony_ci    *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
92e1051a39Sopenharmony_ci                                             salt, saltlen);
93e1051a39Sopenharmony_ci    *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_ITER, &iter);
94e1051a39Sopenharmony_ci    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
95e1051a39Sopenharmony_ci                                            (char *)mdname, 0);
96e1051a39Sopenharmony_ci    *p = OSSL_PARAM_construct_end();
97e1051a39Sopenharmony_ci    if (EVP_KDF_derive(kctx, md_tmp, mdsize, params) != 1)
98e1051a39Sopenharmony_ci        goto err;
99e1051a39Sopenharmony_ci    memcpy(key, md_tmp, kl);
100e1051a39Sopenharmony_ci    memcpy(iv, md_tmp + (16 - ivl), ivl);
101e1051a39Sopenharmony_ci    if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de))
102e1051a39Sopenharmony_ci        goto err;
103e1051a39Sopenharmony_ci    OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE);
104e1051a39Sopenharmony_ci    OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
105e1051a39Sopenharmony_ci    OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
106e1051a39Sopenharmony_ci    rv = 1;
107e1051a39Sopenharmony_ci err:
108e1051a39Sopenharmony_ci    EVP_KDF_CTX_free(kctx);
109e1051a39Sopenharmony_ci    PBEPARAM_free(pbe);
110e1051a39Sopenharmony_ci    return rv;
111e1051a39Sopenharmony_ci}
112e1051a39Sopenharmony_ci
113e1051a39Sopenharmony_ciint PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
114e1051a39Sopenharmony_ci                       ASN1_TYPE *param, const EVP_CIPHER *cipher,
115e1051a39Sopenharmony_ci                       const EVP_MD *md, int en_de)
116e1051a39Sopenharmony_ci{
117e1051a39Sopenharmony_ci    return PKCS5_PBE_keyivgen_ex(cctx, pass, passlen, param, cipher, md, en_de,
118e1051a39Sopenharmony_ci                                 NULL, NULL);
119e1051a39Sopenharmony_ci}
120e1051a39Sopenharmony_ci
121