From e98aa30d555cb5a656d320a0f86ab5b3b1dce2db Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Wed, 20 May 2015 13:23:06 +0100 Subject: [PATCH 1/1] Add scrypt PBE algorithm code. This adds support for the ASN.1 structures in draft-josefsson-scrypt-kdf-03 Private keys encrypted by scrypt can now be decrypted transparently as long as they don't exceed the memory limits. Reviewed-by: Rich Salz --- crypto/asn1/Makefile | 8 +- crypto/asn1/asn1_err.c | 4 + crypto/asn1/p5_scrypt.c | 332 ++++++++++++++++++++++++++++++++++++++++ crypto/evp/evp_err.c | 10 +- crypto/evp/evp_pbe.c | 3 +- include/openssl/asn1.h | 3 + include/openssl/evp.h | 6 + include/openssl/x509.h | 5 + 8 files changed, 361 insertions(+), 10 deletions(-) create mode 100644 crypto/asn1/p5_scrypt.c diff --git a/crypto/asn1/Makefile b/crypto/asn1/Makefile index 20b79489bb..cfa30dd4e9 100644 --- a/crypto/asn1/Makefile +++ b/crypto/asn1/Makefile @@ -27,8 +27,8 @@ LIBSRC= a_object.c a_bitstr.c a_utctm.c a_gentm.c a_time.c a_int.c a_octet.c \ f_int.c f_string.c n_pkey.c \ x_pkey.c bio_asn1.c bio_ndef.c asn_mime.c \ asn1_gen.c asn1_par.c asn1_lib.c asn1_err.c a_strnid.c \ - evp_asn1.c asn_pack.c p5_pbe.c p5_pbev2.c p8_pkey.c asn_moid.c \ - asn_mstbl.c + evp_asn1.c asn_pack.c p5_pbe.c p5_pbev2.c p5_scrypt.c p8_pkey.c \ + asn_moid.c asn_mstbl.c LIBOBJ= a_object.o a_bitstr.o a_utctm.o a_gentm.o a_time.o a_int.o a_octet.o \ a_print.o a_type.o a_dup.o a_d2i_fp.o a_i2d_fp.o \ a_utf8.o a_sign.o a_digest.o a_verify.o a_mbstr.o a_strex.o \ @@ -41,8 +41,8 @@ LIBOBJ= a_object.o a_bitstr.o a_utctm.o a_gentm.o a_time.o a_int.o a_octet.o \ f_int.o f_string.o n_pkey.o \ x_pkey.o bio_asn1.o bio_ndef.o asn_mime.o \ asn1_gen.o asn1_par.o asn1_lib.o asn1_err.o a_strnid.o \ - evp_asn1.o asn_pack.o p5_pbe.o p5_pbev2.o p8_pkey.o asn_moid.o \ - asn_mstbl.o + evp_asn1.o asn_pack.o p5_pbe.o p5_pbev2.o p5_scrypt.o p8_pkey.o \ + asn_moid.o asn_mstbl.o SRC= $(LIBSRC) diff --git a/crypto/asn1/asn1_err.c b/crypto/asn1/asn1_err.c index 0fc0b5e584..b7fbd9d99b 100644 --- a/crypto/asn1/asn1_err.c +++ b/crypto/asn1/asn1_err.c @@ -188,9 +188,11 @@ static ERR_STRING_DATA ASN1_str_functs[] = { {ERR_FUNC(ASN1_F_OID_MODULE_INIT), "OID_MODULE_INIT"}, {ERR_FUNC(ASN1_F_PARSE_TAGGING), "PARSE_TAGGING"}, {ERR_FUNC(ASN1_F_PKCS5_PBE2_SET_IV), "PKCS5_pbe2_set_iv"}, + {ERR_FUNC(ASN1_F_PKCS5_PBE2_SET_SCRYPT), "PKCS5_pbe2_set_scrypt"}, {ERR_FUNC(ASN1_F_PKCS5_PBE_SET), "PKCS5_pbe_set"}, {ERR_FUNC(ASN1_F_PKCS5_PBE_SET0_ALGOR), "PKCS5_pbe_set0_algor"}, {ERR_FUNC(ASN1_F_PKCS5_PBKDF2_SET), "PKCS5_pbkdf2_set"}, + {ERR_FUNC(ASN1_F_PKCS5_SCRYPT_SET), "PKCS5_SCRYPT_SET"}, {ERR_FUNC(ASN1_F_SMIME_READ_ASN1), "SMIME_read_ASN1"}, {ERR_FUNC(ASN1_F_SMIME_TEXT), "SMIME_text"}, {ERR_FUNC(ASN1_F_STBL_MODULE_INIT), "STBL_MODULE_INIT"}, @@ -275,6 +277,8 @@ static ERR_STRING_DATA ASN1_str_reasons[] = { {ERR_REASON(ASN1_R_INVALID_MODIFIER), "invalid modifier"}, {ERR_REASON(ASN1_R_INVALID_NUMBER), "invalid number"}, {ERR_REASON(ASN1_R_INVALID_OBJECT_ENCODING), "invalid object encoding"}, + {ERR_REASON(ASN1_R_INVALID_SCRYPT_PARAMETERS), + "invalid scrypt parameters"}, {ERR_REASON(ASN1_R_INVALID_SEPARATOR), "invalid separator"}, {ERR_REASON(ASN1_R_INVALID_STRING_TABLE_VALUE), "invalid string table value"}, diff --git a/crypto/asn1/p5_scrypt.c b/crypto/asn1/p5_scrypt.c new file mode 100644 index 0000000000..5c4de797f9 --- /dev/null +++ b/crypto/asn1/p5_scrypt.c @@ -0,0 +1,332 @@ +/* p5_scrypt.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2015. + */ +/* ==================================================================== + * Copyright (c) 2015 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "internal/cryptlib.h" +#include +#include +#include +#include +#include + +/* PKCS#5 scrypt password based encryption structures */ + +typedef struct { + ASN1_OCTET_STRING *salt; + ASN1_INTEGER *costParameter; + ASN1_INTEGER *blockSize; + ASN1_INTEGER *parallelizationParameter; + ASN1_INTEGER *keyLength; +} SCRYPT_PARAMS; + +ASN1_SEQUENCE(SCRYPT_PARAMS) = { + ASN1_SIMPLE(SCRYPT_PARAMS, salt, ASN1_OCTET_STRING), + ASN1_SIMPLE(SCRYPT_PARAMS, costParameter, ASN1_INTEGER), + ASN1_SIMPLE(SCRYPT_PARAMS, blockSize, ASN1_INTEGER), + ASN1_SIMPLE(SCRYPT_PARAMS, parallelizationParameter, ASN1_INTEGER), + ASN1_OPT(SCRYPT_PARAMS, keyLength, ASN1_INTEGER), +} ASN1_SEQUENCE_END(SCRYPT_PARAMS) + +DECLARE_ASN1_ALLOC_FUNCTIONS(SCRYPT_PARAMS) +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(SCRYPT_PARAMS) + +static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, size_t saltlen, + size_t keylen, uint64_t N, uint64_t r, + uint64_t p); + +/* + * Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm using scrypt + */ + +X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher, + const unsigned char *salt, int saltlen, + unsigned char *aiv, uint64_t N, uint64_t r, + uint64_t p) +{ + X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL; + int alg_nid; + size_t keylen = 0; + EVP_CIPHER_CTX ctx; + unsigned char iv[EVP_MAX_IV_LENGTH]; + PBE2PARAM *pbe2 = NULL; + ASN1_OBJECT *obj; + + if (!cipher) { + ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + + if (EVP_PBE_scrypt(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0) == 0) { + ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, + ASN1_R_INVALID_SCRYPT_PARAMETERS); + goto err; + } + + alg_nid = EVP_CIPHER_type(cipher); + if (alg_nid == NID_undef) { + ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, + ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); + goto err; + } + obj = OBJ_nid2obj(alg_nid); + pbe2 = PBE2PARAM_new(); + if (pbe2 == NULL) + goto merr; + + /* Setup the AlgorithmIdentifier for the encryption scheme */ + scheme = pbe2->encryption; + + scheme->algorithm = obj; + scheme->parameter = ASN1_TYPE_new(); + if (scheme->parameter == NULL) + goto merr; + + /* Create random IV */ + if (EVP_CIPHER_iv_length(cipher)) { + if (aiv) + memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher)); + else if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0) + goto err; + } + + EVP_CIPHER_CTX_init(&ctx); + + /* Dummy cipherinit to just setup the IV */ + if (EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0) == 0) + goto err; + if (EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) { + ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, + ASN1_R_ERROR_SETTING_CIPHER_PARAMS); + EVP_CIPHER_CTX_cleanup(&ctx); + goto err; + } + EVP_CIPHER_CTX_cleanup(&ctx); + + /* If its RC2 then we'd better setup the key length */ + + if (alg_nid == NID_rc2_cbc) + keylen = EVP_CIPHER_key_length(cipher); + + /* Setup keyfunc */ + + X509_ALGOR_free(pbe2->keyfunc); + + pbe2->keyfunc = pkcs5_scrypt_set(salt, saltlen, keylen, N, r, p); + + if (pbe2->keyfunc == NULL) + goto merr; + + /* Now set up top level AlgorithmIdentifier */ + + ret = X509_ALGOR_new(); + if (ret == NULL) + goto merr; + + ret->algorithm = OBJ_nid2obj(NID_pbes2); + + /* Encode PBE2PARAM into parameter */ + + if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM), pbe2, + &ret->parameter) == NULL) + goto merr; + + PBE2PARAM_free(pbe2); + pbe2 = NULL; + + return ret; + + merr: + ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ERR_R_MALLOC_FAILURE); + + err: + PBE2PARAM_free(pbe2); + X509_ALGOR_free(kalg); + X509_ALGOR_free(ret); + + return NULL; + +} + +static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, size_t saltlen, + size_t keylen, uint64_t N, uint64_t r, + uint64_t p) +{ + X509_ALGOR *keyfunc = NULL; + SCRYPT_PARAMS *sparam = NULL; + + sparam = SCRYPT_PARAMS_new(); + if (sparam == NULL) + goto merr; + + if (!saltlen) + saltlen = PKCS5_SALT_LEN; + + /* This will either copy salt or grow the buffer */ + if (ASN1_STRING_set(sparam->salt, salt, saltlen) == 0) + goto merr; + + if (salt == NULL && RAND_bytes(sparam->salt->data, saltlen) <= 0) + goto err; + + if (ASN1_INTEGER_set_uint64(sparam->costParameter, N) == 0) + goto merr; + + if (ASN1_INTEGER_set_uint64(sparam->blockSize, r) == 0) + goto merr; + + if (ASN1_INTEGER_set_uint64(sparam->parallelizationParameter, p) == 0) + goto merr; + + /* If have a key len set it up */ + + if (keylen > 0) { + sparam->keyLength = ASN1_INTEGER_new(); + if (sparam->keyLength == NULL) + goto merr; + if (ASN1_INTEGER_set_int64(sparam->keyLength, keylen) == 0) + goto merr; + } + + /* Finally setup the keyfunc structure */ + + keyfunc = X509_ALGOR_new(); + if (!keyfunc) + goto merr; + + keyfunc->algorithm = OBJ_nid2obj(NID_id_scrypt); + + /* Encode SCRYPT_PARAMS into parameter of pbe2 */ + + if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(SCRYPT_PARAMS), sparam, + &keyfunc->parameter) == NULL) + goto merr; + + SCRYPT_PARAMS_free(sparam); + return keyfunc; + + merr: + ASN1err(ASN1_F_PKCS5_SCRYPT_SET, ERR_R_MALLOC_FAILURE); + err: + SCRYPT_PARAMS_free(sparam); + X509_ALGOR_free(keyfunc); + return NULL; +} + +int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, + int passlen, ASN1_TYPE *param, + const EVP_CIPHER *c, const EVP_MD *md, int en_de) +{ + unsigned char *salt, key[EVP_MAX_KEY_LENGTH]; + uint64_t p, r, N; + size_t saltlen; + size_t keylen = 0; + int rv = 0; + SCRYPT_PARAMS *sparam = NULL; + + if (EVP_CIPHER_CTX_cipher(ctx) == NULL) { + EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, EVP_R_NO_CIPHER_SET); + goto err; + } + + /* Decode parameter */ + + sparam = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(SCRYPT_PARAMS), param); + + if (sparam == NULL) { + EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, EVP_R_DECODE_ERROR); + goto err; + } + + keylen = EVP_CIPHER_CTX_key_length(ctx); + + /* Now check the parameters of sparam */ + + if (sparam->keyLength) { + uint64_t spkeylen; + if ((ASN1_INTEGER_get_uint64(&spkeylen, sparam->keyLength) == 0) + || (spkeylen != keylen)) { + EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, + EVP_R_UNSUPPORTED_KEYLENGTH); + goto err; + } + } + /* Check all parameters fit in uint64_t and are acceptable to scrypt */ + if (ASN1_INTEGER_get_uint64(&N, sparam->costParameter) == 0 + || ASN1_INTEGER_get_uint64(&r, sparam->blockSize) == 0 + || ASN1_INTEGER_get_uint64(&p, sparam->parallelizationParameter) == 0 + || EVP_PBE_scrypt(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0) == 0) { + EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, + EVP_R_ILLEGAL_SCRYPT_PARAMETERS); + goto err; + } + + /* it seems that its all OK */ + + salt = sparam->salt->data; + saltlen = sparam->salt->length; + if (EVP_PBE_scrypt(pass, passlen, salt, saltlen, N, r, p, 0, key, keylen) + == 0) + goto err; + rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de); + err: + if (keylen) + OPENSSL_cleanse(key, keylen); + SCRYPT_PARAMS_free(sparam); + return rv; +} diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index 7d8f4c6e6b..00c9386e83 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -1,6 +1,6 @@ /* crypto/evp/evp_err.c */ /* ==================================================================== - * Copyright (c) 1999-2013 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -148,6 +148,7 @@ static ERR_STRING_DATA EVP_str_functs[] = { {ERR_FUNC(EVP_F_PKCS5_PBE_KEYIVGEN), "PKCS5_PBE_keyivgen"}, {ERR_FUNC(EVP_F_PKCS5_V2_PBE_KEYIVGEN), "PKCS5_v2_PBE_keyivgen"}, {ERR_FUNC(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN), "PKCS5_V2_PBKDF2_KEYIVGEN"}, + {ERR_FUNC(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN), "PKCS5_v2_scrypt_keyivgen"}, {ERR_FUNC(EVP_F_PKCS8_SET_BROKEN), "PKCS8_set_broken"}, {ERR_FUNC(EVP_F_PKEY_SET_TYPE), "PKEY_SET_TYPE"}, {ERR_FUNC(EVP_F_RC2_MAGIC_TO_METH), "RC2_MAGIC_TO_METH"}, @@ -165,8 +166,7 @@ static ERR_STRING_DATA EVP_str_reasons[] = { {ERR_REASON(EVP_R_BN_DECODE_ERROR), "bn decode error"}, {ERR_REASON(EVP_R_BN_PUBKEY_ERROR), "bn pubkey error"}, {ERR_REASON(EVP_R_BUFFER_TOO_SMALL), "buffer too small"}, - {ERR_REASON(EVP_R_CAMELLIA_KEY_SETUP_FAILED), - "camellia key setup failed"}, + {ERR_REASON(EVP_R_CAMELLIA_KEY_SETUP_FAILED), "camellia key setup failed"}, {ERR_REASON(EVP_R_CIPHER_PARAMETER_ERROR), "cipher parameter error"}, {ERR_REASON(EVP_R_COMMAND_NOT_SUPPORTED), "command not supported"}, {ERR_REASON(EVP_R_CTRL_NOT_IMPLEMENTED), "ctrl not implemented"}, @@ -188,6 +188,7 @@ static ERR_STRING_DATA EVP_str_reasons[] = { {ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY), "expecting a ecdsa key"}, {ERR_REASON(EVP_R_EXPECTING_A_EC_KEY), "expecting a ec key"}, {ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"}, + {ERR_REASON(EVP_R_ILLEGAL_SCRYPT_PARAMETERS), "illegal scrypt parameters"}, {ERR_REASON(EVP_R_INITIALIZATION_ERROR), "initialization error"}, {ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED), "input not initialized"}, {ERR_REASON(EVP_R_INVALID_DIGEST), "invalid digest"}, @@ -212,8 +213,7 @@ static ERR_STRING_DATA EVP_str_reasons[] = { {ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), "operation not supported for this keytype"}, {ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED), "operaton not initialized"}, - {ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE), - "pkcs8 unknown broken type"}, + {ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE), "pkcs8 unknown broken type"}, {ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR), "private key decode error"}, {ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR), "private key encode error"}, {ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"}, diff --git a/crypto/evp/evp_pbe.c b/crypto/evp/evp_pbe.c index e4ad16b292..13d96587a3 100644 --- a/crypto/evp/evp_pbe.c +++ b/crypto/evp/evp_pbe.c @@ -118,7 +118,8 @@ static const EVP_PBE_CTL builtin_pbe[] = { {EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0}, {EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0}, {EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0}, - {EVP_PBE_TYPE_KDF, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen} + {EVP_PBE_TYPE_KDF, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen}, + {EVP_PBE_TYPE_KDF, NID_id_scrypt, -1, -1, PKCS5_v2_scrypt_keyivgen} }; #ifdef TEST diff --git a/include/openssl/asn1.h b/include/openssl/asn1.h index cdd587bab7..06ee0369db 100644 --- a/include/openssl/asn1.h +++ b/include/openssl/asn1.h @@ -1033,9 +1033,11 @@ void ERR_load_ASN1_strings(void); # define ASN1_F_OID_MODULE_INIT 174 # define ASN1_F_PARSE_TAGGING 182 # define ASN1_F_PKCS5_PBE2_SET_IV 167 +# define ASN1_F_PKCS5_PBE2_SET_SCRYPT 231 # define ASN1_F_PKCS5_PBE_SET 202 # define ASN1_F_PKCS5_PBE_SET0_ALGOR 215 # define ASN1_F_PKCS5_PBKDF2_SET 219 +# define ASN1_F_PKCS5_SCRYPT_SET 232 # define ASN1_F_SMIME_READ_ASN1 212 # define ASN1_F_SMIME_TEXT 213 # define ASN1_F_STBL_MODULE_INIT 223 @@ -1109,6 +1111,7 @@ void ERR_load_ASN1_strings(void); # define ASN1_R_INVALID_MODIFIER 186 # define ASN1_R_INVALID_NUMBER 187 # define ASN1_R_INVALID_OBJECT_ENCODING 216 +# define ASN1_R_INVALID_SCRYPT_PARAMETERS 227 # define ASN1_R_INVALID_SEPARATOR 131 # define ASN1_R_INVALID_STRING_TABLE_VALUE 218 # define ASN1_R_INVALID_TIME_FORMAT 132 diff --git a/include/openssl/evp.h b/include/openssl/evp.h index d5af5ed192..3a4bcbd505 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -1072,6 +1072,10 @@ int EVP_PBE_scrypt(const char *pass, size_t passlen, uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, unsigned char *key, size_t keylen); +int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, + int passlen, ASN1_TYPE *param, + const EVP_CIPHER *c, const EVP_MD *md, int en_de); + void PKCS5_PBE_add(void); int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, @@ -1489,6 +1493,7 @@ void ERR_load_EVP_strings(void); # define EVP_F_PKCS5_PBE_KEYIVGEN 117 # define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118 # define EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN 164 +# define EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN 180 # define EVP_F_PKCS8_SET_BROKEN 112 # define EVP_F_PKEY_SET_TYPE 158 # define EVP_F_RC2_MAGIC_TO_METH 109 @@ -1524,6 +1529,7 @@ void ERR_load_EVP_strings(void); # define EVP_R_EXPECTING_A_ECDSA_KEY 141 # define EVP_R_EXPECTING_A_EC_KEY 142 # define EVP_R_FIPS_MODE_NOT_SUPPORTED 167 +# define EVP_R_ILLEGAL_SCRYPT_PARAMETERS 171 # define EVP_R_INITIALIZATION_ERROR 134 # define EVP_R_INPUT_NOT_INITIALIZED 111 # define EVP_R_INVALID_DIGEST 152 diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 6f481b590b..0c2d19a97b 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -1107,6 +1107,11 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, unsigned char *salt, int saltlen, unsigned char *aiv, int prf_nid); +X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher, + const unsigned char *salt, int saltlen, + unsigned char *aiv, uint64_t N, uint64_t r, + uint64_t p); + X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, int prf_nid, int keylen); -- 2.34.1