1 /* 2 * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <openssl/crypto.h> 11 #include <openssl/kdf.h> 12 #include <openssl/core_dispatch.h> 13 #include <openssl/core_names.h> 14 #include <openssl/err.h> 15 #include <openssl/proverr.h> 16 #include <openssl/params.h> 17 #include "internal/numbers.h" 18 #include "prov/implementations.h" 19 #include "prov/provider_ctx.h" 20 #include "prov/kdfexchange.h" 21 #include "prov/providercommon.h" 22 23 static OSSL_FUNC_keyexch_newctx_fn kdf_tls1_prf_newctx; 24 static OSSL_FUNC_keyexch_newctx_fn kdf_hkdf_newctx; 25 static OSSL_FUNC_keyexch_newctx_fn kdf_scrypt_newctx; 26 static OSSL_FUNC_keyexch_init_fn kdf_init; 27 static OSSL_FUNC_keyexch_derive_fn kdf_derive; 28 static OSSL_FUNC_keyexch_freectx_fn kdf_freectx; 29 static OSSL_FUNC_keyexch_dupctx_fn kdf_dupctx; 30 static OSSL_FUNC_keyexch_set_ctx_params_fn kdf_set_ctx_params; 31 static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_tls1_prf_settable_ctx_params; 32 static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_hkdf_settable_ctx_params; 33 static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_scrypt_settable_ctx_params; 34 35 typedef struct { 36 void *provctx; 37 EVP_KDF_CTX *kdfctx; 38 KDF_DATA *kdfdata; 39 } PROV_KDF_CTX; 40 41 static void *kdf_newctx(const char *kdfname, void *provctx) 42 { 43 PROV_KDF_CTX *kdfctx; 44 EVP_KDF *kdf = NULL; 45 46 if (!ossl_prov_is_running()) 47 return NULL; 48 49 kdfctx = OPENSSL_zalloc(sizeof(PROV_KDF_CTX)); 50 if (kdfctx == NULL) 51 return NULL; 52 53 kdfctx->provctx = provctx; 54 55 kdf = EVP_KDF_fetch(PROV_LIBCTX_OF(provctx), kdfname, NULL); 56 if (kdf == NULL) 57 goto err; 58 kdfctx->kdfctx = EVP_KDF_CTX_new(kdf); 59 EVP_KDF_free(kdf); 60 61 if (kdfctx->kdfctx == NULL) 62 goto err; 63 64 return kdfctx; 65 err: 66 OPENSSL_free(kdfctx); 67 return NULL; 68 } 69 70 #define KDF_NEWCTX(funcname, kdfname) \ 71 static void *kdf_##funcname##_newctx(void *provctx) \ 72 { \ 73 return kdf_newctx(kdfname, provctx); \ 74 } 75 76 KDF_NEWCTX(tls1_prf, "TLS1-PRF") 77 KDF_NEWCTX(hkdf, "HKDF") 78 KDF_NEWCTX(scrypt, "SCRYPT") 79 80 static int kdf_init(void *vpkdfctx, void *vkdf, const OSSL_PARAM params[]) 81 { 82 PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx; 83 84 if (!ossl_prov_is_running() 85 || pkdfctx == NULL 86 || vkdf == NULL 87 || !ossl_kdf_data_up_ref(vkdf)) 88 return 0; 89 pkdfctx->kdfdata = vkdf; 90 91 return kdf_set_ctx_params(pkdfctx, params); 92 } 93 94 static int kdf_derive(void *vpkdfctx, unsigned char *secret, size_t *secretlen, 95 size_t outlen) 96 { 97 PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx; 98 size_t kdfsize; 99 int ret; 100 101 if (!ossl_prov_is_running()) 102 return 0; 103 104 kdfsize = EVP_KDF_CTX_get_kdf_size(pkdfctx->kdfctx); 105 106 if (secret == NULL) { 107 *secretlen = kdfsize; 108 return 1; 109 } 110 111 if (kdfsize != SIZE_MAX) { 112 if (outlen < kdfsize) { 113 ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); 114 return 0; 115 } 116 outlen = kdfsize; 117 } 118 119 ret = EVP_KDF_derive(pkdfctx->kdfctx, secret, outlen, NULL); 120 if (ret <= 0) 121 return 0; 122 123 *secretlen = outlen; 124 return 1; 125 } 126 127 static void kdf_freectx(void *vpkdfctx) 128 { 129 PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx; 130 131 EVP_KDF_CTX_free(pkdfctx->kdfctx); 132 ossl_kdf_data_free(pkdfctx->kdfdata); 133 134 OPENSSL_free(pkdfctx); 135 } 136 137 static void *kdf_dupctx(void *vpkdfctx) 138 { 139 PROV_KDF_CTX *srcctx = (PROV_KDF_CTX *)vpkdfctx; 140 PROV_KDF_CTX *dstctx; 141 142 if (!ossl_prov_is_running()) 143 return NULL; 144 145 dstctx = OPENSSL_zalloc(sizeof(*srcctx)); 146 if (dstctx == NULL) 147 return NULL; 148 149 *dstctx = *srcctx; 150 151 dstctx->kdfctx = EVP_KDF_CTX_dup(srcctx->kdfctx); 152 if (dstctx->kdfctx == NULL) { 153 OPENSSL_free(dstctx); 154 return NULL; 155 } 156 if (!ossl_kdf_data_up_ref(dstctx->kdfdata)) { 157 EVP_KDF_CTX_free(dstctx->kdfctx); 158 OPENSSL_free(dstctx); 159 return NULL; 160 } 161 162 return dstctx; 163 } 164 165 static int kdf_set_ctx_params(void *vpkdfctx, const OSSL_PARAM params[]) 166 { 167 PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx; 168 169 return EVP_KDF_CTX_set_params(pkdfctx->kdfctx, params); 170 } 171 172 static const OSSL_PARAM *kdf_settable_ctx_params(ossl_unused void *vpkdfctx, 173 void *provctx, 174 const char *kdfname) 175 { 176 EVP_KDF *kdf = EVP_KDF_fetch(PROV_LIBCTX_OF(provctx), kdfname, 177 NULL); 178 const OSSL_PARAM *params; 179 180 if (kdf == NULL) 181 return NULL; 182 183 params = EVP_KDF_settable_ctx_params(kdf); 184 EVP_KDF_free(kdf); 185 186 return params; 187 } 188 189 #define KDF_SETTABLE_CTX_PARAMS(funcname, kdfname) \ 190 static const OSSL_PARAM *kdf_##funcname##_settable_ctx_params(void *vpkdfctx, \ 191 void *provctx) \ 192 { \ 193 return kdf_settable_ctx_params(vpkdfctx, provctx, kdfname); \ 194 } 195 196 KDF_SETTABLE_CTX_PARAMS(tls1_prf, "TLS1-PRF") 197 KDF_SETTABLE_CTX_PARAMS(hkdf, "HKDF") 198 KDF_SETTABLE_CTX_PARAMS(scrypt, "SCRYPT") 199 200 #define KDF_KEYEXCH_FUNCTIONS(funcname) \ 201 const OSSL_DISPATCH ossl_kdf_##funcname##_keyexch_functions[] = { \ 202 { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))kdf_##funcname##_newctx }, \ 203 { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))kdf_init }, \ 204 { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))kdf_derive }, \ 205 { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))kdf_freectx }, \ 206 { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))kdf_dupctx }, \ 207 { OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))kdf_set_ctx_params }, \ 208 { OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS, \ 209 (void (*)(void))kdf_##funcname##_settable_ctx_params }, \ 210 { 0, NULL } \ 211 }; 212 213 KDF_KEYEXCH_FUNCTIONS(tls1_prf) 214 KDF_KEYEXCH_FUNCTIONS(hkdf) 215 KDF_KEYEXCH_FUNCTIONS(scrypt) 216