1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * Copyright (c) 2018-2019, Oracle and/or its affiliates. All rights reserved. 4e1051a39Sopenharmony_ci * 5e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 6e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 7e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 8e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 9e1051a39Sopenharmony_ci */ 10e1051a39Sopenharmony_ci 11e1051a39Sopenharmony_ci#include <stdio.h> 12e1051a39Sopenharmony_ci#include <stdlib.h> 13e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 14e1051a39Sopenharmony_ci#include <openssl/evp.h> 15e1051a39Sopenharmony_ci#include <openssl/kdf.h> 16e1051a39Sopenharmony_ci#include <openssl/core.h> 17e1051a39Sopenharmony_ci#include <openssl/core_names.h> 18e1051a39Sopenharmony_ci#include "crypto/evp.h" 19e1051a39Sopenharmony_ci#include "internal/numbers.h" 20e1051a39Sopenharmony_ci#include "internal/provider.h" 21e1051a39Sopenharmony_ci#include "evp_local.h" 22e1051a39Sopenharmony_ci 23e1051a39Sopenharmony_ciEVP_KDF_CTX *EVP_KDF_CTX_new(EVP_KDF *kdf) 24e1051a39Sopenharmony_ci{ 25e1051a39Sopenharmony_ci EVP_KDF_CTX *ctx = NULL; 26e1051a39Sopenharmony_ci 27e1051a39Sopenharmony_ci if (kdf == NULL) 28e1051a39Sopenharmony_ci return NULL; 29e1051a39Sopenharmony_ci 30e1051a39Sopenharmony_ci ctx = OPENSSL_zalloc(sizeof(EVP_KDF_CTX)); 31e1051a39Sopenharmony_ci if (ctx == NULL 32e1051a39Sopenharmony_ci || (ctx->algctx = kdf->newctx(ossl_provider_ctx(kdf->prov))) == NULL 33e1051a39Sopenharmony_ci || !EVP_KDF_up_ref(kdf)) { 34e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); 35e1051a39Sopenharmony_ci if (ctx != NULL) 36e1051a39Sopenharmony_ci kdf->freectx(ctx->algctx); 37e1051a39Sopenharmony_ci OPENSSL_free(ctx); 38e1051a39Sopenharmony_ci ctx = NULL; 39e1051a39Sopenharmony_ci } else { 40e1051a39Sopenharmony_ci ctx->meth = kdf; 41e1051a39Sopenharmony_ci } 42e1051a39Sopenharmony_ci return ctx; 43e1051a39Sopenharmony_ci} 44e1051a39Sopenharmony_ci 45e1051a39Sopenharmony_civoid EVP_KDF_CTX_free(EVP_KDF_CTX *ctx) 46e1051a39Sopenharmony_ci{ 47e1051a39Sopenharmony_ci if (ctx == NULL) 48e1051a39Sopenharmony_ci return; 49e1051a39Sopenharmony_ci ctx->meth->freectx(ctx->algctx); 50e1051a39Sopenharmony_ci ctx->algctx = NULL; 51e1051a39Sopenharmony_ci EVP_KDF_free(ctx->meth); 52e1051a39Sopenharmony_ci OPENSSL_free(ctx); 53e1051a39Sopenharmony_ci} 54e1051a39Sopenharmony_ci 55e1051a39Sopenharmony_ciEVP_KDF_CTX *EVP_KDF_CTX_dup(const EVP_KDF_CTX *src) 56e1051a39Sopenharmony_ci{ 57e1051a39Sopenharmony_ci EVP_KDF_CTX *dst; 58e1051a39Sopenharmony_ci 59e1051a39Sopenharmony_ci if (src == NULL || src->algctx == NULL || src->meth->dupctx == NULL) 60e1051a39Sopenharmony_ci return NULL; 61e1051a39Sopenharmony_ci 62e1051a39Sopenharmony_ci dst = OPENSSL_malloc(sizeof(*dst)); 63e1051a39Sopenharmony_ci if (dst == NULL) { 64e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); 65e1051a39Sopenharmony_ci return NULL; 66e1051a39Sopenharmony_ci } 67e1051a39Sopenharmony_ci 68e1051a39Sopenharmony_ci memcpy(dst, src, sizeof(*dst)); 69e1051a39Sopenharmony_ci if (!EVP_KDF_up_ref(dst->meth)) { 70e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); 71e1051a39Sopenharmony_ci OPENSSL_free(dst); 72e1051a39Sopenharmony_ci return NULL; 73e1051a39Sopenharmony_ci } 74e1051a39Sopenharmony_ci 75e1051a39Sopenharmony_ci dst->algctx = src->meth->dupctx(src->algctx); 76e1051a39Sopenharmony_ci if (dst->algctx == NULL) { 77e1051a39Sopenharmony_ci EVP_KDF_CTX_free(dst); 78e1051a39Sopenharmony_ci return NULL; 79e1051a39Sopenharmony_ci } 80e1051a39Sopenharmony_ci return dst; 81e1051a39Sopenharmony_ci} 82e1051a39Sopenharmony_ci 83e1051a39Sopenharmony_ciint evp_kdf_get_number(const EVP_KDF *kdf) 84e1051a39Sopenharmony_ci{ 85e1051a39Sopenharmony_ci return kdf->name_id; 86e1051a39Sopenharmony_ci} 87e1051a39Sopenharmony_ci 88e1051a39Sopenharmony_ciconst char *EVP_KDF_get0_name(const EVP_KDF *kdf) 89e1051a39Sopenharmony_ci{ 90e1051a39Sopenharmony_ci return kdf->type_name; 91e1051a39Sopenharmony_ci} 92e1051a39Sopenharmony_ci 93e1051a39Sopenharmony_ciconst char *EVP_KDF_get0_description(const EVP_KDF *kdf) 94e1051a39Sopenharmony_ci{ 95e1051a39Sopenharmony_ci return kdf->description; 96e1051a39Sopenharmony_ci} 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_ciint EVP_KDF_is_a(const EVP_KDF *kdf, const char *name) 99e1051a39Sopenharmony_ci{ 100e1051a39Sopenharmony_ci return kdf != NULL && evp_is_a(kdf->prov, kdf->name_id, NULL, name); 101e1051a39Sopenharmony_ci} 102e1051a39Sopenharmony_ci 103e1051a39Sopenharmony_ciconst OSSL_PROVIDER *EVP_KDF_get0_provider(const EVP_KDF *kdf) 104e1051a39Sopenharmony_ci{ 105e1051a39Sopenharmony_ci return kdf->prov; 106e1051a39Sopenharmony_ci} 107e1051a39Sopenharmony_ci 108e1051a39Sopenharmony_ciconst EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx) 109e1051a39Sopenharmony_ci{ 110e1051a39Sopenharmony_ci return ctx->meth; 111e1051a39Sopenharmony_ci} 112e1051a39Sopenharmony_ci 113e1051a39Sopenharmony_civoid EVP_KDF_CTX_reset(EVP_KDF_CTX *ctx) 114e1051a39Sopenharmony_ci{ 115e1051a39Sopenharmony_ci if (ctx == NULL) 116e1051a39Sopenharmony_ci return; 117e1051a39Sopenharmony_ci 118e1051a39Sopenharmony_ci if (ctx->meth->reset != NULL) 119e1051a39Sopenharmony_ci ctx->meth->reset(ctx->algctx); 120e1051a39Sopenharmony_ci} 121e1051a39Sopenharmony_ci 122e1051a39Sopenharmony_cisize_t EVP_KDF_CTX_get_kdf_size(EVP_KDF_CTX *ctx) 123e1051a39Sopenharmony_ci{ 124e1051a39Sopenharmony_ci OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; 125e1051a39Sopenharmony_ci size_t s = 0; 126e1051a39Sopenharmony_ci 127e1051a39Sopenharmony_ci if (ctx == NULL) 128e1051a39Sopenharmony_ci return 0; 129e1051a39Sopenharmony_ci 130e1051a39Sopenharmony_ci *params = OSSL_PARAM_construct_size_t(OSSL_KDF_PARAM_SIZE, &s); 131e1051a39Sopenharmony_ci if (ctx->meth->get_ctx_params != NULL 132e1051a39Sopenharmony_ci && ctx->meth->get_ctx_params(ctx->algctx, params)) 133e1051a39Sopenharmony_ci return s; 134e1051a39Sopenharmony_ci if (ctx->meth->get_params != NULL 135e1051a39Sopenharmony_ci && ctx->meth->get_params(params)) 136e1051a39Sopenharmony_ci return s; 137e1051a39Sopenharmony_ci return 0; 138e1051a39Sopenharmony_ci} 139e1051a39Sopenharmony_ci 140e1051a39Sopenharmony_ciint EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen, 141e1051a39Sopenharmony_ci const OSSL_PARAM params[]) 142e1051a39Sopenharmony_ci{ 143e1051a39Sopenharmony_ci if (ctx == NULL) 144e1051a39Sopenharmony_ci return 0; 145e1051a39Sopenharmony_ci 146e1051a39Sopenharmony_ci return ctx->meth->derive(ctx->algctx, key, keylen, params); 147e1051a39Sopenharmony_ci} 148e1051a39Sopenharmony_ci 149e1051a39Sopenharmony_ci/* 150e1051a39Sopenharmony_ci * The {get,set}_params functions return 1 if there is no corresponding 151e1051a39Sopenharmony_ci * function in the implementation. This is the same as if there was one, 152e1051a39Sopenharmony_ci * but it didn't recognise any of the given params, i.e. nothing in the 153e1051a39Sopenharmony_ci * bag of parameters was useful. 154e1051a39Sopenharmony_ci */ 155e1051a39Sopenharmony_ciint EVP_KDF_get_params(EVP_KDF *kdf, OSSL_PARAM params[]) 156e1051a39Sopenharmony_ci{ 157e1051a39Sopenharmony_ci if (kdf->get_params != NULL) 158e1051a39Sopenharmony_ci return kdf->get_params(params); 159e1051a39Sopenharmony_ci return 1; 160e1051a39Sopenharmony_ci} 161e1051a39Sopenharmony_ci 162e1051a39Sopenharmony_ciint EVP_KDF_CTX_get_params(EVP_KDF_CTX *ctx, OSSL_PARAM params[]) 163e1051a39Sopenharmony_ci{ 164e1051a39Sopenharmony_ci if (ctx->meth->get_ctx_params != NULL) 165e1051a39Sopenharmony_ci return ctx->meth->get_ctx_params(ctx->algctx, params); 166e1051a39Sopenharmony_ci return 1; 167e1051a39Sopenharmony_ci} 168e1051a39Sopenharmony_ci 169e1051a39Sopenharmony_ciint EVP_KDF_CTX_set_params(EVP_KDF_CTX *ctx, const OSSL_PARAM params[]) 170e1051a39Sopenharmony_ci{ 171e1051a39Sopenharmony_ci if (ctx->meth->set_ctx_params != NULL) 172e1051a39Sopenharmony_ci return ctx->meth->set_ctx_params(ctx->algctx, params); 173e1051a39Sopenharmony_ci return 1; 174e1051a39Sopenharmony_ci} 175e1051a39Sopenharmony_ci 176e1051a39Sopenharmony_ciint EVP_KDF_names_do_all(const EVP_KDF *kdf, 177e1051a39Sopenharmony_ci void (*fn)(const char *name, void *data), 178e1051a39Sopenharmony_ci void *data) 179e1051a39Sopenharmony_ci{ 180e1051a39Sopenharmony_ci if (kdf->prov != NULL) 181e1051a39Sopenharmony_ci return evp_names_do_all(kdf->prov, kdf->name_id, fn, data); 182e1051a39Sopenharmony_ci 183e1051a39Sopenharmony_ci return 1; 184e1051a39Sopenharmony_ci} 185