Index: openssl-1.1.1n/crypto/err/openssl.txt =================================================================== --- openssl-1.1.1n.orig/crypto/err/openssl.txt +++ openssl-1.1.1n/crypto/err/openssl.txt @@ -754,6 +754,9 @@ EVP_F_EVP_DIGESTINIT_EX:128:EVP_DigestIn EVP_F_EVP_ENCRYPTDECRYPTUPDATE:219:evp_EncryptDecryptUpdate EVP_F_EVP_ENCRYPTFINAL_EX:127:EVP_EncryptFinal_ex EVP_F_EVP_ENCRYPTUPDATE:167:EVP_EncryptUpdate +EVP_F_EVP_KDF_CTRL:224:EVP_KDF_ctrl +EVP_F_EVP_KDF_CTRL_STR:225:EVP_KDF_ctrl_str +EVP_F_EVP_KDF_CTX_NEW_ID:226:EVP_KDF_CTX_new_id EVP_F_EVP_MD_CTX_COPY_EX:110:EVP_MD_CTX_copy_ex EVP_F_EVP_MD_SIZE:162:EVP_MD_size EVP_F_EVP_OPENINIT:102:EVP_OpenInit @@ -816,11 +819,13 @@ EVP_F_PKCS5_PBE_KEYIVGEN:117:PKCS5_PBE_k EVP_F_PKCS5_V2_PBE_KEYIVGEN:118:PKCS5_v2_PBE_keyivgen EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN:164:PKCS5_v2_PBKDF2_keyivgen EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN:180:PKCS5_v2_scrypt_keyivgen +EVP_F_PKEY_KDF_CTRL:227:pkey_kdf_ctrl EVP_F_PKEY_SET_TYPE:158:pkey_set_type EVP_F_RC2_MAGIC_TO_METH:109:rc2_magic_to_meth EVP_F_RC5_CTRL:125:rc5_ctrl EVP_F_R_32_12_16_INIT_KEY:242:r_32_12_16_init_key EVP_F_S390X_AES_GCM_CTRL:201:s390x_aes_gcm_ctrl +EVP_F_SCRYPT_ALG:228:scrypt_alg EVP_F_UPDATE:173:update FIPS_F_DH_BUILTIN_GENPARAMS:100:dh_builtin_genparams FIPS_F_DRBG_RESEED:121:drbg_reseed @@ -873,6 +878,23 @@ FIPS_F_RSA_OSSL_PRIVATE_DECRYPT:117:rsa_ FIPS_F_RSA_OSSL_PRIVATE_ENCRYPT:118:rsa_ossl_private_encrypt FIPS_F_RSA_OSSL_PUBLIC_DECRYPT:119:rsa_ossl_public_decrypt FIPS_F_RSA_OSSL_PUBLIC_ENCRYPT:120:rsa_ossl_public_encrypt +KDF_F_HKDF_EXTRACT:112:HKDF_Extract +KDF_F_KDF_HKDF_DERIVE:113:kdf_hkdf_derive +KDF_F_KDF_HKDF_NEW:114:kdf_hkdf_new +KDF_F_KDF_HKDF_SIZE:115:kdf_hkdf_size +KDF_F_KDF_MD2CTRL:116:kdf_md2ctrl +KDF_F_KDF_PBKDF2_CTRL_STR:117:kdf_pbkdf2_ctrl_str +KDF_F_KDF_PBKDF2_DERIVE:118:kdf_pbkdf2_derive +KDF_F_KDF_PBKDF2_NEW:119:kdf_pbkdf2_new +KDF_F_KDF_SCRYPT_CTRL_STR:120:kdf_scrypt_ctrl_str +KDF_F_KDF_SCRYPT_CTRL_UINT32:121:kdf_scrypt_ctrl_uint32 +KDF_F_KDF_SCRYPT_CTRL_UINT64:122:kdf_scrypt_ctrl_uint64 +KDF_F_KDF_SCRYPT_DERIVE:123:kdf_scrypt_derive +KDF_F_KDF_SCRYPT_NEW:124:kdf_scrypt_new +KDF_F_KDF_TLS1_PRF_CTRL_STR:125:kdf_tls1_prf_ctrl_str +KDF_F_KDF_TLS1_PRF_DERIVE:126:kdf_tls1_prf_derive +KDF_F_KDF_TLS1_PRF_NEW:127:kdf_tls1_prf_new +KDF_F_PBKDF2_SET_MEMBUF:128:pbkdf2_set_membuf KDF_F_PKEY_HKDF_CTRL_STR:103:pkey_hkdf_ctrl_str KDF_F_PKEY_HKDF_DERIVE:102:pkey_hkdf_derive KDF_F_PKEY_HKDF_INIT:108:pkey_hkdf_init @@ -884,6 +906,7 @@ KDF_F_PKEY_SCRYPT_SET_MEMBUF:107:pkey_sc KDF_F_PKEY_TLS1_PRF_CTRL_STR:100:pkey_tls1_prf_ctrl_str KDF_F_PKEY_TLS1_PRF_DERIVE:101:pkey_tls1_prf_derive KDF_F_PKEY_TLS1_PRF_INIT:110:pkey_tls1_prf_init +KDF_F_SCRYPT_SET_MEMBUF:129:scrypt_set_membuf KDF_F_TLS1_PRF_ALG:111:tls1_prf_alg OBJ_F_OBJ_ADD_OBJECT:105:OBJ_add_object OBJ_F_OBJ_ADD_SIGID:107:OBJ_add_sigid @@ -2344,6 +2367,7 @@ EVP_R_ONLY_ONESHOT_SUPPORTED:177:only on EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:150:\ operation not supported for this keytype EVP_R_OPERATON_NOT_INITIALIZED:151:operaton not initialized +EVP_R_PARAMETER_TOO_LARGE:187:parameter too large EVP_R_OUTPUT_WOULD_OVERFLOW:184:output would overflow EVP_R_PARTIALLY_OVERLAPPING:162:partially overlapping buffers EVP_R_PBKDF2_ERROR:181:pbkdf2 error @@ -2436,6 +2460,7 @@ KDF_R_MISSING_SEED:106:missing seed KDF_R_UNKNOWN_PARAMETER_TYPE:103:unknown parameter type KDF_R_VALUE_ERROR:108:value error KDF_R_VALUE_MISSING:102:value missing +KDF_R_WRONG_OUTPUT_BUFFER_SIZE:112:wrong output buffer size OBJ_R_OID_EXISTS:102:oid exists OBJ_R_UNKNOWN_NID:101:unknown nid OCSP_R_CERTIFICATE_VERIFY_ERROR:101:certificate verify error Index: openssl-1.1.1n/crypto/evp/build.info =================================================================== --- openssl-1.1.1n.orig/crypto/evp/build.info +++ openssl-1.1.1n/crypto/evp/build.info @@ -9,7 +9,8 @@ SOURCE[../../libcrypto]=\ p_open.c p_seal.c p_sign.c p_verify.c p_lib.c p_enc.c p_dec.c \ bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \ c_allc.c c_alld.c evp_lib.c bio_ok.c \ - evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \ + evp_pkey.c kdf_lib.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \ + pkey_kdf.c \ e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c \ e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \ e_chacha20_poly1305.c cmeth_lib.c Index: openssl-1.1.1n/crypto/evp/evp_err.c =================================================================== --- openssl-1.1.1n.orig/crypto/evp/evp_err.c +++ openssl-1.1.1n/crypto/evp/evp_err.c @@ -60,6 +60,9 @@ static const ERR_STRING_DATA EVP_str_fun {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTFINAL_EX, 0), "EVP_EncryptFinal_ex"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTUPDATE, 0), "EVP_EncryptUpdate"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTRL, 0), "EVP_KDF_ctrl"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTRL_STR, 0), "EVP_KDF_ctrl_str"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTX_NEW_ID, 0), "EVP_KDF_CTX_new_id"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MD_CTX_COPY_EX, 0), "EVP_MD_CTX_copy_ex"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MD_SIZE, 0), "EVP_MD_size"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_OPENINIT, 0), "EVP_OpenInit"}, @@ -151,12 +154,14 @@ static const ERR_STRING_DATA EVP_str_fun "PKCS5_v2_PBKDF2_keyivgen"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, 0), "PKCS5_v2_scrypt_keyivgen"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_KDF_CTRL, 0), "pkey_kdf_ctrl"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_SET_TYPE, 0), "pkey_set_type"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_RC2_MAGIC_TO_METH, 0), "rc2_magic_to_meth"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_RC5_CTRL, 0), "rc5_ctrl"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_R_32_12_16_INIT_KEY, 0), "r_32_12_16_init_key"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_S390X_AES_GCM_CTRL, 0), "s390x_aes_gcm_ctrl"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_SCRYPT_ALG, 0), "scrypt_alg"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_UPDATE, 0), "update"}, {0, NULL} }; @@ -241,6 +246,8 @@ static const ERR_STRING_DATA EVP_str_rea "operation not supported for this keytype"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATON_NOT_INITIALIZED), "operaton not initialized"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PARAMETER_TOO_LARGE), + "parameter too large"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OUTPUT_WOULD_OVERFLOW), "output would overflow"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PARTIALLY_OVERLAPPING), Index: openssl-1.1.1n/crypto/evp/evp_local.h =================================================================== --- openssl-1.1.1n.orig/crypto/evp/evp_local.h +++ openssl-1.1.1n/crypto/evp/evp_local.h @@ -41,6 +41,11 @@ struct evp_cipher_ctx_st { unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */ } /* EVP_CIPHER_CTX */ ; +struct evp_kdf_ctx_st { + const EVP_KDF_METHOD *kmeth; + EVP_KDF_IMPL *impl; /* Algorithm-specific data */ +} /* EVP_KDF_CTX */ ; + int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md, Index: openssl-1.1.1n/crypto/evp/evp_pbe.c =================================================================== --- openssl-1.1.1n.orig/crypto/evp/evp_pbe.c +++ openssl-1.1.1n/crypto/evp/evp_pbe.c @@ -12,6 +12,7 @@ #include #include #include +#include "crypto/evp.h" #include "evp_local.h" /* Password based encryption (PBE) functions */ Index: openssl-1.1.1n/crypto/evp/kdf_lib.c =================================================================== --- /dev/null +++ openssl-1.1.1n/crypto/evp/kdf_lib.c @@ -0,0 +1,165 @@ +/* + * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "internal/cryptlib.h" +#include +#include +#include +#include +#include "crypto/asn1.h" +#include "crypto/evp.h" +#include "internal/numbers.h" +#include "evp_local.h" + +typedef int sk_cmp_fn_type(const char *const *a, const char *const *b); + +/* This array needs to be in order of NIDs */ +static const EVP_KDF_METHOD *standard_methods[] = { + &pbkdf2_kdf_meth, +#ifndef OPENSSL_NO_SCRYPT + &scrypt_kdf_meth, +#endif + &tls1_prf_kdf_meth, + &hkdf_kdf_meth +}; + +DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_KDF_METHOD *, const EVP_KDF_METHOD *, + kmeth); + +static int kmeth_cmp(const EVP_KDF_METHOD *const *a, + const EVP_KDF_METHOD *const *b) +{ + return ((*a)->type - (*b)->type); +} + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_KDF_METHOD *, const EVP_KDF_METHOD *, + kmeth); + +static const EVP_KDF_METHOD *kdf_meth_find(int type) +{ + EVP_KDF_METHOD tmp; + const EVP_KDF_METHOD *t = &tmp, **ret; + + tmp.type = type; + ret = OBJ_bsearch_kmeth(&t, standard_methods, + OSSL_NELEM(standard_methods)); + if (ret == NULL || *ret == NULL) + return NULL; + + return *ret; +} + +EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id) +{ + EVP_KDF_CTX *ret; + const EVP_KDF_METHOD *kmeth; + + kmeth = kdf_meth_find(id); + if (kmeth == NULL) { + EVPerr(EVP_F_EVP_KDF_CTX_NEW_ID, EVP_R_UNSUPPORTED_ALGORITHM); + return NULL; + } + + ret = OPENSSL_zalloc(sizeof(*ret)); + if (ret == NULL) { + EVPerr(EVP_F_EVP_KDF_CTX_NEW_ID, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (kmeth->new != NULL && (ret->impl = kmeth->new()) == NULL) { + EVP_KDF_CTX_free(ret); + return NULL; + } + + ret->kmeth = kmeth; + return ret; +} + +void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx) +{ + if (ctx == NULL) + return; + + ctx->kmeth->free(ctx->impl); + OPENSSL_free(ctx); +} + +void EVP_KDF_reset(EVP_KDF_CTX *ctx) +{ + if (ctx == NULL) + return; + + if (ctx->kmeth->reset != NULL) + ctx->kmeth->reset(ctx->impl); +} + +int EVP_KDF_ctrl(EVP_KDF_CTX *ctx, int cmd, ...) +{ + int ret; + va_list args; + + va_start(args, cmd); + ret = EVP_KDF_vctrl(ctx, cmd, args); + va_end(args); + + if (ret == -2) + EVPerr(EVP_F_EVP_KDF_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); + + return ret; +} + +int EVP_KDF_vctrl(EVP_KDF_CTX *ctx, int cmd, va_list args) +{ + if (ctx == NULL) + return 0; + + return ctx->kmeth->ctrl(ctx->impl, cmd, args); +} + +int EVP_KDF_ctrl_str(EVP_KDF_CTX *ctx, const char *type, const char *value) +{ + int ret; + + if (ctx == NULL) + return 0; + + if (ctx->kmeth->ctrl_str == NULL) { + EVPerr(EVP_F_EVP_KDF_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + + ret = ctx->kmeth->ctrl_str(ctx->impl, type, value); + if (ret == -2) + EVPerr(EVP_F_EVP_KDF_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED); + + return ret; +} + +size_t EVP_KDF_size(EVP_KDF_CTX *ctx) +{ + if (ctx == NULL) + return 0; + + if (ctx->kmeth->size == NULL) + return SIZE_MAX; + + return ctx->kmeth->size(ctx->impl); +} + +int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen) +{ + if (ctx == NULL) + return 0; + + return ctx->kmeth->derive(ctx->impl, key, keylen); +} + Index: openssl-1.1.1n/crypto/evp/p5_crpt2.c =================================================================== --- openssl-1.1.1n.orig/crypto/evp/p5_crpt2.c +++ openssl-1.1.1n/crypto/evp/p5_crpt2.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -10,105 +10,51 @@ #include #include #include "internal/cryptlib.h" -# include -# include -# include -# include "evp_local.h" +#include +#include +#include +#include +#include "crypto/evp.h" +#include "evp_local.h" /* set this to print out info about the keygen algorithm */ /* #define OPENSSL_DEBUG_PKCS5V2 */ -# ifdef OPENSSL_DEBUG_PKCS5V2 +#ifdef OPENSSL_DEBUG_PKCS5V2 static void h__dump(const unsigned char *p, int len); -# endif - -/* - * This is an implementation of PKCS#5 v2.0 password based encryption key - * derivation function PBKDF2. SHA1 version verified against test vectors - * posted by Peter Gutmann to the PKCS-TNG mailing list. - */ +#endif int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, const unsigned char *salt, int saltlen, int iter, const EVP_MD *digest, int keylen, unsigned char *out) { const char *empty = ""; - unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4]; - int cplen, j, k, tkeylen, mdlen; - unsigned long i = 1; - HMAC_CTX *hctx_tpl = NULL, *hctx = NULL; - - mdlen = EVP_MD_size(digest); - if (mdlen < 0) - return 0; + int rv = 1; + EVP_KDF_CTX *kctx; - hctx_tpl = HMAC_CTX_new(); - if (hctx_tpl == NULL) - return 0; - p = out; - tkeylen = keylen; + /* Keep documented behaviour. */ if (pass == NULL) { pass = empty; passlen = 0; } else if (passlen == -1) { passlen = strlen(pass); } - if (!HMAC_Init_ex(hctx_tpl, pass, passlen, digest, NULL)) { - HMAC_CTX_free(hctx_tpl); - return 0; - } - hctx = HMAC_CTX_new(); - if (hctx == NULL) { - HMAC_CTX_free(hctx_tpl); + if (salt == NULL && saltlen == 0) + salt = (unsigned char *)empty; + + kctx = EVP_KDF_CTX_new_id(EVP_KDF_PBKDF2); + if (kctx == NULL) return 0; - } - while (tkeylen) { - if (tkeylen > mdlen) - cplen = mdlen; - else - cplen = tkeylen; - /* - * We are unlikely to ever use more than 256 blocks (5120 bits!) but - * just in case... - */ - itmp[0] = (unsigned char)((i >> 24) & 0xff); - itmp[1] = (unsigned char)((i >> 16) & 0xff); - itmp[2] = (unsigned char)((i >> 8) & 0xff); - itmp[3] = (unsigned char)(i & 0xff); - if (!HMAC_CTX_copy(hctx, hctx_tpl)) { - HMAC_CTX_free(hctx); - HMAC_CTX_free(hctx_tpl); - return 0; - } - if (!HMAC_Update(hctx, salt, saltlen) - || !HMAC_Update(hctx, itmp, 4) - || !HMAC_Final(hctx, digtmp, NULL)) { - HMAC_CTX_free(hctx); - HMAC_CTX_free(hctx_tpl); - return 0; - } - memcpy(p, digtmp, cplen); - for (j = 1; j < iter; j++) { - if (!HMAC_CTX_copy(hctx, hctx_tpl)) { - HMAC_CTX_free(hctx); - HMAC_CTX_free(hctx_tpl); - return 0; - } - if (!HMAC_Update(hctx, digtmp, mdlen) - || !HMAC_Final(hctx, digtmp, NULL)) { - HMAC_CTX_free(hctx); - HMAC_CTX_free(hctx_tpl); - return 0; - } - for (k = 0; k < cplen; k++) - p[k] ^= digtmp[k]; - } - tkeylen -= cplen; - i++; - p += cplen; - } - HMAC_CTX_free(hctx); - HMAC_CTX_free(hctx_tpl); + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, pass, (size_t)passlen) != 1 + || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, + salt, (size_t)saltlen) != 1 + || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_ITER, iter) != 1 + || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, digest) != 1 + || EVP_KDF_derive(kctx, out, keylen) != 1) + rv = 0; + + EVP_KDF_CTX_free(kctx); + # ifdef OPENSSL_DEBUG_PKCS5V2 fprintf(stderr, "Password:\n"); h__dump(pass, passlen); @@ -118,7 +64,7 @@ int PKCS5_PBKDF2_HMAC(const char *pass, fprintf(stderr, "Key:\n"); h__dump(out, keylen); # endif - return 1; + return rv; } int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, Index: openssl-1.1.1n/crypto/evp/pbe_scrypt.c =================================================================== --- openssl-1.1.1n.orig/crypto/evp/pbe_scrypt.c +++ openssl-1.1.1n/crypto/evp/pbe_scrypt.c @@ -7,135 +7,12 @@ * https://www.openssl.org/source/license.html */ -#include -#include -#include #include #include -#include "internal/numbers.h" +#include #ifndef OPENSSL_NO_SCRYPT -#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) -static void salsa208_word_specification(uint32_t inout[16]) -{ - int i; - uint32_t x[16]; - memcpy(x, inout, sizeof(x)); - for (i = 8; i > 0; i -= 2) { - x[4] ^= R(x[0] + x[12], 7); - x[8] ^= R(x[4] + x[0], 9); - x[12] ^= R(x[8] + x[4], 13); - x[0] ^= R(x[12] + x[8], 18); - x[9] ^= R(x[5] + x[1], 7); - x[13] ^= R(x[9] + x[5], 9); - x[1] ^= R(x[13] + x[9], 13); - x[5] ^= R(x[1] + x[13], 18); - x[14] ^= R(x[10] + x[6], 7); - x[2] ^= R(x[14] + x[10], 9); - x[6] ^= R(x[2] + x[14], 13); - x[10] ^= R(x[6] + x[2], 18); - x[3] ^= R(x[15] + x[11], 7); - x[7] ^= R(x[3] + x[15], 9); - x[11] ^= R(x[7] + x[3], 13); - x[15] ^= R(x[11] + x[7], 18); - x[1] ^= R(x[0] + x[3], 7); - x[2] ^= R(x[1] + x[0], 9); - x[3] ^= R(x[2] + x[1], 13); - x[0] ^= R(x[3] + x[2], 18); - x[6] ^= R(x[5] + x[4], 7); - x[7] ^= R(x[6] + x[5], 9); - x[4] ^= R(x[7] + x[6], 13); - x[5] ^= R(x[4] + x[7], 18); - x[11] ^= R(x[10] + x[9], 7); - x[8] ^= R(x[11] + x[10], 9); - x[9] ^= R(x[8] + x[11], 13); - x[10] ^= R(x[9] + x[8], 18); - x[12] ^= R(x[15] + x[14], 7); - x[13] ^= R(x[12] + x[15], 9); - x[14] ^= R(x[13] + x[12], 13); - x[15] ^= R(x[14] + x[13], 18); - } - for (i = 0; i < 16; ++i) - inout[i] += x[i]; - OPENSSL_cleanse(x, sizeof(x)); -} - -static void scryptBlockMix(uint32_t *B_, uint32_t *B, uint64_t r) -{ - uint64_t i, j; - uint32_t X[16], *pB; - - memcpy(X, B + (r * 2 - 1) * 16, sizeof(X)); - pB = B; - for (i = 0; i < r * 2; i++) { - for (j = 0; j < 16; j++) - X[j] ^= *pB++; - salsa208_word_specification(X); - memcpy(B_ + (i / 2 + (i & 1) * r) * 16, X, sizeof(X)); - } - OPENSSL_cleanse(X, sizeof(X)); -} - -static void scryptROMix(unsigned char *B, uint64_t r, uint64_t N, - uint32_t *X, uint32_t *T, uint32_t *V) -{ - unsigned char *pB; - uint32_t *pV; - uint64_t i, k; - - /* Convert from little endian input */ - for (pV = V, i = 0, pB = B; i < 32 * r; i++, pV++) { - *pV = *pB++; - *pV |= *pB++ << 8; - *pV |= *pB++ << 16; - *pV |= (uint32_t)*pB++ << 24; - } - - for (i = 1; i < N; i++, pV += 32 * r) - scryptBlockMix(pV, pV - 32 * r, r); - - scryptBlockMix(X, V + (N - 1) * 32 * r, r); - - for (i = 0; i < N; i++) { - uint32_t j; - j = X[16 * (2 * r - 1)] % N; - pV = V + 32 * r * j; - for (k = 0; k < 32 * r; k++) - T[k] = X[k] ^ *pV++; - scryptBlockMix(X, T, r); - } - /* Convert output to little endian */ - for (i = 0, pB = B; i < 32 * r; i++) { - uint32_t xtmp = X[i]; - *pB++ = xtmp & 0xff; - *pB++ = (xtmp >> 8) & 0xff; - *pB++ = (xtmp >> 16) & 0xff; - *pB++ = (xtmp >> 24) & 0xff; - } -} - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t)-1) -#endif - -/* - * Maximum power of two that will fit in uint64_t: this should work on - * most (all?) platforms. - */ - -#define LOG2_UINT64_MAX (sizeof(uint64_t) * 8 - 1) - -/* - * Maximum value of p * r: - * p <= ((2^32-1) * hLen) / MFLen => - * p <= ((2^32-1) * 32) / (128 * r) => - * p * r <= (2^30-1) - * - */ - -#define SCRYPT_PR_MAX ((1 << 30) - 1) - /* * Maximum permitted memory allow this to be overridden with Configuration * option: e.g. -DSCRYPT_MAX_MEM=0 for maximum possible. @@ -160,107 +37,43 @@ int EVP_PBE_scrypt(const char *pass, siz uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, unsigned char *key, size_t keylen) { - int rv = 0; - unsigned char *B; - uint32_t *X, *V, *T; - uint64_t i, Blen, Vlen; - - /* Sanity check parameters */ - /* initial check, r,p must be non zero, N >= 2 and a power of 2 */ - if (r == 0 || p == 0 || N < 2 || (N & (N - 1))) - return 0; - /* Check p * r < SCRYPT_PR_MAX avoiding overflow */ - if (p > SCRYPT_PR_MAX / r) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); - return 0; - } - - /* - * Need to check N: if 2^(128 * r / 8) overflows limit this is - * automatically satisfied since N <= UINT64_MAX. - */ - - if (16 * r <= LOG2_UINT64_MAX) { - if (N >= (((uint64_t)1) << (16 * r))) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); - return 0; - } - } + const char *empty = ""; + int rv = 1; + EVP_KDF_CTX *kctx; - /* Memory checks: check total allocated buffer size fits in uint64_t */ - - /* - * B size in section 5 step 1.S - * Note: we know p * 128 * r < UINT64_MAX because we already checked - * p * r < SCRYPT_PR_MAX - */ - Blen = p * 128 * r; - /* - * Yet we pass it as integer to PKCS5_PBKDF2_HMAC... [This would - * have to be revised when/if PKCS5_PBKDF2_HMAC accepts size_t.] - */ - if (Blen > INT_MAX) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); + if (r > UINT32_MAX || p > UINT32_MAX) { + EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_PARAMETER_TOO_LARGE); return 0; } - /* - * Check 32 * r * (N + 2) * sizeof(uint32_t) fits in uint64_t - * This is combined size V, X and T (section 4) - */ - i = UINT64_MAX / (32 * sizeof(uint32_t)); - if (N + 2 > i / r) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); - return 0; + /* Maintain existing behaviour. */ + if (pass == NULL) { + pass = empty; + passlen = 0; } - Vlen = 32 * r * (N + 2) * sizeof(uint32_t); - - /* check total allocated size fits in uint64_t */ - if (Blen > UINT64_MAX - Vlen) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); - return 0; + if (salt == NULL) { + salt = (const unsigned char *)empty; + saltlen = 0; } - if (maxmem == 0) maxmem = SCRYPT_MAX_MEM; - /* Check that the maximum memory doesn't exceed a size_t limits */ - if (maxmem > SIZE_MAX) - maxmem = SIZE_MAX; - - if (Blen + Vlen > maxmem) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); + kctx = EVP_KDF_CTX_new_id(EVP_KDF_SCRYPT); + if (kctx == NULL) return 0; - } - /* If no key return to indicate parameters are OK */ - if (key == NULL) - return 1; - - B = OPENSSL_malloc((size_t)(Blen + Vlen)); - if (B == NULL) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, ERR_R_MALLOC_FAILURE); - return 0; - } - X = (uint32_t *)(B + Blen); - T = X + 32 * r; - V = T + 32 * r; - if (PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, 1, EVP_sha256(), - (int)Blen, B) == 0) - goto err; - - for (i = 0; i < p; i++) - scryptROMix(B + 128 * r * i, r, N, X, T, V); - - if (PKCS5_PBKDF2_HMAC(pass, passlen, B, (int)Blen, 1, EVP_sha256(), - keylen, key) == 0) - goto err; - rv = 1; - err: - if (rv == 0) - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_PBKDF2_ERROR); + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, pass, (size_t)passlen) != 1 + || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, + salt, (size_t)saltlen) != 1 + || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_N, N) != 1 + || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_R, (uint32_t)r) != 1 + || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_P, (uint32_t)p) != 1 + || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAXMEM_BYTES, maxmem) != 1 + || EVP_KDF_derive(kctx, key, keylen) != 1) + rv = 0; - OPENSSL_clear_free(B, (size_t)(Blen + Vlen)); + EVP_KDF_CTX_free(kctx); return rv; } + #endif Index: openssl-1.1.1n/crypto/evp/pkey_kdf.c =================================================================== --- /dev/null +++ openssl-1.1.1n/crypto/evp/pkey_kdf.c @@ -0,0 +1,255 @@ +/* + * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "crypto/evp.h" + +static int pkey_kdf_init(EVP_PKEY_CTX *ctx) +{ + EVP_KDF_CTX *kctx; + + kctx = EVP_KDF_CTX_new_id(ctx->pmeth->pkey_id); + if (kctx == NULL) + return 0; + + ctx->data = kctx; + return 1; +} + +static void pkey_kdf_cleanup(EVP_PKEY_CTX *ctx) +{ + EVP_KDF_CTX *kctx = ctx->data; + + EVP_KDF_CTX_free(kctx); +} + +static int pkey_kdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + EVP_KDF_CTX *kctx = ctx->data; + uint64_t u64_value; + int cmd; + int ret; + + switch (type) { + case EVP_PKEY_CTRL_PASS: + cmd = EVP_KDF_CTRL_SET_PASS; + break; + case EVP_PKEY_CTRL_HKDF_SALT: + case EVP_PKEY_CTRL_SCRYPT_SALT: + cmd = EVP_KDF_CTRL_SET_SALT; + break; + case EVP_PKEY_CTRL_TLS_MD: + case EVP_PKEY_CTRL_HKDF_MD: + cmd = EVP_KDF_CTRL_SET_MD; + break; + case EVP_PKEY_CTRL_TLS_SECRET: + cmd = EVP_KDF_CTRL_SET_TLS_SECRET; + ret = EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_RESET_TLS_SEED); + if (ret < 1) + return ret; + break; + case EVP_PKEY_CTRL_TLS_SEED: + cmd = EVP_KDF_CTRL_ADD_TLS_SEED; + break; + case EVP_PKEY_CTRL_HKDF_KEY: + cmd = EVP_KDF_CTRL_SET_KEY; + break; + case EVP_PKEY_CTRL_HKDF_INFO: + cmd = EVP_KDF_CTRL_ADD_HKDF_INFO; + break; + case EVP_PKEY_CTRL_HKDF_MODE: + cmd = EVP_KDF_CTRL_SET_HKDF_MODE; + break; + case EVP_PKEY_CTRL_SCRYPT_N: + cmd = EVP_KDF_CTRL_SET_SCRYPT_N; + break; + case EVP_PKEY_CTRL_SCRYPT_R: + cmd = EVP_KDF_CTRL_SET_SCRYPT_R; + break; + case EVP_PKEY_CTRL_SCRYPT_P: + cmd = EVP_KDF_CTRL_SET_SCRYPT_P; + break; + case EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES: + cmd = EVP_KDF_CTRL_SET_MAXMEM_BYTES; + break; + default: + return -2; + } + + switch (cmd) { + case EVP_KDF_CTRL_SET_PASS: + case EVP_KDF_CTRL_SET_SALT: + case EVP_KDF_CTRL_SET_KEY: + case EVP_KDF_CTRL_SET_TLS_SECRET: + case EVP_KDF_CTRL_ADD_TLS_SEED: + case EVP_KDF_CTRL_ADD_HKDF_INFO: + return EVP_KDF_ctrl(kctx, cmd, (const unsigned char *)p2, (size_t)p1); + + case EVP_KDF_CTRL_SET_MD: + return EVP_KDF_ctrl(kctx, cmd, (const EVP_MD *)p2); + + case EVP_KDF_CTRL_SET_HKDF_MODE: + return EVP_KDF_ctrl(kctx, cmd, (int)p1); + + case EVP_KDF_CTRL_SET_SCRYPT_R: + case EVP_KDF_CTRL_SET_SCRYPT_P: + u64_value = *(uint64_t *)p2; + if (u64_value > UINT32_MAX) { + EVPerr(EVP_F_PKEY_KDF_CTRL, EVP_R_PARAMETER_TOO_LARGE); + return 0; + } + + return EVP_KDF_ctrl(kctx, cmd, (uint32_t)u64_value); + + case EVP_KDF_CTRL_SET_SCRYPT_N: + case EVP_KDF_CTRL_SET_MAXMEM_BYTES: + return EVP_KDF_ctrl(kctx, cmd, *(uint64_t *)p2); + + default: + return 0; + } +} + +static int pkey_kdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, + const char *value) +{ + EVP_KDF_CTX *kctx = ctx->data; + + if (strcmp(type, "md") == 0) + return EVP_KDF_ctrl_str(kctx, "digest", value); + return EVP_KDF_ctrl_str(kctx, type, value); +} + +static int pkey_kdf_derive_init(EVP_PKEY_CTX *ctx) +{ + EVP_KDF_CTX *kctx = ctx->data; + + EVP_KDF_reset(kctx); + return 1; +} + +/* + * For fixed-output algorithms the keylen parameter is an "out" parameter + * otherwise it is an "in" parameter. + */ +static int pkey_kdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, + size_t *keylen) +{ + EVP_KDF_CTX *kctx = ctx->data; + size_t outlen = EVP_KDF_size(kctx); + + if (outlen == 0 || outlen == SIZE_MAX) { + /* Variable-output algorithm */ + if (key == NULL) + return 0; + } else { + /* Fixed-output algorithm */ + *keylen = outlen; + if (key == NULL) + return 1; + } + return EVP_KDF_derive(kctx, key, *keylen); +} + +#ifndef OPENSSL_NO_SCRYPT +const EVP_PKEY_METHOD scrypt_pkey_meth = { + EVP_PKEY_SCRYPT, + 0, + pkey_kdf_init, + 0, + pkey_kdf_cleanup, + + 0, 0, + 0, 0, + + 0, + 0, + + 0, + 0, + + 0, 0, + + 0, 0, 0, 0, + + 0, 0, + + 0, 0, + + pkey_kdf_derive_init, + pkey_kdf_derive, + pkey_kdf_ctrl, + pkey_kdf_ctrl_str +}; +#endif + +const EVP_PKEY_METHOD tls1_prf_pkey_meth = { + EVP_PKEY_TLS1_PRF, + EVP_PKEY_FLAG_FIPS, + pkey_kdf_init, + 0, + pkey_kdf_cleanup, + + 0, 0, + 0, 0, + + 0, + 0, + + 0, + 0, + + 0, 0, + + 0, 0, 0, 0, + + 0, 0, + + 0, 0, + + pkey_kdf_derive_init, + pkey_kdf_derive, + pkey_kdf_ctrl, + pkey_kdf_ctrl_str +}; + +const EVP_PKEY_METHOD hkdf_pkey_meth = { + EVP_PKEY_HKDF, + EVP_PKEY_FLAG_FIPS, + pkey_kdf_init, + 0, + pkey_kdf_cleanup, + + 0, 0, + 0, 0, + + 0, + 0, + + 0, + 0, + + 0, 0, + + 0, 0, 0, 0, + + 0, 0, + + 0, 0, + + pkey_kdf_derive_init, + pkey_kdf_derive, + pkey_kdf_ctrl, + pkey_kdf_ctrl_str +}; + Index: openssl-1.1.1n/include/crypto/evp.h =================================================================== --- openssl-1.1.1n.orig/include/crypto/evp.h +++ openssl-1.1.1n/include/crypto/evp.h @@ -112,6 +112,24 @@ extern const EVP_PKEY_METHOD hkdf_pkey_m extern const EVP_PKEY_METHOD poly1305_pkey_meth; extern const EVP_PKEY_METHOD siphash_pkey_meth; +/* struct evp_kdf_impl_st is defined by the implementation */ +typedef struct evp_kdf_impl_st EVP_KDF_IMPL; +typedef struct { + int type; + EVP_KDF_IMPL *(*new) (void); + void (*free) (EVP_KDF_IMPL *impl); + void (*reset) (EVP_KDF_IMPL *impl); + int (*ctrl) (EVP_KDF_IMPL *impl, int cmd, va_list args); + int (*ctrl_str) (EVP_KDF_IMPL *impl, const char *type, const char *value); + size_t (*size) (EVP_KDF_IMPL *impl); + int (*derive) (EVP_KDF_IMPL *impl, unsigned char *key, size_t keylen); +} EVP_KDF_METHOD; + +extern const EVP_KDF_METHOD pbkdf2_kdf_meth; +extern const EVP_KDF_METHOD scrypt_kdf_meth; +extern const EVP_KDF_METHOD tls1_prf_kdf_meth; +extern const EVP_KDF_METHOD hkdf_kdf_meth; + struct evp_md_st { int type; int pkey_type; Index: openssl-1.1.1n/crypto/kdf/build.info =================================================================== --- openssl-1.1.1n.orig/crypto/kdf/build.info +++ openssl-1.1.1n/crypto/kdf/build.info @@ -1,3 +1,3 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ - tls1_prf.c kdf_err.c hkdf.c scrypt.c + tls1_prf.c kdf_err.c kdf_util.c hkdf.c scrypt.c pbkdf2.c Index: openssl-1.1.1n/crypto/kdf/hkdf.c =================================================================== --- openssl-1.1.1n.orig/crypto/kdf/hkdf.c +++ openssl-1.1.1n/crypto/kdf/hkdf.c @@ -8,32 +8,33 @@ */ #include +#include #include #include -#include #include +#include #include "internal/cryptlib.h" #include "crypto/evp.h" +#include "kdf_local.h" #define HKDF_MAXBUF 1024 -static unsigned char *HKDF(const EVP_MD *evp_md, - const unsigned char *salt, size_t salt_len, - const unsigned char *key, size_t key_len, - const unsigned char *info, size_t info_len, - unsigned char *okm, size_t okm_len); - -static unsigned char *HKDF_Extract(const EVP_MD *evp_md, - const unsigned char *salt, size_t salt_len, - const unsigned char *key, size_t key_len, - unsigned char *prk, size_t *prk_len); - -static unsigned char *HKDF_Expand(const EVP_MD *evp_md, - const unsigned char *prk, size_t prk_len, - const unsigned char *info, size_t info_len, - unsigned char *okm, size_t okm_len); +static void kdf_hkdf_reset(EVP_KDF_IMPL *impl); +static int HKDF(const EVP_MD *evp_md, + const unsigned char *salt, size_t salt_len, + const unsigned char *key, size_t key_len, + const unsigned char *info, size_t info_len, + unsigned char *okm, size_t okm_len); +static int HKDF_Extract(const EVP_MD *evp_md, + const unsigned char *salt, size_t salt_len, + const unsigned char *key, size_t key_len, + unsigned char *prk, size_t prk_len); +static int HKDF_Expand(const EVP_MD *evp_md, + const unsigned char *prk, size_t prk_len, + const unsigned char *info, size_t info_len, + unsigned char *okm, size_t okm_len); -typedef struct { +struct evp_kdf_impl_st { int mode; const EVP_MD *md; unsigned char *salt; @@ -42,230 +43,208 @@ typedef struct { size_t key_len; unsigned char info[HKDF_MAXBUF]; size_t info_len; -} HKDF_PKEY_CTX; +}; -static int pkey_hkdf_init(EVP_PKEY_CTX *ctx) +static EVP_KDF_IMPL *kdf_hkdf_new(void) { - HKDF_PKEY_CTX *kctx; - - if ((kctx = OPENSSL_zalloc(sizeof(*kctx))) == NULL) { - KDFerr(KDF_F_PKEY_HKDF_INIT, ERR_R_MALLOC_FAILURE); - return 0; - } + EVP_KDF_IMPL *impl; - ctx->data = kctx; + if ((impl = OPENSSL_zalloc(sizeof(*impl))) == NULL) + KDFerr(KDF_F_KDF_HKDF_NEW, ERR_R_MALLOC_FAILURE); + return impl; +} - return 1; +static void kdf_hkdf_free(EVP_KDF_IMPL *impl) +{ + kdf_hkdf_reset(impl); + OPENSSL_free(impl); } -static void pkey_hkdf_cleanup(EVP_PKEY_CTX *ctx) +static void kdf_hkdf_reset(EVP_KDF_IMPL *impl) { - HKDF_PKEY_CTX *kctx = ctx->data; - OPENSSL_clear_free(kctx->salt, kctx->salt_len); - OPENSSL_clear_free(kctx->key, kctx->key_len); - OPENSSL_cleanse(kctx->info, kctx->info_len); - OPENSSL_free(kctx); + OPENSSL_free(impl->salt); + OPENSSL_clear_free(impl->key, impl->key_len); + OPENSSL_cleanse(impl->info, impl->info_len); + memset(impl, 0, sizeof(*impl)); } -static int pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +static int kdf_hkdf_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args) { - HKDF_PKEY_CTX *kctx = ctx->data; + const unsigned char *p; + size_t len; + const EVP_MD *md; - switch (type) { - case EVP_PKEY_CTRL_HKDF_MD: - if (p2 == NULL) + switch (cmd) { + case EVP_KDF_CTRL_SET_MD: + md = va_arg(args, const EVP_MD *); + if (md == NULL) return 0; - kctx->md = p2; + impl->md = md; return 1; - case EVP_PKEY_CTRL_HKDF_MODE: - kctx->mode = p1; + case EVP_KDF_CTRL_SET_HKDF_MODE: + impl->mode = va_arg(args, int); return 1; - case EVP_PKEY_CTRL_HKDF_SALT: - if (p1 == 0 || p2 == NULL) + case EVP_KDF_CTRL_SET_SALT: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + if (len == 0 || p == NULL) return 1; - if (p1 < 0) - return 0; - - if (kctx->salt != NULL) - OPENSSL_clear_free(kctx->salt, kctx->salt_len); - - kctx->salt = OPENSSL_memdup(p2, p1); - if (kctx->salt == NULL) + OPENSSL_free(impl->salt); + impl->salt = OPENSSL_memdup(p, len); + if (impl->salt == NULL) return 0; - kctx->salt_len = p1; + impl->salt_len = len; return 1; - case EVP_PKEY_CTRL_HKDF_KEY: - if (p1 < 0) + case EVP_KDF_CTRL_SET_KEY: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + OPENSSL_clear_free(impl->key, impl->key_len); + impl->key = OPENSSL_memdup(p, len); + if (impl->key == NULL) return 0; - if (kctx->key != NULL) - OPENSSL_clear_free(kctx->key, kctx->key_len); - - kctx->key = OPENSSL_memdup(p2, p1); - if (kctx->key == NULL) - return 0; + impl->key_len = len; + return 1; - kctx->key_len = p1; + case EVP_KDF_CTRL_RESET_HKDF_INFO: + OPENSSL_cleanse(impl->info, impl->info_len); + impl->info_len = 0; return 1; - case EVP_PKEY_CTRL_HKDF_INFO: - if (p1 == 0 || p2 == NULL) + case EVP_KDF_CTRL_ADD_HKDF_INFO: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + if (len == 0 || p == NULL) return 1; - if (p1 < 0 || p1 > (int)(HKDF_MAXBUF - kctx->info_len)) + if (len > (HKDF_MAXBUF - impl->info_len)) return 0; - memcpy(kctx->info + kctx->info_len, p2, p1); - kctx->info_len += p1; + memcpy(impl->info + impl->info_len, p, len); + impl->info_len += len; return 1; default: return -2; - } } -static int pkey_hkdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, - const char *value) +static int kdf_hkdf_ctrl_str(EVP_KDF_IMPL *impl, const char *type, + const char *value) { if (strcmp(type, "mode") == 0) { int mode; if (strcmp(value, "EXTRACT_AND_EXPAND") == 0) - mode = EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND; + mode = EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND; else if (strcmp(value, "EXTRACT_ONLY") == 0) - mode = EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY; + mode = EVP_KDF_HKDF_MODE_EXTRACT_ONLY; else if (strcmp(value, "EXPAND_ONLY") == 0) - mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY; + mode = EVP_KDF_HKDF_MODE_EXPAND_ONLY; else return 0; - return EVP_PKEY_CTX_hkdf_mode(ctx, mode); + return call_ctrl(kdf_hkdf_ctrl, impl, EVP_KDF_CTRL_SET_HKDF_MODE, mode); } - if (strcmp(type, "md") == 0) - return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_DERIVE, - EVP_PKEY_CTRL_HKDF_MD, value); + if (strcmp(type, "digest") == 0) + return kdf_md2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_SET_MD, value); if (strcmp(type, "salt") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value); + return kdf_str2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_SET_SALT, value); if (strcmp(type, "hexsalt") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value); + return kdf_hex2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_SET_SALT, value); if (strcmp(type, "key") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value); + return kdf_str2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_SET_KEY, value); if (strcmp(type, "hexkey") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value); + return kdf_hex2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_SET_KEY, value); if (strcmp(type, "info") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value); + return kdf_str2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_ADD_HKDF_INFO, + value); if (strcmp(type, "hexinfo") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value); + return kdf_hex2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_ADD_HKDF_INFO, + value); - KDFerr(KDF_F_PKEY_HKDF_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE); return -2; } -static int pkey_hkdf_derive_init(EVP_PKEY_CTX *ctx) +static size_t kdf_hkdf_size(EVP_KDF_IMPL *impl) { - HKDF_PKEY_CTX *kctx = ctx->data; - - OPENSSL_clear_free(kctx->key, kctx->key_len); - OPENSSL_clear_free(kctx->salt, kctx->salt_len); - OPENSSL_cleanse(kctx->info, kctx->info_len); - memset(kctx, 0, sizeof(*kctx)); + if (impl->mode != EVP_KDF_HKDF_MODE_EXTRACT_ONLY) + return SIZE_MAX; - return 1; + if (impl->md == NULL) { + KDFerr(KDF_F_KDF_HKDF_SIZE, KDF_R_MISSING_MESSAGE_DIGEST); + return 0; + } + return EVP_MD_size(impl->md); } -static int pkey_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, - size_t *keylen) +static int kdf_hkdf_derive(EVP_KDF_IMPL *impl, unsigned char *key, + size_t keylen) { - HKDF_PKEY_CTX *kctx = ctx->data; - - if (kctx->md == NULL) { - KDFerr(KDF_F_PKEY_HKDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST); + if (impl->md == NULL) { + KDFerr(KDF_F_KDF_HKDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST); return 0; } - if (kctx->key == NULL) { - KDFerr(KDF_F_PKEY_HKDF_DERIVE, KDF_R_MISSING_KEY); + if (impl->key == NULL) { + KDFerr(KDF_F_KDF_HKDF_DERIVE, KDF_R_MISSING_KEY); return 0; } - switch (kctx->mode) { - case EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND: - return HKDF(kctx->md, kctx->salt, kctx->salt_len, kctx->key, - kctx->key_len, kctx->info, kctx->info_len, key, - *keylen) != NULL; - - case EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY: - if (key == NULL) { - *keylen = EVP_MD_size(kctx->md); - return 1; - } - return HKDF_Extract(kctx->md, kctx->salt, kctx->salt_len, kctx->key, - kctx->key_len, key, keylen) != NULL; - - case EVP_PKEY_HKDEF_MODE_EXPAND_ONLY: - return HKDF_Expand(kctx->md, kctx->key, kctx->key_len, kctx->info, - kctx->info_len, key, *keylen) != NULL; + switch (impl->mode) { + case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND: + return HKDF(impl->md, impl->salt, impl->salt_len, impl->key, + impl->key_len, impl->info, impl->info_len, key, + keylen); + + case EVP_KDF_HKDF_MODE_EXTRACT_ONLY: + return HKDF_Extract(impl->md, impl->salt, impl->salt_len, impl->key, + impl->key_len, key, keylen); + + case EVP_KDF_HKDF_MODE_EXPAND_ONLY: + return HKDF_Expand(impl->md, impl->key, impl->key_len, impl->info, + impl->info_len, key, keylen); default: return 0; } } -const EVP_PKEY_METHOD hkdf_pkey_meth = { - EVP_PKEY_HKDF, - 0, - pkey_hkdf_init, - 0, - pkey_hkdf_cleanup, - - 0, 0, - 0, 0, - - 0, - 0, - - 0, - 0, - - 0, 0, - - 0, 0, 0, 0, - - 0, 0, - - 0, 0, - - pkey_hkdf_derive_init, - pkey_hkdf_derive, - pkey_hkdf_ctrl, - pkey_hkdf_ctrl_str +const EVP_KDF_METHOD hkdf_kdf_meth = { + EVP_KDF_HKDF, + kdf_hkdf_new, + kdf_hkdf_free, + kdf_hkdf_reset, + kdf_hkdf_ctrl, + kdf_hkdf_ctrl_str, + kdf_hkdf_size, + kdf_hkdf_derive }; -static unsigned char *HKDF(const EVP_MD *evp_md, - const unsigned char *salt, size_t salt_len, - const unsigned char *key, size_t key_len, - const unsigned char *info, size_t info_len, - unsigned char *okm, size_t okm_len) +static int HKDF(const EVP_MD *evp_md, + const unsigned char *salt, size_t salt_len, + const unsigned char *key, size_t key_len, + const unsigned char *info, size_t info_len, + unsigned char *okm, size_t okm_len) { unsigned char prk[EVP_MAX_MD_SIZE]; - unsigned char *ret; - size_t prk_len; + int ret; + size_t prk_len = EVP_MD_size(evp_md); - if (!HKDF_Extract(evp_md, salt, salt_len, key, key_len, prk, &prk_len)) - return NULL; + if (!HKDF_Extract(evp_md, salt, salt_len, key, key_len, prk, prk_len)) + return 0; ret = HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len); OPENSSL_cleanse(prk, sizeof(prk)); @@ -273,43 +252,38 @@ static unsigned char *HKDF(const EVP_MD return ret; } -static unsigned char *HKDF_Extract(const EVP_MD *evp_md, - const unsigned char *salt, size_t salt_len, - const unsigned char *key, size_t key_len, - unsigned char *prk, size_t *prk_len) +static int HKDF_Extract(const EVP_MD *evp_md, + const unsigned char *salt, size_t salt_len, + const unsigned char *key, size_t key_len, + unsigned char *prk, size_t prk_len) { - unsigned int tmp_len; - - if (!HMAC(evp_md, salt, salt_len, key, key_len, prk, &tmp_len)) - return NULL; - - *prk_len = tmp_len; - return prk; + if (prk_len != (size_t)EVP_MD_size(evp_md)) { + KDFerr(KDF_F_HKDF_EXTRACT, KDF_R_WRONG_OUTPUT_BUFFER_SIZE); + return 0; + } + return HMAC(evp_md, salt, salt_len, key, key_len, prk, NULL) != NULL; } -static unsigned char *HKDF_Expand(const EVP_MD *evp_md, - const unsigned char *prk, size_t prk_len, - const unsigned char *info, size_t info_len, - unsigned char *okm, size_t okm_len) +static int HKDF_Expand(const EVP_MD *evp_md, + const unsigned char *prk, size_t prk_len, + const unsigned char *info, size_t info_len, + unsigned char *okm, size_t okm_len) { HMAC_CTX *hmac; - unsigned char *ret = NULL; - + int ret = 0; unsigned int i; - unsigned char prev[EVP_MAX_MD_SIZE]; - size_t done_len = 0, dig_len = EVP_MD_size(evp_md); - size_t n = okm_len / dig_len; + if (okm_len % dig_len) n++; if (n > 255 || okm == NULL) - return NULL; + return 0; if ((hmac = HMAC_CTX_new()) == NULL) - return NULL; + return 0; if (!HMAC_Init_ex(hmac, prk, prk_len, evp_md, NULL)) goto err; @@ -343,7 +317,7 @@ static unsigned char *HKDF_Expand(const done_len += copy_len; } - ret = okm; + ret = 1; err: OPENSSL_cleanse(prev, sizeof(prev)); Index: openssl-1.1.1n/crypto/kdf/kdf_err.c =================================================================== --- openssl-1.1.1n.orig/crypto/kdf/kdf_err.c +++ openssl-1.1.1n/crypto/kdf/kdf_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -14,6 +14,29 @@ #ifndef OPENSSL_NO_ERR static const ERR_STRING_DATA KDF_str_functs[] = { + {ERR_PACK(ERR_LIB_KDF, KDF_F_HKDF_EXTRACT, 0), "HKDF_Extract"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_HKDF_DERIVE, 0), "kdf_hkdf_derive"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_HKDF_NEW, 0), "kdf_hkdf_new"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_HKDF_SIZE, 0), "kdf_hkdf_size"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_MD2CTRL, 0), "kdf_md2ctrl"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_PBKDF2_CTRL_STR, 0), + "kdf_pbkdf2_ctrl_str"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_PBKDF2_DERIVE, 0), "kdf_pbkdf2_derive"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_PBKDF2_NEW, 0), "kdf_pbkdf2_new"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SCRYPT_CTRL_STR, 0), + "kdf_scrypt_ctrl_str"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SCRYPT_CTRL_UINT32, 0), + "kdf_scrypt_ctrl_uint32"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SCRYPT_CTRL_UINT64, 0), + "kdf_scrypt_ctrl_uint64"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SCRYPT_DERIVE, 0), "kdf_scrypt_derive"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SCRYPT_NEW, 0), "kdf_scrypt_new"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_TLS1_PRF_CTRL_STR, 0), + "kdf_tls1_prf_ctrl_str"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_TLS1_PRF_DERIVE, 0), + "kdf_tls1_prf_derive"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_TLS1_PRF_NEW, 0), "kdf_tls1_prf_new"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_PBKDF2_SET_MEMBUF, 0), "pbkdf2_set_membuf"}, {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_CTRL_STR, 0), "pkey_hkdf_ctrl_str"}, {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_DERIVE, 0), "pkey_hkdf_derive"}, {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_INIT, 0), "pkey_hkdf_init"}, @@ -30,6 +53,7 @@ static const ERR_STRING_DATA KDF_str_fun {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_TLS1_PRF_DERIVE, 0), "pkey_tls1_prf_derive"}, {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_TLS1_PRF_INIT, 0), "pkey_tls1_prf_init"}, + {ERR_PACK(ERR_LIB_KDF, KDF_F_SCRYPT_SET_MEMBUF, 0), "scrypt_set_membuf"}, {ERR_PACK(ERR_LIB_KDF, KDF_F_TLS1_PRF_ALG, 0), "tls1_prf_alg"}, {0, NULL} }; @@ -50,6 +74,8 @@ static const ERR_STRING_DATA KDF_str_rea "unknown parameter type"}, {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_VALUE_ERROR), "value error"}, {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_VALUE_MISSING), "value missing"}, + {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_WRONG_OUTPUT_BUFFER_SIZE), + "wrong output buffer size"}, {0, NULL} }; Index: openssl-1.1.1n/crypto/kdf/kdf_local.h =================================================================== --- /dev/null +++ openssl-1.1.1n/crypto/kdf/kdf_local.h @@ -0,0 +1,22 @@ +/* + * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +int call_ctrl(int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), + EVP_KDF_IMPL *impl, int cmd, ...); +int kdf_str2ctrl(EVP_KDF_IMPL *impl, + int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), + int cmd, const char *str); +int kdf_hex2ctrl(EVP_KDF_IMPL *impl, + int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), + int cmd, const char *hex); +int kdf_md2ctrl(EVP_KDF_IMPL *impl, + int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), + int cmd, const char *md_name); + Index: openssl-1.1.1n/crypto/kdf/kdf_util.c =================================================================== --- /dev/null +++ openssl-1.1.1n/crypto/kdf/kdf_util.c @@ -0,0 +1,73 @@ +/* + * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/cryptlib.h" +#include "crypto/evp.h" +#include "internal/numbers.h" +#include "kdf_local.h" + +int call_ctrl(int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), + EVP_KDF_IMPL *impl, int cmd, ...) +{ + int ret; + va_list args; + + va_start(args, cmd); + ret = ctrl(impl, cmd, args); + va_end(args); + + return ret; +} + +/* Utility functions to send a string or hex string to a ctrl */ + +int kdf_str2ctrl(EVP_KDF_IMPL *impl, + int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), + int cmd, const char *str) +{ + return call_ctrl(ctrl, impl, cmd, (const unsigned char *)str, strlen(str)); +} + +int kdf_hex2ctrl(EVP_KDF_IMPL *impl, + int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), + int cmd, const char *hex) +{ + unsigned char *bin; + long binlen; + int ret = -1; + + bin = OPENSSL_hexstr2buf(hex, &binlen); + if (bin == NULL) + return 0; + + if (binlen <= INT_MAX) + ret = call_ctrl(ctrl, impl, cmd, bin, (size_t)binlen); + OPENSSL_free(bin); + return ret; +} + +/* Pass a message digest to a ctrl */ +int kdf_md2ctrl(EVP_KDF_IMPL *impl, + int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), + int cmd, const char *md_name) +{ + const EVP_MD *md; + + if (md_name == NULL || (md = EVP_get_digestbyname(md_name)) == NULL) { + KDFerr(KDF_F_KDF_MD2CTRL, KDF_R_INVALID_DIGEST); + return 0; + } + return call_ctrl(ctrl, impl, cmd, md); +} + Index: openssl-1.1.1n/crypto/kdf/pbkdf2.c =================================================================== --- /dev/null +++ openssl-1.1.1n/crypto/kdf/pbkdf2.c @@ -0,0 +1,264 @@ +/* + * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include "internal/cryptlib.h" +#include "crypto/evp.h" +#include "kdf_local.h" + +static void kdf_pbkdf2_reset(EVP_KDF_IMPL *impl); +static void kdf_pbkdf2_init(EVP_KDF_IMPL *impl); +static int pkcs5_pbkdf2_alg(const char *pass, size_t passlen, + const unsigned char *salt, int saltlen, int iter, + const EVP_MD *digest, unsigned char *key, + size_t keylen); + +struct evp_kdf_impl_st { + unsigned char *pass; + size_t pass_len; + unsigned char *salt; + size_t salt_len; + int iter; + const EVP_MD *md; +}; + +static EVP_KDF_IMPL *kdf_pbkdf2_new(void) +{ + EVP_KDF_IMPL *impl; + + impl = OPENSSL_zalloc(sizeof(*impl)); + if (impl == NULL) { + KDFerr(KDF_F_KDF_PBKDF2_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + kdf_pbkdf2_init(impl); + return impl; +} + +static void kdf_pbkdf2_free(EVP_KDF_IMPL *impl) +{ + kdf_pbkdf2_reset(impl); + OPENSSL_free(impl); +} + +static void kdf_pbkdf2_reset(EVP_KDF_IMPL *impl) +{ + OPENSSL_free(impl->salt); + OPENSSL_clear_free(impl->pass, impl->pass_len); + memset(impl, 0, sizeof(*impl)); + kdf_pbkdf2_init(impl); +} + +static void kdf_pbkdf2_init(EVP_KDF_IMPL *impl) +{ + impl->iter = PKCS5_DEFAULT_ITER; + impl->md = EVP_sha1(); +} + +static int pbkdf2_set_membuf(unsigned char **buffer, size_t *buflen, + const unsigned char *new_buffer, + size_t new_buflen) +{ + if (new_buffer == NULL) + return 1; + + OPENSSL_clear_free(*buffer, *buflen); + + if (new_buflen > 0) { + *buffer = OPENSSL_memdup(new_buffer, new_buflen); + } else { + *buffer = OPENSSL_malloc(1); + } + if (*buffer == NULL) { + KDFerr(KDF_F_PBKDF2_SET_MEMBUF, ERR_R_MALLOC_FAILURE); + return 0; + } + + *buflen = new_buflen; + return 1; +} + +static int kdf_pbkdf2_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args) +{ + int iter; + const unsigned char *p; + size_t len; + const EVP_MD *md; + + switch (cmd) { + case EVP_KDF_CTRL_SET_PASS: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + return pbkdf2_set_membuf(&impl->pass, &impl->pass_len, p, len); + + case EVP_KDF_CTRL_SET_SALT: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + return pbkdf2_set_membuf(&impl->salt, &impl->salt_len, p, len); + + case EVP_KDF_CTRL_SET_ITER: + iter = va_arg(args, int); + if (iter < 1) + return 0; + + impl->iter = iter; + return 1; + + case EVP_KDF_CTRL_SET_MD: + md = va_arg(args, const EVP_MD *); + if (md == NULL) + return 0; + + impl->md = md; + return 1; + + default: + return -2; + } +} + +static int kdf_pbkdf2_ctrl_str(EVP_KDF_IMPL *impl, const char *type, + const char *value) +{ + if (value == NULL) { + KDFerr(KDF_F_KDF_PBKDF2_CTRL_STR, KDF_R_VALUE_MISSING); + return 0; + } + + if (strcmp(type, "pass") == 0) + return kdf_str2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_PASS, + value); + + if (strcmp(type, "hexpass") == 0) + return kdf_hex2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_PASS, + value); + + if (strcmp(type, "salt") == 0) + return kdf_str2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_SALT, + value); + + if (strcmp(type, "hexsalt") == 0) + return kdf_hex2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_SALT, + value); + + if (strcmp(type, "iter") == 0) + return call_ctrl(kdf_pbkdf2_ctrl, impl, EVP_KDF_CTRL_SET_ITER, + atoi(value)); + + if (strcmp(type, "digest") == 0) + return kdf_md2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_MD, value); + + return -2; +} + +static int kdf_pbkdf2_derive(EVP_KDF_IMPL *impl, unsigned char *key, + size_t keylen) +{ + if (impl->pass == NULL) { + KDFerr(KDF_F_KDF_PBKDF2_DERIVE, KDF_R_MISSING_PASS); + return 0; + } + + if (impl->salt == NULL) { + KDFerr(KDF_F_KDF_PBKDF2_DERIVE, KDF_R_MISSING_SALT); + return 0; + } + + return pkcs5_pbkdf2_alg((char *)impl->pass, impl->pass_len, + impl->salt, impl->salt_len, impl->iter, + impl->md, key, keylen); +} + +const EVP_KDF_METHOD pbkdf2_kdf_meth = { + EVP_KDF_PBKDF2, + kdf_pbkdf2_new, + kdf_pbkdf2_free, + kdf_pbkdf2_reset, + kdf_pbkdf2_ctrl, + kdf_pbkdf2_ctrl_str, + NULL, + kdf_pbkdf2_derive +}; + +/* + * This is an implementation of PKCS#5 v2.0 password based encryption key + * derivation function PBKDF2. SHA1 version verified against test vectors + * posted by Peter Gutmann to the PKCS-TNG mailing list. + */ + +static int pkcs5_pbkdf2_alg(const char *pass, size_t passlen, + const unsigned char *salt, int saltlen, int iter, + const EVP_MD *digest, unsigned char *key, + size_t keylen) +{ + int ret = 0; + unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4]; + int cplen, j, k, tkeylen, mdlen; + unsigned long i = 1; + HMAC_CTX *hctx_tpl = NULL, *hctx = NULL; + + mdlen = EVP_MD_size(digest); + if (mdlen < 0) + return 0; + + hctx_tpl = HMAC_CTX_new(); + if (hctx_tpl == NULL) + return 0; + p = key; + tkeylen = keylen; + if (!HMAC_Init_ex(hctx_tpl, pass, passlen, digest, NULL)) + goto err; + hctx = HMAC_CTX_new(); + if (hctx == NULL) + goto err; + while (tkeylen) { + if (tkeylen > mdlen) + cplen = mdlen; + else + cplen = tkeylen; + /* + * We are unlikely to ever use more than 256 blocks (5120 bits!) but + * just in case... + */ + itmp[0] = (unsigned char)((i >> 24) & 0xff); + itmp[1] = (unsigned char)((i >> 16) & 0xff); + itmp[2] = (unsigned char)((i >> 8) & 0xff); + itmp[3] = (unsigned char)(i & 0xff); + if (!HMAC_CTX_copy(hctx, hctx_tpl)) + goto err; + if (!HMAC_Update(hctx, salt, saltlen) + || !HMAC_Update(hctx, itmp, 4) + || !HMAC_Final(hctx, digtmp, NULL)) + goto err; + memcpy(p, digtmp, cplen); + for (j = 1; j < iter; j++) { + if (!HMAC_CTX_copy(hctx, hctx_tpl)) + goto err; + if (!HMAC_Update(hctx, digtmp, mdlen) + || !HMAC_Final(hctx, digtmp, NULL)) + goto err; + for (k = 0; k < cplen; k++) + p[k] ^= digtmp[k]; + } + tkeylen -= cplen; + i++; + p += cplen; + } + ret = 1; + +err: + HMAC_CTX_free(hctx); + HMAC_CTX_free(hctx_tpl); + return ret; +} Index: openssl-1.1.1n/crypto/kdf/scrypt.c =================================================================== --- openssl-1.1.1n.orig/crypto/kdf/scrypt.c +++ openssl-1.1.1n/crypto/kdf/scrypt.c @@ -8,25 +8,34 @@ */ #include +#include #include -#include -#include #include -#include "internal/cryptlib.h" +#include +#include #include "crypto/evp.h" +#include "internal/numbers.h" +#include "kdf_local.h" #ifndef OPENSSL_NO_SCRYPT +static void kdf_scrypt_reset(EVP_KDF_IMPL *impl); +static void kdf_scrypt_init(EVP_KDF_IMPL *impl); static int atou64(const char *nptr, uint64_t *result); +static int scrypt_alg(const char *pass, size_t passlen, + const unsigned char *salt, size_t saltlen, + uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, + unsigned char *key, size_t keylen); -typedef struct { +struct evp_kdf_impl_st { unsigned char *pass; size_t pass_len; unsigned char *salt; size_t salt_len; - uint64_t N, r, p; + uint64_t N; + uint32_t r, p; uint64_t maxmem_bytes; -} SCRYPT_PKEY_CTX; +}; /* Custom uint64_t parser since we do not have strtoull */ static int atou64(const char *nptr, uint64_t *result) @@ -53,51 +62,53 @@ static int atou64(const char *nptr, uint return 1; } -static int pkey_scrypt_init(EVP_PKEY_CTX *ctx) +static EVP_KDF_IMPL *kdf_scrypt_new(void) { - SCRYPT_PKEY_CTX *kctx; + EVP_KDF_IMPL *impl; - kctx = OPENSSL_zalloc(sizeof(*kctx)); - if (kctx == NULL) { - KDFerr(KDF_F_PKEY_SCRYPT_INIT, ERR_R_MALLOC_FAILURE); - return 0; + impl = OPENSSL_zalloc(sizeof(*impl)); + if (impl == NULL) { + KDFerr(KDF_F_KDF_SCRYPT_NEW, ERR_R_MALLOC_FAILURE); + return NULL; } + kdf_scrypt_init(impl); + return impl; +} - /* Default values are the most conservative recommendation given in the - * original paper of C. Percival. Derivation uses roughly 1 GiB of memory - * for this parameter choice (approx. 128 * r * (N + p) bytes). - */ - kctx->N = 1 << 20; - kctx->r = 8; - kctx->p = 1; - kctx->maxmem_bytes = 1025 * 1024 * 1024; - - ctx->data = kctx; - - return 1; +static void kdf_scrypt_free(EVP_KDF_IMPL *impl) +{ + kdf_scrypt_reset(impl); + OPENSSL_free(impl); } -static void pkey_scrypt_cleanup(EVP_PKEY_CTX *ctx) +static void kdf_scrypt_reset(EVP_KDF_IMPL *impl) { - SCRYPT_PKEY_CTX *kctx = ctx->data; + OPENSSL_free(impl->salt); + OPENSSL_clear_free(impl->pass, impl->pass_len); + memset(impl, 0, sizeof(*impl)); + kdf_scrypt_init(impl); +} - OPENSSL_clear_free(kctx->salt, kctx->salt_len); - OPENSSL_clear_free(kctx->pass, kctx->pass_len); - OPENSSL_free(kctx); +static void kdf_scrypt_init(EVP_KDF_IMPL *impl) +{ + /* Default values are the most conservative recommendation given in the + * original paper of C. Percival. Derivation uses roughly 1 GiB of memory + * for this parameter choice (approx. 128 * r * N * p bytes). + */ + impl->N = 1 << 20; + impl->r = 8; + impl->p = 1; + impl->maxmem_bytes = 1025 * 1024 * 1024; } -static int pkey_scrypt_set_membuf(unsigned char **buffer, size_t *buflen, - const unsigned char *new_buffer, - const int new_buflen) +static int scrypt_set_membuf(unsigned char **buffer, size_t *buflen, + const unsigned char *new_buffer, + size_t new_buflen) { if (new_buffer == NULL) return 1; - if (new_buflen < 0) - return 0; - - if (*buffer != NULL) - OPENSSL_clear_free(*buffer, *buflen); + OPENSSL_clear_free(*buffer, *buflen); if (new_buflen > 0) { *buffer = OPENSSL_memdup(new_buffer, new_buflen); @@ -105,7 +116,7 @@ static int pkey_scrypt_set_membuf(unsign *buffer = OPENSSL_malloc(1); } if (*buffer == NULL) { - KDFerr(KDF_F_PKEY_SCRYPT_SET_MEMBUF, ERR_R_MALLOC_FAILURE); + KDFerr(KDF_F_SCRYPT_SET_MEMBUF, ERR_R_MALLOC_FAILURE); return 0; } @@ -118,149 +129,378 @@ static int is_power_of_two(uint64_t valu return (value != 0) && ((value & (value - 1)) == 0); } -static int pkey_scrypt_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +static int kdf_scrypt_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args) { - SCRYPT_PKEY_CTX *kctx = ctx->data; uint64_t u64_value; + uint32_t value; + const unsigned char *p; + size_t len; + + switch (cmd) { + case EVP_KDF_CTRL_SET_PASS: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + return scrypt_set_membuf(&impl->pass, &impl->pass_len, p, len); + + case EVP_KDF_CTRL_SET_SALT: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + return scrypt_set_membuf(&impl->salt, &impl->salt_len, p, len); - switch (type) { - case EVP_PKEY_CTRL_PASS: - return pkey_scrypt_set_membuf(&kctx->pass, &kctx->pass_len, p2, p1); - - case EVP_PKEY_CTRL_SCRYPT_SALT: - return pkey_scrypt_set_membuf(&kctx->salt, &kctx->salt_len, p2, p1); - - case EVP_PKEY_CTRL_SCRYPT_N: - u64_value = *((uint64_t *)p2); + case EVP_KDF_CTRL_SET_SCRYPT_N: + u64_value = va_arg(args, uint64_t); if ((u64_value <= 1) || !is_power_of_two(u64_value)) return 0; - kctx->N = u64_value; + + impl->N = u64_value; return 1; - case EVP_PKEY_CTRL_SCRYPT_R: - u64_value = *((uint64_t *)p2); - if (u64_value < 1) + case EVP_KDF_CTRL_SET_SCRYPT_R: + value = va_arg(args, uint32_t); + if (value < 1) return 0; - kctx->r = u64_value; + + impl->r = value; return 1; - case EVP_PKEY_CTRL_SCRYPT_P: - u64_value = *((uint64_t *)p2); - if (u64_value < 1) + case EVP_KDF_CTRL_SET_SCRYPT_P: + value = va_arg(args, uint32_t); + if (value < 1) return 0; - kctx->p = u64_value; + + impl->p = value; return 1; - case EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES: - u64_value = *((uint64_t *)p2); + case EVP_KDF_CTRL_SET_MAXMEM_BYTES: + u64_value = va_arg(args, uint64_t); if (u64_value < 1) return 0; - kctx->maxmem_bytes = u64_value; + + impl->maxmem_bytes = u64_value; return 1; default: return -2; + } +} +static int kdf_scrypt_ctrl_uint32(EVP_KDF_IMPL *impl, int cmd, + const char *value) +{ + int int_value = atoi(value); + + if (int_value < 0 || (uint64_t)int_value > UINT32_MAX) { + KDFerr(KDF_F_KDF_SCRYPT_CTRL_UINT32, KDF_R_VALUE_ERROR); + return 0; } + return call_ctrl(kdf_scrypt_ctrl, impl, cmd, (uint32_t)int_value); } -static int pkey_scrypt_ctrl_uint64(EVP_PKEY_CTX *ctx, int type, - const char *value) +static int kdf_scrypt_ctrl_uint64(EVP_KDF_IMPL *impl, int cmd, + const char *value) { - uint64_t int_value; + uint64_t u64_value; - if (!atou64(value, &int_value)) { - KDFerr(KDF_F_PKEY_SCRYPT_CTRL_UINT64, KDF_R_VALUE_ERROR); + if (!atou64(value, &u64_value)) { + KDFerr(KDF_F_KDF_SCRYPT_CTRL_UINT64, KDF_R_VALUE_ERROR); return 0; } - return pkey_scrypt_ctrl(ctx, type, 0, &int_value); + return call_ctrl(kdf_scrypt_ctrl, impl, cmd, u64_value); } -static int pkey_scrypt_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, - const char *value) +static int kdf_scrypt_ctrl_str(EVP_KDF_IMPL *impl, const char *type, + const char *value) { if (value == NULL) { - KDFerr(KDF_F_PKEY_SCRYPT_CTRL_STR, KDF_R_VALUE_MISSING); + KDFerr(KDF_F_KDF_SCRYPT_CTRL_STR, KDF_R_VALUE_MISSING); return 0; } if (strcmp(type, "pass") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_PASS, value); + return kdf_str2ctrl(impl, kdf_scrypt_ctrl, EVP_KDF_CTRL_SET_PASS, + value); if (strcmp(type, "hexpass") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_PASS, value); + return kdf_hex2ctrl(impl, kdf_scrypt_ctrl, EVP_KDF_CTRL_SET_PASS, + value); if (strcmp(type, "salt") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_SCRYPT_SALT, value); + return kdf_str2ctrl(impl, kdf_scrypt_ctrl, EVP_KDF_CTRL_SET_SALT, + value); if (strcmp(type, "hexsalt") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_SCRYPT_SALT, value); + return kdf_hex2ctrl(impl, kdf_scrypt_ctrl, EVP_KDF_CTRL_SET_SALT, + value); if (strcmp(type, "N") == 0) - return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_N, value); + return kdf_scrypt_ctrl_uint64(impl, EVP_KDF_CTRL_SET_SCRYPT_N, value); if (strcmp(type, "r") == 0) - return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_R, value); + return kdf_scrypt_ctrl_uint32(impl, EVP_KDF_CTRL_SET_SCRYPT_R, value); if (strcmp(type, "p") == 0) - return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_P, value); + return kdf_scrypt_ctrl_uint32(impl, EVP_KDF_CTRL_SET_SCRYPT_P, value); if (strcmp(type, "maxmem_bytes") == 0) - return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES, - value); + return kdf_scrypt_ctrl_uint64(impl, EVP_KDF_CTRL_SET_MAXMEM_BYTES, + value); - KDFerr(KDF_F_PKEY_SCRYPT_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE); return -2; } -static int pkey_scrypt_derive(EVP_PKEY_CTX *ctx, unsigned char *key, - size_t *keylen) +static int kdf_scrypt_derive(EVP_KDF_IMPL *impl, unsigned char *key, + size_t keylen) { - SCRYPT_PKEY_CTX *kctx = ctx->data; - - if (kctx->pass == NULL) { - KDFerr(KDF_F_PKEY_SCRYPT_DERIVE, KDF_R_MISSING_PASS); + if (impl->pass == NULL) { + KDFerr(KDF_F_KDF_SCRYPT_DERIVE, KDF_R_MISSING_PASS); return 0; } - if (kctx->salt == NULL) { - KDFerr(KDF_F_PKEY_SCRYPT_DERIVE, KDF_R_MISSING_SALT); + if (impl->salt == NULL) { + KDFerr(KDF_F_KDF_SCRYPT_DERIVE, KDF_R_MISSING_SALT); return 0; } - return EVP_PBE_scrypt((char *)kctx->pass, kctx->pass_len, kctx->salt, - kctx->salt_len, kctx->N, kctx->r, kctx->p, - kctx->maxmem_bytes, key, *keylen); + return scrypt_alg((char *)impl->pass, impl->pass_len, impl->salt, + impl->salt_len, impl->N, impl->r, impl->p, + impl->maxmem_bytes, key, keylen); } -const EVP_PKEY_METHOD scrypt_pkey_meth = { - EVP_PKEY_SCRYPT, - 0, - pkey_scrypt_init, - 0, - pkey_scrypt_cleanup, +const EVP_KDF_METHOD scrypt_kdf_meth = { + EVP_KDF_SCRYPT, + kdf_scrypt_new, + kdf_scrypt_free, + kdf_scrypt_reset, + kdf_scrypt_ctrl, + kdf_scrypt_ctrl_str, + NULL, + kdf_scrypt_derive +}; - 0, 0, - 0, 0, +#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) +static void salsa208_word_specification(uint32_t inout[16]) +{ + int i; + uint32_t x[16]; - 0, - 0, + memcpy(x, inout, sizeof(x)); + for (i = 8; i > 0; i -= 2) { + x[4] ^= R(x[0] + x[12], 7); + x[8] ^= R(x[4] + x[0], 9); + x[12] ^= R(x[8] + x[4], 13); + x[0] ^= R(x[12] + x[8], 18); + x[9] ^= R(x[5] + x[1], 7); + x[13] ^= R(x[9] + x[5], 9); + x[1] ^= R(x[13] + x[9], 13); + x[5] ^= R(x[1] + x[13], 18); + x[14] ^= R(x[10] + x[6], 7); + x[2] ^= R(x[14] + x[10], 9); + x[6] ^= R(x[2] + x[14], 13); + x[10] ^= R(x[6] + x[2], 18); + x[3] ^= R(x[15] + x[11], 7); + x[7] ^= R(x[3] + x[15], 9); + x[11] ^= R(x[7] + x[3], 13); + x[15] ^= R(x[11] + x[7], 18); + x[1] ^= R(x[0] + x[3], 7); + x[2] ^= R(x[1] + x[0], 9); + x[3] ^= R(x[2] + x[1], 13); + x[0] ^= R(x[3] + x[2], 18); + x[6] ^= R(x[5] + x[4], 7); + x[7] ^= R(x[6] + x[5], 9); + x[4] ^= R(x[7] + x[6], 13); + x[5] ^= R(x[4] + x[7], 18); + x[11] ^= R(x[10] + x[9], 7); + x[8] ^= R(x[11] + x[10], 9); + x[9] ^= R(x[8] + x[11], 13); + x[10] ^= R(x[9] + x[8], 18); + x[12] ^= R(x[15] + x[14], 7); + x[13] ^= R(x[12] + x[15], 9); + x[14] ^= R(x[13] + x[12], 13); + x[15] ^= R(x[14] + x[13], 18); + } + for (i = 0; i < 16; ++i) + inout[i] += x[i]; + OPENSSL_cleanse(x, sizeof(x)); +} - 0, - 0, +static void scryptBlockMix(uint32_t *B_, uint32_t *B, uint64_t r) +{ + uint64_t i, j; + uint32_t X[16], *pB; - 0, 0, + memcpy(X, B + (r * 2 - 1) * 16, sizeof(X)); + pB = B; + for (i = 0; i < r * 2; i++) { + for (j = 0; j < 16; j++) + X[j] ^= *pB++; + salsa208_word_specification(X); + memcpy(B_ + (i / 2 + (i & 1) * r) * 16, X, sizeof(X)); + } + OPENSSL_cleanse(X, sizeof(X)); +} - 0, 0, 0, 0, +static void scryptROMix(unsigned char *B, uint64_t r, uint64_t N, + uint32_t *X, uint32_t *T, uint32_t *V) +{ + unsigned char *pB; + uint32_t *pV; + uint64_t i, k; + + /* Convert from little endian input */ + for (pV = V, i = 0, pB = B; i < 32 * r; i++, pV++) { + *pV = *pB++; + *pV |= *pB++ << 8; + *pV |= *pB++ << 16; + *pV |= (uint32_t)*pB++ << 24; + } - 0, 0, + for (i = 1; i < N; i++, pV += 32 * r) + scryptBlockMix(pV, pV - 32 * r, r); - 0, 0, + scryptBlockMix(X, V + (N - 1) * 32 * r, r); - 0, - pkey_scrypt_derive, - pkey_scrypt_ctrl, - pkey_scrypt_ctrl_str -}; + for (i = 0; i < N; i++) { + uint32_t j; + j = X[16 * (2 * r - 1)] % N; + pV = V + 32 * r * j; + for (k = 0; k < 32 * r; k++) + T[k] = X[k] ^ *pV++; + scryptBlockMix(X, T, r); + } + /* Convert output to little endian */ + for (i = 0, pB = B; i < 32 * r; i++) { + uint32_t xtmp = X[i]; + *pB++ = xtmp & 0xff; + *pB++ = (xtmp >> 8) & 0xff; + *pB++ = (xtmp >> 16) & 0xff; + *pB++ = (xtmp >> 24) & 0xff; + } +} + +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t)-1) +#endif + +/* + * Maximum power of two that will fit in uint64_t: this should work on + * most (all?) platforms. + */ + +#define LOG2_UINT64_MAX (sizeof(uint64_t) * 8 - 1) + +/* + * Maximum value of p * r: + * p <= ((2^32-1) * hLen) / MFLen => + * p <= ((2^32-1) * 32) / (128 * r) => + * p * r <= (2^30-1) + */ + +#define SCRYPT_PR_MAX ((1 << 30) - 1) + +static int scrypt_alg(const char *pass, size_t passlen, + const unsigned char *salt, size_t saltlen, + uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, + unsigned char *key, size_t keylen) +{ + int rv = 0; + unsigned char *B; + uint32_t *X, *V, *T; + uint64_t i, Blen, Vlen; + + /* Sanity check parameters */ + /* initial check, r,p must be non zero, N >= 2 and a power of 2 */ + if (r == 0 || p == 0 || N < 2 || (N & (N - 1))) + return 0; + /* Check p * r < SCRYPT_PR_MAX avoiding overflow */ + if (p > SCRYPT_PR_MAX / r) { + EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED); + return 0; + } + + /* + * Need to check N: if 2^(128 * r / 8) overflows limit this is + * automatically satisfied since N <= UINT64_MAX. + */ + + if (16 * r <= LOG2_UINT64_MAX) { + if (N >= (((uint64_t)1) << (16 * r))) { + EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED); + return 0; + } + } + + /* Memory checks: check total allocated buffer size fits in uint64_t */ + + /* + * B size in section 5 step 1.S + * Note: we know p * 128 * r < UINT64_MAX because we already checked + * p * r < SCRYPT_PR_MAX + */ + Blen = p * 128 * r; + /* + * Yet we pass it as integer to PKCS5_PBKDF2_HMAC... [This would + * have to be revised when/if PKCS5_PBKDF2_HMAC accepts size_t.] + */ + if (Blen > INT_MAX) { + EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED); + return 0; + } + + /* + * Check 32 * r * (N + 2) * sizeof(uint32_t) fits in uint64_t + * This is combined size V, X and T (section 4) + */ + i = UINT64_MAX / (32 * sizeof(uint32_t)); + if (N + 2 > i / r) { + EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED); + return 0; + } + Vlen = 32 * r * (N + 2) * sizeof(uint32_t); + + /* check total allocated size fits in uint64_t */ + if (Blen > UINT64_MAX - Vlen) { + EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED); + return 0; + } + + /* Check that the maximum memory doesn't exceed a size_t limits */ + if (maxmem > SIZE_MAX) + maxmem = SIZE_MAX; + + if (Blen + Vlen > maxmem) { + EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED); + return 0; + } + + /* If no key return to indicate parameters are OK */ + if (key == NULL) + return 1; + + B = OPENSSL_malloc((size_t)(Blen + Vlen)); + if (B == NULL) { + EVPerr(EVP_F_SCRYPT_ALG, ERR_R_MALLOC_FAILURE); + return 0; + } + X = (uint32_t *)(B + Blen); + T = X + 32 * r; + V = T + 32 * r; + if (PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, 1, EVP_sha256(), + (int)Blen, B) == 0) + goto err; + + for (i = 0; i < p; i++) + scryptROMix(B + 128 * r * i, r, N, X, T, V); + + if (PKCS5_PBKDF2_HMAC(pass, passlen, B, (int)Blen, 1, EVP_sha256(), + keylen, key) == 0) + goto err; + rv = 1; + err: + if (rv == 0) + EVPerr(EVP_F_SCRYPT_ALG, EVP_R_PBKDF2_ERROR); + + OPENSSL_clear_free(B, (size_t)(Blen + Vlen)); + return rv; +} #endif Index: openssl-1.1.1n/crypto/kdf/tls1_prf.c =================================================================== --- openssl-1.1.1n.orig/crypto/kdf/tls1_prf.c +++ openssl-1.1.1n/crypto/kdf/tls1_prf.c @@ -8,11 +8,15 @@ */ #include +#include +#include #include "internal/cryptlib.h" -#include #include +#include #include "crypto/evp.h" +#include "kdf_local.h" +static void kdf_tls1_prf_reset(EVP_KDF_IMPL *impl); static int tls1_prf_alg(const EVP_MD *md, const unsigned char *sec, size_t slen, const unsigned char *seed, size_t seed_len, @@ -20,9 +24,9 @@ static int tls1_prf_alg(const EVP_MD *md #define TLS1_PRF_MAXBUF 1024 -/* TLS KDF pkey context structure */ +/* TLS KDF kdf context structure */ -typedef struct { +struct evp_kdf_impl_st { /* Digest to use for PRF */ const EVP_MD *md; /* Secret value to use for PRF */ @@ -31,145 +35,137 @@ typedef struct { /* Buffer of concatenated seed data */ unsigned char seed[TLS1_PRF_MAXBUF]; size_t seedlen; -} TLS1_PRF_PKEY_CTX; +}; -static int pkey_tls1_prf_init(EVP_PKEY_CTX *ctx) +static EVP_KDF_IMPL *kdf_tls1_prf_new(void) { - TLS1_PRF_PKEY_CTX *kctx; + EVP_KDF_IMPL *impl; - if ((kctx = OPENSSL_zalloc(sizeof(*kctx))) == NULL) { - KDFerr(KDF_F_PKEY_TLS1_PRF_INIT, ERR_R_MALLOC_FAILURE); - return 0; - } - ctx->data = kctx; + if ((impl = OPENSSL_zalloc(sizeof(*impl))) == NULL) + KDFerr(KDF_F_KDF_TLS1_PRF_NEW, ERR_R_MALLOC_FAILURE); + return impl; +} - return 1; +static void kdf_tls1_prf_free(EVP_KDF_IMPL *impl) +{ + kdf_tls1_prf_reset(impl); + OPENSSL_free(impl); } -static void pkey_tls1_prf_cleanup(EVP_PKEY_CTX *ctx) +static void kdf_tls1_prf_reset(EVP_KDF_IMPL *impl) { - TLS1_PRF_PKEY_CTX *kctx = ctx->data; - OPENSSL_clear_free(kctx->sec, kctx->seclen); - OPENSSL_cleanse(kctx->seed, kctx->seedlen); - OPENSSL_free(kctx); + OPENSSL_clear_free(impl->sec, impl->seclen); + OPENSSL_cleanse(impl->seed, impl->seedlen); + memset(impl, 0, sizeof(*impl)); } -static int pkey_tls1_prf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +static int kdf_tls1_prf_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args) { - TLS1_PRF_PKEY_CTX *kctx = ctx->data; - switch (type) { - case EVP_PKEY_CTRL_TLS_MD: - kctx->md = p2; - return 1; + const unsigned char *p; + size_t len; + const EVP_MD *md; - case EVP_PKEY_CTRL_TLS_SECRET: - if (p1 < 0) + switch (cmd) { + case EVP_KDF_CTRL_SET_MD: + md = va_arg(args, const EVP_MD *); + if (md == NULL) return 0; - if (kctx->sec != NULL) - OPENSSL_clear_free(kctx->sec, kctx->seclen); - OPENSSL_cleanse(kctx->seed, kctx->seedlen); - kctx->seedlen = 0; - kctx->sec = OPENSSL_memdup(p2, p1); - if (kctx->sec == NULL) + + impl->md = md; + return 1; + + case EVP_KDF_CTRL_SET_TLS_SECRET: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + OPENSSL_clear_free(impl->sec, impl->seclen); + impl->sec = OPENSSL_memdup(p, len); + if (impl->sec == NULL) return 0; - kctx->seclen = p1; + + impl->seclen = len; return 1; - case EVP_PKEY_CTRL_TLS_SEED: - if (p1 == 0 || p2 == NULL) + case EVP_KDF_CTRL_RESET_TLS_SEED: + OPENSSL_cleanse(impl->seed, impl->seedlen); + impl->seedlen = 0; + return 1; + + case EVP_KDF_CTRL_ADD_TLS_SEED: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + if (len == 0 || p == NULL) return 1; - if (p1 < 0 || p1 > (int)(TLS1_PRF_MAXBUF - kctx->seedlen)) + + if (len > (TLS1_PRF_MAXBUF - impl->seedlen)) return 0; - memcpy(kctx->seed + kctx->seedlen, p2, p1); - kctx->seedlen += p1; + + memcpy(impl->seed + impl->seedlen, p, len); + impl->seedlen += len; return 1; default: return -2; - } } -static int pkey_tls1_prf_ctrl_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) +static int kdf_tls1_prf_ctrl_str(EVP_KDF_IMPL *impl, + const char *type, const char *value) { if (value == NULL) { - KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_VALUE_MISSING); + KDFerr(KDF_F_KDF_TLS1_PRF_CTRL_STR, KDF_R_VALUE_MISSING); return 0; } - if (strcmp(type, "md") == 0) { - TLS1_PRF_PKEY_CTX *kctx = ctx->data; + if (strcmp(type, "digest") == 0) + return kdf_md2ctrl(impl, kdf_tls1_prf_ctrl, EVP_KDF_CTRL_SET_MD, value); - const EVP_MD *md = EVP_get_digestbyname(value); - if (md == NULL) { - KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_INVALID_DIGEST); - return 0; - } - kctx->md = md; - return 1; - } if (strcmp(type, "secret") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_TLS_SECRET, value); + return kdf_str2ctrl(impl, kdf_tls1_prf_ctrl, + EVP_KDF_CTRL_SET_TLS_SECRET, value); + if (strcmp(type, "hexsecret") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_TLS_SECRET, value); + return kdf_hex2ctrl(impl, kdf_tls1_prf_ctrl, + EVP_KDF_CTRL_SET_TLS_SECRET, value); + if (strcmp(type, "seed") == 0) - return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_TLS_SEED, value); + return kdf_str2ctrl(impl, kdf_tls1_prf_ctrl, EVP_KDF_CTRL_ADD_TLS_SEED, + value); + if (strcmp(type, "hexseed") == 0) - return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_TLS_SEED, value); + return kdf_hex2ctrl(impl, kdf_tls1_prf_ctrl, EVP_KDF_CTRL_ADD_TLS_SEED, + value); - KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE); return -2; } -static int pkey_tls1_prf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, - size_t *keylen) +static int kdf_tls1_prf_derive(EVP_KDF_IMPL *impl, unsigned char *key, + size_t keylen) { - TLS1_PRF_PKEY_CTX *kctx = ctx->data; - if (kctx->md == NULL) { - KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST); + if (impl->md == NULL) { + KDFerr(KDF_F_KDF_TLS1_PRF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST); return 0; } - if (kctx->sec == NULL) { - KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_SECRET); + if (impl->sec == NULL) { + KDFerr(KDF_F_KDF_TLS1_PRF_DERIVE, KDF_R_MISSING_SECRET); return 0; } - if (kctx->seedlen == 0) { - KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_SEED); + if (impl->seedlen == 0) { + KDFerr(KDF_F_KDF_TLS1_PRF_DERIVE, KDF_R_MISSING_SEED); return 0; } - return tls1_prf_alg(kctx->md, kctx->sec, kctx->seclen, - kctx->seed, kctx->seedlen, - key, *keylen); + return tls1_prf_alg(impl->md, impl->sec, impl->seclen, + impl->seed, impl->seedlen, + key, keylen); } -const EVP_PKEY_METHOD tls1_prf_pkey_meth = { - EVP_PKEY_TLS1_PRF, - 0, - pkey_tls1_prf_init, - 0, - pkey_tls1_prf_cleanup, - - 0, 0, - 0, 0, - - 0, - 0, - - 0, - 0, - - 0, 0, - - 0, 0, 0, 0, - - 0, 0, - - 0, 0, - - 0, - pkey_tls1_prf_derive, - pkey_tls1_prf_ctrl, - pkey_tls1_prf_ctrl_str +const EVP_KDF_METHOD tls1_prf_kdf_meth = { + EVP_KDF_TLS1_PRF, + kdf_tls1_prf_new, + kdf_tls1_prf_free, + kdf_tls1_prf_reset, + kdf_tls1_prf_ctrl, + kdf_tls1_prf_ctrl_str, + NULL, + kdf_tls1_prf_derive }; static int tls1_prf_P_hash(const EVP_MD *md, @@ -249,12 +245,11 @@ static int tls1_prf_alg(const EVP_MD *md const unsigned char *seed, size_t seed_len, unsigned char *out, size_t olen) { - if (EVP_MD_type(md) == NID_md5_sha1) { size_t i; unsigned char *tmp; if (!tls1_prf_P_hash(EVP_md5(), sec, slen/2 + (slen & 1), - seed, seed_len, out, olen)) + seed, seed_len, out, olen)) return 0; if ((tmp = OPENSSL_malloc(olen)) == NULL) { @@ -262,7 +257,7 @@ static int tls1_prf_alg(const EVP_MD *md return 0; } if (!tls1_prf_P_hash(EVP_sha1(), sec + slen/2, slen/2 + (slen & 1), - seed, seed_len, tmp, olen)) { + seed, seed_len, tmp, olen)) { OPENSSL_clear_free(tmp, olen); return 0; } Index: openssl-1.1.1n/doc/man3/EVP_KDF_CTX.pod =================================================================== --- /dev/null +++ openssl-1.1.1n/doc/man3/EVP_KDF_CTX.pod @@ -0,0 +1,217 @@ +=pod + +=head1 NAME + +EVP_KDF_CTX, EVP_KDF_CTX_new_id, EVP_KDF_CTX_free, EVP_KDF_reset, +EVP_KDF_ctrl, EVP_KDF_vctrl, EVP_KDF_ctrl_str, EVP_KDF_size, +EVP_KDF_derive - EVP KDF routines + +=head1 SYNOPSIS + + #include + + typedef struct evp_kdf_ctx_st EVP_KDF_CTX; + + EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id); + void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx); + void EVP_KDF_reset(EVP_KDF_CTX *ctx); + int EVP_KDF_ctrl(EVP_KDF_CTX *ctx, int cmd, ...); + int EVP_KDF_vctrl(EVP_KDF_CTX *ctx, int cmd, va_list args); + int EVP_KDF_ctrl_str(EVP_KDF_CTX *ctx, const char *type, const char *value); + size_t EVP_KDF_size(EVP_KDF_CTX *ctx); + int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen); + +=head1 DESCRIPTION + +The EVP KDF routines are a high level interface to Key Derivation Function +algorithms and should be used instead of algorithm-specific functions. + +After creating a C for the required algorithm using +EVP_KDF_CTX_new_id(), inputs to the algorithm are supplied using calls to +EVP_KDF_ctrl(), EVP_KDF_vctrl() or EVP_KDF_ctrl_str() before calling +EVP_KDF_derive() to derive the key. + +=head2 Types + +B is a context type that holds the algorithm inputs. + +=head2 Context manipulation functions + +EVP_KDF_CTX_new_id() creates a KDF context for the algorithm identified by the +specified NID. + +EVP_KDF_CTX_free() frees up the context C. If C is C, nothing +is done. + +=head2 Computing functions + +EVP_KDF_reset() resets the context to the default state as if the context +had just been created. + +EVP_KDF_ctrl() is used to provide inputs to the KDF algorithm prior to +EVP_KDF_derive() being called. The inputs that may be provided will vary +depending on the KDF algorithm or its implementation. This functions takes +variable arguments, the exact expected arguments depend on C. +See L below for a description of standard controls. + +EVP_KDF_vctrl() is the variant of EVP_KDF_ctrl() that takes a C +argument instead of variadic arguments. + +EVP_KDF_ctrl_str() allows an application to send an algorithm specific control +operation to a context C in string form. This is intended to be used for +options specified on the command line or in text files. + +EVP_KDF_size() returns the output size if the algorithm produces a fixed amount +of output and C otherwise. If an error occurs then 0 is returned. +For some algorithms an error may result if input parameters necessary to +calculate a fixed output size have not yet been supplied. + +EVP_KDF_derive() derives C bytes of key material and places it in the +C buffer. If the algorithm produces a fixed amount of output then an +error will occur unless the C parameter is equal to that output size, +as returned by EVP_KDF_size(). + +=head1 CONTROLS + +The standard controls are: + +=over 4 + +=item B + +This control expects two arguments: C, C + +Some KDF implementations require a password. For those KDF implementations +that support it, this control sets the password. + +EVP_KDF_ctrl_str() takes two type strings for this control: + +=over 4 + +=item "pass" + +The value string is used as is. + +=item "hexpass" + +The value string is expected to be a hexadecimal number, which will be +decoded before being passed on as the control value. + +=back + +=item B + +This control expects two arguments: C, C + +Some KDF implementations can take a salt. For those KDF implementations that +support it, this control sets the salt. + +The default value, if any, is implementation dependent. + +EVP_KDF_ctrl_str() takes two type strings for this control: + +=over 4 + +=item "salt" + +The value string is used as is. + +=item "hexsalt" + +The value string is expected to be a hexadecimal number, which will be +decoded before being passed on as the control value. + +=back + +=item B + +This control expects one argument: C + +Some KDF implementations require an iteration count. For those KDF implementations that support it, this control sets the iteration count. + +The default value, if any, is implementation dependent. + +EVP_KDF_ctrl_str() type string: "iter" + +The value string is expected to be a decimal number. + +=item B + +This control expects one argument: C + +For MAC implementations that use a message digest as an underlying computation +algorithm, this control set what the digest algorithm should be. + +EVP_KDF_ctrl_str() type string: "md" + +The value string is expected to be the name of a digest. + +=item B + +This control expects two arguments: C, C + +Some KDF implementations require a key. For those KDF implementations that +support it, this control sets the key. + +EVP_KDF_ctrl_str() takes two type strings for this control: + +=over 4 + +=item "key" + +The value string is used as is. + +=item "hexkey" + +The value string is expected to be a hexadecimal number, which will be +decoded before being passed on as the control value. + +=back + +=item B + +This control expects one argument: C + +Memory-hard password-based KDF algorithms, such as scrypt, use an amount of +memory that depends on the load factors provided as input. For those KDF +implementations that support it, this control sets an upper limit on the amount +of memory that may be consumed while performing a key derivation. If this +memory usage limit is exceeded because the load factors are chosen too high, +the key derivation will fail. + +The default value is implementation dependent. + +EVP_KDF_ctrl_str() type string: "maxmem_bytes" + +The value string is expected to be a decimal number. + +=back + +=head1 RETURN VALUES + +EVP_KDF_CTX_new_id() returns either the newly allocated C +structure or C if an error occurred. + +EVP_KDF_CTX_free() and EVP_KDF_reset() do not return a value. + +EVP_KDF_size() returns the output size. C is returned to indicate +that the algorithm produces a variable amount of output; 0 to indicate failure. + +The remaining functions return 1 for success and 0 or a negative value for +failure. In particular, a return value of -2 indicates the operation is not +supported by the KDF algorithm. + +=head1 SEE ALSO + +L + +=head1 COPYRIGHT + +Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut Index: openssl-1.1.1n/doc/man7/EVP_KDF_HKDF.pod =================================================================== --- /dev/null +++ openssl-1.1.1n/doc/man7/EVP_KDF_HKDF.pod @@ -0,0 +1,180 @@ +=pod + +=head1 NAME + +EVP_KDF_HKDF - The HKDF EVP_KDF implementation + +=head1 DESCRIPTION + +Support for computing the B KDF through the B API. + +The EVP_KDF_HKDF algorithm implements the HKDF key derivation function. +HKDF follows the "extract-then-expand" paradigm, where the KDF logically +consists of two modules. The first stage takes the input keying material +and "extracts" from it a fixed-length pseudorandom key K. The second stage +"expands" the key K into several additional pseudorandom keys (the output +of the KDF). + +=head2 Numeric identity + +B is the numeric identity for this implementation; it +can be used with the EVP_KDF_CTX_new_id() function. + +=head2 Supported controls + +The supported controls are: + +=over 4 + +=item B + +=item B + +=item B + +These controls work as described in L. + +=item B + +This control does not expect any arguments. + +Resets the context info buffer to zero length. + +=item B + +This control expects two arguments: C, C + +Sets the info value to the first B bytes of the buffer B. If a +value is already set, the contents of the buffer are appended to the existing +value. + +The total length of the context info buffer cannot exceed 1024 bytes; +this should be more than enough for any normal use of HKDF. + +EVP_KDF_ctrl_str() takes two type strings for this control: + +=over 4 + +=item "info" + +The value string is used as is. + +=item "hexinfo" + +The value string is expected to be a hexadecimal number, which will be +decoded before being passed on as the control value. + +=back + +=item B + +This control expects one argument: C + +Sets the mode for the HKDF operation. There are three modes that are currently +defined: + +=over 4 + +=item EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND + +This is the default mode. Calling L on an EVP_KDF_CTX set +up for HKDF will perform an extract followed by an expand operation in one go. +The derived key returned will be the result after the expand operation. The +intermediate fixed-length pseudorandom key K is not returned. + +In this mode the digest, key, salt and info values must be set before a key is +derived otherwise an error will occur. + +=item EVP_KDF_HKDF_MODE_EXTRACT_ONLY + +In this mode calling L will just perform the extract +operation. The value returned will be the intermediate fixed-length pseudorandom +key K. The C parameter must match the size of K, which can be looked +up by calling EVP_KDF_size() after setting the mode and digest. + +The digest, key and salt values must be set before a key is derived otherwise +an error will occur. + +=item EVP_KDF_HKDF_MODE_EXPAND_ONLY + +In this mode calling L will just perform the expand +operation. The input key should be set to the intermediate fixed-length +pseudorandom key K returned from a previous extract operation. + +The digest, key and info values must be set before a key is derived otherwise +an error will occur. + +=back + +EVP_KDF_ctrl_str() type string: "mode" + +The value string is expected to be one of: "EXTRACT_AND_EXPAND", "EXTRACT_ONLY" +or "EXPAND_ONLY". + +=back + +=head1 NOTES + +A context for HKDF can be obtained by calling: + + EVP_KDF_CTX *kctx = EVP_KDF_CTX_new_id(EVP_KDF_HKDF); + +The output length of an HKDF expand operation is specified via the C +parameter to the L function. When using +EVP_KDF_HKDF_MODE_EXTRACT_ONLY the C parameter must equal the size of +the intermediate fixed-length pseudorandom key otherwise an error will occur. +For that mode, the fixed output size can be looked up by calling EVP_KDF_size() +after setting the mode and digest on the C. + +=head1 EXAMPLE + +This example derives 10 bytes using SHA-256 with the secret key "secret", +salt value "salt" and info value "label": + + EVP_KDF_CTX *kctx; + unsigned char out[10]; + + kctx = EVP_KDF_CTX_new_id(EVP_KDF_HKDF); + + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) { + error("EVP_KDF_CTRL_SET_MD"); + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, "salt", (size_t)4) <= 0) { + error("EVP_KDF_CTRL_SET_SALT"); + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, "secret", (size_t)6) <= 0) { + error("EVP_KDF_CTRL_SET_KEY"); + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_ADD_HKDF_INFO, "label", (size_t)5) <= 0) { + error("EVP_KDF_CTRL_ADD_HKDF_INFO"); + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { + error("EVP_KDF_derive"); + } + + EVP_KDF_CTX_free(kctx); + +=head1 CONFORMING TO + +RFC 5869 + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L, +L + +=head1 COPYRIGHT + +Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut Index: openssl-1.1.1n/doc/man7/EVP_KDF_PBKDF2.pod =================================================================== --- /dev/null +++ openssl-1.1.1n/doc/man7/EVP_KDF_PBKDF2.pod @@ -0,0 +1,78 @@ +=pod + +=head1 NAME + +EVP_KDF_PBKDF2 - The PBKDF2 EVP_KDF implementation + +=head1 DESCRIPTION + +Support for computing the B password-based KDF through the B +API. + +The EVP_KDF_PBKDF2 algorithm implements the PBKDF2 password-based key +derivation function, as described in RFC 2898; it derives a key from a password +using a salt and iteration count. + +=head2 Numeric identity + +B is the numeric identity for this implementation; it +can be used with the EVP_KDF_CTX_new_id() function. + +=head2 Supported controls + +The supported controls are: + +=over 4 + +=item B + +=item B + +=item B + +=item B + +These controls work as described in L. + +B is the iteration count and its value should be greater than or equal to +1. RFC 2898 suggests an iteration count of at least 1000. The default value is +2048. Any B less than 1 is treated as a single iteration. + +=back + +=head1 NOTES + +A typical application of this algorithm is to derive keying material for an +encryption algorithm from a password in the B, a salt in B, +and an iteration count. + +Increasing the B parameter slows down the algorithm which makes it +harder for an attacker to perform a brute force attack using a large number +of candidate passwords. + +No assumption is made regarding the given password; it is simply treated as a +byte sequence. + +=head1 CONFORMING TO + +RFC 2898 + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L + +=head1 COPYRIGHT + +Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut Index: openssl-1.1.1n/doc/man7/EVP_KDF_SCRYPT.pod =================================================================== --- /dev/null +++ openssl-1.1.1n/doc/man7/EVP_KDF_SCRYPT.pod @@ -0,0 +1,149 @@ +=pod + +=head1 NAME + +EVP_KDF_SCRYPT - The scrypt EVP_KDF implementation + +=head1 DESCRIPTION + +Support for computing the B password-based KDF through the B +API. + +The EVP_KDF_SCRYPT algorithm implements the scrypt password-based key +derivation function, as described in RFC 7914. It is memory-hard in the sense +that it deliberately requires a significant amount of RAM for efficient +computation. The intention of this is to render brute forcing of passwords on +systems that lack large amounts of main memory (such as GPUs or ASICs) +computationally infeasible. + +scrypt provides three work factors that can be customized: N, r and p. N, which +has to be a positive power of two, is the general work factor and scales CPU +time in an approximately linear fashion. r is the block size of the internally +used hash function and p is the parallelization factor. Both r and p need to be +greater than zero. The amount of RAM that scrypt requires for its computation +is roughly (128 * N * r * p) bytes. + +In the original paper of Colin Percival ("Stronger Key Derivation via +Sequential Memory-Hard Functions", 2009), the suggested values that give a +computation time of less than 5 seconds on a 2.5 GHz Intel Core 2 Duo are N = +2^20 = 1048576, r = 8, p = 1. Consequently, the required amount of memory for +this computation is roughly 1 GiB. On a more recent CPU (Intel i7-5930K at 3.5 +GHz), this computation takes about 3 seconds. When N, r or p are not specified, +they default to 1048576, 8, and 1, respectively. The maximum amount of RAM that +may be used by scrypt defaults to 1025 MiB. + +=head2 Numeric identity + +B is the numeric identity for this implementation; it +can be used with the EVP_KDF_CTX_new_id() function. + +=head2 Supported controls + +The supported controls are: + +=over 4 + +=item B + +=item B + +These controls work as described in L. + +=item B + +=item B + +=item B + +B expects one argument: C + +B expects one argument: C + +B expects one argument: C + +These controls configure the scrypt work factors N, r and p. + +EVP_KDF_ctrl_str() type strings: "N", "r" and "p", respectively. + +The corresponding value strings are expected to be decimal numbers. + +=back + +=head1 NOTES + +A context for scrypt can be obtained by calling: + + EVP_KDF_CTX *kctx = EVP_KDF_CTX_new_id(EVP_KDF_SCRYPT); + +The output length of an scrypt key derivation is specified via the +B parameter to the L function. + +=head1 EXAMPLE + +This example derives a 64-byte long test vector using scrypt with the password +"password", salt "NaCl" and N = 1024, r = 8, p = 16. + + EVP_KDF_CTX *kctx; + unsigned char out[64]; + + kctx = EVP_KDF_CTX_new_id(EVP_KDF_SCRYPT); + + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, "password", (size_t)8) <= 0) { + error("EVP_KDF_CTRL_SET_PASS"); + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, "NaCl", (size_t)4) <= 0) { + error("EVP_KDF_CTRL_SET_SALT"); + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_N, (uint64_t)1024) <= 0) { + error("EVP_KDF_CTRL_SET_SCRYPT_N"); + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_R, (uint32_t)8) <= 0) { + error("EVP_KDF_CTRL_SET_SCRYPT_R"); + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_P, (uint32_t)16) <= 0) { + error("EVP_KDF_CTRL_SET_SCRYPT_P"); + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { + error("EVP_KDF_derive"); + } + + { + const unsigned char expected[sizeof(out)] = { + 0xfd, 0xba, 0xbe, 0x1c, 0x9d, 0x34, 0x72, 0x00, + 0x78, 0x56, 0xe7, 0x19, 0x0d, 0x01, 0xe9, 0xfe, + 0x7c, 0x6a, 0xd7, 0xcb, 0xc8, 0x23, 0x78, 0x30, + 0xe7, 0x73, 0x76, 0x63, 0x4b, 0x37, 0x31, 0x62, + 0x2e, 0xaf, 0x30, 0xd9, 0x2e, 0x22, 0xa3, 0x88, + 0x6f, 0xf1, 0x09, 0x27, 0x9d, 0x98, 0x30, 0xda, + 0xc7, 0x27, 0xaf, 0xb9, 0x4a, 0x83, 0xee, 0x6d, + 0x83, 0x60, 0xcb, 0xdf, 0xa2, 0xcc, 0x06, 0x40 + }; + + assert(!memcmp(out, expected, sizeof(out))); + } + + EVP_KDF_CTX_free(kctx); + +=head1 CONFORMING TO + +RFC 7914 + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L + +=head1 COPYRIGHT + +Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the OpenSSL license (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut Index: openssl-1.1.1n/doc/man7/EVP_KDF_TLS1_PRF.pod =================================================================== --- /dev/null +++ openssl-1.1.1n/doc/man7/EVP_KDF_TLS1_PRF.pod @@ -0,0 +1,142 @@ +=pod + +=head1 NAME + +EVP_KDF_TLS1_PRF - The TLS1 PRF EVP_KDF implementation + +=head1 DESCRIPTION + +Support for computing the B PRF through the B API. + +The EVP_KDF_TLS1_PRF algorithm implements the PRF used by TLS versions up to +and including TLS 1.2. + +=head2 Numeric identity + +B is the numeric identity for this implementation; it +can be used with the EVP_KDF_CTX_new_id() function. + +=head2 Supported controls + +The supported controls are: + +=over 4 + +=item B + +This control works as described in L. + +The C control is used to set the message digest associated +with the TLS PRF. EVP_md5_sha1() is treated as a special case which uses the +PRF algorithm using both B and B as used in TLS 1.0 and 1.1. + +=item B + +This control expects two arguments: C, C + +Sets the secret value of the TLS PRF to B bytes of the buffer B. +Any existing secret value is replaced. + +EVP_KDF_ctrl_str() takes two type strings for this control: + +=over 4 + +=item "secret" + +The value string is used as is. + +=item "hexsecret" + +The value string is expected to be a hexadecimal number, which will be +decoded before being passed on as the control value. + +=back + +=item B + +This control does not expect any arguments. + +Resets the context seed buffer to zero length. + +=item B + +This control expects two arguments: C, C + +Sets the seed to B bytes of B. If a seed is already set it is +appended to the existing value. + +The total length of the context seed buffer cannot exceed 1024 bytes; +this should be more than enough for any normal use of the TLS PRF. + +EVP_KDF_ctrl_str() takes two type strings for this control: + +=over 4 + +=item "seed" + +The value string is used as is. + +=item "hexseed" + +The value string is expected to be a hexadecimal number, which will be +decoded before being passed on as the control value. + +=back + +=back + +=head1 NOTES + +A context for the TLS PRF can be obtained by calling: + + EVP_KDF_CTX *kctx = EVP_KDF_CTX_new_id(EVP_KDF_TLS1_PRF, NULL); + +The digest, secret value and seed must be set before a key is derived otherwise +an error will occur. + +The output length of the PRF is specified by the C parameter to the +EVP_KDF_derive() function. + +=head1 EXAMPLE + +This example derives 10 bytes using SHA-256 with the secret key "secret" +and seed value "seed": + + EVP_KDF_CTX *kctx; + unsigned char out[10]; + + kctx = EVP_KDF_CTX_new_id(EVP_KDF_TLS1_PRF); + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) { + error("EVP_KDF_CTRL_SET_MD"); + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_TLS_SECRET, + "secret", (size_t)6) <= 0) { + error("EVP_KDF_CTRL_SET_TLS_SECRET"); + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_ADD_TLS_SEED, "seed", (size_t)4) <= 0) { + error("EVP_KDF_CTRL_ADD_TLS_SEED"); + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { + error("EVP_KDF_derive"); + } + EVP_KDF_CTX_free(kctx); + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L + +=head1 COPYRIGHT + +Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut Index: openssl-1.1.1n/include/openssl/evperr.h =================================================================== --- openssl-1.1.1n.orig/include/openssl/evperr.h +++ openssl-1.1.1n/include/openssl/evperr.h @@ -56,6 +56,9 @@ int ERR_load_EVP_strings(void); # define EVP_F_EVP_ENCRYPTDECRYPTUPDATE 219 # define EVP_F_EVP_ENCRYPTFINAL_EX 127 # define EVP_F_EVP_ENCRYPTUPDATE 167 +# define EVP_F_EVP_KDF_CTRL 224 +# define EVP_F_EVP_KDF_CTRL_STR 225 +# define EVP_F_EVP_KDF_CTX_NEW_ID 226 # define EVP_F_EVP_MD_CTX_COPY_EX 110 # define EVP_F_EVP_MD_SIZE 162 # define EVP_F_EVP_OPENINIT 102 @@ -118,11 +121,13 @@ int ERR_load_EVP_strings(void); # 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_PKEY_KDF_CTRL 227 # define EVP_F_PKEY_SET_TYPE 158 # define EVP_F_RC2_MAGIC_TO_METH 109 # define EVP_F_RC5_CTRL 125 # define EVP_F_R_32_12_16_INIT_KEY 242 # define EVP_F_S390X_AES_GCM_CTRL 201 +# define EVP_F_SCRYPT_ALG 228 # define EVP_F_UPDATE 173 /* @@ -179,6 +184,7 @@ int ERR_load_EVP_strings(void); # define EVP_R_ONLY_ONESHOT_SUPPORTED 177 # define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150 # define EVP_R_OPERATON_NOT_INITIALIZED 151 +# define EVP_R_PARAMETER_TOO_LARGE 187 # define EVP_R_OUTPUT_WOULD_OVERFLOW 184 # define EVP_R_PARTIALLY_OVERLAPPING 162 # define EVP_R_PBKDF2_ERROR 181 Index: openssl-1.1.1n/include/openssl/kdferr.h =================================================================== --- openssl-1.1.1n.orig/include/openssl/kdferr.h +++ openssl-1.1.1n/include/openssl/kdferr.h @@ -23,6 +23,23 @@ int ERR_load_KDF_strings(void); /* * KDF function codes. */ +# define KDF_F_HKDF_EXTRACT 112 +# define KDF_F_KDF_HKDF_DERIVE 113 +# define KDF_F_KDF_HKDF_NEW 114 +# define KDF_F_KDF_HKDF_SIZE 115 +# define KDF_F_KDF_MD2CTRL 116 +# define KDF_F_KDF_PBKDF2_CTRL_STR 117 +# define KDF_F_KDF_PBKDF2_DERIVE 118 +# define KDF_F_KDF_PBKDF2_NEW 119 +# define KDF_F_KDF_SCRYPT_CTRL_STR 120 +# define KDF_F_KDF_SCRYPT_CTRL_UINT32 121 +# define KDF_F_KDF_SCRYPT_CTRL_UINT64 122 +# define KDF_F_KDF_SCRYPT_DERIVE 123 +# define KDF_F_KDF_SCRYPT_NEW 124 +# define KDF_F_KDF_TLS1_PRF_CTRL_STR 125 +# define KDF_F_KDF_TLS1_PRF_DERIVE 126 +# define KDF_F_KDF_TLS1_PRF_NEW 127 +# define KDF_F_PBKDF2_SET_MEMBUF 128 # define KDF_F_PKEY_HKDF_CTRL_STR 103 # define KDF_F_PKEY_HKDF_DERIVE 102 # define KDF_F_PKEY_HKDF_INIT 108 @@ -34,6 +51,7 @@ int ERR_load_KDF_strings(void); # define KDF_F_PKEY_TLS1_PRF_CTRL_STR 100 # define KDF_F_PKEY_TLS1_PRF_DERIVE 101 # define KDF_F_PKEY_TLS1_PRF_INIT 110 +# define KDF_F_SCRYPT_SET_MEMBUF 129 # define KDF_F_TLS1_PRF_ALG 111 /* @@ -51,5 +69,6 @@ int ERR_load_KDF_strings(void); # define KDF_R_UNKNOWN_PARAMETER_TYPE 103 # define KDF_R_VALUE_ERROR 108 # define KDF_R_VALUE_MISSING 102 +# define KDF_R_WRONG_OUTPUT_BUFFER_SIZE 112 #endif Index: openssl-1.1.1n/include/openssl/kdf.h =================================================================== --- openssl-1.1.1n.orig/include/openssl/kdf.h +++ openssl-1.1.1n/include/openssl/kdf.h @@ -10,10 +10,50 @@ #ifndef HEADER_KDF_H # define HEADER_KDF_H +# include # include -#ifdef __cplusplus +# ifdef __cplusplus extern "C" { -#endif +# endif + +# define EVP_KDF_PBKDF2 NID_id_pbkdf2 +# define EVP_KDF_SCRYPT NID_id_scrypt +# define EVP_KDF_TLS1_PRF NID_tls1_prf +# define EVP_KDF_HKDF NID_hkdf + +EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id); +void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx); + +void EVP_KDF_reset(EVP_KDF_CTX *ctx); +int EVP_KDF_ctrl(EVP_KDF_CTX *ctx, int cmd, ...); +int EVP_KDF_vctrl(EVP_KDF_CTX *ctx, int cmd, va_list args); +int EVP_KDF_ctrl_str(EVP_KDF_CTX *ctx, const char *type, const char *value); +size_t EVP_KDF_size(EVP_KDF_CTX *ctx); +int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen); + + +# define EVP_KDF_CTRL_SET_PASS 0x01 /* unsigned char *, size_t */ +# define EVP_KDF_CTRL_SET_SALT 0x02 /* unsigned char *, size_t */ +# define EVP_KDF_CTRL_SET_ITER 0x03 /* int */ +# define EVP_KDF_CTRL_SET_MD 0x04 /* EVP_MD * */ +# define EVP_KDF_CTRL_SET_KEY 0x05 /* unsigned char *, size_t */ +# define EVP_KDF_CTRL_SET_MAXMEM_BYTES 0x06 /* uint64_t */ +# define EVP_KDF_CTRL_SET_TLS_SECRET 0x07 /* unsigned char *, size_t */ +# define EVP_KDF_CTRL_RESET_TLS_SEED 0x08 +# define EVP_KDF_CTRL_ADD_TLS_SEED 0x09 /* unsigned char *, size_t */ +# define EVP_KDF_CTRL_RESET_HKDF_INFO 0x0a +# define EVP_KDF_CTRL_ADD_HKDF_INFO 0x0b /* unsigned char *, size_t */ +# define EVP_KDF_CTRL_SET_HKDF_MODE 0x0c /* int */ +# define EVP_KDF_CTRL_SET_SCRYPT_N 0x0d /* uint64_t */ +# define EVP_KDF_CTRL_SET_SCRYPT_R 0x0e /* uint32_t */ +# define EVP_KDF_CTRL_SET_SCRYPT_P 0x0f /* uint32_t */ + +# define EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND 0 +# define EVP_KDF_HKDF_MODE_EXTRACT_ONLY 1 +# define EVP_KDF_HKDF_MODE_EXPAND_ONLY 2 + + +/**** The legacy PKEY-based KDF API follows. ****/ # define EVP_PKEY_CTRL_TLS_MD (EVP_PKEY_ALG_CTRL) # define EVP_PKEY_CTRL_TLS_SECRET (EVP_PKEY_ALG_CTRL + 1) @@ -30,9 +70,12 @@ extern "C" { # define EVP_PKEY_CTRL_SCRYPT_P (EVP_PKEY_ALG_CTRL + 12) # define EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES (EVP_PKEY_ALG_CTRL + 13) -# define EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND 0 -# define EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY 1 -# define EVP_PKEY_HKDEF_MODE_EXPAND_ONLY 2 +# define EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND \ + EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND +# define EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY \ + EVP_KDF_HKDF_MODE_EXTRACT_ONLY +# define EVP_PKEY_HKDEF_MODE_EXPAND_ONLY \ + EVP_KDF_HKDF_MODE_EXPAND_ONLY # define EVP_PKEY_CTX_set_tls1_prf_md(pctx, md) \ EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ @@ -91,7 +134,7 @@ extern "C" { EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES, maxmem_bytes) -# ifdef __cplusplus +# ifdef __cplusplus } # endif #endif Index: openssl-1.1.1n/include/openssl/ossl_typ.h =================================================================== --- openssl-1.1.1n.orig/include/openssl/ossl_typ.h +++ openssl-1.1.1n/include/openssl/ossl_typ.h @@ -97,6 +97,8 @@ typedef struct evp_pkey_asn1_method_st E typedef struct evp_pkey_method_st EVP_PKEY_METHOD; typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; +typedef struct evp_kdf_ctx_st EVP_KDF_CTX; + typedef struct evp_Encode_Ctx_st EVP_ENCODE_CTX; typedef struct hmac_ctx_st HMAC_CTX; Index: openssl-1.1.1n/test/build.info =================================================================== --- openssl-1.1.1n.orig/test/build.info +++ openssl-1.1.1n/test/build.info @@ -44,7 +44,8 @@ INCLUDE_MAIN___test_libtestutil_OLB = /I ssl_test_ctx_test ssl_test x509aux cipherlist_test asynciotest \ bio_callback_test bio_memleak_test \ bioprinttest sslapitest dtlstest sslcorrupttest bio_enc_test \ - pkey_meth_test pkey_meth_kdf_test uitest cipherbytes_test \ + pkey_meth_test pkey_meth_kdf_test evp_kdf_test uitest \ + cipherbytes_test \ asn1_encode_test asn1_decode_test asn1_string_table_test \ x509_time_test x509_dup_cert_test x509_check_cert_pkey_test \ recordlentest drbgtest sslbuffertest \ @@ -336,6 +337,10 @@ INCLUDE_MAIN___test_libtestutil_OLB = /I INCLUDE[pkey_meth_kdf_test]=../include DEPEND[pkey_meth_kdf_test]=../libcrypto libtestutil.a + SOURCE[evp_kdf_test]=evp_kdf_test.c + INCLUDE[evp_kdf_test]=../include + DEPEND[evp_kdf_test]=../libcrypto libtestutil.a + SOURCE[x509_time_test]=x509_time_test.c INCLUDE[x509_time_test]=../include DEPEND[x509_time_test]=../libcrypto libtestutil.a Index: openssl-1.1.1n/test/evp_kdf_test.c =================================================================== --- /dev/null +++ openssl-1.1.1n/test/evp_kdf_test.c @@ -0,0 +1,237 @@ +/* + * Copyright 2018-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2018-2019, Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* Tests of the EVP_KDF_CTX APIs */ + +#include +#include + +#include +#include +#include "testutil.h" + +static int test_kdf_tls1_prf(void) +{ + int ret = 0; + EVP_KDF_CTX *kctx; + unsigned char out[16]; + + if ((kctx = EVP_KDF_CTX_new_id(EVP_KDF_TLS1_PRF)) == NULL) { + TEST_error("EVP_KDF_TLS1_PRF"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_MD"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_TLS_SECRET, + "secret", (size_t)6) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_TLS_SECRET"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_ADD_TLS_SEED, "seed", (size_t)4) <= 0) { + TEST_error("EVP_KDF_CTRL_ADD_TLS_SEED"); + goto err; + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { + TEST_error("EVP_KDF_derive"); + goto err; + } + + { + const unsigned char expected[sizeof(out)] = { + 0x8e, 0x4d, 0x93, 0x25, 0x30, 0xd7, 0x65, 0xa0, + 0xaa, 0xe9, 0x74, 0xc3, 0x04, 0x73, 0x5e, 0xcc + }; + if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) { + goto err; + } + } + ret = 1; +err: + EVP_KDF_CTX_free(kctx); + return ret; +} + +static int test_kdf_hkdf(void) +{ + int ret = 0; + EVP_KDF_CTX *kctx; + unsigned char out[10]; + + if ((kctx = EVP_KDF_CTX_new_id(EVP_KDF_HKDF)) == NULL) { + TEST_error("EVP_KDF_HKDF"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_MD"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, "salt", (size_t)4) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_SALT"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, "secret", (size_t)6) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_KEY"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_ADD_HKDF_INFO, + "label", (size_t)5) <= 0) { + TEST_error("EVP_KDF_CTRL_ADD_HKDF_INFO"); + goto err; + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { + TEST_error("EVP_KDF_derive"); + goto err; + } + + { + const unsigned char expected[sizeof(out)] = { + 0x2a, 0xc4, 0x36, 0x9f, 0x52, 0x59, 0x96, 0xf8, 0xde, 0x13 + }; + if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) { + goto err; + } + } + ret = 1; +err: + EVP_KDF_CTX_free(kctx); + return ret; +} + +static int test_kdf_pbkdf2(void) +{ + int ret = 0; + EVP_KDF_CTX *kctx; + unsigned char out[32]; + + if ((kctx = EVP_KDF_CTX_new_id(EVP_KDF_PBKDF2)) == NULL) { + TEST_error("EVP_KDF_PBKDF2"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, "password", (size_t)8) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_PASS"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, "salt", (size_t)4) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_SALT"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_ITER, 2) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_ITER"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_MD"); + goto err; + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { + TEST_error("EVP_KDF_derive"); + goto err; + } + + { + const unsigned char expected[sizeof(out)] = { + 0xae, 0x4d, 0x0c, 0x95, 0xaf, 0x6b, 0x46, 0xd3, + 0x2d, 0x0a, 0xdf, 0xf9, 0x28, 0xf0, 0x6d, 0xd0, + 0x2a, 0x30, 0x3f, 0x8e, 0xf3, 0xc2, 0x51, 0xdf, + 0xd6, 0xe2, 0xd8, 0x5a, 0x95, 0x47, 0x4c, 0x43 + }; + if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) { + goto err; + } + } + ret = 1; +err: + EVP_KDF_CTX_free(kctx); + return ret; +} + +#ifndef OPENSSL_NO_SCRYPT +static int test_kdf_scrypt(void) +{ + int ret = 0; + EVP_KDF_CTX *kctx; + unsigned char out[64]; + + if ((kctx = EVP_KDF_CTX_new_id(EVP_KDF_SCRYPT)) == NULL) { + TEST_error("EVP_KDF_SCRYPT"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, "password", (size_t)8) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_PASS"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, "NaCl", (size_t)4) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_SALT"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_N, (uint64_t)1024) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_SCRYPT_N"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_R, (uint32_t)8) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_SCRYPT_R"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_P, (uint32_t)16) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_SCRYPT_P"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAXMEM_BYTES, (uint64_t)16) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_MAXMEM_BYTES"); + goto err; + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) > 0) { + TEST_error("EVP_KDF_derive should have failed"); + goto err; + } + if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAXMEM_BYTES, + (uint64_t)(10 * 1024 * 1024)) <= 0) { + TEST_error("EVP_KDF_CTRL_SET_MAXMEM_BYTES"); + goto err; + } + if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { + TEST_error("EVP_KDF_derive"); + goto err; + } + + { + const unsigned char expected[sizeof(out)] = { + 0xfd, 0xba, 0xbe, 0x1c, 0x9d, 0x34, 0x72, 0x00, + 0x78, 0x56, 0xe7, 0x19, 0x0d, 0x01, 0xe9, 0xfe, + 0x7c, 0x6a, 0xd7, 0xcb, 0xc8, 0x23, 0x78, 0x30, + 0xe7, 0x73, 0x76, 0x63, 0x4b, 0x37, 0x31, 0x62, + 0x2e, 0xaf, 0x30, 0xd9, 0x2e, 0x22, 0xa3, 0x88, + 0x6f, 0xf1, 0x09, 0x27, 0x9d, 0x98, 0x30, 0xda, + 0xc7, 0x27, 0xaf, 0xb9, 0x4a, 0x83, 0xee, 0x6d, + 0x83, 0x60, 0xcb, 0xdf, 0xa2, 0xcc, 0x06, 0x40 + }; + if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) { + goto err; + } + } + ret = 1; +err: + EVP_KDF_CTX_free(kctx); + return ret; +} +#endif + +int setup_tests(void) +{ + ADD_TEST(test_kdf_tls1_prf); + ADD_TEST(test_kdf_hkdf); + ADD_TEST(test_kdf_pbkdf2); +#ifndef OPENSSL_NO_SCRYPT + ADD_TEST(test_kdf_scrypt); +#endif + return 1; +} Index: openssl-1.1.1n/test/evp_test.c =================================================================== --- openssl-1.1.1n.orig/test/evp_test.c +++ openssl-1.1.1n/test/evp_test.c @@ -1705,13 +1705,14 @@ static const EVP_TEST_METHOD encode_test encode_test_run, }; + /** *** KDF TESTS **/ typedef struct kdf_data_st { /* Context for this operation */ - EVP_PKEY_CTX *ctx; + EVP_KDF_CTX *ctx; /* Expected output */ unsigned char *output; size_t output_len; @@ -1738,16 +1739,11 @@ static int kdf_test_init(EVP_TEST *t, co if (!TEST_ptr(kdata = OPENSSL_zalloc(sizeof(*kdata)))) return 0; - kdata->ctx = EVP_PKEY_CTX_new_id(kdf_nid, NULL); + kdata->ctx = EVP_KDF_CTX_new_id(kdf_nid); if (kdata->ctx == NULL) { OPENSSL_free(kdata); return 0; } - if (EVP_PKEY_derive_init(kdata->ctx) <= 0) { - EVP_PKEY_CTX_free(kdata->ctx); - OPENSSL_free(kdata); - return 0; - } t->data = kdata; return 1; } @@ -1756,7 +1752,42 @@ static void kdf_test_cleanup(EVP_TEST *t { KDF_DATA *kdata = t->data; OPENSSL_free(kdata->output); - EVP_PKEY_CTX_free(kdata->ctx); + EVP_KDF_CTX_free(kdata->ctx); +} + +static int kdf_test_ctrl(EVP_TEST *t, EVP_KDF_CTX *kctx, + const char *value) +{ + int rv; + char *p, *tmpval; + + if (!TEST_ptr(tmpval = OPENSSL_strdup(value))) + return 0; + p = strchr(tmpval, ':'); + if (p != NULL) + *p++ = '\0'; + rv = EVP_KDF_ctrl_str(kctx, tmpval, p); + if (rv == -2) { + t->err = "KDF_CTRL_INVALID"; + rv = 1; + } else if (p != NULL && rv <= 0) { + /* If p has an OID and lookup fails assume disabled algorithm */ + int nid = OBJ_sn2nid(p); + + if (nid == NID_undef) + nid = OBJ_ln2nid(p); + if (nid != NID_undef + && EVP_get_digestbynid(nid) == NULL + && EVP_get_cipherbynid(nid) == NULL) { + t->skip = 1; + rv = 1; + } else { + t->err = "KDF_CTRL_ERROR"; + rv = 1; + } + } + OPENSSL_free(tmpval); + return rv > 0; } static int kdf_test_parse(EVP_TEST *t, @@ -1767,7 +1798,7 @@ static int kdf_test_parse(EVP_TEST *t, if (strcmp(keyword, "Output") == 0) return parse_bin(value, &kdata->output, &kdata->output_len); if (strncmp(keyword, "Ctrl", 4) == 0) - return pkey_test_ctrl(t, kdata->ctx, value); + return kdf_test_ctrl(t, kdata->ctx, value); return 0; } @@ -1781,7 +1812,7 @@ static int kdf_test_run(EVP_TEST *t) t->err = "INTERNAL_ERROR"; goto err; } - if (EVP_PKEY_derive(expected->ctx, got, &got_len) <= 0) { + if (EVP_KDF_derive(expected->ctx, got, got_len) <= 0) { t->err = "KDF_DERIVE_ERROR"; goto err; } @@ -1807,6 +1838,106 @@ static const EVP_TEST_METHOD kdf_test_me /** +*** PKEY KDF TESTS +**/ + +typedef struct pkey_kdf_data_st { + /* Context for this operation */ + EVP_PKEY_CTX *ctx; + /* Expected output */ + unsigned char *output; + size_t output_len; +} PKEY_KDF_DATA; + +/* + * Perform public key operation setup: lookup key, allocated ctx and call + * the appropriate initialisation function + */ +static int pkey_kdf_test_init(EVP_TEST *t, const char *name) +{ + PKEY_KDF_DATA *kdata; + int kdf_nid = OBJ_sn2nid(name); + +#ifdef OPENSSL_NO_SCRYPT + if (strcmp(name, "scrypt") == 0) { + t->skip = 1; + return 1; + } +#endif + + if (kdf_nid == NID_undef) + kdf_nid = OBJ_ln2nid(name); + + if (!TEST_ptr(kdata = OPENSSL_zalloc(sizeof(*kdata)))) + return 0; + kdata->ctx = EVP_PKEY_CTX_new_id(kdf_nid, NULL); + if (kdata->ctx == NULL) { + OPENSSL_free(kdata); + return 0; + } + if (EVP_PKEY_derive_init(kdata->ctx) <= 0) { + EVP_PKEY_CTX_free(kdata->ctx); + OPENSSL_free(kdata); + return 0; + } + t->data = kdata; + return 1; +} + +static void pkey_kdf_test_cleanup(EVP_TEST *t) +{ + PKEY_KDF_DATA *kdata = t->data; + OPENSSL_free(kdata->output); + EVP_PKEY_CTX_free(kdata->ctx); +} + +static int pkey_kdf_test_parse(EVP_TEST *t, + const char *keyword, const char *value) +{ + PKEY_KDF_DATA *kdata = t->data; + + if (strcmp(keyword, "Output") == 0) + return parse_bin(value, &kdata->output, &kdata->output_len); + if (strncmp(keyword, "Ctrl", 4) == 0) + return pkey_test_ctrl(t, kdata->ctx, value); + return 0; +} + +static int pkey_kdf_test_run(EVP_TEST *t) +{ + PKEY_KDF_DATA *expected = t->data; + unsigned char *got = NULL; + size_t got_len = expected->output_len; + + if (!TEST_ptr(got = OPENSSL_malloc(got_len))) { + t->err = "INTERNAL_ERROR"; + goto err; + } + if (EVP_PKEY_derive(expected->ctx, got, &got_len) <= 0) { + t->err = "KDF_DERIVE_ERROR"; + goto err; + } + if (!TEST_mem_eq(expected->output, expected->output_len, got, got_len)) { + t->err = "KDF_MISMATCH"; + goto err; + } + t->err = NULL; + + err: + OPENSSL_free(got); + return 1; +} + +static const EVP_TEST_METHOD pkey_kdf_test_method = { + "PKEYKDF", + pkey_kdf_test_init, + pkey_kdf_test_cleanup, + pkey_kdf_test_parse, + pkey_kdf_test_run +}; + + +/** *** KEYPAIR TESTS **/ @@ -2310,6 +2441,7 @@ static const EVP_TEST_METHOD *evp_test_l &digestverify_test_method, &encode_test_method, &kdf_test_method, + &pkey_kdf_test_method, &keypair_test_method, &keygen_test_method, &mac_test_method, Index: openssl-1.1.1n/test/pkey_meth_kdf_test.c =================================================================== --- openssl-1.1.1n.orig/test/pkey_meth_kdf_test.c +++ openssl-1.1.1n/test/pkey_meth_kdf_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -18,30 +18,34 @@ static int test_kdf_tls1_prf(void) { + int ret = 0; EVP_PKEY_CTX *pctx; unsigned char out[16]; size_t outlen = sizeof(out); - pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL); + if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL)) == NULL) { + TEST_error("EVP_PKEY_TLS1_PRF"); + goto err; + } if (EVP_PKEY_derive_init(pctx) <= 0) { TEST_error("EVP_PKEY_derive_init"); - return 0; + goto err; } if (EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_sha256()) <= 0) { TEST_error("EVP_PKEY_CTX_set_tls1_prf_md"); - return 0; + goto err; } if (EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, "secret", 6) <= 0) { TEST_error("EVP_PKEY_CTX_set1_tls1_prf_secret"); - return 0; + goto err; } if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, "seed", 4) <= 0) { TEST_error("EVP_PKEY_CTX_add1_tls1_prf_seed"); - return 0; + goto err; } if (EVP_PKEY_derive(pctx, out, &outlen) <= 0) { TEST_error("EVP_PKEY_derive"); - return 0; + goto err; } { @@ -50,43 +54,49 @@ static int test_kdf_tls1_prf(void) 0xaa, 0xe9, 0x74, 0xc3, 0x04, 0x73, 0x5e, 0xcc }; if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) { - return 0; + goto err; } } + ret = 1; +err: EVP_PKEY_CTX_free(pctx); - return 1; + return ret; } static int test_kdf_hkdf(void) { + int ret = 0; EVP_PKEY_CTX *pctx; unsigned char out[10]; size_t outlen = sizeof(out); - pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); + if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL)) == NULL) { + TEST_error("EVP_PKEY_HKDF"); + goto err; + } if (EVP_PKEY_derive_init(pctx) <= 0) { TEST_error("EVP_PKEY_derive_init"); - return 0; + goto err; } if (EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha256()) <= 0) { TEST_error("EVP_PKEY_CTX_set_hkdf_md"); - return 0; + goto err; } if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, "salt", 4) <= 0) { TEST_error("EVP_PKEY_CTX_set1_hkdf_salt"); - return 0; + goto err; } if (EVP_PKEY_CTX_set1_hkdf_key(pctx, "secret", 6) <= 0) { TEST_error("EVP_PKEY_CTX_set1_hkdf_key"); - return 0; + goto err; } if (EVP_PKEY_CTX_add1_hkdf_info(pctx, "label", 5) <= 0) { TEST_error("EVP_PKEY_CTX_set1_hkdf_info"); - return 0; + goto err; } if (EVP_PKEY_derive(pctx, out, &outlen) <= 0) { TEST_error("EVP_PKEY_derive"); - return 0; + goto err; } { @@ -94,60 +104,66 @@ static int test_kdf_hkdf(void) 0x2a, 0xc4, 0x36, 0x9f, 0x52, 0x59, 0x96, 0xf8, 0xde, 0x13 }; if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) { - return 0; + goto err; } } + ret = 1; +err: EVP_PKEY_CTX_free(pctx); - return 1; + return ret; } #ifndef OPENSSL_NO_SCRYPT static int test_kdf_scrypt(void) { + int ret = 0; EVP_PKEY_CTX *pctx; unsigned char out[64]; size_t outlen = sizeof(out); - pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SCRYPT, NULL); + if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SCRYPT, NULL)) == NULL) { + TEST_error("EVP_PKEY_SCRYPT"); + goto err; + } if (EVP_PKEY_derive_init(pctx) <= 0) { TEST_error("EVP_PKEY_derive_init"); - return 0; + goto err; } if (EVP_PKEY_CTX_set1_pbe_pass(pctx, "password", 8) <= 0) { TEST_error("EVP_PKEY_CTX_set1_pbe_pass"); - return 0; + goto err; } if (EVP_PKEY_CTX_set1_scrypt_salt(pctx, "NaCl", 4) <= 0) { TEST_error("EVP_PKEY_CTX_set1_scrypt_salt"); - return 0; + goto err; } if (EVP_PKEY_CTX_set_scrypt_N(pctx, 1024) <= 0) { TEST_error("EVP_PKEY_CTX_set_scrypt_N"); - return 0; + goto err; } if (EVP_PKEY_CTX_set_scrypt_r(pctx, 8) <= 0) { TEST_error("EVP_PKEY_CTX_set_scrypt_r"); - return 0; + goto err; } if (EVP_PKEY_CTX_set_scrypt_p(pctx, 16) <= 0) { TEST_error("EVP_PKEY_CTX_set_scrypt_p"); - return 0; + goto err; } if (EVP_PKEY_CTX_set_scrypt_maxmem_bytes(pctx, 16) <= 0) { TEST_error("EVP_PKEY_CTX_set_maxmem_bytes"); - return 0; + goto err; } if (EVP_PKEY_derive(pctx, out, &outlen) > 0) { TEST_error("EVP_PKEY_derive should have failed"); - return 0; + goto err; } if (EVP_PKEY_CTX_set_scrypt_maxmem_bytes(pctx, 10 * 1024 * 1024) <= 0) { TEST_error("EVP_PKEY_CTX_set_maxmem_bytes"); - return 0; + goto err; } if (EVP_PKEY_derive(pctx, out, &outlen) <= 0) { TEST_error("EVP_PKEY_derive"); - return 0; + goto err; } { @@ -162,11 +178,13 @@ static int test_kdf_scrypt(void) 0x83, 0x60, 0xcb, 0xdf, 0xa2, 0xcc, 0x06, 0x40 }; if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) { - return 0; + goto err; } } + ret = 1; +err: EVP_PKEY_CTX_free(pctx); - return 1; + return ret; } #endif Index: openssl-1.1.1n/test/recipes/30-test_evp_data/evpkdf.txt =================================================================== --- openssl-1.1.1n.orig/test/recipes/30-test_evp_data/evpkdf.txt +++ openssl-1.1.1n/test/recipes/30-test_evp_data/evpkdf.txt @@ -15,7 +15,7 @@ Title = TLS1 PRF tests (from NIST test vectors) KDF=TLS1-PRF -Ctrl.md = md:MD5-SHA1 +Ctrl.digest = digest:MD5-SHA1 Ctrl.Secret = hexsecret:bded7fa5c1699c010be23dd06ada3a48349f21e5f86263d512c0c5cc379f0e780ec55d9844b2f1db02a96453513568d0 Ctrl.label = seed:master secret Ctrl.client_random = hexseed:e5acaf549cd25c22d964c0d930fa4b5261d2507fad84c33715b7b9a864020693 @@ -23,7 +23,7 @@ Ctrl.server_random = hexseed:135e4d557fd Output = 2f6962dfbc744c4b2138bb6b3d33054c5ecc14f24851d9896395a44ab3964efc2090c5bf51a0891209f46c1e1e998f62 KDF=TLS1-PRF -Ctrl.md = md:MD5-SHA1 +Ctrl.digest = digest:MD5-SHA1 Ctrl.Secret = hexsecret:2f6962dfbc744c4b2138bb6b3d33054c5ecc14f24851d9896395a44ab3964efc2090c5bf51a0891209f46c1e1e998f62 Ctrl.label = seed:key expansion Ctrl.server_random = hexseed:67267e650eb32444119d222a368c191af3082888dc35afe8368e638c828874be @@ -31,7 +31,7 @@ Ctrl.client_random = hexseed:d58a7b1cd4f Output = 3088825988e77fce68d19f756e18e43eb7fe672433504feaf99b3c503d9091b164f166db301d70c9fc0870b4a94563907bee1a61fb786cb717576890bcc51cb9ead97e01d0a2fea99c953377b195205ff07b369589178796edc963fd80fdbe518a2fc1c35c18ae8d KDF=TLS1-PRF -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.Secret = hexsecret:f8938ecc9edebc5030c0c6a441e213cd24e6f770a50dda07876f8d55da062bcadb386b411fd4fe4313a604fce6c17fbc Ctrl.label = seed:master secret Ctrl.client_random = hexseed:36c129d01a3200894b9179faac589d9835d58775f9b5ea3587cb8fd0364cae8c @@ -39,7 +39,7 @@ Ctrl.server_random = hexseed:f6c9575ed7d Output = 202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf KDF=TLS1-PRF -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.Secret = hexsecret:202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf Ctrl.label = seed:key expansion Ctrl.server_random = hexseed:ae6c806f8ad4d80784549dff28a4b58fd837681a51d928c3e30ee5ff14f39868 @@ -48,7 +48,7 @@ Output = d06139889fffac1e3a71865f504aa5d # As above but use long name for KDF KDF=tls1-prf -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.Secret = hexsecret:202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf Ctrl.label = seed:key expansion Ctrl.server_random = hexseed:ae6c806f8ad4d80784549dff28a4b58fd837681a51d928c3e30ee5ff14f39868 @@ -64,7 +64,7 @@ Result = KDF_DERIVE_ERROR # Missing secret. KDF=TLS1-PRF -Ctrl.md = md:MD5-SHA1 +Ctrl.digest = digest:MD5-SHA1 Ctrl.Seed = hexseed:02 Output = 03 Result = KDF_DERIVE_ERROR @@ -72,7 +72,7 @@ Result = KDF_DERIVE_ERROR Title = HKDF tests (from RFC5869 test vectors) KDF = HKDF -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b Ctrl.salt = hexsalt:000102030405060708090a0b0c Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9 @@ -80,20 +80,20 @@ Output = 3cb25f25faacd57a90434f64d0362f2 KDF = HKDF Ctrl.mode = mode:EXTRACT_ONLY -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b Ctrl.salt = hexsalt:000102030405060708090a0b0c Output = 077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5 KDF = HKDF Ctrl.mode = mode:EXPAND_ONLY -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.IKM = hexkey:077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5 Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9 Output = 3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865 KDF = HKDF -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.IKM = hexkey:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f Ctrl.salt = hexsalt:606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf Ctrl.info = hexinfo:b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff @@ -101,20 +101,20 @@ Output = b11e398dc80327a1c8e7f78c596a493 KDF = HKDF Ctrl.mode = mode:EXTRACT_ONLY -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.IKM = hexkey:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f Ctrl.salt = hexsalt:606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf Output = 06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244 KDF = HKDF Ctrl.mode = mode:EXPAND_ONLY -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.IKM = hexkey:06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244 Ctrl.info = hexinfo:b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff Output = b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87 KDF = HKDF -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b Ctrl.salt = salt: Ctrl.info = info: @@ -122,7 +122,7 @@ Output = 8da4e775a563c18f715f802a063c5a3 KDF = HKDF Ctrl.mode = mode:EXTRACT_ONLY -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b Ctrl.salt = salt: Ctrl.info = info: @@ -130,13 +130,13 @@ Output = 19ef24a32c717b167f33a91d6f648bd KDF = HKDF Ctrl.mode = mode:EXPAND_ONLY -Ctrl.md = md:SHA256 +Ctrl.digest = digest:SHA256 Ctrl.IKM = hexkey:19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04 Ctrl.info = info: Output = 8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8 KDF = HKDF -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b Ctrl.salt = hexsalt:000102030405060708090a0b0c Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9 @@ -144,20 +144,20 @@ Output = 085a01ea1b10f36933068b56efa5ad8 KDF = HKDF Ctrl.mode = mode:EXTRACT_ONLY -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b Ctrl.salt = hexsalt:000102030405060708090a0b0c Output = 9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243 KDF = HKDF Ctrl.mode = mode:EXPAND_ONLY -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243 Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9 Output = 085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896 KDF = HKDF -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f Ctrl.salt = hexsalt:606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf Ctrl.info = hexinfo:b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff @@ -165,20 +165,20 @@ Output = 0bd770a74d1160f7c9f12cd5912a06e KDF = HKDF Ctrl.mode = mode:EXTRACT_ONLY -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f Ctrl.salt = hexsalt:606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf Output = 8adae09a2a307059478d309b26c4115a224cfaf6 KDF = HKDF Ctrl.mode = mode:EXPAND_ONLY -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:8adae09a2a307059478d309b26c4115a224cfaf6 Ctrl.info = hexinfo:b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff Output = 0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4 KDF = HKDF -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b Ctrl.salt = salt: Ctrl.info = info: @@ -186,20 +186,20 @@ Output = 0ac1af7002b3d761d1e55298da9d050 KDF = HKDF Ctrl.mode = mode:EXTRACT_ONLY -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b Ctrl.salt = salt: Output = da8c8a73c7fa77288ec6f5e7c297786aa0d32d01 KDF = HKDF Ctrl.mode = mode:EXPAND_ONLY -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:da8c8a73c7fa77288ec6f5e7c297786aa0d32d01 Ctrl.info = info: Output = 0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918 KDF = HKDF -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c Ctrl.salt = salt: Ctrl.info = info: @@ -207,14 +207,14 @@ Output = 2c91117204d745f3500d636a62f64f0 KDF = HKDF Ctrl.mode = mode:EXTRACT_ONLY -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c Ctrl.salt = salt: Output = 2adccada18779e7c2077ad2eb19d3f3e731385dd KDF = HKDF Ctrl.mode = mode:EXPAND_ONLY -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:2adccada18779e7c2077ad2eb19d3f3e731385dd Ctrl.info = info: Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48 @@ -227,27 +227,27 @@ Output = 00 Result = KDF_DERIVE_ERROR KDF = HKDF -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.salt = salt: Ctrl.info = info: Output = 00 Result = KDF_DERIVE_ERROR KDF = HKDF -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c Ctrl.info = info: Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48 KDF = HKDF -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c Ctrl.salt = salt: Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48 KDF = HKDF Ctrl.mode = mode:EXTRACT_AND_EXPAND -Ctrl.md = md:SHA1 +Ctrl.digest = digest:SHA1 Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c Ctrl.salt = salt: Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48 @@ -303,3 +303,133 @@ Ctrl.r = r:8 Ctrl.p = p:1 Result = KDF_DERIVE_ERROR +Title = PBKDF2 tests + +KDF = PBKDF2 +Ctrl.pass = pass:password +Ctrl.salt = salt:salt +Ctrl.iter = iter:1 +Ctrl.digest = digest:sha1 +Output = 0c60c80f961f0e71f3a9b524af6012062fe037a6 + +KDF = PBKDF2 +Ctrl.pass = pass:password +Ctrl.salt = salt:salt +Ctrl.iter = iter:1 +Ctrl.digest = digest:sha256 +Output = 120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b + +KDF = PBKDF2 +Ctrl.pass = pass:password +Ctrl.salt = salt:salt +Ctrl.iter = iter:1 +Ctrl.digest = digest:sha512 +Output = 867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252c02d470a285a0501bad999bfe943c08f050235d7d68b1da55e63f73b60a57fce + +KDF = PBKDF2 +Ctrl.pass = pass:password +Ctrl.salt = salt:salt +Ctrl.iter = iter:2 +Ctrl.digest = digest:sha1 +Output = ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957 + +KDF = PBKDF2 +Ctrl.pass = pass:password +Ctrl.salt = salt:salt +Ctrl.iter = iter:2 +Ctrl.digest = digest:sha256 +Output = ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43 + +KDF = PBKDF2 +Ctrl.pass = pass:password +Ctrl.salt = salt:salt +Ctrl.iter = iter:2 +Ctrl.digest = digest:sha512 +Output = e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f0040713f18aefdb866d53cf76cab2868a39b9f7840edce4fef5a82be67335c77a6068e04112754f27ccf4e + +KDF = PBKDF2 +Ctrl.pass = pass:password +Ctrl.salt = salt:salt +Ctrl.iter = iter:4096 +Ctrl.digest = digest:sha1 +Output = 4b007901b765489abead49d926f721d065a429c1 + +KDF = PBKDF2 +Ctrl.pass = pass:password +Ctrl.salt = salt:salt +Ctrl.iter = iter:4096 +Ctrl.digest = digest:sha256 +Output = c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a + +KDF = PBKDF2 +Ctrl.pass = pass:password +Ctrl.salt = salt:salt +Ctrl.iter = iter:4096 +Ctrl.digest = digest:sha512 +Output = d197b1b33db0143e018b12f3d1d1479e6cdebdcc97c5c0f87f6902e072f457b5143f30602641b3d55cd335988cb36b84376060ecd532e039b742a239434af2d5 + +KDF = PBKDF2 +Ctrl.pass = pass:passwordPASSWORDpassword +Ctrl.salt = salt:saltSALTsaltSALTsaltSALTsaltSALTsalt +Ctrl.iter = iter:4096 +Ctrl.digest = digest:sha1 +Output = 3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038 + +KDF = PBKDF2 +Ctrl.pass = pass:passwordPASSWORDpassword +Ctrl.salt = salt:saltSALTsaltSALTsaltSALTsaltSALTsalt +Ctrl.iter = iter:4096 +Ctrl.digest = digest:sha256 +Output = 348c89dbcbd32b2f32d814b8116e84cf2b17347ebc1800181c4e2a1fb8dd53e1c635518c7dac47e9 + +KDF = PBKDF2 +Ctrl.pass = pass:passwordPASSWORDpassword +Ctrl.salt = salt:saltSALTsaltSALTsaltSALTsaltSALTsalt +Ctrl.iter = iter:4096 +Ctrl.digest = digest:sha512 +Output = 8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b868c005174dc4ee71115b59f9e60cd9532fa33e0f75aefe30225c583a186cd82bd4daea9724a3d3b8 + +KDF = PBKDF2 +Ctrl.hexpass = hexpass:7061737300776f7264 +Ctrl.hexsalt = hexsalt:7361006c74 +Ctrl.iter = iter:4096 +Ctrl.digest = digest:sha1 +Output = 56fa6aa75548099dcc37d7f03425e0c3 + +KDF = PBKDF2 +Ctrl.hexpass = hexpass:7061737300776f7264 +Ctrl.hexsalt = hexsalt:7361006c74 +Ctrl.iter = iter:4096 +Ctrl.digest = digest:sha256 +Output = 89b69d0516f829893c696226650a8687 + +KDF = PBKDF2 +Ctrl.hexpass = hexpass:7061737300776f7264 +Ctrl.hexsalt = hexsalt:7361006c74 +Ctrl.iter = iter:4096 +Ctrl.digest = digest:sha512 +Output = 9d9e9c4cd21fe4be24d5b8244c759665 + +Title = PBKDF2 tests for empty inputs + +KDF = PBKDF2 +Ctrl.pass = pass: +Ctrl.salt = salt:salt +Ctrl.iter = iter:1 +Ctrl.digest = digest:sha1 +Output = a33dddc30478185515311f8752895d36ea4363a2 + +KDF = PBKDF2 +Ctrl.pass = pass: +Ctrl.salt = salt:salt +Ctrl.iter = iter:1 +Ctrl.digest = digest:sha256 +Output = f135c27993baf98773c5cdb40a5706ce6a345cde + +KDF = PBKDF2 +Ctrl.pass = pass: +Ctrl.salt = salt:salt +Ctrl.iter = iter:1 +Ctrl.digest = digest:sha512 +Output = 00ef42cdbfc98d29db20976608e455567fdddf14 + Index: openssl-1.1.1n/test/recipes/30-test_evp_data/evppkey_kdf.txt =================================================================== --- /dev/null +++ openssl-1.1.1n/test/recipes/30-test_evp_data/evppkey_kdf.txt @@ -0,0 +1,305 @@ +# +# Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# Tests start with one of these keywords +# Cipher Decrypt Derive Digest Encoding KDF PKEYKDF MAC PBE +# PrivPubKeyPair Sign Verify VerifyRecover +# and continue until a blank line. Lines starting with a pound sign, +# like this prolog, are ignored. + +Title = TLS1 PRF tests (from NIST test vectors) + +PKEYKDF=TLS1-PRF +Ctrl.md = md:MD5-SHA1 +Ctrl.Secret = hexsecret:bded7fa5c1699c010be23dd06ada3a48349f21e5f86263d512c0c5cc379f0e780ec55d9844b2f1db02a96453513568d0 +Ctrl.label = seed:master secret +Ctrl.client_random = hexseed:e5acaf549cd25c22d964c0d930fa4b5261d2507fad84c33715b7b9a864020693 +Ctrl.server_random = hexseed:135e4d557fdf3aa6406d82975d5c606a9734c9334b42136e96990fbd5358cdb2 +Output = 2f6962dfbc744c4b2138bb6b3d33054c5ecc14f24851d9896395a44ab3964efc2090c5bf51a0891209f46c1e1e998f62 + +PKEYKDF=TLS1-PRF +Ctrl.md = md:MD5-SHA1 +Ctrl.Secret = hexsecret:2f6962dfbc744c4b2138bb6b3d33054c5ecc14f24851d9896395a44ab3964efc2090c5bf51a0891209f46c1e1e998f62 +Ctrl.label = seed:key expansion +Ctrl.server_random = hexseed:67267e650eb32444119d222a368c191af3082888dc35afe8368e638c828874be +Ctrl.client_random = hexseed:d58a7b1cd4fedaa232159df652ce188f9d997e061b9bf48e83b62990440931f6 +Output = 3088825988e77fce68d19f756e18e43eb7fe672433504feaf99b3c503d9091b164f166db301d70c9fc0870b4a94563907bee1a61fb786cb717576890bcc51cb9ead97e01d0a2fea99c953377b195205ff07b369589178796edc963fd80fdbe518a2fc1c35c18ae8d + +PKEYKDF=TLS1-PRF +Ctrl.md = md:SHA256 +Ctrl.Secret = hexsecret:f8938ecc9edebc5030c0c6a441e213cd24e6f770a50dda07876f8d55da062bcadb386b411fd4fe4313a604fce6c17fbc +Ctrl.label = seed:master secret +Ctrl.client_random = hexseed:36c129d01a3200894b9179faac589d9835d58775f9b5ea3587cb8fd0364cae8c +Ctrl.server_random = hexseed:f6c9575ed7ddd73e1f7d16eca115415812a43c2b747daaaae043abfb50053fce +Output = 202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf + +PKEYKDF=TLS1-PRF +Ctrl.md = md:SHA256 +Ctrl.Secret = hexsecret:202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf +Ctrl.label = seed:key expansion +Ctrl.server_random = hexseed:ae6c806f8ad4d80784549dff28a4b58fd837681a51d928c3e30ee5ff14f39868 +Ctrl.client_random = hexseed:62e1fd91f23f558a605f28478c58cf72637b89784d959df7e946d3f07bd1b616 +Output = d06139889fffac1e3a71865f504aa5d0d2a2e89506c6f2279b670c3e1b74f531016a2530c51a3a0f7e1d6590d0f0566b2f387f8d11fd4f731cdd572d2eae927f6f2f81410b25e6960be68985add6c38445ad9f8c64bf8068bf9a6679485d966f1ad6f68b43495b10a683755ea2b858d70ccac7ec8b053c6bd41ca299d4e51928 + +# As above but use long name for KDF +PKEYKDF=tls1-prf +Ctrl.md = md:SHA256 +Ctrl.Secret = hexsecret:202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf +Ctrl.label = seed:key expansion +Ctrl.server_random = hexseed:ae6c806f8ad4d80784549dff28a4b58fd837681a51d928c3e30ee5ff14f39868 +Ctrl.client_random = hexseed:62e1fd91f23f558a605f28478c58cf72637b89784d959df7e946d3f07bd1b616 +Output = d06139889fffac1e3a71865f504aa5d0d2a2e89506c6f2279b670c3e1b74f531016a2530c51a3a0f7e1d6590d0f0566b2f387f8d11fd4f731cdd572d2eae927f6f2f81410b25e6960be68985add6c38445ad9f8c64bf8068bf9a6679485d966f1ad6f68b43495b10a683755ea2b858d70ccac7ec8b053c6bd41ca299d4e51928 + +# Missing digest. +PKEYKDF=TLS1-PRF +Ctrl.Secret = hexsecret:01 +Ctrl.Seed = hexseed:02 +Output = 03 +Result = KDF_DERIVE_ERROR + +# Missing secret. +PKEYKDF=TLS1-PRF +Ctrl.md = md:MD5-SHA1 +Ctrl.Seed = hexseed:02 +Output = 03 +Result = KDF_DERIVE_ERROR + +Title = HKDF tests (from RFC5869 test vectors) + +PKEYKDF = HKDF +Ctrl.md = md:SHA256 +Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b +Ctrl.salt = hexsalt:000102030405060708090a0b0c +Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9 +Output = 3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXTRACT_ONLY +Ctrl.md = md:SHA256 +Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b +Ctrl.salt = hexsalt:000102030405060708090a0b0c +Output = 077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXPAND_ONLY +Ctrl.md = md:SHA256 +Ctrl.IKM = hexkey:077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5 +Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9 +Output = 3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865 + +PKEYKDF = HKDF +Ctrl.md = md:SHA256 +Ctrl.IKM = hexkey:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f +Ctrl.salt = hexsalt:606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf +Ctrl.info = hexinfo:b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff +Output = b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXTRACT_ONLY +Ctrl.md = md:SHA256 +Ctrl.IKM = hexkey:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f +Ctrl.salt = hexsalt:606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf +Output = 06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXPAND_ONLY +Ctrl.md = md:SHA256 +Ctrl.IKM = hexkey:06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244 +Ctrl.info = hexinfo:b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff +Output = b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87 + +PKEYKDF = HKDF +Ctrl.md = md:SHA256 +Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b +Ctrl.salt = salt: +Ctrl.info = info: +Output = 8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXTRACT_ONLY +Ctrl.md = md:SHA256 +Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b +Ctrl.salt = salt: +Ctrl.info = info: +Output = 19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXPAND_ONLY +Ctrl.md = md:SHA256 +Ctrl.IKM = hexkey:19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04 +Ctrl.info = info: +Output = 8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8 + +PKEYKDF = HKDF +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b +Ctrl.salt = hexsalt:000102030405060708090a0b0c +Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9 +Output = 085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXTRACT_ONLY +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b +Ctrl.salt = hexsalt:000102030405060708090a0b0c +Output = 9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXPAND_ONLY +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243 +Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9 +Output = 085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896 + +PKEYKDF = HKDF +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f +Ctrl.salt = hexsalt:606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf +Ctrl.info = hexinfo:b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff +Output = 0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXTRACT_ONLY +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f +Ctrl.salt = hexsalt:606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf +Output = 8adae09a2a307059478d309b26c4115a224cfaf6 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXPAND_ONLY +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:8adae09a2a307059478d309b26c4115a224cfaf6 +Ctrl.info = hexinfo:b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff +Output = 0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4 + +PKEYKDF = HKDF +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b +Ctrl.salt = salt: +Ctrl.info = info: +Output = 0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXTRACT_ONLY +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b +Ctrl.salt = salt: +Output = da8c8a73c7fa77288ec6f5e7c297786aa0d32d01 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXPAND_ONLY +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:da8c8a73c7fa77288ec6f5e7c297786aa0d32d01 +Ctrl.info = info: +Output = 0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918 + +PKEYKDF = HKDF +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c +Ctrl.salt = salt: +Ctrl.info = info: +Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXTRACT_ONLY +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c +Ctrl.salt = salt: +Output = 2adccada18779e7c2077ad2eb19d3f3e731385dd + +PKEYKDF = HKDF +Ctrl.mode = mode:EXPAND_ONLY +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:2adccada18779e7c2077ad2eb19d3f3e731385dd +Ctrl.info = info: +Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48 + +PKEYKDF = HKDF +Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c +Ctrl.salt = salt: +Ctrl.info = info: +Output = 00 +Result = KDF_DERIVE_ERROR + +PKEYKDF = HKDF +Ctrl.md = md:SHA1 +Ctrl.salt = salt: +Ctrl.info = info: +Output = 00 +Result = KDF_DERIVE_ERROR + +PKEYKDF = HKDF +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c +Ctrl.info = info: +Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48 + +PKEYKDF = HKDF +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c +Ctrl.salt = salt: +Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48 + +PKEYKDF = HKDF +Ctrl.mode = mode:EXTRACT_AND_EXPAND +Ctrl.md = md:SHA1 +Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c +Ctrl.salt = salt: +Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48 + +Title = id-scrypt tests (from draft-josefsson-id-scrypt-kdf-03 and others) + +PKEYKDF = scrypt +Ctrl.pass = pass: +Ctrl.salt = salt: +Ctrl.N = N:16 +Ctrl.r = r:1 +Ctrl.p = p:1 +Output = 77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906 + +PKEYKDF = scrypt +Ctrl.pass = pass:password +Ctrl.salt = salt:NaCl +Ctrl.N = N:1024 +Ctrl.r = r:8 +Ctrl.p = p:16 +Output = fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640 + +PKEYKDF = scrypt +Ctrl.hexpass = hexpass:70617373776f7264 +Ctrl.salt = salt:NaCl +Ctrl.N = N:1024 +Ctrl.r = r:8 +Ctrl.p = p:16 +Output = fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640 + +PKEYKDF = scrypt +Ctrl.pass = pass:password +Ctrl.hexsalt = hexsalt:4e61436c +Ctrl.N = N:1024 +Ctrl.r = r:8 +Ctrl.p = p:16 +Output = fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640 + +PKEYKDF = scrypt +Ctrl.pass = pass:pleaseletmein +Ctrl.salt = salt:SodiumChloride +Ctrl.N = N:16384 +Ctrl.r = r:8 +Ctrl.p = p:1 +Output = 7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887 + +# Out of memory +PKEYKDF = scrypt +Ctrl.pass = pass:pleaseletmein +Ctrl.salt = salt:SodiumChloride +Ctrl.N = N:1048576 +Ctrl.r = r:8 +Ctrl.p = p:1 +Result = INTERNAL_ERROR + Index: openssl-1.1.1n/test/recipes/30-test_evp_kdf.t =================================================================== --- /dev/null +++ openssl-1.1.1n/test/recipes/30-test_evp_kdf.t @@ -0,0 +1,13 @@ +#! /usr/bin/env perl +# Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. +# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + + +use OpenSSL::Test::Simple; + +simple_test("test_evp_kdf", "evp_kdf_test"); Index: openssl-1.1.1n/test/recipes/30-test_evp.t =================================================================== --- openssl-1.1.1n.orig/test/recipes/30-test_evp.t +++ openssl-1.1.1n/test/recipes/30-test_evp.t @@ -15,7 +15,7 @@ use OpenSSL::Test qw/:DEFAULT data_file/ setup("test_evp"); my @files = ( "evpciph.txt", "evpdigest.txt", "evpencod.txt", "evpkdf.txt", - "evpmac.txt", "evppbe.txt", "evppkey.txt", "evppkey_ecc.txt", + "evppkey_kdf.txt", "evpmac.txt", "evppbe.txt", "evppkey.txt", "evppkey_ecc.txt", "evpcase.txt", "evpccmcavs.txt" ); plan tests => scalar(@files); Index: openssl-1.1.1n/util/libcrypto.num =================================================================== --- openssl-1.1.1n.orig/util/libcrypto.num +++ openssl-1.1.1n/util/libcrypto.num @@ -4626,3 +4626,11 @@ FIPS_drbg_get_strength FIPS_rand_strength 6380 1_1_0g EXIST::FUNCTION: FIPS_drbg_get_blocklength 6381 1_1_0g EXIST::FUNCTION: FIPS_drbg_init 6382 1_1_0g EXIST::FUNCTION: +EVP_KDF_CTX_new_id 6590 1_1_1d EXIST::FUNCTION: +EVP_KDF_CTX_free 6591 1_1_1d EXIST::FUNCTION: +EVP_KDF_reset 6592 1_1_1d EXIST::FUNCTION: +EVP_KDF_ctrl 6593 1_1_1d EXIST::FUNCTION: +EVP_KDF_vctrl 6594 1_1_1d EXIST::FUNCTION: +EVP_KDF_ctrl_str 6595 1_1_1d EXIST::FUNCTION: +EVP_KDF_size 6596 1_1_1d EXIST::FUNCTION: +EVP_KDF_derive 6597 1_1_1d EXIST::FUNCTION: Index: openssl-1.1.1n/util/private.num =================================================================== --- openssl-1.1.1n.orig/util/private.num +++ openssl-1.1.1n/util/private.num @@ -22,6 +22,7 @@ CRYPTO_EX_dup CRYPTO_EX_free datatype CRYPTO_EX_new datatype DTLS_timer_cb datatype +EVP_KDF_CTX datatype EVP_PKEY_gen_cb datatype EVP_PKEY_METHOD datatype EVP_PKEY_ASN1_METHOD datatype Index: openssl-1.1.1n/crypto/evp/e_chacha20_poly1305.c =================================================================== --- openssl-1.1.1n.orig/crypto/evp/e_chacha20_poly1305.c +++ openssl-1.1.1n/crypto/evp/e_chacha20_poly1305.c @@ -14,8 +14,8 @@ # include # include -# include "evp_local.h" # include "crypto/evp.h" +# include "evp_local.h" # include "crypto/chacha.h" typedef struct { Index: openssl-1.1.1n/crypto/evp/encode.c =================================================================== --- openssl-1.1.1n.orig/crypto/evp/encode.c +++ openssl-1.1.1n/crypto/evp/encode.c @@ -11,8 +11,8 @@ #include #include "internal/cryptlib.h" #include -#include "evp_local.h" #include "crypto/evp.h" +#include "evp_local.h" static unsigned char conv_ascii2bin(unsigned char a, const unsigned char *table);