1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2015-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 <openssl/evp.h> 11e1051a39Sopenharmony_ci#include <openssl/err.h> 12e1051a39Sopenharmony_ci#include <openssl/kdf.h> 13e1051a39Sopenharmony_ci#include <openssl/core_names.h> 14e1051a39Sopenharmony_ci#include "internal/numbers.h" 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_SCRYPT 17e1051a39Sopenharmony_ci 18e1051a39Sopenharmony_ci/* 19e1051a39Sopenharmony_ci * Maximum permitted memory allow this to be overridden with Configuration 20e1051a39Sopenharmony_ci * option: e.g. -DSCRYPT_MAX_MEM=0 for maximum possible. 21e1051a39Sopenharmony_ci */ 22e1051a39Sopenharmony_ci 23e1051a39Sopenharmony_ci#ifdef SCRYPT_MAX_MEM 24e1051a39Sopenharmony_ci# if SCRYPT_MAX_MEM == 0 25e1051a39Sopenharmony_ci# undef SCRYPT_MAX_MEM 26e1051a39Sopenharmony_ci/* 27e1051a39Sopenharmony_ci * Although we could theoretically allocate SIZE_MAX memory that would leave 28e1051a39Sopenharmony_ci * no memory available for anything else so set limit as half that. 29e1051a39Sopenharmony_ci */ 30e1051a39Sopenharmony_ci# define SCRYPT_MAX_MEM (SIZE_MAX/2) 31e1051a39Sopenharmony_ci# endif 32e1051a39Sopenharmony_ci#else 33e1051a39Sopenharmony_ci/* Default memory limit: 32 MB */ 34e1051a39Sopenharmony_ci# define SCRYPT_MAX_MEM (1024 * 1024 * 32) 35e1051a39Sopenharmony_ci#endif 36e1051a39Sopenharmony_ci 37e1051a39Sopenharmony_ciint EVP_PBE_scrypt_ex(const char *pass, size_t passlen, 38e1051a39Sopenharmony_ci const unsigned char *salt, size_t saltlen, 39e1051a39Sopenharmony_ci uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, 40e1051a39Sopenharmony_ci unsigned char *key, size_t keylen, 41e1051a39Sopenharmony_ci OSSL_LIB_CTX *ctx, const char *propq) 42e1051a39Sopenharmony_ci{ 43e1051a39Sopenharmony_ci const char *empty = ""; 44e1051a39Sopenharmony_ci int rv = 1; 45e1051a39Sopenharmony_ci EVP_KDF *kdf; 46e1051a39Sopenharmony_ci EVP_KDF_CTX *kctx; 47e1051a39Sopenharmony_ci OSSL_PARAM params[7], *z = params; 48e1051a39Sopenharmony_ci 49e1051a39Sopenharmony_ci if (r > UINT32_MAX || p > UINT32_MAX) { 50e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, EVP_R_PARAMETER_TOO_LARGE); 51e1051a39Sopenharmony_ci return 0; 52e1051a39Sopenharmony_ci } 53e1051a39Sopenharmony_ci 54e1051a39Sopenharmony_ci /* Maintain existing behaviour. */ 55e1051a39Sopenharmony_ci if (pass == NULL) { 56e1051a39Sopenharmony_ci pass = empty; 57e1051a39Sopenharmony_ci passlen = 0; 58e1051a39Sopenharmony_ci } 59e1051a39Sopenharmony_ci if (salt == NULL) { 60e1051a39Sopenharmony_ci salt = (const unsigned char *)empty; 61e1051a39Sopenharmony_ci saltlen = 0; 62e1051a39Sopenharmony_ci } 63e1051a39Sopenharmony_ci if (maxmem == 0) 64e1051a39Sopenharmony_ci maxmem = SCRYPT_MAX_MEM; 65e1051a39Sopenharmony_ci 66e1051a39Sopenharmony_ci /* Use OSSL_LIB_CTX_set0_default() if you need a library context */ 67e1051a39Sopenharmony_ci kdf = EVP_KDF_fetch(ctx, OSSL_KDF_NAME_SCRYPT, propq); 68e1051a39Sopenharmony_ci kctx = EVP_KDF_CTX_new(kdf); 69e1051a39Sopenharmony_ci EVP_KDF_free(kdf); 70e1051a39Sopenharmony_ci if (kctx == NULL) 71e1051a39Sopenharmony_ci return 0; 72e1051a39Sopenharmony_ci 73e1051a39Sopenharmony_ci *z++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, 74e1051a39Sopenharmony_ci (unsigned char *)pass, 75e1051a39Sopenharmony_ci passlen); 76e1051a39Sopenharmony_ci *z++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, 77e1051a39Sopenharmony_ci (unsigned char *)salt, saltlen); 78e1051a39Sopenharmony_ci *z++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_N, &N); 79e1051a39Sopenharmony_ci *z++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_R, &r); 80e1051a39Sopenharmony_ci *z++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_P, &p); 81e1051a39Sopenharmony_ci *z++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_MAXMEM, &maxmem); 82e1051a39Sopenharmony_ci *z = OSSL_PARAM_construct_end(); 83e1051a39Sopenharmony_ci if (EVP_KDF_derive(kctx, key, keylen, params) != 1) 84e1051a39Sopenharmony_ci rv = 0; 85e1051a39Sopenharmony_ci 86e1051a39Sopenharmony_ci EVP_KDF_CTX_free(kctx); 87e1051a39Sopenharmony_ci return rv; 88e1051a39Sopenharmony_ci} 89e1051a39Sopenharmony_ci 90e1051a39Sopenharmony_ciint EVP_PBE_scrypt(const char *pass, size_t passlen, 91e1051a39Sopenharmony_ci const unsigned char *salt, size_t saltlen, 92e1051a39Sopenharmony_ci uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, 93e1051a39Sopenharmony_ci unsigned char *key, size_t keylen) 94e1051a39Sopenharmony_ci{ 95e1051a39Sopenharmony_ci return EVP_PBE_scrypt_ex(pass, passlen, salt, saltlen, N, r, p, maxmem, 96e1051a39Sopenharmony_ci key, keylen, NULL, NULL); 97e1051a39Sopenharmony_ci} 98e1051a39Sopenharmony_ci 99e1051a39Sopenharmony_ci#endif 100